diff --git a/othersrc/OTRE/.classpath b/othersrc/OTRE/.classpath
new file mode 100644
index 0000000..b98640e
--- /dev/null
+++ b/othersrc/OTRE/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/bcel4-4-1"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/othersrc/OTRE/.project b/othersrc/OTRE/.project
new file mode 100644
index 0000000..9f6b831
--- /dev/null
+++ b/othersrc/OTRE/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>OTRE</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/othersrc/OTRE/.settings/org.eclipse.jdt.core.prefs b/othersrc/OTRE/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..1aa7124
--- /dev/null
+++ b/othersrc/OTRE/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,70 @@
+#Thu Sep 18 21:57:35 CEST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/othersrc/OTRE/MANIFEST.MF b/othersrc/OTRE/MANIFEST.MF
new file mode 100644
index 0000000..c759b23
--- /dev/null
+++ b/othersrc/OTRE/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Premain-Class: org.eclipse.objectteams.otre.jplis.otreAgent
+Can-Redefine-Classes: true
+Built-By: resix
+
diff --git a/othersrc/OTRE/about.html b/othersrc/OTRE/about.html
new file mode 100644
index 0000000..47048bd
--- /dev/null
+++ b/othersrc/OTRE/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>Feb 3, 2010</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/othersrc/OTRE/otre-src-jar.jardesc b/othersrc/OTRE/otre-src-jar.jardesc
new file mode 100644
index 0000000..7556776
--- /dev/null
+++ b/othersrc/OTRE/otre-src-jar.jardesc
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<jardesc>
+    <jar path="org.eclipse.objectteams.runtime/lib/otre.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/OTRE/otre-src-jar.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="false" exportJavaFiles="true" exportOutputFolder="true">
+        <javaElement handleIdentifier="=OTRE/src"/>
+    </selectedElements>
+</jardesc>
diff --git a/othersrc/OTRE/otre_agent.jardesc b/othersrc/OTRE/otre_agent.jardesc
new file mode 100644
index 0000000..cf1515f
--- /dev/null
+++ b/othersrc/OTRE/otre_agent.jardesc
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jardesc>
+    <jar path="org.eclipse.objectteams.otdt/lib/otre_agent.jar"/>
+    <options overwrite="false" compress="true" exportErrors="false" exportWarnings="true" saveDescription="true" descriptionLocation="/OTRE/otre_agent.jardesc" useSourceFolders="false" buildIfNeeded="true"/>
+    <manifest manifestVersion="1.0" usesManifest="true" reuseManifest="false" saveManifest="false" generateManifest="false" manifestLocation="/OTRE/MANIFEST.MF">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportOutputFolder="false" exportJavaFiles="false">
+        <javaElement handleIdentifier="=OTRE/src&lt;org.eclipse.objectteams.otre.jplis{otreAgent.java"/>
+    </selectedElements>
+</jardesc>
diff --git a/othersrc/OTRE/otre_min.jardesc b/othersrc/OTRE/otre_min.jardesc
new file mode 100644
index 0000000..73086e6
--- /dev/null
+++ b/othersrc/OTRE/otre_min.jardesc
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<jardesc>
+    <jar path="org.objectteams.otdt/lib/otre_min.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/OTRE/otre_min.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="false" manifestLocation="/OTRE/MANIFEST.MF" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
+        <javaElement handleIdentifier="=OTRE/src&lt;org.objectteams"/>
+    </selectedElements>
+</jardesc>
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseCallRedirection.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseCallRedirection.java
new file mode 100644
index 0000000..567a422
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseCallRedirection.java
@@ -0,0 +1,1446 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: BaseCallRedirection.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import de.fub.bytecode.classfile.*;
+import de.fub.bytecode.generic.*;
+import de.fub.bytecode.*;
+
+import java.util.*;
+
+import org.eclipse.objectteams.otre.util.*;
+
+/**
+ * for callin-role-methods with recursive method-calls (base calls) we add a
+ * method with extendend signature.
+ * Within the extendend method recursive calls are replaced by the corresponding
+ * (chaining)base-call.<p>
+ * For example:
+ * <pre>
+ *      callin m1() { m1(); } -->
+ *      callin m1(Team _OT$teams[], int _OT$teamIDs[],
+ *                int _OT$idx, int _OT$baseMethTag){
+ *          liftToRole(b1._OT$m1$chain(Team _OT$teams[],
+ *                                     int _OT$teamIDs[],
+ *                                     int _OT$idx,
+ *                                     int _OT$baseMethTag));
+ *      }
+ * </pre>
+ *
+ * @version $Id: BaseCallRedirection.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author  Christine Hundt
+ * @author Stephan Herrmann
+ */
+public class BaseCallRedirection extends ObjectTeamsTransformation {
+
+    static class IHPair {
+		private InstructionHandle _ih1, _ih2;
+		public IHPair (InstructionHandle ih1, InstructionHandle ih2) {
+			_ih1 = ih1;
+			_ih2 = ih2;
+		}
+		public InstructionHandle fst() {return _ih1; }
+		public InstructionHandle snd() {return _ih2; }
+	}
+
+	public BaseCallRedirection(SharedState state) { this(null, state); }
+    public BaseCallRedirection(ClassLoader loader, SharedState state) {
+    	super(loader, state);
+    }
+    
+    /**
+     * @param ce
+     * @param cg
+     */
+    public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
+    	factory = new InstructionFactory(cg);
+    	String class_name = cg.getClassName();
+
+    	if (state.interfaceTransformedClasses.contains(class_name)) {
+    		return; //already transformed!
+    	}
+
+        ConstantPoolGen cpg = cg.getConstantPool();
+    	checkReadClassAttributes(ce, cg, class_name, cpg);
+            
+    	if (!CallinBindingManager.isRole(class_name)) {
+    		return;
+    	}
+						
+    	if (!cg.isInterface()) {
+	    	Set<String> boundBaseMethods = CallinBindingManager.getBoundRoleMethods(class_name);    	
+	    	addBaseCallSurrogatesForReplaceBindings(ce, boundBaseMethods, cg);
+    	}
+
+    	Method[] methods = cg.getMethods();
+    	for (int i=0; i<methods.length; i++) {
+    		Method m = methods[i];
+    		String method_name  = m.getName();
+    		String method_signature = m.getSignature();
+            
+    		if (candidateForImplicitActivation(m, cg, cpg)) { // TODO: check the other preconditions, like not abstact etc. 
+    			cg.replaceMethod(m, genImplicitActivation(m, class_name, cpg, true));
+    		}
+    		
+    		if (!isCallin(m, cg))
+    			continue;
+            if (logging) printLogMessage(method_name + " in " + class_name
+                        + " IS A CALLIN-METHOD!");
+    		if (method_name.startsWith(OT_PREFIX)) {
+    			method_name = revertToOriginalName(method_name);
+    			if (logging) printLogMessage("Reverted tsuper name to " + method_name);
+    		}
+    		// code SHOULD contain at least one base call.
+            if(logging) printLogMessage("----->will add another method " + method_name
+    						+ " with enhanced signature");
+             
+//{SH: retrench signature because otherwise the binding will not be found,
+//     as a result an empty basecall surrogate will be generated leading to repetetive methods...
+//     TODO(SH) is this the proper way to retrench??
+			String enhancedPrefix = "([Lorg/objectteams/Team;[IIII[Ljava/lang/Object;";
+			if (method_signature.startsWith(enhancedPrefix)) 
+    			method_signature = "("+method_signature.substring(enhancedPrefix.length());
+// SH}    		
+    		
+    		boolean roleMethodIsBound = CallinBindingManager.roleMethodHasBinding(class_name, 
+    																	   method_name,
+																		   method_signature);
+
+    		//if (mbs.isEmpty()) {
+    		if (!roleMethodIsBound) {
+    			if (logging) printLogMessage("callin method " + method_name
+    						+ " was not bound in this class!!!");
+    		}
+    		MethodGen baseCallSurrogate = null;
+    		if (!IS_COMPILER_13X_PLUS) { // since 1.3.0 this part is legacy:
+	    		if (!roleMethodIsBound && !methodHasCallinFlags(m, cg, OVERRIDING) && !m.isStatic()) {
+	    			// method not bound in current class and doesn't inherit a base call surrogate
+	    			baseCallSurrogate = generateEmptyBaseCallSurrogate(cg, m);
+	    		}
+	    		if (baseCallSurrogate != null)
+	    			ce.addMethod(baseCallSurrogate.getMethod(), cg);
+    		}
+    		
+    	}
+    	state.interfaceTransformedClasses.add(class_name);
+    }
+
+	/**
+	 *  Generates an "empty" base call surrogate method, which just throws an 'Error'.
+	 *  This method should normaly never be called, but overwritten in a subclass. 
+	 *  It has to be generated just for the wellformedness of the class file.
+	 * @param cg
+	 * @param m
+	 * @param mbs
+	 * @param baseClassName
+	 * @return
+	 */
+	private MethodGen generateEmptyBaseCallSurrogate(ClassGen cg, Method m/*, List mbs*/) {
+		if (m.getName().startsWith(OT_PREFIX))
+			return null; // ot-internal methods don't need this?
+
+		ConstantPoolGen cpg = cg.getConstantPool();
+		String class_name = cg.getClassName();
+		MethodGen mg = new MethodGen(m, class_name, cpg);
+		
+		if (isTSuperWrapper(mg)) {
+			// tsuper wrapper do not need base call surrogates
+			return null;
+		}
+		
+		// role method already was enhanced by compiler
+		Type[] enhancedArgumentTypes = mg.getArgumentTypes();
+		if (IS_COMPILER_GREATER_123) {
+			// add super flag between enhancement and real arguments:
+			int len = enhancedArgumentTypes.length;
+			Type[] newArgumentTypes = new Type[len+1];
+			System.arraycopy(enhancedArgumentTypes, 0, newArgumentTypes, 0, EXTRA_ARGS);
+			newArgumentTypes[EXTRA_ARGS] = Type.BOOLEAN;
+			System.arraycopy(enhancedArgumentTypes, EXTRA_ARGS, newArgumentTypes, EXTRA_ARGS+1, len-EXTRA_ARGS);
+			enhancedArgumentTypes = newArgumentTypes;
+		}
+		Type   enhancedReturnType    = mg.getReturnType();
+		
+// {SH: interface method has no argument names? generate dummy names: 
+		String[] argumentNames = new String[enhancedArgumentTypes.length];
+		for (int i = 0; i < argumentNames.length; i++) {
+			argumentNames[i] = "arg"+i;
+		}
+			
+		// role method already was enhanced by compiler:
+		String[] enhancedArgumentNames = argumentNames;
+// }	
+		InstructionList il = new InstructionList();
+		//int accessFlags = m.getAccessFlags();
+		int accessFlags = Constants.ACC_PROTECTED; // no unanticipated calls possible
+
+// {SH: interface methods must be public abstract:
+		if (cg.isInterface()) 
+			accessFlags = Constants.ACC_ABSTRACT|Constants.ACC_PUBLIC;
+// }
+		
+		MethodGen baseCallSurrogate = new MethodGen(accessFlags,
+													enhancedReturnType,
+													enhancedArgumentTypes,
+													enhancedArgumentNames,
+													getBaseCallSurrogateName(m.getName(), m.isStatic(), class_name /*genRoleInterfaceName(class_name)*/), 
+													class_name,
+													il, cpg);
+// {SH: no code for interface method:
+		if (!cg.isInterface()) {
+			// orig:
+			if (logging)
+				printLogMessage("Exception has to be thrown!");
+
+			createThrowInternalError(cpg, il, new InstructionList(new PUSH(cpg, "Binding-Error: base-call impossible!")));
+
+			il.append(InstructionFactory.createNull(enhancedReturnType));
+			il.append(InstructionFactory.createReturn(enhancedReturnType));
+
+			if (debugging)
+				baseCallSurrogate.addLineNumber(il.getStart(), STEP_OVER_LINENUMBER);
+		}
+// }
+
+		il.setPositions();
+		baseCallSurrogate.removeNOPs();
+		baseCallSurrogate.setMaxStack();
+		baseCallSurrogate.setMaxLocals();
+		return baseCallSurrogate;		
+	}
+
+	/**
+	 * @param mg
+	 * @return
+	 */
+	private static boolean isTSuperWrapper(MethodGen mg) {
+		Type[] argTypes = mg.getArgumentTypes();
+		if (argTypes.length == 0) {
+			return false; // no tsuper marker interface argument existing 
+		}
+		String lastArgument = (argTypes[argTypes.length - 1]).toString();
+		return lastArgument.contains(OTDT_PREFIX);
+	}
+
+	/**
+	 * Adds base call surrogate method for all role method bindings in the current role class.
+	 * Thereby method bindings which are defined in super roles are accumulated and 
+	 * considered as well. 
+	 * @param ce				the ClassEnhancer to which the new method has to be added
+	 * @param boundRoleMethods	the bound methods of the role class
+	 * @param cg 				the ClassGen for the role class
+	 */
+	private void addBaseCallSurrogatesForReplaceBindings(ClassEnhancer ce, Set<String> boundRoleMethods, ClassGen cg)
+	{
+		Iterator<String> it = boundRoleMethods.iterator();
+		while (it.hasNext()) {
+			String nameAndSignature = it.next();
+			int dotIndex = nameAndSignature.indexOf('.');
+			String methodName = nameAndSignature.substring(0, dotIndex);
+			String methodSignature = nameAndSignature.substring(dotIndex + 1);
+			List<MethodBinding> mbs = CallinBindingManager.getBindingsForRoleMethod(cg.getClassName(), 
+																	 methodName, 
+																	 methodSignature);
+			MethodBinding anyMethodBinding = mbs.get(0);
+			if (!anyMethodBinding.isReplace()) {
+				continue; 
+			}
+			mbs.addAll(CallinBindingManager.getInheritedRoleMethodBindings(cg.getClassName(),
+																		   methodName,
+																		   methodSignature));
+			
+			if (anyMethodBinding.hasStaticRoleMethod())
+				continue; // base call surrogates for static methods are generated within the enclosing team class
+			// TODO: remove this check as soon as static replace method bindings are no longer in 'CallinMethodMappings'
+			MethodGen baseCallSurrogate = genBaseCallSurrogate(cg, mbs);
+			ce.addOrReplaceMethod(baseCallSurrogate.getMethod(), cg);
+		}
+	}
+
+	/**
+	 * Generates base call surrogate method for the role method for which the method bindings 'mbs' are.
+	 * Thereby a switch-case for each bound base method is generated.
+	 * This method is only for nonstatic role methods. Base call surrogates for static methods 
+	 * are generated within the enclosing team class
+	 * @param cg			the ClassGen for the role class	
+	 * @param mbs			the method bindings for one role method
+	 * @param baseClassName	the name of the base class
+	 */
+	MethodGen genBaseCallSurrogate(ClassGen cg, List<MethodBinding> mbs) {
+		
+		//baseClassName would not be needed here, if I could find out the root-base-class-type...
+		ConstantPoolGen cpg = cg.getConstantPool();
+		String class_name = cg.getClassName();
+
+		MethodBinding anyBindingForRoleMethod = mbs.get(0);
+		String baseClassName = anyBindingForRoleMethod.getRootBoundBase();
+		String roleMethodSignature = anyBindingForRoleMethod.getRoleMethodSignature();
+
+		Type[] enhancedArgumentTypes;
+		{
+			Type[] argTypesTail = Type.getArgumentTypes(roleMethodSignature);
+			if (IS_COMPILER_GREATER_123) {
+				// add super flag between enhancement and real arguments:
+				int len = argTypesTail.length;
+				System.arraycopy(argTypesTail, 0, argTypesTail=new Type[len+1], 1, len);
+				argTypesTail[0] = Type.BOOLEAN;
+			}
+			enhancedArgumentTypes = enhanceArgumentTypes(argTypesTail);
+		}
+		Type enhancedReturnType = generalizeReturnType(Type.getReturnType(roleMethodSignature));
+		String methodName = anyBindingForRoleMethod.getRoleMethodName();
+		InstructionList il = new InstructionList();
+		int accessFlags = Constants.ACC_PROTECTED;
+
+		MethodGen baseCallSurrogate = new MethodGen(accessFlags,
+													enhancedReturnType,
+													enhancedArgumentTypes,
+													null, // no explicit names
+													getBaseCallSurrogateName(methodName, false, 
+																			 genRoleInterfaceName(class_name)), 
+													class_name,
+													il, cpg);
+
+		ObjectType baseClass = new ObjectType(baseClassName);
+		ObjectType outerClass;
+		{
+			String outerClassName = getOuterClassName(class_name);
+			outerClass = new ObjectType(outerClassName);
+		}
+			
+		LocalVariableGen otResult = null;
+		
+		otResult = baseCallSurrogate.addLocalVariable("_OT$result",
+				enhancedReturnType, null, null);
+
+		il.insert(InstructionFactory.createStore(enhancedReturnType,
+				otResult.getIndex()));
+		il.insert(new ACONST_NULL());
+		il.setPositions(); // about to retrieve instruction handles.
+		
+		if (logging) printLogMessage("base-call switch has to be inserted!");	
+		InstructionList loading = new InstructionList();
+		loading.append(InstructionFactory.createThis());
+		int index = 1;
+		for (int i = 0; i < enhancedArgumentTypes.length; i++) {
+			loading.append(InstructionFactory.createLoad(enhancedArgumentTypes[i],index));
+			index += enhancedArgumentTypes[i].getSize();
+		}
+		
+		Type[] argumentTypes = Type.getArgumentTypes(roleMethodSignature);
+		Type returnType = Type.getReturnType(roleMethodSignature);
+		
+		if (debugging) {
+			baseCallSurrogate.addLineNumber(il.getStart(), STEP_OVER_LINENUMBER);
+		}
+		
+		boolean generateSuperAccess = false;
+		List<SuperMethodDescriptor> superAccesses = IS_COMPILER_GREATER_123 ? CallinBindingManager.getSuperAccesses(baseClassName) : null;
+		if (superAccesses != null) {
+			outer: for (SuperMethodDescriptor superMethod : superAccesses) {
+				for (MethodBinding methodBinding : mbs) {
+					if (   superMethod.methodName.equals(methodBinding.getBaseMethodName())
+						&& superMethod.signature.equals(methodBinding.getBaseMethodSignature())) 
+					{
+						generateSuperAccess = true; 
+						break outer;
+					}
+				}
+			}
+		}
+
+		BranchInstruction ifSuper = new IFEQ(null);
+		GotoInstruction skipElse  = new GOTO(null);
+		if (generateSuperAccess) {
+			// gen: if (isSuperAccess) { _OT$base._OT$m$super(args); } else ...
+			il.append(InstructionFactory.createLoad(Type.BOOLEAN, EXTRA_ARGS+1)); // last synthetic arg is super-flag
+			il.append(ifSuper);
+			il.append(genBaseCallSwitch(cpg, mbs, baseCallSurrogate,
+										 argumentTypes,
+										 outerClass, baseClass,
+										 returnType, 
+										 otResult, loading, true));
+			il.append(skipElse);
+		}
+		InstructionList 
+		basecall = genBaseCallSwitch(cpg, mbs, baseCallSurrogate,
+									 argumentTypes,
+									 outerClass, baseClass,
+									 returnType,
+									 otResult, loading, false);
+		InstructionHandle callStart = basecall.getStart(); // store handle before append eats the list
+		il.append(basecall);
+		if (generateSuperAccess) {
+			ifSuper.setTarget(callStart);
+			skipElse.setTarget(il.append(new NOP()));
+		}
+		
+		il.append(InstructionFactory.createLoad(enhancedReturnType, otResult.getIndex()));
+		il.append(InstructionFactory.createReturn(enhancedReturnType));							
+		
+		il.setPositions();
+		baseCallSurrogate.removeNOPs();
+		baseCallSurrogate.setMaxStack();
+		baseCallSurrogate.setMaxLocals();
+		return baseCallSurrogate;		
+	}
+
+/*
+    Type findBaseFieldType(JavaClass c, ConstantPoolGen cpg) {
+           Field[] fields = c.getFields();
+            for (int l=0; l<fields.length; l++) {
+                Field f = fields[l];
+                if (f.getName().equals(BASE)) {
+                    FieldGen fg = new FieldGen(f, cpg);
+                    return fg.getType();
+                }
+            }
+			JavaClass superClass = Repository.lookupClass(c.getSuperclassName());
+			// BCEL bug: super class of "Object" is "Object":
+			//System.err.println("Superclass of "+ c.getClassName()+" is " +c.getSuperclassName());
+			if (!superClass.getClassName().equals("java.lang.Object")) {
+					return findBaseFieldType(superClass, cpg);
+			}
+            return null;
+    }*/
+
+    /**
+	 * Iterate through the instructions of a callin method.
+	 * <ul>
+	 *   <li>Adjust local variable instructions due to inserted extra arguments.
+	 *   <li>Replace base-calls and calls to activate.
+	 * </ul>
+	 * @param cg
+	 * @param m
+	 * @param mbs List<MethodBinding>
+	 * @return MethodGen
+	 */
+    MethodGen replaceBaseCalls(ClassGen cg, Method m, List<MethodBinding> mbs) {
+
+    	int indexOffset = m.isStatic() ? -1 : 0; // argument indices are decremented for static methods, 
+												 // because of the missing 'this'
+        
+    	ConstantPoolGen cpg = cg.getConstantPool();
+        String class_name   = cg.getClassName();
+        String method_name  = m.getName();
+
+        MethodGen mg = new MethodGen(m, class_name, cpg);
+
+		Type[]   argumentTypes         = mg.getArgumentTypes();
+        Type     returnType            = mg.getReturnType();
+       
+        Type[] enhancedArgumentTypes = enhanceArgumentTypes(mg.getArgumentTypes());
+// {SH abstract methods may not have argument names??        
+        String[] argumentNames;
+        if (m.isAbstract()) {
+        	argumentNames = new String[argumentTypes.length];
+			int index = 0;
+        	for (int i = 0; i < argumentNames.length; i++) {
+				argumentNames[i] = "arg" + index/* i */;
+				index += argumentTypes[i].getSize();
+			}
+			
+/*			
+//			load regular arguments:
+				 int index = 1;
+				 for (int i=0; i<argTypes.length; i++) {
+					 il.append(InstructionFactory.createLoad(argTypes[i],index));
+					 index += argTypes[i].getSize();
+				 }
+//*/
+			
+        } else {
+        	argumentNames = mg.getArgumentNames();
+        }
+        String[] enhancedArgumentNames = enhanceArgumentNames(argumentNames);
+// orig:        String[] enhancedArgumentNames = enhanceArgumentNames(mg.getArgumentNames());
+// SH}       
+
+        Type enhancedMethodReturnType  = generalizeReturnType(m.getSignature());
+
+// {SH instruction list may be null for abstract method		
+// orig:   InstructionList il = mg.getInstructionList().copy();
+		InstructionList il = mg.getInstructionList();
+		if (il != null)
+			il = il.copy();
+		else
+			il = new InstructionList();
+// SH}		
+
+        MethodGen enhancedMethod = new MethodGen(m.getAccessFlags(),
+                                                 enhancedMethodReturnType,
+                                                 enhancedArgumentTypes,
+                                                 enhancedArgumentNames,
+                                                 method_name, class_name,
+                                                 il, cpg);
+		//not needed??:
+		// or not??????
+		copyLocalVariables(mg, enhancedMethod);
+		copyLineNumbers(mg, enhancedMethod);
+		
+        boolean returnValueAdded   =    (returnType               == Type.VOID)
+                                     && (enhancedMethodReturnType != Type.VOID);
+
+		// all exception handlers of this method, which have to be updated later.
+		CodeExceptionGen [] handlers = copyExceptionHandlers(mg, enhancedMethod, il);
+		// list of instruction handles (old and new) that are replaced in the sequel
+		ArrayList<IHPair> replacedInstructions = new ArrayList<IHPair>(); // of IHPair;
+		// set of instruction handles which signal TargetLostException during delete().
+		HashSet<InstructionHandle> targetLost = new HashSet<InstructionHandle>(); // of InstructionHandle
+
+        // create  LocalVariable Object _OT$result:
+        LocalVariableGen otResult = null;
+        
+        int slot = mg.getMaxLocals() + EXTRA_ARGS-indexOffset;
+        otResult = enhancedMethod.addLocalVariable("_OT$result", enhancedMethodReturnType,
+												   slot, null, null);
+        
+        // subtract EXTRA_ARGS since this offset will be added again below.
+        il.insert(InstructionFactory.createStore(enhancedMethodReturnType,
+        							    		 otResult.getIndex() - EXTRA_ARGS));
+
+        il.insert(new ACONST_NULL());
+        il.setPositions(); // about to retrieve instruction handles.
+
+        InstructionHandle[] ihs = il.getInstructionHandles();
+        //printLogMessage("every call of base." + method_name + "(...) will be replaced by "
+        //            + liftMethodName + BASE + "."+baseChainMethodName+"(...))");
+
+        int actInstruction = 0;
+        int offset = EXTRA_ARGS;
+        while (actInstruction < ihs.length) {
+			Instruction act_instruction = ihs[actInstruction].getInstruction();
+/****************************** variable index adaption: **********************************/
+   			if(act_instruction instanceof LocalVariableInstruction) {
+            // add offset to the index of every variable load or store instruction,
+			// because of the inserted EXTRA_ARGS  arguments:
+                LocalVariableInstruction localVariableInstruction = (LocalVariableInstruction) act_instruction;
+                if (localVariableInstruction.getIndex() != 0 || (enhancedMethod.isStatic())) { // 'this' stays at index 0
+                    if (localVariableInstruction instanceof StoreInstruction) {
+                        localVariableInstruction =
+							InstructionFactory.createStore(localVariableInstruction.getType(cpg),
+														   offset+localVariableInstruction.getIndex());
+                    } else if (localVariableInstruction instanceof LoadInstruction) {
+                        localVariableInstruction =
+							InstructionFactory.createLoad(localVariableInstruction.getType(cpg),
+											   			  offset+localVariableInstruction.getIndex());
+                    } else if (localVariableInstruction instanceof IINC) {
+                    	localVariableInstruction.setIndex(offset+localVariableInstruction.getIndex());
+                    	// TODO: check, if this is enough for all kinds of LocalVariableInstructions 
+                    	//               and if there are more instructions which use variable indizes!!
+                    }
+                    ihs[actInstruction].setInstruction(localVariableInstruction);
+                }
+            } else if (act_instruction instanceof RET) {
+                RET ret = (RET)act_instruction;
+                if (ret.getIndex() != 0)
+                    ihs[actInstruction].setInstruction(new RET(offset + ret.getIndex()));
+
+/*************************** "super"- & "tsuper"-call enhancement: **********************************/
+   			} else if (super_or_tsuper_instruction(act_instruction, method_name, cpg) ) {
+
+				InvokeInstruction ii = (InvokeInstruction)act_instruction;
+				InstructionHandle next = ihs[actInstruction+1];
+				InstructionList changedArea;
+				InstructionHandle[] delim = new InstructionHandle[2];
+				int stackDepth = computeArgumentStackDepth(cpg, ii);
+				InstructionList loading = pruneLoading(il, ihs, actInstruction,
+													   stackDepth, cpg,
+													   targetLost, delim, true);
+				if (loading == null) {
+					actInstruction++;
+					continue;
+				}
+				 
+				changedArea = genEnhancedSuperCall(cpg, ii, enhancedMethod, loading);
+				if (returnValueAdded) {
+                    changedArea.append(InstructionFactory.createStore(
+                            enhancedMethodReturnType, otResult.getIndex()));
+                } else {
+					InstructionHandle ih = adjustValue(changedArea, changedArea.getEnd(), enhancedMethodReturnType, returnType);
+					if (debugging && ih != null)
+						mg.addLineNumber(ih, STEP_OVER_LINENUMBER);
+				}
+				replacedInstructions.add(new IHPair(delim[0], changedArea.getStart()));
+				replacedInstructions.add(new IHPair(delim[1], changedArea.getEnd()));
+
+				il.insert(next, changedArea);
+				actInstruction++;
+				continue;
+				
+/*************************** "activate" substitution and base-call generation: ************/
+            //} else if (act_instruction instanceof INVOKEVIRTUAL) {
+            //    INVOKEVIRTUAL iv = (INVOKEVIRTUAL)act_instruction;
+			} else if (act_instruction instanceof InvokeInstruction) {
+				InvokeInstruction iv = (InvokeInstruction)act_instruction;
+                String iv_name = iv.getName(cpg);
+
+                // FIXME(SH): is this still needed? 
+                //            - activate is commented-out,
+                //            - base call is now generated by the compiler.
+                if(!(iv_name.equals(method_name) ||
+                     iv_name.equals("activate")))
+				{
+                    actInstruction++;
+                    continue;
+                }
+                InstructionHandle next = ihs[actInstruction+1];
+                InstructionList changedArea;
+				InstructionHandle[] delim = new InstructionHandle[2];
+               /*
+                if (iv_name.equals("activate")) {
+					// blank original invokevirtual:
+					ihs[actInstruction].setInstruction(new NOP());
+					Type [] ivArgTypes = iv.getArgumentTypes(cpg);
+					int activateArgCount = ivArgTypes.length;
+					InstructionList loading = null;
+					if (activateArgCount == 1)
+						loading = pruneLoading (il, ihs, actInstruction,
+												ivArgTypes[0].getSize(), cpg,
+												targetLost, delim, false);
+					changedArea = enhanceActivateCall(factory, cpg, loading, iv);
+					if (activateArgCount == 1) {
+						replacedInstructions.add(new IHPair(delim[0],
+															changedArea.getStart()));
+						replacedInstructions.add(new IHPair(delim[1],
+															changedArea.getEnd()));
+					}
+                } else*/ { // base call:
+                    int            stackDepth = computeArgumentStackDepth(cpg, iv);
+                    boolean deleteThis = true;
+                   
+                    if(enhancedMethod.isStatic())
+                    	deleteThis = false;
+                    
+                    /*
+                    if (iv.getOpcode()==Constants.INVOKESTATIC) 
+                    	deleteThis = false; 
+                    */
+                    InstructionList   loading = pruneLoading(il, ihs, actInstruction,
+															 stackDepth, cpg,
+															 targetLost, delim, /*true*/deleteThis);
+					//System.err.println(loading);
+					if (loading == null) {
+						actInstruction++;
+						continue;
+					}
+
+					// insert call of base-call surrogate method:
+					String roleInterfaceName = genRoleInterfaceName(cg.getClassName());
+					
+					String calleeClassName = null;
+					if(m.isStatic()) {
+						calleeClassName = extractTeamName(roleInterfaceName);
+					}
+					changedArea = genBaseCallSurrogateCall(cpg, iv, enhancedMethod, loading, extractRoleName(roleInterfaceName), calleeClassName);
+
+					if (returnValueAdded) {
+						changedArea.append(InstructionFactory.createStore(enhancedMethodReturnType,
+																		 otResult.getIndex()));				
+                	} else {
+						InstructionHandle ih = adjustValue(changedArea, changedArea.getEnd(), enhancedMethodReturnType, returnType);
+						if (debugging && ih != null)
+							mg.addLineNumber(ih, STEP_OVER_LINENUMBER);
+                	}
+                    replacedInstructions.add(new IHPair(delim[0], changedArea.getStart()));
+                    replacedInstructions.add(new IHPair(delim[1], changedArea.getEnd()));
+
+				} // if (activate or base call)
+
+                il.insert(next, changedArea);
+
+
+/*************************** "return" enhancements: ************/
+			} else if (act_instruction instanceof ReturnInstruction) {
+				// replace return statement by result preparation and a new return statement
+				// construct back to front, to keep the insertion position!
+				InstructionHandle oldReturn    = ihs[actInstruction];
+				InstructionHandle replacedPos  = oldReturn;
+				il.append(oldReturn, InstructionFactory.createReturn(enhancedMethodReturnType));
+				if (returnValueAdded) {
+					// load ot_result:
+					oldReturn.setInstruction(InstructionFactory.createLoad(enhancedMethodReturnType,
+																otResult.getIndex()));
+				} else {
+					oldReturn.setInstruction(new NOP());
+					replacedPos =
+						adjustValue(il, oldReturn, returnType, enhancedMethodReturnType);
+					if (debugging && replacedPos != null)
+						mg.addLineNumber(replacedPos, STEP_OVER_LINENUMBER);
+				}
+				if (replacedPos != null)
+					replacedInstructions.add(new IHPair(oldReturn, replacedPos));
+            } // conditional over instruction types
+			actInstruction++;
+        } //end while
+
+		// tidy:
+		checkUpdate(handlers, replacedInstructions, targetLost);
+        enhancedMethod.removeNOPs();
+		il.setPositions();
+        enhancedMethod.setMaxStack();
+        enhancedMethod.setMaxLocals();
+
+        return enhancedMethod;
+    }
+
+    /**
+     * Given an invokevirtual compute the space its arguments use on the stack.
+     * @param cpg
+     * @param iv
+     * @return int stack size.
+     */
+    static int computeArgumentStackDepth(ConstantPoolGen cpg, InvokeInstruction ii) {
+        Type [] iiargs = ii.getArgumentTypes(cpg);
+        int depth=0;
+        for (int i=0; i<iiargs.length; i++)
+            depth += iiargs[i].getSize();
+        return depth;
+    }
+
+	/**
+	 *  Copy all local variables from <tt>src</tt> to <tt>dest</tt>.
+	 *  While doing so, increment their index by EXTRA_ARGS.
+	 */
+	static void copyLocalVariables(MethodGen src, MethodGen dest) {
+		Type[] argumentTypes = src.getArgumentTypes();
+		LocalVariableGen[] lvgs = src.getLocalVariables();
+		for (int l=argumentTypes.length; l<lvgs.length; l++) {
+			LocalVariableGen lvg = lvgs[l];
+			if (lvg.getIndex() > 0) {
+				dest.addLocalVariable(lvg.getName(),
+									  			   lvg.getType(),
+									  			   lvg.getIndex()+(EXTRA_ARGS+1), // +1?????
+									  			   null, null);
+				//System.err.println("adding:" +src.getClassName() +" "+src.getName()+" "+lvg.getName() +" " + lvg.getType() +" "+ (lvg.getIndex()+(EXTRA_ARGS+1)));
+			}	
+		}
+	}
+	/** Copy all line numbers from <tt>src</tt> to <tt>dest</tt>. */
+	static void copyLineNumbers(MethodGen src, MethodGen dest) {
+		InstructionList il_dest = dest.getInstructionList();
+		il_dest.setPositions();
+		LineNumberGen[] src_lng = src.getLineNumbers();
+		for (int i=0; i<src_lng.length; i++) {
+			int position = src_lng[i].getInstruction().getPosition();
+			InstructionHandle ih = il_dest.findHandle(position);
+			dest.addLineNumber(ih, src_lng[i].getSourceLine());
+		}
+	}
+   /**
+     * Prune a invokevirtual portion from a given instruction list.
+     * Note, that arguments don't include 'this', which is not pruned but blanked
+     * (need to keep as possible jump target).
+     * @param il the source list
+     * @param ihs array of handles of this list
+     * @param idx points to a invokevirtual that shall be removed
+     * @param stackDepth size of the called method's arguments on the stack.
+	 *                   This is how deep we need to cut into the stack.
+     * @param cpg
+     * @param targetLost set of lost InstructionHandles to be filled
+     * @param delim array of two handles, which should be filled with start and end of
+	 *              the pruned region.
+	 * @param blankThis should the 'this' call target be overwritten?
+     * @return InstructionList a copy of the original value loading.
+     */
+    static InstructionList pruneLoading (InstructionList il, InstructionHandle[] ihs, int idx,
+								  int stackDepth, ConstantPoolGen cpg,
+								  HashSet<InstructionHandle> targetLost, InstructionHandle[] delim,
+								  boolean blankThis)
+    {
+        InstructionList nlist = new InstructionList();
+        InstructionHandle start = ihs[idx];
+        InstructionHandle end = ihs[idx--];
+        while (stackDepth > 0) {
+            start = ihs[idx--];
+            Instruction instr = start.getInstruction();
+            stackDepth -= stackDiff(instr, cpg);
+            nlist.insert(instr);
+        }
+		if (blankThis) {
+			if (!isALoad0(ihs[idx].getInstruction()))
+				return null;
+			ihs[idx].setInstruction(new NOP()); // keep as jump target but delete 'this'
+		}
+        delim[0] = start;
+        delim[1] = end;
+        safeDelete(il, start, end, targetLost);
+		return nlist;
+    }
+
+	static boolean isALoad0(Instruction i) {
+		if (!(i instanceof ALOAD)) return false;
+		return ((ALOAD)i).getIndex() == 0;
+	}
+
+	/** Get the lenght of the longest base method signature in mbs.
+	 *  @param mbs List of {@link MethodBinding MethodBinding}
+	 */
+//	static int getMaxBaseArgLen (List mbs) {
+//		int max=0;
+//		Iterator it = mbs.iterator();
+//		while (it.hasNext()) {
+//			MethodBinding mb = (MethodBinding)it.next();
+//			String sign = mb.getBaseMethodSignature();
+//			int len = Type.getArgumentTypes(sign).length;
+//			if (len>max) max = len;
+//		}
+//		return max;
+//	}
+
+	/**
+     * Generate a dispatching switch statement which calls the proper base method.
+	 * @param cpg
+     * @param mbs list of MethodBinding that applies to this callin method
+     * @param enhancedMethod the enhanced callin method
+	 * @param roleArgumentTypes arg types of the callin method
+     * @param outerClass the Team
+     * @param baseClass the base bound to this role
+     * @param returnType the return type of the original callin method
+     * @param otResult the local variable storing the base call result
+     * @param loading an instruction list holding the original instructions for
+	 *        loading parameters
+     * @return InstructionList the complete replacement implementing the base call.
+     */
+	InstructionList genBaseCallSwitch (ConstantPoolGen cpg,
+									   List<MethodBinding> mbs, MethodGen enhancedMethod,
+									   Type[] roleArgumentTypes,
+									   ObjectType outerClass, ObjectType baseClass,
+                                       Type returnType, LocalVariableGen otResult,
+                                       InstructionList loading,
+                                       boolean isSuperAccess)
+    {
+    	
+        String  className                = enhancedMethod.getClassName();
+        Type    enhancedMethodReturnType = enhancedMethod.getReturnType();
+		boolean callinHasReturnValue     = returnType != Type.VOID;
+
+		InstructionList il = new InstructionList();
+
+		// Setup a variable which holds the result of this base call.
+		// This variabel is local to this segment of code and used only
+		// to transport this result out off the switch statement.
+		int     localResult = -1;
+		LocalVariableGen lg = null;
+		if (callinHasReturnValue) {
+			lg = enhancedMethod.addLocalVariable("_OT$tmpResult", returnType,
+												 null, null);
+			localResult = lg.getIndex();
+			il.append(InstructionFactory.createNull (returnType));
+			il.append(InstructionFactory.createStore(returnType, localResult));
+		}
+		
+				// ---- Prepare the switch: ----
+        InstructionHandle switchStart = il.append
+			(InstructionFactory.createLoad(Type.INT, BASE_METH_ARG));
+		// generated: _OT$baseMethTag
+		
+        removeDuplicatedBaseMethodTags(mbs);
+        
+        // one break for each case clause
+        int numberOfCases = mbs.size();
+        GOTO[] breaks = new GOTO[numberOfCases];
+        for (int i=0; i<numberOfCases; i++)
+            breaks[i] = new GOTO(null);
+
+        int[]               matches = new int[numberOfCases];
+        InstructionHandle[] targets = new InstructionHandle[numberOfCases];
+		int caseCounter = 0;
+
+		Iterator<MethodBinding> it = mbs.iterator();
+		while (it.hasNext()) {
+
+			MethodBinding mb = it.next();
+
+			String wrapperName  = mb.getWrapperName();
+			int[] paramPositions = CallinBindingManager.getParamPositions(outerClass.getClassName(),
+																	wrapperName);
+            if (logging) printLogMessage("param pos(" + wrapperName + ")=" + paramPositions);
+			
+            matches[caseCounter] = CallinBindingManager.getBaseCallTag(mb.getBaseClassName(),
+            														   mb.getBaseMethodName(),
+            														   mb.getBaseMethodSignature());
+            InstructionHandle nextBranch = il.append(new NOP());
+
+			String baseMethodName            = mb.getBaseMethodName();
+			String baseMethodSignature       = mb.getBaseMethodSignature();
+			Type[] baseMethodArgumentTypes   = Type.getArgumentTypes(baseMethodSignature);
+			Type   baseMethodReturnType      = Type.getReturnType   (baseMethodSignature);
+			
+			String baseChainMethodName;
+			Type   baseChainReturnType;
+			Type[] enhancedBaseArgumentTypes;
+			if (isSuperAccess) {
+				baseChainMethodName 		 = OT_PREFIX+baseMethodName+"$super";
+				baseChainReturnType          = returnType;
+				// base arguments are un-enhanced but have a leading base instance:
+				int len = baseMethodArgumentTypes.length;
+				System.arraycopy(baseMethodArgumentTypes, 0, enhancedBaseArgumentTypes=new Type[len+1], 1, len);  
+				enhancedBaseArgumentTypes[0] = baseClass; 
+			} else {
+				baseChainMethodName          = genChainMethName(baseMethodName);
+				baseChainReturnType          = object; // ALWAYS
+				enhancedBaseArgumentTypes    = enhanceArgumentTypes(baseMethodArgumentTypes);
+			}
+			
+			// --- call target: ---
+
+			// if base class type is a role type _OT$base field has role interface type:
+			{
+				String baseClassName = baseClass.toString();
+				if (baseClassName.indexOf(OTDT_PREFIX) != -1) {
+					baseClass = new ObjectType(ObjectTeamsTransformation.genRoleInterfaceName(baseClassName));
+					if(logging) printLogMessage(baseClassName + " --> " + ObjectTeamsTransformation.genRoleInterfaceName(baseClassName));
+				}
+			}
+
+			// load '_OT$base' field:
+			InstructionHandle baseCallLine = il.append(InstructionFactory.createThis());
+			il.append(factory.createFieldAccess(className, BASE, baseClass, Constants.GETFIELD));
+			
+			if (!baseClass.getClassName().equals(mb.getBaseClassName())) {
+				// playedBy has been refined in the sub role;
+				// create a cast to the sub base class:
+				il.append(factory.createCast(baseClass, new ObjectType(mb.getBaseClassName())));
+			}
+			
+			// --- load arguments of the new method: ---
+			//     (letters refer to document parameter-passing.odg)
+			
+			// (u) generate extra arguments (indices are equal at role and base):
+			if (!isSuperAccess)
+				for (int idx = 0; idx < EXTRA_ARGS; idx++) 
+					il.append(InstructionFactory.createLoad(enhancedMethod.getArgumentTypes()[idx], 
+													        idx+1/*translating non-static*/));		
+			
+			// (v)(w)(x) split loading sequence and transfer source-level arguments
+			// (includes reverse-application of parameter mappings):
+
+			// Start at EXTRA_ARGS, because one set of enhancement has already been loaded,
+			// except when doing super access which only has one extra arg: base instance.
+			int start = isSuperAccess ? 1 : EXTRA_ARGS; 
+			il.append(translateLoads(splitLoading(cpg,
+											      loading.copy(),
+												  roleArgumentTypes), 
+									 enhancedMethod.getArgumentTypes(), 
+									 enhancedBaseArgumentTypes, 
+									 paramPositions,
+									 extractTeamName(enhancedMethod.getClassName()), 
+									 className,
+									 new BaseMethodInfo(mb.baseMethodIsCallin(), false/*static*/, mb.getTranslationFlags()),
+									 start,
+									 cpg));
+			// --- done loading ---									 
+
+			// invoke the chaining method of the base class (base-call!):
+			il.append(factory.createInvoke(mb.getBaseClassName(),
+										   baseChainMethodName,
+										   baseChainReturnType,
+										   enhancedBaseArgumentTypes,
+										   isSuperAccess 
+											   ? Constants.INVOKESTATIC
+											   : Constants.INVOKEVIRTUAL
+										   ));
+										   
+			boolean resultLiftingNecessary = ((mb.getTranslationFlags()&1)!=0);
+			
+			if (resultLiftingNecessary) { // call the static lift-method:
+				// STATIC_PARTS_OK: in role: lift method call
+//TODO: lift method args!
+				String liftMethodName = mb.getLiftMethodName();
+				Type liftMethodReturnType = Type.getReturnType(mb.getLiftMethodSignature());
+				Type[] liftMethodArgs = Type.getArgumentTypes(mb.getLiftMethodSignature());
+				
+				il.append(factory.createCast(baseChainReturnType, baseMethodReturnType));
+                il.append(InstructionFactory.createThis());
+                
+                int nestingDepth = countOccurrences(className, '$') -1;
+                il.append(factory.createGetField(className, "this$" + nestingDepth, outerClass ));
+
+                il.append(new SWAP()); // -> .., this$0, (BaseType)result
+				//il.append(new ICONST(LIFT_ARG_RES));
+				
+				il.append(factory.createInvoke(outerClass.getClassName(),
+											   liftMethodName,
+											   liftMethodReturnType,
+											   liftMethodArgs,
+											   Constants.INVOKEVIRTUAL));
+			}
+			
+			InstructionHandle afterBaseCallLine = il.append(new NOP());
+			
+			if (baseChainReturnType != Type.VOID) {
+				// adjust the return value to the type expected by the WRAPPER:
+				il.append(new DUP()); // keep for adjustment below
+				if (!resultLiftingNecessary)
+					adjustValue(il, null, baseChainReturnType, enhancedMethodReturnType);
+				il.append(InstructionFactory.createStore(enhancedMethodReturnType,
+						otResult.getIndex())); // store "globally"
+				// this store is needed to tunnel unused results through the callin.
+
+				// adjust the return value to the type expected by the ORIGINAL CALLIN:
+				adjustValue(il, null,  baseChainReturnType, returnType);
+				if (callinHasReturnValue)
+					il.append(InstructionFactory.createStore(returnType, localResult)); // store "locally"
+	 			    // this store is useful for callins which make use of the result.
+			}  
+		
+            targets[caseCounter] = nextBranch;
+            il.append(breaks[caseCounter]);
+            // generated: break;
+
+            caseCounter++;
+            
+            if (debugging) {
+            	enhancedMethod.addLineNumber(baseCallLine, STEP_INTO_LINENUMBER);
+            	enhancedMethod.addLineNumber(afterBaseCallLine, STEP_OVER_LINENUMBER);
+            }
+		}
+		// Default case: throw an exception reporting the situation:
+		// create: String msg = ("Unhandled base-call case!"+base_method_tag)
+		InstructionList messagePush = new InstructionList();
+		messagePush.append(factory.createNew(OTConstants.STRING_BUFFER_NAME));
+		messagePush.append(new DUP());
+		messagePush.append(factory.createInvoke(OTConstants.STRING_BUFFER_NAME, Constants.CONSTRUCTOR_NAME, Type.VOID, new Type[0], Constants.INVOKESPECIAL));
+		messagePush.append(new PUSH(cpg, "Unhandled base-call case: "));
+		messagePush.append(factory.createInvoke(OTConstants.STRING_BUFFER_NAME, "append", Type.STRINGBUFFER, new Type[]{Type.STRING}, Constants.INVOKEVIRTUAL));
+		messagePush.append(InstructionFactory.createLoad(Type.INT, BASE_METH_ARG));
+		messagePush.append(factory.createInvoke(OTConstants.STRING_BUFFER_NAME, "append", Type.STRINGBUFFER, new Type[]{Type.INT}, Constants.INVOKEVIRTUAL));
+		messagePush.append(factory.createInvoke(OTConstants.STRING_BUFFER_NAME, "toString", Type.STRING, new Type[0], Constants.INVOKEVIRTUAL));
+		// create: throw new OTREInternalError(msg)
+		InstructionHandle defaultCase = createThrowInternalError(cpg, il, messagePush);
+		
+        InstructionHandle afterSwitch = il.append(new NOP()); // all breaks point here.
+
+		il.append(switchStart, createLookupSwitch(matches, targets, breaks,
+												  defaultCase, afterSwitch));
+
+		// retrieve locally stored result:
+		if (callinHasReturnValue) {
+			il.append(InstructionFactory.createLoad(returnType, localResult));
+			lg.setStart(il.getStart()); // restrict local variable to this segment.
+			lg.setEnd(il.getEnd());
+		}
+
+        return il;
+	}
+
+	/**
+	 * Removes duplicated method bindings with the same base call tag from the list, to avoid duplicated 
+	 * cases in the base call surrogate-switch.
+	 * @param mbs
+	 */
+	private static void removeDuplicatedBaseMethodTags(List<MethodBinding> mbs) {
+		if (mbs.size() < 2) // nothing to remove
+			return;
+		
+		MethodBinding[] mbArray = mbs.toArray(new MethodBinding[mbs.size()]);
+		
+		Comparator<MethodBinding> baseCallTagComparator = new Comparator<MethodBinding>() {
+			public int compare(MethodBinding firstMB, MethodBinding secondMB) {
+				int firstBaseTag = CallinBindingManager.getBaseCallTag(firstMB.getBaseClassName(), 
+																	   firstMB.getBaseMethodName(), 
+																	   firstMB.getBaseMethodSignature());
+				int secondBaseTag = CallinBindingManager.getBaseCallTag(secondMB.getBaseClassName(), 
+						   											    secondMB.getBaseMethodName(), 
+						   											    secondMB.getBaseMethodSignature());
+				
+				if (firstBaseTag < secondBaseTag)
+					return -1;
+				if (firstBaseTag > secondBaseTag)
+					return 1;
+				return 0;
+			}
+		};
+		Arrays.sort(mbArray, baseCallTagComparator);
+		for (int i = 0; i + 1 < mbArray.length; i++) {
+			if (baseCallTagComparator.compare(mbArray[i], mbArray[i + 1]) == 0) {
+				mbs.remove(mbArray[i + 1]);
+			}
+		}
+	}
+
+
+	/**
+	 * @param className
+	 * @return
+	 */
+	private static String extractTeamName(String roleClassName) {
+		int lastDollarIndex = roleClassName.lastIndexOf('$');
+		return roleClassName.substring(0, lastDollarIndex);
+	}
+	
+	/** 
+	 * @param className
+	 * @return
+	 */
+	private static String extractRoleName(String roleClassName) {
+		int lastDollarIndex = roleClassName.lastIndexOf('$');
+		return roleClassName.substring(lastDollarIndex+1, roleClassName.length());
+	}
+
+	/**
+	 * FIXME(SH): obsolete!
+	 * @param baseMethodReturnType
+	 * @param returnType
+	 * @return
+	 */
+//	private static boolean returnTypeCompatible(Type from, Type to) {
+//		System.out.println("test for " + from + "->" + to);
+//		if (from.equals(to))
+//			return true;
+//		if (from instanceof ObjectType && to instanceof ObjectType) {// how to handle compatible basic types??
+//			ObjectType otFrom = (ObjectType) from;
+//			ObjectType otTo = (ObjectType) to;
+//			if (otFrom.subclassOf(otTo))
+//				return true;	
+//		}
+//		return false;
+//	}
+
+	/**
+	 *	Copy all exception handlers of a method.
+	 *  @param source the method from where to copy
+	 *  @param dest the method where to copy to
+	 *  @param il instructions of `dest' which must still have the same positions
+	 *            as the instructions in `source'.
+	 *  @return an array of handler generators, which still has to be maintained,
+	 *     whenever instructions are replaced in the methods instruction list.
+	 */
+	static CodeExceptionGen[] copyExceptionHandlers(MethodGen source,
+											 MethodGen dest,
+											 InstructionList il) {
+		il.setPositions(); // needed to retrieve handles by position.
+		CodeExceptionGen[] excGens = source.getExceptionHandlers();
+		CodeExceptionGen[] newGens = new CodeExceptionGen[excGens.length];
+		if ((excGens != null) && excGens.length > 0) {
+			for (int hcount=0; hcount<excGens.length; hcount++) {
+				CodeExceptionGen excGen = excGens[hcount];
+				InstructionHandle excStart   = il.findHandle(excGen.getStartPC().getPosition());
+				InstructionHandle excEnd     = il.findHandle(excGen.getEndPC().getPosition());
+				InstructionHandle excHandler = il.findHandle(excGen.getHandlerPC().getPosition());
+				ObjectType catchType =  excGen.getCatchType();
+				newGens[hcount] =
+					dest.addExceptionHandler(excStart, excEnd, excHandler, catchType);
+			}
+		}
+		return newGens;
+	}
+
+	/**
+	 *  Update the positions of all exception handlers.
+	 *  @param handlers the handlers of this method.
+	 *  @param replaced a pair of InstructionHandles, the first is replaced by the second.
+	 */
+	static void updateHandlers (CodeExceptionGen[] handlers, IHPair replaced) {
+		InstructionHandle old = replaced.fst();
+		InstructionHandle neu = replaced.snd();
+		for (int i=0; i<handlers.length; i++) {
+            // System.out.println("handler "+handlers[i]);
+			if (handlers[i].containsTarget(old) && (old != neu)) {
+                // System.out.println("update "+old+"->"+neu);
+				handlers[i].updateTarget(old, neu);
+			}
+		}
+	}
+
+	/**
+	 * Delete a range of instructions, whithout throwing TargetLostException.
+	 * @param il the list to delete from
+	 * @param start handle to first instruction to delete.
+	 * @param end handle to last instruction to delete.
+	 * @param collect a set of InstructionHandle which are still targeted.
+	 */
+	static void safeDelete(InstructionList il,
+					InstructionHandle start, InstructionHandle end,
+					HashSet<InstructionHandle> collect)
+	{
+		try {
+			il.delete(start, end);
+		} catch(TargetLostException e) {
+			//	System.out.print("Loosing:"+e+" ");
+			InstructionHandle [] targets = e.getTargets();
+			for (int tcount = 0; tcount < targets.length; tcount++) {
+				collect.add(targets[tcount]);
+				// System.out.println(targets[tcount]+"!!");
+			}
+		}
+	}
+
+	/**
+	 *  Update all exceptions handlers with respect to all instructions that were replaced.
+	 *  Check that this covers all instruction handles in 'lost'.
+	 *  @param handles the exception handlers of this method.
+	 *  @param replacedList list of IHPairs describing what has been modified.
+	 *  @param lost set of instruction handles that were still referred to when
+	 *    they were deleted. All these handles should be updated.
+	 */
+	static void checkUpdate(CodeExceptionGen[] handlers, ArrayList<IHPair> replacedList, HashSet<InstructionHandle> lost) {
+        // System.out.println("Update "+replacedList+"/"+lost);
+		Iterator<IHPair> iter = replacedList.iterator();
+		while (iter.hasNext()) {
+			IHPair replaced = iter.next();
+			updateHandlers(handlers, replaced);
+			lost.remove(replaced.fst());
+		}
+		if (!lost.isEmpty()) {
+			System.err.println("Warning: "+lost.size()+" target(s) lost: ");
+			Iterator<InstructionHandle> it = lost.iterator();
+			while (it.hasNext())
+				System.out.println(it.next());
+		}
+	}
+
+	/**
+	 * While adding extra args to an activate call:
+	 * <ul>
+	 *   <li>Check whether an activationLevel was passed (single argument)
+	 *   <li>if so, insert the loading sequence for that expression.
+	 *   <li>also the return differs (void or int), should however be
+	 *      consistent between plain and enhanced version.
+	 *   <li>decrement "idx" so this team is the currently active in the chain.
+	 * </ul>
+	 * @param factory
+	 * @param cpg
+	 * @param loading sequence, which loads "level" argument, else null.
+	 * @param iv the invokevirtual for "activate", used to inspect the
+	 *   original signature.
+	 * @return the full sequence for loading the arguments, but not the
+	 *   call target (because that's the enclosing team and is kept
+	 *   unmodified in the original instruction list).
+	 */
+//    static InstructionList enhanceActivateCall (final InstructionFactory factory,
+//										 ConstantPoolGen cpg,
+//										 InstructionList loading,
+//										 INVOKEVIRTUAL iv) {
+//        InstructionList changedArea = new InstructionList();
+//
+//        // load arguments of the new method:
+//        int index = 1;
+//        Type[] enhancedArgumentTypes = enhanceArgumentTypes(iv.getArgumentTypes(cpg),
+//															0, false, false);
+//		Type returnType = Type.VOID;
+//		int kount = enhancedArgumentTypes.length;
+//		if (iv.getArgumentTypes(cpg).length == 1) {
+//			kount--; // "level" loaded separately via 'loading'
+//			returnType = Type.INT;
+//		}
+//
+//        for (int k=0; k<kount; k++) {
+//            changedArea.append(InstructionFactory.createLoad(enhancedArgumentTypes[k], index));
+//            index += enhancedArgumentTypes[k].getSize();
+//        }
+//		if (loading != null)
+//			changedArea.append(loading);
+//
+//        // invoke the overloaded activate method:
+//        changedArea.append(factory.createInvoke("org.objectteams.Team",
+//                                                "activate",
+//                                                returnType,
+//                                                enhancedArgumentTypes,
+//                                                Constants.INVOKEVIRTUAL));
+//
+//        // generate: idx--;
+//        changedArea.append(InstructionFactory.createLoad(Type.INT, IDX_ARG));
+//        changedArea.append(new ICONST(1));
+//        changedArea.append(new ISUB());
+//        changedArea.append(InstructionFactory.createStore(Type.INT, IDX_ARG));
+//        
+//        return changedArea;
+//    }
+
+	/**
+	 * Generates the instructions to call the enhanced version of the 'super' respectively 'tsuper'
+	 * call in a role method.
+	 * @param cpg						the constant pool
+	 * @param ii							the original invoke instruction
+	 * @param enhancedMethod	the enhanced role method
+	 * @param loading					the originally loaded arguments 
+	 * @return	the instruction list containing the method call ingredients							
+	 */
+	InstructionList genEnhancedSuperCall(ConstantPoolGen cpg, InvokeInstruction ii,
+										   MethodGen enhancedMethod, InstructionList loading)
+	{
+		Type returnType = enhancedMethod.getReturnType();
+		//Type[] argTypes = enhancedMethod.getArgumentTypes();
+		Type[] argTypes = enhanceArgumentTypes(ii.getArgumentTypes(cpg));
+		InstructionList il = new InstructionList();
+
+		il.append(InstructionFactory.createThis());
+		// load all additional arguments of the enhanced method (first EXTRA_ARGS):
+		int index = 1;
+		for (int i=0; i<EXTRA_ARGS; i++) {
+			il.append(InstructionFactory.createLoad(argTypes[i],index));
+			index += argTypes[i].getSize();
+		}
+		// load arguments of the originally call:
+		il.append(loading);
+
+		// call super.<enhancedMethod>:
+		short kind=0;
+		if (ii instanceof INVOKESPECIAL)
+			kind = Constants.INVOKESPECIAL;
+		else
+			kind = Constants.INVOKEVIRTUAL;
+
+		il.append(factory.createInvoke(ii.getClassName(cpg),
+													 	ii.getMethodName(cpg),
+												  	 	returnType,
+														argTypes,
+													 	kind));
+			return il;
+	}
+
+	/**
+	 * Generates the instructions to call the base call surrogate method.
+	 * @param cpg						the constant pool
+	 * @param iv							the original invoke instruction
+	 * @param enhancedMethod	the enhanced role method
+	 * @param loading					the originally loaded arguments 
+	 * @return	the instruction list containing the method call ingredients		
+	 */
+	InstructionList genBaseCallSurrogateCall(ConstantPoolGen cpg, InvokeInstruction/*INVOKEVIRTUAL*/ iv,
+											   MethodGen enhancedMethod, InstructionList loading, 
+											   String roleClassName, String calleeClassName) //JU: added String roleClassName and teamClassName to the method signature
+	{
+		int indexOffset = enhancedMethod.isStatic()?-1:0; // argument indexes are decremented for static methods, 
+																								// because of the missing 'this' 
+		// for static methods callee is 'null' -> substitute by current class (JU)
+		if(calleeClassName == null) {
+			calleeClassName = iv.getClassName(cpg);
+		}
+		
+		Type returnType = enhancedMethod.getReturnType();
+		//Type[] argTypes = enhancedMethod.getArgumentTypes();
+		Type[] argTypes = enhanceArgumentTypes(iv.getArgumentTypes(cpg));
+		InstructionList il = new InstructionList();
+
+		String methodName = getBaseCallSurrogateName(enhancedMethod.getName(), 
+													 enhancedMethod.isStatic(),
+													 roleClassName);
+		short invokeKind;
+				
+		if (!enhancedMethod.isStatic()) {
+			il.append(InstructionFactory.createThis());
+			invokeKind = Constants.INVOKEVIRTUAL;
+		
+		} else { // role method is static: 
+			invokeKind = Constants.INVOKESTATIC;
+		}
+			
+		// load all additional arguments of the enhanced method (first EXTRA_ARGS):
+		int index = 1;
+		for (int i = 0; i < argTypes.length; i++) {
+			if(i < EXTRA_ARGS){ // skip original arguments
+				il.append(InstructionFactory.createLoad(argTypes[i], index+indexOffset));
+			}
+			//calculate the next index
+			index += argTypes[i].getSize();
+		}
+		// load arguments of the originally call:
+		il.append(loading);
+			
+		// call _OT$<enhancedMethod>$base():
+		il.append(factory.createInvoke(calleeClassName,
+													 methodName,
+													 returnType,
+													 argTypes,
+													 invokeKind/*Constants.INVOKEVIRTUAL*/));
+		return il;
+	}
+ 
+ 		
+	/**
+	   * Checks, if a given instuction is a super or a tsuper call 
+	   * @param instr					the instruction to check
+	   * @param method_name	the name of the method from wich the 'inst' came
+	   * @param cpg					the constant pool
+	   * @return							true, if 'inst' is a super or tsuper call
+	   */
+	private static boolean super_or_tsuper_instruction(Instruction instr, String method_name, ConstantPoolGen cpg) {
+		if (isTSuperCall(instr, method_name, cpg))
+			return true;
+		if (isSuperCall(instr, method_name, cpg))
+			return true;
+		return false;
+	}   
+
+	private static boolean isTSuperCall(Instruction instr, String method_name, ConstantPoolGen cpg) {
+		if (instr instanceof INVOKEVIRTUAL) {
+			INVOKEVIRTUAL iv = (INVOKEVIRTUAL)instr;
+			String iv_name = iv.getName(cpg);
+			Type[] argTypes = iv.getArgumentTypes(cpg);
+			if (argTypes.length<1) // no tsuper marker interface parameter!
+				return false;
+			String lastArgument = (argTypes[argTypes.length-1]).toString();
+			if (iv_name.equals(method_name) && (lastArgument.indexOf(TSUPER_PREFIX)!=-1)) {
+				// if iv == <method_name>(..., TSuper__OT__<SuperTeamName>) -->
+                if(logging) printLogMessage("tsuper-call to " + iv_name + " has to be enhanced!");
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private static boolean isSuperCall(Instruction instr, String method_name, ConstantPoolGen cpg) {
+		if (instr instanceof INVOKESPECIAL) { 			
+			INVOKESPECIAL is = (INVOKESPECIAL)instr;
+			String is_name = is.getName(cpg);
+			
+			if(is_name.equals(method_name)) {
+               if(logging) printLogMessage("super-call to " + is_name + " has to be enhanced!");
+			   return true;
+			}
+		}
+		return false;
+	}
+	  
+   /**
+	* Generates the base call surrogate name for a given method name.
+	* @param	method_name the name of the role method
+	* @param	staticFlag 
+	* @param	roleClassName the name of the role method
+	* @return	the base call surrogate name
+	*/
+	private static String getBaseCallSurrogateName(String method_name, boolean staticFlag, String roleClassName) {
+		//JU: for static methods the role class name should be inserted 
+		if(staticFlag) {
+			return OT_PREFIX+roleClassName+"$"+method_name+"$base";
+		}
+		return OT_PREFIX+method_name+"$base";
+	}
+		
+   /**
+	* Reverts a method name to its original by returning the substring after the last '$'
+	* until the end.  
+	* @param	method_name method name to be adjusted
+	* @return	the original method name
+	*/
+	private static String revertToOriginalName(String method_name) {
+		int p = method_name.lastIndexOf('$');
+		return method_name.substring(p + 1);
+	}
+
+/*
+ * (non-Javadoc)
+ * 
+ * @see org.eclipse.objectteams.otre.common.ObjectTeamsTransformation#doTransformCode(de.fub.bytecode.generic.ClassGen)
+ */
+    public void doTransformCode(ClassGen cg) {
+        // nothing to do
+    }
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java
new file mode 100644
index 0000000..06878cb
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java
@@ -0,0 +1,1861 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: BaseMethodTransformation.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import static org.eclipse.objectteams.otre.StaticSliceBaseTransformation._OT_ACTIVE_TEAMS;
+import static org.eclipse.objectteams.otre.StaticSliceBaseTransformation._OT_ACTIVE_TEAM_IDS;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Map.Entry;
+
+import org.eclipse.objectteams.otre.util.CallinBindingManager;
+import org.eclipse.objectteams.otre.util.DebugUtil;
+import org.eclipse.objectteams.otre.util.ListValueHashMap;
+import org.eclipse.objectteams.otre.util.MethodBinding;
+import org.eclipse.objectteams.otre.util.TeamIdDispenser;
+
+import de.fub.bytecode.Constants;
+import de.fub.bytecode.classfile.Field;
+import de.fub.bytecode.classfile.LineNumber;
+import de.fub.bytecode.classfile.LineNumberTable;
+import de.fub.bytecode.classfile.Method;
+import de.fub.bytecode.generic.AASTORE;
+import de.fub.bytecode.generic.ACONST_NULL;
+import de.fub.bytecode.generic.ALOAD;
+import de.fub.bytecode.generic.ANEWARRAY;
+import de.fub.bytecode.generic.ARRAYLENGTH;
+import de.fub.bytecode.generic.ATHROW;
+import de.fub.bytecode.generic.ArrayType;
+import de.fub.bytecode.generic.BasicType;
+import de.fub.bytecode.generic.BranchInstruction;
+import de.fub.bytecode.generic.ClassGen;
+import de.fub.bytecode.generic.ConstantPoolGen;
+import de.fub.bytecode.generic.DUP;
+import de.fub.bytecode.generic.DUP_X1;
+import de.fub.bytecode.generic.FieldGen;
+import de.fub.bytecode.generic.GOTO;
+import de.fub.bytecode.generic.IADD;
+import de.fub.bytecode.generic.ICONST;
+
+import de.fub.bytecode.generic.IFNE;
+import de.fub.bytecode.generic.IFNONNULL;
+import de.fub.bytecode.generic.IF_ICMPLT;
+import de.fub.bytecode.generic.IINC;
+import de.fub.bytecode.generic.INVOKESPECIAL;
+import de.fub.bytecode.generic.Instruction;
+import de.fub.bytecode.generic.InstructionConstants;
+import de.fub.bytecode.generic.InstructionFactory;
+import de.fub.bytecode.generic.InstructionHandle;
+import de.fub.bytecode.generic.InstructionList;
+import de.fub.bytecode.generic.InvokeInstruction;
+import de.fub.bytecode.generic.LDC;
+import de.fub.bytecode.generic.LocalVariableGen;
+import de.fub.bytecode.generic.MONITOREXIT;
+import de.fub.bytecode.generic.MethodGen;
+import de.fub.bytecode.generic.NOP;
+import de.fub.bytecode.generic.ObjectType;
+import de.fub.bytecode.generic.POP;
+import de.fub.bytecode.generic.PUSH;
+import de.fub.bytecode.generic.TABLESWITCH;
+import de.fub.bytecode.generic.Type;
+
+
+/**
+ * Insert dispatch code into base methods affected by callin bindings. <p>
+ * If a loaded class contains binding declarations (transmitted by attributes)
+ * these are stored for further determination of necessity for base-method-transforming.
+ * Classes for which a callin binding exists will be transformed:
+ * (base-class)methods <i>m()</i> which are changed by a callin will be copied to
+ * <tt>_OT$<i>m</i>$orig()</tt>.
+ * Hereafter the original method <i>m()</i> will be transformend depending on the
+ * callin-modifier:
+ * <ul>
+ *  <li> replace: only the (role-)callin-method is called
+ *  <li> after: first the original-method <tt>_OT$<i>m</i>$orig()</tt> is called and
+ *       then the callin-method
+ *  <li> before: first the the callin-method is called and then original-method
+ *       <tt>_OT$<i>m</i>$orig()</tt>
+ * </ul>
+ *
+ * @version $Id: BaseMethodTransformation.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author Christine Hundt
+ * @author Stephan Herrmann
+ */
+
+public class BaseMethodTransformation
+	extends ObjectTeamsTransformation
+{
+	// configurability for stepping behavior of the chaining wrapper:
+	private static boolean SHOW_ORIG_CALL 		= true;
+	private static boolean SHOW_RECURSIVE_CALL	= true;
+	private static boolean SHOW_ROLE_CALL		= true;
+	static {
+		String callinStepping = System.getProperty("ot.debug.callin.stepping");
+		if (callinStepping != null) {
+			SHOW_ORIG_CALL = SHOW_RECURSIVE_CALL = SHOW_ROLE_CALL = false;
+			StringTokenizer tokens = new StringTokenizer(callinStepping, ",");
+			while (tokens.hasMoreTokens()) {
+				String token = tokens.nextToken();
+				if ("orig".equals(token))
+					SHOW_ORIG_CALL = true;
+				else if ("recurse".equals(token))
+					SHOW_RECURSIVE_CALL = true;
+				else if ("role".equals(token))
+					SHOW_ROLE_CALL = true;
+			}
+		}
+	}
+
+	// method of o.o.Team:
+    private static final String IS_ACTIVE = "isActive";  //$NON-NLS-1$
+
+	private final static int NORESULT = -1;
+
+	// FIXME(SH): once we remove JMangler support, these maps can be reduced to their RHS because then we'll consistently have one transformer per class:
+    private HashMap /* class_name -> HashSet(method_name) */<String, HashSet<String>> transformableMethods = new HashMap<String, HashSet<String>>();
+    private HashMap /* class_name -> HashSet(method_name) */<String, HashSet<String>> overridableMethods = new HashMap<String, HashSet<String>>();
+
+	public boolean useReflection = false;
+	
+	public BaseMethodTransformation(SharedState state) {
+		this(null, state);
+	}
+
+	public BaseMethodTransformation(ClassLoader loader, SharedState state) {
+		super(loader, state);
+	}
+	/**
+	 *  The code transformer only replaces the original code with
+	 *  the initial wrapper.
+	 */
+    public void doTransformCode(ClassGen cg) {
+    	factory = new InstructionFactory(cg);
+    	ConstantPoolGen cpg        = cg.getConstantPool();
+    	String          class_name = cg.getClassName();
+			
+    	Method[] methods = cg.getMethods();
+    	for (int i=0; i<methods.length; i++) {
+    		Method m           = methods[i];
+    		//if (m.isNative())
+    		//	continue;
+    		if (m.isVolatile())
+    			continue; // don't touch bridge methods
+    		
+    		String method_name = m.getName();
+				
+    		if (CallinBindingManager.isBoundBaseClass(class_name) 
+    				&& !CallinBindingManager.hasBoundBaseParent(class_name) 
+    				&& method_name.equals(Constants.CONSTRUCTOR_NAME)) 
+    		{
+    			addToConstructor(m, getInitializedRoleSet(cg.getClassName(), false), cg, cpg);
+    			continue;
+    		}
+			                
+    		String method_signature = m.getSignature();
+
+    		if (state.interfaceTransformedClasses.contains(class_name)) {
+    			HashSet<String> transformable = transformableMethods.get(class_name);
+    			HashSet<String> overridable = overridableMethods.get(class_name);
+    			if (transformable.contains(method_name + '.' + method_signature))
+    				cg.replaceMethod(m, m = generateInitialWrapper(m, class_name, cg.getMajor(), cpg));
+    			else if (overridable.contains(method_name + '.' + method_signature))
+    				cg.replaceMethod(m, m = generateSuperCall(m, cg, cpg));
+    			
+    			Method replacement = checkReplaceWickedSuper(class_name, m, cpg);
+    			if (replacement != null)
+    				cg.replaceMethod(m, replacement);
+    		}
+    	}
+    }
+
+    /*
+     * If a base method m1 has a super-call super.m2() and if that method m2 is callin-bound
+     * we currently bypass aspect dispatch to avoid infinite recursions.
+     */
+	private Method checkReplaceWickedSuper(String className, Method m, ConstantPoolGen cpg)
+	{
+        if (m.isAbstract() || m.isNative())
+            return null;
+		MethodGen mg = new MethodGen(m, className, cpg);
+		String method_name = m.getName();
+		InstructionHandle[] ihs = mg.getInstructionList().getInstructionHandles();
+		boolean found = false;
+		for (InstructionHandle ih : ihs) {
+			if (ih.getInstruction() instanceof INVOKESPECIAL) { 			
+				Instruction actInstruction = ih.getInstruction();
+				INVOKESPECIAL is = (INVOKESPECIAL)actInstruction;
+				String is_name = is.getName(cpg);
+				if (   !is_name.equals(method_name) 							// not same method
+					&& !is_name.equals("<init>"))    							// not ctor call
+				{ 
+					String superClassName = is.getClassName(cpg);
+					if (   !superClassName.equals(className)					// not private method of same class
+						&& CallinBindingManager.isBoundBaseMethod( 				// target method is callin-affected
+													superClassName,	
+													is_name, 
+													is.getSignature(cpg)))
+					{					
+						found = true;
+	                    if(logging) printLogMessage("wicked super-call to " + is_name //$NON-NLS-1$
+	                            + " has to be redirected to the orig-version!"); //$NON-NLS-1$
+						ih.setInstruction(factory.createInvoke(superClassName, 
+															   "_OT$"+is_name+"$orig",
+															   is.getReturnType(cpg),
+															   is.getArgumentTypes(cpg),
+															   Constants.INVOKESPECIAL)); 
+					}
+				}
+			}
+		}
+		if (found) 
+			return mg.getMethod();
+		return null;
+ 	}
+
+	/**
+	 * Main entry for this transformer.
+	 */
+    public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
+    	String class_name = cg.getClassName();
+    	//SourceMapGeneration sourceMapGen = new SourceMapGeneration(cg);
+
+    	ConstantPoolGen cpg = cg.getConstantPool();
+    	factory = new InstructionFactory(cg);
+    	if (CallinBindingManager.isBoundBaseClass(class_name) && !cg.isInterface())  {
+    		// TODO: where to add the role set infrastructure, if only an interface is bound? Implementing classes?
+    		if (cg.containsField(OTConstants.ROLE_SET) == null && !CallinBindingManager.hasBoundBaseParent(class_name)) {
+    			ce.addField(generateRoleSet(cpg, class_name), cg);
+    			ce.addMethod(generateAddRole(cpg, class_name), cg);
+    			ce.addMethod(generateRemoveRole(cpg, class_name), cg);
+    			ce.addImplements(OTConstants.IBOUND_BASE, cg);
+    		}
+    	}
+
+    	HashSet<String> transformedMethods = transformableMethods.get(class_name);
+    	if (transformedMethods == null) {
+    		transformedMethods = new HashSet<String>();
+    		transformableMethods.put(class_name, transformedMethods);
+    	}
+    	HashSet<String> renamedMethods = overridableMethods.get(class_name);
+    	if (renamedMethods == null) {
+    		renamedMethods = new HashSet<String>();
+    		overridableMethods.put(class_name, renamedMethods);
+    	}
+
+    	checkReadClassAttributes(ce, cg, class_name, cpg);
+		
+    	//JU: change the class modifier to 'public' if decapsulation required
+    	if(CallinBindingManager.checkBaseClassModifierChange(class_name) && !cg.isPublic()) {
+    		cg.setAccessFlags(makePublicFlags(cg.getAccessFlags()));
+    	}
+    	
+    	Collection<MethodBinding> inheritedBindings = CallinBindingManager.getInheritedCallinBindings(class_name);
+    	
+//		if (inheritedSigns!=null && !inheritedSigns.isEmpty()) {
+//			Iterator itx = inheritedSigns.iterator();
+//			while (itx.hasNext()) {
+//				System.err.print(class_name+" : ");
+//				String[] next = (String[])itx.next();
+//				System.err.println(next[0] +" " +next[1]) ;
+//			}
+//		}
+    	/*
+    	 String[] interfaceNames = cg.getInterfaceNames();
+    	 Collection interfaceInheritedSigns  = new LinkedList();
+    	 //System.err.println("searching inherited bindings for: "+class_name);
+    	  for (int i=0; i<interfaceNames.length;i++) {
+    	  		if (!interfaceNames[i].equals(class_name))
+    	  			interfaceInheritedSigns.addAll(CallinBindingManager.getInterfaceInheritedCallinBindings(interfaceNames[i]));
+          }*/
+		/*
+		 if (!interfaceInheritedSigns.isEmpty()) {
+		 	System.err.println("BMT: searching inherited bindings for: "+class_name);
+		 		for (Iterator iterator = interfaceInheritedSigns.iterator(); iterator.hasNext();) {
+		 			String[] element = (String[]) iterator.next();
+		 			System.err.println(element[0]+element[1]);
+		        }
+		 }*/
+		//inheritedSigns.addAll(interfaceInheritedSigns);
+			
+    	boolean haveDirectCallin =
+    		CallinBindingManager.isBoundBaseClass(class_name);
+		// IMPLICIT_INHERITANCE
+    	if (inheritedBindings.size() == 0 && !haveDirectCallin /*&& interfaceInheritedSigns.size()==0*/) {
+            if(logging) printLogMessage("\nCallins: nothing to do for class " + class_name); //$NON-NLS-1$
+    		return; // nothing to do
+    	}
+    	// if class is already transformed by this transformer
+    	/*
+    	 if (interfaceTransformedClasses.contains(class_name))
+    	 	continue;
+		*/
+			
+    	if(cg.isInterface()) {
+    		//CallinBindingManager.addBoundBaseInterface(class_name); // <- this is to late, implementing class may be loaded before!!
+    		return; // No transfomations neccessary for interfaces.
+    	}
+			
+        if(logging) printLogMessage("\nCallin bindings may be changing class " //$NON-NLS-1$
+    				+ class_name + ':');
+
+        // A field to optimize class-literal in initial wrapper:
+		if (cg.getMajor() < 49) {// pre 1.5?
+			if (cg.containsField(OTConstants.SELF_CLASS) == null)
+				ce.addField(new FieldGen(Constants.ACC_PROTECTED|Constants.ACC_STATIC, 
+	                           			 classType, 
+	                           			 OTConstants.SELF_CLASS,
+	                           			 cpg)
+								.getField(),
+	                        cg);
+		}
+    	
+    	Method[] methods = cg.getMethods();
+    	for (int i=0; i<methods.length; i++) {
+    		Method m           = methods[i];
+    		if (m.isVolatile()) // bridge method!
+    			continue;
+    		String method_name = m.getName();
+    		String method_signature = m.getSignature();
+    		
+    		Collection<MethodBinding> bindingsForMethod = null;
+    		// IMPLICIT_INHERITANCE
+    		if (haveDirectCallin)
+    			bindingsForMethod = CallinBindingManager .
+    			getBindingForBaseMethod(class_name, method_name, m.getSignature());
+    		
+    		//JU: added the following statement to determine overridden static base methods
+    		//Collection inheritedCallinBindings = CallinBindingManager.getInheritedCallinBindings(class_name);
+    		//CH: removed it again, because it is the same as 'inheritedSigns'!
+    		
+    		MethodGen mg = null;
+    		int firstLine = STEP_OVER_LINENUMBER;
+    		String original_signature = method_signature;
+    		/*if (bindingsForMethod != null || containsSign(inheritedSigns, m)*/ /*|| containsSign(interfaceInheritedSigns, m)*/ //) {
+    		MethodBinding match= matchingBinding(inheritedBindings, m, false);
+    		if (bindingsForMethod != null || (match!= null && !m.isStatic() && !m.isPrivate())) {
+    			
+    			mg = new MethodGen(m, class_name, cpg);
+    			Method orig_method;
+					
+    			String name_orig = genOrigMethName(method_name);
+    			if (cg.containsMethod(name_orig, m.getSignature())!=null) {
+    				continue;// method was already copied to orig-version!
+    			}
+				
+    			if (debugging)
+    				firstLine = findFirstLineNumber(m);
+    			
+    			mg.setName(name_orig);
+					
+				// TODO(SH): store this match, or keep previous?
+    			if (matchingBinding(inheritedBindings, m, true) != null) // this method was adapted in a super class 
+    				replaceSuperCalls(mg, method_name, cpg);
+					
+    			orig_method = mg.getMethod();
+    			ce.addMethod(orig_method, cg);
+                if(logging) printLogMessage("Method " + method_name + " was backuped as " //$NON-NLS-1$ //$NON-NLS-2$
+    						+ name_orig + '.');
+
+                if (match == null || method_signature.equals(match.getBaseMethodSignature()))
+                	renamedMethods.add(method_name+'.'+method_signature);
+                else // override with covariant return: at the VM-level this is a *new* method.
+                	transformedMethods.add(method_name+'.'+method_signature);
+    		}
+
+    		/*if (bindingsForMethod != null || (containsSign(inheritedSigns,m) && m.isStatic())*/ /*|| containsSign(interfaceInheritedSigns, m)*/ //) {
+    		//CH: changed 'inheritedCallinBindings' to 'inheritedSigns', because it was the same.
+    		if (bindingsForMethod != null) { 
+    			//add method '_OT$<method_name>$chain' :
+    			Method chain;
+    			mg = getConcretMethodGen(m, class_name, cpg);
+    			chain = generateChainingWrapper(mg, method_name,
+    									original_signature/*method_signature*/, class_name, cpg, cg, firstLine);
+													
+    			if (cg.containsMethod(chain.getName(), chain.getSignature()) == null)
+    				ce.addMethod(chain, cg);
+
+    			transformedMethods.add(method_name + '.' + method_signature);
+    		}
+    		if (mg == null)
+                if (logging) printLogMessage("No method binding (direct or inherited) found for " //$NON-NLS-1$
+                            + method_name);
+    	}
+    	state.interfaceTransformedClasses.add(class_name);
+    }
+    
+    private int findFirstLineNumber(Method m) {
+		LineNumberTable lnt = m.getLineNumberTable();
+		if (lnt != null && lnt.getTableLength() > 0) {
+			LineNumber[] lineNumberTable = lnt.getLineNumberTable();
+			for (int i=0; i<lineNumberTable.length; i++) {
+				int lineNumber = lineNumberTable[i].getLineNumber();
+				if (lineNumber != OTConstants.STEP_OVER_LINENUMBER)
+					return lineNumber;
+			}
+			return lineNumberTable[0].getLineNumber();
+		}
+		return STEP_OVER_LINENUMBER; // make it a valid line number
+	}
+
+	/**
+	 * "super"-calls in callin bound base methods have to be redirected to the _OT$...$orig version, if the
+	 * super-method is bound (and thus renamed to _OT$..$orig) too.
+	 *
+	 * @param orig_method	the copied method
+	 * @param method_name	the prior name of the copied method
+	 * @param cpg			the corresponding constang pool	
+	 */
+	private void replaceSuperCalls(MethodGen orig_method, String method_name, ConstantPoolGen cpg) {
+		// search for super calls:
+		InstructionList il = orig_method.getInstructionList();
+		InstructionHandle[] ihs = il.getInstructionHandles();
+		int actInstrIndex = 0;
+		while (actInstrIndex < ihs.length) {
+			if (ihs[actInstrIndex].getInstruction() instanceof INVOKESPECIAL) { 			
+				Instruction actInstruction = ihs[actInstrIndex].getInstruction();
+				INVOKESPECIAL is = (INVOKESPECIAL)actInstruction;
+				String is_name = is.getName(cpg);
+				if(is_name.equals(method_name)) {
+					String superClassName = is.getClassName(cpg);
+                    if(logging) printLogMessage("super-call to " + is_name //$NON-NLS-1$
+                            + " has to be redirected to the orig-version!"); //$NON-NLS-1$
+					// generate and set an instruction calling the orig-version of the super method:
+					InvokeInstruction superOrigCall = factory.createInvoke(superClassName, 
+																		   orig_method.getName(),
+																		   orig_method.getReturnType(),
+																		   orig_method.getArgumentTypes(),
+																		   Constants.INVOKESPECIAL);
+					ihs[actInstrIndex].setInstruction(superOrigCall); 
+				}
+			}
+			actInstrIndex++;
+		}
+		// redirect them ( change called method name to  _OT$..$orig ) if super-method has been renamed:
+		// --> 
+	}
+
+	/**
+	 *  Is method `m' contained in `baseMethodBindings'?
+	 *  @param nameSigns list of MethodBinding
+	 *  @param m
+     *  @param strict if true covariance must not be considered
+     *  @return the matching binding from baseMethodBindings or null.
+	 */
+	static MethodBinding matchingBinding (Collection<MethodBinding> baseMethodBindings, Method m, boolean strict) 
+	{
+		for (MethodBinding binding: baseMethodBindings) 
+			if (binding.matchesMethod(m.getName(), m.getSignature(), strict)) 
+				return binding;
+
+		return null;
+	}
+
+	/**
+	 *  Get a MethodGen for `m'.
+	 *  If `m' is abstract setup a new concrete method.
+	 */
+	static MethodGen getConcretMethodGen (Method m, String class_name, ConstantPoolGen cpg) {
+		MethodGen mg;
+		String signature   = m.getSignature();
+		Type[] argTypes    = Type.getArgumentTypes(signature);
+		if (m.isAbstract()) {
+			Type   returnType  = Type.getReturnType(signature);
+			InstructionList il = new InstructionList();
+			il.append(new NOP());
+			mg = new MethodGen(m.getAccessFlags()&~Constants.ACC_ABSTRACT,
+							   returnType, argTypes,
+							   null, // names are unknown
+							   m.getName(), class_name,
+							   il, cpg);
+		} else {
+            mg = wipeMethod(m, class_name, cpg);
+		}
+		if (debugging) {
+			mg.removeLocalVariables();
+			mg.removeLocalVariableTypes();
+			int slot = 0;
+			// create local variable table for "this" and arguments:
+			if (!m.isAbstract())
+				mg.addLocalVariable("this", new ObjectType(class_name),	slot++, null, null);
+			for (int i=0; i<argTypes.length; i++)
+				mg.addLocalVariable("arg"+i, argTypes[i], slot++, null, null);
+			mg.setMaxLocals();
+		}
+		return mg;
+	}
+
+    /**
+     * Generate the initial wrapper for the passed mehtod. 
+     * It binds callin dispatch to Team-unaware client code.
+     * @param m						the original method	
+     * @param class_name	the name of the appropriate class
+     * @param major 
+     * @param cpg					the ConstantPoolGen of the class
+     * @return							the generated method
+     */
+    private Method generateInitialWrapper(Method          m,
+										  String          class_name,
+										  int             major, 
+										  ConstantPoolGen cpg)
+	{
+        MethodGen mg = getConcretMethodGen(m, class_name, cpg);
+
+        String  method_name     = m.getName();
+        Type    returnType      = mg.getReturnType();
+        Type    chainReturnType = object;
+        Type[]  argTypes        = mg.getArgumentTypes();
+
+        String  name_chain      = genChainMethName(method_name);
+
+        InstructionList il      = mg.getInstructionList();
+
+        InstructionHandle startSynchronized;
+        InstructionHandle chainCall; 
+        int monitor;
+		// start generating
+		{
+		    LocalVariableGen lg; // used for several local variables
+		    
+		    // Team[] _OT$teams;
+		    int teams;
+		    lg = mg.addLocalVariable(TEAMS, teamArray, null, null);
+		    teams = lg.getIndex();
+		    
+		    // synchronized (TopMostBoundBaseClass.class) {
+		    Pair<Integer,InstructionHandle> monitorResult = addClassMonitorEnter(mg, il, CallinBindingManager.getTopmostBoundBase(class_name), major, cpg);
+		    monitor = monitorResult.first;
+		    if (debugging)
+		    	// no natural lines in this method: step-over until chain call, which has step-into: debugging => addLineNumber
+		    	mg.addLineNumber(monitorResult.second, STEP_OVER_LINENUMBER);
+
+		    // _OT$teams= new Teams[_OT$activeTeams.length];
+		    startSynchronized= // begin area protected by exception handler
+		    il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		    il.append(InstructionConstants.ARRAYLENGTH);
+		    il.append((Instruction)factory.createNewArray(teamType, (short) 1));
+		    il.append(InstructionFactory.createStore(Type.OBJECT, teams));
+
+		    // _OT$teamIDs=new int[_OT$activeTeamIDs.length];
+		    int teamIDs;
+		    lg = mg.addLocalVariable(TEAMIDS, intArray, null, null);
+		    teamIDs = lg.getIndex();
+		    il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
+		    il.append(InstructionConstants.ARRAYLENGTH);
+		    il.append((Instruction)factory.createNewArray(Type.INT, (short) 1));
+		    il.append(InstructionFactory.createStore(Type.OBJECT, teamIDs));
+		    
+		    // for (int i=0; i<_OT$activeTeams.length; ...
+		    int for_index;
+		    lg = mg.addLocalVariable("i", Type.INT, null, null); //$NON-NLS-1$
+		    for_index = lg.getIndex();
+		    il.append(new PUSH(cpg, 0));
+		    il.append(InstructionFactory.createStore(Type.INT, for_index));
+		  InstructionHandle for_start = 
+			il.append(InstructionFactory.createLoad(Type.INT, for_index));
+		    il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		    il.append(InstructionConstants.ARRAYLENGTH);
+		  BranchInstruction if_loop_finished = 
+			          InstructionFactory.createBranchInstruction(Constants.IF_ICMPGE, null);
+		    il.append(if_loop_finished);
+    
+		    	// if (!_OT$activeTeams[i].isActive()) {
+			    il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+			    il.append(InstructionFactory.createLoad(Type.INT, for_index));
+			    il.append(InstructionConstants.AALOAD);
+			    il.append(factory.createInvoke(OTConstants.teamName, IS_ACTIVE, Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEINTERFACE));
+			  BranchInstruction if_team_isactive = 
+				  		  InstructionFactory.createBranchInstruction(Constants.IFNE, null);
+			    il.append(if_team_isactive);
+	
+				    // invalidate activation of current team:
+			    	// _OT$teams[i]= null;
+				    il.append(InstructionFactory.createLoad(Type.OBJECT, teams));
+				    il.append(InstructionFactory.createLoad(Type.INT, for_index));
+				    il.append(InstructionConstants.ACONST_NULL);
+				    il.append(InstructionConstants.AASTORE);
+		
+				    // _OT$teamIDs[i]= -1;
+				    il.append(InstructionFactory.createLoad(Type.OBJECT, teamIDs));
+				    il.append(InstructionFactory.createLoad(Type.INT, for_index));
+				    il.append(new PUSH(cpg, -1));
+				    il.append(InstructionConstants.IASTORE);
+				  BranchInstruction goto_continue = 
+					          InstructionFactory.createBranchInstruction(Constants.GOTO, null);
+				    il.append(goto_continue);
+				    
+				// } else { adopt activation of current team:
+				// _OT$teams[i]= _OT$activeTeams[i];
+			  InstructionHandle adopt_activation = 
+			    il.append(InstructionFactory.createLoad(Type.OBJECT, teams));
+			    il.append(InstructionFactory.createLoad(Type.INT, for_index));
+			    il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+			    il.append(InstructionFactory.createLoad(Type.INT, for_index));
+			    il.append(InstructionConstants.AALOAD);
+			    il.append(InstructionConstants.AASTORE);
+	
+				// _OT$teamIDs[i]= _OT$activeTeamIDs[i];
+			    il.append(InstructionFactory.createLoad(Type.OBJECT, teamIDs));
+			    il.append(InstructionFactory.createLoad(Type.INT, for_index));
+			    il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
+			    il.append(InstructionFactory.createLoad(Type.INT, for_index));
+			    il.append(InstructionConstants.IALOAD);
+			    il.append(InstructionConstants.IASTORE);
+
+		    // closing the above for: i++ and jump back:
+		  InstructionHandle do_continue = 
+			il.append(new IINC(for_index, 1));
+		    il.append(InstructionFactory.createBranchInstruction(Constants.GOTO, for_start));
+
+		    // link jump instructions to their targets:
+		    InstructionHandle loop_finished = il.append(new NOP()); // synthetic jump target
+		    if_loop_finished.setTarget(loop_finished);
+		    if_team_isactive.setTarget(adopt_activation);
+		    goto_continue.setTarget(do_continue);
+		
+		    // No more access to array fields, release monitor:
+		    il.append(InstructionFactory.createLoad(Type.OBJECT, monitor));
+		    il.append(new MONITOREXIT());
+		    
+			// load special arguments:
+			if(!m.isStatic()) { // "this" cannot be accessed by static methods 
+				chainCall= il.append(InstructionFactory.createThis());                  // this
+			} else {
+				chainCall= il.append(new NOP());
+			}
+			
+			if (debugging)
+				mg.addLineNumber(chainCall, STEP_INTO_LINENUMBER);
+			// ih now points to end of area protected by exception handler 
+			
+			il.append(InstructionFactory.createLoad(teamArray, teams));  // _OT$teams
+			il.append(InstructionFactory.createLoad(intArray, teamIDs)); // _OT$teamIDs
+			il.append(new ICONST(0));                         // _OT$idx = 0
+			il.append(new ICONST(0));							// _OT$bindIdx = 0
+            il.append(new ICONST(-1));                        // _OT$baseMethTag is unused here
+			il.append(new ACONST_NULL());                     // _OT$unusedArgs = null
+		}
+		
+		
+        // load regular arguments:
+        int index = m.isStatic()?0:1;
+        // chaining wrapper is always public, so never user INVOKESPECIAL:
+        short invocationKind = m.isStatic()?Constants.INVOKESTATIC:Constants.INVOKEVIRTUAL;
+		
+        for (int i=0; i<argTypes.length; i++) {
+            il.append(InstructionFactory.createLoad(argTypes[i],index));
+            index += argTypes[i].getSize();
+        }
+		//
+        il.append(factory.createInvoke(class_name, name_chain,
+									   chainReturnType,
+									   enhanceArgumentTypes(argTypes),
+									   invocationKind));
+		// generated invoke: _OT$<method_name>$chain (a1,.. aN)
+
+        
+		adjustValue(il, null, chainReturnType, returnType);
+        il.append(InstructionFactory.createReturn(returnType));
+        
+        // handler for exception within synchronized:
+        LocalVariableGen ex= mg.addLocalVariable("exceptionInSynchronized", Type.THROWABLE, il.getEnd(), null); //$NON-NLS-1$
+        InstructionHandle handler=
+        il.append(InstructionFactory.createStore(Type.THROWABLE, ex.getIndex()));
+        il.append(InstructionFactory.createLoad(Type.OBJECT, monitor));
+        il.append(new MONITOREXIT());
+        il.append(InstructionFactory.createLoad(Type.THROWABLE, ex.getIndex()));
+        il.append(new ATHROW());
+        mg.addExceptionHandler(startSynchronized, chainCall, handler, Type.THROWABLE);
+        
+		// tidy:
+        mg.setMaxStack();
+        mg.setMaxLocals();
+        Method generatedMethod = mg.getMethod();
+        il.dispose();
+        return generatedMethod;
+    }
+
+	/**
+	 * Generate a version of the passed method which only calls its super method 
+	 * (which will eventually call an initial-wrapper in a directly bound class).
+	 * @param m		the original method
+	 * @param cg	the ClassGen of the appropriate class
+	 * @param cpg the ConstantPoolGen of the class
+	 * @return			the generated method
+	 */
+	Method generateSuperCall (Method          m,
+							  ClassGen        cg,
+							  ConstantPoolGen cpg)
+	{
+		short invocationKind = m.isStatic() ? Constants.INVOKESTATIC : Constants.INVOKESPECIAL;
+        MethodGen mg = getConcretMethodGen(m, cg.getClassName(), cpg);
+
+        String  method_name     = m.getName();
+        Type    returnType      = mg.getReturnType();
+        Type[]  argTypes        = mg.getArgumentTypes();
+        InstructionList il      = mg.getInstructionList();
+
+        if(logging) printLogMessage("\nReplacing with call to super: " + method_name); //$NON-NLS-1$
+		// start generating
+		if(!m.isStatic()){ //JU
+			il.append(InstructionFactory.createThis());
+		} 
+        int index = 1;
+        for (int i=0; i<argTypes.length; i++) {
+            il.append(InstructionFactory.createLoad(argTypes[i],index));
+            index += argTypes[i].getSize();
+        }
+        il.append(factory.createInvoke(cg.getSuperclassName(), method_name,
+									   returnType, argTypes,
+									   invocationKind));
+        il.append(InstructionFactory.createReturn(returnType));
+		// generated invoke: return super.<method_name> (a1,.. aN)
+
+		// tidy:
+        mg.setMaxStack();
+        mg.setMaxLocals();
+        Method generatedMethod = mg.getMethod();
+        il.dispose();
+        return generatedMethod;
+	}
+
+	
+	/**
+	 * Generate a chaining wrapper for the original method described by the passed arguments. 
+	 * This includes dispatch code and the termination condition for the recursion.
+	 * @param mg								the MethodGen of the original method
+	 * @param method_name			the name of the original method
+	 * @param method_signature	the signature of the original method
+	 * @param class_name				the name of the appropriate class
+	 * @param cpg								the ConstantPoolGen of the class
+	 * @param cg								the ClassGen of the class
+	 * @param firstLine							the first real source line of this method
+	 * @return
+	 */
+	Method generateChainingWrapper(MethodGen 		mg,
+								   String 	 		method_name,
+								   String 	 		method_signature,
+								   String 	 		class_name, 
+								   ConstantPoolGen 	cpg, 
+								   ClassGen  		cg,
+								   int 		 		firstLine)
+    {
+        Type     origReturnType        = mg.getReturnType();
+        Type[]   argumentTypes         = mg.getArgumentTypes();
+        String[] argumentNames         = mg.getArgumentNames();
+        Type[]   enhancedArgumentTypes = enhanceArgumentTypes(argumentTypes);
+        String[] enhancedArgumentNames = enhanceArgumentNames(argumentNames);
+        Type enhancedReturnType = object;  // ALWAYS!
+
+        InstructionList il = new InstructionList();
+
+        // the chaining wrapper has to be 'public' because it will be called by base calls:
+        int accessFlags = makePublicFlags(mg.getAccessFlags());
+        
+        MethodGen chainMethod = new MethodGen(accessFlags,
+                                              enhancedReturnType,
+                                              enhancedArgumentTypes,
+                                              enhancedArgumentNames,
+                                              genChainMethName(method_name),
+                                              class_name,
+                                              il, cpg);
+
+		// All chaining calls return an Object.
+		// Need to store this in a local variable to keep the stack
+		// balanced, because each section (before, replace, after)
+		// is guarded by its own exception handler, and they don't
+		// like pending objects on the stack.
+        InstructionHandle ih;
+        int result, ot_team;
+		{
+			LocalVariableGen lg =
+				chainMethod.addLocalVariable("_OT$result", enhancedReturnType, //$NON-NLS-1$
+											 null, null);
+			result = lg.getIndex();
+			ih = il.append(InstructionFactory.createNull(enhancedReturnType));
+			if (debugging)
+				chainMethod.addLineNumber(ih, STEP_OVER_LINENUMBER);
+			lg.setStart(il.append(InstructionFactory.createStore(enhancedReturnType, result)));
+			// generated: RType _OT$result = null;
+			
+			lg = chainMethod.addLocalVariable("_OT$team", teamType, null, null); //$NON-NLS-1$
+			ot_team = lg.getIndex();
+			// generated: Team _OT$team;
+		}
+		
+		int indexOffset = chainMethod.isStatic() ? -1 : 0; // argument indizes are decremented for static methods, 
+                                                           // because of the missing 'this'
+		short invocationKind = getInvocationType(mg);
+
+        il.append(InstructionFactory.createLoad(Type.INT, IDX_ARG + indexOffset));
+        il.append(InstructionFactory.createLoad(teamArray, TEAMS_ARG + indexOffset));
+        il.append(new ARRAYLENGTH());
+        IF_ICMPLT recursionNotYetTerminated = new IF_ICMPLT(null);
+        il.append(recursionNotYetTerminated);
+        // generated: if (_OT$teams.length < _OT$idx) {
+
+        
+		// load arguments:
+        if (!chainMethod.isStatic()) {
+        	ih = il.append(InstructionFactory.createThis());
+        } else {
+        	ih = il.append(new NOP());
+        }
+        if (debugging)
+        	chainMethod.addLineNumber(ih, SHOW_ORIG_CALL ? firstLine : STEP_INTO_LINENUMBER); // show orig call at method header ("dispatching")
+
+        int index = EXTRA_ARGS + 1;
+        for (int i = 0; i < argumentTypes.length; i++) {
+            il.append(InstructionFactory.createLoad(argumentTypes[i], index + indexOffset));
+            index += argumentTypes[i].getSize();
+        }
+		//
+        il.append(factory.createInvoke(class_name, genOrigMethName(method_name),
+                                       origReturnType, argumentTypes,
+									   invocationKind));
+		// generated: this._OT$<method_name>$orig (a1,.., aN) 	for nonstatic case
+        //                     _OT$<method_name>$orig (a1,.., aN) 			for static case
+		
+        if (debugging)
+        	chainMethod.addLineNumber(il.append(new NOP()), STEP_OVER_LINENUMBER);
+        
+        adjustValue(il, null, origReturnType, enhancedReturnType);
+        il.append(InstructionFactory.createReturn(enhancedReturnType));
+        // generated: return _OT$result;
+
+        ih = il.append(new NOP());
+        recursionNotYetTerminated.setTarget(ih);
+        // generated: ; (end of the if part)
+
+        il.append(InstructionFactory.createLoad(teamArray, TEAMS_ARG + indexOffset));
+        il.append(InstructionFactory.createLoad(Type.INT,  IDX_ARG + indexOffset));
+        il.append(InstructionFactory.createArrayLoad(teamType));
+        il.append(InstructionFactory.createStore(teamType, ot_team));
+        // generated: _OT$team = _OT$teams[_OT$idx];
+
+        // ---------------------------------------------
+        createDispatchCode(chainMethod, il,
+						   class_name, method_name,
+						   method_signature, result, ot_team, cg, firstLine);
+        // ---------------------------------------------
+
+		ih = il.append(InstructionFactory.createLoad(enhancedReturnType, result));
+        il.append(InstructionFactory.createReturn(enhancedReturnType));
+        // generated: return _OT$result;
+        if (debugging)
+        	chainMethod.addLineNumber(ih, STEP_OVER_LINENUMBER);
+        
+		// tidy:
+		chainMethod.removeNOPs();
+		try { // [SH]: overcautious: I once saw this CCE with no clue, why it happened :(
+			chainMethod.setMaxStack();
+		} catch (ClassCastException cce) {
+			System.err.println(chainMethod);
+			cce.printStackTrace();
+		}
+        chainMethod.setMaxLocals();
+		//chainMethod.removeNOPs();
+		Method generated = chainMethod.getMethod();
+		il.dispose();
+        return generated;
+    }
+
+	private short getInvocationType(MethodGen chainMethod) {
+		if (chainMethod.isStatic())
+			return Constants.INVOKESTATIC;
+		if (chainMethod.isPrivate())
+			return Constants.INVOKESPECIAL;
+		else
+			return Constants.INVOKEVIRTUAL;
+	}
+
+	/**
+	 * @param i
+	 * @return
+	 */
+	private static int makePublicFlags(int flags) {
+		if ((flags & Constants.ACC_PUBLIC) != 0) {
+			return flags;
+		}
+		if ((flags & Constants.ACC_PRIVATE) != 0) {
+			flags &= ~Constants.ACC_PRIVATE;
+		} else if ((flags & Constants.ACC_PROTECTED) != 0) {
+			flags &= ~Constants.ACC_PROTECTED;
+		}
+		flags |= Constants.ACC_PUBLIC;
+		return flags;
+	}
+
+	/**
+	 *  Generate the dispatch code by which a chaining wrapper invokes the
+	 *  callin method(s).
+	 *  This consists of three switch blocks: before, replace, after.
+	 * @param chainMethod				the chaining wrapper method
+	 * @param il									the InstructionList of the chaining wrapper			
+	 * @param class_name				the name of the appropriate class
+	 * @param method_name			the name of the original method
+	 * @param method_signature	the signature of the original method
+	 * @param result							the index of the '_OT$result' variable
+	 * @param ot_team						the index of the variable containing the team currently processed by the chaining wrapper
+	 * @param cg								the ClassGen of the appropriate class
+	 * @param firstLine							the first real source line of this method
+	 */
+	void createDispatchCode(MethodGen chainMethod, InstructionList il,
+							String class_name, String method_name,
+							String method_signature, int result, int ot_team, ClassGen cg, int firstLine)
+    {
+
+        //    get bindings for actually modified methods and sort them by callin-modifier:
+        //      modifier -> ArrayList<MethodBinding>
+        HashMap<String, ArrayList<MethodBinding>> sortedMethodBindings = new HashMap<String, ArrayList<MethodBinding>>();
+        Collection<MethodBinding> callinsForMethod;
+        callinsForMethod = CallinBindingManager.getBindingForBaseMethod(class_name,
+        																method_name, method_signature);
+        //System.err.println(class_name +" : "+callinsForMethod);
+        List<MethodBinding> inheritedMethodBindings = CallinBindingManager.getInheritedBaseMethodBindings(class_name, method_name, method_signature);
+        //System.err.println(inheritedMethodBindings);
+        
+        //--------------------------------------------------------------------------------------------
+        //JU: initialize callinsForMethod for overridden static base methods (begin)
+//        if(chainMethod.isStatic()){
+//        	if(callinsForMethod == null) {
+//        		callinsForMethod = new LinkedList();
+//        	}
+//        	
+//        	Collection classesDefBindingsToStaticMethods = CallinBindingManager.getInheritedCallinBindingsForStaticMethods(class_name, method_name, method_signature);
+//        	Iterator classesIt = classesDefBindingsToStaticMethods.iterator();
+//        	while(classesIt.hasNext()){
+//        		String superClassName = (String) classesIt.next();
+//        		Collection callinsFromSuperClasses = CallinBindingManager.getBindingForBaseMethod(superClassName, method_name, method_signature);
+//        		callinsForMethod.addAll(callinsFromSuperClasses);
+//        	}
+//        }
+        //JU: (end)
+        //----------------------------------------------------------------------------------------------
+        if (!chainMethod.isStatic())
+        	callinsForMethod.addAll(inheritedMethodBindings);
+        
+        /*
+        String[] interfaceNames = cg.getInterfaceNames();
+		Collection interfaceInheritedMethodBindings  = new LinkedList();
+		for (int i=0; i<interfaceNames.length;i++) {
+			if (!interfaceNames[i].equals(class_name))
+				interfaceInheritedMethodBindings.addAll(
+						CallinBindingManager.getInterfaceInheritedMethodBindings(method_name,
+																														  method_signature, 
+																														  interfaceNames[i]));
+		}
+
+		if (callinsForMethod == null)
+			callinsForMethod = new LinkedList();
+		
+		callinsForMethod.addAll(interfaceInheritedMethodBindings);
+       */
+        ListValueHashMap<MethodBinding> beforeBindings = new ListValueHashMap<MethodBinding>();
+        ListValueHashMap<MethodBinding> replaceBindings = new ListValueHashMap<MethodBinding>();
+        ListValueHashMap<MethodBinding> afterBindings = new ListValueHashMap<MethodBinding>();
+        
+        Iterator<MethodBinding> it = callinsForMethod.iterator();
+        while (it.hasNext()) {
+        	MethodBinding methodBinding = it.next();
+        	//sourceMapGen.addSourceMapInfo(methodBinding);
+        	String        modifier      = methodBinding.getModifier();
+        	ArrayList<MethodBinding>     bindings      = sortedMethodBindings.get(modifier);
+        	if (bindings == null) {
+        		bindings = new ArrayList<MethodBinding>();
+        		sortedMethodBindings.put(modifier, bindings);
+        	}
+        	bindings.add(methodBinding);
+        	// ----> added for predecedence purpose:
+        	String teamName = methodBinding.getTeamClassName();
+        	if (modifier.equals("before")) {                    //$NON-NLS-1$
+        		beforeBindings.put(teamName, methodBinding);
+        	} else if (modifier.equals("replace")) {            //$NON-NLS-1$
+        		replaceBindings.put(teamName, methodBinding);
+        	} else if (modifier.equals("after")) {              //$NON-NLS-1$
+        		afterBindings.put(teamName, methodBinding);
+        	}
+        	// <---
+        }
+        
+        // if any team has multiple bindings, we need to insert additional checks to avoid duplicate
+        // invocation of before/after causes during recursion.
+        boolean useBindingIdx = false;
+        for (LinkedList<MethodBinding> perTeamMethods : replaceBindings.valueSet())
+        	if (perTeamMethods.size() > 1) {
+        		useBindingIdx = true;
+        		break;
+        	}
+
+        /****************************************************************************/
+        // before callin :
+        if (sortedMethodBindings.containsKey("before")) {          //$NON-NLS-1$
+            if(logging) printLogMessage("before bindings will be applied..."); //$NON-NLS-1$
+        	il.append(createSwitch(
+        				  beforeBindings,
+        				  chainMethod, ot_team,
+        				  NORESULT, firstLine, cg.getMajor(), useBindingIdx));
+            if(logging) printLogMessage("before bindings: "        //$NON-NLS-1$
+        					+ sortedMethodBindings.get("before")); //$NON-NLS-1$
+        }
+        /****************************************************************************/
+        // replacement callin or direct recursion :
+        if (sortedMethodBindings.containsKey("replace")) { //$NON-NLS-1$
+            if(logging) printLogMessage("recursive call and replace bindings will be applied..."); //$NON-NLS-1$
+        	il.append(createSwitch(
+        				  replaceBindings,
+        				  chainMethod, ot_team,
+        				  result, firstLine, cg.getMajor(), useBindingIdx));
+            if(logging) printLogMessage("replace bindings: " //$NON-NLS-1$
+        					+ sortedMethodBindings.get("replace")); //$NON-NLS-1$
+        } else {
+            if(logging) printLogMessage("recursive chain-method call will be done..."); //$NON-NLS-1$
+        	// recursive call:
+
+			createRecursiveCall(il, chainMethod, result, 1, 0, method_name, method_signature, firstLine);
+        }
+        /****************************************************************************/
+        // after callin :
+        if (sortedMethodBindings.containsKey("after")) { //$NON-NLS-1$
+            if(logging) printLogMessage("after bindings will be applied..."); //$NON-NLS-1$
+        	il.append(createSwitch(
+        				  afterBindings,
+        				  chainMethod, ot_team,
+        				  /*NORESULT*/result, firstLine, cg.getMajor(), useBindingIdx));
+            if(logging) printLogMessage("after bindings: " //$NON-NLS-1$
+        					+ sortedMethodBindings.get("after")); //$NON-NLS-1$
+        }
+    }
+
+	/**
+	 *  Create a switch statement which contains one case for each MethodBinding
+	 *  in a given list.
+	 *  The switch block is furthermore wrapped in a try-catch block.
+	 *  Herein all {@link org.objectteams.LiftingVetoException LiftingVetoException}
+	 *  are caught, and possibly reported (if Dot.log.lift ist set).
+	 * @param methodBindings hash map of team names to 'MethodBinding' lists
+	 * @param mg method being generated.
+	 * @param ot_team index of local variable <tt>_OT$team</tt>
+	 * @param ot_result index of local variable <tt>_OT$result</tt>
+	 */
+	private InstructionList createSwitch(ListValueHashMap<MethodBinding> methodBindings, MethodGen mg,
+										 int ot_team, int ot_result,
+										 int firstLine,
+										 int major,
+										 boolean useBindingIdx)
+	{
+        InstructionList il = new InstructionList();
+
+		boolean handlesReplacement = false;
+
+		int indexOffset = mg.isStatic()?-1:0; // argument indizes are decremented for static methods, 
+                                                                       // because of the missing 'this'
+        
+		// load value to be switched:
+        il.append(InstructionFactory.createLoad(intArray, TEAMIDS_ARG+indexOffset));
+        il.append(InstructionFactory.createLoad(Type.INT, IDX_ARG+indexOffset));
+        InstructionHandle switchStart = il.append(InstructionFactory.createArrayLoad(Type.INT));
+		// generated: _OT$teamIDs[_OT$idx]
+
+        int numberOfCases = methodBindings.size();
+
+        // one break for each case clause
+        GOTO[] breaks = new GOTO[numberOfCases];
+        for (int i = 0; i < numberOfCases; i++)
+            breaks[i] = new GOTO(null);
+
+        int[]               matches = new int[numberOfCases];
+        InstructionHandle[] targets = new InstructionHandle[numberOfCases];
+
+        int      caseCounter     = 0;
+        
+        List<MethodBinding> methodBindingsForTeam = null;
+        MethodBinding mb = null;
+        Iterator <Entry<String, LinkedList<MethodBinding>>> teamIterator = methodBindings.entrySet().iterator();
+		while (teamIterator.hasNext()) {
+			Entry<String, LinkedList<MethodBinding>> entry = teamIterator.next();
+			String teamName = entry.getKey();
+			methodBindingsForTeam = entry.getValue();
+			//System.out.println(methodBindings.get(teamName));
+			
+			/*MethodBinding*/ mb = methodBindingsForTeam.get(0);
+			
+            matches[caseCounter] = TeamIdDispenser.getTeamId(teamName);
+            InstructionHandle nextBranch = il.append(new NOP());
+
+            // generate (_OT$teamID == teamId) branch here:
+
+			// ========== create Cases: ==========
+            if (mb.isReplace()) { // distinct treatment of replacement:
+				handlesReplacement = true;
+				createReplaceCase(mg, il,
+								  teamName, methodBindingsForTeam,
+								  ot_result, ot_team, major, firstLine);
+			} else { // before or after callin:
+				BranchInstruction ifBindingIdx = null;
+				if (useBindingIdx) {
+					// only if bindingIdx == 0
+					il.append(InstructionFactory.createLoad(Type.INT, BIND_IDX_ARG+indexOffset));
+					ifBindingIdx= new IFNE(null);
+					il.append(ifBindingIdx);
+				}
+                createBeforeAfterCase(mg, il, teamName,
+									  methodBindingsForTeam, ot_result, ot_team, major, firstLine);
+				if (useBindingIdx) {
+					ifBindingIdx.setTarget(il.append(new NOP()));
+				}
+			}
+
+			// ===================================
+
+            targets[caseCounter] = nextBranch;
+            /*InstructionHandle break_instr =*/ il.append(breaks[caseCounter]);
+			// generated: break;
+  
+            caseCounter++;
+        } // end of while
+        	
+        // generate default branch here:
+        InstructionHandle defaultBranch = il.append(new NOP());
+        if (handlesReplacement)
+			createRecursiveCall(il, mg, ot_result, 1, 0, mb.getBaseMethodName(), mb.getBaseMethodSignature(), firstLine);
+
+        InstructionHandle afterSwitch = il.append(new NOP()); // all breaks point here.
+
+		// ===== assemble the switch ====
+		il.append(switchStart,
+				  createLookupSwitch(matches, targets, breaks,
+									 defaultBranch, afterSwitch)
+				 );
+		// ==============================
+
+		// wrap everything in a try {} catch (LiftingVetoException e) {..}
+		InstructionHandle endTry = il.getEnd();
+
+		GOTO skipHdlr = null;
+		skipHdlr = new GOTO(null);
+		il.append(skipHdlr);
+		// generated: goto normal exit
+
+		InstructionHandle hdlr = il.append(new NOP());
+		il.append(DebugUtil.createReportExc(factory));
+
+		// catch: proceed with recursion if caught in a replace call
+		if (handlesReplacement)
+			createRecursiveCall(il, mg, ot_result, 1, 0, mb.getBaseMethodName(), mb.getBaseMethodSignature(), firstLine);
+
+		mg.addExceptionHandler(il.getStart(), endTry, hdlr, liftingVeto);
+
+		InstructionHandle nop = il.append(new NOP());
+		skipHdlr.setTarget(nop);
+
+        return il;
+    }
+
+	/** Create the recursice call of this chaining method.
+	 * @param il insert the call into this list.
+	 * @param mg this chaining method
+	 * @param ot_result stack index of the _OT$result variable or NORESULT.
+	 * @param idx_offset TODO
+	 * @param bindIdx_offset TODO
+	 * @param methodName TODO
+	 * @param methodSignature TODO
+	 */
+	void createRecursiveCall (InstructionList il,
+							  MethodGen mg,
+							  int ot_result, int idx_offset, int bindIdx_offset, String methodName, String methodSignature, int firstLine)
+	{
+		InstructionHandle ih = !mg.isStatic()
+				? il.append(InstructionFactory.createThis())
+				: il.append(new NOP());
+		if (debugging)
+			mg.addLineNumber(ih, SHOW_RECURSIVE_CALL ? firstLine : STEP_INTO_LINENUMBER); // show recursive call at method header ("dispatching")
+		
+ 		Type[] argTypes = mg.getArgumentTypes();
+		Type returnType = mg.getReturnType();
+		short invocationKind = getInvocationType(mg);
+		
+		// arguments: no adjustment except idx++.
+		int index = 1;
+		int indexOffset = mg.isStatic()?-1:0; // argument indizes are decremented for static methods, 
+                                                                       // because of the missing 'this'
+		for (int i=0; i<argTypes.length; i++) {
+			il.append(InstructionFactory.createLoad(argTypes[i], index+indexOffset));
+			if (index == OTConstants.IDX_ARG && idx_offset != 0) { // _OT$idx has to be incremented (adding idx_offset)
+				il.append(new ICONST(idx_offset));
+				il.append(new IADD());
+			} else if (index == OTConstants.BIND_IDX_ARG) { // _OT$bindIdx has to be incremented (adding bindIdx_offset)
+				if (bindIdx_offset == 0) { // bindArg argument has to be set to '0'
+					il.append(new POP()); 			// remove loaded _OT$bindIdx
+					il.append(new ICONST(0)); // replace it by '0' 
+				} else {
+					il.append(new ICONST(bindIdx_offset));
+					il.append(new IADD());
+				}
+			}
+			index += argTypes[i].getSize();
+		}
+		il.append(factory.createInvoke(mg.getClassName(), mg.getName(),
+									   returnType, argTypes,
+									   invocationKind));
+
+		il.append(InstructionFactory.createStore(returnType, ot_result));
+
+		// _OT$result = _OT$<method_name>$chain(_OT$teams, _OT$teamIDs, _OT$idx+1,
+		//                                         a1, .., aN);
+		if (debugging)
+			mg.addLineNumber(il.append(new NOP()), STEP_OVER_LINENUMBER);
+	}
+
+
+	/**
+	 * Create a block for a before or after callin as a case with a surrounding switch.
+	 * @param mg TODO
+	 * @param il InstructionList being assembled.
+	 * @param connectorClassName name of a Team which has a callin to this method.
+	 * @param mbList MethodBindings describing the callins.
+	 * @param ot_result index of local variable <tt>_OT$result</tt>.
+	 * @param ot_team  index of local variable <tt>_OT$team</tt>.l
+	 * @param major
+	 * @param firstLine							the first real source line of this method
+	 */
+	void createBeforeAfterCase(MethodGen mg,
+							   InstructionList il, String connectorClassName,
+							   List<MethodBinding> mbList, int ot_result, int ot_team,
+							   int major, int firstLine)
+    {	
+
+		MethodBinding mb = mbList.get(0);
+		ConstantPoolGen cpg = mg.getConstantPool();
+		
+		mbList = CallinBindingManager.sortMethodBindings(mbList, connectorClassName);
+		
+		Iterator<MethodBinding> it = mbList.iterator();
+		while (it.hasNext()) {
+			/*MethodBinding nextMethodBinding*/mb = it.next();
+		
+			String baseMethodSignature = mb.getBaseMethodSignature();
+			Type[] baseArgTypes = Type.getArgumentTypes(baseMethodSignature);
+			Type baseReturnType = Type.getReturnType(baseMethodSignature);
+			
+			Type[] wrapperArgTypes = Type.getArgumentTypes(mb.getWrapperSignature());
+			int argsLen = wrapperArgTypes.length - 1; // don't count base arg.
+			
+			il.append(InstructionFactory.createLoad(teamType, ot_team));
+
+			int packedArgPos = 0;
+			InstructionHandle argArray = null;
+			if (useReflection) {
+				il.append(factory.createInvoke("java.lang.Object", "getClass", classType, new Type[0], Constants.INVOKEVIRTUAL));
+				il.append(new LDC(cpg.addString(mb.getWrapperName())));
+				pushTypeArray(il, wrapperArgTypes, major, cpg);
+				il.append(factory.createInvoke("java.lang.Class", "getMethod", methodType, OTConstants.getMethodSignature, Constants.INVOKEVIRTUAL));
+				
+				il.append(InstructionFactory.createLoad(teamType, ot_team));
+				// generated: 
+				//   _OT$team.getClass().getMethod(<wrapperName>, <wrapper sign>)  
+				//   _OT$team
+				argArray = il.append(new ANEWARRAY(cpg.addClass(object)));
+				
+			} else {
+				il.append(factory.createCast(teamType, new ObjectType(connectorClassName)));
+				// generated: (<TeamClass>)_OT$team
+			}
+			
+			// first argument: base object:
+			packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
+			{
+				if (!mg.isStatic())
+					il.append(InstructionFactory.createThis());
+				else
+					il.append(InstructionFactory.createNull(Type.OBJECT)); // no base object
+			}
+			checkPackValue1(il, useReflection, Type.OBJECT);
+			
+			// second argument: base result (if appropriate)
+			if ( mb.isAfter() && !baseReturnType.equals(Type.VOID)) { // after callin wrapper get the base method result as second argument
+				packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
+				{
+					il.append(InstructionFactory.createLoad(object, ot_result));
+					adjustValue(il, null, object, baseReturnType);
+					argsLen --; // the second (result) arg is also not part of the arg list
+				}
+				checkPackValue1(il, useReflection, baseReturnType);
+			}
+			
+			// ------- load regular args: --------
+			
+			// stack positions for load instructions (one-based for non-statics, since 0 == this)
+			int stackIndex = EXTRA_ARGS + (mg.isStatic() ? 0 : 1);
+			// where within baseArgTypes do source arguments start?
+			int firstArg = 0;
+			
+			if (mb.baseMethodIsCallin()) {
+				// skip enhancement of this callin method (lower role).
+				firstArg   += EXTRA_ARGS;
+				stackIndex += EXTRA_ARGS;
+				argsLen    += EXTRA_ARGS;
+			}
+			for (int i = firstArg; i < argsLen; i++) {
+                if(logging) printLogMessage("loading " + baseArgTypes[i].toString()); //$NON-NLS-1$
+
+                packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
+                {
+					il.append(InstructionFactory.createLoad(baseArgTypes[i],stackIndex));
+                }
+				checkPackValue1(il, useReflection, baseArgTypes[i]);
+				
+				stackIndex += baseArgTypes[i].getSize();
+			}
+			
+			InstructionHandle callinCall;
+			if (useReflection) {
+				// this information was missing above:
+				il.insert(argArray, createIntegerPush(cpg, packedArgPos));
+				
+				callinCall = il.append(factory.createInvoke("java.lang.reflect.Method", "invoke", object, new Type[]{object, objectArray}, Constants.INVOKEVIRTUAL));
+				il.append(new POP()); // before/after wrappers return void
+			} else {
+				callinCall = il.append(factory.createInvoke(connectorClassName,
+											   mb.getWrapperName(),
+											   Type.VOID, wrapperArgTypes,
+											   Constants.INVOKEVIRTUAL));
+			}
+			if (debugging) {
+				mg.addLineNumber(callinCall, SHOW_ROLE_CALL ? firstLine : STEP_INTO_LINENUMBER); // show role call at method header ("dispatching")
+				mg.addLineNumber(il.append(new NOP()), STEP_OVER_LINENUMBER);
+			}
+		}
+    }
+
+	/* this and the next method serve as a bracket for all pushes that may or may not require
+	 * packing in an array, the array must already exist on the stack. */
+	private int checkPackValue0(InstructionList il, boolean doPack, int argCount, ConstantPoolGen cpg) {
+		if (doPack) {
+			il.append(new DUP());
+			il.append(createIntegerPush(cpg, argCount));
+			return argCount+1;
+		} else {
+			return argCount;
+		}
+	}
+	private void checkPackValue1(InstructionList il, boolean doPack, Type argType) {
+		if (doPack) {
+			if (argType instanceof BasicType)
+				il.append(createBoxing((BasicType)argType));
+			il.append(new AASTORE());
+		}
+	}
+	/* Push an array of Class representing the signature given by argTypes. */
+	private void pushTypeArray(InstructionList il, Type[] argTypes, int major, ConstantPoolGen cpg) {
+		il.append(createIntegerPush(cpg, argTypes.length));
+		il.append(new ANEWARRAY(cpg.addClass(classType)));
+		for (int i=0; i<argTypes.length; i++) {
+			Type type = argTypes[i];
+			il.append(new DUP());
+			il.append(createIntegerPush(cpg, i));
+			if (type instanceof BasicType) {
+				il.append(factory.createFieldAccess(toObjectTypeName((BasicType)type), "TYPE", classType, Constants.GETSTATIC));
+			} else if (type instanceof ObjectType) {
+				appendClassLiteral(il, ((ObjectType)type).getClassName(), major, cpg);
+			} else if (type instanceof ArrayType) { 
+				String prefix = "";
+				while (type instanceof ArrayType) {
+					prefix += '[';
+					type = ((ArrayType)type).getElementType();
+				}
+				String elemTypeName = null;
+				if (type instanceof ObjectType)
+					elemTypeName = "L"+((ObjectType)type).getClassName()+';';
+				else if (type instanceof BasicType)
+					elemTypeName = ((BasicType)type).getSignature();
+				appendClassLiteral(il, prefix+elemTypeName, major, cpg);
+			} else {
+				throw new OTREInternalError("unsupported type in signature "+type);
+			}
+			il.append(new AASTORE());
+		}
+	}
+
+	/**
+	 * Create a block for a replace callin as a case within a surrounding switch. If there are multiple bindings from the 
+	 * same team to this base method, the bindings are sorted according to the precedence list of this team.
+	 * @param mg base method being generated.
+	 * @param il instruction list being assembled.
+	 * @param connectorClassName name of a Team which has a callin to this method.
+	 * @param mbList list of 'MethodBinding's
+	 * @param ot_result index of a local variable <tt>_OT$result</tt>.
+	 * @param ot_team  index of local variable <tt>_OT$team</tt>.
+	 * @param major class file version
+	 */
+	void createReplaceCase(MethodGen mg, InstructionList il,
+						   String connectorClassName, List<MethodBinding> mbList,
+						   int ot_result, int ot_team, int major, int firstLine)
+    {
+		
+		int indexOffset = mg.isStatic() ? -1 : 0; // argument indizes are decremented for static methods, 
+												  // because of the missing 'this' 
+		boolean multipleBindings = mbList.size() > 1;
+		mbList = CallinBindingManager.sortMethodBindings(mbList, connectorClassName);
+		
+		MethodBinding mb = mbList.get(0); // default, if only one binding exists
+		
+		LocalVariableGen unused_args_lg = mg.addLocalVariable(UNUSED, objectArray, null, null);
+		int unused_args = unused_args_lg.getIndex();
+		unused_args_lg.setStart(il.append(new NOP()));
+		if (multipleBindings) {
+			InstructionList addition = new InstructionList();
+			// load value to be switched:
+			
+			InstructionHandle switchStart = addition.append(InstructionFactory.createLoad(Type.INT, BIND_IDX_ARG+indexOffset)); 
+			// loaded _OT$bindIdx
+			
+			int numberOfCases = mbList.size();
+			
+			// one break for each case clause
+			GOTO[] breaks = new GOTO[numberOfCases];
+			for (int i=0; i<numberOfCases; i++)
+				breaks[i] = new GOTO(null);
+			
+			int[] matches = new int[numberOfCases];
+			InstructionHandle[] targets = new InstructionHandle[numberOfCases];
+			
+			int      caseCounter     = 0;
+			Iterator<MethodBinding> mbIterator = mbList.iterator();
+			while (mbIterator.hasNext()) {
+				mb = mbIterator.next();
+				matches[caseCounter] = caseCounter;
+				InstructionHandle nextBranch = addition.append(new NOP());
+				// ========== create Cases: ===========
+				addition.append(createSingleReplaceCallin(mg, connectorClassName, mb, ot_result, ot_team, unused_args, multipleBindings, mg.isStatic(), major, firstLine));
+				// ==============================
+				targets[caseCounter] = nextBranch;
+				/*InstructionHandle break_instr =*/ addition.append(breaks[caseCounter]);
+				// generated: break;
+				caseCounter++;
+			}
+			// ========== create default: ===========
+			InstructionHandle defaultBranch = addition.append(new NOP());
+			createRecursiveCall(addition, mg, ot_result, 1, 0, mb.getBaseMethodName(), mb.getBaseMethodSignature(), firstLine);
+			// ==============================
+			
+			InstructionHandle afterSwitch = addition.append(new NOP()); // all breaks point here.
+			
+			for (int i=0; i<numberOfCases; i++)
+				breaks[i].setTarget(afterSwitch);
+			
+			addition.append(switchStart, new TABLESWITCH(matches, targets, defaultBranch));
+			// wrap everything in a try {} catch (LiftingVetoException e) {..}
+			InstructionHandle endTry = addition.getEnd();
+			
+			GOTO skipHdlr = null;
+			skipHdlr = new GOTO(null);
+			addition.append(skipHdlr);
+			// generated: goto normal exit
+			
+			InstructionHandle hdlr = addition.append(new NOP());
+			addition.append(DebugUtil.createReportExc(factory));
+			
+			// ========== create catch instructions: ===========
+			createRecursiveCall(addition, mg, ot_result, 0, 1, mb.getBaseMethodName(), mb.getBaseMethodSignature(), firstLine);
+			// =====================================
+			mg.addExceptionHandler(addition.getStart(), endTry, hdlr, liftingVeto);
+			
+			InstructionHandle nop = addition.append(new NOP());
+			skipHdlr.setTarget(nop);
+			il.append(addition);
+		} else { // only a single replace callin:
+			il.append(createSingleReplaceCallin(mg, connectorClassName, mb, ot_result, ot_team, unused_args, multipleBindings, mg.isStatic(), major, firstLine));
+		}
+		unused_args_lg.setEnd(il.getEnd());
+	}
+
+	/**
+	 * Creates a single replace callin call.
+	 *
+	 * @param mg						base method being generated.
+	 * @param connectorClassName		name of a Team which has a callin to this method.
+	 * @param mb						the 'MethodBinding' for this callin. 
+	 * @param ot_result					index of a local variable <tt>_OT$result</tt>.
+	 * @param ot_team					index of local variable <tt>_OT$team</tt>.
+	 * @param unused_args				index of local variable <tt>_OT$unused_args</tt>.
+	 * @param multipleBindings			flag indicating if there are multiple bindings in this case
+	 * @param staticBaseMethod TODO
+	 * @param major 					class file version
+	 * @param firstLine					first real source line number of this method
+	 * @return							instruction list for the callin call
+	 */
+	private InstructionList createSingleReplaceCallin(MethodGen mg, String connectorClassName, MethodBinding mb, int ot_result, int ot_team, int unused_args, boolean multipleBindings, boolean staticBaseMethod, int major, int firstLine) 
+	{
+		// Sequence of values to load is (letters refer to document parameter-passing.odg):
+		// (f) _OT$team: 	call target for invoking the callin-wrapper
+		// (g) baseObject:	this or null
+		// (h) enhancement: [Team[IIII[Object; 
+		// 					idxs are being manipulated here,
+		//					unusedArgs[] is allocated and filled with 
+		// (i)                - (int,Team) if current method is static role method.
+		// (j)                - enhancement arguments, if current method is callin method
+		// (k) regular arguments.
+		
+		// ------------------------------------------
+    	//               prepare Types:
+		// ------------------------------------------
+		Type[] chainArgTypes = mg.getArgumentTypes();
+    	Type[] baseArgTypes  = Type.getArgumentTypes(mb.getBaseMethodSignature());
+    	Type[] roleArgTypes  = Type.getArgumentTypes(mb.getRoleMethodSignature());
+    	roleArgTypes = enhanceArgumentTypes(roleArgTypes);
+    	String wrapperName = mb.getWrapperName();
+    	Type wrapperReturnType = Type.getReturnType(mb.getWrapperSignature());
+
+    	Type[] wrapperArgTypes = Type.getArgumentTypes(mb.getWrapperSignature());
+    	
+    	// calculate return type:
+        Type chainReturnType = mg.getReturnType();
+        
+        ConstantPoolGen cpg = mg.getConstantPool();
+        InstructionList il = new InstructionList();
+        // (f):
+        il.append(InstructionFactory.createLoad(teamType, ot_team));
+
+		int packedArgPos = 0;
+		InstructionHandle argArray = null;
+		if (useReflection) {
+			il.append(factory.createInvoke("java.lang.Object", "getClass", classType, new Type[0], Constants.INVOKEVIRTUAL));
+			il.append(new LDC(cpg.addString(mb.getWrapperName())));
+			pushTypeArray(il, wrapperArgTypes, major, cpg);
+			il.append(factory.createInvoke("java.lang.Class", "getMethod", methodType, OTConstants.getMethodSignature, Constants.INVOKEVIRTUAL));
+			
+			il.append(InstructionFactory.createLoad(teamType, ot_team));
+			// generated: 
+			//   _OT$team.getClass().getMethod(<wrapperName>, <wrapper sign>)  
+			//   _OT$team
+			argArray = il.append(new ANEWARRAY(cpg.addClass(object)));
+		} else {
+			il.append(factory.createCast(teamType, new ObjectType(connectorClassName)));
+			// generated: (<TeamClass>)_OT$team
+		}
+       
+        // (g):
+		packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
+		{
+	        if(!staticBaseMethod)
+				il.append(InstructionFactory.createThis());
+			else
+				il.append(InstructionFactory.createNull(Type.OBJECT)); // no base object
+		}
+		checkPackValue1(il, useReflection, Type.OBJECT);
+        
+    	// ----------------------------------------
+    	// (h)   Load Extra Arguments:
+    	// ----------------------------------------
+        int staticOffset = staticBaseMethod?-1:0; // argument indizes are decremented for static methods, 
+		          								  // because of the missing 'this' 
+        // first 4 extra arguments: _OT$teams, _OT$teamIDs, _OT$idx, _OT$bindIdx
+        for (int i=0; i<4; i++) { // If this is called only once _OT$idx has to be incremented, else _OT$bindIdx has to be incremented
+        	packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
+        	{
+	        	il.append(InstructionFactory.createLoad(chainArgTypes[i], i+1+staticOffset));
+	    		if (!multipleBindings && i+1+staticOffset == OTConstants.IDX_ARG+staticOffset) {// _OT$idx++:
+	    			il.append(new ICONST(1));
+	            	il.append(new IADD());
+	    		} else if (multipleBindings && i+1+staticOffset == OTConstants.BIND_IDX_ARG+staticOffset) {// _OT$bindIdx:
+	    			il.append(new ICONST(1));
+	            	il.append(new IADD());
+	    		}
+        	}
+        	checkPackValue1(il, useReflection, chainArgTypes[i]);
+        }
+		// _OT$baseMethTag:
+        int base_meth_tag = CallinBindingManager.getBaseCallTag(mb.getBaseClassName(), 
+												        		mb.getBaseMethodName(), 
+												        		mb.getBaseMethodSignature());
+//        //JU: added this if-statement (begin) ----------------------------------------------
+//        if(staticBaseMethod && !mg.getClassName().equals(mb.getBaseClassName())){
+//        	//the method binding is a dummy -> the callin wrapper is performed 
+//        	//with an invalid base method tag value -> an exception will be thrown
+//        	base_meth_tag = INVALID_BASE_METHOD_TAG;
+//        }
+//        //JU (end) --------------------------------------------------------------------------
+        
+        packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
+        {
+        	il.append(createIntegerPush(cpg, base_meth_tag));
+        }
+        checkPackValue1(il, useReflection, Type.INT);
+
+        // collect regular args first, insert into il later:
+        InstructionList regularArgs = new InstructionList();
+        
+        // put "new Object[]" on stack, later containing unused arguments:
+        packedArgPos = checkPackValue0(il, useReflection, packedArgPos, cpg);
+        {
+	        il.append(createIntegerPush(cpg, baseArgTypes.length)); 
+	        		// enough space to hold ALL base arguments
+	        		// Note that the callin wrapper may add more elements to this array.
+	        il.append((Instruction)factory.createNewArray(object, (short)1));
+	        il.append(InstructionFactory.createStore(objectArray, unused_args));
+	        // generated: _OT$unusedArgs = new Object[<n_base_args>];
+	
+	    	// ----------------------------------------
+	        // handle more arguments: load regular ones, store unused arguments into the array:
+	    	// ----------------------------------------
+	        int unusedArgsIdx = 0; // index into Object[].
+	
+			int stackIdx = EXTRA_ARGS + 1 + staticOffset; // one-based, since 0 == this (unless static)
+			int regularArgsStart = EXTRA_ARGS;
+			boolean baseIsStaticCallin = mb.baseMethodIsCallin() && staticBaseMethod;
+			if (baseIsStaticCallin) { 
+				// (i) need these synthetic arguments up-front: "int dummy, Team enclosingTeam"
+				storeUnusedArg(il, unused_args, 0,  // constant
+						   	   new ICONST(0),
+						   	   Type.INT,
+						   	   cpg);
+				storeUnusedArg(il, unused_args, 1,  // constant 
+						   	   new ALOAD(regularArgsStart+1), 
+						   	   OTConstants.teamType,
+						   	   cpg);
+	
+				// consumed first two parameters into unusedArgs:
+				regularArgsStart+=2;
+				stackIdx += 2;
+				unusedArgsIdx += 2;
+			}
+	        for (int i=regularArgsStart; i<chainArgTypes.length; i++) {
+				Type argType = chainArgTypes[i];
+				Instruction loadingInstruction = InstructionFactory.createLoad(argType, stackIdx);
+				if (isRegularArg(i, mb.baseMethodIsCallin(), staticBaseMethod)) {
+					// (k) collect loading instruction, for appending after _OT$unusedArgs.
+					packedArgPos = checkPackValue0(regularArgs, useReflection, packedArgPos, cpg);
+					{
+						regularArgs.append(loadingInstruction);
+					}
+					checkPackValue0(regularArgs, useReflection, packedArgPos, cpg);
+				} else {
+					// (j) store unused arg 
+					storeUnusedArg(il, unused_args, unusedArgsIdx++, loadingInstruction, argType, cpg);
+					// generated: _OT$unusedArgs[<unusedArgsIdx>] = maybeBox(a<index>);
+				}
+				stackIdx += argType.getSize();
+	        }
+	        il.append(InstructionFactory.createLoad(objectArray, unused_args));
+        }
+        checkPackValue1(il, useReflection, objectArray);
+        
+		// (k) insert previously assembled load-sequence:
+        il.append(regularArgs);
+        
+    	// ============= INVOKEVIRTUAL (wrapper) =============
+        InstructionHandle callinCall;
+        if (useReflection) {
+    		// this information was missing above:
+			il.insert(argArray, createIntegerPush(cpg, packedArgPos));
+			
+			callinCall = il.append(factory.createInvoke("java.lang.reflect.Method", "invoke", object, new Type[]{object, objectArray}, Constants.INVOKEVIRTUAL));
+			wrapperReturnType = Type.OBJECT;
+        } else {
+        	callinCall = il.append(factory.createInvoke(connectorClassName, wrapperName,
+    								   wrapperReturnType,
+    								   wrapperArgTypes,
+    								   Constants.INVOKEVIRTUAL));
+        }
+		if (debugging) {
+			mg.addLineNumber(callinCall, SHOW_ROLE_CALL ? firstLine : STEP_INTO_LINENUMBER); // show role call at method header ("dispatching")
+        	mg.addLineNumber(il.append(new NOP()), STEP_OVER_LINENUMBER);
+		}
+
+		adjustValue(il, null, wrapperReturnType, chainReturnType);
+		il.append(InstructionFactory.createStore(chainReturnType, ot_result));
+		
+		return il;
+	}
+
+	/**
+	 *  Store an unused value (loaded by pushInstruction) into _OT$unusedArgs 
+	 */
+	private void storeUnusedArg(InstructionList il, 
+								int 		    unused_args, 
+								int 			arrayIndex, 
+								Instruction 	pushInstruction,
+								Type        	argType,
+								ConstantPoolGen cpg) 
+	{
+		il.append(InstructionFactory.createLoad(objectArray, unused_args));
+		il.append(createIntegerPush(cpg, arrayIndex));
+		il.append(pushInstruction);
+		if (argType instanceof BasicType)
+			il.append(createBoxing((BasicType)argType));
+		il.append(InstructionFactory.createArrayStore(objectArray));
+	}
+
+	/**
+	 * Is the parameter at position idx mapped (by paramPositions or implicitly)?
+	 * Cut off head: 
+	 * 		- (int,Team) if present (static role method)
+	 * 		- enhancement (possible twice)
+	 * @param idx parameter index of enhanced signature
+	 */
+	static boolean isRegularArg (int idx, boolean baseIsCallin, boolean baseIsStatic) {
+		if (baseIsCallin && baseIsStatic) // FIXME(SH): should be baseIsRole instead of baseIsCallin!
+			idx -= 2;
+		int firstVisible = EXTRA_ARGS + (baseIsCallin?EXTRA_ARGS:0); // skip one or two enhancements
+		return idx >= firstVisible;
+	}
+
+	/**
+	 *  Given an argument of type <tt>actual</tt>, must
+	 *  we use type <tt>formal</tt> in signatures,
+	 *  because it is a supertype of <tt>actual</tt>?
+	 */
+	static Type checkWiden (Type actual, Type formal) {
+		if (!actual.equals(formal)
+			&& actual instanceof ObjectType
+			&& formal instanceof ObjectType)
+		{
+			ObjectType actualObj = (ObjectType)actual;
+			ObjectType formalObj = (ObjectType)formal;
+			if (actualObj.subclassOf(formalObj))
+				return formalObj;
+		}
+		return actual;
+	}
+
+	/**
+	 * Create an instruction list for initializing the role set field on-demand.
+	 * @param valueRequired should the role set be on the stack after this sequence?
+	 * @param cg	the ClassGen of the appropriate class
+	 */
+	private InstructionList getInitializedRoleSet(String class_name, boolean valueRequired) {;
+		InstructionList il = new InstructionList();
+
+		// try to retrieve existing set:
+		il.append(new ALOAD(0));
+		il.append(factory.createGetField(class_name, OTConstants.ROLE_SET, OTConstants.roleSetType));
+		if (valueRequired)
+			il.append(new DUP()); // a spare value to keep on the stack if successful
+		
+		// if (roleSet == null) ..
+		IFNONNULL branch = new IFNONNULL(null);
+		il.append(branch);
+
+		// conditionally create the set:
+		if (valueRequired)
+			il.append(new POP()); // remove useless "null", replace with DUP_X1 below
+		il.append(new ALOAD(0));
+		il.append(factory.createNew(OTConstants.roleSetType));
+		il.append(new DUP());
+		il.append(factory.createInvoke(OTConstants.roleSetType.getClassName(),
+													 		Constants.CONSTRUCTOR_NAME,
+													 		Type.VOID,
+													 		Type.NO_ARGS, 
+													 		Constants.INVOKESPECIAL));
+		if (valueRequired)
+			il.append(new DUP_X1()); // push below pending "this"
+		
+		// store in the field:
+		il.append(factory.createPutField(class_name, OTConstants.ROLE_SET, OTConstants.roleSetType));
+	
+		// endif
+		branch.setTarget(il.append(new NOP()));
+		return il;
+	}
+	
+	/**
+	 * Generates the field '_OT$roleSet' which is used to store the added roles.
+	 * @param cpg			the ClassGen of the appropriate class
+	 * @param class_name	the name of the class
+	 * @return				the generated field
+	 */
+	private Field generateRoleSet(ConstantPoolGen cpg, String class_name) {
+		FieldGen fg = new FieldGen(Constants.ACC_PROTECTED, 
+                                   OTConstants.roleSetType,
+                                   OTConstants.ROLE_SET,
+                                   cpg);
+		return fg.getField();	
+	}
+	
+	/**
+	 * Generates the method 'public void _OT$addRole(Object role)' which adds the passed object 
+	 * to the role set of this base class.
+	 * @param cpg					the ClassGen of the appropriate class
+	 * @param class_name	the name of the class
+	 * @return							the generated method 
+	 */
+	private Method generateAddRole(ConstantPoolGen cpg, String class_name) {
+
+		InstructionList il = new InstructionList();
+		MethodGen mg = new MethodGen(Constants.ACC_PUBLIC,
+				 					 Type.VOID,
+				 					 new Type[] { Type.OBJECT },
+				 					 new String[] {"role"},
+				 					 OTConstants.ADD_ROLE, class_name,
+				 					 il, cpg);
+		
+		il.append(getInitializedRoleSet(class_name, /*valueRequired*/true)); 
+		
+		il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
+		il.append(factory.createInvoke(OTConstants.roleSetType.getClassName(), 
+									   "add", 
+									   Type.BOOLEAN, 
+									   new Type[] {Type.OBJECT},
+									   Constants.INVOKEVIRTUAL));
+		il.append(new POP());
+		il.append(InstructionFactory.createReturn(Type.VOID));
+		mg.removeNOPs();
+		mg.setMaxStack();
+		mg.setMaxLocals(2);
+		return mg.getMethod();
+	}
+	
+	/**
+	 * Generates the method 'public void _OT$removeRole(Object role)' which removes the passed object 
+	 * from the role set of this base class.
+	 * @param cpg			the ClassGen of the appropriate class				
+	 * @param class_name  	the name of the class
+	 * @return				the generated method 
+	 */
+	private Method generateRemoveRole(ConstantPoolGen cpg, String class_name) {
+		
+		InstructionList il = new InstructionList();
+		MethodGen mg = new MethodGen(Constants.ACC_PUBLIC,
+						 			 Type.VOID,
+						 			 new Type[] { Type.OBJECT },
+						 			 new String[] {"role"},
+						 			 OTConstants.REMOVE_ROLE, class_name,
+						 			 il, cpg);
+		il.append(new ALOAD(0)); 			  
+		il.append(factory.createGetField(class_name, OTConstants.ROLE_SET, OTConstants.roleSetType));
+		il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
+		il.append(factory.createInvoke(OTConstants.roleSetType.getClassName(), 
+									   "remove", 
+									   Type.BOOLEAN, 
+									   new Type[] {Type.OBJECT},
+									   Constants.INVOKEVIRTUAL));
+		il.append(new POP());
+		il.append(InstructionFactory.createReturn(Type.VOID));
+		mg.removeNOPs();
+		mg.setMaxStack(2);
+		mg.setMaxLocals(2);
+		return mg.getMethod();
+	}
+	
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseTagInsertion.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseTagInsertion.java
new file mode 100644
index 0000000..ebbf234
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/BaseTagInsertion.java
@@ -0,0 +1,205 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: BaseTagInsertion.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import de.fub.bytecode.generic.*;
+import de.fub.bytecode.*;
+
+
+import java.util.*;
+
+import org.eclipse.objectteams.otre.util.*;
+
+/**
+ * This transformer inserts tag fields for all (topmost) bound base classes.
+ * Tag fields look like this:
+ * <pre>
+ *   public short <i>TeamName</i>_OT$Tag;
+ * </pre>
+ * where <i>TeamName</i> is any team which has a callin binding for this base class.
+ * It also inserts initialization of this tag into every constructor.
+ * 
+ * @version $Id: BaseTagInsertion.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author  Christine Hundt
+ * @author  Stephan Herrmann
+ */
+public class BaseTagInsertion 
+{
+    private static boolean logging   = false;
+    final   static String  tagSuffix = "_OT$Tag";
+
+	static String getTagFieldName (String teamName) {
+        return teamName.replace('.', '$') + tagSuffix;
+    }
+
+	static {
+		if (System.getProperty("ot.log") != null)
+			logging = true;
+	}
+
+	public static class SharedState extends ObjectTeamsTransformation.SharedState {
+	    // Record base tags of interfaces here (String->HashMap). 
+	    // Need to be considered in all implementing classes.
+	    // baseName -> HashMap  (teamName -> tag (Integer)):
+	    private HashMap<String, HashMap<String, Integer>> baseTagsOfInterfaces = new HashMap<String, HashMap<String, Integer>>();
+	}
+
+	SharedState state;
+	
+    public BaseTagInsertion(SharedState state) {
+		this.state = state;
+	}
+
+	/**
+     * @param ce
+     * @param cg
+     */
+    public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
+       
+        String class_name = cg.getClassName();
+        ConstantPoolGen cpg = cg.getConstantPool();
+/*
+ 		if (interfaceTransformedClasses.contains(class_name))
+ 			continue; // already transformed!
+*/
+
+        HashMap<String, Integer> baseTags = getAllBaseTags(cg);
+
+        if (baseTags == null) return; // not a bound base
+
+        if (cg.isInterface())
+        	state.baseTagsOfInterfaces.put(class_name, baseTags);
+			
+        state.interfaceTransformedClasses.add(class_name);
+        if (logging)
+			printLogMessage("Found bound base: " + class_name);
+            
+        Iterator<String> teams = baseTags.keySet().iterator();
+        while (teams.hasNext()) {
+        	String teamName = teams.next();
+       	
+        	String fieldName = getTagFieldName(teamName);//team + tagSuffix;
+
+        	if (cg.containsMethod("get"+fieldName, "()S") == null)
+        	{
+        		if(logging)
+        			printLogMessage("create base tag access get" + fieldName);
+        		Integer tag = baseTags.get(teamName);
+        		MethodGen mg = genBaseTagGetter(cpg, class_name, fieldName, tag.intValue(), cg.isInterface());
+        		ce.addMethod(mg.getMethod(), cg);
+        	}
+        }
+        // addedBaseTags.addAll(baseTags);
+    }
+
+	/**
+	 * Collect base tags from this class and its super interfaces.
+	 * @param cg
+	 * @return
+	 */
+	private HashMap<String, Integer> getAllBaseTags(ClassGen cg) {
+		// accumulate here base tags from bound super interfaces and this class:
+		HashMap<String, Integer> baseTags = null;
+		
+		// TODO (SH): consider all transformed super interfaces.
+		String superIfc = getTransformedSuperIfc(cg);
+		if (superIfc != null) 
+			baseTags = state.baseTagsOfInterfaces.get(superIfc);
+		
+		String class_name = cg.getClassName();
+		HashMap<String, Integer> classBaseTags = CallinBindingManager.getBaseTags(class_name);
+		if (CallinBindingManager.isRole(class_name)) {
+				// search for base tags inherited from the implicit super (role) class:
+				HashMap<String, Integer> inheritedBaseTags = CallinBindingManager.getInheritedBaseTags(class_name);
+				classBaseTags.putAll(inheritedBaseTags);
+				// search for base tags of the implementing role class:
+				String implementingRoleName = ObjectTeamsTransformation.genImplementingRoleName(class_name);
+				HashMap<String, Integer> implementingRolebaseTags = CallinBindingManager.getBaseTags(implementingRoleName);
+				classBaseTags.putAll(implementingRolebaseTags);
+				// TODO: check, if the we also need the implicitly inherited tags of the implementing role class!
+		}
+		
+		if (baseTags == null)
+			baseTags = classBaseTags;
+		else
+			baseTags.putAll(classBaseTags);
+		
+		return baseTags;
+	}
+
+    /**
+     * Search the interfaces implemented by the class `cg' for an interface
+     * that is a bound base. 
+     * TODO (SH): should return all such interfaces!
+	 * @param cg
+	 * @return
+	 */
+	private String getTransformedSuperIfc(ClassGen cg) {
+		String[] ifcs = cg.getInterfaceNames();
+		for (int i=0; i<ifcs.length; i++){
+			if (state.interfaceTransformedClasses.contains(ifcs[i]))
+				return ifcs[i];
+		}
+		return null;
+	}
+
+	/**
+	 * Generate a getter method for the base tag field.
+	 * @param cpg
+	 * @param class_name this (base-) class shall carry the new method
+	 * @param fieldName name of the tag field.
+	 * @param abstractFlg should the method be generated as abstract (ie., without a body)?
+	 * @return
+	 */
+	static MethodGen genBaseTagGetter(
+			ConstantPoolGen cpg, String class_name, 
+			String fieldName, int tagValue, boolean abstractFlg) 
+	{
+		int accessFlags = Constants.ACC_PUBLIC;
+		if (abstractFlg)
+			accessFlags |= Constants.ACC_ABSTRACT;
+			
+		InstructionList il = new InstructionList();
+		MethodGen mg = new MethodGen(
+				accessFlags, 
+				Type.SHORT, Type.NO_ARGS, new String[]{}, 
+				"get"+fieldName, class_name, 
+				il, cpg);
+		if (!abstractFlg) {
+			// gen: "return <constant tagValue>"
+			il.append(new PUSH(cpg, tagValue));
+			il.append(InstructionFactory.createReturn(Type.INT));
+		}
+		mg.setMaxStack();
+		mg.setMaxLocals();
+		return mg;
+	}
+	
+    /**
+     *  Insert tag initializations into each constructor.
+     */	
+	public void doTransformCode(ClassGen cg) {
+    	// FIXME(SH): do not declare as CodeTransformer.
+    }
+  
+    /**
+     * @param message
+     */
+    private static void printLogMessage(String message) {
+    	System.out.println(message);
+    }
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ClassEnhancer.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ClassEnhancer.java
new file mode 100644
index 0000000..aa80c98
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ClassEnhancer.java
@@ -0,0 +1,79 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2005-2009 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: ClassEnhancer.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import de.fub.bytecode.classfile.Field;
+import de.fub.bytecode.classfile.Method;
+import de.fub.bytecode.generic.ClassGen;
+import de.fub.bytecode.generic.ConstantPoolGen;
+
+
+
+/**
+ * This interface is used to abstract from the BCEL external transformations.
+ *  
+ * @author Christine Hundt
+ * @author Juergen Widiker
+ * @author Stephan Herrmann
+ */
+public interface ClassEnhancer {
+
+	/**
+	 * Adds the interface 'interfaceName' to the implements clause of class 'cg'.
+	 */
+	public void addImplements(String interfaceName, ClassGen cg);
+	
+	/**
+	 * Adds the method 'm' to the class represented by 'cg'.
+	 * @param m		the method to be added
+	 * @param cg	the ClassGen of the appropriate class
+	 */
+	void addMethod(Method m, ClassGen cg);
+
+	/**
+	 * Adds method 'm' to the class 'cg' or, if a method with the
+	 * same name and signature already exists, replace that method.
+	 * @param method
+	 * @param cg
+	 */
+	void addOrReplaceMethod(Method method, ClassGen cg);
+	
+	/**
+	 * Adds the field 'f' to the class represented by 'cg'.
+	 * @param f
+	 * @param cg
+	 */
+	void addField(Field f, ClassGen cg);
+
+	/**
+	 * Loads the class named 'className'.
+	 * @param className	the name of the class to be loaded
+	 * @param client the transformer on behalf of which we are called, can be used to call checkReadClassAttributes.
+	 */
+	void loadClass(String className, ObjectTeamsTransformation client);
+	
+	/**
+	 * Decapsulation of the method 'm'. This means that the access modifier of this method is set to 'public'.
+	 * @param m							the name of the method to be decapsulated				
+	 * @param className			the name of the belonging class
+	 * @param packageName  the name of the belonging package
+	 * @param cpg						the ConstantPoolGen of the class	
+	 */
+	void decapsulateMethod(Method m, ClassGen cg, String packageName, ConstantPoolGen cpg);
+
+
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/Decapsulation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/Decapsulation.java
new file mode 100644
index 0000000..9f74123
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/Decapsulation.java
@@ -0,0 +1,427 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2003, 2009 Technical University Berlin, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: Decapsulation.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.objectteams.otre.util.CallinBindingManager;
+import org.eclipse.objectteams.otre.util.FieldDescriptor;
+import org.eclipse.objectteams.otre.util.SuperMethodDescriptor;
+
+import de.fub.bytecode.Constants;
+import de.fub.bytecode.classfile.Method;
+import de.fub.bytecode.generic.ClassGen;
+import de.fub.bytecode.generic.ConstantPoolGen;
+import de.fub.bytecode.generic.InstructionFactory;
+import de.fub.bytecode.generic.InstructionList;
+import de.fub.bytecode.generic.MethodGen;
+import de.fub.bytecode.generic.ObjectType;
+import de.fub.bytecode.generic.Type;
+
+/**
+ *  For each base method that is bound by callout and has
+ *  insufficient visibility, the visibility is set to public.
+ *  If the corresponding JMangler-patch is installed, check
+ *  whether the affected base class resides in a sealed package.
+ *  In that case dissallow decapsulation by throwing an IllegalAccessError.
+ *  
+ *  @version $Id: Decapsulation.java 23408 2010-02-03 18:07:35Z stephan $
+ *  @author Stephan Herrmann
+ */
+public class Decapsulation 
+	extends ObjectTeamsTransformation
+	implements Constants 
+{
+	
+//	HashSet modifiedPackages = new HashSet();
+
+	public static class SharedState extends ObjectTeamsTransformation.SharedState {
+		private HashMap /* class_name -> HashSet(callout accessed fields) */<String, HashSet<String>> generatedFieldCalloutAccessors
+			= new HashMap<String, HashSet<String>>();
+		private HashMap /* class_name -> HashSet(super-accessed methods (sign))*/<String, HashSet<String>> generatedSuperAccessors
+    		= new HashMap<String, HashSet<String>>();
+	}
+	@Override
+	SharedState state() {
+		return (SharedState)this.state;
+	}
+   
+    public Decapsulation(SharedState state) {
+    	this(null, state);
+    }
+    public Decapsulation(ClassLoader loader, SharedState state) {
+    	super(loader, state);
+    	// FIXME(SH): can we ever release this transformer and its state?
+    	synchronized(ObjectTeamsTransformation.reentrentTransformations) {
+    		ObjectTeamsTransformation.reentrentTransformations.add(this);
+    	}
+    }
+
+	/**
+	 * Main entry for this transformer.
+	 */
+//	@SuppressWarnings("unchecked")
+	public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {		
+		String          class_name = cg.getClassName();
+		ConstantPoolGen cpg        = cg.getConstantPool();
+		
+		// if class is already transformed by this transformer
+		if (state.interfaceTransformedClasses.contains(class_name))
+			return;
+
+		checkReadClassAttributes(ce, cg, class_name, cpg);
+            
+        // next step starts to transform, so record this class now.
+		state.interfaceTransformedClasses.add(class_name);
+
+		generateFieldAccessForCallout(ce, cg, class_name, cpg);
+		
+		generateSuperAccessors(ce, cg, class_name, cpg);
+
+		HashSet<String> calloutBindings = CallinBindingManager.getCalloutBindings(class_name);
+
+		if (calloutBindings == null) {
+            if(logging) printLogMessage("\nClass " + class_name 
+					+ " requires no callout adjustment.");
+			return; 
+		}
+			
+        if(logging) printLogMessage("\nCallout bindings might be changing class " 
+					+ class_name + ":");
+
+		HashSet<String> oldStyleBinding = new HashSet<String>();
+		
+		// try new style decapsulation first (since 1.2.8):
+		for (String calloutBinding : calloutBindings) {
+			DecapsulationDescriptor desc = new DecapsulationDescriptor();
+			if (!desc.decode(calloutBinding, cg))
+				oldStyleBinding.add(calloutBinding); // old style attribute
+			else if (!desc.existsAlready) 
+				ce.addMethod(desc.generate(class_name, cpg), cg);
+		}
+		
+		if (oldStyleBinding.isEmpty()) return;
+		
+		// --> follows: old style decapsulation for remaining bindings:
+		int pos = class_name.lastIndexOf('.');
+		String package_name = "NO_PACKAGE";
+		if (pos != -1)
+			package_name = class_name.substring(0,pos);
+			
+		Method[] methods = cg.getMethods();
+		for (int i = 0; i < methods.length; i++) {
+			Method m           = methods[i];
+			String method_name = m.getName();
+			
+			boolean requiresAdjustment = CallinBindingManager.
+			requiresCalloutAdjustment(oldStyleBinding, 
+										method_name,
+										m.getSignature());
+				
+			if (requiresAdjustment) {
+				ce.decapsulateMethod(m, cg, package_name, cpg);
+			}
+		}
+	}
+	class DecapsulationDescriptor {
+		short invokeKind;
+		String targetClass;
+		String methodName;
+		String methodSign;
+		Type returnType; 
+		Type[] args;
+		String accessorName;
+		
+		boolean existsAlready;
+		
+		/**
+		 * new style encoding is
+		 * targetClassName ('!' | '?') methodName '.' methodSign 
+		 */
+		boolean decode(String encodedBinding, ClassGen cg) {
+			int sepPos = encodedBinding.indexOf('!');
+			if (sepPos != -1) { // static method:
+				invokeKind = INVOKESTATIC;
+			} else {
+				sepPos = encodedBinding.indexOf('?');
+				if (sepPos != -1) {
+					invokeKind = INVOKEVIRTUAL;
+				} else {
+					return false; // old style
+				}
+			}
+			targetClass = encodedBinding.substring(0, sepPos);
+			int sigPos = encodedBinding.indexOf('(', sepPos);
+			methodName = encodedBinding.substring(sepPos+1, sigPos);
+			methodSign = encodedBinding.substring(sigPos);
+			
+			returnType = Type.getReturnType(methodSign); 
+			args = Type.getArgumentTypes(methodSign);
+
+			accessorName = "_OT$decaps$"+methodName;
+			existsAlready = cg.containsMethod(accessorName, methodSign) != null;
+			if (invokeKind == INVOKEVIRTUAL) {
+				Method existing = cg.containsMethod(methodName, methodSign);
+				if (existing != null && existing.isPrivate())
+					invokeKind = INVOKESPECIAL; // accessing private
+			}
+			
+			return true;
+		}
+		Method generate(String currentClass, ConstantPoolGen cpg) {
+			InstructionList il = new InstructionList();
+			int instanceOffset = 0;
+			short flags = Constants.ACC_PUBLIC;
+			if (invokeKind != INVOKESTATIC) {
+				instanceOffset=1;
+				il.append(InstructionFactory.createThis());
+			} else {
+				flags |= Constants.ACC_STATIC;
+			}
+			int pos= 0;
+			for (int i = 0; i < args.length; i++) {
+				il.append(InstructionFactory.createLoad(args[i], pos+instanceOffset));
+				pos += args[i].getSize();
+			}
+			il.append(new InstructionFactory(cpg).createInvoke(targetClass, methodName, returnType, args, invokeKind));
+			il.append(InstructionFactory.createReturn(returnType));
+			MethodGen newMethod = new MethodGen(flags, returnType, args, /*argNames*/null, accessorName, currentClass, il, cpg);
+			newMethod.setMaxLocals();
+			newMethod.setMaxStack();
+			return newMethod.getMethod();
+		}
+	}
+
+	/**
+	 * Generates getter and setter methods for all fields of the class 'class_name' which are accessed via callout. 
+	 * Informations are received via attributs (CallinBindingManager). 
+	 * @param cg					the ClassGen of the appropriate class
+	 * @param class_name		the name of the class
+	 * @param cpg					the ConstantPoolGen of the class
+	 * @param es					the ExtensionSet to add the new access methods
+	 */
+	private void generateFieldAccessForCallout(ClassEnhancer ce, ClassGen cg, String class_name, ConstantPoolGen cpg) {
+		InstructionFactory factory = null;
+		
+		HashSet<String> addedAccessMethods = state().generatedFieldCalloutAccessors.get(class_name);
+
+		List<FieldDescriptor> getter = CallinBindingManager.getCalloutGetFields(class_name);
+		if (getter != null) {
+	    	factory = new InstructionFactory(cg);
+			Iterator<FieldDescriptor> it = getter.iterator();
+			while (it.hasNext()) {
+				FieldDescriptor fd = it.next();
+				String key = "get_" + fd.getFieldName() + fd.getFieldSignature();
+				if (logging)
+					printLogMessage("Generating getter method "+key);
+				if (addedAccessMethods == null)
+					addedAccessMethods = new HashSet<String>();
+				if (addedAccessMethods.contains(key))
+					continue; // this getter has already been created
+				ce.addMethod(generateGetter(cpg, class_name, fd, factory), cg);
+				addedAccessMethods.add(key);
+				state().generatedFieldCalloutAccessors.put(class_name, addedAccessMethods);
+			}
+		}
+
+		List<FieldDescriptor> setter = CallinBindingManager.getCalloutSetFields(class_name);
+		if (setter != null) {
+			if (factory == null)
+		    	factory = new InstructionFactory(cg);
+			Iterator<FieldDescriptor> it = setter.iterator();
+			while (it.hasNext()) {
+				FieldDescriptor fd = it.next();
+				String key = "set_"+fd.getFieldName()+fd.getFieldSignature();
+				if (logging)
+					printLogMessage("Generating setter method "+key);
+				if (addedAccessMethods == null)
+					addedAccessMethods = new HashSet<String>();
+				if (addedAccessMethods.contains(key))
+					continue; // this setter has already been created
+				ce.addMethod(generateSetter(cpg, class_name, fd, factory), cg);
+				addedAccessMethods.add(key);
+				state().generatedFieldCalloutAccessors.put(class_name, addedAccessMethods);
+			}
+		}
+	}
+
+
+	/**
+	 * Generates a getter method for the field described by 'fd' in the class 'class_name'. 
+	 * @param cpg					the ConstantPoolGen of the class
+	 * @param class_name		the name of the class
+	 * @param fd						the FieldDescriptor describing the affected field
+	 * @param factory				an InstructionFactory for this class
+	 * @return							the generated getter method
+	 */
+	private Method generateGetter(ConstantPoolGen cpg, String class_name, FieldDescriptor fd, InstructionFactory factory) {
+		String fieldName = fd.getFieldName();
+		Type fieldType =  Type.getType(fd.getFieldSignature());
+		Type baseType = new ObjectType(class_name);
+		
+		InstructionList il = new InstructionList();
+		String[] argumentNames;
+		Type[]   argumentTypes;
+		if (fd.isStaticField()) {
+			argumentNames = new String[0];
+			argumentTypes = new Type[0];
+		} else {
+			argumentNames = new String[] {"base_obj"};
+			argumentTypes = new Type[]   {baseType};
+		}
+		MethodGen mg = new MethodGen((Constants.ACC_PUBLIC|Constants.ACC_STATIC),
+	 			  												  fieldType,
+																  argumentTypes,
+																  argumentNames,
+																  OT_PREFIX+"get$"+fieldName,
+																  class_name,
+																  il, cpg);
+		if (!fd.isStaticField())
+			il.append(InstructionFactory.createLoad(baseType, 0)); // first argument is at slot 0 in static methods
+		short fieldKind = fd.isStaticField()?Constants.GETSTATIC:Constants.GETFIELD;
+		il.append(factory.createFieldAccess(class_name, fieldName, fieldType, fieldKind));
+		il.append(InstructionFactory.createReturn(fieldType));
+
+		mg.removeNOPs();
+		mg.setMaxStack();
+		mg.setMaxLocals();
+		return mg.getMethod();
+	}
+	
+
+	/**
+	 * Generates a setter method for the field described by 'fd' in the class 'class_name'. 
+	 * @param cpg					the ConstantPoolGen of the class
+	 * @param class_name		the name of the class
+	 * @param fd						the FieldDescriptor describing the affected field
+	 * @param factory				an InstructionFactory for this class
+	 * @return							the generated getter method
+	 */
+	private Method generateSetter(ConstantPoolGen cpg, String class_name, FieldDescriptor fd, InstructionFactory factory ) {
+		String fieldName = fd.getFieldName();
+		Type fieldType =  Type.getType(fd.getFieldSignature());
+		Type baseType = new ObjectType(class_name);
+
+		Type[]   argumentTypes;
+		String[] argumentNames;
+		if (fd.isStaticField()) {
+			argumentTypes = new Type[]   { fieldType};
+			argumentNames = new String[] {"new_value"};			
+		} else {
+			argumentTypes = new Type[]   {baseType,   fieldType};
+			argumentNames = new String[] {"base_obj", "new_value"};
+		}
+		
+		InstructionList il = new InstructionList();
+		MethodGen mg = new MethodGen((Constants.ACC_PUBLIC|Constants.ACC_STATIC),
+	 			  												  Type.VOID,
+																  argumentTypes,
+																  argumentNames,
+																  OT_PREFIX+"set$"+fieldName,
+																  class_name,
+																  il, cpg);
+
+		int argumentPosition; // position for the argument holding the new field value.
+		if (!fd.isStaticField()) {
+			il.append(InstructionFactory.createLoad(baseType, 0)); // first argument is at slot 0 in static methods
+			argumentPosition = 1;
+		} else {
+			argumentPosition = 0;
+		}
+		il.append(InstructionFactory.createLoad(fieldType, argumentPosition));
+		short fieldKind = fd.isStaticField()?Constants.PUTSTATIC:Constants.PUTFIELD;
+		il.append(factory.createFieldAccess(class_name, fieldName, fieldType, fieldKind));
+		il.append(InstructionFactory.createReturn(Type.VOID));
+
+		mg.removeNOPs();
+		mg.setMaxStack();
+		mg.setMaxLocals();
+		return mg.getMethod();
+	}
+	
+	private void generateSuperAccessors(ClassEnhancer ce, ClassGen cg, String class_name, ConstantPoolGen cpg) {
+		InstructionFactory factory = null;
+		
+		HashSet<String> addedAccessMethods = state().generatedSuperAccessors.get(class_name);
+
+		List<SuperMethodDescriptor> methods = CallinBindingManager.getSuperAccesses(class_name);
+		if (methods != null) {
+	    	factory = new InstructionFactory(cg);
+	    	for (SuperMethodDescriptor superMethod : methods) {
+				String key = superMethod.methodName+'.'+superMethod.signature;
+				if (logging)
+					printLogMessage("Generating super access method "+key);
+				if (addedAccessMethods == null)
+					addedAccessMethods = new HashSet<String>();
+				if (addedAccessMethods.contains(key))
+					continue; // this accessor has already been created
+				ce.addMethod(generateSuperAccessor(cpg, class_name, superMethod, factory), cg);
+				addedAccessMethods.add(key);
+				state().generatedSuperAccessors.put(class_name, addedAccessMethods);
+			}
+		}
+	}
+	
+	private Method generateSuperAccessor(ConstantPoolGen cpg, String className, SuperMethodDescriptor superMethod, InstructionFactory factory) 
+	{ 
+		int endPos = superMethod.signature.indexOf(')');
+		String segment = superMethod.signature.substring(1, endPos);
+		String[] typeNames = (segment.length() > 0) ? segment.split(",") : new String[0];
+		Type[] argTypes = new Type[typeNames.length];
+		for (int i = 0; i < argTypes.length; i++) 
+			argTypes[i] = Type.getType(typeNames[i]);
+		
+		int index = superMethod.signature.lastIndexOf(')') + 1;
+		Type returnType = Type.getType(superMethod.signature.substring(index));
+		
+		Type baseType = new ObjectType(className);
+		Type[] wrapperTypes = new Type[argTypes.length+1];
+		System.arraycopy(argTypes, 0, wrapperTypes, 1, argTypes.length);
+		wrapperTypes[0] = baseType;
+		String[] argNames = new String[wrapperTypes.length];
+		for (int i = 0; i < argNames.length; i++) {
+			argNames[i] = "arg"+i;
+		}
+		InstructionList il = new InstructionList();
+		MethodGen mg = new MethodGen((Constants.ACC_PUBLIC|Constants.ACC_STATIC),
+									 returnType,
+									 wrapperTypes,
+									 argNames,
+									 OT_PREFIX+superMethod.methodName+"$super",
+									 className,
+									 il, cpg);
+		il.append(InstructionFactory.createLoad(baseType, 0)); // first argument is base instance
+		for (int i = 0; i < argTypes.length; i++) 
+			il.append(InstructionFactory.createLoad(argTypes[i], i+1));
+		
+		// if super method is also callin bound directly invoke the orig-version 
+		// (to avoid that BaseMethodTransformation.checkReplaceWickedSuper() has to rewrite this code again): 
+		String methodName = (CallinBindingManager.isBoundBaseMethod(superMethod.superClass, superMethod.methodName, superMethod.signature))
+								? genOrigMethName(superMethod.methodName)
+								: superMethod.methodName;
+		
+		il.append(factory.createInvoke(superMethod.superClass, methodName, returnType, argTypes, INVOKESPECIAL));
+		il.append(InstructionFactory.createReturn(returnType));
+		mg.setMaxStack();
+		mg.setMaxLocals();
+		return mg.getMethod();
+	}
+	
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java
new file mode 100644
index 0000000..48e949d
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java
@@ -0,0 +1,162 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2009 Stephan Herrmann
+ *  
+ * All rights reserved. This program and the accompanying materials
+ * 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: LiftingParticipantTransformation.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+
+import org.objectteams.Team;
+
+import de.fub.bytecode.Constants;
+import de.fub.bytecode.classfile.Method;
+import de.fub.bytecode.generic.ALOAD;
+import de.fub.bytecode.generic.BranchInstruction;
+import de.fub.bytecode.generic.ClassGen;
+import de.fub.bytecode.generic.ConstantPoolGen;
+import de.fub.bytecode.generic.DUP;
+import de.fub.bytecode.generic.GOTO;
+import de.fub.bytecode.generic.IFNULL;
+import de.fub.bytecode.generic.INVOKESPECIAL;
+import de.fub.bytecode.generic.InstructionFactory;
+import de.fub.bytecode.generic.InstructionHandle;
+import de.fub.bytecode.generic.InstructionList;
+import de.fub.bytecode.generic.LDC;
+import de.fub.bytecode.generic.MethodGen;
+import de.fub.bytecode.generic.NEW;
+import de.fub.bytecode.generic.NOP;
+import de.fub.bytecode.generic.ObjectType;
+import de.fub.bytecode.generic.POP;
+import de.fub.bytecode.generic.Type;
+
+/**
+ * If the property ot.lifting.participant is set transform all lift methods and insert 
+ * static calls to createRole(Team,Object,String)Object; to the registered lifting participant
+ * before creating a new role. If createRole returns non-null then that value is taken
+ * as the new role, otherwise lifting proceeds as normal, i.e., normally creates a new role.
+ *  
+ * @author stephan
+ * @since 1.3.1
+ */
+public class LiftingParticipantTransformation extends ObjectTeamsTransformation {
+	
+
+	private static String PARTICIPANT_NAME = System.getProperty("ot.lifting.participant");
+	private static boolean checked = false;
+	
+	final private static String LIFT_PREFIX = "_OT$liftTo"; 
+
+	private static final String WRONG_ROLE_EXCEPTION = "org.objectteams.WrongRoleException";
+	private static final String LIFTING_FAILED_EXCEPTION = "org.objectteams.LiftingFailedException";
+	private static final String LIFTING_VETO_EXCEPTION = "org.objectteams.LiftingVetoException";
+	
+	private static final ObjectType iLiftingParticipant = new ObjectType("org.objectteams.ILiftingParticipant"); 
+
+	private static final String CREATE_ROLE_METHOD = "createRole";
+	private static final String LIFTING_PARTICIPANT_FIELD = "_OT$liftingParticipant";
+	
+	public LiftingParticipantTransformation(SharedState state) { this(null, state); }
+
+	public LiftingParticipantTransformation(ClassLoader loader, SharedState state) { super(loader, state); }
+
+	public void doTransformCode(ClassGen cg) 
+	{
+		if (PARTICIPANT_NAME == null) return;
+	
+		if (!classNeedsTeamExtensions(cg)) return;
+		
+		synchronized (LiftingParticipantTransformation.class) {
+			if (!checked) {
+				try {
+					// install a shared instance into class Team:
+					Class<?> participantClass = loader.loadClass(PARTICIPANT_NAME);
+					Team.class.getField(LIFTING_PARTICIPANT_FIELD).set(null, participantClass.newInstance());
+				} catch (Exception e) {
+					new IllegalArgumentException("Lifting participant "+PARTICIPANT_NAME+" is invalid.", e).printStackTrace();
+					PARTICIPANT_NAME = null;
+				}
+				checked = true;
+			}
+		}
+		
+    	factory = new InstructionFactory(cg);
+    	ConstantPoolGen cpg        = cg.getConstantPool();
+    	String          class_name = cg.getClassName();
+    	
+    	// FIXME(SH): evaluate inclusion/exclusion filter per className
+			
+    	Method[] methods = cg.getMethods();
+    	for (int i=0; i<methods.length; i++) {
+    		Method m           = methods[i];
+    		if (!m.getName().startsWith(LIFT_PREFIX))
+    			continue;
+    		
+			cg.replaceMethod(m, m = weaveLiftingParticipant(m, class_name, cpg));
+    	}
+	}
+
+	private Method weaveLiftingParticipant(Method m, String className, ConstantPoolGen cpg) {
+		MethodGen mg = new MethodGen(m, className, cpg);
+		InstructionList il = mg.getInstructionList();
+		InstructionHandle[] ihs = il.getInstructionHandles();
+		for (int i=0; i<ihs.length; i++) {
+			InstructionHandle ih = ihs[i];
+			if (ih.getInstruction() instanceof NEW) 
+			{
+				NEW newInstr = (NEW) ih.getInstruction();
+				Type newType = newInstr.getType(cpg);
+				String newTypeName = newType.toString();
+				
+				// don't transform creation of these exceptions:
+				if (newTypeName.equals(LIFTING_FAILED_EXCEPTION)) continue;
+				if (newTypeName.equals(LIFTING_VETO_EXCEPTION)) continue;
+				if (newTypeName.equals(WRONG_ROLE_EXCEPTION)) continue;
+				
+				ih.setInstruction(new NOP()); // keep this handle for the enclosing switch
+				
+				InstructionList inset = new InstructionList();
+				// fetch instance of lifting participant from Team._OT$liftingParticipant
+				inset.append(factory.createFieldAccess(teamClassType.getClassName(),  
+													   LIFTING_PARTICIPANT_FIELD, 
+													   iLiftingParticipant, 
+													   Constants.GETSTATIC));
+				inset.append(new ALOAD(0)); 						// load the team
+				inset.append(new ALOAD(1));							// load the base
+				inset.append(new LDC(cpg.addString(newTypeName)));	// load the role class name
+				inset.append(factory.createInvoke(iLiftingParticipant.getClassName(),	// receiver type 
+												  CREATE_ROLE_METHOD, 					// method
+												  object, 								// return type
+												  new Type[] {teamType, object, string},// arg types
+												  Constants.INVOKEINTERFACE));
+				inset.append(new DUP());	// keep value after null-check
+				BranchInstruction isNull = new IFNULL(null);
+				inset.append(isNull);
+				inset.append(factory.createCast(object, newType));
+				// let goto skip: 0: new R, 1: dup, 2: aload_0, 3: aload_1, (4: cast if needed), 4: o. 5: invokespecial<init>
+				int invokeOffset = 4;
+				if (!(ihs[i+invokeOffset].getInstruction() instanceof INVOKESPECIAL))
+					invokeOffset++;
+				inset.append(new GOTO(ihs[i+invokeOffset+1])); // one past above sequence
+				
+				// continue here if null, i.e., perform the original new-instruction
+				InstructionHandle goOn = inset.append(new POP()); // discard dup'ed value from above
+				isNull.setTarget(goOn);
+				inset.append(newInstr); // re-insert deleted first instruction
+				
+				il.append(ih, inset);
+			}
+		}
+		return mg.getMethod();
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/LowerableTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/LowerableTransformation.java
new file mode 100644
index 0000000..1db8d9f
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/LowerableTransformation.java
@@ -0,0 +1,72 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2009 Stephan Herrmann
+ *  
+ * All rights reserved. This program and the accompanying materials
+ * 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: LowerableTransformation.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import de.fub.bytecode.Constants;
+import de.fub.bytecode.generic.ClassGen;
+import de.fub.bytecode.generic.MethodGen;
+import de.fub.bytecode.generic.Type;
+
+/**
+ * This transformer helps legacy class files pre 1.3.2 to cope with changes re ILowerable.lower().
+ * 
+ * @author stephan
+ * @since 1.3.2
+ */
+public class LowerableTransformation extends ObjectTeamsTransformation {
+	
+	// static because checking is performed without instance context (from scanClassOTAttribrutes)
+	// using ClassGen rather than names should, however, avoid conflicts between different class loaders etc.
+	static Set<ClassGen> transformationRequests = new HashSet<ClassGen>();
+	
+	public LowerableTransformation(SharedState state) { this(null, state); }
+
+	public LowerableTransformation(ClassLoader loader, SharedState state) {
+		super(loader, state);
+	}
+	
+	public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
+		synchronized (transformationRequests) {
+			if (!transformationRequests.remove(cg))
+				return;
+		}
+		// yes, a change was requested, add method "public abstract Object lower();"
+		MethodGen lower = new MethodGen(Constants.ACC_PUBLIC|Constants.ACC_ABSTRACT, object, new Type[0], new String[0], "lower", cg.getClassName(), null, cg.getConstantPool());
+		ce.addMethod(lower.getMethod(), cg);
+	}
+
+	/** After reading the compiler version of a class file, check if this class is affected by the change. */
+	public static void checkRequiresAdaptation(int major, int minor, int revision, ClassGen cg) {
+		// only 1.3.1 and below:
+		if (major > 1) return;
+		if (major == 1 && minor > 3) return;
+		if (major == 1 && minor == 3 && revision > 1) return;
+		// only interfaces ...
+		if (!cg.isInterface()) return;
+		// ... implementing ILowerabel:
+		for (String superInterface : cg.getInterfaceNames()) {
+			if ("org.objectteams.Team$ILowerable".equals(superInterface))
+				synchronized(transformationRequests) {
+					transformationRequests.add(cg);
+					return;
+				}
+		}
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTConstants.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTConstants.java
new file mode 100644
index 0000000..d207abd
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTConstants.java
@@ -0,0 +1,178 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: OTConstants.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import de.fub.bytecode.generic.*;
+
+
+/**
+ * Constants for the Object Teams Runtime Environment
+ * @author Christine Hundt
+ * @author Stephan Herrmann
+ */
+public interface OTConstants {
+	// ------------------------------------------
+	// ---------- Types: ------------------------
+	// ------------------------------------------
+	/**                            Type <tt>java.lang.Object</tt> */
+    ObjectType object        = new ObjectType("java.lang.Object");
+	/**                            Type <tt>java.lang.Object</tt> */
+    ObjectType string        = new ObjectType("java.lang.String");
+    /**                            Type <tt>java.lang.Class</tt> */
+    ObjectType classType = new ObjectType("java.lang.Class");
+    /** 						   Signature of java.lang.Class#getMethod(String, Class...) */
+    public static final Type[] getMethodSignature = new Type[]{string, new ArrayType(classType, 1)};
+    /**                            Type <tt>java.lang.reflect.Method</tt> */
+    ObjectType methodType = new ObjectType("java.lang.reflect.Method");
+    /**                            Type <tt>org.objectteams.Team</tt> */
+    String     teamName          = "org.objectteams.ITeam";
+    ObjectType teamType          = new ObjectType(teamName);
+    String     teamClassName     = "org.objectteams.Team";
+    ObjectType teamClassType     = new ObjectType(teamClassName);
+	/**                            Type <tt>org.objectteams.LiftingVetoException</tt> */
+    ObjectType liftingVeto   = new ObjectType("org.objectteams.LiftingVetoException");
+    /**                            Type <tt>org.eclipse.objectteams.otre.OTREInternalError</tt> */	
+    ObjectType internalError = new ObjectType("org.eclipse.objectteams.otre.OTREInternalError");
+	/**                            Type <tt>org.eclipse.objectteams.otre.OTREInternalError</tt> */	
+	ObjectType notProvidedError = new ObjectType("org.objectteams.ResultNotProvidedError");
+	/**                            Type <tt>org.eclipse.objectteams.otre.UnsupportedFeatureException</tt> */	
+	ObjectType unsupportedFeature = new ObjectType("org.objectteams.UnsupportedFeatureException");
+	
+	ObjectType threadType  = new ObjectType("java.lang.Thread");
+	
+	/**                          Type <tt>org.objectteams.Team[]</tt> */
+    ArrayType  teamArray   = new ArrayType(teamType, 1);
+	/**                          Type <tt>int[]</tt> */
+    ArrayType  intArray    = new ArrayType(Type.INT, 1);
+	/**                          Type <tt>java.lang.Object[]</tt> */
+    ArrayType  objectArray = new ArrayType(object, 1);
+
+	ObjectType roleSetType = new ObjectType("java.util.HashSet");
+	
+	ObjectType nullPointerException = new ObjectType("java.lang.NullPointerException");
+
+	String STRING_BUFFER_NAME    = "java.lang.StringBuffer";
+	
+	// ============ VERSION: ==============
+	public static final int    OT_VERSION_MAJOR = 0;
+    public static final int    OT_VERSION_MINOR = 8;
+    public static final int    OT_REVISION = 18;
+    
+    // required compiler revision in the 0.9 stream:
+    public static final int    OT09_REVISION = 26;
+
+    // required compiler revision in the 1.0 stream:
+    public static final int    OT10_REVISION = 0;
+    
+    // required compiler revision in the 1.1 stream:
+    public static final int    OT11_REVISION = 0;
+
+    // required compiler revision in the 1.2 stream:
+    public static final int    OT12_REVISION = 0;
+
+    // required compiler revision in the 1.3 stream:
+    public static final int    OT13_REVISION = 0;
+
+    // required compiler revision in the 1.4 stream:
+    public static final int    OT14_REVISION = 1;
+
+    // ------------------------------------------
+	// ---------- Flags and Modifiers: ----------
+	// ------------------------------------------
+	/** Bytecode encoding of modifier <tt>team</tt> */
+    final static int TEAM  = 0x8000;
+
+	// 'CallinFlags':
+	final static int OVERRIDING =1; // this role method is inherited from the super role
+	final static int WRAPPER =2; // this is a role method wrapper (in a team)
+
+	// ------------------------------------------
+	// ---------- Names: ------------------------
+	// ------------------------------------------
+	/**                              General prefix to mark all generated names. */
+    final static String OT_PREFIX = "_OT$";
+	/**                              Name of the base reference of roles. */
+    final static String BASE      = "_OT$base";
+	/**                              Name of the getBase method of roles (ifc and class). */
+    final static String GET_BASE  = "_OT$getBase";
+	/**							  Prefix for otdt. */
+	final static String OTDT_PREFIX = "__OT__";
+	/**							  Tsuper marker interface prefix. */
+	final static String TSUPER_PREFIX = "TSuper__OT__";
+	/** field for storing the class object in JVM < 5 */
+	final static String SELF_CLASS = "_OT$self_class$";
+
+	// -----------------------------------------
+	// ---------- Signature enhancement --------
+	// -----------------------------------------
+	
+	/**                              Name of synthetic parameter. */
+	final static String TEAMS     = "_OT$teams";
+	/**                              Name of synthetic parameter. */
+	final static String TEAMIDS   = "_OT$teamIDs";
+	/**                              Name of synthetic parameter. */
+	final static String IDX       = "_OT$idx";
+	/**                              Name of synthetic parameter. */
+	final static String BIND_IDX       = "_OT$bindIdx";
+	/**                              Name of synthetic parameter. */
+	final static String UNUSED    = "_OT$unusedArgs";
+	/**                              Name of synthetic parameter. */
+    final static String BASE_METH_TAG = "_OT$baseMethTag";
+
+	/**                            Number of extra arguments in enhanced signatures. */
+	static final int EXTRA_ARGS  = 6;
+	/**                            Position of generated argument. */
+	static final int TEAMS_ARG   = 1;
+	/**                            Position of generated argument. */
+	static final int TEAMIDS_ARG = 2;
+	/**                            Position of generated argument. */
+	static final int IDX_ARG     = 3;
+	/**                            Position of generated argument. */
+	static final int BIND_IDX_ARG = 4;
+	/**                            Position of generated argument. */
+    static final int BASE_METH_ARG = 5; // ## really const? also UNUSED?
+	/**                            Position of generated argument. */
+	static final int UNUSED_ARG  = 6;
+
+	// ---------- Features to prevent/aid garbage collection: ----------
+	String ROLE_SET              = OT_PREFIX + "roleSet";    // field  HashSet _OT$roleSet;
+	String ADD_ROLE              = OT_PREFIX + "addRole";    // method void _OT$addRole(Object)
+	String REMOVE_ROLE           = OT_PREFIX + "removeRole"; // method void _OT$removeRole(Object)
+
+	String IBOUND_BASE           = "org.objectteams.IBoundBase"; // interface comprising the above methods.
+	
+	
+	// -----------------------------------------
+	// ---------- Other constants --------
+	// -----------------------------------------
+	/**							Marker for comment lines in the team config file. */    
+	static final String COMMENT_MARKER = "#";
+	/**							Constant for invalid base method tags (a method can not be relocated from a base call). */    
+	static final int INVALID_BASE_METHOD_TAG = -2;
+	
+	// --------------------------------------------------------------
+	// ---------- Separator for static replace binding keys ---------
+	// --------------------------------------------------------------
+	 static final String STATIC_REPLACE_BINDING_SEPARATOR = ".."; 
+	 
+	 // ------------------------------------------------------------------------------------
+	 // ---------- Linenumbers with more information.  ----------------------
+	 // ---------- (semantic linenumber) For debugging purpose.  ------
+	 // ------------------------------------------------------------------------------------
+	 static final int STEP_OVER_LINENUMBER = Short.MAX_VALUE *2;
+	 static final int STEP_INTO_LINENUMBER = STEP_OVER_LINENUMBER - 1;
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTREInternalError.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTREInternalError.java
new file mode 100644
index 0000000..04110e2
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/OTREInternalError.java
@@ -0,0 +1,62 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2003-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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$
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+/**
+ * @author stephan 
+ */
+public class OTREInternalError extends Error {
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static final String _bugmsg = 
+        "An error occurred in the Object Teams runtime environment.\n"+
+        "We would appreciate if you send a bug report to bugs@ObjectTeams.org.\n"+
+        "Please include your program (if possible) and the following diagnostic\n"+
+        "in your report. -- Thank you. The OT/J developers\n";
+    /**
+     * 
+     */
+    public OTREInternalError() {
+        super(_bugmsg);
+    }
+
+    /**
+     * @param message
+     */
+    public OTREInternalError(String message) {
+        super(_bugmsg+message);
+    }
+
+    /**
+     * @param cause
+     */
+    public OTREInternalError(Throwable cause) {
+        super(_bugmsg+cause.toString());
+    }
+
+    /**
+     * @param message
+     * @param cause
+     */
+    public OTREInternalError(String message, Throwable cause) {
+        super(_bugmsg+message+cause.toString());
+    }
+
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java
new file mode 100644
index 0000000..7158659
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java
@@ -0,0 +1,2259 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: ObjectTeamsTransformation.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.objectteams.otre.util.AnnotationHelper;
+import org.eclipse.objectteams.otre.util.AttributeReadingGuard;
+import org.eclipse.objectteams.otre.util.CallinBindingManager;
+import org.eclipse.objectteams.otre.util.RoleBaseBinding;
+
+import de.fub.bytecode.Constants;
+import de.fub.bytecode.Repository;
+import de.fub.bytecode.classfile.Attribute;
+import de.fub.bytecode.classfile.Constant;
+import de.fub.bytecode.classfile.ConstantUtf8;
+import de.fub.bytecode.classfile.InnerClass;
+import de.fub.bytecode.classfile.InnerClasses;
+import de.fub.bytecode.classfile.JavaClass;
+import de.fub.bytecode.classfile.LineNumberTable;
+import de.fub.bytecode.classfile.Method;
+import de.fub.bytecode.classfile.Unknown;
+import de.fub.bytecode.generic.*;
+
+/**
+ * Superclass for all transformations in this package.
+ * This class and its subclasses depends on neither JMangler nor JPLIS.
+ * 
+ * Contains common fields and methods.
+ *
+ * @author  Christine Hundt
+ * @author  Stephan Herrmann
+ */
+public abstract class ObjectTeamsTransformation
+	implements OTConstants
+{
+	
+	// ------------------------------------------
+	// ---------- Flags: ------------------------
+	// ------------------------------------------
+
+	/** Check whether <tt>flags</tt> denote a generated callin wrapper. */
+    static boolean isCallinWrapper(Method m, ClassGen cg) {
+		return methodHasCallinFlags(m, cg, WRAPPER);
+	}
+
+	/** Check whether <tt>flags</tt> denote a callin method from the source code. */
+    static boolean isCallin(Method m, ClassGen cg) {
+    	return (methodHasCallinFlags(m, cg, 0) && !isCallinWrapper(m, cg));
+    }
+
+
+	// ------------------------------------------
+	// ---------- Names: ------------------------
+	// ------------------------------------------
+
+	/** Generate the name for a backup of a method. */
+    static String genOrigMethName(String methName) {
+        return "_OT$" + methName + "$orig";
+    }
+
+	/** Generate the name for a chaining wrapper. */
+    static String genChainMethName(String methName) {
+        return "_OT$" + methName + "$chain";
+    }
+
+    static ArrayList<ObjectTeamsTransformation> reentrentTransformations = new ArrayList<ObjectTeamsTransformation>();
+    
+    /** Common factory for all tranformers.
+	 *	To be initialized once we get a class for transformation. */
+	InstructionFactory factory;
+
+    /** State shared among all instances that work for the same class loader. */
+    public static class SharedState {
+    	/** ArrayList of classes whose interfaces have already been transformed by this transformer/classloader combo. */
+    	ArrayList<String> interfaceTransformedClasses = new ArrayList<String>();
+    }
+    /** Reference to the shared state of transformers. */
+    final SharedState state;
+
+    SharedState state() {
+    	return state;
+    }
+    
+    /** Which class loader are we working for? */
+    protected ClassLoader loader;
+    
+	public ObjectTeamsTransformation(SharedState state) { this(null, state); }
+
+	public ObjectTeamsTransformation(ClassLoader loader, SharedState state) {
+		this.loader = loader;
+		this.state = state;
+	}
+
+	// ------------------------------------------
+	// ---------- Logging: ----------------------
+	// ------------------------------------------
+	/** Initialized from property <tt>ot.log</tt>. */
+    static boolean logging = false;
+
+    static {
+        if(System.getProperty("ot.log") != null)
+            logging = true;
+    }
+
+	/** Print <tt>message</tt> only if <tt>logging</tt> is true. */
+    public static void printLogMessage(String message) {
+        System.out.println(message);
+    }
+	
+	//	------------------------------------------
+	// ---------- use the following file as config file for additional active teams: --------
+	// ------------------------------------------
+	 /** Initialized from property <tt>ot.teamconfig</tt>. */
+	 
+	 static String TEAM_CONFIG_FILE = null;
+
+	 static {
+		TEAM_CONFIG_FILE = System.getProperty("ot.teamconfig");
+	 }
+	 
+	 //	------------------------------------------
+	 // ---------- Compatibility with different compiler versions: --------
+	 // ------------------------------------------
+	 
+	 // compiler 1.2.4 introduces isSuperAccess flag for basecall surrogate:
+	 protected static boolean IS_COMPILER_GREATER_123 = false;
+	 
+	 protected static boolean IS_COMPILER_13X_PLUS = false;
+	 
+	 protected static boolean IS_COMPILER_14X_PLUS = false;
+
+	 // ------------------------------------------
+	 // ---------- This flag must currently be true for OT/Equinox: ----------------------
+	 // ------------------------------------------
+	 /** Initialized from property <tt>ot.equinox</tt>. */
+	 public static boolean WORKAROUND_REPOSITORY = false;
+	 
+	 static {
+	 	if(System.getProperty("ot.equinox") != null)
+	 		WORKAROUND_REPOSITORY = true;
+	 }
+	 
+	 // ------------------------------------------
+	 // ---------- Debugging: ----------------------
+	 // ------------------------------------------
+	 /** Initialized from property <tt>ot.debug</tt>. */
+	 static boolean debugging = false;
+	 
+	 static {
+	 	if(System.getProperty("ot.debug") != null)
+	 		debugging = true;
+	 }
+	 
+	// -------------------------------------------------------
+	// ---------- Modes for implicit team activateion --------
+	// -------------------------------------------------------
+	enum ImplicitActivationMode { NEVER, ANNOTATED, ALWAYS }
+	static ImplicitActivationMode implicitActivationMode = ImplicitActivationMode.ANNOTATED;
+	static {
+		String prop = System.getProperty("ot.implicit.team.activation");
+		for (ImplicitActivationMode mode : ImplicitActivationMode.values()) {
+			if (mode.name().equals(prop)) {
+				implicitActivationMode = mode;
+				break;
+			}
+		}
+	}
+
+	// -----------------------------------------
+	// ---------- Signature enhancement --------
+	// -----------------------------------------
+
+	/**
+	 *  Prepend hidden arguments to the signature.
+	 *  This methods only treats argument names.
+	 * @see #enhanceArgumentTypes
+	 *  The arguments are:
+	 *  <dl>
+	 *  <dt><tt>Team[] _OT$teams</tt></dt>
+	 *      <dd>array of active Teams affecting the current base method.
+	 *  <dt><tt>int[] _OT$teamIDs</tt></dt>
+	 *      <dd>array of IDs of the above Teams.
+	 *  <dt><tt>int _OT$idx</tt></dt>
+	 *      <dd>index into above arrays: the Team currently being processed.
+	 *  <dt><tt>Object[] _OT$unusedArgs</tt></dt>
+	 *      <dd>array of arguments which are unused by the current role method.
+	 *  </dl>
+	 *  @param argumentNames array of original argument names.
+	 *  @return augmented array of argument names.
+	 */
+    static String[] enhanceArgumentNames(String[] argumentNames) {
+		return enhanceArgumentNames(argumentNames, 0);
+	}
+
+	/**
+	 *  Prepend hidden arguments to the signature.
+	 *  This methods only treats argument names.
+	 * @see #enhanceArgumentTypes
+	 *  The arguments are:
+	 *  <dl>
+	 *  <dt><tt>Team[] _OT$teams</tt></dt>
+	 *      <dd>array of active Teams affecting the current base method.
+	 *  <dt><tt>int[] _OT$teamIDs</tt></dt>
+	 *      <dd>array of IDs of the above Teams.
+	 *  <dt><tt>int _OT$idx</tt></dt>
+	 *      <dd>index into above arrays: the Team currently being processed.
+	 *  <dt><tt>Object[] _OT$unusedArgs</tt></dt>
+	 *      <dd>array of arguments which are unused by the current role method.
+	 *  </dl>
+	 *  @param argumentNames array of original argument names.
+	 *  @param idx position where new arguments should be inserted into
+	 *             <tt>originalArgumentTypes</tt>.
+	 *  @return augmented array of argument names.
+	 */
+    static String[] enhanceArgumentNames(String[] argumentNames, int idx) {
+  
+    	String[] enhancedArgumentNames =
+			new String[argumentNames.length + EXTRA_ARGS];
+
+        for (int j=0; j<idx; j++)
+            enhancedArgumentNames[j] = argumentNames[j];
+
+        enhancedArgumentNames [idx + TEAMS_ARG     - 1] = TEAMS;
+        enhancedArgumentNames [idx + TEAMIDS_ARG   - 1] = TEAMIDS;
+        enhancedArgumentNames [idx + IDX_ARG       - 1] = IDX;
+        enhancedArgumentNames [idx + BIND_IDX_ARG  - 1] = BIND_IDX;
+        enhancedArgumentNames [idx + BASE_METH_ARG - 1] = BASE_METH_TAG;
+        enhancedArgumentNames [idx + UNUSED_ARG    - 1] = UNUSED;
+
+        for (int j = idx; j < argumentNames.length; j++)
+            enhancedArgumentNames[j + EXTRA_ARGS] = argumentNames[j];
+       
+        return enhancedArgumentNames;
+    }
+
+	/**
+	 * @see #enhanceArgumentTypes(Type[])
+	 * @param signature String from which to extract the argument types.
+	 * @return
+	 */
+	static Type[] enhanceArgumentTypes(String signature) {
+		Type[] types = Type.getArgumentTypes(signature);
+		return enhanceArgumentTypes(types);
+	}
+
+	/**
+	 *  Prepend hidden arguments to the signature.
+	 *  This methods only treats argument types.
+	 *  @see #enhanceArgumentNames
+	 *
+	 *  @param originalArgumentTypes array of original argument types.
+	 *  @return augmented array of argument names.
+	 */
+    static Type[] enhanceArgumentTypes(Type[] originalArgumentTypes) {
+		return enhanceArgumentTypes(originalArgumentTypes, 0, true);
+	}
+
+	/**
+	 *  Prepend hidden arguments to the signature.
+	 *  This methods only treats argument types.
+	 *  @see #enhanceArgumentNames
+	 *
+	 *  @param originalArgumentTypes array of original argument types.
+	 *  @param idx position where new arguments should be inserted into
+	 *             <tt>originalArgumentTypes</tt>.
+	 *  @param createUnused should the <tt>unusedArgs</tt> argument be created?
+	 *  @return augmented array of argument types.
+	 */
+    static Type[] enhanceArgumentTypes(Type[]  originalArgumentTypes,
+								int     idx,
+								boolean createUnused)
+	{
+    // creates enhanced argument type array:
+    // ..(a1,.., aN) -> ..(Team[], int[], int, Object[], a1, .., aN)
+		int offset = createUnused ? EXTRA_ARGS : EXTRA_ARGS-1;
+
+        Type[] enhancedArgumentTypes =
+			new Type[originalArgumentTypes.length+offset];
+
+        for (int j=0; j<idx; j++)
+            enhancedArgumentTypes[j] = originalArgumentTypes[j];
+
+        enhancedArgumentTypes     [idx+TEAMS_ARG     - 1] = teamArray;
+        enhancedArgumentTypes     [idx+TEAMIDS_ARG   - 1] = intArray;
+        enhancedArgumentTypes     [idx+IDX_ARG       - 1] = Type.INT;
+        enhancedArgumentTypes     [idx+BIND_IDX_ARG	 - 1] = Type.INT;
+        enhancedArgumentTypes     [idx+BASE_METH_ARG - 1] = Type.INT;
+		if (createUnused) {
+			enhancedArgumentTypes [idx+UNUSED_ARG    - 1] = objectArray;
+		}
+
+        for (int j = idx; j < originalArgumentTypes.length; j++)
+            enhancedArgumentTypes[j + EXTRA_ARGS] = originalArgumentTypes[j];
+
+        return enhancedArgumentTypes;
+    }
+
+    /**
+	 * Remove the arguments previously added by
+	 * {@link #enhanceArgumentTypes enhanceArgumentTypes}.
+	 * 
+	 * @param enhancedArgumentTypes
+	 * @param staticFlag
+	 * @return
+	 */
+    // FIXME(SH): obsolete
+    public static Type[] _retrenchArgumentTypes(Type[] enhancedArgumentTypes, boolean staticFlag) {
+    // create retrenched argument type array:
+    // ..(Team[], int[], int, Object[], a1, .., aN) -> ..(a1,.., aN)
+
+        int offset = staticFlag? -1 : 0;
+    	
+        Type[] retrenchedArgumentTypes =
+			new Type[enhancedArgumentTypes.length - EXTRA_ARGS + offset];
+
+        for (int j = EXTRA_ARGS; j < enhancedArgumentTypes.length + offset; j++)
+            retrenchedArgumentTypes[j - EXTRA_ARGS] = enhancedArgumentTypes[j];
+
+        return retrenchedArgumentTypes;
+    }
+
+	// ---------------------------------------------------
+	// ---------- further type and value conversions -----
+	// ---------------------------------------------------
+
+	/**
+	 *  @see #generalizeReturnType(Type)
+	 *  @param signature String from which to extract the return type.
+	 */
+	static Type generalizeReturnType (String signature) {
+		Type type = Type.getReturnType(signature);
+		return generalizeReturnType(type);
+	}
+
+	/**
+	 * Given a return type, determine a reference type to which this type can be
+	 * converted. "Object" if type is VOID.
+	 * 
+	 * @param type
+	 * @return
+	 */
+	static Type generalizeReturnType (Type type) {
+		if (type instanceof ReferenceType) return type;
+		return object;
+	}
+
+	/**
+	 * Get the generalized return type from <tt>sign1</tt>, unless
+	 * <tt>sing2</tt> has void return type. In the latter case return
+	 * <tt>Object</tt>.
+	 * 
+	 * @see #generalizeReturnType(Type)
+	 * @param sign1
+	 * @param sign2
+	 * @return
+	 */
+	static Type generalizeReturnType (String sign1, String sign2) {
+		Type type = Type.getReturnType(sign2);
+		if (type == Type.VOID) return object;
+		return generalizeReturnType(sign1);
+	}
+
+	/**
+	 * Assuming a value of type <tt>oldType</tt> on the stack, convert it to a
+	 * value of type <tt>newType</tt>. Changes instruction list <tt>il</tt>
+	 * after position <tt>ih</tt> or at its end if <tt>ih</tt> is null.
+	 * 
+	 * @param il
+	 * @param ih
+	 * @param oldType
+	 * @param newType
+	 * @return the first inserted instruction or null if no adjustment needed
+	 */
+    InstructionHandle adjustValue (InstructionList il, InstructionHandle ih,
+								   Type oldType, Type newType) {
+		if (ih == null)
+			ih = il.getEnd();
+        if (oldType.equals(newType))
+			return null;
+
+        if (newType == Type.VOID)
+            return il.append(ih, new POP());
+        else if (oldType == Type.VOID)
+            return il.append(ih, InstructionFactory.ACONST_NULL);
+        else if (oldType instanceof BasicType)
+            return il.append(ih, createBoxing((BasicType)oldType));
+        else if (newType instanceof BasicType)
+            return il.append(ih, createUnboxing((BasicType)newType));
+        else
+            return il.append(ih, factory.createCast(oldType, newType));
+    }
+
+	// ------------------------------------------
+	// ---------- (Un-)Boxing: ------------------
+	// ------------------------------------------
+
+	/**
+	 * Get the name of the class suitable for boxing <tt>basicType</tt>.
+	 * 
+	 * @param basicType
+	 * @return
+	 */
+    static String toObjectTypeName(BasicType basicType) {
+        String result = "";
+        switch (basicType.getType()) {
+            case Constants.T_BOOLEAN : result = "java.lang.Boolean";   break;
+            case Constants.T_INT :     result = "java.lang.Integer";   break;
+            case Constants.T_FLOAT :   result = "java.lang.Float";     break;
+            case Constants.T_DOUBLE :  result = "java.lang.Double";    break;
+            case Constants.T_SHORT :   result = "java.lang.Short";     break;
+            case Constants.T_BYTE :    result = "java.lang.Byte";      break;
+            case Constants.T_CHAR :    result = "java.lang.Character"; break;
+            case Constants.T_LONG :    result = "java.lang.Long";      break;
+            default: throw new Error("OTRE failure: Basic Type not supported!!"+basicType);
+        }
+        return result;
+    }
+
+	/**
+	 * Create the instructions needed for boxing a basic type value. The value
+	 * is expected on the stack an will be replaced by the boxed value.
+	 * 
+	 * @param basicType	type of the value on the stack.
+	 * @return an InstructionList containing the conversion instructions.
+	 */
+    InstructionList createBoxing(BasicType basicType) {
+        InstructionList il   = new InstructionList();
+		String boxedTypeName = toObjectTypeName(basicType);
+		                                              // .., result
+        il.append(factory.createNew(boxedTypeName));  // .., result, box,
+
+        if (basicType.equals(Type.DOUBLE) || basicType.equals(Type.LONG)) {
+        // 'double' and 'long' are category 2 computational type:
+            il.append(new DUP_X2());                  // .., box, result, box
+            il.append(new DUP_X2());                  // .., box, box, result, box
+        } else {
+            il.append(new DUP_X1());                  // .., box, result, box
+            il.append(new DUP_X1());                  // .., box, box, result, box
+        }
+        il.append(new POP());                         // .., box, box, result
+        il.append(factory.createInvoke(boxedTypeName,
+                                       Constants.CONSTRUCTOR_NAME,
+                                       Type.VOID,
+                                       new Type[] { basicType },
+                                       Constants.INVOKESPECIAL));
+        return il;
+    }
+
+	/**
+	 * Create the instructions needed for unboxing a basic type value. The value
+	 * is expected on the stack an will be replaced by the unboxed value.
+	 * 
+	 * @param basicType	expected type after unboxing.
+	 * @return an InstructionList containing the conversion instructions.
+	 */
+    InstructionList createUnboxing(BasicType basicType) {
+        InstructionList il   = new InstructionList();
+		String boxedTypeName = toObjectTypeName(basicType);
+        il.append(factory.createCast(object,
+									 new ObjectType(boxedTypeName)));
+        il.append(factory.createInvoke(boxedTypeName,
+									   basicType.toString() + "Value",
+									   basicType,
+									   Type.NO_ARGS,
+									   Constants.INVOKEVIRTUAL));
+        return il;
+    }
+
+    /** Push an integer constant using the most appropriate/compact instruction. */
+    Instruction createIntegerPush(ConstantPoolGen cpg, int val) {
+    	if (val <= 5)
+    		return new ICONST(val);
+    	if (val <= Byte.MAX_VALUE)
+    		return new BIPUSH((byte)val);
+    	if (val <= Short.MAX_VALUE)
+    		return new SIPUSH((short)val);
+    	return new LDC(cpg.addInteger(val));
+    }
+    
+    /** 
+     * Create a throwing instruction for an OTREInternalError.
+     * 
+     * @param cpg
+     * @param il		  instruction list to generate into
+     * @param messagePush push sequence producing the exception message.
+     * @return 			  handle to the first generated instruction
+     */
+	InstructionHandle createThrowInternalError(ConstantPoolGen cpg, InstructionList il, InstructionList messagePush) {
+		InstructionHandle start = il.append(factory.createNew(OTConstants.internalError));
+		il.append(new DUP());
+		il.append(messagePush);
+		il.append(factory.createInvoke(OTConstants.internalError.getClassName(),
+				Constants.CONSTRUCTOR_NAME,
+				Type.VOID,
+				new Type[] { Type.STRING }, 
+				Constants.INVOKESPECIAL));
+		il.append(new ATHROW());
+		return start;
+	}
+
+	/**
+	 * Create a lookswitch from its constituents. Since JVM 1.4 this requires
+	 * sorting of matches.
+	 * 
+	 * @param matches
+	 * @param targets
+	 * @param breaks an array of breaks (GOTOs) whose target will
+	 *               be updated to point to <tt>afterSwitch</tt>
+	 * @param defaultBranch
+	 * @param afterSwitch
+	 * @return the generated instruction.
+	 */
+	static BranchInstruction createLookupSwitch (int[] matches,
+										  InstructionHandle[] targets,
+										  GOTO[]              breaks,
+										  InstructionHandle   defaultBranch,
+										  InstructionHandle   afterSwitch) {
+
+		int numberOfCases = matches.length;
+        for (int i = 0; i < numberOfCases; i++)
+            breaks[i].setTarget(afterSwitch);
+
+        HashMap<Integer, InstructionHandle> match_target_mapping = new HashMap<Integer, InstructionHandle>();
+        for (int i = 0; i < numberOfCases; i++)
+            match_target_mapping.put(Integer.valueOf(matches[i]), targets[i]);
+
+        Arrays.sort(matches);
+        for (int i = 0; i < numberOfCases; i++)
+            targets[i] = match_target_mapping.get(Integer.valueOf(matches[i]));
+
+        BranchInstruction inst = new LOOKUPSWITCH(matches, targets, defaultBranch);
+		return inst;
+	}
+
+	
+    /**
+	 * Read all byte code attributes for a given class. Side-Effect: depending
+	 * on the Referenced-Team attribute, additional classes may be scheduled for
+	 * loading.
+	 * 
+	 * @param ce
+	 * @param cg
+	 * @param class_name
+	 * @param cpg
+	 */
+    public void checkReadClassAttributes(ClassEnhancer ce,
+								         ClassGen cg,
+								  		 String class_name,
+								  		 ConstantPoolGen cpg)
+    {
+    	AttributeReadingGuard guard = AttributeReadingGuard.getInstanceForLoader(this.loader);
+    	boolean addTeamInitializations = false;
+    	List<String> classesToLoad;
+    	synchronized (guard) {
+    		if (!guard.iAmTheFirst(class_name))
+    			return;
+			if (AttributeReadingGuard.isFirstLoadedClass())
+				addTeamInitializations = true;
+			// scan for attributes here, because this transformer is applied first:
+			Attribute[] attrsClass = cg.getAttributes();
+			classesToLoad = scanClassOTAttributes(attrsClass, class_name, cpg, cg);
+			
+			guard.workDone(class_name);
+		}
+    	if (addTeamInitializations)
+    		addTeamInitializations(cg, ce);
+    	
+		Iterator<String> it = classesToLoad.iterator();
+		while (it.hasNext()) {
+			String next = it.next();
+            if(logging) printLogMessage("Loading of class " + next + " will be forced now!");
+			ce.loadClass(next, this);
+		}
+			
+		// scan for parameter bindings:
+		Method[] possibleRoleMethods = cg.getMethods();
+		for (int i=0; i<possibleRoleMethods.length; i++) {
+			Method meth = possibleRoleMethods[i];
+			Attribute[] attrsMethod = meth.getAttributes();
+			scanMethodOTAttributes(attrsMethod, class_name, meth.getName(), cpg);
+		}
+        if(logging) printLogMessage(this.getClass().getName()
+						+ " picked up the attributes for class " + class_name );
+    }
+        
+    // --- helpers for adding line numbers at the front of a method  ---
+    // unfortunately BCEL does not sort line numbers, but the debugger expects them sorted.
+    class Pair<F,S> {
+    	F first;
+    	S second;
+    	Pair(F f, S s) {
+    		this.first = f;
+    		this.second = s;
+    	}
+    }
+    @SuppressWarnings("unchecked") // can't declare array of generics
+	Pair<InstructionHandle, Integer>[] saveLineNumbers(MethodGen method, ConstantPoolGen cpg) {
+    	LineNumberTable lnt = method.getLineNumberTable(cpg);
+    	InstructionHandle[] ihs = method.getInstructionList().getInstructionHandles();
+    	Pair<InstructionHandle, Integer>[] oldLines = new Pair[lnt.getTableLength()];
+    	{
+			int cur = -1;
+			int n = 0;
+			for (int i=0; i<ihs.length; i++) {
+				int next = lnt.getSourceLine(ihs[i].getPosition());
+				if (next > cur)  // reached a new source line
+					oldLines[n++] = new Pair<InstructionHandle, Integer>(ihs[i], new Integer(next));
+				cur = next;
+			}
+    	}
+    	return oldLines;    	
+    }
+    /** Append the saved line numbers to the end of the method's line number table. */
+	void restoreLineNumbers(MethodGen method, Pair<InstructionHandle, Integer>[] oldLines) {
+		for (int i=0; i<oldLines.length; i++) {
+			if (oldLines[i] == null)
+				continue;
+			InstructionHandle ih = oldLines[i].first;
+			int line = oldLines[i].second.intValue();
+			method.addLineNumber(ih, line);
+		}
+	}
+
+    /**
+	 * Adds team initialization for all teams in the config file.
+	 * 
+	 * @param cg
+	 * @param ce
+	 */
+    private void addTeamInitializations(ClassGen cg, ClassEnhancer ce) {
+    	String main_class_name = cg.getClassName();
+    	ConstantPoolGen cpg = cg.getConstantPool();
+    	InstructionFactory factory = new InstructionFactory(cpg);
+    	Method main = cg.containsMethod("main", "([Ljava/lang/String;)V");
+    	if (main == null) {
+    		// JPLIS launching may intercept system classes before the custom main.
+    		// reset the guard in order to retry with subsequent classes.
+    		AttributeReadingGuard.reset();
+    		return; // no main method in the first loaded class...
+    	}
+    	
+    	MethodGen mainMethod = new MethodGen(main, main_class_name, cpg);
+    	InstructionList il = mainMethod.getInstructionList();
+    	
+    	int startLine = -1;
+    	Pair<InstructionHandle,Integer>[] oldLines = null;
+    	if (debugging) {
+    		LineNumberTable lnt = mainMethod.getLineNumberTable(cpg);
+    		if (lnt != null) {
+    			startLine = lnt.getSourceLine(0);
+    			oldLines = saveLineNumbers(mainMethod, cpg);
+    		}
+    	}
+    	
+    	if (TEAM_CONFIG_FILE != null) {
+    		
+    		InstructionList teamInitializations = new InstructionList();
+    		List<String> teamsToInitialize = getTeamsFromConfigFile();
+    		Iterator<String> teamIt = teamsToInitialize.iterator();
+    		while (teamIt.hasNext()) {
+    			String nextTeam = teamIt.next();
+    			JavaClass teamClass = Repository.lookupClass(nextTeam);
+    			if (teamClass == null) {
+    				System.err.println("Config error: Team class '"+nextTeam+ "' in config file '"+ TEAM_CONFIG_FILE+"' can not be found!");
+    				System.err.println("Main class = "+main_class_name+
+    									", class loader = "+(this.loader!=null?this.loader.getClass().getName():"null")+
+    									", transformer = "+this.getClass().getName());
+    				continue;
+    			}
+    			ClassGen teamClassGen = new ClassGen(teamClass);
+    			if (teamClassGen.containsMethod(Constants.CONSTRUCTOR_NAME, "()V") == null) {
+    				System.err.println("Activation failed: Team class '"+nextTeam+ "' has no default constuctor!");
+    				continue;
+    			}
+    			ce.loadClass(nextTeam, this);
+    			if (logging)
+					printLogMessage("Adding initialization of team " + nextTeam
+							+ " to main method of class " + main_class_name);
+    			teamInitializations.append(factory.createNew(nextTeam));
+    			teamInitializations.append(new DUP());
+    			teamInitializations.append(factory.createInvoke(nextTeam,
+    					Constants.CONSTRUCTOR_NAME,
+						Type.VOID,
+						Type.NO_ARGS,
+						Constants.INVOKESPECIAL));
+    			teamInitializations.append(factory.createGetStatic(OTConstants.teamClassName,
+						"ALL_THREADS",
+						 OTConstants.threadType));
+    			teamInitializations.append(factory.createInvoke(nextTeam,
+    					"activate",
+						Type.VOID,
+						new Type[] {OTConstants.threadType},
+						Constants.INVOKEVIRTUAL));
+    		}
+    		il.insert(teamInitializations);
+    	}
+    	// register main thread with TeamThreadManager:
+        InstructionHandle cursor;
+        cursor = il.insert(new ICONST(1)); // isMain=true
+        cursor = il.append(cursor, new ACONST_NULL()); // parent=null
+        cursor = il.append(cursor, factory.createInvoke("org.objectteams.TeamThreadManager", 
+						                "newThreadStarted",
+										 Type.BOOLEAN,
+										 new Type[]{Type.BOOLEAN, OTConstants.threadType},
+										 Constants.INVOKESTATIC));
+        cursor = il.append(cursor, new POP()); // don't use boolean return
+
+    	il.setPositions(); 
+    	if (debugging && startLine > 0) {
+    		mainMethod.removeLineNumbers(); 					  // fresh start, to ensure correct order
+    		mainMethod.addLineNumber(il.getStart(), startLine-1); // new number to the front
+    		restoreLineNumbers(mainMethod, oldLines);		      // append old numbers
+    	}
+    	mainMethod.setInstructionList(il);
+    	mainMethod.setMaxStack();
+    	mainMethod.setMaxLocals();
+    	
+    	cg.replaceMethod(main, mainMethod.getMethod());
+    }
+
+	/**
+	 * @return a list of teams in the team initialization config file
+	 */
+	private static List<String> getTeamsFromConfigFile() {
+		List<String> result = new LinkedList<String>();
+		try {
+			FileInputStream fstream = new FileInputStream(TEAM_CONFIG_FILE);
+			BufferedReader in = new BufferedReader(new InputStreamReader(fstream));
+ 			while (in.ready()) {
+				String nextLine = in.readLine();
+				String nextTeam = nextLine.trim();
+				if (nextTeam.startsWith(COMMENT_MARKER))
+					continue; // this is a comment line
+				if (!nextTeam.equals("")) {
+					result.add(nextTeam.trim());
+				}
+			}
+			in.close();
+		} catch (Exception e) {
+			System.err.println("File input error: config file '" + TEAM_CONFIG_FILE + "' can not be found!");
+		}
+		return result;
+	}
+
+	 // -------------------------------------------------------------------------------------------------
+	 // -------- store and return adapted bases for OT/Equinox --------------
+	 // this data is collected by scanClassOTAttributes and must be collected by the caller
+	 // before processing the next class.
+	 // -------------------------------------------------------------------------------------------------
+	 public HashSet<String> adaptedBases = new HashSet<String>();
+
+	 /** Internal API for {@link org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer} */
+	 public Collection<String> fetchAdaptedBases() {
+		 HashSet<String> result;
+		 result = new HashSet<String>(adaptedBases);
+		 adaptedBases.clear();
+		 return result;
+	 }
+
+	 // ------------------------------------------------------------------------------------------------- 
+     /**
+ 	  * Container for base method properties
+	  */
+	 public static class BaseMethodInfo {
+		 private String baseClassName;
+		private String baseMethodName;
+		private String baseMethodSignature;
+		boolean isCallin;
+		private boolean isRoleMethod;
+		boolean isStatic;
+		private int[] parameterPositions;
+		int translationFlags;
+
+		BaseMethodInfo(String base_class_name, String base_method_name,
+					   String base_method_signature, boolean isCallin,
+					   boolean isRoleMethod, boolean isStatic,
+					   int[] parameter_positions, int translationFlags) 
+		{
+			this.baseClassName = base_class_name;
+			this.baseMethodName = base_method_name;
+			this.baseMethodSignature = base_method_signature;
+			this.isCallin = isCallin;
+			this.isRoleMethod = isRoleMethod;
+			this.isStatic = isStatic;
+			this.parameterPositions = parameter_positions;
+			this.translationFlags = translationFlags;
+		}
+		/** Minimal version to pass some info into #translateLoads(): */
+		BaseMethodInfo(boolean isCallin, boolean isStatic, int translationFlags) 
+		{
+			this.isCallin = isCallin;
+			this.isStatic = isStatic;
+			this.translationFlags = translationFlags;
+		}
+
+		public boolean isStaticRoleMethod() {
+			return this.isRoleMethod && this.isStatic;
+		}
+
+		String getBaseClassName() {
+			return baseClassName;
+		}
+
+		String getBaseMethodName() {
+			return baseMethodName;
+		}
+
+		String getBaseMethodSignature() {
+			return baseMethodSignature;
+		}
+
+		int[] getParameterPositions() {
+			return parameterPositions;
+		}
+	}
+	
+	/**
+	 * Scan the Attributes found in the class class_name for binding attributes
+     * and registers them in the CallinBindingManager.
+	 * 
+	 * @param attributes    the Attributes to be examined
+	 * @param class_name    the name of the class where the Attributes were found
+     * @param cpg           the classes ConstantPoolGen
+	 * @return              an ArrayList containing the names of classes which have
+	*                       to be loaded immediately
+    */
+    ArrayList<String> scanClassOTAttributes(Attribute[] attributes,
+								 String          class_name,
+								 ConstantPoolGen cpg,
+								 ClassGen cg)
+	{
+        if(logging) printLogMessage("Inspecting " + class_name);
+        ArrayList<String> classesToLoad = new ArrayList<String>();
+        String base_class_name = null;
+        for (int k=0; k<attributes.length; k++) {
+            Attribute actAttr = attributes[k];
+            Unknown attr = isOTAttribute(actAttr);
+	
+            if (attr != null) { //this is a callin attribute
+                String attrName = attr.getName();
+                if(logging) printLogMessage("CallinBindingAttribute: " + attrName);
+                byte[] indizes = attr.getBytes();
+                int count = combineTwoBytes(indizes, 0);
+                int numberOfEntries=0;
+				String [] names;
+				if (attrName.equals("OTClassFlags")) {
+					int classFlags = combineTwoBytes(indizes, 0);
+					String flagsString = "";
+					if ((classFlags & 1) != 0) {
+						flagsString = "team ";
+						// TODO: use this instead of team modifier
+					}
+					if ((classFlags & 2) != 0) {
+						flagsString += "role";
+						CallinBindingManager.addRole(class_name);
+					}
+                    if (logging) {
+						printLogMessage("OTClassFlags:");
+						printLogMessage("\t" + flagsString);
+					}
+				} else if (attrName.equals("CallinRoleBaseBindings")) {
+                    numberOfEntries = 2;
+                    int i = 2;
+                    int n = 2 * count * numberOfEntries; // n = count << 2; 
+                    names = new String[numberOfEntries];
+                    while (i <= n) {
+						i = scanStrings(names, indizes, i, cpg);
+						String role_name = names[0];
+						String base_name = names[1];
+                        if(logging) printLogMessage("**** Binding: " + role_name 
+                                                    + " playedBy " + base_name);
+
+                        //set binding:
+                        CallinBindingManager.addRoleBaseBinding(role_name, base_name, class_name);
+                        CallinBindingManager.addTeamBaseRelation(class_name, base_name);
+                        
+                		// [OT/Equinox] store adapted bases:
+               			adaptedBases.add(base_name);
+
+                        // super roles have to be loaded first for binding inheritance purpose:
+                        // not necessary anymore?
+                        //classesToLoad.addAll(getSuperRoles(role_name, attributes, cpg));
+                        // roles themselve have to be loaded too:
+                        classesToLoad.add(role_name);
+                    }
+				} else if (attrName.equals("BoundClassesHierarchy")) {
+                    numberOfEntries = 2;
+                    int i = 2;
+                    int n = 2 * count * numberOfEntries; // n = count << 2; 
+                    names = new String[numberOfEntries];
+                    while (i <= n) {
+						i = scanStrings(names, indizes, i, cpg);
+						String sub_name = names[0];
+						String super_name = names[1];
+						
+						CallinBindingManager.addBoundSuperclassLink(sub_name, super_name);
+                        if(logging)printLogMessage("**** super-class link: "+sub_name
+										+" -> "+super_name);
+                    }
+                } else if (attrName.equals("CallinMethodMappings")) {
+                    //numberOfEntries = 6;
+                    int i = 2;
+                    for (int n=0; n<count;n++) {
+                    	// JSR-045 support:
+                    	names = new String[1];
+                    	i = scanStrings(names, indizes, i, cpg);
+                    	String binding_file_name = names[0];
+                    	int binding_line_number = combineTwoBytes(indizes, i);
+                    	i += 2;
+                    	int binding_line_offset = combineTwoBytes(indizes, i);
+                    	i += 2;
+                    	boolean is_static_role_method = false;
+                    	boolean covariant_base_return= false;
+                    	// regular stuff:
+                    	numberOfEntries = 3;
+						names = new String[numberOfEntries];
+						i = scanStrings(names, indizes, i, cpg);
+						String wrapper_name = null;
+						String wrapper_signature = null;
+						// first 3 names:
+						int index = 0;
+						
+						String binding_label         = names[index++];
+						String role_method_name      = names[index++];
+						String role_method_signature = names[index++];
+						
+						{	// a flag:
+							int flags = combineTwoBytes(indizes, i);
+							is_static_role_method = (flags & 1) != 0;
+							// flag value 4 is "inherited"
+							covariant_base_return = (flags & 8) != 0;
+							i+=2;
+						}
+						// 3 more names
+						numberOfEntries = 3;
+						names = new String[numberOfEntries];
+						i = scanStrings(names, indizes, i, cpg);
+						index = 0;
+						//if (NEW_COMPILER_VERSION)
+						// static_role_method = see attribute
+							
+						String lift_method_name				= names[index++];
+						String lift_method_signature		= names[index++];
+						String binding_modifier				= names[index++];
+
+                        int base_len = combineTwoBytes(indizes, i);
+                        i += 2;
+
+                        names = new String[4];
+                        for (int n_base = 0; n_base < base_len; n_base++) {
+                            i = scanStrings(names, indizes, i, cpg);
+                            String base_method_name         = names[0];
+						    String base_method_signature	= names[1];
+							wrapper_name               		= names[2];
+							wrapper_signature          		= names[3];
+
+							byte baseFlags = indizes[i++];
+							boolean baseIsCallin = (baseFlags & 1) != 0;
+							boolean baseIsStatic = (baseFlags & 2) != 0;
+	                        int translationFlags = (combineTwoBytes(indizes, i)<<16) + combineTwoBytes(indizes, i+2);
+	                        i += 4;
+
+                            if(logging) {
+                                printLogMessage("**** Binding: " + binding_label + ":"
+                                        + role_method_name + role_method_signature
+                                        + " <- " + binding_modifier + " "
+                                        + base_method_name + base_method_signature);
+                                printLogMessage("**** Wrapper: " + wrapper_name
+                                        + wrapper_signature);
+                            }
+                            //set binding:
+                            CallinBindingManager.addMethodBinding(class_name,
+                            									  base_class_name, // previously read from PlayedBy attribute
+                            								  	  binding_file_name,
+															  	  binding_line_number,
+															  	  binding_line_offset,
+															  	  binding_label,
+															  	  role_method_name,
+															  	  role_method_signature,
+															  	  is_static_role_method,
+															  	  wrapper_name,
+															  	  wrapper_signature,
+															  	  binding_modifier,
+															  	  base_method_name,
+															  	  base_method_signature,
+															  	  baseIsStatic,
+															  	  baseIsCallin,
+															  	  covariant_base_return,
+															  	  translationFlags,
+															  	  lift_method_name, 
+															  	  lift_method_signature); 
+
+                        }
+                    }
+                } else if (attrName.equals("OTSpecialAccess")) {
+                	numberOfEntries = 3;
+                	int i = 2;
+                	for (int j = 0; j < count; j++) {
+                		short kind = indizes[i++];
+                		switch (kind) {
+                		case 1: // DecapsulatedMethodAccess
+                			names = new String[numberOfEntries];
+                			i = scanStrings(names, indizes, i, cpg);
+                			if(logging) printLogMessage("**** Callout: " + names[0] + "." 
+								     + names[1]+ " " + names[2]);
+                			CallinBindingManager.addCalloutBinding(names[0], names[1], names[2]);
+                			break;
+                		case 2: // CalloutFieldAccess
+                			short flags = indizes[i++];
+                			String accessMode = (flags & 1) == 1 ? "set" : "get";
+                			boolean isStaticField = (flags & 2) != 0;
+                			names = new String[numberOfEntries];
+                			i = scanStrings(names, indizes, i, cpg);
+                			if (logging)
+                				printLogMessage("**** Callout bound field: " + accessMode+(isStaticField?" static ":" ")
+                							    + names[2]+ " " + names[1]);
+                			CallinBindingManager.addCalloutBoundFileds(names[0], names[1], names[2], accessMode, isStaticField);
+
+                			synchronized(reentrentTransformations) {
+	                			for (ObjectTeamsTransformation transformation : reentrentTransformations) 
+	            					transformation.state.interfaceTransformedClasses.remove(names[0]);
+                			}
+                			
+                			break;
+                		case 3: // SuperMethodAccess
+                			numberOfEntries = 4; 
+                			names = new String[numberOfEntries];
+                			i = scanStrings(names, indizes, i, cpg);
+                			if(logging) printLogMessage("**** SuperAccess: " + names[0] + "." 
+								     + names[2]+ names[3]+" superclass "+names[1]);
+                			CallinBindingManager.addSuperAccess(names[0], names[1], names[2], names[3]);
+                			break;
+                		}
+                	}                	
+                	// adapted baseclasses (w/ or w/o decapsulation):
+                	count = combineTwoBytes(indizes, i);
+                	i += 2;
+                	names = new String[1];
+                	for (int j=0; j<count; j++) {
+	                	i = scanStrings(names, indizes, i, cpg);
+	                	byte flag = indizes[i++];
+	                	if (flag == 1) {
+							CallinBindingManager.addBaseClassForModifierChange(names[0]);
+						} else {
+							CallinBindingManager.addExtraReferencedBase(class_name, names[0]);
+	                		// [OT/Equinox]: store adapted bases:
+                			adaptedBases.add(names[0]);
+						}
+                	}
+				} else if (attrName.equals("ReferencedTeams")) {
+                    numberOfEntries = 1;
+                    int i = 2;
+                    int n = 2 * count * numberOfEntries; // n = count << 1;
+                    names = new String[numberOfEntries];
+                    while (i <= n) {
+						i = scanStrings(names, indizes, i, cpg);
+						String referenced_team = names[0];
+                        if(logging) printLogMessage("**** found ReferencedTeams: " + referenced_team);
+                        classesToLoad.add(referenced_team);
+
+                    }
+                } else if (attrName.equals("BaseClassTags")) {
+                    numberOfEntries = 2;
+                    String baseClass = "";
+		            int tag = 0;
+		            HashMap<String, Integer> tagMap = new HashMap<String, Integer>();
+
+                    int i = 2;
+                    int n = 2 * count * numberOfEntries; //count << 2; 
+                    while (i <= n) {
+						for (int j = 0; j < numberOfEntries; j++) {
+							int nextIndex = combineTwoBytes(indizes, i);
+							if (j == 0) {
+								ConstantUtf8 cons = (ConstantUtf8) cpg
+										.getConstant(nextIndex);
+								baseClass = cons.getBytes();
+							} else if (j == 1) {
+								tag = nextIndex;
+							}
+							i += 2;
+						}
+			            tagMap.put(baseClass, Integer.valueOf(tag));
+                        if(logging) printLogMessage("**** found Base tag: " + class_name + "."
+                                + baseClass + "->" + tag);
+                    }
+		            CallinBindingManager.addBaseTags(class_name, tagMap);
+				} else if (attrName.equals("PlayedBy")) {
+					names = new String[1];
+					scanStrings(names, indizes, 0, cpg);
+					base_class_name = names[0];
+					int langle = base_class_name.indexOf('<');
+					if (langle > -1) // it's an anchored type p.T$R<@C.o.f>, cut off everything after and including '<'.
+						base_class_name = base_class_name.substring(0, langle-1);
+                    if(logging) printLogMessage("**** found PlayedBy:  " + base_class_name);
+                    // base_class_name is stored for later use, when method bindings are found.
+					CallinBindingManager.addSuperRoleLink(cg.getClassName(), cg.getSuperclassName());
+					// this information is NOT NEEDED at moment!		
+				} else if (attrName.equals("OTCompilerVersion")) {
+					int encodedVersion = combineTwoBytes(indizes, 0);
+					int major = encodedVersion >>> 9;
+					int minor = (encodedVersion >>> 5) & 0xF;
+					int revision = encodedVersion & 0x1F;
+                    if(logging) printLogMessage("**** class file was produced by compiler version "
+                            + major + "." + minor + "." + revision + " ****");
+                    IS_COMPILER_GREATER_123 = false; // reset, may be updated below
+                    LowerableTransformation.checkRequiresAdaptation(major, minor, revision, cg);
+					// 1.4 stream:
+					if (major == 1 && minor == 4) {
+						if (revision < OT14_REVISION) {
+							if (class_name.startsWith(OTConstants.teamClassName))
+								continue; // no specific byte codes in ooTeam and its inner classes.
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
+						}
+						IS_COMPILER_GREATER_123 = true;
+						IS_COMPILER_13X_PLUS = true;
+						IS_COMPILER_14X_PLUS = true;
+					// 1.3 stream:
+					} else if (major == 1 && minor == 3) {
+						if (revision < OT13_REVISION) {
+							if (class_name.startsWith(OTConstants.teamClassName))
+								continue; // no specific byte codes in ooTeam and its inner classes.
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
+						}
+						IS_COMPILER_GREATER_123 = true;
+						IS_COMPILER_13X_PLUS = true;
+					// 1.2 stream:
+					} else if (major == 1 && minor == 2) {
+						if (revision < OT12_REVISION) {
+							if (class_name.startsWith(OTConstants.teamClassName))
+								continue; // no specific byte codes in ooTeam and its inner classes.
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
+						}
+						if (revision > 3)
+							IS_COMPILER_GREATER_123 = true;
+						// 1.1 stream:
+					} else if (major == 1 && minor == 1) {
+						if (revision < OT11_REVISION) {
+							if (class_name.startsWith(OTConstants.teamClassName))
+								continue; // no specific byte codes in ooTeam and its inner classes.
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
+						}
+						// 1.0 stream:
+					} else if (major == 1 && minor == 0) {
+						if (revision < OT10_REVISION) {
+							if (class_name.startsWith(OTConstants.teamClassName))
+								continue; // no specific byte codes in ooTeam and its inner classes.
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
+						}
+					// 0.9 stream:
+					} else if (major == 0 && minor == 9) {
+						if (revision < OT09_REVISION) {
+							if (class_name.startsWith(OTConstants.teamClassName))
+								continue; // no specific byte codes in ooTeam and its inner classes.
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
+						}
+					// 0.8 stream (OBSOLETE!)
+					} else {
+						if (major != OT_VERSION_MAJOR)
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported major version " + major);
+						if (minor != OT_VERSION_MINOR)
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported minor version " + minor);
+						if (revision < OT_REVISION)
+							throw new InternalError("OTRE: Class " + class_name + " has unsupported revision " + revision);
+					}
+				} else if (attrName.equals("CallinPrecedence")) {
+                    List<String> precedenceList = new LinkedList<String>(); 
+                    numberOfEntries = 1;
+                    int i = 2;
+                    int n = 2 * count * numberOfEntries; // n = count << 1;
+                    names = new String[numberOfEntries];
+                    while (i <= n) {
+                        i = scanStrings(names, indizes, i, cpg);
+                        String binding_label = names[0];
+                        precedenceList.add(binding_label);
+                    }
+                    if(logging) printLogMessage("**** found precedence list for " + class_name + ": "
+                            + precedenceList + " ****");
+                    CallinBindingManager.addPrecedenceList(precedenceList, class_name);
+                }
+            }
+        }
+        return classesToLoad;
+    }
+    
+	/**
+	 * Read some strings from a byte array.
+	 * @param entries Result array to be provided by caller.
+	 * @param indizes buffer of read bytes to be provided by caller,
+	 *                consists if indizes into the constant pool
+	 * @param i       current index into indizes
+	 * @param cpg     the pool.
+	 * @result        updated value of <tt>i</tt>.
+	 */
+	public static int scanStrings(String[] entries,
+					byte[]          indizes,
+					int             i,
+					ConstantPoolGen cpg)
+	{
+		for (int j = 0; j < entries.length; j++) {
+			int nextIndex = combineTwoBytes(indizes, i);
+			ConstantUtf8 cons      = (ConstantUtf8)cpg.getConstant(nextIndex);
+			String       content   = cons.getBytes();
+			entries[j] = content;
+			i += 2;
+		}
+		return i;
+	}
+
+    /**
+    *  Scan the Attributes found in the method <tt>method_name</tt> for binding attributes
+    *  and registers them in the {@link CallinBindingManager CallinBindingManager}.
+    *
+    *  @param attributes    the Attributes to be examined
+    *  @param class_name    the name of the class where the Attributes were found
+    *  @param method_name   the name of the method where the Attributes were found
+    *  @param cpg
+    */
+    static void scanMethodOTAttributes(Attribute[] attributes,
+								String          class_name,
+								String          method_name,
+								ConstantPoolGen cpg)
+	{
+        for (int k = 0; k < attributes.length; k++) {
+            Attribute actAttr = attributes[k];
+            Unknown attr = isOTAttribute(actAttr);
+            if (attr != null) { //this is an OT attribute
+                String attrName = attr.getName();
+                if(logging) printLogMessage("CallinBindingAttribute(" + method_name + ") :"
+                        + attrName);
+                if (attrName.equals("CallinParamMappings")) {
+					byte[] indizes = attr.getBytes();
+					int [] positions = null;
+					if (indizes == null) throw new RuntimeException("Unexpected null attr");
+					int count = combineTwoBytes(indizes, 0);
+					positions = new int[count];
+					int p = 2;
+					for (int i = 0; i < count; i++, p += 2) {
+						positions[i] = combineTwoBytes(indizes, p);
+						// System.out.println(" "+i+"<-"+positions[i]);
+					}
+					CallinBindingManager.addParameterBinding(class_name,
+															 method_name,
+															 positions);
+					// Here it is correct to use the (wrapper) method name without a signature, 
+					// because for overloaded methods there are separate wrappers with unique (mangled) names. 
+				}
+            }
+        }
+    }
+
+
+	/**
+    *  Determines, if the given Attribute is a callin-attribute.
+    *
+    *  @param attr      the Attriute to be checked
+    *  @return          the Attribute casted to Unknown, for later use, if true
+    *                   null, if it is not a callin-attribute
+    */
+    static Unknown isOTAttribute(Attribute attr) {
+        if (attr instanceof Unknown) {
+            Unknown unknown = (Unknown)attr;
+            String attrName = unknown.getName();
+            if (attrName.equals("CallinRoleBaseBindings") 	||
+                attrName.equals("BoundClassesHierarchy")    ||
+                attrName.equals("CallinMethodMappings")   	||
+                attrName.equals("CallinParamMappings")     	||
+                attrName.equals("CallinFlags")             	||
+				attrName.equals("OTSpecialAccess")     		||
+                attrName.equals("WrappedRoleSignature")   	||
+				attrName.equals("WrappedBaseSignature") 	||
+                attrName.equals("ReferencedTeams")        	||
+                attrName.equals("BaseClassTags")		  	||
+                attrName.equals("PlayedBy") 			  	||
+                attrName.equals("Modifiers")				||
+                attrName.equals("OTCompilerVersion") 		||
+                attrName.equals("OTClassFlags")				||
+                attrName.equals("OTJoinPoints")				||
+				attrName.equals("CallinPrecedence")			||
+				attrName.equals("StaticReplaceBindings"))
+            {
+                return unknown;
+            }
+        }
+        return null;
+    }
+
+    /**
+    *  Combines two int's representing the higher and the lower part
+	*  of a two byte number.
+    *
+    *  @param first     the first (higer?) byte
+    *  @param second    the second (lower?) byte
+    *  @return          the combined number
+    */
+    public static int combineTwoBytes(byte [] indizes, int start) {
+		int first = indizes[start];
+		int second = indizes[start + 1];
+		int twoBytes = 0;
+
+		twoBytes = twoBytes | (first & 0xff);
+		twoBytes = twoBytes << 8;
+		twoBytes = twoBytes | (second & 0xff);
+		return twoBytes;
+    }
+    
+	/**
+	 *  Returns a list of names of all super classes of class 'role_name' which are inner
+	 *  classes of the enclosing team, what are all super roles of the 
+	 *  role 'role_name'.
+	 *
+	 *  @param role_name     the name of the role class
+	 *  @param attributes    the attributes of the enclosing team class
+	 *  @param cpg	the constant pool of the enclosing team class
+	 *  @return          the list of super role names
+	 */
+	/*
+	private List getSuperRoles(String role_name, Attribute[] attributes, ConstantPoolGen cpg) {
+		LinkedList superRoleNames = new LinkedList();
+		JavaClass[] super_classes = Repository.getSuperClasses(role_name);
+		 if (super_classes.length < 2) {// extends only Object, or none?
+		 	return superRoleNames;
+		 }
+		LinkedList innerClassNames = new LinkedList();
+		for (int i=0; i<attributes.length; i++) {
+			Attribute actAttr = attributes[i];
+			if (actAttr instanceof InnerClasses) {
+				InnerClass[] inners = ((InnerClasses)actAttr).getInnerClasses();
+				for (int j=0; j<inners.length; j++) {
+					int name_index = inners[j].getInnerNameIndex();
+					Constant name_c = cpg.getConstant(name_index);
+					String name = ((ConstantUtf8)name_c).getBytes();
+					int outer_class_index = inners[j].getOuterClassIndex();	
+					Constant outer_c = cpg.getConstant(outer_class_index);
+					String outerName = ((ConstantClass)outer_c).getBytes(cpg.getConstantPool());
+					outerName = outerName.replace('/', '.');
+					innerClassNames.add(outerName + "$" +name);
+				}
+			}
+		}
+		for (int i=0; i<super_classes.length; i++) {
+			String superClassName = super_classes[i].getClassName();
+			if (innerClassNames.contains(superClassName)) {
+				superRoleNames.addFirst(superClassName);
+			}
+		}
+		return superRoleNames;	
+	}*/
+    
+    /**
+     * Remove all contents of a method as preparation for adding a new implementation
+	 *
+     * @param m 			The original method
+     * @param class_name 	The class containing the method
+     * @param cpg 			The class' constant pool
+     * @return An empty method generator with the same declaration as m 
+     *     	   and no implementation.
+     */
+    protected static MethodGen wipeMethod(Method m, String class_name, ConstantPoolGen cpg) {
+        MethodGen mg;
+        mg = new MethodGen(m, class_name, cpg);
+        mg.getInstructionList().dispose(); //throw away the old implementation
+        mg.removeLineNumbers();
+        mg.removeLocalVariables();
+        mg.removeLocalVariableTypes();
+        mg.removeExceptionHandlers();
+        mg.removeAttributes();
+        return mg;
+    }
+    
+	/**
+	 * Add instructions of InstructionList il after the super constructor call of this constuctor.
+	 *
+	 * @param m 		the constructor method
+	 * @param addedCode	the InstructionList containing the instructions to be added
+	 * @param cg		the ClassGen
+	 * @param cpg		the constant pool
+	 */
+	static void addToConstructor(Method m, InstructionList addedCode, ClassGen cg, ConstantPoolGen cpg) {
+		String class_name = cg.getClassName();
+		MethodGen mg = new MethodGen(m, class_name, cpg);
+		InstructionList il = mg.getInstructionList().copy();
+		InstructionHandle[] ihs = il.getInstructionHandles();
+
+		MethodGen newConstructor = new MethodGen(mg.getAccessFlags(),
+												 mg.getReturnType(),
+												 mg.getArgumentTypes(),
+												 mg.getArgumentNames(),
+												 mg.getName(),
+												 class_name,
+												 il,
+												 cpg );
+
+//[SH:] 				
+		updateCopiedMethod(mg, il, ihs, newConstructor);
+//[:HS]
+
+		int stackDepth = 0;
+		int actInstrIndex = 0;
+		
+		boolean pauseStackCounting = false;
+		InstructionHandle gotoTarget = null;
+		
+		// skip everything up to and including super() or this() call
+		while (!((ihs[actInstrIndex].getInstruction() instanceof INVOKESPECIAL)
+					&& (stackDepth - (ihs[actInstrIndex].getInstruction().consumeStack(cpg))) == 0)) {
+
+			Instruction actInstruction = ihs[actInstrIndex].getInstruction();
+
+			if (gotoTarget != null && actInstruction.equals(gotoTarget.getInstruction())) {
+				pauseStackCounting = false;
+				gotoTarget = null;
+			}
+			
+			if (actInstruction instanceof GotoInstruction) {
+				GotoInstruction gotoInsruction = (GotoInstruction)actInstruction;
+				gotoTarget = gotoInsruction.getTarget();
+				pauseStackCounting = true;
+			}
+			if (!pauseStackCounting) {
+				stackDepth -= actInstruction.consumeStack(cpg);
+				stackDepth += actInstruction.produceStack(cpg);
+			}
+
+			actInstrIndex++;
+		}
+		
+		InstructionHandle ih = ihs[actInstrIndex];
+		INVOKESPECIAL invoke = (INVOKESPECIAL)ih.getInstruction();
+		String specialName = invoke.getName(cpg);
+		if (!specialName.equals(Constants.CONSTRUCTOR_NAME)) {
+			System.err.println("###ALERT: " + specialName);
+			return;
+		}
+
+		if (logging) printLogMessage("Adding code to " + class_name + "." + m.getName());
+		
+		// calculate the length of the added code BEFORE it is inserted into the instruction list:
+//[SH:] extracted for adding further manipulation of addedCode:
+		int addedCodeLength = padCodeToAdd(addedCode);
+//[:HS]
+		
+		InstructionHandle startOfAddedCode = il.append(ih, addedCode);
+
+		il.setPositions();
+
+		newConstructor.setInstructionList(il);
+		newConstructor.setMaxStack();
+		newConstructor.setMaxLocals();
+//[SH:] if an unused local variable was copied in updateCopiedMethod() 
+//      we have to adjust max_locals,
+//      because unused locals are not found by setMaxLocals().
+		newConstructor.setMaxLocals(Math.max(newConstructor.getMaxLocals(), mg.getMaxLocals()));
+//[:HS]
+		
+		copyAndAdjustLineNumbers(mg, newConstructor, addedCodeLength, startOfAddedCode);
+		
+		cg.replaceMethod(m, newConstructor.getMethod());
+	}
+
+	/** 
+	 * Pads a given instruction list to multiples of 4 returning the padded length.
+	 * Note that clients of this function must not call removeNOPs()!
+	 * 
+	 * Rationale: 
+	 * switch instructions pad the lists of jmp targets to start at an offset % 4 == 0. 
+	 * In order to ensure that this padding will not change when inserting new bytes
+	 * the added bytes have to be a multiple of 4.
+	 */
+	static int padCodeToAdd(InstructionList addedCode) {
+//[orig:]
+		int addedCodeLength = 0;
+		Instruction[] instr = addedCode.getInstructions();
+		for (int i = 0; i < instr.length; i++) {
+			addedCodeLength += instr[i].getLength();
+		}
+//[:giro]
+		while (addedCodeLength % 4 > 0) {
+			addedCode.append(new NOP());
+			addedCodeLength++;
+		}
+		return addedCodeLength;
+	}
+
+//[SH:] helper methods for more complete method copying:
+	
+	/** After a method (incl. its instruction list) has been copied,
+	 *  we need to manually copy some more properties:
+	 *  + local variables
+	 *  + declared exceptions
+	 *  + exception handlers.
+	 */
+	static void updateCopiedMethod(MethodGen methodOrig, 
+								   InstructionList ilCopy, 
+								   InstructionHandle[] ihsCopy, 
+								   MethodGen methodCopy) 
+	{
+		// local variables:
+		LocalVariableGen[] oldLocals = methodOrig.getLocalVariables();
+		int argLen = methodOrig.getArgumentTypes().length;
+		if (!methodOrig.isStatic())
+			argLen++; // this
+		if (oldLocals.length > argLen) {
+			InstructionList oldIL = methodOrig.getInstructionList();
+			int maxLocals = methodOrig.getMaxLocals();
+			for (int i = argLen; i<oldLocals.length; i++) {
+				LocalVariableGen var = oldLocals[i];
+				LocalVariableGen newVar =
+					methodCopy.addLocalVariable(var.getName(), var.getType(), 
+												mapIH(var.getStart(), oldIL, ihsCopy), 
+												mapIH(var.getEnd(),   oldIL, ihsCopy));
+				newVar.setIndex(var.getIndex());
+				// reset, addLocalVariable might have changed this.
+				methodCopy.setMaxLocals(maxLocals); 
+			}
+		}
+		// declared exceptions:
+		BaseCallRedirection.copyExceptionHandlers(methodOrig, methodCopy, ilCopy);
+		// exception handlers:
+		for(String excName : methodOrig.getExceptions())
+			methodCopy.addException(excName);
+	}
+	
+	static InstructionHandle mapIH(InstructionHandle alienIH, InstructionList oldIL, InstructionHandle[] newIHs) 
+	{
+		int position = alienIH.getPosition();
+		int[] newPositions = oldIL.getInstructionPositions();
+		for (int i=0; i<newPositions.length; i++) {
+			if (newPositions[i] == position)
+				return newIHs[i];
+		}
+		return null;
+	}
+//[:HS]
+	
+	/**
+	 * Copy all line numbers from <tt>src</tt> to <tt>dest</tt>.
+	 * For bytecode instructions after the added code area an offset has to be added to the 
+	 * bytecode positions of the line numbers. 
+	 * If in debug modus (flag 'debugging') add 'STEP_OVER_LINENUMBER' for the added code. 
+	 * 
+	 * @param src				The source method.
+	 * @param dest				The destination method.
+	 * @param offset			The offest to be added (the length of the added code list).
+	 * @param startOfAddedCode	InstructionHandle to the beginning of the added code. 
+	 */
+	static void copyAndAdjustLineNumbers(MethodGen src, MethodGen dest, int offset, InstructionHandle startOfAddedCode) {
+		InstructionList il_dest = dest.getInstructionList();
+		LineNumberGen[] src_lng = src.getLineNumbers();
+		boolean addedCodeHasLineNumber = false;
+
+		for (int i = 0; i < src_lng.length; i++) {
+			int position = src_lng[i].getInstruction().getPosition();
+			if (position == startOfAddedCode.getPosition()) { // add the line number for added code here:
+				dest.addLineNumber(startOfAddedCode, STEP_OVER_LINENUMBER);
+				addedCodeHasLineNumber = true;
+				continue;
+			}
+			if (position >= startOfAddedCode.getPosition())  // move line numbers, because of inserted code (add offset)
+				position += offset;
+			InstructionHandle ih = il_dest.findHandle(position);
+			if (ih == null) {
+				System.err.println("Handle not found!");
+			} else {
+				dest.addLineNumber(ih, src_lng[i].getSourceLine());
+			}
+		}
+		if (!addedCodeHasLineNumber) { // no custom code after added code: add line number now:
+			dest.addLineNumber(startOfAddedCode, STEP_OVER_LINENUMBER);
+		}
+	}
+	
+	/**
+	* Test if a method has the given 'callin_flag'. 
+	*
+	* @param m				the method to search
+	* @param cg				the ClassGen
+	* @param callin_flags 	the flags to check for; 0 means any callin flags
+	* @return true, if the method has the callin flag
+	*/
+	public  static boolean methodHasCallinFlags(Method m, ClassGen cg, int callin_flags) {
+		boolean found = false;
+		Attribute[] attributes = m.getAttributes();
+		for (int i = 0; i < attributes.length; i++) {
+			Attribute actAttr = attributes[i];
+			if (!(actAttr instanceof Unknown)) 
+				continue; 
+			Unknown attr = (Unknown)actAttr;
+			if (!(attr.getName().equals("CallinFlags")))
+				continue;
+			if (callin_flags == 0)
+				return true;
+			byte [] bytes = attr.getBytes();
+			int flags = combineTwoBytes(bytes, 0);
+			if ((flags & callin_flags) != 0) {
+                if(logging) printLogMessage("Found CallinFlag " + callin_flags + " for "
+                        + cg.getClassName() + "." + m.getName() + ".");
+				found = true;
+			}
+		}
+		return found;
+	}
+
+	/**
+	 * A team needs to get added the team specific part, if it is a non-abstract team and
+	 * not the class org.objectteams.Team itself.
+	 * 
+	 * @param cg 	the class to be tested
+	 * @return true if this is a team which has to be extended
+	 */
+	protected static boolean classNeedsTeamExtensions(ClassGen cg) {
+		return !(( (cg.getAccessFlags() & OTConstants.TEAM) == 0)
+				|| (cg.getClassName().equals(OTConstants.teamClassName))
+				|| ((cg.getAccessFlags() & Constants.ACC_ABSTRACT) != 0));
+	}
+
+	/**
+	 * Generates the name of the implementing role for the given role interface name.
+	 * (Inserts the '__OT__' marker.)
+	 *
+	 * @param roleName the role interface name
+	 * @return the implementing role class name
+	 */
+	protected static String genImplementingRoleName(String roleName) {
+		int lastDollar = roleName.lastIndexOf('$');
+		StringBuilder sb = new StringBuilder(roleName);
+		sb.insert(lastDollar + 1, OTDT_PREFIX);
+		return sb.toString();
+	}
+
+	/**
+	 * Generates the name of the role interface the given role class is implementing. 
+	 *(Removes the '__OT__' marker.) 
+	 *
+	 * @param roleName the role class name
+	 * @return the implemented role interface
+	 */
+	public static String genRoleInterfaceName(String roleName) {
+	      int lastDollar = roleName.lastIndexOf('$');
+	      StringBuilder sb = new StringBuilder(roleName);
+	      sb.delete(lastDollar + 1, lastDollar + 1 + OTDT_PREFIX.length());
+	      return sb.toString();
+	}
+		
+	protected static boolean isReflectiveOTMethod(String methodName, String methodSignature) {
+		if ((methodName.equals("hasRole") && methodSignature.equals("(Ljava/lang/Object;)Z"))
+				|| (methodName.equals("hasRole") && methodSignature.equals("(Ljava/lang/Object;Ljava/lang/Class;)Z"))
+				|| (methodName.equals("getRole") && methodSignature.equals("(Ljava/lang/Object;)Ljava/lang/Object;"))
+				|| (methodName.equals("getRole") && methodSignature.equals("(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;"))
+				|| (methodName.equals("getAllRoles") && methodSignature.equals("()[Ljava/lang/Object;"))
+				|| (methodName.equals("getAllRoles") && methodSignature.equals("(Ljava/lang/Class;)[Ljava/lang/Object;"))
+				|| (methodName.equals("unregisterRole") && methodSignature.equals("(Ljava/lang/Object;)V"))
+				|| (methodName.equals("unregisterRole") && methodSignature.equals("(Ljava/lang/Object;Ljava/lang/Class;)V"))
+		   )
+			return true;
+		return false;
+	}
+	
+	/**
+	 * Calculates the name of the outer class.
+	 *
+	 * @param className	the full name of the inner class
+	 * @return the name of the outer class
+	 */
+	public static String getOuterClassName(String className) {
+		int    dollarIndex       = className.lastIndexOf('$');
+		if (dollarIndex == -1) // no outer class exists!
+			return null;
+		String outerClassName    = className.substring(0, dollarIndex);
+		return outerClassName;
+	}
+	
+	/**
+	 * @param m
+	 * @param cg 
+	 * @return
+	 */
+	static boolean candidateForImplicitActivation(Method m, ClassGen cg, ConstantPoolGen cpg) {
+		if (!IS_COMPILER_14X_PLUS)
+			implicitActivationMode = ImplicitActivationMode.ALWAYS;
+		switch (implicitActivationMode) {
+		case NEVER:	
+			return false;
+		case ANNOTATED :
+			if (   AnnotationHelper.containsImplicitActivationAttribute(m.getAttributes(), cpg)
+				|| AnnotationHelper.containsImplicitActivationAttribute(cg.getAttributes(), cpg))
+				return canImplicitlyActivate(m);
+			return false;
+		case ALWAYS:
+			if (!canImplicitlyActivate(m))
+				return false;
+			
+			Attribute[] attributes = m.getAttributes();
+			for(Attribute a : attributes) {
+				if (a instanceof Unknown) {
+					Unknown attr = (Unknown) a;
+					String attrName = attr.getName();
+					if ("RoleClassMethodModifiers".equals(attrName)) {
+						byte[] bytes = attr.getBytes();
+						int flags = combineTwoBytes(bytes, 0);
+						if (flags == 0 ||/* flags == 2 || */flags == 4) {
+							// 0: default, 2: private, 4: protected
+							return false;
+						}
+					}
+				}
+			}
+			if (!m.isPublic()) 
+				return false; // m originally wasn't public
+			
+			String className = cg.getClassName();
+			return !(CallinBindingManager.isRole(className) && cg.isProtected());
+		default:
+			return false; // cannot happen switch is exhaustive.
+		}
+    }
+
+	private static boolean canImplicitlyActivate(Method m) {
+		String methodName = m.getName();
+		String methodSignature = m.getSignature();
+		boolean isCandidate =
+			(!m.isAbstract()) &&
+			(!m.isStatic()) &&
+			(!methodName.startsWith(OT_PREFIX)) &&
+			(!methodName.equals(Constants.CONSTRUCTOR_NAME)) &&
+			(!(methodName.equals("activate") && methodSignature.equals("()V"))) &&
+			(!(methodName.equals("deactivate") && methodSignature.equals("()V"))) &&
+			(!isReflectiveOTMethod(m.getName(), methodSignature));
+		return isCandidate;
+	}
+
+	/**
+	 * @param s
+	 * @param c
+	 * @return
+	 */
+	static int countOccurrences(String s, char c) {
+		int count = 0;
+        int idx = s.indexOf(c);
+        while (idx != -1) {
+            idx = s.indexOf(c, idx + 1);
+            count++;
+        }
+        return count;
+    }
+
+	/**
+	 * This method performs the changes for implicit Team activation.
+	 * @param m					a method for which implicit activation will be enabled.
+	 * @param className			the class name for 'm'.
+	 * @param cpg				the constant pool of the class 'className'.
+	 * @param activateOuter 	true, if the surrounding team has to be activated
+	 * @return 
+	 */
+	Method genImplicitActivation(Method m, String className, ConstantPoolGen cpg, boolean activateOuter) {
+		String targetName = className;
+		int nestingDepth = 0;
+		ObjectType outerClass = null;
+		if (activateOuter) {
+			outerClass = new ObjectType(getOuterClassName(className));
+			nestingDepth = countOccurrences(className, '$') - 1;
+			targetName = outerClass.getClassName();
+		}
+		MethodGen mg = new MethodGen(m, className, cpg);
+		InstructionList il = mg.getInstructionList();
+		InstructionList prefix = new InstructionList();
+		InstructionHandle try_start = il.getStart();
+		// ---> new implicit activation
+		prefix.append(InstructionFactory.createThis());
+		if (activateOuter) {// this is for a role method: activate the outer team
+			// FIXME(SH): check replacing this$n with _OT$getTeam()
+			prefix.append(factory.createGetField(className, "this$" + nestingDepth, outerClass));
+		}
+         prefix.append(factory.createInvoke(targetName, "_OT$implicitlyActivate",
+				Type.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
+		// <-- new implicit activation
+        if (debugging)
+         	mg.addLineNumber(prefix.getStart() , STEP_OVER_LINENUMBER); 
+		il.insert(prefix);
+
+		InstructionList postfix = new InstructionList();
+		// ---> new implicit deactivation
+		postfix.append(InstructionFactory.createThis());
+		if (activateOuter) {// this is for a role method: deactivate the outer team
+			postfix.append(factory.createGetField(className, "this$"+nestingDepth, outerClass));
+		}
+		postfix.append(factory.createInvoke(targetName,
+				"_OT$implicitlyDeactivate", Type.VOID, Type.NO_ARGS,
+				Constants.INVOKEVIRTUAL));
+		// <-- new implicit deactivation
+
+		FindPattern findPattern = new FindPattern(il);
+		String pat = "`ReturnInstruction'";
+		InstructionHandle ih = findPattern.search(pat);
+		while (ih != null) {
+			// insert deactivate-call before return instruction in ih:
+			InstructionList postfixCopy = postfix.copy();
+			if (debugging)
+				mg.addLineNumber(postfixCopy.getStart(), STEP_OVER_LINENUMBER);
+			InstructionHandle inserted = il.insert(ih, postfixCopy); // instruction lists can not be reused
+			il.redirectBranches(ih, inserted); // SH: retarget all jumps that targeted at the return instruction
+			if (ih.getNext() == null)
+				break; // end of instruction list reached
+			ih = findPattern.search(pat, ih.getNext());
+		}
+
+		/**
+		 * **** add an exception handler which calls deactivate before throwing
+		 * the exception (finaly-simulation): ***
+		 */
+		ObjectType throwable = new ObjectType("java.lang.Throwable");
+		LocalVariableGen exception = mg.addLocalVariable(
+				"_OT$thrown_exception", throwable, null, null);
+		InstructionHandle try_end = il.getEnd();
+		InstructionList postfix_ex = postfix.copy();
+		if (debugging)
+			mg.addLineNumber(postfix_ex.getStart(), STEP_OVER_LINENUMBER);
+		postfix_ex.insert(InstructionFactory.createStore(throwable, exception
+				.getIndex()));
+		postfix_ex.append(InstructionFactory.createLoad(throwable, exception
+				.getIndex()));
+		postfix_ex.append(new ATHROW());
+		InstructionHandle deactivation_handler = il.append(il.getEnd(),
+				postfix_ex);
+		mg.addExceptionHandler(try_start, try_end, deactivation_handler,
+				throwable);
+		/** ******************************************************************** */
+
+		mg.setInstructionList(il);
+		mg.setMaxLocals();
+		mg.setMaxStack();
+		
+		if (!debugging)
+			return mg.getMethod();
+		
+		/* sorting the line numbers per start pc: */
+		Method newMethod = mg.getMethod();
+		MethodGen newMethodGen = new MethodGen(newMethod, className, cpg);
+		
+		LineNumberGen[] lineNumbers = newMethodGen.getLineNumbers();
+		
+		newMethodGen.removeLineNumbers();
+		
+		Arrays.sort(lineNumbers, new Comparator<LineNumberGen>() {
+		public int compare(LineNumberGen ln1, LineNumberGen ln2) {
+			int firstLineNumberPC = ln1.getLineNumber().getStartPC();
+			int secondLineNumberPC = ln2.getLineNumber().getStartPC();
+			
+			if (firstLineNumberPC < secondLineNumberPC)
+				return -1;
+			if (firstLineNumberPC > secondLineNumberPC)
+				return 1;
+			return 0;
+		}
+	}); 
+
+		for (int i = 0; i<lineNumbers.length; i++) {
+			newMethodGen.addLineNumber(lineNumbers[i].getInstruction(), lineNumbers[i].getSourceLine());
+		}		
+
+		return newMethodGen.getMethod();
+	}
+	
+	/**
+	 *  How many bytes does an instruction produce on the stack?
+	 */
+	static protected int stackDiff(Instruction instr, ConstantPoolGen cpg) {
+		return instr.produceStack(cpg) - instr.consumeStack(cpg);
+	}
+
+	/**
+	 *  Split an instruction list that loads method arguments into
+	 *  one list for each argument.
+	 *  @param cpg
+	 *  @param src the original loading sequence (will be destroyed by this method).
+	 *  @param argumentTypes source-level argument types of the callin method.
+	 *  @return array of load sequences, same order as before but split into individual arguments.
+	 */
+	protected InstructionList[] splitLoading(ConstantPoolGen cpg, InstructionList src, Type[] argumentTypes) {
+		int len = argumentTypes.length;
+		InstructionList[] res = new InstructionList[len];
+		// starting right _before_ an invoke instruction we loop backwards 
+		// to find those values on the stack that would be passed to the method.
+		for (int idx = len-1; idx>=0; idx--) {
+			// new sub-list:
+			res[idx] = new InstructionList();
+			// how many bytes to expect on the stack:
+			int expectedArgSize = argumentTypes[idx].getSize();
+			// loop until we have a sequence that produces the expected number of bytes:
+			while (expectedArgSize > 0) {
+				InstructionHandle loadH = src.getEnd();
+				Instruction       load  = loadH.getInstruction();
+				expectedArgSize -= stackDiff(load, cpg);
+				try {
+					// transfer instruction from src to res[roleIdx]:
+					res[idx].insert(load);
+					src.delete(loadH);
+				} catch (TargetLostException e) {
+					throw new OTREInternalError(e);
+				}
+			}
+		}
+		return res;
+	}
+
+	/**
+	 *  Translate the parameter loading of a base call to the correct sequence
+	 *  expected by the base chaining wrapper.
+	 *  Treats tunneled arguments but not current enhancement args.
+	 *  Tasks performed:
+	 *  <ul>
+	 *     <li>pick load sequences from <tt>splitLoad</tt>
+	 *     <li>extract unused args from Object[]
+	 *     <li>insert casting or lowering if needed.
+	 *  </ul>
+	 *  More documentation is found in document parameter-passing.odg.
+	 *  
+	 * @param splitLoad one list of load instructions for each argument, ordered as found in the bytecode.
+	 * @param enhancedRoleArgumentTypes enhanced role arguments
+	 * @param enhancedBaseArgumentTypes arguments of the base chaining wrapper.
+	 * @param parameterPosition encoded parameter mappings.
+	 * @param teamName The name of the team containing the role class.
+	 * @param enclosingRoleName enclosing role class or null for static replace/base-call.
+	 * @param baseIsCallin is the base method a callin method?
+	 * @param baseIsStaticRoleMethod is the base method a static role method?
+	 * @param one byte for each parameter, signalling if lowering is required
+	 * @return a complete loading sequence for all source-level and tunneled arguments
+	 */
+	protected InstructionList translateLoads(InstructionList[] splitLoad, 
+											 Type[]  		   enhancedRoleArgumentTypes, 
+											 Type[]  		   enhancedBaseArgumentTypes, 
+											 int[]   		   parameterPositions,
+											 String  		   teamName, 
+											 String  		   enclosingRoleName,
+											 BaseMethodInfo    baseMethod,
+											 int    		   start,
+											 ConstantPoolGen   cpg) 
+	{
+		boolean isStatic               = baseMethod.isStatic;
+		boolean baseIsStaticRoleMethod = baseMethod.isStaticRoleMethod();
+		boolean baseIsCallin 	       = baseMethod.isCallin;
+		int     translationFlags	   = baseMethod.translationFlags;
+		
+		InstructionList il = new InstructionList();		
+
+		// index into "Object[] _OT$unusedArgs" (points to first arg that has not yet been consumed):
+		int nextUnusedArg = 0; 
+		// index into enhancedBaseArgumentTypes:
+		int baseIdx;
+		// source-level version of baseIdx, i.e., ignoring any enhanced arguments:
+		int baseSrcIdx;
+		// index into roleArgumentTypes:
+		int roleIdx;
+		// source-level version of roleIdx, i.e., ignoring any enhanced arguments:
+		int roleSrcIdx;		
+
+		// ==  Note: letters (u-x) below refer to document parameter-passing.odg. ==
+		// Skip enhancements that are already loaded (given in start).
+		for (baseIdx = start; baseIdx < enhancedBaseArgumentTypes.length; baseIdx++) {
+			baseSrcIdx = baseIdx-start;      // (u) skip first enhancement (already loaded)
+			if (baseIsStaticRoleMethod) 
+				baseSrcIdx -= 2;			 // (v) not mapped but extracted from unusedArgs
+			if (baseIsCallin)
+				baseSrcIdx -= EXTRA_ARGS;    // (w) not mapped but extracted from unusedArgs
+
+			// value-dispatching: where to find this parameters? 
+			if (baseSrcIdx < 0) {
+				// (v) or (w)
+				roleSrcIdx = -1;
+			} else {
+				// (x) merge arguments from unused and real:
+				int numAvailableRoleArgs = enhancedRoleArgumentTypes.length-EXTRA_ARGS;
+				if (!isStatic && IS_COMPILER_GREATER_123)
+					numAvailableRoleArgs--; // don't count isSuperAccess
+				roleSrcIdx = getMappedRolePosition(baseSrcIdx, parameterPositions, numAvailableRoleArgs);
+			}
+			
+			// got all information, fetch it now:
+			Type baseArgumentType = enhancedBaseArgumentTypes[baseIdx];
+			if (roleSrcIdx == -1) {
+				// not mapped, retrieve from _OT$unusedArgs:
+				retrieveFromUnusedArg(il, nextUnusedArg++, baseArgumentType, cpg);
+			} else {
+				// mapped, fetch from splitLoad:
+				roleIdx = roleSrcIdx+EXTRA_ARGS; // role always has an additional set of enhancements 
+				if (IS_COMPILER_GREATER_123 && !isStatic) roleIdx++; // (+ isSuperAccess)
+				Type roleArgumentType = enhancedRoleArgumentTypes[roleIdx];
+				il.append(splitLoad[roleSrcIdx]);
+				if (!roleArgumentType.equals(baseArgumentType)) {
+					convertParamToBase(il, teamName, enclosingRoleName, roleArgumentType, baseArgumentType, 
+										(translationFlags & (2<<baseSrcIdx)) != 0);
+				}
+			}
+		}
+		if (il.isEmpty())
+			il.append(new NOP()); // ensure caller receives at least one instruction handle (for line number)
+		return il;
+	}
+	
+	/* Is the base arg identified by 'baseIdx' mapped to a role parameter?
+	 * If so: which role position is it mapped to?
+	 * If not: return -1
+	 */
+	private int getMappedRolePosition(int     baseSrcIdx, 
+									  int[]   parameterPositions, 
+									  int     numAvailableRoleArgs) 
+	{
+		if (parameterPositions == null) {
+			if (baseSrcIdx < numAvailableRoleArgs) // as many as available ...
+				return baseSrcIdx;        		   // in original order.
+		} else {
+			// search parameter mapping:
+			for (int i = 0; i < parameterPositions.length; i++) {
+				if (parameterPositions[i] == baseSrcIdx+1) // positions are one-based (base side)
+					return i;
+			}
+		}
+		return -1;
+	}
+
+	/* Retrieve an unused (tunneled) argument from position 'unusedIdx' of the _OT$unusedArgs array. */
+	private void retrieveFromUnusedArg(InstructionList il, 
+							   int             unusedIdx, 
+							   Type            baseArgumentType,
+							   ConstantPoolGen cpg) 
+	{
+		il.append(InstructionFactory.createLoad(objectArray, /*this*/1 + (UNUSED_ARG-1))); // 'UNUSED_ARG' is one-based
+		il.append(createIntegerPush(cpg, unusedIdx));
+		il.append(InstructionFactory.createArrayLoad(objectArray));
+		if (baseArgumentType instanceof BasicType)
+			il.append(createUnboxing((BasicType) baseArgumentType));
+		else  // ObjectTypes just have to be re-casted
+			il.append(factory.createCast(object, baseArgumentType));
+	}
+
+	/* May perform any of these conversions: casting, lowering, array-lowering.
+	 * Conversion is generated into 'il'. 
+	 */
+	private void convertParamToBase(InstructionList il, 
+									String          teamName, 
+									String 			enclosingRoleName, 
+									Type 			roleArgumentType, 
+									Type 			baseArgumentType,
+									boolean         loweringFlag) 
+	{
+		if (roleArgumentType instanceof ObjectType
+		    && baseArgumentType instanceof ObjectType) 
+		{
+			if (loweringFlag) {
+				lowerObject(il, teamName, roleArgumentType, baseArgumentType);
+			} else {
+				if(logging) printLogMessage("Try to cast " + roleArgumentType +
+						" to " + baseArgumentType);
+				il.append(factory.createCast(roleArgumentType,
+						baseArgumentType));
+			}
+		} else 
+		if (   roleArgumentType instanceof BasicType
+			&& baseArgumentType instanceof ObjectType) 
+		{
+			il.append(createBoxing((BasicType)roleArgumentType));
+		} else 
+		if (   roleArgumentType instanceof ObjectType
+			&& baseArgumentType instanceof BasicType) 
+		{
+			il.append(createUnboxing((BasicType)baseArgumentType));
+		} else
+		if (   roleArgumentType instanceof ArrayType
+		    && baseArgumentType instanceof ArrayType)
+		{
+			lowerArray(il, teamName, enclosingRoleName, roleArgumentType, baseArgumentType);
+		} else {
+			throw new OTREInternalError("OTRE internal error:"+
+							   "No way to make types conform\n"+
+							   "role type "+roleArgumentType+
+							   " -> "+baseArgumentType);
+		}
+	}
+
+	/* Lower one object from roleArgumentType to baseArgumentType. */
+	private void lowerObject(InstructionList il, 
+							 String 		 teamName, 
+							 Type 			 roleArgumentType, 
+							 Type 			 baseArgumentType) 
+	{
+		String roleIfcName = ((ObjectType)roleArgumentType).getClassName();
+		// use interface implementing role type for base-field access! 
+		String roleClassName = ObjectTeamsTransformation.genImplementingRoleName(roleIfcName);
+		
+		int dollarIdx = roleClassName.lastIndexOf('$');
+		if (dollarIdx == -1) {
+			throw new OTREInternalError("OTRE internal error:" +
+										"No way to make types conform\n" +
+										"role type " + roleArgumentType +
+										" -> " + baseArgumentType);
+		}
+		boolean isNested = dollarIdx != roleClassName.indexOf('$'); // is last == first?
+		String strengthenedRoleName = teamName + roleClassName.substring(dollarIdx);
+		
+		// baseArgumentType may be imprecise due to cast in param mapping, 
+		// try a RBB instead to find the exact base type
+		RoleBaseBinding rbb = CallinBindingManager.getRoleBaseBinding(strengthenedRoleName);
+		if (rbb != null) 
+			baseArgumentType = new ObjectType(rbb.getBaseClassName());
+
+		if (isNested) {
+			// cannot use field access here, because role strengthening would require resolved information
+			// so use the _OT$getBase() method instead:
+			short kind = (roleIfcName.lastIndexOf('$') == roleIfcName.lastIndexOf("$__OT__")) // last segment is roleclass?
+							? Constants.INVOKEVIRTUAL
+							: Constants.INVOKEINTERFACE;
+			il.append(factory.createInvoke(roleIfcName, GET_BASE, baseArgumentType, new Type[0], kind));
+		} else {
+			// access field via the role class:
+			il.append(factory.createCast(roleArgumentType, new ObjectType(strengthenedRoleName)));
+			
+			// optimized version directly accessing the field:
+			il.append(factory.createGetField(strengthenedRoleName,
+											 BASE,
+											 baseArgumentType));
+		}
+	}
+
+	/* Lower from roleArgumentType[] to baseArgumentType[]. */
+	private void lowerArray(InstructionList il, String teamName, String enclosingRoleName, Type roleArgumentType, Type baseArgumentType) {
+		ArrayType array = (ArrayType)roleArgumentType;
+		String roleName =((ObjectType)array.getElementType()).getClassName();
+		int dollarIdx = roleName.lastIndexOf('$');
+		String pureRoleName = roleName.substring(dollarIdx + 1);
+		String transformMethodName = getArrayLoweringMethodName(pureRoleName, array.getDimensions());
+		if (enclosingRoleName != null) {
+			// fetch team from enclosing role:
+			il.append(InstructionFactory.createThis());
+			// FIXME(SH): is this$0 always correct (nesting!)??
+			il.append(factory.createGetField(enclosingRoleName, "this$0", new ObjectType(teamName)));
+		} else {
+			// "this" is the team:
+			il.append(InstructionFactory.createThis());
+		}
+		il.append(new SWAP()); // 'push' team instance below the role array
+		il.append(factory.createInvoke(teamName, 
+									   transformMethodName, 
+									   baseArgumentType, 
+									   new Type[]{roleArgumentType}, 
+									   Constants.INVOKEVIRTUAL));
+	}
+	
+	private String getArrayLoweringMethodName(String roleName, int dimensions) {
+		return "_OT$transformArray" + roleName + "_OT$" + dimensions;
+	}
+
+	public List<String> getInnerClassNames(ClassGen cg, ConstantPoolGen cpg) {
+		Attribute[] attributes = cg.getAttributes();		
+		LinkedList<String> innerClassNames = new LinkedList<String>();
+		for (int i = 0; i < attributes.length; i++) {
+			Attribute actAttr = attributes[i];
+			if (actAttr instanceof InnerClasses) {
+				InnerClass[] inners = ((InnerClasses)actAttr).getInnerClasses();
+				for (int j=0; j<inners.length; j++) {
+					int name_index = inners[j].getInnerNameIndex();
+					Constant name_c = cpg.getConstant(name_index);
+					String name = ((ConstantUtf8)name_c).getBytes();
+					innerClassNames.add(name);
+				}
+			}
+		}
+		return innerClassNames;
+	}
+
+	/**
+	 * Create a monitor enter using a class literal
+	 * @param mg 		 target method to which a local variable is added which holds the monitor object
+	 * @param il		 instruction list to append to
+	 * @param class_name name of the class literal to use as monitor
+	 * @param major		 major class file version, used to determine how to translate class literals
+	 * @param cpg		 constant pool gen
+	 * @return the slot index of the monitor local variable and the handle of the first generated instruction.
+	 */
+	protected Pair<Integer,InstructionHandle> addClassMonitorEnter(MethodGen 		mg, 
+																   InstructionList 	il,
+																   String			class_name, 
+																   int 				major, 
+																   ConstantPoolGen 	cpg)
+	{
+		int monitor;
+		InstructionHandle ih= 
+			appendClassLiteral(il, class_name, major, cpg);
+		il.append(new DUP()); // for store and monitorenter
+		LocalVariableGen lg2= 
+			mg.addLocalVariable("monitor", Type.OBJECT, il.getStart(), null); //$NON-NLS-1$
+		monitor= lg2.getIndex();
+		il.append(InstructionFactory.createStore(Type.OBJECT, monitor)); // for use by monitorexit
+		il.append(new MONITORENTER());
+		return new Pair<Integer, InstructionHandle>(monitor, ih);
+	}
+	
+	/** 
+	 * Append an instruction sequence for loading the class literal for `class_name'.
+	 * @param il	instruction list to append to
+	 * @param class_name class name of the class literal
+	 * @param major java version as stored in the byte code.
+	 * @param cpg   for generating bytes
+	 * @return the handle of the first instruction of the sequence.
+	 */
+	protected InstructionHandle appendClassLiteral(InstructionList il, 
+												   String          class_name, 
+												   int             major,
+												   ConstantPoolGen cpg) 
+	{
+		if (major >= 49) // java 5
+			return il.append(new LDC(cpg.addClass(new ObjectType(class_name))));
+		// pre java 5, do it the hard way:
+		// if (_OT$self_class$ != null)
+	  InstructionHandle start= 
+		il.append(factory.createFieldAccess(class_name, OTConstants.SELF_CLASS, classType, Constants.GETSTATIC));
+	    il.append(new DUP()); // keep a copy as a potential result
+	  BranchInstruction checkLoaded=
+		          InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
+	    il.append(checkLoaded);
+	    il.append(new POP()); // discard null from above
+	    // _OT$self_class$= Class.forName(<class_name>); // never fails, it is THIS class
+		il.append(new LDC(cpg.addString(class_name)));
+	  	il.append(factory.createInvoke("java.lang.Class", 
+	  								   "forName", 
+	  								   classType,
+	  								   new Type[]{new ObjectType("java.lang.String")},
+	  								   Constants.INVOKESTATIC));
+	  	il.append(new DUP()); // keep a copy as the result
+	  	il.append(factory.createFieldAccess(class_name, OTConstants.SELF_CLASS, classType, Constants.PUTSTATIC));
+	
+	  	checkLoaded.setTarget(il.append(new NOP()));
+	  	return start;
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java
new file mode 100644
index 0000000..3525912
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java
@@ -0,0 +1,757 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: StaticSliceBaseTransformation.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import de.fub.bytecode.classfile.*;
+import de.fub.bytecode.generic.*;
+import de.fub.bytecode.*;
+
+import org.eclipse.objectteams.otre.util.*;
+
+
+/**
+ * Adds to base classes with callin bindings what can be literally pasted in:
+ * 
+ * Fields:
+ * 		protected static Team[] _OT$activeTeams;
+ * 		protected static int[] _OT$activeTeamIDs;
+ * Methods:
+ * 		public static void _OT$addTeam(Team team, in team_id)
+ * 		public static void _OT$removeTeam(Team team)
+ * Static initialization (adds clinit method, if not yet presented):
+ * 		_OT$activeTeams = new Team[0];
+ * 		_OT$activeTeamIDs = new int[0];
+ * 
+ *   
+ * @version $Id: StaticSliceBaseTransformation.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author  Christine Hundt
+ * @author  Stephan Herrmann
+ */
+public class StaticSliceBaseTransformation 
+	extends ObjectTeamsTransformation 
+{
+	static final String _OT_ACTIVE_TEAMS=    "_OT$activeTeams";   //$NON-NLS-1$
+	static final String _OT_ACTIVE_TEAM_IDS= "_OT$activeTeamIDs"; //$NON-NLS-1$
+
+	public StaticSliceBaseTransformation(SharedState state) { this(null, state); }
+	public StaticSliceBaseTransformation(ClassLoader loader, SharedState state) { super(loader, state); }
+	
+	public void doTransformCode(ClassGen cg) {
+		if (cg.isInterface())
+			return; // can't add implementation
+		// IMPLICIT_INHERITANCE
+        
+        String class_name = cg.getClassName();
+		if (!CallinBindingManager.isBoundBaseClass(class_name) 
+		/*&& !CallinBindingManager.containsBoundBaseInterface(cg.getInterfaceNames())*/)
+			return; //only (base-)classes with callin bindings need this addition
+		/*// this only works if teams are only added at the root bound base class
+		if (CallinBindingManager.isBoundBaseClass(cg.getSuperclassName()))
+			continue; // team infrastructur already added by super class
+		*/
+		if (CallinBindingManager.hasBoundBaseParent(class_name))
+			return; // team infrastructure already has been added to a super class
+
+        ConstantPoolGen cpg = cg.getConstantPool();
+		factory = new InstructionFactory(cpg);
+		addStaticInitializations(cg, cpg); 
+     }
+
+	/**
+	 * @param ce
+	 * @param cg
+	 */
+	public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
+		String class_name = cg.getClassName();
+		ConstantPoolGen cpg = cg.getConstantPool();
+		
+		checkReadClassAttributes(ce, cg, class_name, cpg);
+		
+		if (cg.isInterface())
+			return; // can't add implementation
+		if (state.interfaceTransformedClasses.contains(class_name))
+			return; // class has already been transformed by this transformer
+		// IMPLICIT_INHERITANCE
+		if (!CallinBindingManager.isBoundBaseClass(class_name)
+		/*&& !CallinBindingManager.containsBoundBaseInterface(cg.getInterfaceNames())*/)
+			return; //only (base-)classes with callin bindings need this addition
+		/*// this only works if teams are only added at the root bound base class
+		if (CallinBindingManager.isBoundBaseClass(cg.getSuperclassName()))
+		continue; // team infrastructur already added by super class
+		*/
+		if (CallinBindingManager.hasBoundBaseParent(class_name))
+			return; // team infrastructure already has been added to a super class
+		if(logging) printLogMessage("StaticSliceBaseTransformer transforms "+ class_name);
+		
+		if(CallinBindingManager.isRole(class_name)) {
+			addImplicitSubclassNotificationInfrastructure(ce, cg);
+		}
+
+		// addition of the fields '_OT$activeTeams' and '_OT$activeTeamIDs':
+		int accessFlags = Constants.ACC_PROTECTED | Constants.ACC_STATIC;
+
+		FieldGen activeTeamsField = new FieldGen(accessFlags, teamArray, _OT_ACTIVE_TEAMS, cpg);
+		ce.addField(activeTeamsField.getField(), cg);
+		// generated global variable: protected static Team[] _OT$activeTeams;
+
+		FieldGen activeTeamIDsField = new FieldGen(accessFlags, intArray, _OT_ACTIVE_TEAM_IDS, cpg);
+		ce.addField(activeTeamIDsField.getField(), cg);
+		// generated global variable: protected static int[] _OT$activeTeamIDs;
+
+		factory = new InstructionFactory(cpg);
+		
+		// implementation of method '_OT$addTeam'
+		ce.addMethod(genAddTeam(class_name, cg.getMajor(), cpg).getMethod(), cg);
+            
+		// implementation of method '_OT$removeTeam':
+		ce.addMethod(genRemoveTeam(class_name, cg.getMajor(), cpg).getMethod(), cg);
+            
+		// implementation of the static class initialization method '<clinit>':
+		/* Adding static initializations requires the addition of the clinit method, if not yet presented.
+		 * This requires synchronization with other transformers (TeamInterfaceImplementer) 
+		 * which may do the same this. This is done via 'TeamIdDispenser.clinitAdded(class_name)'.
+		 */
+		Method clinit = cg.containsMethod(Constants.STATIC_INITIALIZER_NAME, "()V");
+         
+		if (clinit != null || TeamIdDispenser.clinitAdded(class_name, loader)) {
+			// the clinit-Method only has to be extended by the code transformation of this transformer
+			state.interfaceTransformedClasses.add(class_name);
+			return;
+		}
+
+		InstructionList il = new InstructionList();
+		MethodGen clinitMethod = new MethodGen(Constants.ACC_STATIC,
+                                                    Type.VOID,
+                                                    Type.NO_ARGS,
+                                                    new String[] { },
+                                                    Constants.STATIC_INITIALIZER_NAME, class_name,
+                                                    il, cpg);
+
+		il.append(InstructionFactory.createReturn(Type.VOID));
+
+		clinitMethod.setMaxStack();
+		clinitMethod.setMaxLocals();
+		
+		ce.addMethod(clinitMethod.getMethod(), cg);
+
+/***********************************************************************************************************/
+		il.dispose();
+		state.interfaceTransformedClasses.add(class_name);
+    }
+
+	/* Code to be generated:
+	    public static void _OT$addTeam(Team team, int teamID)
+	    {
+	        int l;
+	        // Second part of the "if" below: Avoid duplicate entry of the same team.
+	        // Assumption (see r17473): this strategy assumes that a team instance
+	        // can only be duplicated directly after the first registration.
+	        // Reason: registerAtBases() calling addTeam() for multiple sub-bases
+	        // which share the same _OT$activateTeams et al fields from a common super-base.
+	        if((l = _OT$activeTeams.length) != 0 && _OT$activeTeams[0] == team)
+	        {
+	            return;
+	        } else
+	        {
+	            Team newTeams[] = new Team[l + 1];
+	            int newTeamIDs[] = new int[l + 1];
+	            System.arraycopy(_OT$activeTeams, 0, newTeams, 1, l);
+	            System.arraycopy(_OT$activeTeamIDs, 0, newTeamIDs, 1, l);
+	            _OT$activeTeams = newTeams;
+	            _OT$activeTeamIDs = newTeamIDs;
+	            _OT$activeTeams[0] = team;
+	            _OT$activeTeamIDs[0] = teamID;
+	            return;
+	        }
+	    }
+	 */
+	private MethodGen genAddTeam(String class_name, int major, ConstantPoolGen cpg) {
+		LocalVariableGen lg;
+		InstructionList il;
+		il = new InstructionList();
+		MethodGen addTeamMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNCHRONIZED,
+                                                    Type.VOID,
+                                                    new Type[] { teamType, Type.INT },
+                                                    new String[] { "team", "teamID" },
+                                                    "_OT$addTeam", class_name,
+                                                    il, cpg);
+	    // synchronized (BaseClass.class) {
+	  int monitor = addClassMonitorEnter(addTeamMethod, il, class_name, major, cpg).first;
+
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		il.append(new ARRAYLENGTH());
+		lg = addTeamMethod.addLocalVariable("l", Type.INT, null, null);
+		int l = lg.getIndex();
+		il.append(new DUP());
+		lg.setStart(il.append(InstructionFactory.createStore(Type.INT, l)));
+		// generated: int l = _OT$activeTeams.length;
+		
+		// add duplication check:
+	  BranchHandle emptyArray =
+		il.append(new IFEQ(null));
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		il.append(new ICONST(0));
+		il.append(InstructionFactory.createArrayLoad(teamType));
+		il.append(new ALOAD(0));
+	  BranchHandle noDuplication =
+		il.append(new IF_ACMPNE(null));
+	  GOTO earlyExit = new GOTO(null);
+		il.append(earlyExit);
+		InstructionHandle skipReturn = il.append(new NOP());
+		emptyArray.setTarget(skipReturn);
+		noDuplication.setTarget(skipReturn);
+		// generated: if (l > 0 && _OT$activeTeams[0] == team ) return; 
+		
+		lg = addTeamMethod.addLocalVariable("newTeams", teamArray, null, null);
+		int newTeams = lg.getIndex();
+		il.append(InstructionFactory.createLoad(Type.INT, l));
+		il.append(new ICONST(1));
+		il.append(new IADD());
+		il.append((Instruction)factory.createNewArray(teamType, (short)1));
+		//this are very strange (but necessary!?) casts...
+		lg.setStart(il.append(InstructionFactory.createStore(teamArray, newTeams)));
+		// generated: Team[] newTeams = new Team[l+1];
+		
+		lg = addTeamMethod.addLocalVariable("newTeamIDs", intArray, null, null);
+		int newTeamIDs = lg.getIndex();
+		il.append(InstructionFactory.createLoad(Type.INT, l));
+		il.append(new ICONST(1));
+		il.append(new IADD());
+		il.append((Instruction)factory.createNewArray(Type.INT, (short)1));
+		//this are very strange (but necessary!?) casts...
+		lg.setStart(il.append(InstructionFactory.createStore(intArray, newTeamIDs)));
+		// generated: int[] newTeamIDs = new int[l+1];
+		
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		il.append(new ICONST(0));
+		il.append(InstructionFactory.createLoad(teamArray, newTeams));
+		il.append(new ICONST(1));
+		il.append(InstructionFactory.createLoad(Type.INT, l));
+		ObjectType object = new ObjectType("java.lang.Object");
+		il.append(factory.createInvoke("java.lang.System", "arraycopy",
+                                            Type.VOID,
+                                            new Type[] {object, Type.INT, object, Type.INT, Type.INT },
+                                            Constants.INVOKESTATIC));
+            // generated: System.arraycopy(_OT$activeTeams, 0, newTeams, 1, l);
+
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
+		il.append(new ICONST(0));
+		il.append(InstructionFactory.createLoad(intArray, newTeamIDs));
+		il.append(new ICONST(1));
+		il.append(InstructionFactory.createLoad(Type.INT, l));
+		il.append(factory.createInvoke("java.lang.System", "arraycopy",
+                                            Type.VOID,
+                                            new Type[] {object, Type.INT, object, Type.INT, Type.INT },
+                                            Constants.INVOKESTATIC));
+            // generated: System.arraycopy(_OT$activeTeamIDs, 0, newTeamIDs, 1, l);
+
+		il.append(InstructionFactory.createLoad(teamArray, newTeams));
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.PUTSTATIC));
+		// generated: _OT$activeTeams   = newTeams;
+
+		il.append(InstructionFactory.createLoad(intArray, newTeamIDs));
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.PUTSTATIC));
+		// generated: _OT$activeTeamIDs = newTeamIDs;
+		
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		il.append(new ICONST(0));
+		il.append(new ALOAD(0));
+		il.append(InstructionFactory.createArrayStore(teamType));
+		// generated: _OT$activeTeams[0]   = team;
+		
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
+		il.append(new ICONST(0));
+		il.append(new ILOAD(1));
+		il.append(InstructionFactory.createArrayStore(Type.INT));
+		// generated: _OT$activeTeamIDs[0] = teamID;
+		
+		if (CallinBindingManager.isRole(class_name)) {
+			il.append(new ALOAD(0));
+			il.append(new ILOAD(1));
+			il.append(factory.createInvoke(class_name, "_OT$activateNotify", Type.VOID, new Type[] { teamType, Type.INT }, Constants.INVOKESTATIC));
+			// generated: _OT$activateNotify(team, teamID);
+		}
+		
+	    // No more access to array fields, release monitor:
+	  InstructionHandle exitSequence =
+		il.append(InstructionFactory.createLoad(Type.OBJECT, monitor));
+	    il.append(new MONITOREXIT());
+	    earlyExit.setTarget(exitSequence);
+
+		il.append(InstructionFactory.createReturn(Type.VOID));
+
+		addTeamMethod.setMaxStack();
+		addTeamMethod.setMaxLocals();
+		addTeamMethod.removeNOPs();
+		return addTeamMethod;
+	}
+
+	/* Code to be generated:
+   		public static void _OT$removeTeam(Team team)
+    	{
+	        int l;
+	        if((l = _OT$activeTeams.length) == 0)
+	            return;
+	        boolean found = false;
+	        int newLen= l-1;
+	        Team newTeams[] = new Team[newLen];
+	        int newTeamIDs[] = new int[newLen];
+	        for(int i = 0; i < l; i++)
+	            if(!found)
+	            {
+	                if(_OT$activeTeams[i] == team)
+	                {
+	                    found = true;
+	                } else if (i<newLen) { // coded as: jump if (newLen<=i)
+	                {
+	                    newTeams[i] = _OT$activeTeams[i];
+	                    newTeamIDs[i] = _OT$activeTeamIDs[i];
+	                }
+	            } else
+	            {
+	                newTeams[i - 1] = _OT$activeTeams[i];
+	                newTeamIDs[i - 1] = _OT$activeTeamIDs[i];
+	            }
+	
+	        if(found)
+	        {
+	            _OT$activeTeams = newTeams;
+	            _OT$activeTeamIDs = newTeamIDs;
+	        }
+	    }
+	 */
+	private MethodGen genRemoveTeam(String class_name, int major, ConstantPoolGen cpg) 
+	{
+		LocalVariableGen lg;
+		InstructionList il;
+		int l;
+		BranchHandle emptyArray;
+		int newTeams;
+		int newTeamIDs;
+		il = new InstructionList();
+		MethodGen removeTeamMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNCHRONIZED,
+                                                    Type.VOID,
+                                                    new Type[] { teamType },
+                                                    new String[] { "team" },
+                                                    "_OT$removeTeam", class_name,
+                                                    il, cpg);
+
+	    // synchronized (BaseClass.class) {
+	    int monitor = addClassMonitorEnter(removeTeamMethod, il, class_name, major, cpg).first;
+
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		il.append(new ARRAYLENGTH());
+		lg = removeTeamMethod.addLocalVariable("l", Type.INT, null, null);
+		//int l = lg.getIndex();
+		l = lg.getIndex();
+		il.append(new DUP());
+		lg.setStart(il.append(InstructionFactory.createStore(Type.INT, l)));
+		// generated: int l = _OT$activeTeams.length;
+
+		emptyArray = il.append(new IFNE(null));
+	  GOTO earlyExit = new GOTO(null);
+		il.append(earlyExit);
+		emptyArray.setTarget(il.append(new NOP()));
+		// generated: if (l == 0) return;
+		
+		lg = removeTeamMethod.addLocalVariable("found", Type.BOOLEAN, null, null);
+		int found = lg.getIndex();
+		il.append(new ICONST(0));
+		lg.setStart(il.append(InstructionFactory.createStore(Type.BOOLEAN, found)));
+		// generated: boolean found = false;
+
+		lg = removeTeamMethod.addLocalVariable("newTeams", teamArray, null, null);
+		newTeams = lg.getIndex();
+		il.append(InstructionFactory.createLoad(Type.INT, l));
+		// [SH]: variable newLen
+		LocalVariableGen lgNewLen= removeTeamMethod.addLocalVariable("newLen", Type.INT, il.getEnd(), null);
+		il.append(new ICONST(1));
+		il.append(new ISUB());
+		// [SH] store for later use:
+		il.append(new DUP());
+		il.append(InstructionFactory.createStore(Type.INT, lgNewLen.getIndex()));
+		// [HS] generated: "newLen= l-1;"
+		il.append((Instruction)factory.createNewArray(teamType, (short)1));
+		lg.setStart(il.append(InstructionFactory.createStore(teamArray, newTeams)));
+		// generated: Team[] newTeams = new Team[newLen];
+		
+		lg = removeTeamMethod.addLocalVariable("newTeamIDs", intArray, null, null);
+		//int newTeamIDs = lg.getIndex();
+		newTeamIDs = lg.getIndex();
+		//[SH]:
+		il.append(InstructionFactory.createLoad(Type.INT, lgNewLen.getIndex()));
+		il.append((Instruction)factory.createNewArray(Type.INT, (short)1));
+		lg.setStart(il.append(InstructionFactory.createStore(intArray, newTeamIDs)));
+		// generated: int[] newTeamIDs = new int[newLen];
+
+		// start for-loop
+		lg = removeTeamMethod.addLocalVariable("i", Type.INT, null, null);
+		int loopCounter = lg.getIndex();
+		il.append(new ICONST(0));
+		lg.setStart(il.append(InstructionFactory.createStore(Type.INT, loopCounter)));
+	  GOTO try_leave_loop = new GOTO(null);
+		il.append(try_leave_loop);
+		InstructionHandle i_lower_l = il.append(new NOP());
+		// loop body:
+		il.append(InstructionFactory.createLoad(Type.BOOLEAN, found));
+	  IFNE already_found = new IFNE(null);
+		il.append(already_found);
+
+		// outer if part:
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		il.append(new ILOAD(loopCounter));
+		il.append(InstructionFactory.createArrayLoad(teamType));
+		il.append(new ALOAD(0)); //first parameter
+	  IF_ACMPNE teams_not_equal = new IF_ACMPNE(null);
+		il.append(teams_not_equal);
+		
+		// inner if part:
+		il.append(new ICONST(1));
+		il.append(InstructionFactory.createStore(Type.BOOLEAN, found));
+	  GOTO skip_outer_else_part = new GOTO(null);
+		il.append(skip_outer_else_part);
+		
+		// inner else part:
+		teams_not_equal.setTarget(il.append(new NOP()));
+		
+		// [SH] sanity check:
+		il.append(InstructionFactory.createLoad(Type.INT, lgNewLen.getIndex()));
+		il.append(new ILOAD(loopCounter));
+	  IF_ICMPLE if_len_le_i= new IF_ICMPLE(null);
+		il.append(if_len_le_i);
+		// [HS] generated: else if (!(newLen <= i)) { 
+		il.append(new ALOAD(newTeams));
+		il.append(new ILOAD(loopCounter));
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		il.append(new ILOAD(loopCounter));
+		il.append(InstructionFactory.createArrayLoad(teamType));
+		il.append(new AASTORE());
+		// generated: newTeams[i] = _OT$activeTeams[i];
+		
+		il.append(new ALOAD(newTeamIDs));
+		il.append(new ILOAD(loopCounter));
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
+		il.append(new ILOAD(loopCounter));
+		il.append(InstructionFactory.createArrayLoad(Type.INT));
+		il.append(new IASTORE());
+		// generated: newTeamIDs[i] = _OT$activeTeamIDs[i];
+		
+	  GOTO end_of_loop = new GOTO(null);
+		il.append(end_of_loop);
+		
+		// outer else part:
+		already_found.setTarget(il.append(new NOP()));
+		il.append(new ALOAD(newTeams));
+		il.append(new ILOAD(loopCounter));
+		il.append(new ICONST(1));
+		il.append(new ISUB());
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.GETSTATIC));
+		il.append(new ILOAD(loopCounter));
+		il.append(InstructionFactory.createArrayLoad(teamType));
+		il.append(new AASTORE());
+		// generated: newTeams[i-1] = _OT$activeTeams[i];
+		
+		il.append(new ALOAD(newTeamIDs));
+		il.append(new ILOAD(loopCounter));
+		il.append(new ICONST(1));
+		il.append(new ISUB());
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.GETSTATIC));
+		il.append(new ILOAD(loopCounter));
+		il.append(InstructionFactory.createArrayLoad(Type.INT));
+		il.append(new IASTORE());
+		// generated: newTeamIDs[i-1] = _OT$activeTeamIDs[i];
+		
+		skip_outer_else_part.setTarget(il.append(new NOP()));
+		// [SH] connect "else if" from above:
+		if_len_le_i.setTarget(il.getEnd());
+		end_of_loop.setTarget(il.append(new IINC(loopCounter, 1)));
+		try_leave_loop.setTarget(il.append(InstructionFactory.createLoad(Type.INT, loopCounter)));
+		il.append(new ILOAD(l));
+		il.append(new IF_ICMPLT(i_lower_l));
+		// end for-loop
+		
+		il.append(InstructionFactory.createLoad(Type.BOOLEAN, found));
+		BranchHandle notFound = il.append(new IFEQ(null));
+		// generated: if (found) {
+		
+		il.append(InstructionFactory.createLoad(teamArray, newTeams));
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.PUTSTATIC));
+		// generated: _OT$activeTeams = newTeams;
+
+		il.append(InstructionFactory.createLoad(intArray, newTeamIDs));
+		il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.PUTSTATIC));
+		// generated: _OT$activeTeamIDs = newTeamIDs;
+
+		if (CallinBindingManager.isRole(class_name)) {
+			il.append(new ALOAD(0));
+			il.append(factory.createInvoke(class_name, "_OT$deactivateNotify", Type.VOID, new Type[] { teamType }, Constants.INVOKESTATIC));
+			// generated: _OT$deactivateNotify(team);
+		}
+
+	    // No more access to array fields, release monitor:
+	  InstructionHandle exitSequence =
+	    il.append(InstructionFactory.createLoad(Type.OBJECT, monitor));
+	    il.append(new MONITOREXIT());
+	    earlyExit.setTarget(exitSequence);
+	    notFound.setTarget(exitSequence);
+
+		il.append(InstructionFactory.createReturn(Type.VOID));
+
+		removeTeamMethod.setMaxStack();
+		removeTeamMethod.setMaxLocals();
+		removeTeamMethod.removeNOPs();
+		return removeTeamMethod;
+	}
+
+    /**
+     * Add infrastructure for implicit subclasses to register and be notified. This 'observer' mechanism 
+     * is necessary, because an implicit subclass does not inherit the addition/removal 
+     * of a team at the implicit superclass. 
+	 * @param ce	The ClassEnhancer object to add methods and fields.
+	 * @param cg	The ClassGen object representing the current class. 
+	 */
+	private void addImplicitSubclassNotificationInfrastructure(ClassEnhancer ce, ClassGen cg) {
+
+		ConstantPoolGen cpg = cg.getConstantPool();
+		factory = new InstructionFactory(cpg);
+		String class_name = cg.getClassName();
+		ObjectType linkedListType = new ObjectType("java.util.LinkedList");
+		int accessFlags = Constants.ACC_PROTECTED | Constants.ACC_STATIC;
+		FieldGen teamRegistrationObserversField = new FieldGen(accessFlags, linkedListType, "_OT$teamRegistrationObservers", cpg);
+		ce.addField(teamRegistrationObserversField.getField(), cg);
+		
+/***********************************************************************************************************/
+		
+		InstructionList il = new InstructionList();
+		
+		MethodGen observerRegistrationMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
+                                                    Type.VOID,
+                                                    new Type[] { classType },
+                                                    new String[] { "implicitSubClass" },
+                                                    "_OT$registerObserver", class_name,
+                                                    il, cpg);
+
+		il.append(factory.createFieldAccess(class_name, "_OT$teamRegistrationObservers", linkedListType, Constants.GETSTATIC));
+		il.append(InstructionFactory.createLoad(classType, 0));
+		il.append(factory.createInvoke("java.util.LinkedList", "add", Type.BOOLEAN, new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL));
+		il.append(new POP());
+		il.append(new RETURN());
+		
+		observerRegistrationMethod.setMaxStack(2);
+		observerRegistrationMethod.setMaxLocals();
+		
+		ce.addMethod(observerRegistrationMethod.getMethod(), cg);
+/***********************************************************************************************************/
+		il = new InstructionList();
+		
+		MethodGen activateNotifyMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
+                                                    												  Type.VOID,
+																									  new Type[] { teamType, Type.INT },
+																									  new String[] { "team", "teamID" },
+																									  "_OT$activateNotify", class_name,
+																									  il, cpg);
+		
+		createNotifyMethodImplementation(activateNotifyMethod, cpg, class_name);
+		
+		ce.addMethod(activateNotifyMethod.getMethod(), cg);
+/***********************************************************************************************************/
+		il = new InstructionList();
+		
+		MethodGen deactivateNotifyMethod = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
+                                                    												  Type.VOID,
+																									  new Type[] { teamType },
+																									  new String[] { "team" },
+																									  "_OT$deactivateNotify", class_name,
+																									  il, cpg);
+		createNotifyMethodImplementation(deactivateNotifyMethod, cpg, class_name);
+
+		ce.addMethod(deactivateNotifyMethod.getMethod(), cg);
+	}
+
+
+	/**
+	 * Create implementation of methods '_OT$activateNotify' and _OT$deactivateNotify'.
+	 * @param notifyMethod	Method which has to be implemented.
+	 * @param cpg					Corresponding constant pool.
+	 * @param class_name	Name of the class for wich to implement the method.
+	 */
+	private void createNotifyMethodImplementation(MethodGen notifyMethod, ConstantPoolGen cpg, String class_name) {
+		boolean isActivateMethod = notifyMethod.getName().equals("_OT$activateNotify");
+//		int methodArgs = isActivateMethod ? 2 : 1;
+
+		int iteratorIdx = isActivateMethod ? 2 : 1;
+		int curClassIdx = isActivateMethod ? 3 : 2;
+		int anotherIdx1 = isActivateMethod ? 4 : 3;
+		int anotherIdx2 = isActivateMethod ? 5 : 4;
+		String methodToInvoke = isActivateMethod ? "_OT$addTeam" : "_OT$removeTeam";
+		
+		InstructionList il = notifyMethod.getInstructionList();
+		il.append(factory.createFieldAccess(class_name,  "_OT$teamRegistrationObservers", new ObjectType("java.util.LinkedList"), Constants.GETSTATIC));
+		BranchInstruction ifnonnull_3 = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
+		il.append(ifnonnull_3);
+		il.append(InstructionFactory.createReturn(Type.VOID));
+		InstructionHandle ih_7 = il.append(factory.createFieldAccess(class_name,  "_OT$teamRegistrationObservers", new ObjectType("java.util.LinkedList"), Constants.GETSTATIC));
+		il.append(factory.createInvoke("java.util.LinkedList", "iterator", new ObjectType("java.util.Iterator"), Type.NO_ARGS, Constants.INVOKEVIRTUAL));
+		il.append(InstructionFactory.createStore(Type.OBJECT,iteratorIdx));
+		InstructionHandle ih_14 = il.append(InstructionFactory.createLoad(Type.OBJECT,iteratorIdx));
+		il.append(factory.createInvoke("java.util.Iterator", "hasNext", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEINTERFACE));
+		BranchInstruction ifeq_20 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
+		il.append(ifeq_20);
+		il.append(InstructionFactory.createLoad(Type.OBJECT,iteratorIdx));
+		il.append(factory.createInvoke("java.util.Iterator", "next", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEINTERFACE));
+		il.append(factory.createCheckCast(classType));
+		il.append(InstructionFactory.createStore(Type.OBJECT,curClassIdx));
+		il.append(InstructionConstants.ACONST_NULL);
+		il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx1));
+		InstructionHandle ih_36 = il.append(InstructionFactory.createLoad(Type.OBJECT,curClassIdx));
+		il.append(new PUSH(cpg, methodToInvoke));
+		il.append(new PUSH(cpg,iteratorIdx));
+		il.append((Instruction)factory.createNewArray(classType, (short) 1));
+		il.append(InstructionConstants.DUP);
+		
+		il.append(new PUSH(cpg, 0));
+		il.append(new PUSH(cpg, OTConstants.teamName));
+		il.append(factory.createInvoke("java.lang.Class", "forName", 
+															classType, new Type[] { Type.STRING },
+															 Constants.INVOKESTATIC));
+
+		il.append(InstructionConstants.AASTORE);
+		if (isActivateMethod){ // add the integer argument:
+			il.append(InstructionConstants.DUP);
+			il.append(new PUSH(cpg, 1));
+			il.append(factory.createFieldAccess("java.lang.Integer", "TYPE", classType, Constants.GETSTATIC));
+			il.append(InstructionConstants.AASTORE);
+		}
+		il.append(factory.createInvoke("java.lang.Class", "getMethod", new ObjectType("java.lang.reflect.Method"), new Type[] { Type.STRING, new ArrayType(classType, 1) }, Constants.INVOKEVIRTUAL));
+		InstructionHandle ih_76 = il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx1));
+		BranchInstruction goto_78 = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
+		il.append(goto_78);
+		InstructionHandle ih_81 = il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx2));
+		il.append(factory.createFieldAccess("java.lang.System", "err", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
+		il.append(new PUSH(cpg, "activateNotifyMethod not found!"));
+		il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
+		InstructionHandle ih_91 = il.append(InstructionFactory.createLoad(Type.OBJECT,anotherIdx1));
+		BranchInstruction ifnull_93 = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
+		il.append(ifnull_93);
+		il.append(InstructionFactory.createLoad(Type.OBJECT,anotherIdx1));
+		il.append(InstructionConstants.ACONST_NULL);
+		il.append(new PUSH(cpg,iteratorIdx));
+		il.append((Instruction)factory.createNewArray(Type.OBJECT, (short) 1));
+		il.append(InstructionConstants.DUP);
+		il.append(new PUSH(cpg, 0));
+		il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
+		il.append(InstructionConstants.AASTORE);
+
+		if (isActivateMethod) {	// load the integer argument:
+			il.append(InstructionConstants.DUP);
+			il.append(new PUSH(cpg, 1));
+			il.append(factory.createNew("java.lang.Integer"));
+			il.append(InstructionConstants.DUP);
+			il.append(InstructionFactory.createLoad(Type.INT, 1));
+			il.append(factory.createInvoke("java.lang.Integer", Constants.CONSTRUCTOR_NAME, Type.VOID, new Type[] { Type.INT }, Constants.INVOKESPECIAL));
+			il.append(InstructionConstants.AASTORE);
+		}
+		il.append(factory.createInvoke("java.lang.reflect.Method", "invoke", Type.OBJECT, new Type[] { Type.OBJECT, new ArrayType(Type.OBJECT, 1) }, Constants.INVOKEVIRTUAL));
+		InstructionHandle ih_121 = il.append(InstructionConstants.POP);
+		InstructionHandle ih_122;
+		BranchInstruction goto_122 = InstructionFactory.createBranchInstruction(Constants.GOTO, ih_14);
+		ih_122 = il.append(goto_122);
+		InstructionHandle ih_125 = il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx2));
+		il.append(factory.createFieldAccess("java.lang.System", "err", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
+		il.append(new PUSH(cpg, "Can not call activateNotifyMethod!"));
+		il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
+		BranchInstruction goto_135 = InstructionFactory.createBranchInstruction(Constants.GOTO, ih_14);
+		il.append(goto_135);
+		InstructionHandle ih_138 = il.append(InstructionFactory.createStore(Type.OBJECT,anotherIdx2));
+		il.append(factory.createFieldAccess("java.lang.System", "err", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
+		il.append(new PUSH(cpg, "InvocationTargetException"));
+		il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
+		BranchInstruction goto_148 = InstructionFactory.createBranchInstruction(Constants.GOTO, ih_14);
+		il.append(goto_148);
+		InstructionHandle ih_151 = il.append(InstructionFactory.createReturn(Type.VOID));
+		ifnonnull_3.setTarget(ih_7);
+		ifeq_20.setTarget(ih_151);
+		goto_78.setTarget(ih_91);
+		ifnull_93.setTarget(ih_122);
+		notifyMethod.addExceptionHandler(ih_36, ih_76, ih_81, new ObjectType("java.lang.NoSuchMethodException"));
+		notifyMethod.addExceptionHandler(ih_91, ih_121, ih_125, new ObjectType("java.lang.IllegalAccessException"));
+		notifyMethod.addExceptionHandler(ih_91, ih_121, ih_138, new ObjectType("java.lang.reflect.InvocationTargetException"));
+		
+		notifyMethod.setMaxStack();
+		notifyMethod.setMaxLocals();
+	}
+
+	/**
+     * Adds initialization of the team array and the team index array to the static initializer of this class.
+     * If this base class is a role at the same time, then also add initialization of the observer list.
+     * @param cg	The representation of the class.
+     * @param cpg	The constant pool of the class.
+	 */
+	private void addStaticInitializations(ClassGen cg, ConstantPoolGen cpg) {
+		Method clinitMethod = cg.containsMethod(Constants.STATIC_INITIALIZER_NAME, "()V");
+		 /* The clinit method always exists at this moment, because it has been added 
+         * by the interface transformer part of this transformer if necessary.
+         */
+		MethodGen mg = new MethodGen(clinitMethod, cg.getClassName(), cpg);
+		InstructionList il = mg.getInstructionList();
+		// add static initialization for added static fields at start of the <clinit> method:
+		il.insert(inizializeStaticFields(cg.getClassName()));
+		mg.setMaxStack();
+		mg.setMaxLocals();
+		Method newClinit = mg.getMethod();
+		cg.replaceMethod(clinitMethod, newClinit);
+		il.dispose();
+		// Reuse instruction handles
+	}
+	
+    /**
+     * @param class_name
+     * @return
+     */
+    private InstructionList inizializeStaticFields(String class_name) {
+    	// STATIC_PARTS_TODO : in base: static initialization of team fields
+        InstructionList il = new InstructionList();
+        il.append(new ICONST(0));
+        il.append((Instruction)factory.createNewArray(teamType, (short)1));
+        //this are very strange (but necessary!?) casts...
+        il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAMS, teamArray, Constants.PUTSTATIC));
+        //generated: _OT$activeTeams = new Team[0];
+
+        il.append(new ICONST(0));
+        il.append((Instruction)factory.createNewArray(Type.INT, (short)1));
+        //this are very strange (but necessary!?) casts...
+        il.append(factory.createFieldAccess(class_name, _OT_ACTIVE_TEAM_IDS, intArray, Constants.PUTSTATIC));
+        //generated: _OT$activeTeamIDs = new int[0];
+        
+        if (CallinBindingManager.isRole(class_name)) {
+        	ObjectType linkedListType = new ObjectType("java.util.LinkedList");
+        	il.append(factory.createNew(linkedListType));
+        	il.append(new DUP());
+        	il.append(factory.createInvoke("java.util.LinkedList", 
+        								   Constants.CONSTRUCTOR_NAME, 
+        								   Type.VOID, Type.NO_ARGS, 
+        								   Constants.INVOKESPECIAL));
+        								   
+			il.append(factory.createFieldAccess(class_name, 
+												"_OT$teamRegistrationObservers", 
+												linkedListType, Constants.PUTSTATIC ));
+        	
+        	//generated: _OT$teamRegistrationObservers = new LinkedList();
+        }
+        return il;
+    }
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java
new file mode 100644
index 0000000..104374d
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java
@@ -0,0 +1,175 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: SubBoundBaseMethodRedefinition.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import de.fub.bytecode.classfile.*;
+import de.fub.bytecode.generic.*;
+import de.fub.bytecode.*;
+
+import java.util.*;
+
+import org.eclipse.objectteams.otre.util.*;
+
+/**
+ * Redefines inherited (and not redefined) base methods in subclasses with a
+ * call to the super method if they are bound for the subclass only. This is
+ * done in order to provide a place for the BaseMethodTransformer to weave in
+ * the callin code.
+ * 
+ * @version $Id: SubBoundBaseMethodRedefinition.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author  Christine Hundt
+ * @author  Stephan Herrmann
+ */
+
+public class SubBoundBaseMethodRedefinition 
+	extends ObjectTeamsTransformation {
+
+	public SubBoundBaseMethodRedefinition(SharedState state) { this(null, state); }
+	public SubBoundBaseMethodRedefinition(ClassLoader loader, SharedState state) { super(loader, state); }
+
+	/**
+	 * Main entry for this transformer.
+	 */
+	public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
+		String class_name = cg.getClassName();
+		ConstantPoolGen cpg = cg.getConstantPool();
+
+		factory = new InstructionFactory(cg);
+
+		checkReadClassAttributes(ce, cg, class_name, cpg);
+
+		// if class is already transformed by this transformer
+		if (state.interfaceTransformedClasses.contains(class_name)) {
+			return;
+		}
+
+		List<MethodBinding> mbsForClass = CallinBindingManager
+				.getMethodBindingsForBaseClass(class_name);
+		if (mbsForClass.isEmpty()) {
+			return; // no bindings for this base class
+		}
+
+		List<MethodBinding> inheritedBoundMethods = getInheritedBoundMethods(mbsForClass, cg);
+		
+		addSubBoundMethodRedefinitions(inheritedBoundMethods, ce, cg);
+		state.interfaceTransformedClasses.add(class_name);
+	}
+
+	/**
+	 * Adds redefinitions with calls to the super method to all methods
+	 * contained in the 'inheritedBoundMethods' list.
+	 * 
+	 * @param inheritedBoundMethods
+	 *            The list of method bindings for inherited methods.
+	 * @param ce
+	 *            ClassEnhancer with the extension set of this class.
+	 * @param cg
+	 *            The ClassGen object for the transformed class.
+	 */
+	private void addSubBoundMethodRedefinitions(List<MethodBinding> inheritedBoundMethods,
+			ClassEnhancer ce, ClassGen cg) {
+		List<String> alreadyAddedRedefinitions = new LinkedList<String>();
+
+		Iterator<MethodBinding> it = inheritedBoundMethods.iterator();
+		while (it.hasNext()) {
+			MethodBinding mb = it.next();
+			String baseMethodKey = mb.getBaseMethodName() + "."
+					+ mb.getBaseMethodSignature();
+
+			if (alreadyAddedRedefinitions.contains(baseMethodKey)) {
+				continue;
+			}
+			Method m = genMethodRedefinition(mb, cg);
+			
+			ce.addMethod(m, cg);
+            if(logging) printLogMessage("Added " + baseMethodKey + " to " + cg.getClassName());
+			alreadyAddedRedefinitions.add(baseMethodKey);
+		}
+	}
+
+	/**
+	 * Generates a (redefining) method, which just calls its super version.
+	 * 
+	 * @param mb
+	 *            A method binding containing the method to be redefined.
+	 * @param cg
+	 *            The ClassGen object for the transformed class.
+	 * @return The generated method.
+	 */
+	private Method genMethodRedefinition(MethodBinding mb, ClassGen cg) {
+		boolean staticMethod = mb.hasStaticBaseMethod();
+		short invocationKind = staticMethod ? Constants.INVOKESTATIC : Constants.INVOKESPECIAL;
+		
+		String methodName = mb.getBaseMethodName();
+		String methodSignature = mb.getBaseMethodSignature();
+		String className = mb.getBaseClassName();
+		Type returnType = Type.getReturnType(methodSignature);
+		Type[] argTypes = Type.getArgumentTypes(methodSignature);
+		InstructionList il = new InstructionList();
+
+		int accFlags = Constants.ACC_PUBLIC;
+		if (staticMethod) {
+			accFlags = accFlags | Constants.ACC_STATIC;
+		}
+		MethodGen redefinition = new MethodGen(accFlags, returnType, argTypes, 
+											   null, methodName, className, il, 
+											   cg.getConstantPool());
+
+		if(!staticMethod){
+			il.append(InstructionFactory.createThis());
+		}
+		// load all arguments:
+		int index = 1;
+		for (int i = 0; i < argTypes.length; i++) {
+			il.append(InstructionFactory.createLoad(argTypes[i], index));
+			index += argTypes[i].getSize();
+		}
+		il.append(factory.createInvoke(cg.getSuperclassName(), methodName,
+				returnType, argTypes, invocationKind));
+		il.append(InstructionFactory.createReturn(returnType));
+
+		redefinition.removeNOPs();
+		il.setPositions();
+		redefinition.setMaxStack();
+		redefinition.setMaxLocals();
+		return redefinition.getMethod();
+	}
+
+	/**
+	 * Selects all method bindings from the 'mbsForClass' list which methods are
+	 * inherited only (not defined in the class itself).
+	 * 
+	 * @param mbsForClass
+	 *            The method bindings of the transformed class.
+	 * @param cg
+	 *            The ClassGen object for the transformed class.
+	 * @return A sublist of 'mbsForClass' containing all bindings for methods
+	 *         which are inherited only.
+	 * 
+	 */
+	private static List<MethodBinding> getInheritedBoundMethods(List<MethodBinding> mbsForClass, ClassGen cg) {
+		List<MethodBinding> inheritedBoundMethod = new LinkedList<MethodBinding>();
+		Iterator<MethodBinding> it = mbsForClass.iterator();
+		while (it.hasNext()) {
+			MethodBinding mb = it.next();
+			if ((cg.containsMethod(mb.getBaseMethodName(), mb
+					.getBaseMethodSignature())) == null)
+				inheritedBoundMethod.add(mb);
+		}
+		return inheritedBoundMethod;
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java
new file mode 100644
index 0000000..faa7cd1
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java
@@ -0,0 +1,1011 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: TeamInterfaceImplementation.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import de.fub.bytecode.classfile.*;
+import de.fub.bytecode.generic.*;
+import de.fub.bytecode.*;
+
+import java.util.*;
+
+import org.eclipse.objectteams.otre.util.*;
+
+/**
+ * Adds the general Team infrastructure to team classes.
+ * 
+ * Fields: public (static) final_OT$ID <- static if 'ot.no_static' ist set
+ * Methods: public int activate(int level) public int deactivate(int level)
+ * public int _OT$getID() Static initialization (adds clinit method, if not yet
+ * presented) OR to every constructor: <- if 'ot.no_static' is set _OT$ID =
+ * TeamIdDispenser.getTeamId(class_name)
+ * 
+ * Enables implicit team activation for normal (user defined) public team-level
+ * methods. A call to 'activate' is woven at the beginning of the method. A call
+ * to 'deactivate' is woven before every return and at every thrown exception.
+ * 
+ * @version $Id: TeamInterfaceImplementation.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author Christine Hundt
+ * @author Stephan Herrmann
+ */
+public class TeamInterfaceImplementation 
+	extends ObjectTeamsTransformation {
+
+	private boolean isJPLIS;
+
+
+	public TeamInterfaceImplementation(boolean isJPLIS, SharedState state) {
+		this(isJPLIS, null, state);
+	}
+
+	public TeamInterfaceImplementation(boolean isJPLIS, ClassLoader loader, SharedState state) {
+		super(loader, state);
+		this.isJPLIS = isJPLIS;
+	}
+
+	/**
+	 * @param cg
+	 */
+	public void doTransformCode(ClassGen cg) {
+		factory = new InstructionFactory(cg);
+
+		if (!classNeedsTeamExtensions(cg)) {
+			return;
+		}
+
+        ConstantPoolGen cpg = cg.getConstantPool();
+        String class_name = cg.getClassName();
+		genImplicitActivation(cg, cpg);
+		
+		InstructionList implicitSuperRoleRegistrations = genImplicitSuperRegistration(cg, cpg);
+		if (!implicitSuperRoleRegistrations.isEmpty()) {
+			// add implicitSuperRoleRegistrations to the static initializer:
+			Method clinitMethod = cg.containsMethod(Constants.STATIC_INITIALIZER_NAME, "()V");
+			addToMethodStart(implicitSuperRoleRegistrations, clinitMethod, cg, cpg);
+		}
+
+		if (CallinBindingManager.getBasesPerTeam(class_name) == null) {
+			return; // this team does not adapt any base class
+		}
+
+		/**
+		 * ******************* add initialization of the field '_OT$ID' to the static initializer : ******
+		 */
+		int nextTeamId = TeamIdDispenser.getTeamId(class_name);
+		
+		/*
+		 * The clinit method always exists at this moment, because it has
+		 * been added by the interface transformer part of this transformer
+		 * if necessary.
+		 */
+		addStaticInitializations(nextTeamId, cg, cpg);
+	}
+
+	/**
+	 * Add initialization of "_OT$ID" with 'nextTeamID' to the static
+	 * initializer of this team class.
+	 * 
+	 * @param nextTeamId
+	 *            the id which will be associated with the currently transformed
+	 *            team
+	 * @param cg
+	 *            the ClassGen for the given team class
+	 * @param cpg
+	 *            the constant pool ot the team
+	 */
+	private void addStaticInitializations(int nextTeamId, ClassGen cg,
+			ConstantPoolGen cpg) {
+		Method clinitMethod = cg.containsMethod(
+				Constants.STATIC_INITIALIZER_NAME, "()V");
+		MethodGen mg = new MethodGen(clinitMethod, cg.getClassName(), cpg);
+		InstructionList il = mg.getInstructionList();
+
+		InstructionList addedInitialization = new InstructionList();
+		addedInitialization.append(createIntegerPush(cpg, nextTeamId));
+		addedInitialization.append(factory.createFieldAccess(cg.getClassName(),
+				"_OT$ID", Type.INT, Constants.PUTSTATIC));
+		// generated: _OT$ID = <id dispensed by TeamIdDispenser>;
+		
+		// add static initialization for added static field at the beginning of
+		// the <clinit> method:
+		il.insert(addedInitialization);
+		mg.setMaxStack();
+		mg.setMaxLocals();
+
+		Method newClinit = mg.getMethod();
+		cg.replaceMethod(clinitMethod, newClinit);
+
+		il.dispose(); // Reuse instruction handles
+	}
+	
+	/**
+	 * For all roles in the current team which have tsuper versions: 
+	 * Generate instruction list containig calls to registration methods 
+	 * the implicit super roles. 
+	 *
+	 * @param cg	The ClassGen of the current team.
+	 * @param cpg	The constant pool of the current team.
+	 * @return		The instruction list containing the registration calls.
+	 */
+	private InstructionList genImplicitSuperRegistration(ClassGen cg, ConstantPoolGen cpg) {
+		InstructionList il = new InstructionList();
+		List<String> inheritedRoleNames = getInheritedRoleNames(cg, cpg);
+			if (inheritedRoleNames.isEmpty())
+				return il; // nothing to do
+			Iterator<String> iter = inheritedRoleNames.iterator();
+			while (iter.hasNext()) {
+				String roleName = iter.next();
+				String unqualifiedRoleName = roleName.substring(roleName.lastIndexOf('$') + 1);
+				if (CallinBindingManager.isBoundBaseAndRoleClass(roleName)) {
+					String potientialImplicitSuperRoleName = cg.getSuperclassName() + '$' + unqualifiedRoleName;
+					
+ 					if (!CallinBindingManager.isBoundBaseAndRoleClass(potientialImplicitSuperRoleName)) {
+						// Only bound base classes have the infrastructure for notifying 
+						// implicit subclasses about team activation!
+						continue;
+					}
+ 					il.append(new PUSH(cpg, roleName));
+					il.append(factory.createInvoke("java.lang.Class", "forName", 
+												   classType, new Type[] { Type.STRING },
+												   Constants.INVOKESTATIC));
+					il.append(factory.createInvoke(potientialImplicitSuperRoleName, "_OT$registerObserver", 
+												   Type.VOID, new Type [] { classType },
+												   Constants.INVOKESTATIC));
+				}
+			}
+		return il;
+	}
+
+	public void doTransformInterface(ClassEnhancer ce, ClassGen cg) {
+		String class_name = cg.getClassName();
+		ConstantPoolGen cpg = cg.getConstantPool();
+
+		checkReadClassAttributes(ce, cg, class_name, cpg);
+
+		if (state.interfaceTransformedClasses.contains(class_name)) {
+			return; // class has already been transformed by this transformer
+		}
+
+		if (!classNeedsTeamExtensions(cg)) {
+			return;
+		}
+		
+		factory = new InstructionFactory(cg);
+		
+		/**
+		 * ********** empty implementation of the static class initialization method '<clinit>' ***
+		 * NOTE: this is unnecessary in some cases, but checking is too complicated
+		 */
+		addStaticInitializer(cg, cpg, class_name, ce);
+
+		List<String> handledBases = CallinBindingManager.getBasesPerTeam(class_name);
+		// TeamInterfaceImplementer only registers teams at bases, wich are part
+		// of a 'CallinRoleBaseBinding'-attribute of the team.
+		if (handledBases == null) {
+			return; // this team does not adapt any base class
+		}
+		
+		if(logging) printLogMessage("Adding the general Team infrastructure to "
+				+ class_name);
+
+		/**
+		 * ******************* addition of the field '_OT$ID'
+		 * **********************************
+		 */
+
+		int accessFlags = Constants.ACC_PUBLIC | Constants.ACC_FINAL | Constants.ACC_STATIC;
+
+		FieldGen IDField = new FieldGen(accessFlags, Type.INT, "_OT$ID", cpg);
+		ce.addField(IDField.getField(), cg);
+		// generated global variable: public final static int _OT$ID;
+
+		factory = new InstructionFactory(cpg);
+		InstructionList il;
+
+		/**
+		 * ******************* implementation of method '_OT$getID'
+		 * ************************
+		 */
+
+		il = new InstructionList();
+		MethodGen getIDMethod = new MethodGen(Constants.ACC_PUBLIC, Type.INT,
+				Type.NO_ARGS, new String[] {}, "_OT$getID", class_name, il, cpg);
+
+		il.append(factory.createFieldAccess(class_name, "_OT$ID", Type.INT,
+				Constants.GETSTATIC));
+		il.append(InstructionFactory.createReturn(Type.INT));
+
+		getIDMethod.setMaxStack();
+		getIDMethod.setMaxLocals();
+
+		ce.addMethod(getIDMethod.getMethod(), cg);
+
+		/**
+		 * ***************** implementation of team (un)registration methods
+		 * **********************
+		 */
+
+		ce.addMethod(generateTeamRegistrationMethod(cpg, class_name,
+				handledBases), cg);
+
+		ce.addMethod(generateTeamUnregistrationMethod(cpg, class_name,
+				handledBases), cg);
+
+		/**
+		 * ***************** implementation of base call surrogtes for static methods
+		 * **********************
+		 */
+		Method [] base_call_surrogates = generateStaticBaseCallSurrogates(class_name, cpg, cg);
+		for(int i=0; i<base_call_surrogates.length;i++) {
+			// perhaps the compiler already generated an empty surrogate for an unbound super-role?
+			// (see X.1.5-otjld-callin-from-static-base-method-12a)
+			ce.addOrReplaceMethod(base_call_surrogates[i], cg);
+		}
+		
+		/** *************************************************************************** */
+
+		il.dispose();
+		state.interfaceTransformedClasses.add(class_name);
+	}
+	
+	/**
+	 * Add the given instruction list to the start of the givern method.
+	 * @param additionalInstructions
+	 * @param method
+	 * @param cg
+	 * @param cpg
+	 */
+	private void addToMethodStart(InstructionList additionalInstructions, Method method, ClassGen cg, ConstantPoolGen cpg) {
+		MethodGen mg = new MethodGen(method, cg.getClassName(), cpg);
+		InstructionList il = mg.getInstructionList();
+		il.insert(additionalInstructions);
+		mg.setMaxStack();
+		mg.setMaxLocals();
+
+		Method newMethod = mg.getMethod();
+		cg.replaceMethod(method, newMethod);
+		il.dispose(); // Reuse instruction handles	
+	}
+
+	/**
+	 * Generate the static initializer method 'clinit'.
+	 * @param cpg			The constant pool
+	 * @param class_name	The name of the class
+	 * @param cg			The ClassGen for the class
+	 * @return				The static initialier for this class
+	 */
+	void addStaticInitializer(ClassGen cg, ConstantPoolGen cpg, String class_name, ClassEnhancer ce) {
+		/*
+		 * Adding static initializations requires the addition of the clinit
+		 * method, if not yet presented. This requires synchronization with
+		 * other transformers (TeamInterfaceImplementer) which may do the
+		 * same this. This is done via 'TeamIdDispenser.clinitAdded(class_name)'.
+		 */
+		Method existingClinit = cg.containsMethod(Constants.STATIC_INITIALIZER_NAME, "()V");
+		if (existingClinit == null &&  !TeamIdDispenser.clinitAdded(class_name, loader)) {
+			// otherwise the clinit-Method already exists and only has to be extended
+			// by the code transformation of this transformer
+			InstructionList il = new InstructionList();
+			MethodGen clinitMethodGen = new MethodGen(Constants.ACC_STATIC,
+					Type.VOID, Type.NO_ARGS, new String[] {},
+					Constants.STATIC_INITIALIZER_NAME, class_name, il, cpg);
+
+			il.append(InstructionFactory.createReturn(Type.VOID));
+
+			clinitMethodGen.setMaxStack();
+			clinitMethodGen.setMaxLocals();
+			Method clinitMethod = clinitMethodGen.getMethod();
+			ce.addMethod(clinitMethod, cg);
+		}
+	}
+
+	/**
+	 * Generates the ' _OT$registerAtBases()' method. This method registers the
+	 * team at every adapted base class by calling the respective 'addTeam'
+	 * method.
+	 * 
+	 * @param cpg
+	 *            The ConstantPoolGen of the team class.
+	 * @param class_name
+	 *            The name of the team class.
+	 * @param handledBases
+	 *            The list of teams adapted by (roles of) this team.
+	 * @return The generated 'activate' method.
+	 */
+	Method generateTeamRegistrationMethod(ConstantPoolGen cpg,
+			String class_name, List<String> handledBases)
+	{
+		InstructionList il = new InstructionList();
+		MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, Type.VOID,
+				Type.NO_ARGS, null, "_OT$registerAtBases", class_name, il, cpg);
+
+		Iterator<String> it = handledBases.iterator();
+		while (it.hasNext()) {
+			String actBase = it.next();
+			//if (CallinBindingManager.hasBoundBaseParent(actBase))
+			//	continue; // team was already added to a super base class
+			//	problem: bound base parent could be bound to another team class!!!
+			
+			//String boundBase = CallinBindingManager.getBoundBaseParent(actBase);
+			//if (boundBase != null && handledBases.contains(boundBase))
+			//	continue;
+			if (CallinBindingManager.teamAdaptsSuperBase(class_name, actBase)) 
+				continue;
+			
+			InstructionHandle startTry = il.append(new ALOAD(0));
+			
+			il.append(factory.createFieldAccess(class_name, "_OT$ID", Type.INT,
+					Constants.GETSTATIC));
+			il.append(factory.createInvoke(actBase, "_OT$addTeam", Type.VOID,
+					new Type[] { teamType, Type.INT }, Constants.INVOKESTATIC));
+			// generated: <actBase>._OT$addTeam(this, _OT$ID);
+			
+			addNoSuchMethodErrorHandling(startTry, il.getEnd(), getErrorMessage(class_name, actBase, "Activation"), il, mg, cpg);
+		}
+		il.append(new RETURN());
+
+		mg.setMaxStack();
+		mg.setMaxLocals();
+		return mg.getMethod();
+	}
+
+	/**
+	 * Direct inverse of generateTeamRegistrationMethod(..). Generates the '
+	 * _OT$unregisterFromBases' method. This method deregisters the team at
+	 * every adapted base class by calling the respective 'removeTeam' method.
+	 * 
+	 * @param cpg
+	 *            The ConstantPoolGen of the team class.
+	 * @param class_name
+	 *            The name of the team class.
+	 * @param handledBases
+	 *            The list of teams adapted by (roles of) this team.
+	 * @return The generated 'deactivate' method.
+	 */
+	Method generateTeamUnregistrationMethod(ConstantPoolGen cpg,
+			String class_name, List<String> handledBases) {
+
+		InstructionList il = new InstructionList();
+		MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, Type.VOID,
+				Type.NO_ARGS, null, "_OT$unregisterFromBases", class_name, il,
+				cpg);
+
+		Iterator<String> it = handledBases.iterator();
+		while (it.hasNext()) {
+			String actBase = it.next();
+			//if (CallinBindingManager.hasBoundBaseParent(actBase))
+			//	continue; // team was only added to a super base class
+			// problem: bound base parent could be bound to another team class!!!
+			
+			// String boundBase = CallinBindingManager.getBoundBaseParent(actBase);
+			//if (boundBase != null && handledBases.contains(boundBase))
+			//	continue;
+			if (CallinBindingManager.teamAdaptsSuperBase(class_name, actBase)) 
+				continue;
+			
+			InstructionHandle startTry = il.append(new ALOAD(0));
+
+			il.append(factory.createInvoke(actBase, "_OT$removeTeam",
+					Type.VOID, new Type[] { teamType }, Constants.INVOKESTATIC));
+			// generated: <actBase>._OT$removeTeam(this, _OT$ID);
+			
+			addNoSuchMethodErrorHandling(startTry, il.getEnd(), getErrorMessage(class_name, actBase, "Deactivation"), il, mg, cpg);
+		}
+		il.append(new RETURN());
+
+		mg.setMaxStack();
+		mg.setMaxLocals();
+		return mg.getMethod();
+	}
+
+	private String getErrorMessage(String teamName, String baseName, String action) {
+		String errorMessage = action+" of team '" + teamName + "' failed! Callins of this team have NOT been WOVEN into base class '" + baseName + "'!\n" 
+		  + "This is probably caused by a loading order problem.";
+		if (!isJPLIS)
+			errorMessage += "\nIf "+baseName+" is loaded from the bootstrap classpath launching the program in JPLIS mode may perhaps avoid this problem.";
+		return errorMessage;
+	}
+	
+	/**
+	 * Adds an exception handler to the given method which catches 'java.lang.NoSuchMethodError's 
+	 * caused by missing team registration methods in base classes. Causes the throwing of an 
+	 * 'org.objectteams.UnsupportedFeatureException'.
+	 * 
+	 * @param startTry		handle to the start of the try block
+	 * @param endTry		handle to the end of the try block
+	 * @param errorMessage	the error message to be printed when throwing the exception
+	 * @param il			instruction list of the method
+	 * @param mg			MethodGen of the method
+	 * @param cpg			corresponding ConstantPoolGen
+	 */
+	private void addNoSuchMethodErrorHandling(InstructionHandle startTry, InstructionHandle endTry, 
+											  String errorMessage, InstructionList il, MethodGen mg, 
+											  ConstantPoolGen cpg) {
+		GOTO skipHdlr = null;
+		skipHdlr = new GOTO(null);
+		il.append(skipHdlr);
+		// generated: goto normal exit
+		
+		// throw away the expection reference:
+		InstructionHandle hdlr = il.append(new POP()); 
+		
+		il.append(factory.createNew(OTConstants.unsupportedFeature));
+		il.append(new DUP());
+		il.append(new PUSH(cpg, errorMessage));
+		il.append(factory.createInvoke(OTConstants.unsupportedFeature.getClassName(),
+													 Constants.CONSTRUCTOR_NAME,
+													 Type.VOID,
+													 new Type[] { Type.STRING }, 
+													 Constants.INVOKESPECIAL));
+		il.append(new ATHROW());
+		
+		InstructionHandle nop = il.append(new NOP());
+		skipHdlr.setTarget(nop);
+		mg.addExceptionHandler(startTry, endTry, hdlr, new ObjectType("java.lang.NoSuchMethodError"));
+	}
+
+	/**
+	 * Generate implicit Team activation for each "normal" public method.
+	 * 
+	 * @param cg
+	 *            class for which methods are to be augmented.
+	 * @param cpg
+	 *            the constant pool of the class 'cg'.
+	 */
+	void genImplicitActivation(ClassGen cg, ConstantPoolGen cpg) {
+		Method[] methods = cg.getMethods();
+		for (int i = 0; i < methods.length; i++) {
+			Method m = methods[i];
+			if (candidateForImplicitActivation(m, cg, cpg)) {
+                if(logging) printLogMessage("Adding implicit activation to " + m.getName());
+				cg.replaceMethod(m, genImplicitActivation(m, cg.getClassName(), cpg, false)); 
+			}
+		}
+	}
+	
+	/**
+	 * Scans the team attribute StaticReplaceBinding and generates an array of base call surrogates
+	 * 
+	 * @param class_name
+	 * @param cpg
+	 * @param cg
+	 * @return
+	 */
+	private Method [] generateStaticBaseCallSurrogates(String class_name, ConstantPoolGen cpg, ClassGen cg){
+		
+		Set<String> roleMethodKeys = new HashSet<String>();
+		
+		//------------------------------------------------------------------------------------------
+		// scan static replace bindings attributes
+		//------------------------------------------------------------------------------------------
+		Attribute [] attributes = cg.getAttributes();
+		for(int k=0; k<attributes.length; k++){
+			
+			Unknown attr = isOTAttribute(attributes[k]);
+			if(attr == null) continue;
+		
+			if(attr.getName().equals("StaticReplaceBindings")) {
+				
+				byte[] indizes = attr.getBytes();
+				int count = combineTwoBytes(indizes, 0);
+	            int numberOfEntries=0;
+				String [] names;
+				numberOfEntries = 5;
+				int i = 2;
+				
+				for (int n=0; n<count;n++) {
+					names = new String[numberOfEntries];
+					i = scanStrings(names, indizes, i, cpg);
+					int index = 0;
+					String role_name             = names[index++];
+					String role_method_name      = names[index++];
+					String role_method_signature = names[index++];
+					String lift_method_name      = names[index++];
+					String lift_method_signature = names[index++];
+										
+					String roleMethodKey = genRoleMethodKey(class_name, role_name, role_method_name, role_method_signature, lift_method_name, lift_method_signature);
+					roleMethodKeys.add(roleMethodKey);
+						
+					int base_len = combineTwoBytes(indizes, i);
+					BaseMethodInfo baseMethod;
+					i += 2;
+					names = new String[3];
+					for (int n_base = 0; n_base < base_len; n_base++) {
+						int [] positions = null;
+						
+						i = scanStrings(names, indizes, i, cpg);
+						
+						int flags = indizes[i++];
+						boolean baseIsCallin     = (flags & 1) != 0;
+						boolean baseIsRoleMethod = (flags & 2) != 0;
+						boolean baseIsStatic     = (flags & 4) != 0;
+						//parameter positions scanning
+						int pos_len = combineTwoBytes(indizes, i);
+                        i+=2;
+                        
+                        if(pos_len > 0) {
+                        	positions = new int[pos_len];
+                        }
+                        
+                        for(int pos = 0; pos < pos_len; pos++){
+                        	positions[pos] = combineTwoBytes(indizes,i);
+                        	i += 2;
+                        }
+                        int translationFlags = (combineTwoBytes(indizes, i)<<16) + combineTwoBytes(indizes, i+2);
+                        i+=4;
+						baseMethod = new BaseMethodInfo(names[0], names[1], names[2], 
+														baseIsCallin, baseIsRoleMethod, baseIsStatic, 
+														positions, translationFlags);
+						
+						CallinBindingManager.assignBaseCallTag(names[0],names[1],names[2]);
+						CallinBindingManager.addStaticReplaceBindingForRoleMethod(roleMethodKey, baseMethod);
+					}					
+				}
+				break; 
+			}
+		}
+		
+		//------------------------------------------------------------------------------------------
+		// generate base call surrogates
+		//------------------------------------------------------------------------------------------
+		Iterator<String> roleMethodIter = roleMethodKeys.iterator();
+		int count = roleMethodKeys.size();
+		Method [] generatedSurrogates = new Method[count];
+		
+		int j = 0;
+		
+		while(roleMethodIter.hasNext()) {
+			String roleMethodKey = roleMethodIter.next();
+			LinkedList<BaseMethodInfo> baseMethods = CallinBindingManager.getStaticReplaceBindingsForRoleMethod(roleMethodKey);
+			
+			//split the key into team class name, role class name, role method name and role method signature
+			int firstPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR);
+			int secondPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR, firstPointIndex+1);
+			int thirdPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR, secondPointIndex+1);
+			int fourthPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR, thirdPointIndex+1);
+			int fifthPointIndex = roleMethodKey.indexOf(STATIC_REPLACE_BINDING_SEPARATOR, fourthPointIndex+1);
+			
+			String role_name = roleMethodKey.substring(firstPointIndex+2, secondPointIndex);
+			String role_method_name = roleMethodKey.substring(secondPointIndex+2, thirdPointIndex);
+			String role_method_signature = roleMethodKey.substring(thirdPointIndex+2, fourthPointIndex);
+			String lift_method_name = null;
+			String lift_method_signature = null;
+			// SH: without this check we get 
+			//        StringIndexOutOfBoundsException: String index out of range: -1
+			//     I hope this patch is correct..
+			if (  fourthPointIndex + 2 <= fifthPointIndex
+				&& fifthPointIndex + 2 < roleMethodKey.length()) 
+			{
+				lift_method_name = roleMethodKey.substring(fourthPointIndex+2, fifthPointIndex);
+				lift_method_signature = roleMethodKey.substring(fifthPointIndex+2, roleMethodKey.length());
+			}
+			
+			generatedSurrogates[j] = genBaseCallSurrogate(cg, role_name, role_method_name, 
+														  role_method_signature, 
+														  lift_method_name, lift_method_signature, baseMethods);
+			j++;
+		}
+		
+		return generatedSurrogates;
+	}
+	
+	/**
+	 * Generates a base call surrogate for a given static role method
+	 * @param cg
+	 * @param role_name		
+	 * @param role_method_name
+	 * @param role_method_signature
+	 * @param lift_method_name
+	 * @param lift_method_signature
+	 * @param base_methods
+	 * @return
+	 */
+	private Method genBaseCallSurrogate(ClassGen cg,
+										String role_name, 
+										String role_method_name,
+										String role_method_signature,
+										String lift_method_name,
+										String lift_method_signature, 
+										LinkedList<BaseMethodInfo> base_methods)
+	{	
+		ConstantPoolGen cpg = cg.getConstantPool();
+		String class_name = cg.getClassName();
+
+		if (base_methods.isEmpty()) { 
+			return null;
+		}
+		Type[] enhancedArgumentTypes = enhanceArgumentTypes(Type.getArgumentTypes(role_method_signature));
+		Type enhancedReturnType  = generalizeReturnType(Type.getReturnType(role_method_signature));
+		String[] enhancedArgumentNames = null;
+		InstructionList il = new InstructionList();
+		int accessFlags = Constants.ACC_PROTECTED;
+		
+		MethodGen baseCallSurrogate = new MethodGen(accessFlags,
+																enhancedReturnType,
+																enhancedArgumentTypes,
+																enhancedArgumentNames,
+																getBaseCallSurrogateName(role_name, role_method_name), 
+																class_name,
+																il, cpg);
+			
+		
+		LocalVariableGen otResult = null;
+		
+		/*
+		 int slot = enhancedArgumentTypes.length+1;
+		 otResult = baseCallSurrogate.addLocalVariable("_OT$result",
+		 enhancedReturnType,
+		 slot, null, null);
+		 */
+		otResult = baseCallSurrogate.addLocalVariable("_OT$result",
+				enhancedReturnType, null, null);
+		
+		il.insert(InstructionFactory.createStore(enhancedReturnType,
+				otResult.getIndex()));
+		il.insert(new ACONST_NULL());
+		il.setPositions(); // about to retrieve instruction handles.
+		
+		if(logging) printLogMessage("base-call switch has to be inserted!");
+		InstructionList loading = new InstructionList();
+		loading.append(InstructionFactory.createThis());
+		int index = 1;
+		for (int i = 0; i < enhancedArgumentTypes.length; i++) {
+			loading.append(InstructionFactory.createLoad(enhancedArgumentTypes[i],index));
+			index += enhancedArgumentTypes[i].getSize();
+		}
+		
+		Type[] argumentTypes = Type.getArgumentTypes(role_method_signature);
+		Type returnType = Type.getReturnType(role_method_signature);
+		
+		if (debugging) {
+			baseCallSurrogate.addLineNumber(il.getStart(), STEP_OVER_LINENUMBER);
+		}
+		
+		il.append(genBaseCallSwitch(cpg, base_methods, baseCallSurrogate,
+				argumentTypes,
+				returnType,
+				lift_method_name,
+				lift_method_signature,
+				otResult, loading, cg.getClassName()));
+		
+		il.append(InstructionFactory.createLoad(enhancedReturnType, otResult.getIndex()));
+		il.append(InstructionFactory.createReturn(enhancedReturnType));							
+		
+		il.setPositions();
+		baseCallSurrogate.removeNOPs();
+		baseCallSurrogate.setMaxStack();
+		baseCallSurrogate.setMaxLocals();
+		return baseCallSurrogate.getMethod();
+	}
+	
+	private static String getBaseCallSurrogateName(String class_name, String method_name){
+		// base call surrogate for static callin methods:
+		// name contains role class name and role method name, 
+		// because its generated into the team.
+		return OT_PREFIX + class_name + "$" + method_name + "$base";		
+	}
+	
+	/** 
+     * Generate a dispatching switch statement which calls the proper base method.
+	 * @param cpg
+	 * @param base_methods list of BaseMethodInfo that applies to this callin method
+	 * @param enhancedMethod the enhanced callin method
+	 * @param argumentTypes arg types of the callin method
+	 * @param returnType the return type of the original callin method
+	 * @param liftMethodSignature
+	 * @param otResult the local variable storing the base call result
+	 * @param loading an instruction list holding the original instructions for
+	 *        loading parameters
+	 * @param teamName
+	 * @param lift_method_name
+	 * @return InstructionList the complete replacement implementing the base call.
+     */
+	InstructionList genBaseCallSwitch (ConstantPoolGen cpg,
+									   LinkedList<BaseMethodInfo> base_methods, MethodGen enhancedMethod,
+									   Type[] argumentTypes,
+                                       Type returnType, String liftMethodName, String liftMethodSignature,
+                                       LocalVariableGen otResult, InstructionList loading, String teamName)
+    {
+    	
+		short invocationKind = Constants.INVOKESTATIC;
+		
+        String  className                = enhancedMethod.getClassName();
+        Type    enhancedMethodReturnType = enhancedMethod.getReturnType();
+		boolean callinHasReturnValue = returnType != Type.VOID;
+
+		InstructionList il = new InstructionList();
+
+		// Setup a variable which holds the result of this base call.
+		// This variabel is local to this segment of code and used only
+		// to transport this result out off the switch statement.
+		int     localResult = -1;
+		LocalVariableGen lg = null;
+		if (callinHasReturnValue) {
+			lg = enhancedMethod.addLocalVariable("_OT$tmpResult", returnType,
+												 null, null);
+			localResult = lg.getIndex();
+			il.append(InstructionFactory.createNull (returnType));
+			il.append(InstructionFactory.createStore(returnType, localResult));
+		}
+		
+				// ---- Prepare the switch: ----
+        InstructionHandle switchStart = il.append
+			(InstructionFactory.createLoad(Type.INT, BASE_METH_ARG));
+		// generated: _OT$baseMethTag
+        
+        //base_methods may contain duplicates!
+        //baseMethodTags is used to determine the number of cases without duplicates
+        HashSet<Integer> baseMethodTags = new HashSet<Integer>();
+        Iterator<BaseMethodInfo> iter = base_methods.iterator();
+        while(iter.hasNext()) {
+        	BaseMethodInfo baseMethod = iter.next();
+        	//baseMethodTags.add(CallinBindingManager.getBaseCallTag( baseMethod.getBaseClassName(),
+        	//														baseMethod.getBaseMethodName(),
+        	//														baseMethod.getBaseMethodSignature()));
+        	int baseMethodTag = CallinBindingManager.getBaseCallTag(baseMethod.getBaseClassName(),
+        															baseMethod.getBaseMethodName(),
+																	baseMethod.getBaseMethodSignature());
+        	baseMethodTags.add(Integer.valueOf(baseMethodTag));
+        }       
+        
+        // one break for each case clause
+        int numberOfCases = baseMethodTags.size();
+        
+        GOTO[] breaks = new GOTO[numberOfCases];
+        for (int i=0; i<numberOfCases; i++)
+            breaks[i] = new GOTO(null);
+        
+        int[]               matches = new int[numberOfCases];
+        InstructionHandle[] targets = new InstructionHandle[numberOfCases];
+		int caseCounter = 0;
+
+		//now baseMethodTags is used to store the handled tags
+		baseMethodTags.clear();
+		
+		//JU:
+		Type[] enhancedMethodArguments = enhancedMethod.getArgumentTypes();
+		Type[] enhancedArgumentsForBaseCall = new Type[enhancedMethodArguments.length - 1];
+		System.arraycopy(enhancedMethodArguments, 0,
+                enhancedArgumentsForBaseCall, 0,
+                enhancedArgumentsForBaseCall.length);
+		
+		Iterator<BaseMethodInfo> it = base_methods.iterator();
+		while (it.hasNext()) {
+			
+			BaseMethodInfo baseMethod = it.next();
+			String baseClassName = baseMethod.getBaseClassName();
+			String baseMethodName = baseMethod.getBaseMethodName();
+			String baseMethodSignature = baseMethod.getBaseMethodSignature();
+			int base_method_tag = CallinBindingManager.getBaseCallTag(baseClassName, baseMethodName, baseMethodSignature);
+			
+			//if the current baseMethod is a dulpicate:
+			// workaround for jdk 1.4:
+			Integer bmt = Integer.valueOf(base_method_tag);
+			//if(baseMethodTags.contains(base_method_tag)){
+			if (baseMethodTags.contains(bmt)) {
+				continue;
+			}
+			
+			//baseMethodTags.add(base_method_tag);
+			baseMethodTags.add(bmt);
+		
+			int [] parameterPositions = baseMethod.getParameterPositions();
+			int len = Type.getArgumentTypes(baseMethodSignature).length;
+
+			// if the base method is a callin method as well, further enhance the signature:
+			if (baseMethod.isCallin) 
+				len += EXTRA_ARGS;			
+
+
+			matches[caseCounter] = CallinBindingManager.getBaseCallTag(baseClassName, baseMethodName, baseMethodSignature);
+            InstructionHandle nextBranch = il.append(new NOP());
+
+			Type[] baseMethodArgumentTypes   = Type.getArgumentTypes(baseMethodSignature);
+			Type   baseMethodReturnType      = Type.getReturnType   (baseMethodSignature);
+			String baseChainMethodName       = genChainMethName(baseMethodName);
+			Type   baseChainReturnType       = object; // ALWAYS
+			Type[] enhancedBaseArgumentTypes = enhanceArgumentTypes(baseMethodArgumentTypes);
+			
+			boolean resultLiftingNecessary   = false;
+
+            // TODO (SH): if both types are ObjectType we should probably use subclassOf() ??
+            // (don't lift if simple polymorphism suffices!)
+            //TODO: if the base method return type is a subtype of the role method return type no lifting has to take place!! is this allowed??
+			//if (!returnTypeCompatible(baseMethodReturnType, returnType) && callinHasReturnValue)
+			if (/*!baseMethodReturnType.equals(object) &&*/ 
+				   !baseMethodReturnType.equals(returnType) 
+				&& !(baseMethodReturnType instanceof BasicType) // requires boxing not lifting
+				&& !(returnType instanceof BasicType)			// requires unboxing not lifting
+				&& callinHasReturnValue)
+			{
+				resultLiftingNecessary = true;
+			}
+
+			// --- load arguments of the new method: ---
+			//     (letters refer to document parameter-passing.odg)
+		
+			// (u) generate extra arguments (indices are equal at role and base):
+			for (int idx = 0; idx < EXTRA_ARGS; idx++) 
+				il.append(InstructionFactory.createLoad(enhancedMethodArguments[idx], 
+														idx+1)); // first arg is "this" (enclosing team)			
+			
+			// (v)(w)(x) split loading sequence and transfer source-level arguments
+			// (includes reverse-application of parameter mappings):
+			InstructionHandle baseCallLine = il.append(translateLoads(splitLoading(cpg,
+																				   loading.copy(),
+																				   argumentTypes), 
+																	  enhancedMethodArguments, 
+																	  enhancedBaseArgumentTypes, 
+																	  parameterPositions, 
+																	  teamName, 
+																	  null,
+																	  baseMethod,
+																	  EXTRA_ARGS/*start*/,
+																	  cpg));
+			// --- done loading ---			
+
+			// invoke the chaining method of the base class (base-call!):
+			il.append(factory.createInvoke(baseClassName, 
+										   baseChainMethodName,
+										   baseChainReturnType,
+										   enhancedBaseArgumentTypes,
+										   invocationKind));
+
+			// FIXME(SH): if this assert holds, remove computing of resultLiftingNecessary above.
+			assert resultLiftingNecessary == ((baseMethod.translationFlags & 1) != 0);
+			
+			if (resultLiftingNecessary) { // call the lift-method: 
+				Type[] liftMethodArgs = Type.getArgumentTypes(liftMethodSignature);
+				Type liftMethodReturnType = Type.getReturnType(liftMethodSignature);
+
+				// cast result of base call:
+				il.append(factory.createCast(baseChainReturnType, baseMethodReturnType));
+
+				// load the team instance at which to call the lift method:
+				il.append(InstructionFactory.createThis());
+				il.append(factory.createCast(object, new ObjectType(teamName)));
+				
+				// put them in correct order:
+                il.append(new SWAP()); // -> .., this$0, (BaseType)result
+				
+				il.append(factory.createInvoke(teamName,
+											   liftMethodName,
+											   liftMethodReturnType,
+											   liftMethodArgs,
+											   Constants.INVOKEVIRTUAL));
+			}
+
+			// adjust the return value to the type expected by the WRAPPER:
+			il.append(new DUP()); // keep for adjustment below
+			if (!resultLiftingNecessary)
+				adjustValue(il, null, baseChainReturnType, enhancedMethodReturnType);
+			il.append(InstructionFactory.createStore(enhancedMethodReturnType,
+					otResult.getIndex())); // store "globally"
+			// this store is needed to tunnel unused results through the callin.
+			
+			InstructionHandle afterBaseCallLine = il.append(new NOP());
+			
+			// adjust the return value to the type expected by the ORIGINAL CALLIN:
+			adjustValue(il, null,  baseChainReturnType, returnType);
+			if (callinHasReturnValue) {
+				il.append(InstructionFactory.createStore(returnType, localResult)); // store "locally"
+			}	
+ 			    // this store is useful for callins which make use of the result.
+
+            targets[caseCounter] = nextBranch;
+            il.append(breaks[caseCounter]);
+            // generated: break;
+
+            caseCounter++;
+            
+            if (debugging) {
+            	enhancedMethod.addLineNumber(baseCallLine, STEP_INTO_LINENUMBER);
+            	enhancedMethod.addLineNumber(afterBaseCallLine, STEP_OVER_LINENUMBER);
+            }
+		}
+        
+        //JU: added the follwing part (begin) -----------------------------------------------------	
+        InstructionHandle defaultBranch = il.append(new NOP());
+        
+        if (logging)
+			printLogMessage("Exeption has to be thrown! Base-Call is impossible.");
+		
+		il.append(factory.createNew(OTConstants.unsupportedFeature));
+		il.append(new DUP());
+		// ## FIXME: fix otld$
+		il.append(new PUSH(cpg, "Binding-Error: base-call from " + className + "." + enhancedMethod.getName()
+								+ "impossible! This problem is documented in OTLD $XY."));
+		il.append(factory.createInvoke(OTConstants.unsupportedFeature.getClassName(),
+													 Constants.CONSTRUCTOR_NAME,
+													 Type.VOID,
+													 new Type[] { Type.STRING }, 
+													 Constants.INVOKESPECIAL));
+		il.append(new ATHROW());
+		//JU: (end) --------------------------------------------------------------------------------
+		
+		InstructionHandle afterSwitch = il.append(new NOP()); // all breaks point here.
+
+		il.append(switchStart, createLookupSwitch(matches, targets, breaks,
+												  defaultBranch, afterSwitch));
+
+		// retrieve locally stored result:
+		if (callinHasReturnValue) {
+			il.append(InstructionFactory.createLoad(returnType, localResult));
+			lg.setStart(il.getStart()); // restrict local variable to this segment.
+			lg.setEnd(il.getEnd());
+		}
+        return il;
+	}
+	
+	/**
+	 * Generates a key for the given role method parameters
+	 * 
+	 * @param teamClassName
+	 * @param roleClassName
+	 * @param roleMethodName
+	 * @param roleMethodSignature
+	 * @param liftMethodSignature
+	 * @return
+	 */
+	private static String genRoleMethodKey(String teamClassName,
+			String roleClassName, String roleMethodName,
+			String roleMethodSignature, String liftMethodName,
+			String liftMethodSignature)
+	{
+		StringBuilder roleMethodKey = new StringBuilder(64);
+		roleMethodKey.append(teamClassName);
+		roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
+		roleMethodKey.append(roleClassName);
+		roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
+		roleMethodKey.append(roleMethodName);
+		roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
+		roleMethodKey.append(roleMethodSignature);
+		roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
+		roleMethodKey.append(liftMethodName);
+		roleMethodKey.append(STATIC_REPLACE_BINDING_SEPARATOR);
+		roleMethodKey.append(liftMethodSignature);
+		return roleMethodKey.toString();
+	}
+	
+	/**
+	  * Read the InheritedRoles attribute and return the list of inherited roles.
+	  * @param cg	The ClassGen of the inspected class.
+	  * @param cpg	The constant pool of the instpected class.
+	  * @return		A list of inherited role names.
+	  */
+	 private List<String> getInheritedRoleNames(ClassGen cg, ConstantPoolGen cpg) {
+		 Attribute[] attributes = cg.getAttributes();		
+		 LinkedList<String> inheritedRoleNames = new LinkedList<String>();
+		 for (int i = 0; i < attributes.length; i++) {
+			 Attribute actAttr = attributes[i];
+			 if (actAttr instanceof Unknown) {
+				 Unknown attr = (Unknown)actAttr;
+				 byte[] indizes = attr.getBytes();
+				 int count = combineTwoBytes(indizes, 0);
+				 if (attr.getName().equals("InheritedRoles")) {
+					 int j = 2;
+					 while (j<=2*count) {
+						 String[] names = new String[1];
+						 j = scanStrings(names, indizes, j, cpg);
+						 String inherited_role = names[0];
+						 inheritedRoleNames.add(inherited_role);
+					 }
+				 }
+			 }
+		 }
+		 return inheritedRoleNames;
+	 }
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/ThreadActivation.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ThreadActivation.java
new file mode 100644
index 0000000..7ac2e1e
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/ThreadActivation.java
@@ -0,0 +1,190 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: ThreadActivation.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import java.util.HashSet;
+
+import de.fub.bytecode.classfile.*;
+import de.fub.bytecode.generic.*;
+import de.fub.bytecode.*;
+
+
+/**
+ * This transformer inserts a notification call to the TeamThreadManager at the 
+ * beginning of every run()-Method in Subtypes of java.lang.Thread or java.lang.Runnable. 
+ * Thre TeamThreadManager then ensures the thread activation of the current thread 
+ * for every global active team instance.
+ * 
+ * @author  Christine Hundt
+ * @author  Stephan Herrmann
+ */
+public class ThreadActivation 
+{
+	// name of a generated field that stores the thread which created a given runnable:
+	private static final String CREATION_THREAD = "_OT$creationThread";
+	HashSet<String> transformableClasses = new HashSet<String>();
+	
+	private boolean shouldTransform(ClassGen cg) {
+		Method runMethode = cg.containsMethod("run", "()V");
+		if (runMethode == null || runMethode.isAbstract()) {
+			// this class contains no concrete run() method
+			return false;
+		}
+		String class_name = cg.getClassName();
+		// check if this class is a subtype of Thread or Runnable:
+		try {
+			return Repository.implementationOf(class_name, "java.lang.Runnable") || Repository.instanceOf(class_name, "java.lang.Thread");
+		} catch (NullPointerException npe) {
+			if (ObjectTeamsTransformation.WORKAROUND_REPOSITORY) {
+				return false;
+			}
+			else
+				throw npe; // rethrow
+		}
+	}
+	public void doTransformInterface(ClassEnhancer enhancer, ClassGen cg) {
+		if (!shouldTransform(cg))
+			return;
+		
+		// if class is already transformed by this transformer
+		if (this.transformableClasses.contains(cg.getClassName()))
+			return;
+		
+		this.transformableClasses.add(cg.getClassName());
+		FieldGen field = new FieldGen(Constants.ACC_PRIVATE, OTConstants.threadType, CREATION_THREAD, cg.getConstantPool());
+		enhancer.addField(field.getField(), cg);
+	}
+	/**
+     *  
+     */	
+	public void doTransformCode(ClassGen cg) {
+		if (!this.transformableClasses.contains(cg.getClassName()))
+			return;
+		
+		this.transformableClasses.remove(cg.getClassName());
+
+		InstructionFactory factory = new InstructionFactory(cg);
+
+		for (Method method : cg.getMethods()) {
+			MethodGen mg = isRootCtor(method, cg);
+			if (mg != null)
+				enhanceConstructor(cg, factory, method, mg);
+		}
+		
+		enhanceRunMethod(cg, factory);
+    }
+	private void enhanceRunMethod(ClassGen cg, InstructionFactory factory) {
+		String class_name = cg.getClassName();
+		ConstantPoolGen cpg = cg.getConstantPool();
+
+		Method runMethode = cg.containsMethod("run", "()V"); // existence checked in transformInterface
+
+		MethodGen mg = new MethodGen(runMethode, class_name, cpg);
+		InstructionList il = mg.getInstructionList();
+		InstructionHandle try_start = il.getStart();
+		
+		/** *** Insert a call to TeamThreadManager.newThreadStarted() at the beginning of the run() method: ****** */	
+		InstructionList threadActivation = new InstructionList();
+		threadActivation.append(new ICONST(0)); // isMain = false
+		threadActivation.append(InstructionConstants.ALOAD_0); // parent=this._OT$creationThread;
+		threadActivation.append(factory.createFieldAccess(class_name, CREATION_THREAD, OTConstants.threadType, Constants.GETFIELD));
+		threadActivation.append(factory.createInvoke("org.objectteams.TeamThreadManager", 
+				                                             "newThreadStarted",
+															 Type.BOOLEAN,
+															 new Type[]{Type.BOOLEAN, OTConstants.threadType},
+															 Constants.INVOKESTATIC));
+		LocalVariableGen flag = mg.addLocalVariable("_OT$isThreadStart", Type.BOOLEAN, il.getStart(), il.getEnd());
+		threadActivation.append(new ISTORE(flag.getIndex()));
+		il.insert(threadActivation);
+		
+		/** *** Insert a call to TeamThreadManager.threadEnded() before every return of the run() method: ******** */	
+		InstructionList threadDeactivation = new InstructionList();
+		threadDeactivation.append(new ILOAD(flag.getIndex()));
+		BranchInstruction ifIsThreadStarted = new IFEQ(null);
+		threadDeactivation.append(ifIsThreadStarted);
+		threadDeactivation.append(factory.createInvoke("org.objectteams.TeamThreadManager", 
+                "threadEnded",
+				 Type.VOID,
+				 Type.NO_ARGS,
+				 Constants.INVOKESTATIC));
+		ifIsThreadStarted.setTarget(threadDeactivation.append(new NOP()));
+
+		FindPattern findPattern = new FindPattern(il);
+		String pat = "`ReturnInstruction'";
+		InstructionHandle ih = findPattern.search(pat);
+		while (ih != null) {
+			// insert deactivate-call before return instruction in ih:
+			InstructionList deactivationCopy = threadDeactivation.copy();
+			InstructionHandle inserted = il.insert(ih, deactivationCopy); // instruction lists can not be reused
+			il.redirectBranches(ih, inserted);// SH: retarget all jumps that targeted at the return instruction
+			if (ih.getNext() == null)
+				break; // end of instruction list reached
+			ih = findPattern.search(pat, ih.getNext());
+		}
+
+		/** **** Add an exception handler which calls TeamThreadManager.threadEnded() *****
+		 * ***** before throwing the exception (finaly-simulation): 											        */
+		ObjectType throwable = new ObjectType("java.lang.Throwable");
+		LocalVariableGen exception = mg.addLocalVariable(
+				"_OT$thrown_exception", throwable, null, null);
+		InstructionHandle try_end = il.getEnd();
+		InstructionList deactivation_ex = threadDeactivation.copy();
+		deactivation_ex.insert(InstructionFactory.createStore(throwable, exception.getIndex()));
+		deactivation_ex.append(InstructionFactory.createLoad(throwable, exception.getIndex()));
+		deactivation_ex.append(new ATHROW());
+		InstructionHandle deactivation_handler = il.append(il.getEnd(), deactivation_ex);
+		mg.addExceptionHandler(try_start, try_end, deactivation_handler, throwable);
+		/** ******************************************************************** */		
+		
+		mg.setMaxStack();
+        mg.setMaxLocals();
+        Method generatedMethod = mg.getMethod();
+        cg.replaceMethod(runMethode, generatedMethod);
+        threadActivation.dispose();
+        il.dispose();
+	}
+	// is method a constructor that does not invoke another this()-ctor?
+	private MethodGen isRootCtor(Method method, ClassGen cg) {
+		if (!method.getName().equals("<init>"))
+			return null;
+		String className = cg.getClassName();
+		ConstantPoolGen cpg = cg.getConstantPool();
+		MethodGen mg = new MethodGen(method, className, cpg);
+		InstructionList il = mg.getInstructionList();
+		InstructionHandle ih = il.getStart();
+		while (ih != null && ih.getInstruction().getOpcode() != Constants.INVOKESPECIAL) {
+			ih = ih.getNext();
+		}
+		if (ih == null)
+			return null;
+		if (((InvokeInstruction)ih.getInstruction()).getClassName(cpg).equals(className))
+			return null; // this-call
+		return mg;
+	}
+	// add statements to store the thread that created this runnable
+	private void enhanceConstructor(ClassGen cg, InstructionFactory factory, Method initMethod, MethodGen mg) {
+		String class_name = cg.getClassName();
+		InstructionList il = mg.getInstructionList();
+		il.insert(il.getEnd(), InstructionConstants.ALOAD_0);
+		il.insert(il.getEnd(), factory.createInvoke("java.lang.Thread", "currentThread", OTConstants.threadType, new Type[0], Constants.INVOKESTATIC));
+		il.insert(il.getEnd(), factory.createFieldAccess(class_name, CREATION_THREAD, OTConstants.threadType, Constants.PUTFIELD));
+		mg.setMaxStack();
+	    mg.setMaxLocals();
+	    cg.replaceMethod(initMethod, mg.getMethod());
+	    il.dispose();
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java
new file mode 100644
index 0000000..e390663
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java
@@ -0,0 +1,143 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2005-2008 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: JPLISEnhancer.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.jplis;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.objectteams.otre.ClassEnhancer;
+import org.eclipse.objectteams.otre.OTREInternalError;
+import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
+
+import de.fub.bytecode.Constants;
+import de.fub.bytecode.classfile.ClassParser;
+import de.fub.bytecode.classfile.Field;
+import de.fub.bytecode.classfile.Method;
+import de.fub.bytecode.classfile.Utility;
+import de.fub.bytecode.generic.ClassGen;
+import de.fub.bytecode.generic.ConstantPoolGen;
+import de.fub.bytecode.generic.MethodGen;
+
+
+/**
+* This class implements the ClassEnhancer interface with the JPLIS (Java5) specific behavior.
+*  
+* @author Christine Hundt
+* @author Juergen Widiker
+* @author Stephan Herrmann
+*/
+
+public class JPLISEnhancer implements ClassEnhancer {
+
+	private ClassLoader loader;
+	
+	public JPLISEnhancer(ClassGen cg, ClassLoader loader) {
+		this.loader = loader;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.objectteams.otre.ClassEnhancer#addImplements(java.lang.String, de.fub.bytecode.generic.ClassGen)
+	 */
+	public void addImplements(String interfaceName, ClassGen cg) {
+		cg.addInterface(interfaceName);		
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.objectteams.otre.common.ClassEnhancer#addMethod(de.fub.bytecode.classfile.Method, de.fub.bytecode.generic.ClassGen)
+	 */
+	public void addMethod(Method m, ClassGen cg) {
+		if (cg.containsMethod(m.getName(), m.getSignature()) != null)
+			new OTREInternalError("Warning: repetive adding of method "
+					           + m.getName() + m.getSignature() 
+							   + " to class " + cg.getClassName())
+						.printStackTrace();
+		cg.addMethod(m);
+	}
+
+	public void addOrReplaceMethod(Method method, ClassGen cg) {
+		Method existingMethod = cg.containsMethod(method.getName(), method.getSignature());
+		if (existingMethod == null)
+			addMethod(method, cg);
+		else
+			cg.replaceMethod(existingMethod, method);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.objectteams.otre.common.ClassEnhancer#addField(de.fub.bytecode.classfile.Field, de.fub.bytecode.generic.ClassGen)
+	 */
+	public void addField(Field f, ClassGen cg) {
+		if (cg.containsField(f.getName()) != null)
+			new OTREInternalError("Warning: repetitive adding of field "
+					           + f.getName() + f.getSignature() 
+							   + " to class " + cg.getClassName())
+						.printStackTrace();
+		cg.addField(f);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.objectteams.otre.common.ClassEnhancer#loadClass(java.lang.String)
+	 */
+	public void loadClass(String className, ObjectTeamsTransformation client) {
+		// SH: no forced class loading within OT/Equinox
+		if(System.getProperty("ot.equinox") != null)
+			return;
+		try {
+			String binaryName = className.replace('.', '/');
+			InputStream is = loader.getResourceAsStream(binaryName+".class");
+			if (is != null) {
+				ClassGen cg = new ClassGen(new ClassParser(is, className).parse());
+				client.checkReadClassAttributes(this, cg, className, cg.getConstantPool());
+			}
+		} catch (IOException ex) {
+			ex.printStackTrace();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.objectteams.otre.common.ClassEnhancer#decapsulateMethod(de.fub.bytecode.classfile.Method, java.lang.String, de.fub.bytecode.generic.ConstantPoolGen)
+	 */
+	public void decapsulateMethod(Method m, ClassGen cg, String packageName, ConstantPoolGen cpg) {
+		String className = cg.getClassName();
+		int flags = m.getAccessFlags();
+		MethodGen mg = new MethodGen(m, className, cpg);
+
+		if ((flags & Constants.ACC_PUBLIC) == 0) {
+			int newFlags = flags;
+			newFlags &= ~(Constants.ACC_PROTECTED|Constants.ACC_PRIVATE); // clear old visibility
+			newFlags |= Constants.ACC_PUBLIC;                             // set new visibility
+			mg.setAccessFlags(newFlags);
+            if(System.getProperty("ot.log") != null)
+                ObjectTeamsTransformation.printLogMessage("Adjusting from "
+										+ Utility.accessToString(flags)
+										+ " to public:\n\t"
+										+ className
+                        				+ "." + m);
+			if (!packageName.equals("NO_PACKAGE")) 
+				checkSeal(packageName, className);
+		}
+		cg.replaceMethod(m, mg.getMethod());
+	}
+	
+	private static void checkSeal(String package_name, String class_name) {
+		Package pckg = Package.getPackage(package_name);
+		if ( (pckg != null) && pckg.isSealed()) 
+			throw new IllegalAccessError(
+					"OT/J callout binding:\n"
+					+"Trying to break sealed "+pckg);
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java
new file mode 100644
index 0000000..df7488b
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java
@@ -0,0 +1,287 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2005-2009 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: ObjectTeamsTransformer.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.jplis;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.objectteams.otre.BaseCallRedirection;
+import org.eclipse.objectteams.otre.BaseMethodTransformation;
+import org.eclipse.objectteams.otre.BaseTagInsertion;
+import org.eclipse.objectteams.otre.Decapsulation;
+import org.eclipse.objectteams.otre.LiftingParticipantTransformation;
+import org.eclipse.objectteams.otre.LowerableTransformation;
+import org.eclipse.objectteams.otre.OTConstants;
+import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
+import org.eclipse.objectteams.otre.StaticSliceBaseTransformation;
+import org.eclipse.objectteams.otre.SubBoundBaseMethodRedefinition;
+import org.eclipse.objectteams.otre.TeamInterfaceImplementation;
+import org.eclipse.objectteams.otre.ThreadActivation;
+import org.eclipse.objectteams.otre.util.AttributeReadingGuard;
+import org.eclipse.objectteams.otre.util.CallinBindingManager;
+
+import de.fub.bytecode.Repository;
+import de.fub.bytecode.classfile.ClassParser;
+import de.fub.bytecode.classfile.JavaClass;
+import de.fub.bytecode.generic.ClassGen;
+
+
+/**
+ * Main entry into the OTRE when using JPLIS
+ * 
+ * @author Christine Hundt
+ * @author Stephan Herrmann
+ */
+public class ObjectTeamsTransformer implements ClassFileTransformer {
+	
+	// force loading all transformer classes to reduce risk of deadlock in class loading.
+	static Class<?>[] transformerClasses = new Class<?>[] {	
+		BaseCallRedirection.class, 
+		BaseMethodTransformation.class,
+		BaseTagInsertion.class,
+		Decapsulation.class,
+		LiftingParticipantTransformation.class,
+		LowerableTransformation.class,
+		StaticSliceBaseTransformation.class,
+		SubBoundBaseMethodRedefinition.class,
+		TeamInterfaceImplementation.class,
+		ThreadActivation.class
+	};
+	
+	/**
+	 * One instance of this class is used per class loader to ensure disjoint scopes.
+	 */
+	static class StateGroup {
+		ObjectTeamsTransformation.SharedState bcrState = new ObjectTeamsTransformation.SharedState();
+		ObjectTeamsTransformation.SharedState bmtState = new ObjectTeamsTransformation.SharedState();
+		BaseTagInsertion.SharedState 		  btiState = new BaseTagInsertion.SharedState();
+		Decapsulation.SharedState 			  decState = new Decapsulation.SharedState();
+		ObjectTeamsTransformation.SharedState lptState = new ObjectTeamsTransformation.SharedState();
+		ObjectTeamsTransformation.SharedState lowState = new ObjectTeamsTransformation.SharedState();
+		ObjectTeamsTransformation.SharedState ssbtState = new ObjectTeamsTransformation.SharedState();
+		ObjectTeamsTransformation.SharedState sbbmrState = new ObjectTeamsTransformation.SharedState();
+		ObjectTeamsTransformation.SharedState tiiState = new ObjectTeamsTransformation.SharedState();
+	}
+	static Map<ClassLoader, StateGroup> states = new HashMap<ClassLoader, StateGroup>();
+
+	static boolean warmedUp = false;
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader,
+	 *      java.lang.String, java.lang.Class, java.security.ProtectionDomain,
+	 *      byte[])
+	 */
+	public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
+			ProtectionDomain protectionDomain, byte[] classfileBuffer)
+			throws IllegalClassFormatException
+	{
+		if (warmedUp)
+			return internalTransform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
+		synchronized (loader) {
+			try {
+				return internalTransform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
+			} finally {
+				warmedUp = true;
+			}		
+		}
+	}
+	public byte[] internalTransform(ClassLoader loader, String className, Class<?> classBeingRedefined,
+			ProtectionDomain protectionDomain, byte[] classfileBuffer)
+			throws IllegalClassFormatException
+	{
+		if (className.startsWith("org/objectteams/transformer")
+				|| className.startsWith("org/cs3/jmangler")
+				|| className.startsWith("de/fub/bytecode"))
+		{
+			// skip OTRE, BCEL and JMangler classes
+			return null;
+		}
+//		if (!(className.startsWith("java") || className.startsWith("sun")))
+			// System.err.println("ObjectTeamsTransformer transforming: " + className);
+		if (classBeingRedefined != null) {
+			System.out.println("Redefinition!");
+			return null;
+		}
+		
+		// state sharing among transformers:
+		StateGroup states = ObjectTeamsTransformer.states.get(loader);
+		if (states == null)
+			ObjectTeamsTransformer.states.put(loader, states = new StateGroup());
+		//
+		// One fresh instance of each transformer for a given class:
+		//
+		BaseCallRedirection baseCallRedirection 
+			= new BaseCallRedirection(				loader,	states.bcrState);
+		BaseMethodTransformation baseMethodTransformation 
+			= new BaseMethodTransformation(			loader,	states.bmtState);
+		BaseTagInsertion baseTagInsertion 
+			= new BaseTagInsertion(							states.btiState);
+		Decapsulation decapsulation 
+			= new Decapsulation(					loader,	states.decState);
+		LiftingParticipantTransformation liftingParticipantTransformation 
+			= new LiftingParticipantTransformation(	loader, states.lptState);
+		LowerableTransformation lowerableTransformation 
+			= new LowerableTransformation(			loader, states.lowState);
+		StaticSliceBaseTransformation staticSliceBaseTransformation
+			= new StaticSliceBaseTransformation(	loader, states.ssbtState);
+		SubBoundBaseMethodRedefinition subBoundBaseMethodRedefinition 
+			= new SubBoundBaseMethodRedefinition(	loader,	states.sbbmrState);
+		TeamInterfaceImplementation teamInterfaceImplementation 
+			= new TeamInterfaceImplementation(true, loader, states.tiiState);
+		ThreadActivation threadActivation 
+			= new ThreadActivation();
+				
+		// tell Repository about the class loader for improved lookupClass()
+		ClassLoader prevLoader= Repository.classLoaders.get();
+		Repository.classLoaders.set(loader);
+		
+		InputStream is  = new ByteArrayInputStream(classfileBuffer);
+		try {
+			JavaClass java_class = new ClassParser(is, className).parse();
+			//Repository.addClass(java_class);
+			ClassGen cg = new ClassGen(java_class);
+			
+			JPLISEnhancer jpe = new JPLISEnhancer(cg, loader);
+			
+			Collection<String> adaptedBases; // [OT/Equinox]
+			// [OT/Equinox] remember the first transformation which holds adaptedBases
+			adaptedBases= setFirstTransformation(subBoundBaseMethodRedefinition);
+			// [OT/Equinox] if class has previously been transformed fetch the list of
+			// adapted bases from the CallinBindingManager instead of reading it now.
+			if (   (cg.getAccessFlags() & OTConstants.TEAM) != 0
+				&& !AttributeReadingGuard.getInstanceForLoader(loader).iAmTheFirst(cg.getClassName())) 
+			{
+				List<String> basesOfTeam = CallinBindingManager.getBasesPerTeam(cg.getClassName());
+				if (basesOfTeam != null)
+					adaptedBases.addAll(basesOfTeam);				
+			}
+			subBoundBaseMethodRedefinition.doTransformInterface(jpe, cg);
+			baseCallRedirection.doTransformInterface(jpe, cg);
+			decapsulation.doTransformInterface(jpe, cg);
+		try {
+			baseMethodTransformation.useReflection = (loader == null); // bootstrap classes cannot be called directly
+			baseMethodTransformation.doTransformInterface(jpe, cg);
+		} catch (Throwable t) {
+			System.err.println("Error transforming class: "+cg.getClassName());
+			t.printStackTrace();
+		}
+			baseTagInsertion.doTransformInterface(jpe, cg);
+			lowerableTransformation.doTransformInterface(jpe, cg);
+			staticSliceBaseTransformation.doTransformInterface(jpe, cg);
+			teamInterfaceImplementation.doTransformInterface(jpe, cg);
+			
+//			subBoundBaseMethodRedefinition.doTransformInterface(jpe, cg);
+//			baseCallRedirection.doTransformInterface(jpe, cg);
+//			decapsulation.doTransformInterface(jpe, cg);
+//			baseMethodTransformation.doTransformInterface(jpe, cg);
+//			baseTagInsertion.doTransformInterface(jpe, cg);
+//			staticSliceBaseTransformation.doTransformInterface(jpe, cg);
+//			teamInterfaceImplementation.doTransformInterface(jpe, cg);
+			threadActivation.doTransformInterface(jpe, cg);
+
+			
+//			baseCallRedirection.doTransformCode(cg); // empty method
+			baseMethodTransformation.doTransformCode(cg);
+			baseTagInsertion.doTransformCode(cg);
+			liftingParticipantTransformation.doTransformCode(cg);
+			staticSliceBaseTransformation.doTransformCode(cg);
+			teamInterfaceImplementation.doTransformCode(cg);
+			threadActivation.doTransformCode(cg);
+			
+			JavaClass new_java_class = cg.getJavaClass(); 
+			if (dumping) {
+				new_java_class.dump("jplis_dump/" + className + ".class");
+			}
+			return new_java_class.getBytes();
+		} catch (IOException e) {
+			System.err.println("ClassFileTransformer could not parse class file buffer to JavaClass");
+			e.printStackTrace();
+		} finally {
+			// uninstall class loader:
+			Repository.classLoaders.set(prevLoader);
+		}
+		return null;
+	}
+	
+	/**
+	 * External API (for OT/Equinox):
+	 * Destructively fetch the set of adapted base classes 
+	 * recorded since the last call to this method.
+	 * 
+	 * @return
+	 */
+	public Collection<String> fetchAdaptedBases() {
+		if (this.firstTransformation == null)
+			return null;
+		Collection<String>result= this.firstTransformation.fetchAdaptedBases();
+		this.firstTransformation= null;
+		return result;
+	}
+	
+	/**
+	 * External API (for OT/Equinox):
+	 * Read the OT-Attributes of a class without loading the class.
+	 * @throws IOException 
+	 * @throws ClassFormatError 
+	 */
+	public void readOTAttributes(InputStream file, String fileName, ClassLoader loader) 
+			throws ClassFormatError, IOException 
+	{
+		ClassParser   cp  = new ClassParser(file, fileName);
+		ClassGen      cg  = new ClassGen(cp.parse());
+		JPLISEnhancer jpe = new JPLISEnhancer(cg, /*loader (unused)*/null);
+		ClassLoader prevLoader= Repository.classLoaders.get();
+		Repository.classLoaders.set(loader);
+		try {
+			setFirstTransformation(new ObjectTeamsTransformation(loader, null) {});
+			firstTransformation.checkReadClassAttributes(jpe, cg, cg.getClassName(), cg.getConstantPool());
+		} finally {
+			Repository.classLoaders.set(prevLoader);
+		}
+	}
+	
+	// helper structure for above:
+	/* The first transformation performed holds the list of adapted bases. */
+	private ObjectTeamsTransformation firstTransformation;
+
+	/* @return the collection of adapted bases currently in use. */
+	private Collection<String> setFirstTransformation(ObjectTeamsTransformation t) {
+		if (this.firstTransformation != null)
+			t.adaptedBases= this.firstTransformation.adaptedBases; // collect into existing
+		this.firstTransformation= t;
+		return t.adaptedBases;
+	}
+
+	//	 ------------------------------------------
+	// ---------- Class file dumping: ----------------------
+	// ------------------------------------------
+	/** Initialized from property <tt>ot.dump</tt>. */
+    static boolean dumping = false;
+    static {
+        if(System.getProperty("ot.dump")!=null)
+            dumping = true;
+    }
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/otreAgent.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/otreAgent.java
new file mode 100644
index 0000000..ee6077f
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/jplis/otreAgent.java
@@ -0,0 +1,48 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2005-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: otreAgent.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.jplis;
+
+import java.lang.instrument.Instrumentation;
+
+/**
+*
+* @version $Id: otreAgent.java 23408 2010-02-03 18:07:35Z stephan $
+* @author Christine Hundt
+*/
+public class otreAgent {
+
+	private static Instrumentation instCopy;
+//	private static String optionsCopy;
+	
+	private static ObjectTeamsTransformer otTransformer;
+
+	public static void premain(String options, Instrumentation inst) {
+		instCopy = inst;
+//		optionsCopy = options;
+		
+		// add all necessary transformers:
+		otTransformer = new ObjectTeamsTransformer();
+		instCopy.addTransformer(otTransformer);
+		
+		/* All future class definitions will be seen by the transformer, 
+		 except definitions of classes upon which any registered transformer is dependent. */
+	}
+	
+	public static Instrumentation getInstrumentation() {
+		return instCopy;
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AnnotationHelper.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AnnotationHelper.java
new file mode 100644
index 0000000..9f01412
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AnnotationHelper.java
@@ -0,0 +1,102 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2009 Stephan Herrmann
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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$
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 			Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
+import org.objectteams.ImplicitTeamActivation;
+
+import de.fub.bytecode.classfile.Attribute;
+import de.fub.bytecode.classfile.Unknown;
+import de.fub.bytecode.generic.ConstantPoolGen;
+
+/** 
+ * Helper class for parsing / skipping runtime visible annotations.
+ * 
+ * @author stephan
+ * @since 1.4.0
+ */
+public class AnnotationHelper {
+
+	/**
+	 * Does any of the given attributes contain an {@link ImplicitTeamActivation} annotation?
+	 * @param attrs attributes to inspect
+	 * @param cpg   constant pool for string lookup
+	 * @return true if an {@link ImplicitTeamActivation} annotation was found.
+	 */
+	public static boolean containsImplicitActivationAttribute(Attribute[] attrs, ConstantPoolGen cpg) {
+		if (attrs != null) {
+			for (Attribute attr : attrs) {
+				if (attr instanceof Unknown && ((Unknown)attr).getName().equals("RuntimeVisibleAnnotations")) {
+					Unknown unknown = (Unknown) attr;
+					byte[] bytes = unknown.getBytes();
+					int len = ObjectTeamsTransformation.combineTwoBytes(bytes, 0);
+					int i = 2;
+					String[] names = new String[1];
+					for (int n=0; n<len; n++) {
+						i = ObjectTeamsTransformation.scanStrings(names, bytes, i, cpg);
+						if ("Lorg/objectteams/ImplicitTeamActivation;".equals(names[0]))
+							return true;
+						i = skipNameValuePairs(bytes, i, names[0], cpg);
+					}
+				}						
+			}
+		}
+		return false;
+	}
+
+	private static int  skipNameValuePairs(byte[] bytes, int i, String typeName, ConstantPoolGen cpg) {
+		int numPairs = ObjectTeamsTransformation.combineTwoBytes(bytes, i);
+		i+=2;
+		for (int p=0; p<numPairs; p++)
+			i = skipElementValue(bytes, i+2 /*skip name*/, typeName, cpg);
+		return i;
+	}
+
+	private static int skipElementValue(byte[] bytes, int i, String typeName, ConstantPoolGen cpg) {
+		short tag = bytes[i++];
+		switch (tag) {
+		case 'B': // byte
+		case 'C': // char
+		case 'D': // double
+		case 'F': // float
+		case 'I': // int
+		case 'J': // long
+		case 'S': // short
+		case 'Z': // boolean
+		case 's': // String
+		case 'c': // Class
+			i+=2; break;
+		case 'e': // Enum constant
+			i+=4; break;
+		case '@': // Annotation
+			String[] typeName2 = new String[1];
+			i = ObjectTeamsTransformation.scanStrings(typeName2, bytes, i, cpg); // nested annotation type			
+			i = skipNameValuePairs(bytes, i, typeName2[0], cpg);
+			break;
+		case '[': // Array
+			int numArrayVals = ObjectTeamsTransformation.combineTwoBytes(bytes, i);
+			i+=2;
+			for (int j = 0; j < numArrayVals; j++)
+				i = skipElementValue(bytes, i, typeName, cpg);
+			break;
+		default:
+			throw new RuntimeException("Unexpected element value kind in annotation: " + typeName);
+		}
+		return i;
+	}
+
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java
new file mode 100644
index 0000000..4d72e02
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java
@@ -0,0 +1,80 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: AttributeReadingGuard.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Christine Hundt
+ * @author Stephan Herrmann
+ */
+public class AttributeReadingGuard {
+	
+	private static Map<ClassLoader, AttributeReadingGuard> instances = new HashMap<ClassLoader, AttributeReadingGuard>();
+    private static AttributeReadingGuard defaultInstance = new AttributeReadingGuard();
+    
+    private ArrayList<String> servedClasses = new ArrayList<String>();
+    
+    // this one flag is really global (concerns the one main class of the application):
+    private static boolean firstLoaded = true;
+
+    /**
+     * @param className
+     * @return
+     */
+    public boolean iAmTheFirst(String className) {
+        return !this.servedClasses.contains(className);    
+    }
+    
+    /**
+     * Processing the given class is done.
+     * @param className
+     */
+    public void workDone(String className) {
+    	this.servedClasses.add(className);    
+    }
+    
+    /**
+     * @return whether this class is the first being loaded => possibly the main class.
+     */
+    public static synchronized boolean isFirstLoadedClass() {
+    	if (!firstLoaded)
+    		return false;
+    	firstLoaded = false;
+    	return true;
+    }
+
+    /** First loaded class has no main => it was a false alarm. */
+	public static void reset() {
+		firstLoaded = true;
+	}
+
+	/**
+	 * Since actual data are stored in an instance, static methods need to retrieve the appropriate
+     * instance regarding the given class loader.
+	 */
+	public static AttributeReadingGuard getInstanceForLoader(ClassLoader loader) {
+		if (loader == null)
+			return defaultInstance;
+		
+		AttributeReadingGuard instance = instances.get(loader);
+		if (instance == null)
+			instances.put(loader, instance = new AttributeReadingGuard());
+		return instance;
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundClass.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundClass.java
new file mode 100644
index 0000000..1746be5
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundClass.java
@@ -0,0 +1,80 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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$
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+import java.util.HashSet;
+
+import de.fub.bytecode.generic.ObjectType;
+
+/**
+ * @version $Id: BoundClass.java,v 1.8 2006-12-19 21:31:30 stephan Exp $ 
+ * @author Christine Hundt
+ */
+public class BoundClass {
+	private String name;
+	
+	private BoundClass _super;
+	//private BoundClass _tsuper;
+	private HashSet<String> adaptingTeams = new HashSet<String>(); 
+
+	public BoundClass(String className, String teamName) {
+		name = className;
+		this.adaptingTeams.add(teamName);
+		_super = null;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public boolean isAdaptedByTeam(String teamName) {
+		return this.adaptingTeams.contains(teamName);
+	}
+	
+	public void addAdaptingTeam(String teamName) {
+		this.adaptingTeams.add(teamName);
+	}
+
+	public void setSuper(BoundClass superClass) {
+		_super = superClass;
+	}
+	
+	public BoundClass getSuper() {
+		return _super;
+	}
+	
+	public boolean isSubClassOf(String anotherClass) {
+		BoundClass superClass = _super;
+		while (superClass!=null) {
+			if (superClass.getName().equals(anotherClass)) {
+				return true;
+			}
+			superClass = superClass.getSuper();
+		}
+		return false;
+	}
+
+	public void updateSuper(BoundClass newSuperBaseClass, ObjectType newSuperBaseType) {
+		// FIXME(SH): implement ;-)		
+		// test if newSuperBaseType is above or below _super.
+		// also check if tsupers (i.e., more than one super) must be treated as well.
+	}
+	
+//	public String toString() {
+//		return name;
+//	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundMethod.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundMethod.java
new file mode 100644
index 0000000..4a4a8fb
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/BoundMethod.java
@@ -0,0 +1,48 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: BoundMethod.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+/**
+ * @author Christine Hundt
+ * @version $Id: BoundMethod.java 23408 2010-02-03 18:07:35Z stephan $
+ */
+public class BoundMethod {
+	private String name;
+	private String signature;
+	private boolean isCallin;
+	
+//	private MethodBinding binding;
+	
+	public BoundMethod(String methodName, String methodSignature, boolean isCallin, MethodBinding methodBinding) {
+		name = methodName;
+		signature = methodSignature;
+		this.isCallin = isCallin;
+//		binding = methodBinding;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public String getSignature() {
+		return signature;
+	}
+	
+	public boolean getIsCallin() {
+		return this.isCallin;
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/CallinBindingManager.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/CallinBindingManager.java
new file mode 100644
index 0000000..ba2330a
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/CallinBindingManager.java
@@ -0,0 +1,1429 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: CallinBindingManager.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+//import de.fub.bytecode.generic.Type; // just for javadoc.
+import de.fub.bytecode.Repository;
+import de.fub.bytecode.classfile.JavaClass;
+import de.fub.bytecode.generic.ObjectType;
+
+import org.eclipse.objectteams.otre.OTREInternalError;
+import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
+import org.eclipse.objectteams.otre.ObjectTeamsTransformation.BaseMethodInfo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * @version $Id: CallinBindingManager.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author Christine Hundt
+ */
+@SuppressWarnings("nls")
+public class CallinBindingManager {
+	// map of bindings for role classes: roleClassName -> RoleBaseBinding
+	private static HashMap<String, RoleBaseBinding> roleBindings = new HashMap<String, RoleBaseBinding>(); 
+	
+	// map of bindings for base classes: baseClassName -> List[RoleBaseBinding]
+	private static ListValueHashMap<RoleBaseBinding> baseBindings = new ListValueHashMap<RoleBaseBinding>();
+	
+	// maps a team to its handled bases: teamClassName -> List[BaseClassName]
+	private static ListValueHashMap<String> basesPerTeam = new ListValueHashMap<String>();
+	
+	//	maps a team to its contained roles: teamClassName -> List[RoleClassName]
+	private static ListValueHashMap<String> rolesPerTeam = new ListValueHashMap<String>();
+	
+	// store sets of bases indexed by a team name, 
+	// where the team adapts (decapsulates) the given bases without a direct playedBy relation
+	private static HashMap<String, HashSet<String>> extraReferencedBases = new HashMap<String, HashSet<String>>();
+
+	/**
+	 * Add super-link of the BoundRole object for the RoleBaseBinding of 'className' to 'superClassName'.
+	 * @param className				the name of the class for which to add the super-link
+	 * @param superClassName	the name of the super class to be linked
+	 */
+	public static void addSuperRoleLink(String className, String superClassName) {
+		if (!roleBindings.containsKey(superClassName))
+			return; // no super role class stored!
+		RoleBaseBinding rbbSuper = roleBindings.get(superClassName);
+		RoleBaseBinding rbb = roleBindings.get(className);
+		// establish link from the role to its super role class:
+		rbb.getRoleClass().setSuper(rbbSuper.getRoleClass());
+	}
+	
+	/**
+	 * @param baseClassName
+     */
+	private static void addSuperBaseLink(String teamClassName, String baseClassName, RoleBaseBinding rbb) 
+	{
+		BoundClass baseClass = rbb.getBaseClass();
+		ObjectType baseClassType = new ObjectType(baseClassName);
+		if (!checkLookup(baseClassType.getClassName())) // TODO: workaround for classes loaded from special locations
+			return;
+		// clone the set for re-entrance:
+		Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it = getBaseBindingsCloneIterator();
+		while (it.hasNext()) {
+			Entry<String, LinkedList<RoleBaseBinding>> entry = it.next();
+			String currentBaseClassName = entry.getKey();
+			if (currentBaseClassName.equals(baseClassName)) continue;
+			ObjectType currentType = new ObjectType(currentBaseClassName);
+			if (!checkLookup(currentType.getClassName())) // TODO: workaround for classes loaded from special locations
+				continue;
+			// BoundClass objects are unique per base object, so just take the first binding: 
+			BoundClass currentBaseClass = entry.getValue().getFirst().getBaseClass();
+			if(baseClassType.subclassOf(currentType)) {
+				BoundClass rbbSuper = baseClass.getSuper();
+				if (rbbSuper != null)  {
+					if (rbbSuper.getName().equals(currentBaseClassName))
+						continue; // no need for action: already set.
+					baseClass.updateSuper(currentBaseClass, currentType);
+				}
+				baseClass.setSuper(currentBaseClass);
+			}
+			else if (currentType.subclassOf(baseClassType)) {
+				BoundClass currentSuper = currentBaseClass.getSuper();
+				// if sub base classes may be registered before super base class, 
+				// this case has to be considered too:
+				if (currentSuper != null) {
+					if (currentSuper.getName().equals(baseClassName))
+						continue; // no need for action: already set.
+					currentBaseClass.updateSuper(baseClass, baseClassType);
+				}
+				currentBaseClass.setSuper(baseClass);
+			}
+		}
+	}
+
+    /**
+     * Declare role playedBy base.
+	 *
+     * @param roleClassName		the name of the played role class
+     * @param baseClassName		the name of the playing base class
+     */
+    public static void addRoleBaseBinding(String roleClassName, String baseClassName, String teamClassName) {
+		RoleBaseBinding rbb = roleBindings.get(roleClassName);
+		if (rbb == null) {
+			rbb = new RoleBaseBinding(roleClassName, baseClassName, teamClassName);
+			roleBindings.put(roleClassName, rbb);
+		}
+		addSuperBaseLink(teamClassName, baseClassName, rbb);
+		synchronized (baseBindings) {
+			baseBindings.put(baseClassName, rbb);
+		}
+		addTeamRoleRelation(teamClassName, roleClassName);
+  	}
+
+    /**
+     * @param teamClassName
+     * @param baseClassName
+     */
+    public static void addTeamBaseRelation(String teamClassName, String baseClassName) {
+    	JavaClass baseClass = Repository.lookupClass(baseClassName);
+    	if (checkLookup(baseClassName) && baseClass.isInterface()) { // TODO: workaround for classes loaded from special locations
+    		// TODO (SH): need to register with all implementing classes!
+            if (logging) {
+                ObjectTeamsTransformation.printLogMessage("*** Skipping base " + baseClassName + ": is an interface");
+    			ObjectTeamsTransformation.printLogMessage("Classses implementing the interface " + baseClassName + " have to be transformed!");
+    		}
+    		addBoundBaseInterface(baseClassName);
+    	} else {
+    		List<String> bases = basesPerTeam.get(teamClassName);
+    		if (bases==null || !bases.contains(baseClassName))
+    			basesPerTeam.put(teamClassName, baseClassName);
+    	}
+    }
+    
+    /**
+     * @param teamClassName
+     * @return
+     */
+    public static List<String> getBasesPerTeam(String teamClassName) {
+        // (PH): return empty list instead of null when team has no bases?
+    	return basesPerTeam.get(teamClassName);
+    }
+    
+    /**
+     * @param teamClassName
+     * @param roleClassName
+     */
+    public static void addTeamRoleRelation(String teamClassName, String roleClassName) {
+        	List<String> roles = rolesPerTeam.get(teamClassName);
+    		if (roles == null || !roles.contains(roleClassName))
+    			rolesPerTeam.put(teamClassName, roleClassName);
+    }
+    
+    /**
+     * @param teamClassName
+     * @return
+     */
+    public static List<String> getRolePerTeam(String teamClassName) {
+    	return rolesPerTeam.get(teamClassName);
+    }
+
+    private static LinkedList<String> allRoles = new LinkedList<String>();
+    
+    /**
+     * @param roleName
+     */
+    public static void addRole(String roleName) {
+    	allRoles.add(roleName);
+    }
+    
+    /**
+     * @param roleName
+     * @return
+     */
+    public static boolean isRole(String roleName) {
+    	return allRoles.contains(roleName);
+    }
+    
+    public static void addExtraReferencedBase(String teamName, String baseName) {
+    	HashSet<String> bases = extraReferencedBases.get(teamName);
+    	if (bases == null) {
+    		bases = new HashSet<String>();
+    		extraReferencedBases.put(teamName, bases);
+    	}
+    	bases.add(baseName);
+    }
+    
+    /**
+     * Get all bases adapted by a team without a direct playedBy relation.
+     * @param teamName
+     * @return non-null Set (may be empty).
+     */
+    public static Set<String> getExtraReferencedBases(String teamName) {
+    	Set<String> bases = extraReferencedBases.get(teamName);
+    	if (bases != null)
+    		return bases;
+    	return new HashSet<String>();
+    }
+    
+	/**
+     * Declare binding of a pair of methods.
+	 * @param roleClassName
+	 * @param bindingFileName TODO
+	 * @param bindingLineNumber TODO
+	 * @param bindingLineOffset TODO
+	 * @param roleMethodName
+	 * @param roleMethodSignature signature ready for interpretation by
+     *                      {@link Type de.fub.bytecode.generic.Type}
+	 * @param isStaticRoleMethod TODO
+	 * @param modifier "before", "after" or "replace"
+	 * @param baseMethodName
+	 * @param baseMethodSignature
+	 * @param isStaticBaseMethod is the base method static?
+	 * @param baseIsCallin is the base method a callin method?
+	 * @param translationFlags one bit for the result and for each argument indicating whether lifting/lowering is needed
+	 * @param liftMethodName
+	 * @param liftMethodSignature
+     */
+    public static void addMethodBinding(
+	        String roleClassName, String baseClassName, 
+	        String bindingFileName, int bindingLineNumber, int bindingLineOffset,
+            String bindingLabel, String roleMethodName, String roleMethodSignature, boolean isStaticRoleMethod, 
+			String wrapperName, String wrapperSignature, String modifier, 
+			String baseMethodName, String baseMethodSignature, 
+			boolean isStaticBaseMethod,	boolean baseIsCallin, boolean covariantBaseReturn, 
+			int translationFlags, String liftMethodName, String liftMethodSignature)
+	{
+		RoleBaseBinding rbb = roleBindings.get(roleClassName);
+		if (rbb == null) {
+			// no binding found, create it now:
+			if (baseClassName == null)
+				throw new OTREInternalError("PlayedBy attribute must be read before method bindings.");
+			int lastDollar = roleClassName.lastIndexOf('$');
+			String teamClassName = roleClassName.substring(0, lastDollar);
+			rbb = new RoleBaseBinding(roleClassName, baseClassName, teamClassName);
+			roleBindings.put(roleClassName, rbb);
+		}
+		//System.err.println(rbb.getRoleClass().getName()+"<-*->"+rbb.getBaseClass().getName());
+		rbb.addMethodBinding(bindingFileName, bindingLineNumber, bindingLineOffset, 
+											 bindingLabel, roleMethodName, roleMethodSignature, isStaticRoleMethod,
+			                                 wrapperName, wrapperSignature, modifier,
+			                                 baseMethodName, baseMethodSignature, 
+			                                 isStaticBaseMethod, baseIsCallin, covariantBaseReturn,
+			                                 translationFlags,
+			                                 liftMethodName, liftMethodSignature);
+  	
+		if (modifier.equals("replace"))
+			assignBaseCallTag(rbb.getBaseClassName(), baseMethodName, baseMethodSignature);
+	}
+
+    /**
+     * Get all callin bindings for a given base method.
+     * @param className the base class
+     * @param methodName the base method
+     * @return Collection of <pre>MethodBinding</pre>
+     */
+    public static Collection<MethodBinding> getBindingForBaseMethod(String baseClassName, String baseMethodName, String baseMethodSignature)
+	{
+		LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
+		LinkedList<MethodBinding> resultList = new LinkedList<MethodBinding>();
+		if (rbbList != null) {
+			Iterator<RoleBaseBinding> it = rbbList.iterator();
+			while (it.hasNext()) {
+				RoleBaseBinding rbb = it.next();
+				List<MethodBinding> mbs = rbb.getBaseMethodBindings(baseMethodName, baseMethodSignature);
+				if (mbs != null)
+					addFiltered(resultList, mbs, baseMethodName, baseMethodSignature);
+			}
+		}
+		// IMPLICIT_INHERITANCE
+		addFiltered(resultList, 
+					getImplicitlyInheritedBaseMethodBindings(baseClassName, baseMethodName, baseMethodSignature),
+					baseMethodName,
+					baseMethodSignature);
+		if (resultList.isEmpty())
+			return null;
+		return resultList;
+    }
+    /** variant of the above, optimized for computing only a boolean result instead of a complete list. */
+    public static boolean isBoundBaseMethod(String baseClassName, String baseMethodName, String baseMethodSignature)
+	{
+		LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
+		if (rbbList != null) {
+			for (RoleBaseBinding rbb : rbbList) {
+				List<MethodBinding> mbs = rbb.getBaseMethodBindings(baseMethodName, baseMethodSignature);
+				if (mbs != null)
+					for (MethodBinding mb : mbs)
+						if (mb.matchesMethod(baseMethodName, baseMethodSignature, /* strict */ true))
+								return true;
+			}
+		}
+		// IMPLICIT_INHERITANCE
+		for (MethodBinding mb : getImplicitlyInheritedBaseMethodBindings(baseClassName, baseMethodName, baseMethodSignature))
+			if (mb.matchesMethod(baseMethodName, baseMethodSignature, /* strict */ true))
+					return true;
+		return false;
+    }
+    // add bindings from candidates to resultList, perhaps checking
+    // full signatures (i.e., if not covariantBaseReturn).
+    private static void addFiltered(Collection<MethodBinding> resultList, 
+    								Collection<MethodBinding> candidates,
+    								String name,
+    							    String fullSignature) 
+    {
+   		for (MethodBinding methodBinding : candidates) 
+			if (methodBinding.matchesMethod(name, fullSignature, /*strict*/false)) 
+				resultList.add(methodBinding);			
+    }
+    
+    /**
+     * Gets all implicitly inherited method bindings for the given base method.
+     * Note: the result can only contain elements for base classes which are
+     * roles at the same time! 
+     * @param baseClassName			the name of the base class
+     * @param baseMethodName		the name of the base mehtod
+     * @param baseMethodSignature	the descriptor or the base method signature
+     * @return a Collection with all implicitly inherited method bindings
+     */
+    private static Collection<MethodBinding> getImplicitlyInheritedBaseMethodBindings(String baseClassName, String baseMethodName, String baseMethodSignature) { 
+    	List<MethodBinding> resultList = new LinkedList<MethodBinding>();
+    	
+    	if (!isRole(baseClassName))
+    		return resultList; // only roles can have implicit super types
+		
+		Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it = getBaseBindingsCloneIterator();
+
+		while (it.hasNext()) {
+			Entry<String, LinkedList<RoleBaseBinding>> entry = it.next();
+			String have = entry.getKey();
+			// look for true superClass (not same):
+			if (have.equals(baseClassName)) 
+				continue;
+			if (isImplicitSubtype(baseClassName, have)) {
+				// now we have an implicit superClass:
+				if (logging)
+                    ObjectTeamsTransformation.printLogMessage(baseClassName
+                            + " implicitly inherits callin bindings from " + have);
+                // collect the signatures of all bound base methods:
+   				List<RoleBaseBinding> rbbList = entry.getValue();
+				if (rbbList != null) {
+					Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
+					while (rbb_it.hasNext()) {
+						RoleBaseBinding rbb = rbb_it.next();
+						List<MethodBinding> mbs = rbb.getBaseMethodBindings(baseMethodName, baseMethodSignature);
+						if (mbs != null)
+							resultList.addAll(mbs);
+					}
+				}
+			}
+		}
+		//if (!resultList.isEmpty())
+		//	System.err.println(resultList);
+		return resultList;
+    }
+
+	/**
+	 * Get all callin bindings that a given base class may inherit from its superclass.
+	 * @param className
+	 * @result list of MethodBinding
+	 */
+	public static Collection<MethodBinding> getInheritedCallinBindings (String className) {
+/*
+		List classBindings = baseBindings.get(className);
+	if (classBindings!=null) {
+		// any RoleBaseBinding contains the corresponding BoundClass object for the super base:
+		RoleBaseBinding anyRBB = (RoleBaseBinding)classBindings.get(0);
+		// problem: if a sub base class is not explicitly bound to a role class no corresponding 
+		//                BoundClass object exists. How can we access the super bindings via the 
+		//                super-link??
+		BoundClass bc = anyRBB.getBaseClass();
+		//System.out.println("-----------");
+		while (bc.getSuper()!=null) {
+			System.out.println(bc.getName());
+			bc = bc.getSuper();
+	}
+		//System.out.println("-----------");
+		}
+*/		
+
+		List<MethodBinding> result = new LinkedList<MethodBinding>();
+		ObjectType current = new ObjectType(className);
+		if (!checkLookup(current.getClassName())) // TODO: workaround for classes loaded from special locations
+			return result; 
+		// clone for re-entrance:
+		Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it= getBaseBindingsCloneIterator();
+		while (it.hasNext()) {
+			Entry<String, LinkedList<RoleBaseBinding>> entry = it.next();
+			String have = entry.getKey();
+			// look for true superClass (not same):
+			if (have.equals(className)) continue;
+			ObjectType haveType = new ObjectType(have);
+			//System.err.println(current + " : "+haveType);
+			//System.err.println(de.fub.bytecode.Repository.lookupClass(have));
+			if (!checkLookup(haveType.getClassName())) // TODO: workaround for classes loaded from special locations
+					continue;
+			if (current.subclassOf(haveType)) {
+				// now we have a true superClass:
+				if (logging)
+                    ObjectTeamsTransformation.printLogMessage(className
+                            + " inherits callin bindings from " + have);
+                // collect the signatures of all bound base methods:
+   				List<RoleBaseBinding> rbbList = entry.getValue();
+				if (rbbList != null) {
+					Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
+					while (rbb_it.hasNext()) {
+						RoleBaseBinding rbb = rbb_it.next();
+						result.addAll(rbb.getBaseMethodBindings());
+					}
+				}
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * Get all super classes defining callin bindings that a given static base
+	 * method may inherit.
+	 * 
+	 * @author juerwid
+	 * @param className
+	 * @param methodName
+	 * @param methodSignaturte
+	 * @result list of <String[] {class_name}>
+	 */
+	public static Collection<String> getInheritedCallinBindingsForStaticMethods(
+			String className, String methodName, String methodSignature)
+	{
+		List<String> result = new LinkedList<String>();
+		ObjectType current = new ObjectType(className);
+		if (!checkLookup(current.getClassName())) // TODO: workaround for classes loaded from special locations
+			return result; 
+		// clone for re-entrance:
+		Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it = getBaseBindingsCloneIterator();
+		boolean getNextClass = false;
+		while (it.hasNext()) {
+			Entry<String,LinkedList<RoleBaseBinding>> entry = it.next();			
+			String have = entry.getKey();
+			// look for true superClass (not same):
+			if (have.equals(className)) continue;
+			ObjectType haveType = new ObjectType(have);
+			if (!checkLookup(haveType.getClassName())) // TODO: workaround for classes loaded from special locations
+					continue;
+			if (current.subclassOf(haveType)) {
+				// now we have a true superClass:
+				if (logging)
+					ObjectTeamsTransformation.printLogMessage(className
+							+ " inherits callin bindings from " + have);
+                // collect the signatures of all bound base methods:
+   				LinkedList<RoleBaseBinding> rbbList = entry.getValue();
+				if (rbbList != null) {
+					Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
+					while (rbb_it.hasNext() && !getNextClass) {
+						RoleBaseBinding rbb = rbb_it.next();
+						List<String[]> methods = rbb.getBaseSignatures();
+						Iterator<String[]> methodsIter = methods.iterator();
+						while(methodsIter.hasNext() && !getNextClass){
+							String[] aMethod = methodsIter.next();
+							if(methodName.equals(aMethod[0]) && methodSignature.equals(aMethod[1])){
+								result.add(have);
+								getNextClass = true;
+							}
+						}
+					}
+					if(getNextClass){
+						getNextClass = false;
+						continue;
+					}
+				}
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * Checks if 'subType' is an implicit subtype of 'superType'.
+	 * To be true the role name parts have to be equal and the 
+	 * team name parts have to be in a 'real' subtype relationship.
+	 *
+	 * @param subType	the name of the potential subtype.
+	 * @param superType	the name of the potential supertype.
+	 * @return	true, if subType implicitly inherits from superType.
+	 */
+	private static boolean isImplicitSubtype(String subType, String superType) {
+		//System.err.println(subType +" -?-> " + superType);
+		int dollarIdxSub = subType.lastIndexOf('$');
+		int dollarIdxSuper = superType.lastIndexOf('$');
+		if (dollarIdxSub==-1 || dollarIdxSuper==-1)
+			return false; // no roles
+		String pureSubType = subType.substring(dollarIdxSub+1, subType.length());
+		String pureSuperType = superType.substring(dollarIdxSuper+1, superType.length());
+		if (!pureSubType.equals(pureSuperType))
+			return false;// no identical role names
+		
+		String subTeamName = subType.substring(0, dollarIdxSub);
+		String superTeamName = superType.substring(0,dollarIdxSuper);
+
+		if (!(checkLookup(subTeamName) && checkLookup(superTeamName)))
+				return false; // Repository can not lookup types
+		ObjectType subTeamType = new ObjectType(subTeamName);
+		ObjectType superTeamType = new ObjectType(superTeamName);
+		if (subTeamType.subclassOf(superTeamType)) {
+            if (logging)
+                ObjectTeamsTransformation.printLogMessage(subType
+                        + " implicitly inherits method bindings from " + superType);
+			//System.err.println(subType + " implicitly inherits method bindings from " + superType);
+			return true;
+		}
+		return false; // no inheritance relation between teams
+	}
+	
+	/**
+	 * Check to avoid NullPointerExceptions caused by the Repository when classes can not be looked up (because they loaded by
+	 * classloaders with special a classpath)
+	 *
+	 * @param current	The name of the class to look up in the Repository.
+	 * @return False, if the class can not be found, true else.
+	 */
+	private static boolean checkLookup(String className) {
+		if (Repository.lookupClass(className) == null) {
+			if (OTEQUINOX_WARN)
+				System.err.println("Warning: Repository could not lookup class " + className + "!");
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Get all inherited method bindings for a given base method, which are 
+	 * bindings declared for a super base class.
+	 *
+	 * the actual base class has additional bindings for this method!  
+	 * @param baseClassName			the name of the role class
+	 * @param baseMethodName		the name of the role method
+	 * @param baseMethodSignature	the signature of the role method
+	 * @result a List containing all inherited bindings for the role method
+	 */
+	public static List<MethodBinding> getInheritedBaseMethodBindings(String baseClassName, String baseMethodName, String baseMethodSignature) {
+
+		List<MethodBinding> inheritedMethodBindings = new LinkedList<MethodBinding>();
+		if (!isBoundBaseClass(baseClassName)) {
+			return inheritedMethodBindings;
+		}
+		LinkedList<RoleBaseBinding> baseBindingsForBase = baseBindings.get(baseClassName);
+		if (baseBindingsForBase == null) 
+			return inheritedMethodBindings;
+		
+		Iterator<RoleBaseBinding> it = baseBindingsForBase.iterator();
+		while (it.hasNext()) {
+			RoleBaseBinding rbb = it.next(); 
+			BoundClass bc = rbb.getBaseClass();
+			while (bc.getSuper() != null) {
+				bc = bc.getSuper();
+				String superRoleName = bc.getName();
+				Collection<MethodBinding> superRoleMethodBindings = CallinBindingManager.getBindingForBaseMethod(
+																				   		 superRoleName, 
+																						 baseMethodName, 
+																						 baseMethodSignature);
+				if (superRoleMethodBindings!=null)
+					inheritedMethodBindings.addAll(superRoleMethodBindings);
+			}
+		}
+		return inheritedMethodBindings;
+	}
+
+	/**
+	 * Get all inherited method bindings for a given role method, which are
+	 * bindings declared in a super role class. The actual role class has
+	 * additional bindings for this method!
+	 * 
+	 * @param roleClassName			the name of the role class
+	 * @param roleMethodName		the name of the role method
+	 * @param roleMethodSignature	the signature of the role method
+	 * @result a List containing all inherited bindings for the role method
+	 */
+	public static List<MethodBinding> getInheritedRoleMethodBindings(String roleClassName, String roleMethodName, String roleMethodSignature) {
+		List<MethodBinding> inheritedMethodBindings = new LinkedList<MethodBinding>();
+		if (!isBoundRoleClass(roleClassName)) {
+			return inheritedMethodBindings;
+		}
+		RoleBaseBinding rbb = roleBindings.get(roleClassName);
+		BoundClass bc = rbb.getRoleClass();
+		while (bc.getSuper() != null) {
+			bc = bc.getSuper();
+			String superRoleName = bc.getName();
+			List<MethodBinding> superRoleMethodBindings = CallinBindingManager.getBindingsForRoleMethod(
+																		superRoleName, 
+																		roleMethodName, 
+																		roleMethodSignature);
+			inheritedMethodBindings.addAll(superRoleMethodBindings);
+		}
+		return inheritedMethodBindings;
+	}
+
+	/**
+	 * All bindings for a given role method concerning its base class.
+	 * 
+	 * @return List of MethodBinding
+	 */
+	public static List<MethodBinding> getBindingsForRoleMethod(String roleClassName,
+			String roleMethodName, String roleMethodSignature)
+	{
+		RoleBaseBinding rbb = roleBindings.get(roleClassName);
+		if (rbb==null) {
+			return new LinkedList<MethodBinding>();
+		}
+		List<MethodBinding> roleMethodBindings = rbb.getRoleMethodBindings(roleMethodName, roleMethodSignature);
+		if (roleMethodBindings == null) {
+			return new LinkedList<MethodBinding>();
+		}
+		return roleMethodBindings;
+	}
+
+	/**
+	 * @param className
+	 * @return
+	 */
+	public static boolean isBoundBaseClass(String className) {
+		// and has at least one method binding?
+		boolean result = baseBindings.containsKey(className);
+		if (result || !isRole(className)) {
+			return result;
+		}
+		else {// bound implicit super class?
+			Iterator<String> it = getBaseBindingsKeyIterator();
+			while (it.hasNext()) {
+				String have = it.next();
+				// look for true superClass (not same):
+				if (have.equals(className)) 
+					continue;
+				if (isImplicitSubtype(className, have))
+					return true;
+			}
+			return result;
+		}
+	}
+	
+	/**
+	 * @param className
+	 * @return
+	 */
+	public static boolean isBoundBaseAndRoleClass(String className) {
+		// and has at least one method binding?
+		if (baseBindings.containsKey(className)) 
+			return true;
+		// bound implicit super class?
+		Iterator<String> it = getBaseBindingsKeyIterator();
+		while (it.hasNext()) {
+			String have = it.next();
+			// look for true superClass (not same):
+			if (have.equals(className)) 
+				continue;
+			if (isImplicitSubtype(className, have))
+				return true;
+		}
+		return false;
+	}
+	
+	/**
+	 * @param baseClassName
+	 * @return
+	 */
+	public static boolean hasBoundBaseParent(String baseClassName) {
+		LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
+		if (rbbList != null) {
+			Iterator<RoleBaseBinding> it = rbbList.iterator();
+			while (it.hasNext()) {
+				RoleBaseBinding rbb = it.next();
+				if (rbb.getBaseClass().getSuper()!=null)
+					return true;
+			}
+		}
+		// IMPLICIT_INHERITANCE
+		//if (isUnboundSubBase(baseClassName))
+		//	return true;
+		return false;
+	}
+	
+	
+	/**
+	 * Returns the name of the topmost bound base class.
+	 * 
+	 * @param baseClassName
+	 * @return
+	 */
+	public static String getTopmostBoundBase(String baseClassName) {
+		LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
+		if (rbbList != null) {
+			// assumption: EVERY BoundClass object has been connected to its bound super classes.
+			RoleBaseBinding anyRBB = rbbList.get(0);
+			BoundClass bc = anyRBB.getBaseClass();
+			while (bc.getSuper() != null) {
+	            bc = bc.getSuper();
+	        }
+			return bc.getName();
+		}
+		return baseClassName;
+	}
+	
+	/**
+	 * @param baseClassName
+	 * @return
+	 */
+	public static String getBoundBaseParent(String baseClassName) {
+		LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
+		if (rbbList != null) {
+			Iterator<RoleBaseBinding> it = rbbList.iterator();
+			while (it.hasNext()) {
+				RoleBaseBinding rbb = it.next();
+				BoundClass bc = rbb.getBaseClass().getSuper();
+				if (bc!=null)
+					return bc.getName();
+			}
+		}
+		// IMPLICIT_INHERITANCE
+		//if (isUnboundSubBase(baseClassName))
+		//	return true;
+		return null;
+	}
+	
+	/**
+	 * @param teamClassName
+	 * @param baseClassName
+	 * @return
+	 */
+	public static boolean teamAdaptsSuperBase(String teamClassName, String baseClassName) {
+		LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
+		if (rbbList != null && !rbbList.isEmpty()) {
+			RoleBaseBinding rbb = rbbList.getFirst(); // all entries refer to the same base class.
+			BoundClass bc = rbb.getBaseClass().getSuper();
+			while (bc!=null) {
+				if (bc.isAdaptedByTeam(teamClassName))
+					return true;
+				bc = bc.getSuper();
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * @param baseClassName
+	 * @return
+	 */
+//	private static boolean isUnboundSubBase(String baseClassName) {
+//		ObjectType current = new ObjectType(baseClassName);
+//		if (!checkLookup(current.getClassName())) // TODO: workaround for classes loaded from special locations
+//			return false; 
+//		Iterator /* String */ it = baseBindings.keySet().iterator();
+//		while (it.hasNext()) {
+//			String have = (String)it.next();
+//			// look for true superClass (not same):
+//			if (have.equals(baseClassName)) continue;
+//			ObjectType haveType = new ObjectType(have);
+//			//System.err.println(current + " : "+haveType);
+//			//System.err.println(de.fub.bytecode.Repository.lookupClass(have));
+//			if (!checkLookup(haveType.getClassName())) // TODO: workaround for classes loaded from special locations
+//					continue;
+//			if (current.subclassOf(haveType)) {
+//				return true;
+//			}
+//		}
+//		return false;
+//	}
+
+	/**
+	 * @param className
+	 * @return
+	 */
+	public static boolean isBoundRoleClass(String className) {
+		return roleBindings.containsKey(className);
+	}
+
+	/**
+	 * @param className
+	 * @return
+	 */
+	public static RoleBaseBinding getRoleBaseBinding(String roleClassName) {
+		return roleBindings.get(roleClassName);
+	}
+	
+	/**
+	 * @param roleClassName
+	 * @return
+	 */
+	public static List<MethodBinding> getMethodBindingsForRoleClass(String roleClassName)
+	{
+		RoleBaseBinding rbb = roleBindings.get(roleClassName);
+		return rbb.getRoleMethodBindings();
+	}
+	
+	/**
+	 * @param roleClassName
+	 * @return
+	 */
+	public static Set<String> getBoundRoleMethods(String roleClassName) {
+		Set<String> roleMethodKeySet = new HashSet<String>();
+		if (roleBindings.get(roleClassName) != null) {
+			RoleBaseBinding rbb = roleBindings.get(roleClassName);
+			roleMethodKeySet = rbb.getRoleMethodSignatures();
+		}
+		return roleMethodKeySet;
+	}
+	
+	/**
+	 * @param baseClassName
+	 * @return
+	 */
+	public static List<MethodBinding> getMethodBindingsForBaseClass(String baseClassName) 
+	{
+		LinkedList<RoleBaseBinding> rbbList = baseBindings.get(baseClassName);
+		LinkedList<MethodBinding> resultList = new LinkedList<MethodBinding>();
+		if (rbbList != null) {
+			Iterator<RoleBaseBinding> it = rbbList.iterator();
+			while (it.hasNext()) {
+				RoleBaseBinding rbb = it.next();
+				resultList.addAll(rbb.getRoleMethodBindings());
+			}
+		 }
+		 return resultList;
+	}
+	
+    // --------------------------------------------------
+    //     discriminate base methods by tag per callin
+    //  --------------------------------------------------
+    // baseClass.baseMeth.baseMethodSignature -> tag
+    private static HashMap<String, Integer> baseCallTags = new HashMap<String, Integer>();
+    // -- follow access methods for baseCallTags:
+	
+    /**
+     * @param baseClass
+     * @param baseMeth
+     * @param baseMethodSignature
+     */
+    public static void assignBaseCallTag (String baseClass, String baseMeth, 
+    														   String baseMethodSignature) 
+    {
+		// every base method bound by a replace callin gets an unique tag:	
+		String key = baseClass+"."+baseMeth+"."+baseMethodSignature;
+		int tag = baseCallTags.size();
+		if (!baseCallTags.containsKey(key))
+			baseCallTags.put(key, Integer.valueOf(tag));
+	}
+
+    public static int getBaseCallTag (String base_class_name, 
+    								  String base_method_name, 
+    								  String base_method_signature) {
+        String key = base_class_name + "." + base_method_name
+		+ "." + base_method_signature;
+		return baseCallTags.get(key).intValue();
+    }
+
+    // ----------------------------------------------
+    //      Map argument positions:
+    // ----------------------------------------------
+    // teamName -> callinWrapperName -> int[]
+	private static HashMap<String, HashMap<String, int[]>> paramMappings = new HashMap<String, HashMap<String, int[]>>();
+    // -- follow access methods for paramMappings:
+
+	/**
+	 * @param teamName
+	 * @param methodWrapper
+	 * @param positions
+	 */
+	public static void addParameterBinding (String teamName,
+											String methodWrapper,
+											int[] positions) {
+		HashMap<String, int[]> teamMap = paramMappings.get(teamName);
+		if (teamMap == null) {
+			teamMap = new HashMap<String, int[]>();
+			paramMappings.put(teamName, teamMap);
+		}
+		teamMap.put(methodWrapper, positions);
+	}
+
+	public static boolean hasParamMappings (String teamName, String methodWrapper)
+	{
+		HashMap<String,int[]> teamMap = paramMappings.get(teamName);
+		if (teamMap == null) return false;
+		return teamMap.containsKey(methodWrapper);
+	}
+
+	/** Get parameter positions for the given team or any super team. */
+	public static int[] getParamPositions (String teamName, String methodWrapper)
+	{
+		int[] positions = getExactParamPositions(teamName, methodWrapper);
+		if (positions != null)
+			return positions;
+		// inherit parameter mappings from super teams: -- >> 
+		Iterator<String> superTeams = getSuperTeamsWithParamMappigs(teamName).iterator();
+		while (superTeams.hasNext()) {
+			positions = getExactParamPositions(superTeams.next(), methodWrapper);
+			if (positions != null) // found (the!) parameter mapping
+				return positions;
+		}
+		return null;
+	}
+	/** Get parameter positions for exactly the given team (no super teams). */
+	private static int[] getExactParamPositions(String teamName, String methodWrapper) {
+		HashMap<String,int[]>teamMap = paramMappings.get(teamName);
+		if (teamMap == null)
+			return null;
+		return teamMap.get(methodWrapper);
+	}
+	
+	private static List<String> getSuperTeamsWithParamMappigs(String teamName) {
+		LinkedList<String> result = new LinkedList<String>();
+		if (!checkLookup(teamName)) // TODO: workaround for classes loaded from special locations
+			return result;
+		for (JavaClass superTeam : Repository.getSuperClasses(teamName))
+			if (paramMappings.get(superTeam.getClassName()) != null)
+				result.add(superTeam.getClassName());
+		return result;
+	}
+	
+
+    // -----------------------------------------------
+    //   tags for teams per base class:
+    // -----------------------------------------------
+    // baseName -> HashMap  (teamName -> tag (Integer))
+    private static HashMap<String, HashMap<String, Integer>> baseTags = new HashMap<String, HashMap<String, Integer>>();
+
+    /**
+     * @param teamName
+     * @param baseToTag
+     */
+    public static void addBaseTags (String teamName, HashMap<String, Integer> baseToTag) {
+	    Iterator<Entry<String, Integer>> iter = baseToTag.entrySet().iterator();
+	    while (iter.hasNext()) {
+	    	Entry<String,Integer> entry = iter.next();
+	        String baseName = entry.getKey();
+	        Integer tag = entry.getValue();
+	        HashMap<String, Integer> thisBaseTags = baseTags.get(baseName);
+	        if (thisBaseTags == null) {
+    		    thisBaseTags = new HashMap<String, Integer>();
+    		    baseTags.put(baseName, thisBaseTags);
+	        }
+	        thisBaseTags.put(teamName, tag);
+	    }
+    }
+
+    /**
+     *  Get all tags of teams which have callins for a given base class.
+     * @param baseClassName base class name.
+     * @return HashMap: team name -> tag (Integer)
+     */
+    public static HashMap<String, Integer> getBaseTags (String baseClassName) {
+    	HashMap<String, Integer> baseClassTags = baseTags.get(baseClassName);
+    	if (baseClassTags == null)
+    		return new HashMap<String, Integer>();
+    	return baseTags.get(baseClassName); 
+    }
+    
+    /**
+     * Get all tags of teams which have callins for implicit super types
+     * of the given base class. 
+     * Note: this is only possible if the base class is a role at the same time! 
+     * @param baseClassName	base class name.
+     * @return HashMap: team name -> tag (Integer)
+     */
+    public static HashMap<String, Integer> getInheritedBaseTags(String baseClassName) {
+    	HashMap<String, Integer> result = new HashMap<String, Integer>();
+    	// clone for re-entrance:
+    	Iterator<String> it = getBaseBindingsKeyIterator();
+		while (it.hasNext()) {
+			String have = it.next();
+			// look for true superClass (not same):
+			if (have.equals(baseClassName)) 
+				continue;
+			if (isImplicitSubtype(baseClassName, have))
+				result.putAll(getBaseTags(have));
+		}
+		return result;
+    }
+
+	// -----------------------------------------------
+	//   callout bindings that require adjustment:
+	// -----------------------------------------------
+	// baseClass -> HashSet (method_name+signature)
+	private static HashMap<String, HashSet<String>> calloutBindings = new HashMap<String, HashSet<String>>();
+
+	/**
+	 * @param clazz
+	 * @param meth
+	 * @param sign
+	 */
+	public static void addCalloutBinding(String clazz, String meth, String sign) {
+		HashSet<String> bindings = calloutBindings.get(clazz);
+		if (bindings == null) {
+			bindings = new HashSet<String>();
+			calloutBindings.put(clazz, bindings);
+		}
+		bindings.add(meth + sign);
+	}
+
+	/**
+	 * @param clazz
+	 * @return
+	 */
+	public static HashSet<String> getCalloutBindings (String clazz) {
+		return calloutBindings.get(clazz);
+	}
+	
+	/**
+	 * @param bindings
+	 * @param method_name
+	 * @param signature
+	 * @return
+	 */
+	public static boolean requiresCalloutAdjustment(HashSet<String> bindings,
+											 		String method_name,
+											 		String signature)
+	{
+		return bindings.contains(method_name+signature);
+	}
+	
+	//	 -----------------------------------------------
+	//   callouts to base class fields are stored here for furher reading and get/set method generation:
+	// -----------------------------------------------
+	private static ListValueHashMap<FieldDescriptor> calloutSetFields = new ListValueHashMap<FieldDescriptor>();
+	private static ListValueHashMap<FieldDescriptor> calloutGetFields = new ListValueHashMap<FieldDescriptor>();
+
+ 
+	/**
+	 * @param roleClassName
+	 * @param fieldName
+	 * @param fieldSignature
+	 * @param accessMode
+	 * @param isStaticField
+	 */
+	public static void addCalloutBoundFileds(String baseClassName, String fieldName, 
+			String fieldSignature, String accessMode, boolean isStaticField) 
+	{
+		FieldDescriptor fd = new FieldDescriptor(fieldName, fieldSignature, isStaticField);
+
+		if (accessMode.equals("get")) {
+			calloutGetFields.put(baseClassName, fd);
+		} else if (accessMode.equals("set")) {
+			calloutSetFields.put(baseClassName, fd);
+		} else {
+			throw new OTREInternalError("CalloutFieldAccess attribute contains wrong access mode: "+accessMode);
+		}
+	}
+	
+	/**
+	 * @param baseClassName
+	 * @return
+	 */
+	public static List<FieldDescriptor> getCalloutGetFields(String baseClassName) {
+		return calloutGetFields.get(baseClassName);
+	}
+	
+	/**
+	 * @param baseClassName
+	 * @return
+	 */
+	public static List<FieldDescriptor> getCalloutSetFields(String baseClassName) {
+		return calloutSetFields.get(baseClassName);
+	}
+
+	// -----------------------------------------------
+	// base calls to super methods via special accessor
+	// -----------------------------------------------
+	private static ListValueHashMap<SuperMethodDescriptor> superMethods = new ListValueHashMap<SuperMethodDescriptor>();
+
+	public static void addSuperAccess(String baseClassName, String superClassName, String methodName, String signature) {
+		SuperMethodDescriptor superMethod = new SuperMethodDescriptor(methodName, baseClassName, superClassName, signature);
+		superMethods.put(baseClassName, superMethod);
+	}
+	public static List<SuperMethodDescriptor> getSuperAccesses(String class_name) {
+		return superMethods.get(class_name);
+	}
+
+	//	 -----------------------------------------------
+	//   bound interfaces have to be registered, for implementing classes to inherit callin bindings:
+	// -----------------------------------------------
+	private static List<String> boundBaseInterfaces = new LinkedList<String>();
+
+	/**
+	 * @param baseInterfaceName	The name of the bound base interface.
+	 */
+	public static void addBoundBaseInterface(String baseInterfaceName) {
+		if (!boundBaseInterfaces.contains(baseInterfaceName))
+			boundBaseInterfaces.add(baseInterfaceName);
+	}
+
+	/**
+	 * @param interfaceName
+	 * @return
+	 */
+	public static Collection<String[]> getInterfaceInheritedCallinBindings(String interfaceName) {
+		List<String[]> result = new LinkedList<String[]>();
+		//System.err.println(interfaceName);
+		//System.err.println(boundBaseInterfaces);
+		if (boundBaseInterfaces.contains(interfaceName)) {
+            if (logging)
+                ObjectTeamsTransformation.printLogMessage(interfaceName
+                        + " bequests callin bindings to implementing class");
+              // collect the signatures of all bound base methods:
+ 				LinkedList<RoleBaseBinding> rbbList = baseBindings.get(interfaceName);
+				if (rbbList != null) {
+					Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
+					while (rbb_it.hasNext()) {
+						RoleBaseBinding rbb = rbb_it.next();
+						result.addAll(rbb.getBaseSignatures());
+
+						// System.err.println("inheriting binding: "+rbb);
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * @param methodName
+	 * @param methodSignature
+	 * @param interfaceName
+	 * @return
+	 */
+	public static Collection<MethodBinding> getInterfaceInheritedMethodBindings(
+			String methodName, String methodSignature, String interfaceName) {
+		List<MethodBinding> result = new LinkedList<MethodBinding>();
+		if (boundBaseInterfaces.contains(interfaceName)) {
+			LinkedList<RoleBaseBinding> rbbList = baseBindings.get(interfaceName);
+			if (rbbList != null) {
+				Iterator<RoleBaseBinding> rbb_it = rbbList.iterator();
+				while (rbb_it.hasNext()) {
+					RoleBaseBinding rbb = rbb_it.next();
+					List<MethodBinding> mbs = rbb.getBaseMethodBindings(methodName, methodSignature);
+					if (mbs != null)
+						result.addAll(mbs);
+				}
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * @param interfaceNames
+	 * @return
+	 */
+	public static boolean containsBoundBaseInterface(String[] interfaceNames) {
+		for (int i = 0; i < interfaceNames.length; i++) {
+			if (boundBaseInterfaces.contains(interfaceNames[i]))
+				return true;
+		}
+		return false;
+	}
+	
+	//	 -----------------------------------------------
+	//   precedence can be set for a list of method bindings:
+	// -----------------------------------------------
+	
+	private static ListValueHashMap<List<String>> precedencePerTeam = new ListValueHashMap<List<String>>();
+	
+	/**
+	 * Add a precedence list for the given team.
+	 * @param precedenceList	the list of binding labels defining their precedence
+	 * @param teamName 		the name of the team for which the precedence list was defined
+	 */
+	public static void addPrecedenceList(List<String> precedenceList, String teamName) {
+		precedencePerTeam.put(teamName, precedenceList);
+	}
+	
+	/**
+	 * Sorts the method binding list according to the given precedence for the team
+	 * @param mbList			the list of 'MethodBinding's to be sorted
+	 * @param teamName	the name of the corresponding team
+	 * @return	the sorted 'MethodBindig' list
+	 */
+	public static List<MethodBinding> sortMethodBindings(List<MethodBinding> mbList, String teamName) {
+		if (mbList.size() < 2)
+			return mbList; // nothing to sort
+		String outermostTeamName;
+		int dollarIdx = teamName.indexOf('$');
+		if (dollarIdx > 0)
+			outermostTeamName = teamName.substring(0, dollarIdx);
+		else outermostTeamName = teamName;
+		
+		List<List<String>> precedenceList = precedencePerTeam.get(outermostTeamName);
+		if (precedenceList==null) {
+			// mbList has to be reduced by removing overridden bindings:
+			return removeOverridden(mbList);
+		}
+		
+		LinkedList<MethodBinding> sortedMethodBindings = new LinkedList<MethodBinding>();
+		Iterator<List<String>> predIt = precedenceList.iterator();
+		
+		while (predIt.hasNext()) {
+			List<String> plainList = predIt.next();
+			Iterator<String> plainIt = plainList.iterator();
+			
+			while (plainIt.hasNext()) {
+				boolean foundOne = false;
+				String label = plainIt.next();
+				Iterator<MethodBinding> mbIter = mbList.iterator();
+				List<MethodBinding> alreadySorted = new LinkedList<MethodBinding>();
+				
+				while (mbIter.hasNext()) {
+					MethodBinding mb = mbIter.next();
+					
+					if (mb.getQualifiedBindingLabel().equals(label)) { // mb exactly fits binding label:
+						alreadySorted.add(mb);
+						if (!foundOne) {
+							sortedMethodBindings.add(mb);
+							foundOne = true;
+						} else checkInheritance(sortedMethodBindings.getLast(), mb); 
+					
+					} else if (mb.inheritsBindingLabel(label, teamName)) { // mb inherits  binding label:
+						alreadySorted.add(mb);
+						if (!foundOne) {
+							sortedMethodBindings.add(mb);
+							foundOne = true;
+						} else {// maybe it is a subtype of the already added?
+							MethodBinding lastAdded = sortedMethodBindings.getLast();
+							if (mb.overridesMethodBinding(lastAdded)) {
+								sortedMethodBindings.set(sortedMethodBindings.size()-1, mb);
+								foundOne = true;
+							} else checkInheritance(sortedMethodBindings.getLast(), mb);
+						}
+					}
+				}
+				if (foundOne) {
+					Iterator<MethodBinding> sortedIter = alreadySorted.iterator();
+					while (sortedIter.hasNext()) {
+						MethodBinding mb = sortedIter.next();
+						mbList.remove(mb);
+					}
+				}
+			}
+		}
+//		if (mbList.size() > 0) {
+//			System.err.println("ERROR: Unsortable method bindings: " + mbList +"!");
+//			 // assumption: all remaining method bindings are overridden! TODO: check assumption!
+//		}
+		return sortedMethodBindings;
+	}
+
+	/**
+	 * Removes overridden method bindings from the given list. Assumes that 
+	 * all bindings in the list are in a sub/super type relationship.
+	 * @param mbList		the method binding list
+	 * @return		the most specific method binding overriding all others
+	 */
+	private static List<MethodBinding> removeOverridden(List<MethodBinding> mbList) {
+		MethodBinding mostSpecificMB = mbList.get(0);
+		Iterator<MethodBinding> mbIter = mbList.iterator();
+		while (mbIter.hasNext()) {
+			MethodBinding mb = mbIter.next();
+			if (mb.overridesMethodBinding(mostSpecificMB)) {
+				mostSpecificMB = mb;
+			} else checkInheritance(mostSpecificMB, mb);
+		}
+		List<MethodBinding> resultList = new LinkedList<MethodBinding>();
+		resultList.add(mostSpecificMB);
+		return resultList;
+	}
+		
+	/**
+	 * Checks if 'subMB' 'inherits' from 'superMB'. Used to check if assumptions 
+	 * about the precedence lists are fulfilled.
+	 *
+	 * @param subMB		the overriding method binding
+	 * @param superMB	the overridden method binding
+	 */
+	private static void checkInheritance(MethodBinding subMB, MethodBinding superMB) {
+		if (! (subMB.equals(superMB) || subMB.overridesMethodBinding(superMB))) {
+			//System.err.println("sub: " + subMB + "\n super: " + superMB);
+			throw new OTREInternalError("Wrong assumption! Broken precedence list possible.");
+		}
+	}
+    
+    // ------------------------------------------
+    // ---------- Logging: ----------------------
+    // ------------------------------------------
+    /** Initialized from property <tt>ot.log</tt>. */
+    static boolean logging = false;
+    /** Initialized from property <tt>otequinox.debug</tt> */
+    static boolean OTEQUINOX_WARN = false;
+    static {
+        if(System.getProperty("ot.log") != null)
+            logging = true;
+        String warnlevel = System.getProperty("otequinox.debug");
+        if (warnlevel != null) {
+        	warnlevel = warnlevel.toUpperCase();
+        	if (warnlevel.startsWith("INFO") || warnlevel.equals("OK"))
+        		OTEQUINOX_WARN = true;
+        }
+    }
+    
+	//	 -----------------------------------------------
+	//   static replace callin bindings have to be stored in the team, special treatment:
+	// -----------------------------------------------
+    	
+	// maps an implemented role method to its base methods: roleMethod -> List[baseMethod] // added by JU
+	private static ListValueHashMap<BaseMethodInfo> staticReplaceBindings = new ListValueHashMap<BaseMethodInfo>();
+	
+	/**
+	 * Adds a base method to its implemented role method (static replace bindings).
+	 * 
+	 * @param roleMethodKey a string structured according team_class_ name.role_class_name.role_method_name.role_method_signature
+	 * @param baseMethodInfo an Object contained base class name, base method name and base method signature
+	 */
+	public static void addStaticReplaceBindingForRoleMethod(String roleMethodKey, BaseMethodInfo baseMethodInfo) {
+		staticReplaceBindings.put(roleMethodKey, baseMethodInfo);
+	}
+	
+	/**
+	 * Returns static method bindings for the given role method
+	 * @param roleMethodKey
+	 * @return
+	 */
+	public static LinkedList<BaseMethodInfo> getStaticReplaceBindingsForRoleMethod(String roleMethodKey) {
+		return staticReplaceBindings.get(roleMethodKey);
+	}
+
+	/**
+	 * @param roleClassName
+	 * @param roleMethodName
+	 * @param roleMethodSignature
+	 * @return
+	 */
+	public static boolean roleMethodHasBinding(String roleClassName, String roleMethodName, String roleMethodSignature) {
+		RoleBaseBinding rbb = roleBindings.get(roleClassName);
+		if (rbb == null) {
+			return false;
+		}
+		return rbb.hasRoleMethodBinding(roleMethodName, roleMethodSignature);
+	}
+	
+	// -----------------------------------------------
+	//  access modifiers of some base classes have to be changed to 'public' (decapsulation)
+	//  the names of these classes are stored in baseClassesForModifierChange 
+	// -----------------------------------------------
+	private static LinkedList<String> baseClassesForModifierChange = new LinkedList<String>();
+	
+	/**
+	 * Adds the given class name to the list of class names intended for decapsulation 
+	 * @param className
+	 */
+	public static void addBaseClassForModifierChange(String className){
+		baseClassesForModifierChange.add(className);
+	}
+	
+	/**
+	 * Checks whether a class name is contained in the list of classes intended for decapsulation
+	 * @param className
+	 * @return
+	 */
+	public static boolean checkBaseClassModifierChange(String className) {
+		Iterator<String> iter = baseClassesForModifierChange.iterator();
+		while(iter.hasNext()) {
+			if(className.equals(iter.next())){
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public static void addBoundSuperclassLink(String sub_name, String super_name) {
+		synchronized (baseBindings) {
+			bases:
+			for (RoleBaseBinding subBinding : baseBindings.getFlattenValues()) {
+				if (subBinding.getBaseClassName().equals(sub_name)) {
+					for (RoleBaseBinding superBinding : baseBindings.getFlattenValues()) {
+						if (subBinding == superBinding) continue;
+						if (superBinding.getBaseClassName().equals(super_name)) {
+							subBinding.getBaseClass().setSuper(superBinding.getBaseClass());
+							break bases;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/** Either retrieve an existing BoundClass for `className' are create a new one. 
+     *  If an existing one is used it is updated for the new adapting team.
+     */
+	public static BoundClass getBoundBaseClass(String className, String teamClassName) {
+		for (RoleBaseBinding subBinding : baseBindings.getFlattenValues()) {
+			if (subBinding.getBaseClassName().equals(className)) { 
+				BoundClass baseClass = subBinding.getBaseClass();
+				baseClass.addAdaptingTeam(teamClassName);
+				return baseClass;
+			}
+		}
+		return new BoundClass(className, teamClassName);
+	}
+
+	// ==== HELPERS FOR RE-ENTRANCE SAFETY: ====
+
+	private static Iterator<String> getBaseBindingsKeyIterator() {
+		synchronized (baseBindings) {
+			ArrayList<String> list = new ArrayList<String>();
+	    	list.addAll(baseBindings.keySet());
+	    	Iterator<String> it = list.iterator();
+			return it;
+		}
+	}
+
+	private static Iterator<Entry<String, LinkedList<RoleBaseBinding>>> getBaseBindingsCloneIterator() {
+		synchronized (baseBindings) {
+			ArrayList<Entry<String, LinkedList<RoleBaseBinding>>> list = new ArrayList<Entry<String,LinkedList<RoleBaseBinding>>>();
+			list.addAll(baseBindings.entrySet());
+			Iterator<Entry<String, LinkedList<RoleBaseBinding>>> it = list.iterator();
+			return it;
+		}
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/DebugUtil.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/DebugUtil.java
new file mode 100644
index 0000000..7282185
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/DebugUtil.java
@@ -0,0 +1,155 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2003-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: DebugUtil.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+import de.fub.bytecode.generic.*;
+import de.fub.bytecode.Constants;
+import java.util.Enumeration;
+
+import org.eclipse.objectteams.otre.OTConstants;
+
+/**
+ * @author Stephan Herrmann
+ */
+@SuppressWarnings("nls")
+public class DebugUtil {
+
+	// -----------------------------------------
+	// -------- Development utilities  ---------
+	// -----------------------------------------
+
+    /**
+    *  Creates an the instructions necessary to "System.out.println" 
+	*  the given string.
+    *
+    *  @param cpg     the constant pool of the class where this instructions 
+	*                 will be inserted
+    *  @param string  the String to be printed
+    *  @return        an InstructionList containing the necessary instructions
+    */
+	public static InstructionList createPrintln(ConstantPoolGen cpg, 
+												InstructionFactory factory,
+												String string) 
+	{
+        InstructionList il  = new InstructionList();
+        ObjectType p_stream = new ObjectType("java.io.PrintStream");
+
+        il.append(factory.createFieldAccess("java.lang.System", "out", 
+											p_stream,
+											Constants.GETSTATIC));
+        il.append(new PUSH(cpg, string + "\n"));
+        il.append(factory.createInvoke("java.io.PrintStream", "print", 
+									   Type.VOID, 
+									   new Type[] { Type.STRING }, 
+									   Constants.INVOKEVIRTUAL));
+        return il;
+    }
+
+	/**
+	 * Create a <tt>System.out.println</tt> call for an <tt>Object</tt>
+	 * argument. The argument is assumed to be on the stack and will not
+	 * be consumed.
+	 */
+    public static InstructionList createPrintlnObj(InstructionFactory factory) {
+        InstructionList il  = new InstructionList();
+        ObjectType p_stream = new ObjectType("java.io.PrintStream");
+
+		il.append(new DUP());
+        il.append(factory.createFieldAccess("java.lang.System", "out", 
+											p_stream,
+											Constants.GETSTATIC));
+		il.append(new SWAP());
+        il.append(factory.createInvoke("java.io.PrintStream", "print", 
+									   Type.VOID, 
+									   new Type[] { OTConstants.object }, 
+									   Constants.INVOKEVIRTUAL));
+        return il;
+    }
+
+	/**
+	 * Create a <tt>System.out.println</tt> call for an <tt>Exception</tt>
+	 * argument. The argument is assumed to be on the stack and _will_
+	 * be consumed. This effect is however only performed, if 
+	 * the property ot.log.lift is set.
+	 */
+    public static InstructionList createReportExc(InstructionFactory factory) {
+        InstructionList il  = new InstructionList();
+		if (System.getProperty("ot.log.lift") == null) {
+			il.append(new POP());
+		} else {
+			ObjectType p_stream = new ObjectType("java.io.PrintStream");
+			
+			il.append(factory.createFieldAccess("java.lang.System", "out", 
+												p_stream,
+												Constants.GETSTATIC));
+			il.append(new SWAP());
+			il.append(factory.createInvoke("java.io.PrintStream", "println", 
+										   Type.VOID, 
+										   new Type[] { OTConstants.object }, 
+										   Constants.INVOKEVIRTUAL));
+		}
+        return il;
+    }
+
+	/**
+	 * Create a <tt>System.out.println</tt> call for an <tt>int</tt>
+	 * argument. The argument is assumed to be on the stack and will not
+	 * be consumed.
+	 */
+    public static InstructionList createPrintlnInt(InstructionFactory factory) {
+        InstructionList il  = new InstructionList();
+        ObjectType p_stream = new ObjectType("java.io.PrintStream");
+
+		il.append(new DUP());
+        il.append(factory.createFieldAccess("java.lang.System", "out", 
+											p_stream,
+											Constants.GETSTATIC));
+		il.append(new SWAP());
+        il.append(factory.createInvoke("java.io.PrintStream", "print", 
+									   Type.VOID, 
+									   new Type[] { Type.INT }, 
+									   Constants.INVOKEVIRTUAL));
+        return il;
+    }
+    
+    public static InstructionList createPrintlnBool(ConstantPoolGen cp) {
+    	InstructionList il= new InstructionList();
+    	int             out     = cp.addFieldref("java.lang.System", "out",
+    											 "Ljava/io/PrintStream;");
+    	int             println = cp.addMethodref("java.io.PrintStream", "println",
+    											  "(Z)V");
+    	il.append(new DUP());
+    	il.append(new GETSTATIC(out));
+    	il.append(new SWAP());
+    	il.append(new INVOKEVIRTUAL(println));
+    	return il;
+    }
+
+    @SuppressWarnings("unchecked")
+	public static void printIL (InstructionList il, ConstantPoolGen cpg) {
+        int off = 0;
+        Enumeration en =  il.elements();
+        while(en.hasMoreElements()) {
+            Instruction i = ((InstructionHandle)en.nextElement()).getInstruction();
+            off += i.produceStack(cpg);
+            off -= i.consumeStack(cpg);
+            System.out.print(off);
+            System.out.println("  = "+i);
+        }
+    }
+
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/FieldDescriptor.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/FieldDescriptor.java
new file mode 100644
index 0000000..30a3dd0
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/FieldDescriptor.java
@@ -0,0 +1,53 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: FieldDescriptor.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+/**
+ * @author resix
+ */
+public class FieldDescriptor {
+	private String fieldName;
+	private String fieldSignature;
+	private boolean isStaticField;
+
+	public FieldDescriptor(String name, String signature, boolean is_static) {
+		fieldName = name;
+		fieldSignature = signature;
+		isStaticField = is_static;
+	}
+	
+	/**
+	 * @return Returns the fieldName.
+	 */
+	public String getFieldName() {
+		return fieldName;
+	}
+	
+	/**
+	 * @return Returns the fieldSignature.
+	 */
+	public String getFieldSignature() {
+		return fieldSignature;
+	}
+	
+	/**
+	 * @return Returns the isStaticField.
+	 */
+	public boolean isStaticField() {
+		return isStaticField;
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/ListValueHashMap.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/ListValueHashMap.java
new file mode 100644
index 0000000..665ee5f
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/ListValueHashMap.java
@@ -0,0 +1,103 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: ListValueHashMap.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * @author resix
+ */
+public class ListValueHashMap<ValueType> {
+	private HashMap<String, LinkedList<ValueType>> hashMap = new HashMap<String, LinkedList<ValueType>>();
+	//redundant structure for faster access:
+	private LinkedList<ValueType> flattenValues = new  LinkedList<ValueType>();
+
+	/**
+	 * @param key
+	 * @param value
+	 */
+	public void put(String key, ValueType value) {
+		LinkedList<ValueType> list;
+		if (!hashMap.containsKey(key)) {
+			list = new LinkedList<ValueType>();
+		} else {
+			list = hashMap.get(key);
+		}
+		list.add(value);
+		hashMap.put(key, list);
+		flattenValues.add(value);
+	}
+
+	/**
+	 * @return
+	 */
+	public List<ValueType> getFlattenValues() {
+		return flattenValues;
+	}
+	
+	/**
+	 * @param key
+	 * @return
+	 */
+	public LinkedList<ValueType> get(String key) {
+		if (!hashMap.containsKey(key))  {
+			return null;
+		}
+		return hashMap.get(key);
+	}
+	
+	public boolean containsKey(Object o) {
+		return hashMap.containsKey(o);	
+	}
+
+	public Set<String> keySet() {
+		return hashMap.keySet();
+	}
+
+	public Set<Entry<String, LinkedList<ValueType>>>  entrySet() {
+		return hashMap.entrySet();
+	}
+	
+	public int size() {
+		return hashMap.size();
+	}
+	
+	public String toString() {
+		StringBuilder result = new StringBuilder(32);
+		Iterator it = hashMap.entrySet().iterator();
+		while (it.hasNext()) {
+			Entry entry = (Entry) it.next();
+			result.append(entry.getKey());
+            result.append(": ");
+            result.append(entry.getValue().toString());
+            result.append("\n");
+		}
+		if (result.length() == 0)
+			return super.toString();
+		return result.toString();
+	}
+
+	public Collection<LinkedList<ValueType>> valueSet() {
+		return hashMap.values();
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/MethodBinding.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/MethodBinding.java
new file mode 100644
index 0000000..ecc5436
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/MethodBinding.java
@@ -0,0 +1,395 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: MethodBinding.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+import org.eclipse.objectteams.otre.OTConstants;
+
+/**
+ * @version $Id: MethodBinding.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author Christine Hundt
+ */
+public class MethodBinding {
+
+	private String bindingFileName;
+	private int bindingLineNumber;
+	private int bindingLineOffset;
+	
+	private String bindingLabel;
+	
+	private BoundMethod baseMethod;
+	private BoundMethod roleMethod;
+
+	private boolean isStaticBaseMethod;
+	private boolean isStaticRoleMethod;
+	private boolean covariantBaseReturn;
+	
+	private int translationFlags;
+	
+   	private String wrapperName;
+	private String wrapperSignature;
+
+   	private String modifier;
+   	private String liftMethodName;
+   	private String liftMethodSignature;
+    
+    private String roleClassName;
+    
+    // back reference for the class binding containing this method binding.
+    private RoleBaseBinding classBinding;
+
+    /**
+     * 
+     */
+    public MethodBinding() {}
+
+    /**
+     * @param bindingFileName
+     * @param bindingLineNumber
+     * @param bindingLineOffest
+     * @param bindingLabel
+     * @param roleMethodName
+     * @param roleMethodSignature
+     * @param isStaticRoleMethod
+     * @param wrapperName
+     * @param wrapperSignature
+     * @param modifier
+     * @param baseMethodName
+     * @param baseMethodSignature
+     * @param isStaticBaseMethod
+     * @param baseIsCallin
+     * @param liftMethodName
+     * @param liftMethodSignature
+     * @param classBinding
+     */
+    public MethodBinding(
+            String bindingFileName, int bindingLineNumber, int bindingLineOffest,
+			String bindingLabel, String roleMethodName, String roleMethodSignature, boolean isStaticRoleMethod, 
+			String wrapperName, String wrapperSignature, String modifier, 
+			String baseMethodName, String baseMethodSignature, 
+			boolean isStaticBaseMethod,	boolean baseIsCallin, boolean covariantBaseReturn, 
+			int translationFlags, 
+			String liftMethodName, String liftMethodSignature, RoleBaseBinding classBinding) 
+	{
+    	this.bindingFileName = bindingFileName;
+    	this.bindingLineNumber = bindingLineNumber;
+    	this.bindingLineOffset = bindingLineOffest;
+    	
+    	this.bindingLabel = bindingLabel;
+		roleMethod = new BoundMethod(roleMethodName, roleMethodSignature, false, this);
+		baseMethod = new BoundMethod(baseMethodName, baseMethodSignature, baseIsCallin, this);
+		// BoundMethod object for one method is not unique!
+		// but if it would be unique the 'binding' link would not be unique
+		this.isStaticRoleMethod  = isStaticRoleMethod;
+		this.isStaticBaseMethod  = isStaticBaseMethod;
+		this.covariantBaseReturn = covariantBaseReturn;
+		this.translationFlags    = translationFlags;
+        this.wrapperName         = wrapperName;
+        this.wrapperSignature    = wrapperSignature;
+        this.modifier            = modifier;
+        this.liftMethodName      = liftMethodName;
+        this.liftMethodSignature = liftMethodSignature;
+        this.classBinding        = classBinding;
+        this.roleClassName       = classBinding.getRoleClassName();
+    }
+
+    /**
+     * @return
+     */
+    public String getRoleClassName() {
+		return roleClassName;
+    }
+
+    /**
+     * @return
+     */
+    public String getBindingFileName() {
+		return bindingFileName;
+	}
+	
+	/**
+	 * @return
+	 */
+	public int getBindingLineNumber() {
+		return bindingLineNumber;
+	}
+	
+	/**
+	 * @return
+	 */
+	public int getBindingLineOffset() {
+		return bindingLineOffset;
+	}
+    
+    /**
+     * @return
+     */
+    public String getBindingLabel() {
+    	return bindingLabel;
+    }
+    
+    /**
+     * @return
+     */
+    public String getQualifiedBindingLabel() {
+    	String result = roleClassName;
+    	// remove the outermost team (use the '$' to distinguish pack1.Team1$Role from Team1$__OT__Team2$Role):
+    	result = result.substring(result.indexOf('$') + 1);
+    	// replace "$" by "." in the role class name:
+    	result = result.replace('$', '.');
+    	// remove  "__OT__" prefixes in role class names:
+    	result = result.replace(OTConstants.OTDT_PREFIX, ""); //$NON-NLS-1$
+    	// add the binding label and return:    	
+    	return result + '.' + bindingLabel;
+    }
+    
+    /**
+     * @return
+     */
+    public String getRoleMethodName() {
+		return roleMethod.getName();
+    }
+    
+    /**
+     * @return
+     */
+    public String getRoleMethodSignature() {
+		return roleMethod.getSignature();
+    }
+	
+	/**
+	 * @return
+	 */
+	public String getWrapperName() {
+		return wrapperName;
+	}
+	
+	/**
+	 * @return
+	 */
+	public String getWrapperSignature() {
+		return wrapperSignature;
+	}
+
+    /**
+     * @return
+     */
+    public String getBaseClassName() {
+		return classBinding.getBaseClassName();
+    }
+
+    /**
+     * @return
+     */
+    public String getBaseMethodName() {
+		return baseMethod.getName();
+    }
+
+    /**
+     * @return
+     */
+    public String getBaseMethodSignature() {
+		return baseMethod.getSignature();
+    }
+
+    /**
+     * @return
+     */    
+    public boolean baseMethodIsCallin() {
+    	return baseMethod.getIsCallin();
+    }
+ 
+    /**
+     * @return
+     */    
+    public String getModifier() {
+        return modifier;
+    }
+	
+    /**
+     * @return
+     */
+    public boolean isReplace() {
+		return modifier.equals("replace");
+	}
+	
+	/**
+	 * @return
+	 */
+	public boolean isAfter() {
+		return modifier.equals("after");
+	}
+	
+	/**
+	 * @return
+	 */
+	public boolean isBefore() {
+		return modifier.equals("before");
+	}
+	
+	/**
+	 * @return Returns the liftMethodName.
+	 */
+	public String getLiftMethodName() {
+		return liftMethodName;
+	}
+	
+	/**
+	 * @return Returns the liftMethodSignature.
+	 */
+	public String getLiftMethodSignature() {
+		return liftMethodSignature;
+	}
+	
+	/**
+	 * @return Returns the corresponding class binding.
+	 */
+	public RoleBaseBinding getClassBinding() {
+		return classBinding;
+	}
+	
+	/**
+	 * Returns the most super bound base class of the base class belonging to
+	 * this MethodBinding. Note: only consider base classes bound by roles of
+	 * the corresponding team!
+	 * 
+	 * @return the most super bound base class
+	 */
+	public String getRootBoundBase() {
+		BoundClass bc = classBinding.getRoleClass();
+		while (bc.getSuper() != null && CallinBindingManager.isBoundRoleClass(bc.getSuper().getName()) ) {
+            bc = bc.getSuper();
+        }
+		RoleBaseBinding rbb = CallinBindingManager.getRoleBaseBinding(bc.getName());
+		return rbb.getBaseClassName();
+	}
+	
+	/**
+	 * Returns the name of the team surrounding the role class of this binding.
+	 * 
+	 * @return the name of the corresponding team
+	 */
+	public String getTeamClassName() {
+		int dollarIndex = roleClassName.lastIndexOf('$');
+		// return everything before the last '$', because for nested teams there are more than one:
+        return roleClassName.substring(0, dollarIndex);
+	}
+	
+	/**
+	 * @param anotherMB
+	 * @return
+	 */
+	public boolean overridesMethodBinding(MethodBinding anotherMB) {
+		if (anotherMB == null)
+			return false;
+		if (!bindingLabel.equals(anotherMB.getBindingLabel()))
+			return false;
+		return classBinding.getRoleClass().isSubClassOf(anotherMB.getClassBinding().getRoleClassName());
+	}
+	
+	/**
+	 * @param bindingLabel
+	 * @param teamName
+	 * @return
+	 */
+	public boolean inheritsBindingLabel(String bindingLabel, String teamName) {
+		String prefix = teamName + "$__OT__";
+		int dotIndex = bindingLabel.lastIndexOf('.');
+		String classOfLabel = prefix + bindingLabel.substring(0, dotIndex);
+		if (!bindingLabel.substring(dotIndex + 1).equals(this.bindingLabel))
+			return false;
+		
+		if (classBinding.getRoleClass().isSubClassOf(classOfLabel))
+			return true;
+		return false;
+	}
+
+    /**
+     * @param mb
+     * @return
+     */
+    public boolean equals(MethodBinding mb) {
+        return roleMethod.getName().equals(mb.getRoleMethodName())
+			&& roleMethod.getSignature().equals(mb.getRoleMethodSignature())
+			&& classBinding.getBaseClassName().equals(mb.getBaseClassName())
+			&& baseMethod.getName().equals(mb.getBaseMethodName())
+			&& baseMethod.getSignature().equals(mb.getBaseMethodSignature())
+			&& modifier.equals(mb.getModifier());
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        StringBuilder result = new StringBuilder(32);
+        result.append("\t");
+        result.append(getQualifiedBindingLabel());
+        result.append(": ");
+        result.append(roleMethod.getName());
+        result.append(roleMethod.getSignature());
+        result.append(" <-> ");
+        result.append(modifier);
+        result.append(" ");
+        result.append(baseMethod.getName());
+        result.append(baseMethod.getSignature());
+        if (this.covariantBaseReturn)
+        	result.append('+');
+        return result.toString();
+    }
+
+	/**
+	 * @return
+	 */
+	public boolean hasStaticRoleMethod() {
+		return isStaticRoleMethod;
+	}
+	
+    /**
+     * @return
+     */
+	public boolean hasStaticBaseMethod() {
+		return isStaticBaseMethod;
+	}
+
+	public int getTranslationFlags() {
+		return this.translationFlags;
+	}
+
+	/** For base methods provide a key without the trailing return type to cater for covariance. */ 
+	static String getBaseMethodKey(String baseMethodName, String baseMethodSignature) {
+		int pos= baseMethodSignature.lastIndexOf(')');
+		String baseMethodKey = baseMethodName + '.' + baseMethodSignature.substring(0, pos+1);
+		return baseMethodKey;
+	}
+
+	/** 
+	 * Is the method specified by mName and mSig a match for this method binding?
+	 * @param mName method name
+	 * @param mSig full method signature
+	 * @param strict if true covariance is not supported
+	 */
+	public boolean matchesMethod(String mName, String mSig, boolean strict) {
+		String baseMethodName = getBaseMethodName();
+		String baseMethodSignature = getBaseMethodSignature();
+		if (this.covariantBaseReturn && !strict) {
+			return getBaseMethodKey(mName, mSig).equals(
+				   getBaseMethodKey(baseMethodName, baseMethodSignature));
+		} else {
+			return mName.equals(baseMethodName) 
+				&& mSig.equals(baseMethodSignature);
+		}
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/RoleBaseBinding.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/RoleBaseBinding.java
new file mode 100644
index 0000000..172c0ae
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/RoleBaseBinding.java
@@ -0,0 +1,228 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: RoleBaseBinding.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @version $Id: RoleBaseBinding.java 23408 2010-02-03 18:07:35Z stephan $
+ * @author Christine Hundt
+ */
+public class RoleBaseBinding {
+
+	private BoundClass roleClass;
+	private BoundClass baseClass;
+
+	private ListValueHashMap<MethodBinding> roleMethodBindings = new ListValueHashMap<MethodBinding>();
+	private ListValueHashMap<MethodBinding> baseMethodBindings = new ListValueHashMap<MethodBinding>();
+	
+    /**
+     * 
+     */
+    public RoleBaseBinding() {
+    }
+
+    /**
+     * @param _roleClassName
+     * @param _baseClassName
+     * @param teamClassName
+     */
+    public RoleBaseBinding(String _roleClassName, String _baseClassName, String teamClassName) {
+    	roleClass = new BoundClass(_roleClassName, teamClassName);
+    	baseClass = CallinBindingManager.getBoundBaseClass(_baseClassName, teamClassName);
+    }
+
+    /**
+     * @param bindingFileName
+     * @param bindingLineNumber
+     * @param bindingLineOffset
+     * @param bindingLabel
+     * @param roleMethodName
+     * @param roleMethodSignature
+     * @param isStaticRoleMethod
+     * @param wrapperName
+     * @param wrapperSignature
+     * @param modifier
+     * @param baseMethodName
+     * @param baseMethodSignature
+     * @param isStaticBaseMethod
+     * @param baseIsCallin
+     * @param translationFlags
+     * @param liftMethodName
+     * @param liftMethodSignature
+     */
+    public void addMethodBinding(
+            String bindingFileName, int bindingLineNumber, int bindingLineOffset,
+			String bindingLabel, String roleMethodName, String roleMethodSignature,
+			boolean isStaticRoleMethod, String wrapperName, String wrapperSignature, String modifier, 
+			String baseMethodName, String baseMethodSignature, 
+			boolean isStaticBaseMethod, boolean baseIsCallin, boolean covariantBaseReturn,
+			int translationFlags, String liftMethodName, String liftMethodSignature)
+	{
+		MethodBinding mb = new MethodBinding(bindingFileName, bindingLineNumber, bindingLineOffset,
+																		   bindingLabel, roleMethodName, roleMethodSignature, isStaticRoleMethod,
+							   											   wrapperName, wrapperSignature, modifier,
+							   											   baseMethodName, baseMethodSignature, 
+							   											   isStaticBaseMethod, baseIsCallin, covariantBaseReturn, 
+							   											   translationFlags,
+																		   liftMethodName,
+							   											   liftMethodSignature, this);
+		// TODO: check, if the key has to include the 'binding_label'
+		String baseMethodKey = MethodBinding.getBaseMethodKey(baseMethodName, baseMethodSignature);
+		String roleMethodKey = roleMethodName + '.' + roleMethodSignature;
+		roleMethodBindings.put(roleMethodKey, mb);
+		baseMethodBindings.put(baseMethodKey, mb);
+    }
+
+	/**
+	 * @return
+	 */
+	public List<MethodBinding> getBaseMethodBindings() {
+		return baseMethodBindings.getFlattenValues();
+	}
+	
+	/**
+	 * @param baseMethodName
+	 * @param baseMethodSignature
+	 * @return
+	 */
+	public List<MethodBinding> getBaseMethodBindings(String baseMethodName, String baseMethodSignature) {
+		String baseMethodKey = MethodBinding.getBaseMethodKey(baseMethodName, baseMethodSignature);
+		return baseMethodBindings.get(baseMethodKey);
+	}
+
+	/**
+	 * @return
+	 */
+	public List<MethodBinding> getRoleMethodBindings() {
+		return roleMethodBindings.getFlattenValues();
+	}
+	
+	/**
+	 * @param roleMethodName
+	 * @param roleMethodSignature
+	 * @return
+	 */
+	public List<MethodBinding> getRoleMethodBindings(String roleMethodName, String roleMethodSignature) {
+		String roleMethodKey = roleMethodName + '.' + roleMethodSignature;
+		return roleMethodBindings.get(roleMethodKey);
+	}
+	
+	/**
+	 * @param roleMethodName
+	 * @param roleMethodSignature
+	 * @return
+	 */
+	public boolean hasRoleMethodBinding(String roleMethodName, String roleMethodSignature) {
+		String signatureWithoutReturnType = roleMethodSignature.substring(0, roleMethodSignature.lastIndexOf(')') + 1);
+		Set<String> bindingKeys = roleMethodBindings.keySet();
+		Iterator<String> it = bindingKeys.iterator();
+		while (it.hasNext()) {
+			String key = it.next();
+			String keyWithoutReturnType = key.substring(0, key.lastIndexOf(')') + 1);
+			if (keyWithoutReturnType.equals(roleMethodName + '.'
+					+ signatureWithoutReturnType))
+				return true;
+		}
+		return false;
+	}
+	
+	public Set<String> getRoleMethodSignatures() {
+		return roleMethodBindings.keySet();	
+	}
+	
+	/**
+	 * @return
+	 */
+	public BoundClass getRoleClass() {
+		return roleClass;
+	}
+	
+	/**
+	 * @return
+	 */
+	public BoundClass getBaseClass() {
+			return baseClass;
+		}
+	
+    /**
+     * @return
+     */
+    public String getRoleClassName() {
+		return roleClass.getName();
+	}
+
+	/**
+	 * @return
+	 */
+	public String getBaseClassName() {
+		return baseClass.getName();
+	}
+
+	/**
+	 * Collect all base method signatures for this role-base pair.
+	 * @result List <String[] {name, signature}>
+	 */
+	public List<String[]> getBaseSignatures () {
+		List<String[]> result = new LinkedList<String[]>();
+		List<MethodBinding> baseMethodBindingList = getBaseMethodBindings();
+		Iterator<MethodBinding> it = baseMethodBindingList.iterator();
+		while (it.hasNext()) {
+			MethodBinding mb = it.next();
+			result.add(new String [] {
+				mb.getBaseMethodName(),
+				mb.getBaseMethodSignature()
+			});
+		}
+        return result;
+	}
+
+    /**
+     * @param rbb
+     * @return
+     */
+    public boolean equals(RoleBaseBinding rbb) {
+        return roleClass.getName().equals(rbb.getRoleClassName())
+			&& baseClass.getName().equals(rbb.getBaseClassName());
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        StringBuilder out = new StringBuilder(64);
+        out.append(roleClass.getName());
+        out.append(" <-> ");
+        out.append(baseClass.getName());
+	    out.append("\nmethod bindings:\n");
+	    List mbsList = getBaseMethodBindings();
+	    Iterator it = mbsList.iterator();
+	    while (it.hasNext()) {
+			MethodBinding mb = (MethodBinding)it.next();
+			out.append("\n");
+            out.append(mb.getBaseMethodName());
+            out.append(".");
+            out.append(mb.getBaseMethodSignature());
+            out.append(":");
+            out.append(mb.toString());
+	    }
+        return out.toString();
+    }
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/SuperMethodDescriptor.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/SuperMethodDescriptor.java
new file mode 100644
index 0000000..02b9c04
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/SuperMethodDescriptor.java
@@ -0,0 +1,33 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2008 Technical University Berlin, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: SuperMethodDescriptor.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+
+/** Representation of a base-super method call, requiring a special access method. */
+public class SuperMethodDescriptor {
+	public String methodName;
+	public String declaringClass;
+	public String superClass;
+	public String signature;
+	public SuperMethodDescriptor(String methodName, String declaringClass,
+			String superClass, String signature) {
+		super();
+		this.methodName = methodName;
+		this.declaringClass = declaringClass;
+		this.superClass = superClass;
+		this.signature = signature;
+	}
+}
diff --git a/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/TeamIdDispenser.java b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/TeamIdDispenser.java
new file mode 100644
index 0000000..100a0a1
--- /dev/null
+++ b/othersrc/OTRE/src/org/eclipse/objectteams/otre/util/TeamIdDispenser.java
@@ -0,0 +1,69 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2002-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: TeamIdDispenser.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre.util;
+import java.util.*;
+
+public class TeamIdDispenser {
+
+	private static Map<ClassLoader, TeamIdDispenser> instances = new HashMap<ClassLoader, TeamIdDispenser>();
+    private static TeamIdDispenser defaultInstance = new TeamIdDispenser();
+    
+    static int lastDispensedId = 0;
+    private static HashMap<String, Integer> teamIDs = new HashMap<String, Integer>();
+
+//    @SuppressWarnings("unchecked")
+	private static int produceNextTeamId(String team_name) {
+        lastDispensedId++;
+        Integer teamId = Integer.valueOf(lastDispensedId);
+        teamIDs.put(team_name, teamId);
+        return lastDispensedId;
+    }
+
+    public static int getTeamId(String class_name) {
+        Integer teamId = teamIDs.get(class_name);
+        if (teamId != null)
+        	// the team <class_name> already has a team-id assigned
+        	return teamId.intValue();
+		else return produceNextTeamId(class_name);
+    }
+    
+    // Data shared among different transformers of the same class loader:
+    // REFACTOR: move the following to a better place:
+    private ArrayList<String> clinitAddedClasses = new ArrayList<String>();
+    public static boolean clinitAdded(String class_name, ClassLoader loader) {
+    	TeamIdDispenser instance = getInstanceForLoader(loader);
+    	if (instance.clinitAddedClasses.contains(class_name))
+    		return true;
+		
+    	instance.clinitAddedClasses.add(class_name);
+		return false;	
+    }
+    
+	/**
+	 * Since actual data are stored in an instance, static methods need to retrieve the appropriate
+     * instance regarding the given class loader.
+	 */
+	private static TeamIdDispenser getInstanceForLoader(ClassLoader loader) {
+		if (loader == null)
+			return defaultInstance;
+		
+		TeamIdDispenser instance = instances.get(loader);
+		if (instance == null)
+			instances.put(loader, instance = new TeamIdDispenser());
+		return instance;
+	}
+}
diff --git a/othersrc/OTRE/src/org/objectteams/DoublyWeakHashMap.java b/othersrc/OTRE/src/org/objectteams/DoublyWeakHashMap.java
new file mode 100644
index 0000000..4b72f1e
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/DoublyWeakHashMap.java
@@ -0,0 +1,96 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2010 Stephan Herrmann.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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$
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+/**
+ * This class defines hash maps where both key and value are weak references.
+ * It is implemented by delegating to a WeakHashMap and additionally
+ * wrapping the value in a WeakReference.
+ * 
+ * @author stephan
+ * @since 0.7.0
+ * @param <K>
+ * @param <V>
+ */
+public class DoublyWeakHashMap<K,V> implements Map<K,V> {
+
+	private WeakHashMap<K, WeakReference<V>> map;
+	
+	public DoublyWeakHashMap() {
+		this.map = new WeakHashMap<K, WeakReference<V>>();
+	}
+	public int size() {
+		return this.map.size();
+	}
+
+	public boolean isEmpty() {
+		return this.map.isEmpty();
+	}
+
+	public boolean containsKey(Object key) {
+		return this.map.containsKey(key);
+	}
+
+	public boolean containsValue(Object value) {
+		return this.map.containsValue(value);
+	}
+
+	public V get(Object key) {
+		return this.map.get(key).get();
+	}
+
+	public V put(K key, V value) {
+		this.map.put(key, new WeakReference<V>(value));
+		return value;
+	}
+
+	public V remove(Object key) {
+		WeakReference<V> value = this.map.remove(key);
+		return (value == null) ? null : value.get();
+	}
+
+	public void putAll(Map<? extends K, ? extends V> t) {
+		for (Entry<? extends K, ? extends V> entry : t.entrySet())
+			this.map.put(entry.getKey(), new WeakReference<V>(entry.getValue()));
+	}
+
+	public void clear() {
+		this.map.clear();
+	}
+
+	public Set<K> keySet() {
+		return this.map.keySet();
+	}
+
+	public Collection<V> values() {
+		ArrayList<V> result = new ArrayList<V>(this.map.size());
+		for (WeakReference<V> valRef : this.map.values())
+			result.add(valRef.get());
+		return result;
+	}
+
+	public Set<java.util.Map.Entry<K, V>> entrySet() {
+		throw new UnsupportedFeatureException("Method entrySet is not implemented for DoublyWeakHashMap");
+	}
+}
diff --git a/othersrc/OTRE/src/org/objectteams/DuplicateRoleException.java b/othersrc/OTRE/src/org/objectteams/DuplicateRoleException.java
new file mode 100644
index 0000000..ae3e851
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/DuplicateRoleException.java
@@ -0,0 +1,48 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: DuplicateRoleException.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Signal a violation of OTJLD 2.4.1(c).
+ * Also Team.getRole(Object) may throw a DuplicateRoleException if
+ * more than one role is found for the given base object
+ * (in that case those roles are found in different role-caches).
+ * 
+ * 
+ * @author stephan
+ * @version $Id: DuplicateRoleException.java 23408 2010-02-03 18:07:35Z stephan $
+ */
+public class DuplicateRoleException extends RuntimeException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * @param message
+	 */
+	public DuplicateRoleException(String roleClassName) {
+		super("Failed to create a role instance of type "+roleClassName+"\n"+
+			  "A role for the given base object already exists (OTJLD 2.4.1(c)).");
+	}
+	
+	public DuplicateRoleException(String roleName1, String roleName2) {
+		super("Ambiguous role instances: found a role in hierarchies "+
+				roleName1+" and "+roleName2);
+	}
+}
diff --git a/othersrc/OTRE/src/org/objectteams/IBaseMigratable.java b/othersrc/OTRE/src/org/objectteams/IBaseMigratable.java
new file mode 100644
index 0000000..edc9202
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/IBaseMigratable.java
@@ -0,0 +1,35 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2008 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: IBaseMigratable.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Marker interface: if a role declares to implement this interface
+ * the compiler will generate the method defined herein, and prepare
+ * the role so that the migration will indeed be possible.
+ * 
+ * @author stephan
+ * @since 1.2.5
+ */
+public interface IBaseMigratable {
+	/**
+	 * Migrate the current role to the otherBase.
+	 * 
+	 * @param otherBase new base that this role should adapt, must
+	 *        be of a valid base type for the current role.
+	 */
+	<B> void migrateToBase(B otherBase);
+}
diff --git a/othersrc/OTRE/src/org/objectteams/IBoundBase.java b/othersrc/OTRE/src/org/objectteams/IBoundBase.java
new file mode 100644
index 0000000..9f196bf
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/IBoundBase.java
@@ -0,0 +1,28 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2007-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: IBoundBase.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Super type for all bound base classes. Purely internal class, not intended for client use.
+ * @author Stephan Herrmann
+ */
+public interface IBoundBase {
+	/** Method to be used by generated code, only (lifting constructor). */
+	void _OT$addRole(Object aRole);
+	/** Method to be used by generated code, only (unregisterRole()). */
+	void _OT$removeRole(Object aRole);
+}
\ No newline at end of file
diff --git a/othersrc/OTRE/src/org/objectteams/IConfined.java b/othersrc/OTRE/src/org/objectteams/IConfined.java
new file mode 100644
index 0000000..8ead4b4
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/IConfined.java
@@ -0,0 +1,24 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: IConfined.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/** 
+ * Special interface that does not extend Object
+ * 
+ * @author stephan
+ */
+public interface IConfined {}
\ No newline at end of file
diff --git a/othersrc/OTRE/src/org/objectteams/ILiftingParticipant.java b/othersrc/OTRE/src/org/objectteams/ILiftingParticipant.java
new file mode 100644
index 0000000..408d087
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/ILiftingParticipant.java
@@ -0,0 +1,40 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2009 Stephan Herrmann
+ *  
+ * All rights reserved. This program and the accompanying materials
+ * 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: ILiftingParticipant.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * A lifting participant hooks into the lifting process.
+ * 
+ * @author stephan
+ * @since 1.3.1
+ */
+public interface ILiftingParticipant {
+	/**
+	 * This method is called when lifting does not find a suitable role within the
+	 * team's internal role cache. If this method returns a non-null value,
+	 * this value is considered by the runtime as being the desired role 
+	 * (i.e., it must be castable to that role type), and no new role is created. 
+	 * If this method returns null, lifting proceeds as normal, i.e., 
+	 * a fresh role is created using the default lifting constructor.
+	 * 
+	 * @param teamInstance
+	 * @param baseInstance
+	 * @param roleClassName
+	 * @return either null or an instance of the class specified by roleClassName
+	 */
+	Object createRole(ITeam teamInstance, Object baseInstance, String roleClassName);
+}
diff --git a/othersrc/OTRE/src/org/objectteams/ITeam.java b/othersrc/OTRE/src/org/objectteams/ITeam.java
new file mode 100644
index 0000000..84b1cd0
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/ITeam.java
@@ -0,0 +1,204 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2010 Stephan Herrmann.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: ITeam.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Public interface of all team classes.
+ */
+public interface ITeam {
+	
+    /**
+     *  Interface for all role classes that should allow explicit lowering.
+     *  The interface provides a phantom method <pre>&lt;B&gt; B lower()</pre>
+     *  where B is the bound base class of the implementing role class.
+     *  There is no need to implement the method lower, since this is done by the compiler.
+     */
+    public interface ILowerable {
+		// internal method needed for cast and instanceof
+    	ITeam _OT$getTeam();
+    }
+
+	/**
+	 *  This role interface has no properties not even those of java.lang.Object.
+	 */
+	public interface IConfined extends org.objectteams.IConfined {
+		// internal method needed for cast and instanceof
+		ITeam _OT$getTeam(); 
+	}
+
+
+	/**
+	 * Activates the team and therefore all of its callin bindings. 
+	 * This activation applies to the current thread only.
+	 */
+	public abstract void activate();
+
+	/**
+	 * Deactivates the team and therefore all of its callin bindings. 
+	 * This deactivation applies to the current thread only.
+	 */
+	public abstract void deactivate();
+
+	/**
+	 * Activates the team and therefore all of its callin bindings for passed thread. 
+	 * If the constant 'Team.ALL_THREADS' is passed, this activation globally applies to all threads.
+	 */
+	public abstract void activate(Thread thread);
+
+	/**
+	 * Deactivates the team and therefore all of its callin bindings for passed thread. 
+	 * If the constant 'Team.ALL_THREADS' is passed, this deactivation globally applies to all threads.
+	 */
+	public abstract void deactivate(Thread thread);
+
+	/**
+	 * Checks, if the team instance is active for the current thread.
+	 * @return true, if the team is active, false else.
+	 */
+	public abstract boolean isActive();
+
+	/**
+	 * Checks, if the team instance is active for the 'thread'.
+	 * @param thread	The thread for which to check activity.
+	 * @return	true, if the team is active for 'thread', false else.
+	 */
+	public abstract boolean isActive(Thread thread);
+
+	/**
+	 * Does given base object have a role in this team?
+	 * This method will consider roles of any type.
+	 * 
+	 * @param aBase any object, i.e., no checks are performed whether the base object's
+	 * 		class is bound by any role class in this team. 	
+	 * @return
+	 */
+	public abstract boolean hasRole(Object aBase);
+
+	/**
+	 * Does given base object have a role in this team?
+	 * The role must be an instance of the specified role type.
+	 * 
+	 * @param aBase any object, i.e., no checks are performed whether the base object's
+	 * 		class is bound by any role class in this team.
+	 * @param roleClass Class instance specifying the required role type.
+	 *      If this does not specify an existing role class an IllegalArgumentException will be thrown.
+	 *      TODO (SH): is it legal to pass an unbound role class? 	
+	 * @return
+	 */
+	public abstract boolean hasRole(Object aBase, Class<?> roleType);
+
+	/**
+	 * Retrieve a role for a given base object.
+	 * If more than one role exists, a DuplicateRoleException is thrown.
+	 * 
+	 * @param aBase
+	 * @return
+	 */
+	public abstract Object getRole(Object aBase);
+
+	/**
+	 * Retrieve a role for a given base object.
+	 * The role must be an instance of the specified role type.
+	 * 
+	 * @param aBase any object, i.e., no checks are performed whether the base object's
+	 * 		class is bound by any role class in this team.
+	 * @param roleClass Class instance specifying the required role type.
+	 *      If this does not specify an existing role class an IllegalArgumentException will be thrown.
+	 * @return
+	 */
+	public abstract <T> T getRole(Object aBase, Class<T> roleType);
+
+	/**
+	 * Retrieve all bound roles registered in the current team.
+	 * 
+	 * This method uses internal structures of weak references. 
+	 * For that reason it may return role instances which were about to be reclaimed 
+	 * by the garbage collector. 
+	 * If performance permits, it is thus advisable to always call System.gc() 
+	 * prior to calling getAllRoles() in order to achieve deterministic results
+	 * 
+	 * @return a non-null array.
+	 */
+	public abstract Object[] getAllRoles();
+
+	/**
+	 * Retrieve all bound roles registered in the current team that
+	 * are instance of roleType or a subtype thereof.
+	 * 
+	 * This method uses internal structures of weak references. 
+	 * For that reason it may return role instances which were about to be reclaimed 
+	 * by the garbage collector. 
+	 * If performance permits, it is thus advisable to always call System.gc() 
+	 * prior to calling getAllRoles() in order to achieve deterministic results
+	 * 
+	 * @param roleType must be a top-most bound role of this team. 
+	 * @return a non-null array.
+	 */
+	public abstract <T> T[] getAllRoles(Class<T> roleType);
+
+	/**
+	 * Query whether any role instance of this team instance is currently executing a
+	 * method due to a callin binding.
+	 * @return
+	 */
+	public abstract boolean isExecutingCallin();
+
+	/**
+	 * Remove a role from the internal registry, which means that the role will no longer be
+	 * considered during lifting.
+	 *  
+	 * @param aRole
+	 */
+	public abstract void unregisterRole(Object aRole);
+
+	/**
+	 * Remove a role from the internal registry, which means that the role will no longer be
+	 * considered during lifting.
+	 *  
+	 * @param aRole
+	 * @param roleType
+	 */
+	public abstract void unregisterRole(Object aRole, Class<?> roleType);
+
+	/**
+	 * Not API.
+	 * This method saves the activation state of the team  for the current thread.
+	 * If active, it also saves, if the activation was explicit or implicit.
+	 * This method has to be called by the generated code when entering a within block, 
+	 * before the activation.
+	 */
+	public int _OT$saveActivationState();
+	
+	/**
+	 * Not API.
+	 * This method restores the former saved activation state of the team  for the current thread.
+	 * If active, it also restores, if the activation was explicit or implicit.
+	 * This method has to be called by the generated code when leaving a within block 
+	 * (in the finally block).
+	 */
+	public void _OT$restoreActivationState(int old_state);
+	
+	/**
+	 * Not API, for use by TeamThreadManager, only.
+	 */
+	public boolean internalIsActiveSpecificallyFor(Thread t);
+	
+	/**
+	 * Not API, for use by TeamThreadManager, only.
+	 */
+	public void deactivateForEndedThread(Thread thread);
+}
\ No newline at end of file
diff --git a/othersrc/OTRE/src/org/objectteams/ITeamMigratable.java b/othersrc/OTRE/src/org/objectteams/ITeamMigratable.java
new file mode 100644
index 0000000..39be566
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/ITeamMigratable.java
@@ -0,0 +1,36 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2008 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: ITeamMigratable.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Marker interface: if a role declares to implement this interface
+ * the compiler will generate the method defined herein, and prepare
+ * the role so that the migration will indeed be possible.
+ * Note, that a migratable role does not obey the family guarantee.
+ * 
+ * @author stephan
+ * @since 1.2.5
+ */
+public interface ITeamMigratable {
+	/**
+	 * Migrate the current role to the otherTeam.
+	 * 
+	 * @param otherTeam new team that should adopt this role
+	 * @return the migrated (and re-typed) role (actually of type R<@otherTeam>).  FIXME(SH)
+	 */
+	<R> R migrateToTeam(final ITeam otherTeam);
+}
diff --git a/othersrc/OTRE/src/org/objectteams/IllegalRoleCreationException.java b/othersrc/OTRE/src/org/objectteams/IllegalRoleCreationException.java
new file mode 100644
index 0000000..f745d73
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/IllegalRoleCreationException.java
@@ -0,0 +1,35 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2007-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: IllegalRoleCreationException.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Exception to be thrown when a bound role is being instantiated but
+ * the constructor does not assign a base object.
+ *  
+ * @author stephan
+ */
+@SuppressWarnings("serial")
+public class IllegalRoleCreationException extends RuntimeException {
+	public IllegalRoleCreationException() {
+		super();
+	}
+	
+	@Override
+	public String getMessage() {
+		return "Cannot instantiate a bound role using a default constructor of its tsuper class";
+	}
+}
diff --git a/othersrc/OTRE/src/org/objectteams/ImplicitTeamActivation.java b/othersrc/OTRE/src/org/objectteams/ImplicitTeamActivation.java
new file mode 100644
index 0000000..09eda96
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/ImplicitTeamActivation.java
@@ -0,0 +1,45 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2009 Stephan Herrmann
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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$
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 			Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This marker annotation enables implicit team activation for the annotated element:
+ * <ul>
+ * <li>If attached to a method the effect is that each call to this method implicitly
+ *     activates the enclosing team.</li>
+ * <li>If attached to a class it has the same effect as annotating all contained methods.</li>
+ * </ul>
+ * See <a href="http://www.objectteams.org/def/1.3/s5.html#s5.3">OTJLD § 5.3</a>.
+ * <p>
+ * This annotation is only evaluated if the property <code>ot.implicit.team.activation</code>
+ * is set to the string <code>ANNOTATED</code>.
+ * </p>
+ * @author stephan
+ * @since 1.4.0
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface ImplicitTeamActivation {
+	/* no members, pure marker annotation. */
+}
diff --git a/othersrc/OTRE/src/org/objectteams/LiftingFailedException.java b/othersrc/OTRE/src/org/objectteams/LiftingFailedException.java
new file mode 100644
index 0000000..99f2dd2
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/LiftingFailedException.java
@@ -0,0 +1,46 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2003-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: LiftingFailedException.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * This exception signals that lifting failed due to unresolved
+ * binding ambiguity.
+ */
+public class LiftingFailedException extends RuntimeException {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private Object base;
+	private String roleType;
+	
+	/**
+	 * @param base the object that should be lifted
+	 * @param roleType the name of the role type for which
+	 *                 lifting was attempted.
+	 */
+	public LiftingFailedException(Object base, String roleType) {
+		this.base = base;
+		this.roleType = roleType;
+	}
+	
+	public String getMessage() {
+		return "\nFailed to lift '" + base + "' of " + base.getClass()
+				+ " to type '" + roleType
+				+ "'\n(See OT/J definition para. 2.3.4(c)).";
+	}
+}
diff --git a/othersrc/OTRE/src/org/objectteams/LiftingVetoException.java b/othersrc/OTRE/src/org/objectteams/LiftingVetoException.java
new file mode 100644
index 0000000..3a9b83a
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/LiftingVetoException.java
@@ -0,0 +1,45 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2003-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: LiftingVetoException.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ *  This exception is used by the language implementation
+ *  to signal a failed lifting due to a guard predicate that evaluated to false.
+ *  @author Stephan Herrmann
+ */
+public class LiftingVetoException extends RuntimeException {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	ITeam aTeam = null;
+	Object base = null;
+	
+	public LiftingVetoException(ITeam aTeam, Object base) {
+		this.aTeam = aTeam;
+		this.base = base;
+	}
+	
+    public LiftingVetoException() {
+		super("");
+    }
+    
+	public String toString() {
+		return "Team " + aTeam + " refuses to lift " + base
+				+ "\n(this exception should not be seen in applications).";
+	}
+}
diff --git a/othersrc/OTRE/src/org/objectteams/ResultNotProvidedException.java b/othersrc/OTRE/src/org/objectteams/ResultNotProvidedException.java
new file mode 100644
index 0000000..b6baccb
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/ResultNotProvidedException.java
@@ -0,0 +1,61 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: ResultNotProvidedException.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * @author resix
+ */
+public class ResultNotProvidedException extends RuntimeException {
+
+		/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+		private static final String _bugmsg = 
+		"\nNo base call executed! Result value was uninitialized!\n(see OT/J language definition para. 4.3(e)).";
+
+		/**
+		 * 
+		 */
+		public ResultNotProvidedException() {
+			super(_bugmsg);
+		}
+
+		/**
+		 * @param message
+		 */
+		public ResultNotProvidedException(String message) {
+			super(_bugmsg + "\n" + message);
+			StackTraceElement[] ste = new StackTraceElement[0];
+			setStackTrace(ste);
+		}
+
+		/**
+		 * @param cause
+		 */
+		public ResultNotProvidedException(Throwable cause) {
+			super(_bugmsg + cause.toString());
+		}
+
+		/**
+		 * @param message
+		 * @param cause
+		 */
+		public ResultNotProvidedException(String message, Throwable cause) {
+			super(_bugmsg + message/* +cause.toString() */);
+		}
+}
diff --git a/othersrc/OTRE/src/org/objectteams/RoleCastException.java b/othersrc/OTRE/src/org/objectteams/RoleCastException.java
new file mode 100644
index 0000000..f6608c9
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/RoleCastException.java
@@ -0,0 +1,39 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: RoleCastException.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * This exception is thrown if a cast to a role class fails due to
+ * different enclosing team instances.
+ * @author Stephan Herrmann
+ */
+public class RoleCastException extends ClassCastException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static final String MSG = 
+		"Different enclosing team instances (see OT/J language definition para. 1.2.4(b)).";
+
+	/* (non-Javadoc)
+	 * @see java.lang.Throwable#getMessage()
+	 */
+	public String getMessage() {
+		return MSG;
+	}
+}
\ No newline at end of file
diff --git a/othersrc/OTRE/src/org/objectteams/Team.java b/othersrc/OTRE/src/org/objectteams/Team.java
new file mode 100644
index 0000000..c6c5f33
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/Team.java
@@ -0,0 +1,490 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2002-2007 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: Team.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+import java.awt.EventQueue;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.WeakHashMap;
+
+/**
+ *  This is the root class of all team definitions.
+ *  Any class with the <tt>team</tt> modifier implicitly
+ *  inherits from this class.
+ *  
+ */
+public /* team */ class Team implements ITeam {
+	// Technical note: comments starting with //$Debug are intended
+	// for a standalone tool that generates an interface 
+	// which the debugger needs in order to know about line numbers in this class.
+	
+	/*
+	 *  Synchronization: This class supports two levels of synchronization:
+	 *  <ul>
+	 *  <li>Fields of <code>Team</code> are synchronized 
+	 *      using <code>this</code> as the monitor.
+	 *  <li>Those calls that (un)register a team at its base classes are synchronized 
+	 *      via <code>registrationLock</code>
+	 *  </ul>
+	 *  This allows releasing the lock on <code>this</code> before calling to the base class.
+	 *  Note, that the synchronized portion of each initial-wrapper is also synchronized 
+	 *  (against <code>_OT$addTeam/_OT$removeTeam</code>) and that it calls back to
+	 *  the registered teams (method <code>isActive()</code>). 
+	 *  Without <code>registrationLock</code> this situation could easily deadlock:
+	 *  Thread1: <pre>t.activate() -> Base._OT$addTeam()</pre>: owns t, waits for Base.
+	 *  Thread2: <pre>b.bm() (initial wrapper) -> t.isActive()</pre>: owns Base, waits for t. 
+	 */
+	
+	/**
+	 * Internal field used by the runtime to install a lifting participant if one is configured.
+	 */
+	public static ILiftingParticipant _OT$liftingParticipant = null;
+	
+	/**
+	 * Default constructor for debugging purpose.
+	 */
+	public Team() {} //$Debug(TeamConstructor)
+
+	/*
+	 * manual copy-inheritance of a role interface from ITeam.
+	 */
+	public interface ILowerable extends ITeam.ILowerable {}
+
+	/*
+	 * manual copy-inheritance of a role interface from ITeam.
+	 */
+	public interface IConfined extends ITeam.IConfined {}
+	
+	/**
+	 *  Special role type that<ul>
+	 * <li> does not extend java.lang.Object
+	 * <li> may not leak references outside the team.
+	 * </ul>
+	 */
+	protected interface Confined { 
+		/* internal method needed for cast and instanceof
+		 * (this method will be generated for role classes) */
+		ITeam _OT$getTeam();
+	}
+	
+    /** 
+     * This class would have been generated by the OT-compiler.
+     * Don't explicitly use it in client code!
+     */
+    protected class __OT__Confined implements Confined {
+		// internal method needed for cast and instanceof
+    	public ITeam _OT$getTeam() {
+    		return Team.this; //$Debug(ConfinedGetTeam)
+    	}
+    }
+
+	/**
+	 *  Internal function for identifying a Team.
+	 *  Should not be called by client code.
+	 */
+	public int _OT$getID () {return -1;}
+
+    /**
+	 * The constant <code>ALL_THREADS</code> is used for global team (de-)activation.
+	 */
+	public static final Thread ALL_THREADS = new Thread();
+	
+	private static final int _OT$UNREGISTERED = 0;
+	private static final int _OT$REGISTERED = 1;
+	private  int _OT$registrationState = _OT$UNREGISTERED;
+	
+	private boolean _OT$globalActive = false;
+	
+	private ThreadLocal<Integer> _OT$implicitActivationsPerThread = new ThreadLocal<Integer>() {
+		protected synchronized Integer initialValue() {
+			return Integer.valueOf(0);
+		}
+	};
+	
+	private boolean _OT$lazyGlobalActiveFlag = false;
+	
+	/**
+	 * <code>_OT$activatedThreads</code> contains all threads for which this team instance is active.
+	 * key		= activated thread
+	 * value 	= Boolean(true) for explicit activation | Boolean(false) for implicit activation.
+	 */
+	private WeakHashMap<Thread, Boolean> _OT$activatedThreads = new WeakHashMap<Thread, Boolean>();
+	
+	/** This lock is used to protect activate/deactivate methods <strong>including</strong>
+	 *  the calls to doRegistration/doUnregistration. 
+	 */
+	private Object _OT$registrationLock= new Object();
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public void activate() {
+		activate(Thread.currentThread());
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public void deactivate() {
+		deactivate(Thread.currentThread());
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public void activate(Thread thread) {
+		// acquire both locks to avoid incomplete execution:
+		synchronized (this._OT$registrationLock) {
+			synchronized (this) {
+				if (thread.equals(ALL_THREADS)) {
+					_OT$globalActive = true;
+					_OT$lazyGlobalActiveFlag = true;
+					TeamThreadManager.addGlobalActiveTeam(this);
+				} else { // activation only for 'thread':
+					// register 'thread' as active:
+					_OT$activatedThreads.put(thread, Boolean.TRUE);
+				}
+			} // release this before calling synchronized base class methods
+			doRegistration(); //$Debug(ActivateMethod)		
+		}
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public void deactivate(Thread thread) {
+		// acquire both locks to avoid incomplete execution:
+		synchronized (this._OT$registrationLock) {
+			boolean shouldUnregister= false;
+			synchronized(this) {
+				if (_OT$globalActive && EventQueue.isDispatchThread()) {
+					System.err.println("Warning: Deactivation for the AWT-Event-Thread is not effective right now!");
+				}
+				if (thread.equals(ALL_THREADS)) {
+					_OT$globalActive = false;
+					TeamThreadManager.removeGlobalActiveTeam(this);
+					// unregister all threads:
+					_OT$activatedThreads.clear();
+					shouldUnregister= true;
+				} else { // deactivation only for 'thread':
+					if (_OT$lazyGlobalActiveFlag) { 
+						// be eager now: activate for all (other) threads:
+						_OT$activateForAllThreads();
+					} 
+					// deactivate for 'thread', no longer active:
+					_OT$activatedThreads.remove(thread);
+					if (!_OT$lazyGlobalActiveFlag  && _OT$activatedThreads.isEmpty()) {
+						shouldUnregister= true;
+					}
+				}
+				_OT$lazyGlobalActiveFlag = false; 
+			} // release this before calling synchronized base class methods
+			if (shouldUnregister) 		//$Debug(DeactivateMethod)
+				doUnregistration();
+		}
+	}
+	
+	public void deactivateForEndedThread(Thread thread) {
+		synchronized (_OT$registrationLock) {
+			boolean shouldUnregister= false;
+			synchronized (this) {
+				_OT$activatedThreads.remove(thread);
+				if (!_OT$lazyGlobalActiveFlag  && _OT$activatedThreads.isEmpty())
+					shouldUnregister= true;				
+			}
+			if (shouldUnregister)
+				doUnregistration();
+		}
+	}
+	
+	private void _OT$activateForAllThreads() {
+		HashSet threads = TeamThreadManager.getExistingThreads();
+		Iterator it = threads.iterator();
+		while (it.hasNext()) {
+			Thread a_thread = (Thread) it.next();
+			activate(a_thread); // use smaller activate version (no ALL_THREADS, no registerAtBases,...
+		}
+	}
+
+	/**
+	 * This method is used for implicit activation in team-level methods.
+	 * Implicit activation only applies to the current thread.
+	 * Don't call it from client code.
+	 */
+	public void _OT$implicitlyActivate() {
+		synchronized (this._OT$registrationLock) {
+			boolean shouldRegister= false;
+			synchronized (this) {
+				// this method is used for debugging purpose (team monitor)
+				Thread currentThread = Thread.currentThread();
+				if (!_OT$activatedThreads.containsKey(currentThread)) {
+					// register 'thread' as active:
+					_OT$activatedThreads.put(currentThread, Boolean.FALSE);
+					shouldRegister= true;
+				}
+				//	increment thread local implicit activaion counter:
+				int implActCount = (_OT$implicitActivationsPerThread.get()).intValue();
+				_OT$implicitActivationsPerThread.set(Integer.valueOf(implActCount + 1 )); 
+			}
+			if (shouldRegister) //$Debug(ImplicitActivateMethod)
+				doRegistration();
+		}
+	}
+	
+	/**
+	 * This method is used for implicitly deactivation in team-level methods.
+	 * It respects explicit activation changes and nested calls to team-level methods.
+	 * Implicit deactivation only applies to the current thread.
+	 * Don't call it from client code.
+	 */
+	public void _OT$implicitlyDeactivate() {
+		synchronized (this._OT$registrationLock) {
+			boolean shouldUnregister= false;
+			synchronized(this) {
+				// this method is used for debugging purpose (team monitor)
+				Thread currentThread = Thread.currentThread();
+				boolean explicitlyActivated = false;
+				if (_OT$activatedThreads.containsKey(currentThread)) {
+					explicitlyActivated = ((Boolean) _OT$activatedThreads.get(currentThread)).booleanValue();
+				}
+				if (!explicitlyActivated 
+						&& !_OT$lazyGlobalActiveFlag // no explicit activation overriding the implicit one 
+						&& ((_OT$implicitActivationsPerThread.get()).intValue() == 1))  // this is the last implicit activation
+				{
+					_OT$activatedThreads.remove(currentThread);
+					if (_OT$activatedThreads.isEmpty()) // there are not other threads for which this theam is active
+					{
+						shouldUnregister= true;
+					}
+				}				
+				// decrement thread local implicit activaion counter:
+				int implActCount = (_OT$implicitActivationsPerThread.get()).intValue();
+				_OT$implicitActivationsPerThread.set(Integer.valueOf(implActCount - 1)); 
+			}
+			if (shouldUnregister) //$Debug(ImplicitDeactivateMethod)
+				doUnregistration();
+		}
+	}
+	
+	/**
+	 * Define whether per-thread activation of this team should be inheritable
+	 * such that the team will be activated automatically for any new threads 
+	 * that are spawned from a thread for which the team is already active at that time.
+	 * 
+	 * @param inheritable whether or not activation should be inheritable to new threads
+	 */
+	public void setInheritableActivation(boolean inheritable) {
+		if (inheritable)
+			TeamThreadManager.registerTeamForActivationInheritance(this);
+		else
+			TeamThreadManager.unRegisterTeamForActivationInheritance(this);
+	}
+	
+	// not API (for use by the TeamThreadManager)
+	public boolean internalIsActiveSpecificallyFor(Thread t) {
+		return this._OT$activatedThreads.containsKey(t);
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isActive() {
+		return isActive(Thread.currentThread());
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isActive(Thread thread) {
+		if (_OT$globalActive && EventQueue.isDispatchThread())
+			return true;
+		if (thread.equals(ALL_THREADS)) {
+			return _OT$globalActive;
+		}
+		if (_OT$lazyGlobalActiveFlag) {
+				return true;
+		} else {
+			//if (!TeamThreadManager.getExistingThreads().contains(thread)) { // this thread is already finished!
+			if (!thread.isAlive()) { // this thread is already finished!
+				throw new IllegalThreadStateException("Called 'isActive(...)' for a thread which is no longer running!");
+			}
+			return _OT$activatedThreads.containsKey(thread);
+		}
+	}
+
+// ***** for restoring the activation state after a within block:	---->*****
+	private static final int _OT$INACTIVE = 0;
+	private static final int _OT$IMPLICIT_ACTIVE = 1;
+	private static final int _OT$EXPLICIT_ACTIVE = 2;
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public synchronized int _OT$saveActivationState() {
+		int old_state = _OT$INACTIVE;
+		if (_OT$lazyGlobalActiveFlag) {
+			old_state = _OT$EXPLICIT_ACTIVE;
+		} else {
+			Thread current_thread = Thread.currentThread();
+			if (_OT$activatedThreads.containsKey(current_thread)) {
+				old_state = _OT$IMPLICIT_ACTIVE;
+				if (((Boolean)_OT$activatedThreads.get(current_thread)).booleanValue()) {
+					old_state = _OT$EXPLICIT_ACTIVE;
+				}
+			}
+		}
+		return old_state;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public void _OT$restoreActivationState(int old_state) {
+		synchronized (_OT$registrationLock) {
+			if (old_state == _OT$INACTIVE) // team was inactive before:
+				deactivate();
+			else { // team was active before: has to be reactivated:
+				boolean explicit = (old_state == _OT$EXPLICIT_ACTIVE);
+				synchronized (this) {					
+					_OT$activatedThreads.put(Thread.currentThread(), Boolean.valueOf(explicit));
+				}
+				doRegistration();
+			}
+		}
+	}
+//	 ***** <----for restoring the activation state after a within block.	*****
+	
+
+	private void doRegistration() {
+		if (_OT$registrationState == _OT$UNREGISTERED) {
+			_OT$registerAtBases();
+			_OT$registrationState = _OT$REGISTERED;
+		}
+	}
+	
+	private void doUnregistration() {
+		if (_OT$registrationState == _OT$REGISTERED) {
+			_OT$unregisterFromBases();
+			_OT$registrationState = _OT$UNREGISTERED;
+		}
+	}
+	
+	/**
+	 * This method will be implemented by generated code in subteams.
+	 * It registers the team at every base playing one of its roles. 
+	 * Don't call it from client code.
+	 */
+	public void _OT$registerAtBases() {} 
+
+	/**
+	 * This method will be implemented by generated code in subteams.
+	 * It unregisters the team from every base playing one of its roles. 
+	 * Don't call it from client code.
+	 */
+	public void _OT$unregisterFromBases() {}
+	
+	//public int _OT$activationState = -1; // TODO: remove usage of  this from generated code	
+		
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean hasRole(Object aBase) {
+		// overriding method to be generated by the compiler for each team with bound roles. 
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean hasRole(Object aBase, Class<?> roleType) {
+		// overriding method to be generated by the compiler for each team with bound roles. 
+		throw new IllegalArgumentException("No such bound role type in this team: "+roleType.getName());
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object getRole(Object aBase) {
+		// overriding method to be generated by the compiler for each team with bound roles. 
+		return null;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public <T> T getRole(Object aBase, Class<T> roleType) {
+		// overriding method to be generated by the compiler for each team with bound roles. 
+		return null;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object[] getAllRoles() {
+		// overriding method to be generated by the compiler for each team with bound roles. 
+		return new Object[0];
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public <T> T[] getAllRoles(Class<T> roleType) {
+		// overriding method to be generated by the compiler for each team with bound roles. 		
+		throw new IllegalArgumentException("Class org.objectteams.Team has no bound roles.");
+	}
+	
+	/** Internal variable to be set from generated code. */
+	private boolean _OT$isExecutingCallin = false;
+	
+	/**
+	 * Method only for internal use by generated code.
+	 */
+	public boolean _OT$setExecutingCallin(boolean newFlag) {
+		boolean oldVal = _OT$isExecutingCallin;
+		_OT$isExecutingCallin = newFlag;
+		return oldVal;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isExecutingCallin() {
+		return _OT$isExecutingCallin;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public void unregisterRole(Object aRole) {
+		// overriding method to be generated by the compiler for each team with bound roles. 
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void unregisterRole(Object aRole, Class<?> roleType) {
+		// overriding method to be generated by the compiler for each team with bound roles. 
+	}
+	
+	@Override
+	protected void finalize() throws Throwable {
+		// nop, hook for the debugger 
+		@SuppressWarnings("unused")
+		int i= 2+3; // Note: body must not be empty for debuggger to be able to stop.
+	} // $Debug(FinalizeMethod)
+}
diff --git a/othersrc/OTRE/src/org/objectteams/TeamThreadManager.java b/othersrc/OTRE/src/org/objectteams/TeamThreadManager.java
new file mode 100644
index 0000000..ce1b174
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/TeamThreadManager.java
@@ -0,0 +1,97 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2006-2008 Berlin Institute of Technology, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * 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: TeamThreadManager.java 23408 2010-02-03 18:07:35Z stephan $
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+import java.util.HashSet;
+import java.util.WeakHashMap;
+
+
+/**
+ * This class is for internal use, only.
+ * 
+ * Maintain information about existing threads as to manage
+ * team activation per thread vs. globally.
+ * 
+ * @author Chistine Hundt
+ * @author Stephan Herrmann
+ */
+public class TeamThreadManager {
+
+	private static Object token = new Object();
+	
+	private static HashSet<ITeam> globalActiveTeams = new HashSet<ITeam>();
+	private static WeakHashMap<ITeam,Object> teamsWithActivationInheritance = new WeakHashMap<ITeam,Object>();
+	private static HashSet<Thread> existingThreads = new HashSet<Thread>();
+	
+	public static boolean newThreadStarted(boolean isMain, Thread parent) {
+		if (!isMain && (new Exception().getStackTrace().length > 3))
+			return false;
+		// workaround for application hang on Mac OS with Apple JVM:
+		Thread currentThread = Thread.currentThread();
+		if (System.getProperty("os.name").startsWith("Mac"))
+			if (currentThread.getName().equals("AWT-Shutdown"))
+				return false;
+
+		ITeam[] globalTeams;
+		ITeam[] inheritableTeams;
+		synchronized (TeamThreadManager.class) {
+			existingThreads.add(currentThread);
+			
+			globalTeams = globalActiveTeams.toArray(new ITeam[globalActiveTeams.size()]);
+			inheritableTeams = teamsWithActivationInheritance.keySet().toArray(new ITeam[teamsWithActivationInheritance.size()]);
+		}
+		// activate teams outside synchronized block:
+		for (ITeam t : globalTeams)			
+			t.activate(currentThread); // small version? global -> already registered...!
+		if (parent != null)
+			for (ITeam t : inheritableTeams)
+				if (t.internalIsActiveSpecificallyFor(parent))
+					t.activate(currentThread); // pass activation from parent to child thread
+		return true;
+	}
+	public static void threadEnded() {
+		ITeam[] teamsToDeactivate = internalThreadEnded();
+		// + remove per thread activation:
+		for (ITeam t : teamsToDeactivate) 
+			//t.deactivate(Thread.currentThread()); // small version?
+			t.deactivateForEndedThread(Thread.currentThread());			
+	}
+	private synchronized static ITeam[] internalThreadEnded() {
+		existingThreads.remove(Thread.currentThread());
+		// fetch all global active teams for deactivation:
+		return globalActiveTeams.toArray(new ITeam[globalActiveTeams.size()]);
+	}
+	
+	public synchronized static void addGlobalActiveTeam(ITeam t) {
+		globalActiveTeams.add(t);
+	}
+	
+	public synchronized static void removeGlobalActiveTeam(ITeam t) {
+		globalActiveTeams.remove(t);
+	}
+	
+	public static HashSet<Thread> getExistingThreads() {
+		return existingThreads;
+	}
+	public static void registerTeamForActivationInheritance(ITeam aTeam) {
+		teamsWithActivationInheritance.put(aTeam,token);
+	}
+	public static void unRegisterTeamForActivationInheritance(ITeam aTeam) {
+		teamsWithActivationInheritance.remove(aTeam);
+	}
+
+}
diff --git a/othersrc/OTRE/src/org/objectteams/UnsupportedFeatureException.java b/othersrc/OTRE/src/org/objectteams/UnsupportedFeatureException.java
new file mode 100644
index 0000000..9b1c1ff
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/UnsupportedFeatureException.java
@@ -0,0 +1,60 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: UnsupportedFeatureException.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * @author resix
+ */
+public class UnsupportedFeatureException extends RuntimeException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static final String _bugmsg = "\nThe program encountered an unsupported situation! ";
+
+	/**
+	 * 
+	 */
+	public UnsupportedFeatureException() {
+		super(_bugmsg);
+	}
+
+	/**
+	 * @param message
+	 */
+	public UnsupportedFeatureException(String message) {
+		super(_bugmsg + "\n" + message);
+		StackTraceElement[] ste = new StackTraceElement[0];
+		setStackTrace(ste);
+	}
+
+	/**
+	 * @param cause
+	 */
+	public UnsupportedFeatureException(Throwable cause) {
+		super(_bugmsg + cause.toString());
+	}
+
+	/**
+	 * @param message
+	 * @param cause
+	 */
+	public UnsupportedFeatureException(String message, Throwable cause) {
+		super(_bugmsg + message/*+cause.toString()*/);
+	}
+}
diff --git a/othersrc/OTRE/src/org/objectteams/WrongRoleException.java b/othersrc/OTRE/src/org/objectteams/WrongRoleException.java
new file mode 100644
index 0000000..da84d33
--- /dev/null
+++ b/othersrc/OTRE/src/org/objectteams/WrongRoleException.java
@@ -0,0 +1,57 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2003-2009 Berlin Institute of Technology, Germany.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * 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: WrongRoleException.java 23408 2010-02-03 18:07:35Z stephan $
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * This exception is thrown by the OT/J infra structure if a role for a given base object
+ * was requested during lifting, but a role with an incompatible type was already
+ * registered for that base object. Can only happen if a compile time warning occurred.
+ * @author Stephan Herrmann
+ */
+public class WrongRoleException extends RuntimeException {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private Class clazz;
+	private Object base;
+	private Object role;
+
+	/**
+	 * @param clazz
+	 * @param base
+	 * @param role
+	 */
+	public WrongRoleException (Class clazz, Object base, Object role) {
+		this.clazz = clazz;
+		this.base = base;
+		this.role = role;
+	}
+	
+	public String getMessage() {
+		String baseClazz = base.getClass().getName();
+		String roleClazz = role.getClass().getName();
+		return "The compiler has warned you about ambiguous role bindings.\n"
+				+ "Now lifting to " + clazz
+				+ " fails with the following objects\n"
+				+ "(see OT/J language definition para. 2.3.4(d)):\n"
+				+ "Provided:\n  Base object: " + base + "\n" + "  Base type:   "
+				+ baseClazz + "\n" 
+				+ "Found in cache:\n  Role object: " + role + "\n"
+				+ "  Role type:   " + roleClazz;
+	}
+}
