Merge commit '9b5f216eb1069dc8f5211bf81bf5e2fb46bebbe1' into
OT_BETA_JAVA8

Conflicts:
	plugins/org.eclipse.objectteams.otdt.jdt.ui/META-INF/MANIFEST.MF
	releng/build-scripts/build/otdt_prerequisites.sh
	releng/map/otdt.map.in
diff --git a/features/org.eclipse.objectteams.otdt.core.patch/feature.xml b/features/org.eclipse.objectteams.otdt.core.patch/feature.xml
index 631a89e..033af83 100644
--- a/features/org.eclipse.objectteams.otdt.core.patch/feature.xml
+++ b/features/org.eclipse.objectteams.otdt.core.patch/feature.xml
@@ -59,7 +59,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jdt" version="3.10.0.v20130709-0800" patch="true"/>
+      <import feature="org.eclipse.jdt" version="3.10.0.N20130724-2000" patch="true"/>
    </requires>
 
    <plugin
diff --git a/features/org.eclipse.objectteams.otequinox.feature/feature.xml b/features/org.eclipse.objectteams.otequinox.feature/feature.xml
index 1d62208..11621fc 100644
--- a/features/org.eclipse.objectteams.otequinox.feature/feature.xml
+++ b/features/org.eclipse.objectteams.otequinox.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.objectteams.otequinox"
       label="%featureName"
-      version="2.2.0.qualifier"
+      version="2.3.0.qualifier"
       provider-name="%providerName"
       plugin="org.eclipse.objectteams.otequinox"
       colocation-affinity="org.eclipse.rcp">
@@ -26,14 +26,6 @@
    </url>
 
    <plugin
-         id="org.eclipse.objectteams.otequinox.hook"
-         download-size="24"
-         install-size="56"
-         version="0.0.0"
-         fragment="true"
-         unpack="false"/>
-
-   <plugin
          id="org.eclipse.objectteams.runtime"
          download-size="89"
          install-size="202"
@@ -55,33 +47,6 @@
          unpack="false"/>
 
    <plugin
-         id="org.eclipse.objectteams.otequinox.sunjvm"
-         os="linux"
-         download-size="1"
-         install-size="1"
-         version="0.0.0"
-         fragment="true"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.objectteams.otequinox.sunjvm"
-         os="solaris"
-         download-size="1"
-         install-size="1"
-         version="0.0.0"
-         fragment="true"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.objectteams.otequinox.sunjvm"
-         os="win32"
-         download-size="1"
-         install-size="1"
-         version="0.0.0"
-         fragment="true"
-         unpack="false"/>
-
-   <plugin
          id="org.eclipse.objectteams.otequinox.branding"
          download-size="15"
          install-size="20"
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/LocalVMLauncher.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/LocalVMLauncher.java
index e3de69a..cdfbd79 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/LocalVMLauncher.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/LocalVMLauncher.java
@@ -60,10 +60,10 @@
 	if (vmName != null && vmName.indexOf("JRockit") != -1) {
 		return new JRockitVMLauncher();
 	}
-	final String osName = System.getProperty("os.name");
-	if (osName.startsWith("Mac")) {
-		return new MacVMLauncher();
-	}
+//	final String osName = System.getProperty("os.name");
+//	if (osName.startsWith("Mac")) {
+//		return new MacVMLauncher();
+//	}
 	File file = new File(Util.getJREDirectory() + "/lib/rt.jar");
 	if (file.exists()) {
 		return new StandardVMLauncher();
diff --git a/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/META-INF/MANIFEST.MF
index b27a348..d2e7475 100644
--- a/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.compiler.adaptor;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.jdt.core;bundle-version="[3.9.0.v_OTDT_r220,4.0.0)",
@@ -11,7 +11,7 @@
  org.eclipse.core.resources;bundle-version="[3.7.100,4.0.0)",
  org.eclipse.pde.core;bundle-version="[3.7.0,4.0.0)",
  org.eclipse.objectteams.otdt;bundle-version="[2.2.0,3.0.0)"
-Export-Package: org.eclipse.objectteams.otdt.internal.compiler.adaptor;x-friends:="org.eclipse.objectteams.otdt.test.builder"
+Export-Package: org.eclipse.objectteams.otdt.internal.compiler.adaptor;x-friends:="org.eclipse.objectteams.otdt.test.builder,org.eclipse.core.resources,org.eclipse.jdt.core,org.eclipse.pde.core"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy
 Bundle-Activator: org.eclipse.objectteams.otdt.compiler.adaptor.CompilerAdaptorPlugin
diff --git a/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/plugin.xml b/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/plugin.xml
index 57c0d97..147a3f8 100644
--- a/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/plugin.xml
+++ b/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/plugin.xml
@@ -44,7 +44,7 @@
          </team>
          <team
                activation="NONE"
-               class="org.eclipse.objectteams.otdt.internal.compiler.adaptor.CheckUniqueCallinCapture.Batch"
+               class="org.eclipse.objectteams.otdt.internal.compiler.adaptor.CheckUniqueCallinCapture$Batch"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
          </team>
       </aspectBinding>
diff --git a/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/src/org/eclipse/objectteams/otdt/internal/compiler/adaptor/BaseImportChecker.java b/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/src/org/eclipse/objectteams/otdt/internal/compiler/adaptor/BaseImportChecker.java
index d5b7984..df47f67 100644
--- a/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/src/org/eclipse/objectteams/otdt/internal/compiler/adaptor/BaseImportChecker.java
+++ b/plugins/org.eclipse.objectteams.otdt.compiler.adaptor/src/org/eclipse/objectteams/otdt/internal/compiler/adaptor/BaseImportChecker.java
@@ -46,6 +46,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
 import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
 
 import base org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
@@ -235,7 +236,8 @@
 			return Collections.emptyList();
 		}
 		private void addTeamNames(ReferenceBinding type, List<String> names) {
-			names.add(String.valueOf(type.readableName()));
+			char[] binaryName = CharOperation.concatWith(type.compoundName, '.');
+			names.add(String.valueOf(CharOperation.replace(binaryName, IOTConstants.OT_DELIM_NAME, new char[0])));
 			for (ReferenceBinding member : type.memberTypes())
 				if (member != null && member.isTeam())
 					addTeamNames(member, names);
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/PDELaunchingAdaptor.java b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/PDELaunchingAdaptor.java
index 75752d2..10df9dc 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/PDELaunchingAdaptor.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/PDELaunchingAdaptor.java
@@ -54,30 +54,34 @@
 	/** Mediating between LauncherTab and JREBlock: */
 	LauncherTab currentTab = null;
 	
-	static final String OSGI_EXTENSIONS       = "-Dosgi.framework.extensions=reference:file:"; //$NON-NLS-1$
-	static final String OTEQUINOX_HOOK 		  = "org.eclipse.objectteams.otequinox.hook";
-	static final String HOOK_CONFIGURATOR     = "-Dosgi.hook.configurators.include=org.eclipse.objectteams.otequinox.hook.HookConfigurator";//$NON-NLS-1$
-	static final String CLASSLOADER_LOCKING   = "-Dosgi.classloader.lock=classname"; //$NON-NLS-1$
+//	static final String OSGI_EXTENSIONS       = "-Dosgi.framework.extensions=reference:file:"; //$NON-NLS-1$
+//	static final String OTEQUINOX_HOOK 		  = "org.eclipse.objectteams.otequinox.hook";
+//	static final String HOOK_CONFIGURATOR     = "-Dosgi.hook.configurators.include=org.eclipse.objectteams.otequinox.hook.HookConfigurator";//$NON-NLS-1$
+//	static final String CLASSLOADER_LOCKING   = "-Dosgi.classloader.lock=classname"; //$NON-NLS-1$
 	static final String ENABLE_OTEQUINOX      = "-Dot.equinox=1"; //$NON-NLS-1$     // this also causes the WORKAROUND_REPOSITORY flag being set to true in OTRE.
 	static final String DISABLE_OTEQUINOX     = "-Dot.equinox=false"; //$NON-NLS-1$ // prevents TransformerHook installation and start of TransformerPlugin
 	static final String OT_DEBUG_VMARG        = "-Dot.debug"; //$NON-NLS-1$
 	static final String OTE_AGENT_ARG		  = "-javaagent:" + OTREContainer.getOtequinoxAgentJarPath().toOSString();
 	// slot [0] to be filled in from the launch config:
-	static final String[] OT_VM_ARGS          = { null, HOOK_CONFIGURATOR, CLASSLOADER_LOCKING, ENABLE_OTEQUINOX };
-	static final String[] OT_VM_DEBUG_ARGS    = { null, HOOK_CONFIGURATOR, CLASSLOADER_LOCKING, ENABLE_OTEQUINOX, OT_DEBUG_VMARG, OTE_AGENT_ARG };
-	static final String[] VM_ARGS          = { CLASSLOADER_LOCKING, DISABLE_OTEQUINOX };
-	static final String[] VM_DEBUG_ARGS    = { CLASSLOADER_LOCKING, DISABLE_OTEQUINOX, OT_DEBUG_VMARG };
+	static final String[] OT_VM_ARGS          = { ENABLE_OTEQUINOX };
+	static final String[] OT_VM_DEBUG_ARGS    = { ENABLE_OTEQUINOX, OT_DEBUG_VMARG, OTE_AGENT_ARG };
+	static final String[] VM_ARGS          = { DISABLE_OTEQUINOX };
+	static final String[] VM_DEBUG_ARGS    = { DISABLE_OTEQUINOX, OT_DEBUG_VMARG };
+//	static final String[] OT_VM_ARGS          = { null, HOOK_CONFIGURATOR, CLASSLOADER_LOCKING, ENABLE_OTEQUINOX };
+//	static final String[] OT_VM_DEBUG_ARGS    = { null, HOOK_CONFIGURATOR, CLASSLOADER_LOCKING, ENABLE_OTEQUINOX, OT_DEBUG_VMARG, OTE_AGENT_ARG };
+//	static final String[] VM_ARGS          = { CLASSLOADER_LOCKING, DISABLE_OTEQUINOX };
+//	static final String[] VM_DEBUG_ARGS    = { CLASSLOADER_LOCKING, DISABLE_OTEQUINOX, OT_DEBUG_VMARG };
 
 	/** select proper set of arguments for an OT-launch, insert otequinox.hook using it's actual install location. */
 	static String[] getOTArgs(ISharedPluginModel hookModel, String mode) {
 		String[] otArgs = OT_VM_ARGS;
 		if (mode != null && mode.equals(ILaunchManager.DEBUG_MODE))
 			otArgs = OT_VM_DEBUG_ARGS;
-		if (hookModel == null) {
-			OTDebugAdaptorPlugin.logError("Required fragment "+OTEQUINOX_HOOK+" not found");
-			return null;
-		}
-		otArgs[0] = OSGI_EXTENSIONS+hookModel.getInstallLocation();
+//		if (hookModel == null) {
+//			OTDebugAdaptorPlugin.logError("Required fragment "+OTEQUINOX_HOOK+" not found");
+//			return null;
+//		}
+//		otArgs[0] = OSGI_EXTENSIONS+hookModel.getInstallLocation();
 		return otArgs;
 	}
 	/** 
@@ -186,7 +190,7 @@
 		{
 			String[] args = base.extendVMArguments(config);
 			if (isOTLaunch(config))
-				return PDELaunchingAdaptor.extendVMArguments(args, getBundle(OTEQUINOX_HOOK), this.mode);
+				return PDELaunchingAdaptor.extendVMArguments(args, null /*getBundle(OTEQUINOX_HOOK)*/, this.mode);
 			else
 				return PDELaunchingAdaptor.addDisableOTEquinoxArgument(args);
 		}
@@ -223,7 +227,7 @@
 		{
 			String result = base.extendVMArgument(config);
 			if (isOTLaunch(config))
-				return PDELaunchingAdaptor.extendVMArguments(result, getBundle(OTEQUINOX_HOOK), this.mode);
+				return PDELaunchingAdaptor.extendVMArguments(result, null /*getBundle(OTEQUINOX_HOOK)*/, this.mode);
 			else
 				return result+' '+DISABLE_OTEQUINOX;
 		}
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.debug.ui/META-INF/MANIFEST.MF
index ed445a6..5b72b1e 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.debug.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.debug.ui;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: org.eclipse.objectteams.otdt.debug.ui.OTDebugUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.ui/src/org/eclipse/objectteams/otdt/debug/ui/internal/actions/OTBreakpointLocationVerifierJob.java b/plugins/org.eclipse.objectteams.otdt.debug.ui/src/org/eclipse/objectteams/otdt/debug/ui/internal/actions/OTBreakpointLocationVerifierJob.java
index 5f33152..49ff88f 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.ui/src/org/eclipse/objectteams/otdt/debug/ui/internal/actions/OTBreakpointLocationVerifierJob.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug.ui/src/org/eclipse/objectteams/otdt/debug/ui/internal/actions/OTBreakpointLocationVerifierJob.java
@@ -41,6 +41,7 @@
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.TextSelection;
+import org.eclipse.objectteams.otdt.core.ext.OTDTPlugin;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IEditorPart;
@@ -135,6 +136,12 @@
             }
             options.put(JavaCore.COMPILER_COMPLIANCE, compilerCompliance);
             options.put(JavaCore.COMPILER_SOURCE, compilerSource);
+//{ObjectTeams: copy one more option to ensure proper parsing:
+            if (project != null) {
+	            String isPureJava = project.getOption(OTDTPlugin.OT_COMPILER_PURE_JAVA, true);
+	            options.put(OTDTPlugin.OT_COMPILER_PURE_JAVA, isPureJava);
+            }
+// SH}
 			parser.setCompilerOptions(options);
 		}
 		CompilationUnit compilationUnit= (CompilationUnit)parser.createAST(null);
diff --git a/plugins/org.eclipse.objectteams.otdt.jdt.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.jdt.ui/META-INF/MANIFEST.MF
index 74a451a..d842ea4 100644
--- a/plugins/org.eclipse.objectteams.otdt.jdt.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.jdt.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.jdt.ui;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Require-Bundle: org.eclipse.jdt.ui;bundle-version="[3.7.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.7.0,4.0.0)",
  org.eclipse.core.resources;bundle-version="[3.7.0,4.0.0)",
@@ -26,8 +26,14 @@
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy
 Bundle-Localization: plugin
-Export-Package: org.eclipse.objectteams.otdt.internal.ui.assist;x-friends:="org.eclipse.objectteams.otdt.ui.tests",
- org.eclipse.objectteams.otdt.internal.ui.javaeditor;x-internal:=true,
- org.eclipse.objectteams.otdt.internal.ui.packageview;x-friends:="org.eclipse.objectteams.otdt.ui.tests",
- org.eclipse.objectteams.otdt.internal.ui.viewsupport;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui";x-internal:=true
+Export-Package: org.eclipse.objectteams.otdt.internal.ui.assist;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui";x-friends:="org.eclipse.objectteams.otdt.ui.tests",
+ org.eclipse.objectteams.otdt.internal.ui.packageview;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui";x-friends:="org.eclipse.objectteams.otdt.ui.tests",
+ org.eclipse.objectteams.otdt.internal.ui.javaeditor;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui",
+ org.eclipse.objectteams.otdt.internal.ui.util;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui",
+ org.eclipse.objectteams.otdt.internal.ui.search;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui",
+ org.eclipse.objectteams.otdt.internal.ui.viewsupport;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui",
+ org.eclipse.objectteams.otdt.internal.corext;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui",
+ org.eclipse.objectteams.otdt.internal.ui.text;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui",
+ org.eclipse.objectteams.otdt.internal.ui.compare;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui",
+ org.eclipse.objectteams.otdt.internal.ui.typehierarchy;ot-aspect-host="org.eclipse.objectteams.otdt.jdt.ui"
 
diff --git a/plugins/org.eclipse.objectteams.otdt.jdt.ui/plugin.xml b/plugins/org.eclipse.objectteams.otdt.jdt.ui/plugin.xml
index 0e46720..e5c93be 100644
--- a/plugins/org.eclipse.objectteams.otdt.jdt.ui/plugin.xml
+++ b/plugins/org.eclipse.objectteams.otdt.jdt.ui/plugin.xml
@@ -134,7 +134,7 @@
         </team>
         <team
               activation="NONE"
-              class="org.eclipse.objectteams.otdt.internal.ui.assist.CompletionAdaptor.CreateMethodMappingCompletionProposal"
+              class="org.eclipse.objectteams.otdt.internal.ui.assist.CompletionAdaptor$CreateMethodMappingCompletionProposal"
               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
         </team>
         <team
@@ -198,7 +198,7 @@
         </team>
         <team
               activation="NONE"
-              class="org.eclipse.objectteams.otdt.internal.ui.viewsupport.MarkerViewAdaptor.MarkersViewLifeCycle.MarkersView"
+              class="org.eclipse.objectteams.otdt.internal.ui.viewsupport.MarkerViewAdaptor$MarkersViewLifeCycle$MarkersView"
               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
         </team>
      </aspectBinding>
diff --git a/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/assist/BaseImportRewriting.java b/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/assist/BaseImportRewriting.java
index 63927c7..6ed95af 100644
--- a/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/assist/BaseImportRewriting.java
+++ b/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/assist/BaseImportRewriting.java
@@ -40,6 +40,7 @@
 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.objectteams.otdt.internal.corext.RoleFileAdaptor;
@@ -47,8 +48,8 @@
 import base org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
 import base org.eclipse.jdt.internal.codeassist.CompletionEngine;
 import base org.eclipse.jdt.internal.codeassist.InternalCompletionProposal;
+import base org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleTypeReference;
 import base org.eclipse.jdt.internal.codeassist.complete.CompletionParser;
-import base org.eclipse.jdt.internal.compiler.ast.TypeReference;
 
 /**
  * This team advises the completion engine et al to produce base-imports if appropriate.
@@ -102,8 +103,9 @@
 		
 		/** Entry (output) conditionally passing data to next role. */
 		void checkRecordBaseclassReference(CompletionOnBaseTypeRef ref)
-			<- after TypeReference createSingleAssistTypeReference(char[] assistName, long position) 
-			with { ref <- result }
+			<- after TypeReference createSingleAssistTypeReference(char[] assistName, long position)
+			base when (result instanceof CompletionOnSingleTypeReference)
+			with { ref <- (CompletionOnSingleTypeReference)result }
 		void checkRecordBaseclassReference(CompletionOnBaseTypeRef ref) {
 			if (!this.nextIsBaseclass)
 				// not within required context, cancel the role:
@@ -115,7 +117,7 @@
 	 * This role is registered by lifting in {@link CompletionParser#checkRecordBaseclassReference(CompletionOnBaseTypeRef)}.
 	 * Its presence marks a type reference as completion on base class.
 	 */
-	protected class CompletionOnBaseTypeRef	playedBy TypeReference
+	protected class CompletionOnBaseTypeRef	playedBy CompletionOnSingleTypeReference
 		base when (BaseImportRewriting.this.hasRole(base, CompletionOnBaseTypeRef.class))
 	{
 		/** adjust pretty printing for testing and debugging. */
diff --git a/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/javaeditor/JavaEditorAdaptor.java b/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/javaeditor/JavaEditorAdaptor.java
index 529f73b..7eb7cfc 100644
--- a/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/javaeditor/JavaEditorAdaptor.java
+++ b/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/javaeditor/JavaEditorAdaptor.java
@@ -31,7 +31,7 @@
 import org.eclipse.ui.texteditor.ITextEditor;

 import org.eclipse.objectteams.otdt.core.OTModelManager;

 import org.eclipse.objectteams.otdt.internal.ui.javaeditor.RoleOverrideIndicatorManager;
-

+
 import base org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;

 import base org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;

 import base org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
diff --git a/plugins/org.eclipse.objectteams.otdt.pde.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.pde.ui/META-INF/MANIFEST.MF
index 0b438d2..f9c31ee 100644
--- a/plugins/org.eclipse.objectteams.otdt.pde.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.pde.ui/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %pluginName
 Bundle-Vendor: %providerName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.pde.ui;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: org.eclipse.objectteams.otdt.internal.pde.ui.OTPDEUIPlugin
 Require-Bundle: org.eclipse.ui;bundle-version="[3.7.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.7.0,4.0.0)",
diff --git a/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTPDEUIMessages.java b/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTPDEUIMessages.java
index 833bc66..6b4b30e 100644
--- a/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTPDEUIMessages.java
+++ b/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTPDEUIMessages.java
@@ -47,6 +47,12 @@
 
 	public static String ToggleOTSupportAction_configurationError_title;
 
+
+	public static String Validation_MissingAspectPackageExport_error;
+
+	public static String Resolution_AddAspectPackageExport_label;
+	public static String Resolution_AddAspectPackageExport_description;
+
 	static {
 		NLS.initializeMessages(BUNDLE_NAME, OTPDEUIMessages.class);
 	}
diff --git a/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTPDEUIMessages.properties b/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTPDEUIMessages.properties
index d5ef37e..2b00b86 100644
--- a/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTPDEUIMessages.properties
+++ b/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTPDEUIMessages.properties
@@ -13,5 +13,12 @@
 
 Validation_UnresolveBasePlugin_error=Base plug-in {0} cannot be resolved
 
+Validation_MissingAspectPackageExport_error=Package {0} containing one or more bound teams must be exported.
+Resolution_AddAspectPackageExport_label=Export aspect package {0}
+Resolution_AddAspectPackageExport_description=For binding teams of package {0} to their bases\n\
+the following export must be inserted:\n\
+Export-Package: {1}
+
 ToggleOTSupportAction_configurationError_message=Error Configuring Project {0}.
 ToggleOTSupportAction_configurationError_title=Project Configuration Error
+
diff --git a/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/validation/BundleValidation.java b/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/validation/BundleValidation.java
index c886988..6e0f0ca 100644
--- a/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/validation/BundleValidation.java
+++ b/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/validation/BundleValidation.java
@@ -18,6 +18,9 @@
 
 import static org.eclipse.objectteams.otequinox.Constants.*;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.objectteams.otdt.internal.pde.ui.OTPDEUIMessages;
 import org.eclipse.objectteams.otequinox.ActivationKind;
@@ -30,12 +33,13 @@
 import org.eclipse.pde.internal.core.text.bundle.BundleModel;
 import org.eclipse.pde.internal.ui.correction.AbstractManifestMarkerResolution;
 import org.eclipse.pde.internal.ui.correction.AbstractPDEMarkerResolution;
+import org.eclipse.pde.internal.ui.correction.AddExportPackageMarkerResolution;
 import org.eclipse.ui.IMarkerResolution;
 import org.osgi.framework.Constants;
 import org.eclipse.osgi.service.resolver.BundleDescription;
 import org.eclipse.osgi.service.resolver.State;
+import org.eclipse.osgi.util.ManifestElement;
 import org.eclipse.osgi.util.NLS;
-
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
@@ -59,6 +63,8 @@
 {
 	/** Constant for a problem that can be resolved by adding an activation policy to the manifest. */
 	static final int ADD_ACTIVATION_POLICY = 0x1801; // must not overlap with any constant in org.eclipse.pde.internal.core.builders.PDEMarkerFactory. 
+	/** Constant for a problem that can be resolved by adding an activation policy to the manifest. */
+	static final int ADD_PACKAGE_EXPORT = 0x1802; // must not overlap with any constant in org.eclipse.pde.internal.core.builders.PDEMarkerFactory. 
 	
 	ThreadLocal<BundleCheckingContext> bundleContext = new ThreadLocal<BundleCheckingContext>();
 	
@@ -72,6 +78,7 @@
 		// flags set during validation of one bundle:
 		protected boolean isAspectBundle = false;
 		protected boolean hasTeamActivation = false;
+		protected List<String> aspectPackages = new ArrayList<String>();
 
 		@SuppressWarnings("decapsulation")
 		spanContext <- replace validateFiles;
@@ -131,7 +138,16 @@
 				// check the teams for activation ALL_THREADS or THREAD:
 				NodeList teamNodes = element.getElementsByTagName(TEAM);
 				for (int t=0; t<teamNodes.getLength(); t++) {
-					Object activation = ((Element)teamNodes.item(t)).getAttribute(ACTIVATION);
+					// record aspect packages:
+					Element teamNode = (Element)teamNodes.item(t);
+					Object teamClass = teamNode.getAttribute(CLASS);
+					if (teamClass instanceof String) {
+						String teamName = (String) teamClass;
+						int lastDot = teamName.lastIndexOf('.');
+						context.aspectPackages.add(teamName.substring(0, lastDot));
+					}
+					// team activation?
+					Object activation = teamNode.getAttribute(ACTIVATION);
 					if (ActivationKind.ALL_THREADS.toString().equals(activation)) {
 						context.hasTeamActivation = true;
 						break;
@@ -160,8 +176,11 @@
 			base when (BundleValidation.this.bundleContext.get().isAspectBundle)
 	{			
 		@SuppressWarnings("decapsulation")
+		void addMarkerAttribute(IMarker marker, String attr, String val)
+			-> void addMarkerAttribute(IMarker marker, String attr, String val);
+		@SuppressWarnings("decapsulation")
 		IHeader getHeader(String key) -> IHeader getHeader(String key);
-		void report(String message, int line, int severity, int resolution, String category) 
+		IMarker report(String message, int line, int severity, int resolution, String category) 
 			-> IMarker report(String message, int line, int severity, int resolution, String category);
 		
 		void validateBundleActivatorPolicy() <- after void validateBundleActivatorPolicy();
@@ -181,9 +200,42 @@
 				   hasTeamActivation ? CompilerFlags.ERROR : CompilerFlags.WARNING, 	// only severe if relevant team activation is requested. 
 				   ADD_ACTIVATION_POLICY, 
 				   PDEMarkerFactory.CAT_FATAL);
-		}		
+		}
+
+		void validateExportPackages() <- after void validateExportPackages();
+
+		void validateExportPackages() {
+			List<String> needingExport = bundleContext.get().aspectPackages;
+			if (needingExport.isEmpty()) return;
+			IHeader header = getHeader(Constants.EXPORT_PACKAGE);
+			if (header != null) {
+				ManifestElement[] elements = header.getElements();
+				for (int i = 0; i < elements.length; i++)
+					needingExport.remove(elements[i].getValue());
+			}
+			for (String unmatched : needingExport) {
+				IMarker marker = report(NLS.bind(OTPDEUIMessages.Validation_MissingAspectPackageExport_error, unmatched), 
+						   1, 
+						   CompilerFlags.ERROR, 	// can reduce severity when we have the option to add the export at runtime 
+						   ADD_PACKAGE_EXPORT, 
+						   PDEMarkerFactory.CAT_FATAL);
+				addMarkerAttribute(marker, "package", unmatched); //$NON-NLS-1$
+
+				IHeader aspectBundleName = getHeader(Constants.BUNDLE_SYMBOLICNAME);
+				if (aspectBundleName != null && aspectBundleName.getValue() != null) {
+					String bundleSymbolicName = aspectBundleName.getValue();
+					int semi = bundleSymbolicName.indexOf(';');
+					if (semi != -1)
+						bundleSymbolicName = bundleSymbolicName.substring(0, semi); // strip of attributes/directives like ;singleton:=true
+					addMarkerAttribute(marker, "export", unmatched+";ot-aspect-host=\""+bundleSymbolicName+"\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				}
+				else {
+					addMarkerAttribute(marker, "export", unmatched); //$NON-NLS-1$
+				}
+			}
+		}
 	}
-	
+
 	/** Unbound role: simple rewriting of the manifest to add or correct an activation policy header. */
 	protected class SetActivationPolicyResolution extends AbstractManifestMarkerResolution 
 	{	
@@ -206,6 +258,25 @@
 		}
 	}
 	
+	/** Unbound role: simple rewriting of the manifest to add an Export-Package header. */
+	protected class ExportAspectPackageResolution extends AddExportPackageMarkerResolution {
+		String packageName;
+		String export; // extended version with ot-aspect-host attribute
+		public ExportAspectPackageResolution(IMarker marker) {
+			super(AbstractPDEMarkerResolution.CREATE_TYPE, marker.getAttribute("export", null)); //$NON-NLS-1$
+			this.packageName = marker.getAttribute("package", null); //$NON-NLS-1$
+			this.export = marker.getAttribute("export", null); //$NON-NLS-1$
+		}
+		@Override
+		public String getLabel() {
+			return NLS.bind(OTPDEUIMessages.Resolution_AddAspectPackageExport_label, packageName);
+		}
+		@Override
+		public String getDescription() {
+			return NLS.bind(OTPDEUIMessages.Resolution_AddAspectPackageExport_description, packageName, export);
+		}
+	}
+	
 	/**
 	 * Advise the base class for handling missing/incorrect activation policy 
 	 * (code {@link BundleValidation#ADD_ACTIVATION_POLICY}).
@@ -217,10 +288,12 @@
 		callin IMarkerResolution[] getResolutions(IMarker marker) {
 			IMarkerResolution[] result = base.getResolutions(marker);
 			if (result.length == 0) {
-				int problemID = marker.getAttribute("id", PDEMarkerFactory.NO_RESOLUTION); //$NON-NLS-1$
+				int problemID = marker.getAttribute(PDEMarkerFactory.PROBLEM_ID, PDEMarkerFactory.NO_RESOLUTION);
 				switch (problemID) {
 					case BundleValidation.ADD_ACTIVATION_POLICY :
 						return new IMarkerResolution[] {new SetActivationPolicyResolution(AbstractPDEMarkerResolution.CREATE_TYPE)};
+					case BundleValidation.ADD_PACKAGE_EXPORT :
+						return new IMarkerResolution[] {new ExportAspectPackageResolution(marker) };
 				}
 			}
 			return result;
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.refactoring/META-INF/MANIFEST.MF
index 1d48a7a..ce56649 100644
--- a/plugins/org.eclipse.objectteams.otdt.refactoring/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.refactoring;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.jdt.ui;bundle-version="[3.7.0,4.0.0)",
@@ -18,9 +18,13 @@
  org.eclipse.ltk.ui.refactoring;bundle-version="[3.4.1,4.0.0)",
  org.eclipse.objectteams.otdt;bundle-version="[2.0.0,3.0.0)",
  org.eclipse.objectteams.otdt.jdt.ui;bundle-version="[2.1.0,3.0.0)"
-Export-Package: org.eclipse.objectteams.otdt.internal.refactoring.adaptor.extractmethod;x-internal:=true,
+Export-Package: org.eclipse.objectteams.otdt.internal.refactoring.adaptor;x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.refactoring.adaptor.extractmethod;x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup;x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pushdown;x-internal:=true,
  org.eclipse.objectteams.otdt.internal.refactoring.corext;x-internal:=true,
  org.eclipse.objectteams.otdt.internal.refactoring.corext.base;x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.refactoring.corext.rename;x-internal:=true,
  org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.extractcallin;x-internal:=true,
  org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.inlinecallin;x-internal:=true,
  org.eclipse.objectteams.otdt.internal.refactoring.otrefactorings.rolefile;x-friends:="org.eclipse.objectteams.otdt.ui.tests.refactoring",
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.xml b/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.xml
index 6f75a3e..aae5a9e 100644
--- a/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.xml
+++ b/plugins/org.eclipse.objectteams.otdt.refactoring/plugin.xml
@@ -15,7 +15,7 @@
          </team>
          <team
                activation="NONE"
-               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.RenameAdaptor.OTNodeAdjustments"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.RenameAdaptor$OTNodeAdjustments"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
          </team>
          <team
@@ -45,7 +45,7 @@
          </team>
          <team
                activation="NONE"
-               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup.PullUpAdaptor.PullUpRefactoringProcessorRole"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup.PullUpAdaptor$PullUpRefactoringProcessorRole"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
          </team>
          <team
@@ -85,7 +85,7 @@
          </team>
          <team
                activation="NONE"
-               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.ExtractInterfaceAdaptor.Processor"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.ExtractInterfaceAdaptor$Processor"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
          </team>
          <team
@@ -95,7 +95,7 @@
          </team>
          <team
                activation="NONE"
-               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.ReorgAdaptor.BaseImporting"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.ReorgAdaptor$BaseImporting"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
          </team>
       </aspectBinding>
@@ -107,12 +107,12 @@
          </basePlugin>
          <team
                activation="NONE"
-               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.MoveAdaptor.MoveCU"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.MoveAdaptor$MoveCU"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
          </team>
          <team
                activation="NONE"
-               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup.PullUpAdaptor.Visibility"
+               class="org.eclipse.objectteams.otdt.internal.refactoring.adaptor.pullup.PullUpAdaptor$Visibility"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
          </team>
       </aspectBinding>
diff --git a/plugins/org.eclipse.objectteams.otdt.samples/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.samples/META-INF/MANIFEST.MF
index 01c4170..9b40b0a 100644
--- a/plugins/org.eclipse.objectteams.otdt.samples/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.samples/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.samples;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: org.eclipse.objectteams.otdt.internal.samples.OTSamplesPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.objectteams.otdt.samples/plugin.xml b/plugins/org.eclipse.objectteams.otdt.samples/plugin.xml
index 564ccc2..0cabce0 100644
--- a/plugins/org.eclipse.objectteams.otdt.samples/plugin.xml
+++ b/plugins/org.eclipse.objectteams.otdt.samples/plugin.xml
@@ -167,7 +167,7 @@
          <team class="org.eclipse.objectteams.otdt.internal.samples.SamplesAdapter"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif"
                activation="ALL_THREADS"/>
-         <team class="org.eclipse.objectteams.otdt.internal.samples.SamplesAdapter.SampleWizardAdapter"
+         <team class="org.eclipse.objectteams.otdt.internal.samples.SamplesAdapter$SampleWizardAdapter"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif"
                activation="NONE"/>
       </aspectBinding>
diff --git a/plugins/org.eclipse.objectteams.otdt/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt/META-INF/MANIFEST.MF
index d401ddf..9760408 100644
--- a/plugins/org.eclipse.objectteams.otdt/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otdt;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-ClassPath: otdtcoreext.jar
 Bundle-Activator: org.eclipse.objectteams.otdt.core.ext.OTDTPlugin
 Bundle-Vendor: %providerName
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/OTDTPlugin.java b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/OTDTPlugin.java
index 0ba2b62..bce0d77 100644
--- a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/OTDTPlugin.java
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/OTDTPlugin.java
@@ -221,7 +221,17 @@
 	 */	
 	public static final String OT_COMPILER_UNUSED_PARAMMAP =  PLUGIN_ID + ".compiler.problem.unused_parammap";
 
-
+	/**
+	 * Compiler option ID: Parse pure Java (disabling OT/J keywords).
+	 * This is not normally set by clients but initialized from the project nature.
+	 * <dl>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String OT_COMPILER_PURE_JAVA = PLUGIN_ID + ".compiler.option.pure_java";
+	
     private static OTDTPlugin _singleton = null;
 
 
diff --git a/plugins/org.eclipse.objectteams.otequinox.branding/.project b/plugins/org.eclipse.objectteams.otequinox.branding/.project
index b753acd..8d40611 100644
--- a/plugins/org.eclipse.objectteams.otequinox.branding/.project
+++ b/plugins/org.eclipse.objectteams.otequinox.branding/.project
@@ -10,9 +10,20 @@
 			<arguments>
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.jdt.core.javanature</nature>
 		<nature>org.eclipse.objectteams.otdt.OTJavaNature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
 	</natures>
 </projectDescription>
diff --git a/plugins/org.eclipse.objectteams.otequinox.branding/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otequinox.branding/META-INF/MANIFEST.MF
index de1184c..44d34d0 100644
--- a/plugins/org.eclipse.objectteams.otequinox.branding/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otequinox.branding/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otequinox.branding;singleton:=true
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.7.0,4.0.0)",
@@ -12,3 +12,4 @@
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy
 Bundle-Activator: org.eclipse.objectteams.otequinox.branding.Activator
+Export-Package: org.eclipse.objectteams.otequinox.internal.branding;x-friends:="org.eclipse.ui.workbench"
diff --git a/plugins/org.eclipse.objectteams.otequinox/.classpath b/plugins/org.eclipse.objectteams.otequinox/.classpath
index 304e861..098194c 100644
--- a/plugins/org.eclipse.objectteams.otequinox/.classpath
+++ b/plugins/org.eclipse.objectteams.otequinox/.classpath
@@ -1,7 +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 kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/plugins/org.eclipse.objectteams.otequinox/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.objectteams.otequinox/.settings/org.eclipse.jdt.core.prefs
index 64ec586..3a4c56d 100644
--- a/plugins/org.eclipse.objectteams.otequinox/.settings/org.eclipse.jdt.core.prefs
+++ b/plugins/org.eclipse.objectteams.otequinox/.settings/org.eclipse.jdt.core.prefs
@@ -1,70 +1,100 @@
-#Thu Mar 12 15:19:36 CET 2009
 eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.compliance=1.7
 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.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
 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.explicitlyClosedAutoCloseable=warning
 org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
 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.includeNullInfoFromAsserts=enabled
 org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
 org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
 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.missingDefaultCase=ignore
 org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
 org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
 org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
 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.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
 org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
 org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
 org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
 org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
 org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
 org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
 org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=enabled
 org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
 org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
 org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=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=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
 org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+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.unusedObjectAllocation=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.unusedTypeParameter=ignore
 org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.objectteams.otdt.compiler.option.pure_java=enabled
diff --git a/plugins/org.eclipse.objectteams.otequinox/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otequinox/META-INF/MANIFEST.MF
index 68de648..e12d8be 100644
--- a/plugins/org.eclipse.objectteams.otequinox/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otequinox/META-INF/MANIFEST.MF
@@ -2,19 +2,15 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.otequinox;singleton:=true
-Bundle-Version: 2.2.0.qualifier
-Bundle-Vendor: %providerName
-Bundle-Localization: plugin
-Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.6.0,4.0.0)",
- org.eclipse.equinox.registry;bundle-version="[3.5.100,4.0.0)",
- org.eclipse.core.jobs;bundle-version="[3.5.100,4.0.0)",
- org.eclipse.osgi;bundle-version="[3.7.0,4.0.0)",
- org.objectweb.asm;bundle-version="[3.3.1,4.0.0)",
- org.eclipse.objectteams.runtime;bundle-version="[2.0.1,3.0.0)";visibility:=reexport
-Import-Package: org.eclipse.core.internal.runtime;resolution:=optional,
- org.eclipse.objectteams.otequinox.hook;version="[2.1.0,3.0.0)"
+Bundle-Version: 2.3.0.qualifier
 Bundle-Activator: org.eclipse.objectteams.otequinox.TransformerPlugin
-Export-Package: org.eclipse.objectteams.otequinox
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.objectteams.runtime;bundle-version="2.3.0";visibility:=reexport,
+ org.eclipse.osgi;bundle-version="3.10.0",
+ org.eclipse.equinox.ds;bundle-version="1.4.100",
+ org.eclipse.jdt.annotation;bundle-version="[1.1.0,2.0.0)";resolution:=optional
+Import-Package: org.osgi.service.component;version="1.2.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
 Bundle-ActivationPolicy: lazy
-
+Export-Package: org.eclipse.objectteams.otequinox
diff --git a/plugins/org.eclipse.objectteams.otequinox/META-INF/p2.inf b/plugins/org.eclipse.objectteams.otequinox/META-INF/p2.inf
index 25b3050..f6e8e6a 100644
--- a/plugins/org.eclipse.objectteams.otequinox/META-INF/p2.inf
+++ b/plugins/org.eclipse.objectteams.otequinox/META-INF/p2.inf
@@ -1,10 +1,7 @@
-instructions.install = \
-	addProgramProperty(propName:osgi.hook.configurators.include,propValue:org.eclipse.objectteams.otequinox.hook.HookConfigurator); \
-	setProgramProperty(propName:osgi.classloader.singleThreadLoads,propValue:false); \
-	setProgramProperty(propName:osgi.classloader.lock,propValue:classname); \
-	setProgramProperty(propName:ot.equinox,propValue:1);
-instructions.uninstall = \
-	removeProgramProperty(propName:osgi.hook.configurators.include,propValue:org.eclipse.objectteams.otequinox.hook.HookConfigurator); \
-	setProgramProperty(propName:osgi.classloader.singleThreadLoads,propValue:); \
-	setProgramProperty(propName:osgi.classloader.lock,propValue:); \
-	setProgramProperty(propName:ot.equinox,propValue:);
+instructions.configure=\
+	org.eclipse.equinox.p2.touchpoint.eclipse.setStartLevel(startLevel:1); \
+    org.eclipse.equinox.p2.touchpoint.eclipse.markStarted(started:true);
+instructions.unconfigure=\
+	org.eclipse.equinox.p2.touchpoint.eclipse.setStartLevel(startLevel:-1); \
+    org.eclipse.equinox.p2.touchpoint.eclipse.markStarted(started:false);
+    
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otequinox/Status.txt b/plugins/org.eclipse.objectteams.otequinox/Status.txt
new file mode 100644
index 0000000..6107204
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/Status.txt
@@ -0,0 +1,26 @@
+See https://bugs.eclipse.org/bugs/show_bug.cgi?id=406518
+
+(0) Register our WeavingHook as early as possible during start-up.
+Done, but need re-thinking. TJ said on equinox-dev: use start level 1
+
+NOTYET:
+-------
+(5) Add dependencies so that each bound base bundle can see:
+    - the OT runtime (package org.objectteams)
+    - the aspect bundle(s) into which the woven code may call
+Pending: dynamically export the aspect package if not statically declared
+
+(8) Subclasses of Thread (and ideally: implementors of Runnable, the latter
+    has not yet been realized) need to be woven to insert a trigger into OT's
+    TeamThreadManager. This mechanism may need to be redesigned entirely.
+
+(10) Detect if more than one version of any bound base bundle is installed.
+    May want to re-think strategy how to handle this case, currently:
+    pick the highest version.
+
+(12) Implement "forced exports", which allows access from an aspect bundle
+    to classes of a base bundle which are not exported from their bundle
+    (subject to checking of aspect permissions, see (9)).
+
+(9) If aspect permission checking is used, we need to veto the loading
+    of classes of any aspect bundle violating the current policy.
diff --git a/plugins/org.eclipse.objectteams.otequinox/about.ini b/plugins/org.eclipse.objectteams.otequinox/about.ini
index 10f4b53..5229b10 100644
--- a/plugins/org.eclipse.objectteams.otequinox/about.ini
+++ b/plugins/org.eclipse.objectteams.otequinox/about.ini
@@ -1,15 +1,12 @@
 aboutText=Object Teams -- Equinox integration (OT/Equinox)\n\
 \n\
-Version: 2.2.0\n\
+Version: 2.3.0\n\
 \n\
-Part of the Eclipse Kepler Simultaneous Release\n\
+Part of the Eclipse Luna Simultaneous Release\n\
 \n\
 (c) Copyright Technical University Berlin and others, 2005, 2013\n\
 Visit http://www.eclipse.org/objectteams\n\
 \n\
-Upon installation, OT/Equinox is enabled in your configuration/config.ini file.\n\
-For instructions on how to temporarily disable OT/Equinox see the instructions at:\n\
-	http://www.objectteams.org/distrib/features.html#otequinox 
 
 
 featureImage=ote_32n.png
diff --git a/plugins/org.eclipse.objectteams.otequinox/bcelpatch/org.apache.bcel.generic.BranchHandle.class b/plugins/org.eclipse.objectteams.otequinox/bcelpatch/org.apache.bcel.generic.BranchHandle.class
new file mode 100644
index 0000000..d882ad3
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/bcelpatch/org.apache.bcel.generic.BranchHandle.class
Binary files differ
diff --git a/plugins/org.eclipse.objectteams.otequinox/bcelpatch/org.apache.bcel.generic.InstructionHandle.class b/plugins/org.eclipse.objectteams.otequinox/bcelpatch/org.apache.bcel.generic.InstructionHandle.class
new file mode 100644
index 0000000..91bfedc
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/bcelpatch/org.apache.bcel.generic.InstructionHandle.class
Binary files differ
diff --git a/plugins/org.eclipse.objectteams.otequinox/build.properties b/plugins/org.eclipse.objectteams.otequinox/build.properties
index e8a500f..9034c45 100644
--- a/plugins/org.eclipse.objectteams.otequinox/build.properties
+++ b/plugins/org.eclipse.objectteams.otequinox/build.properties
@@ -1,3 +1,5 @@
+source.. = src/
+output.. = bin/
 bin.includes = META-INF/,\
                plugin.xml,\
                .,\
@@ -5,10 +7,8 @@
                about.ini,\
                ote_32n.png,\
                plugin.properties,\
-               about.html
-jars.compile.order = .
+               about.html,\
+               bcelpatch/
 src.includes = schema/,\
                about.ini
-source.. = src/
-jre.compilation.profile = J2SE-1.5
 javacProjectSettings=true
diff --git a/plugins/org.eclipse.objectteams.otequinox/schema/aspectBindings.exsd b/plugins/org.eclipse.objectteams.otequinox/schema/aspectBindings.exsd
index 7ed4fb7..6a1c4e8 100644
--- a/plugins/org.eclipse.objectteams.otequinox/schema/aspectBindings.exsd
+++ b/plugins/org.eclipse.objectteams.otequinox/schema/aspectBindings.exsd
@@ -143,7 +143,7 @@
                   Fully qualified name of a team class.
                </documentation>
                <appInfo>
-                  <meta.attribute kind="java" basedOn=":org.objectteams.ITeam"/>
+                  <meta.attribute kind="java" basedOn="org.objectteams.Team"/>
                </appInfo>
             </annotation>
          </attribute>
@@ -153,7 +153,7 @@
                   Fully qualified name of the team&apos;s super-class if that is not org.objectteams.Team but another team of the same plugin.
                </documentation>
                <appInfo>
-                  <meta.attribute kind="java" basedOn=":org.objectteams.ITeam"/>
+                  <meta.attribute kind="java" basedOn="org.objectteams.Team"/>
                </appInfo>
             </annotation>
          </attribute>
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java
new file mode 100644
index 0000000..e2cc2d8
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java
@@ -0,0 +1,348 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2009, 2013 Germany and Technical University Berlin, Germany and others.
+ * 
+ * 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
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 		Technical University Berlin - Initial API and implementation
+ * 		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.otequinox.TransformerPlugin.log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.internal.osgi.weaving.Util.ProfileKind;
+import org.eclipse.objectteams.otequinox.ActivationKind;
+import org.objectteams.Team;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.hooks.weaving.WovenClass;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Capability;
+
+/** 
+ * Each instance of this class represents the information read from one extension to org.eclipse.objectteams.otequinox.aspectBindings.
+ * Already during {@link AspectBindingRegistry#loadAspectBindings()} the string based information is resolved into instances
+ * of {@link TeamBinding} and {@link BaseBundle}.
+ * @author stephan
+ * @since 1.3.0 (was a nested class before that) 
+ */
+@NonNullByDefault
+public class AspectBinding {
+
+	/**
+	 * Attribute for exports and dynamic imports making the team visible to its adapted base classes.
+	 * The bundle id of the aspect bundle is used as the attribute value to disambiguate between
+	 * multiple same-names packages from different bundles. 
+	 */
+	static final String OT_ASPECT_HOST_ATTRIBUTE = "ot-aspect-host";
+
+	class TeamBinding {
+
+		String teamName;
+		@Nullable Class<? extends Team> teamClass;
+
+		@Nullable String superTeamName;
+		@Nullable TeamBinding superTeam;
+		final List<TeamBinding> subTeams = new ArrayList<>();
+		Set<TeamBinding> equivalenceSet = new HashSet<>();
+
+		ActivationKind activation;
+		boolean hasScannedBases;
+		boolean isActivated;
+
+		boolean importsAdded;
+		boolean importsAddedToSuper;
+		boolean importsAddedToSub;
+
+		final List<String> baseClassNames = new ArrayList<>();
+
+		public TeamBinding(String teamName, ActivationKind activationKind, @Nullable String superTeamName) {
+			this.teamName = teamName;
+			this.activation = activationKind;
+			this.superTeamName = superTeamName;
+			this.equivalenceSet.add(this);
+		}
+
+		/** After scanning class file attributes: add the names of all bound base classes. */
+		public void addBaseClassNames(Collection<String> baseClassNames) {
+			this.baseClassNames.addAll(baseClassNames);
+			for (String baseClassName : baseClassNames) {
+				Set<TeamBinding> teams = baseBundle.teamsPerBase.get(baseClassName);
+				if (teams == null)
+					baseBundle.teamsPerBase.put(baseClassName, teams = new HashSet<>());
+				teams.add(this);
+			}
+		}
+
+		@SuppressWarnings("unchecked")
+		public @Nullable Class<? extends Team> loadTeamClass(Bundle fallbackBundle) {
+			if (teamClass != null) return teamClass;
+			for (String candidate : TeamLoader.possibleTeamNames(teamName)) {
+				try {
+					Bundle aspectBundle = AspectBinding.this.aspectBundle;
+					// FIXME: no aspectBundle if no PackageAdmin was found, is using the fallbackBundle OK?
+					if (aspectBundle == null)
+						aspectBundle = fallbackBundle;
+					Class<?> result = aspectBundle.loadClass(candidate);
+					if (result != null)
+						return this.teamClass = (Class<? extends Team>) result;
+				} catch (NoClassDefFoundError|ClassNotFoundException e) {
+					e.printStackTrace();
+					// keep looking
+				}
+			}
+			return null;
+		}
+
+		/**
+		 * Add imports to this team's package into the bundle of the given base class.
+		 * @param baseClass
+		 * @param direction 1 means traveling to supers, -1 means traveling to subs, 0 comprises both
+		 */
+		public void addImportTo(WovenClass baseClass, int direction) {
+			importsAdded = true;
+			
+			String packageOfTeam = "";
+			int dot = teamName.lastIndexOf('.'); // TODO: can we detect if thats really the package (vs. Outer.Inner)?
+			if (dot != -1)
+				packageOfTeam = teamName.substring(0, dot);
+			String packageWithAttribute = packageOfTeam+";"+OT_ASPECT_HOST_ATTRIBUTE+"=\""+aspectPlugin+"\"";
+			
+			if (!OTWeavingHook.hasImport(baseClass, packageOfTeam, packageWithAttribute)) {	
+				checkExported: {
+					List<String> imports = baseClass.getDynamicImports();
+					Bundle aspectBundle = AspectBinding.this.aspectBundle;
+					BundleRevision bundleRevision = aspectBundle != null ? aspectBundle.adapt(BundleRevision.class) : null;
+					if (bundleRevision != null) { // catch uninstalled state
+						for (Capability capability : bundleRevision.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE)) {
+							Object exported = capability.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+							if (exported instanceof String && exported.equals(packageOfTeam)) {
+								if (capability.getAttributes().containsKey(OT_ASPECT_HOST_ATTRIBUTE)) {
+									imports.add(packageWithAttribute);
+								} else {
+									log(IStatus.WARNING, "Package "+packageOfTeam+" for team "+teamName.substring(dot+1)+" is exported without an 'ot-aspect-host' attribute.");
+									imports.add(packageOfTeam);
+								}
+								break checkExported;
+							}
+						}
+						log(IStatus.ERROR, "Package "+packageOfTeam+" for team "+teamName.substring(dot+1)+" is not exported by its bundle "+aspectPlugin);
+					} else {
+						log(IStatus.WARNING, "Can't check exporting of "+teamName+", bundle information for "+aspectPlugin+" is not available");
+					}
+				}
+				log(IStatus.INFO, "Added dependency from base "+baseClass.getClassName()+" to package '"+packageOfTeam+"'");
+			}
+			if (direction != -1) {
+				importsAddedToSuper = true;
+				final TeamBinding superTeam2 = superTeam;
+				if (superTeam2 != null)
+					superTeam2.addImportTo(baseClass, 1);
+			}
+			if (direction != 1) {
+				importsAddedToSub = true;
+				for (TeamBinding subTeam : subTeams)
+					subTeam.addImportTo(baseClass, -1);
+			}
+		}
+
+		/** Has all work for this team been done? */
+		public boolean isDone() { // TODO travel up/down?
+			if (activation != ActivationKind.NONE && !isActivated)
+				return false;
+			if (!(importsAdded && importsAddedToSub && importsAddedToSuper))
+				return false;
+			return true;
+		}
+
+		@Override
+		public String toString() {
+			return "team "+teamName+"("+(this.activation)+") super "+superTeamName;
+		}
+	}
+	
+	/**
+	 * Represents a base bundle against which one or more aspectBindings are declared.
+	 * Used to find all teams affecting any given base class in this base bundle.
+	 */
+	static class BaseBundle {
+		String bundleName;
+		/** Team classes indexed by base classes that should trigger activating the team. */
+		private HashMap<String, Set<TeamBinding>> teamsPerBase = new HashMap<>();
+		boolean otreAdded;		
+
+		public BaseBundle(String bundleName) {
+			this.bundleName = bundleName;
+		}
+	}
+	
+	public String aspectPlugin;
+	public @Nullable Bundle aspectBundle; // null if we don't have a PackageAdmin for bundle lookup
+	public String basePluginName;
+	public BaseBundle baseBundle;
+	public @Nullable IConfigurationElement[] forcedExports; // not yet evaluated
+	public TeamBinding[]   teams;
+
+	public boolean hasScannedTeams;
+	
+	Set<TeamBinding> teamsInProgress = new HashSet<>(); // TODO cleanup teams that are done
+	
+	public AspectBinding(String aspectId, @Nullable Bundle aspectBundle, BaseBundle baseBundle, @Nullable IConfigurationElement[] forcedExportsConfs, int count) 
+	{
+		this.aspectPlugin= aspectId;
+		this.aspectBundle= aspectBundle;
+		this.baseBundle=     baseBundle;
+		this.basePluginName= baseBundle.bundleName;
+		this.forcedExports= forcedExportsConfs;
+		
+		this.teams = new TeamBinding[count];
+	}
+
+	/** Create an initial (unconnected) resolved team binding. */
+	public TeamBinding createResolvedTeam(int count, String teamName, @Nullable String activationSpecifier, @Nullable String superTeamName) {
+		ActivationKind kind = ActivationKind.NONE;
+		try {
+			if (activationSpecifier != null)
+				kind = ActivationKind.valueOf(activationSpecifier);
+		} catch (IllegalArgumentException iae) {	
+			log(iae, "Invalid activation kind "+activationSpecifier+" for team "+teamName);
+		}
+		return this.teams[count] = new TeamBinding(teamName, kind, superTeamName);
+	}
+
+	/** Connect all resolvable info in all contained TeamBindings using the given lookup table. */
+	public void connect(Map<String, Set<TeamBinding>> teamLookup) {
+		for (int i = 0; i < teams.length; i++) {
+			TeamBinding team = teams[i];
+
+			// do we have TeamBindings representing the same team class (from different aspect bindings)?
+			Set<TeamBinding> equivalenceSet = teamLookup.get(team.teamName);
+			if (equivalenceSet != null)
+				team.equivalenceSet.addAll(equivalenceSet);
+			if (team.equivalenceSet.size() > 1)
+				log(IStatus.INFO, "team "+team.teamName+" participates in "+team.equivalenceSet.size()+" aspect bindings.");
+
+			if (team.superTeamName != null) {
+				Set<TeamBinding> superTeams = teamLookup.get(team.superTeamName);
+				if (superTeams != null) {
+					for (TeamBinding superTeam : superTeams) {
+						team.superTeam = superTeam;
+						superTeam.subTeams.add(team);
+					}
+				} else {
+					Exception e = new Exception("No such aspect binding");
+					log(e, "Class "+team.superTeamName+" not registered (declared to be superclass of team "+team.teamName);
+				}
+			}
+		}		
+	}
+
+	/** Answer the names of teams to load for a given base class. */
+	public synchronized @Nullable Collection<TeamBinding> getTeamsForBase(String baseClassName) {
+		Set<TeamBinding> teams = baseBundle.teamsPerBase.get(baseClassName);
+		// in case any team cannot immediately be instantiated/activated
+		// it will be added to the next queue: OTWeavingHook.deferredTeams.
+		if (teams != null) {
+			teams =  new HashSet<>(teams);
+			teams.removeAll(teamsInProgress); // no double-triggering
+			teamsInProgress.addAll(teams);
+		}
+		return teams;		
+	}
+
+	/** If a given team requires no activation, check if its super team should be activated instead. */
+	public @Nullable TeamBinding getOtherTeamToActivate(TeamBinding team) {
+		TeamBinding superTeam = team.superTeam;
+		if (superTeam != null && superTeam.activation != ActivationKind.NONE) {
+			return superTeam;
+		}
+		// sub teams?
+		return null;
+	}
+
+	/**
+	 * Read OT attributes of all teams in this aspectBinding 
+	 * and collect affected base classes into the teamBindings.
+	 */
+	public synchronized void scanTeamClasses(Bundle bundle) {
+		long time = 0;
+		if (Util.PROFILE) time= System.nanoTime();
+		ClassScanner scanner = new ClassScanner();
+		for (@SuppressWarnings("null")@NonNull TeamBinding team : getAllTeamBindings()) {
+			if (team.hasScannedBases) continue; // not a surprise for members of equivalentSet
+			team.hasScannedBases = true;
+			try {
+				String teamName = scanner.readOTAttributes(bundle, team.teamName);
+				Collection<String> baseClassNames = scanner.getCollectedBaseClassNames();
+				if (team.baseClassNames.isEmpty()) {
+					for (TeamBinding equivalent : team.equivalenceSet)
+						equivalent.addBaseClassNames(baseClassNames);
+				}
+				log(IStatus.INFO, "Scanned team class "+teamName+", found "+baseClassNames.size()+" base classes");
+			} catch (Exception e) {
+				log(e, "Failed to scan team class "+team.teamName);
+			}
+		}
+		this.hasScannedTeams = true;
+		if (Util.PROFILE) Util.profile(time, ProfileKind.Scan, bundle.getSymbolicName());
+	}
+
+	private List<TeamBinding> getAllTeamBindings() {
+		List<TeamBinding> all = new ArrayList<>();
+		for (TeamBinding team : teams) all.add(team);
+		for (int i = 0; i < teams.length; i++) {
+			if (teams[i].superTeam != null)
+				all.add(teams[i].superTeam);
+			all.addAll(teams[i].subTeams);
+		}
+		return all;
+	}
+
+	/** Add all require imports to match the hidden reverse dependency created by any team binding to this base class. */
+	public void addImports(WovenClass baseClass) {
+		String baseClassName = baseClass.getClassName();
+		Set<TeamBinding> teams = baseBundle.teamsPerBase.get(baseClassName);
+		if (teams != null)
+			for (TeamBinding resolvedTeam : teams)
+				resolvedTeam.addImportTo(baseClass, 0); // 0 = travel both directions (sub/super)
+	}
+
+	public void cleanUp(String baseClass) {
+		baseBundle.teamsPerBase.remove(baseClass);
+	}
+
+	public boolean isDone() {
+		for (int i = 0; i < teams.length; i++)
+			if (!teams[i].isDone())
+				return false;
+		return true;
+	}
+
+	public String toString() {
+		String result = "\tbase plugin "+basePluginName+"\n\tadapted by aspect pluging "+aspectPlugin;
+		for (TeamBinding team : teams)
+			result += "\n\t\t "+team.toString();
+		return result;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
new file mode 100644
index 0000000..03f1338
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
@@ -0,0 +1,268 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2008, 2013 Technical University Berlin, Germany and others.
+ *  
+ * 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
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ *	Technical University Berlin - Initial API and implementation
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.otequinox.Constants.ACTIVATION;
+import static org.eclipse.objectteams.otequinox.Constants.ASPECT_BINDING_EXTPOINT_ID;
+import static org.eclipse.objectteams.otequinox.Constants.BASE_PLUGIN;
+import static org.eclipse.objectteams.otequinox.Constants.CLASS;
+import static org.eclipse.objectteams.otequinox.Constants.ID;
+import static org.eclipse.objectteams.otequinox.Constants.REQUIRED_FRAGMENT;
+import static org.eclipse.objectteams.otequinox.Constants.SELF;
+import static org.eclipse.objectteams.otequinox.Constants.SUPERCLASS;
+import static org.eclipse.objectteams.otequinox.Constants.TEAM;
+import static org.eclipse.objectteams.otequinox.Constants.TRANSFORMER_PLUGIN_ID;
+import static org.eclipse.objectteams.otequinox.TransformerPlugin.log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.BaseBundle;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.TeamBinding;
+import org.eclipse.objectteams.otequinox.Constants;
+import org.osgi.framework.Bundle;
+
+/**
+ * An instance of this class holds the information loaded from extensions
+ * to the <code>aspectBindings</code> extension point.
+ */
+// parts of this class are moved from org.eclipse.objectteams.otequinox.TransformerPlugin
+@NonNullByDefault
+public class AspectBindingRegistry {
+	
+	private static List<String> KNOWN_OTDT_ASPECTS = new ArrayList<String>();
+	static {
+		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.jdt.ui");
+		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.compiler.adaptor");
+		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.refactoring");
+		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.pde.ui");
+		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.samples");
+	}
+	/** main internal registry of aspect bindings. */
+	private static HashMap<String, ArrayList<AspectBinding>> aspectBindingsByBasePlugin = 
+			   new HashMap<String, ArrayList<AspectBinding>>();
+	private static HashMap<String, ArrayList<AspectBinding>> aspectBindingsByAspectPlugin = 
+		       new HashMap<String, ArrayList<AspectBinding>>();
+	private Set<String> selfAdaptingAspects= new HashSet<String>(); // TODO, never read / evaluated
+	
+	public static boolean IS_OTDT = false;
+	
+	public boolean isOTDT() {
+		return IS_OTDT;
+	}
+
+	/* Load extensions for org.eclipse.objectteams.otequinox.aspectBindings and check aspect permissions. */
+	public void loadAspectBindings(
+			IExtensionRegistry extensionRegistry,
+			@SuppressWarnings("deprecation") @Nullable org.osgi.service.packageadmin.PackageAdmin packageAdmin,
+			OTWeavingHook hook) 
+	{
+		IConfigurationElement[] aspectBindingConfigs = extensionRegistry
+				.getConfigurationElementsFor(TRANSFORMER_PLUGIN_ID, ASPECT_BINDING_EXTPOINT_ID);
+		Map<String, Set<TeamBinding>> teamLookup = new HashMap<>();
+		Map<String, BaseBundle> baseBundleLookup = new HashMap<>();
+		AspectBinding[] bindings = new AspectBinding[aspectBindingConfigs.length];
+		
+		for (int i = 0; i < aspectBindingConfigs.length; i++) {
+			IConfigurationElement currentBindingConfig = aspectBindingConfigs[i];
+
+			//aspect:
+			@SuppressWarnings("null")@NonNull String aspectBundleId= currentBindingConfig.getContributor().getName();
+			IS_OTDT |= KNOWN_OTDT_ASPECTS.contains(aspectBundleId);
+			Bundle aspectBundle = null;
+			if (packageAdmin != null) {
+				@SuppressWarnings("deprecation")
+				Bundle[] aspectBundles = packageAdmin.getBundles(aspectBundleId, null);
+				if (aspectBundles == null || aspectBundles.length == 0 || (aspectBundles[0].getState() < Bundle.RESOLVED)) {
+					log(IStatus.ERROR, "aspect bundle "+aspectBundleId+" is not resolved - not loading aspectBindings.");
+					continue;
+				}
+				aspectBundle = aspectBundles[0];
+			}
+			
+			//base:
+			IConfigurationElement[] basePlugins = currentBindingConfig.getChildren(BASE_PLUGIN);
+			if (basePlugins.length != 1) {
+				log(IStatus.ERROR, "aspectBinding of "+aspectBundleId+" must declare exactly one basePlugin");
+				continue;
+			}
+			String baseBundleId = basePlugins[0].getAttribute(ID);
+			if (baseBundleId == null) {
+				log(IStatus.ERROR, "aspectBinding of "+aspectBundleId+" must specify the id of a basePlugin");
+				continue;
+			}
+			BaseBundle baseBundle = baseBundleLookup.get(baseBundleId); 
+			if (baseBundle == null)		
+				baseBundleLookup.put(baseBundleId, baseBundle = new BaseBundle(baseBundleId));
+				
+ 			//base fragments?
+			IConfigurationElement[] fragments = basePlugins[0].getChildren(REQUIRED_FRAGMENT);
+			if (fragments != null 
+					&& !checkRequiredFragments(aspectBundleId, baseBundleId, fragments, packageAdmin)) // reported inside
+				continue;
+			
+			IConfigurationElement[] teams = currentBindingConfig.getChildren(TEAM);
+			int teamCount = teams.length;
+			for (int j = 0; j < teams.length; j++) if (teams[j].getAttribute(CLASS) == null) teamCount --;
+			AspectBinding binding = new AspectBinding(aspectBundleId,
+														aspectBundle,
+														baseBundle,
+														basePlugins[0].getChildren(Constants.FORCED_EXPORTS_ELEMENT), 
+														teamCount);
+			bindings[i] = binding;
+			// TODO(SH): maybe enforce that every bundle id is given only once?
+
+			//teams:
+			try {
+				for (int j = 0, count = 0; count < teamCount; j++) {
+					String teamClass = teams[j].getAttribute(CLASS);
+					if (teamClass == null) continue;
+					TeamBinding team = binding.createResolvedTeam(count++, teamClass, teams[j].getAttribute(ACTIVATION), teams[j].getAttribute(SUPERCLASS));
+					Set<TeamBinding> teamSet = teamLookup.get(teamClass);
+					if (teamSet == null)
+						teamLookup.put(teamClass, teamSet = new HashSet<>());
+					teamSet.add(team);
+				}
+				
+				@NonNull String realBaseBundleId = baseBundleId.toUpperCase().equals(SELF) ? aspectBundleId : baseBundleId;
+				addBindingForBaseBundle(realBaseBundleId, binding);
+				addBindingForAspectBundle(aspectBundleId, binding);
+				hook.setBaseTripWire(packageAdmin, realBaseBundleId, baseBundleLookup.get(realBaseBundleId));
+
+				log(IStatus.INFO, "registered:\n"+binding);
+			} catch (Throwable t) {
+				log(t, "Invalid aspectBinding extension");
+			}
+		}
+		// second round to connect sub/super teams to aspect bindings:
+		for (int i = 0; i < bindings.length; i++) {
+			bindings[i].connect(teamLookup);
+		}
+	}
+	
+	@SuppressWarnings("deprecation") // multiple uses of deprecated but still recommended class PackageAdmin
+	private boolean checkRequiredFragments(String aspectBundleId, String baseBundleId, IConfigurationElement[] fragments, 
+			@Nullable org.osgi.service.packageadmin.PackageAdmin packageAdmin) 
+	{
+		// checking only, no real action needed.
+		boolean hasError = false;
+		for (IConfigurationElement fragment : fragments) {
+			String fragId = fragment.getAttribute(ID);
+			if (fragId == null) {
+				log(IStatus.ERROR, "Mandatory attribute \"id\" missing from element \"requiredFragment\" of aspect binding in "+aspectBundleId);
+				return false;
+			} 
+			if (packageAdmin == null) {
+				log(IStatus.ERROR, "Not checking required fragment "+fragId+" in aspect binding of "+aspectBundleId+", package admin service not present");
+				return false; // report only once.
+			}
+			
+			Bundle[] fragmentBundles = packageAdmin.getBundles(fragId, null);
+			if (fragmentBundles == null || fragmentBundles.length == 0) {
+				log(IStatus.ERROR, "Required fragment "+fragId+" not found in aspect binding of "+aspectBundleId);
+				hasError = true;
+				continue;
+			}
+			Bundle fragmentBundle = fragmentBundles[0];
+			String aspectBindingHint = " (aspect binding of "+aspectBundleId+")";
+			if (packageAdmin.getBundleType(fragmentBundle) != org.osgi.service.packageadmin.PackageAdmin.BUNDLE_TYPE_FRAGMENT) {
+				log(IStatus.ERROR, "Required fragment " + fragId + " is not a fragment" + aspectBindingHint);
+				hasError = true;
+				continue;
+			}
+			Bundle[] hosts = packageAdmin.getHosts(fragmentBundle);
+			if (hosts == null || hosts.length == 0) {
+				if (fragmentBundle.getState() < Bundle.RESOLVED) {
+					log(IStatus.ERROR, "Required fragment " + fragId + " is not resolved" + aspectBindingHint);
+					hasError = true;
+					continue;
+				}
+				log(IStatus.ERROR, "Required fragment "+fragId+" has no host bundle"+aspectBindingHint);
+				hasError = true;					
+				continue;
+			}
+			Bundle host = hosts[0];
+			if (!host.getSymbolicName().equals(baseBundleId)) {
+				log(IStatus.ERROR, "Required fragment "+fragId+" has wrong host "+host.getSymbolicName()+aspectBindingHint);
+				hasError = true;
+			}
+		}
+		return !hasError;
+	}
+
+	private static void addBindingForBaseBundle(String baseBundleId, AspectBinding binding) {
+		ArrayList<AspectBinding> bindingList = aspectBindingsByBasePlugin.get(baseBundleId);
+		if (bindingList == null) {
+			bindingList = new ArrayList<AspectBinding>();
+			aspectBindingsByBasePlugin.put(baseBundleId, bindingList);
+		}
+		bindingList.add(binding);
+	}
+
+	private void addBindingForAspectBundle(String aspectBundleId, AspectBinding binding) {
+		ArrayList<AspectBinding> bindingList = aspectBindingsByAspectPlugin.get(aspectBundleId);
+		if (bindingList == null) {
+			bindingList = new ArrayList<AspectBinding>();
+			aspectBindingsByAspectPlugin.put(aspectBundleId, bindingList);
+		}
+		bindingList.add(binding);
+		if (binding.basePluginName.toUpperCase().equals(SELF))
+			selfAdaptingAspects.add(aspectBundleId);
+	}
+	
+
+	/**
+	 * Given a potential aspect bundle, answer the symbolic names of all base bundles
+	 * adapted by the aspect bundle.
+	 */
+	public @Nullable String[] getAdaptedBasePlugins(Bundle aspectBundle) {
+		ArrayList<AspectBinding> bindings = aspectBindingsByAspectPlugin.get(aspectBundle.getSymbolicName());
+		if (bindings == null) return null;
+		String[] basePlugins = new String[bindings.size()];
+		for (int i=0; i<basePlugins.length; i++) {
+			basePlugins[i] = bindings.get(i).basePluginName;
+		}
+		return basePlugins;
+	}
+
+	/** Is `symbolicName' the name of a base plugin for which an adapting team is registered? */
+	public boolean isAdaptedBasePlugin(@Nullable String symbolicName) {
+		ArrayList<AspectBinding> list = aspectBindingsByBasePlugin.get(symbolicName);
+		return list != null && !list.isEmpty();
+	}
+
+	/**
+	 * Get the list of aspect bindings affecting the given base plugin.
+	 */
+	public @Nullable List<AspectBinding> getAdaptingAspectBindings(@Nullable String basePluginName) {
+		return aspectBindingsByBasePlugin.get(basePluginName);
+	}
+
+	public @Nullable List<AspectBinding> getAspectBindings(String aspectBundle) {
+		return aspectBindingsByAspectPlugin.get(aspectBundle);		
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BCELPatcher.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BCELPatcher.java
new file mode 100644
index 0000000..09db6ba
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BCELPatcher.java
@@ -0,0 +1,91 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2013 GK Software AG
+ *  
+ * 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
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.otequinox.TransformerPlugin.log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.zip.CRC32;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.objectteams.otequinox.TransformerPlugin;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.hooks.weaving.WovenClass;
+
+public class BCELPatcher {
+
+	static final String BCEL_PLUGIN_ID = "org.apache.bcel";
+	private static final String BCEL_PATH_DIR = "bcelpatch/";
+
+	public static void fixBCEL(WovenClass clazz) {
+		String name = clazz.getClassName();
+		byte[] classbytes = clazz.getBytes();
+		boolean shouldPatch = false;
+		if ("org.apache.bcel.generic.InstructionHandle".equals(name)) {
+			CRC32 crc32 = new CRC32();
+			crc32.update(classbytes);
+			long crc = crc32.getValue();
+			String detail = "";
+			if (classbytes.length != 0x1623)
+				detail+="\n\tlength="+classbytes.length;	// identify original class
+			if (crc != 0x42132087 && crc != 0xdb1b9859L)	// --""-- (I've seen two versions of this class file, semantically equivalent though)
+				detail+="\n\tcrc="+crc;
+			if (classbytes[0x0F00] != 0x18)
+				detail+="\n\tmodifiers of getInstructionHandle="+classbytes[0xF00];	// modifiers of method getInstructionHandle at "static final"
+			if (classbytes[0x105C] != 0x04)
+				detail+="\n\tmodifiers of addHandle="+classbytes[0x105C];			// modifiers of method getHandle at "protected"
+			if (detail.length() == 0) {
+				shouldPatch = true;
+			} else {
+				log(IStatus.WARNING, "Class org.apache.bcel.generic.InstructionHandle needs a hot-patch but has unexpected byte code:"+detail);
+			}
+		} else if ("org.apache.bcel.generic.BranchHandle".equals(name)) {
+			CRC32 crc32 = new CRC32();
+			crc32.update(classbytes);
+			long crc = crc32.getValue();
+			String detail = "";
+			if (classbytes.length != 0x09F1)
+				detail+="\n\tlength="+classbytes.length;	// identify original class
+			if (crc != 0xd3c37c19L && crc != 0x74bee71eL)	// --""-- (I've seen two versions of this class file, semantically equivalent though)
+				detail+="\n\tcrc="+crc;
+			if (classbytes[0x067E] != 0x18)
+				detail+="\n\tmodifiers of getBranchHandle="+classbytes[0x067E];	// modifiers of method getBranchHandle at "static final"
+			if (classbytes[0x06F8] != 0x04)
+				detail+="\n\tmodifiers of addHandle="+classbytes[0x06F8];		// modifiers of method getHandle at "protected"
+			if (detail.length() == 0) {
+				shouldPatch = true;
+			} else {
+				log(IStatus.WARNING, "Class org.apache.bcel.generic.BranchHandle needs a hot-patch but has unexpected byte code:"+detail);
+			}
+		}
+		if (shouldPatch) {
+			Bundle otequinoxBundle = TransformerPlugin.getBundle();
+			URL entry = otequinoxBundle.getEntry(BCEL_PATH_DIR+name+".class");
+			try (InputStream stream = entry.openStream()) {
+				int len = stream.available();
+				byte[] newBytes = new byte[len];
+				stream.read(newBytes);
+				log(IStatus.INFO, "hot-patched a bug in class "+name+"\n"+
+									"\tsee https://bugs.eclipse.org/bugs/show_bug.cgi?id=344350");
+				clazz.setBytes(newBytes);
+			} catch (IOException e) {
+				log(e, "Failed to hot-patch bcel class "+name);
+			}
+		}
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java
new file mode 100644
index 0000000..d44d63d
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java
@@ -0,0 +1,133 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2013 GK Software AG
+ *  
+ * 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
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.otequinox.TransformerPlugin.log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.BaseBundle;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.hooks.weaving.WovenClass;
+
+/**
+ * Each instance of this class represents the fact that a given base bundle has aspect bindings,
+ * which require to load / instantiate / activate one or more teams at a suitable point in time.
+ */
+@NonNullByDefault
+public class BaseBundleLoadTrigger {
+
+	private AspectBindingRegistry aspectBindingRegistry;
+	@SuppressWarnings("deprecation")
+	private @Nullable org.osgi.service.packageadmin.PackageAdmin admin;
+
+	private String baseBundleName;	
+	@Nullable private BaseBundle baseBundle; // null when representing an aspectBundle with SELF-adapting teams
+	private boolean otreAdded = false;
+	private List<AspectBinding> aspectBindings = new ArrayList<>();
+
+	public BaseBundleLoadTrigger(String bundleSymbolicName, @Nullable BaseBundle baseBundle, AspectBindingRegistry aspectBindingRegistry, 
+			@SuppressWarnings("deprecation") @Nullable org.osgi.service.packageadmin.PackageAdmin admin) 
+	{
+		this.baseBundleName = bundleSymbolicName;
+		this.baseBundle = baseBundle;
+		this.aspectBindingRegistry = aspectBindingRegistry;
+		this.admin = admin;
+	}
+	
+	/**
+	 * Signal that the given class is being loaded and trigger any necessary steps:
+	 * (1) add import to OTRE (now)
+	 * (2) scan team (now)
+	 * (3) add imports base->aspect (now)
+	 * (4) load & instantiate & activate (now or later).
+	 */
+	@SuppressWarnings("deprecation") // uses deprecated PackageAdmin
+	public void fire(WovenClass baseClass, Set<String> beingDefined, OTWeavingHook hook) {
+
+		// (1) OTRE import added once per base bundle:
+		synchronized(this) {
+			final BaseBundle baseBundle2 = baseBundle;
+			if (!otreAdded && !(baseBundle2 != null && baseBundle2.otreAdded)) {
+				otreAdded = true;
+				if (baseBundle2 != null) baseBundle2.otreAdded = true;
+				log(IStatus.INFO, "Adding OTRE import to "+baseBundleName);
+				List<String> imports = baseClass.getDynamicImports();
+				imports.add("org.objectteams");
+			}
+		}
+		
+		// for each team in each aspect binding:
+		if (aspectBindings.isEmpty())
+			aspectBindings.addAll(aspectBindingRegistry.getAdaptingAspectBindings(baseBundleName));
+		List<WaitingTeamRecord> deferredTeamClasses = new ArrayList<>();
+		for (AspectBinding aspectBinding : aspectBindings) {
+			if (!aspectBinding.hasScannedTeams)
+				log(IStatus.INFO, "Preparing aspect binding for base bundle "+baseBundleName);
+			final org.osgi.service.packageadmin.PackageAdmin admin2 = admin;
+			if (admin2 == null) {
+				log(IStatus.ERROR, "Cannot find aspect bundle "+aspectBinding.aspectPlugin);
+				continue;					
+			} else {
+				Bundle aspectBundle = aspectBinding.aspectBundle;
+				if (aspectBundle == null) {
+					Bundle[] aspectBundles = admin2.getBundles(aspectBinding.aspectPlugin, null);
+					if (aspectBundles == null || aspectBundles.length == 0) {
+						log(IStatus.ERROR, "Cannot find aspect bundle "+aspectBinding.aspectPlugin);
+						continue;
+					}
+					aspectBundle = aspectBundles[0];
+					assert aspectBundle != null : "Package admin should not return a null array element";
+				}
+				// (2) scan all teams in affecting aspect bindings:
+				if (!aspectBinding.hasScannedTeams)
+					aspectBinding.scanTeamClasses(aspectBundle);
+				
+				// (3) add dependencies to the base bundle:
+				aspectBinding.addImports(baseClass);
+
+				// (4) try optional steps:
+				TeamLoader loading = new TeamLoader(deferredTeamClasses, beingDefined);
+				loading.loadTeamsForBase(aspectBundle, aspectBinding, baseClass);
+			}
+		}
+
+		// if some had to be deferred collect them now:
+		if (!deferredTeamClasses.isEmpty()) {
+			hook.addDeferredTeamClasses(deferredTeamClasses);
+		}
+
+		// mark done for this base class 
+		// (do outside the look in case multiple aspect bindings point to the same baseBundle)
+		for (AspectBinding aspectBinding : aspectBindings) {
+			String baseClassName = baseClass.getClassName();
+			assert baseClassName != null : "WovenClass.getClassName() should not answer null";
+			aspectBinding.cleanUp(baseClassName);
+		}
+	}
+
+	public boolean isDone() {
+		for (AspectBinding binding : aspectBindings)
+			if (!binding.isDone())
+				return false;
+		return true;
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java
new file mode 100644
index 0000000..61ef558
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java
@@ -0,0 +1,151 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2008, 2013 Technical University Berlin, Germany and others
+ * 
+ * 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
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 		Technical University Berlin - Initial API and implementation
+ * 		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.otequinox.TransformerPlugin.log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
+import org.eclipse.objectteams.otre.util.CallinBindingManager;
+import org.osgi.framework.Bundle;
+
+/**
+ * Simple facility for scanning class files for OT Attributes without
+ * actually doing any weaving.
+ * 
+ * @author stephan
+ * @since 1.2.0
+ */
+@SuppressWarnings("nls")
+@NonNullByDefault
+public class ClassScanner 
+{
+	// default is "on", leave this switch for trouble shooting and profiling:
+	public static final boolean REPOSITORY_USE_RESOURCE_LOADER = !"off".equals(System.getProperty("otequinox.repository.hook"));
+
+	// collect class names recorded by readOTAttributes:
+	
+	//   * this version used by the MasterTeamLoader.loadTeams:
+	HashMap<String,ArrayList<String>> baseClassNamesByTeam = new HashMap<String, ArrayList<String>>();
+	//   * these fields used by TransformerHook.processClass (collected over multiple readOTAttributes):
+	ArrayList<String> allBaseClassNames = new ArrayList<String>();
+	ArrayList<String> roleClassNames = new ArrayList<String>();
+
+
+	/** 
+	 * Read all OT byte code attributes for the specified class.
+	 * While doing so the names of roles and adapted base classes are collected.
+	 * 
+	 * @param bundle    where to look
+	 * @param className the class to investigate (team or role)
+	 * @param loader    the loader (could be null) to use for further classFile lookup
+	 * @return the real class name (potentially involving '$' and '__OT__' substitution/insertion
+	 * @throws ClassFormatError
+	 * @throws IOException
+	 * @throws ClassNotFoundException the team or role class was not found
+	 */
+	public String readOTAttributes(Bundle bundle, String className)
+			throws ClassFormatError, IOException, ClassNotFoundException 
+	{
+		Object loader = REPOSITORY_USE_RESOURCE_LOADER ? bundle : null;
+		Pair<URL,String> result = TeamLoader.findTeamClassResource(className, bundle);
+		if (result == null)
+			throw new ClassNotFoundException(className);
+		URL classFile = result.first;
+		className = result.second;
+		ObjectTeamsTransformer transformer = new ObjectTeamsTransformer();
+		try (InputStream inputStream = classFile.openStream()) {
+			transformer.readOTAttributes(inputStream, classFile.getFile(), loader);
+		}
+		Collection<String> currentBaseNames = transformer.fetchAdaptedBases(); // destructive read
+		if (currentBaseNames != null) {
+			// store per team:
+			ArrayList<String> basesPerTeam = this.baseClassNamesByTeam.get(className);
+			if (basesPerTeam == null) {
+				basesPerTeam = new ArrayList<String>();
+				this.baseClassNamesByTeam.put(className, basesPerTeam);
+			}
+			basesPerTeam.addAll(currentBaseNames);
+			// accumulated store:
+			allBaseClassNames.addAll(currentBaseNames);
+		}
+		readMemberTypeAttributes(bundle, className, transformer);
+		return className;
+	}
+	
+	/** 
+	 * Get the names of the base classes adapted by the given team and 
+	 * encountered while reading the byte code attributes.
+	 * (Destructive read). 
+	 */
+	public @Nullable Collection<String> getCollectedBaseClassNames(String teamName) {
+		return this.baseClassNamesByTeam.remove(teamName);
+	}
+
+	/** 
+	 * Get the names of all adapted base classes encountered while reading the byte code attributes.
+	 * (Destructive read). 
+	 */
+	public Collection<String> getCollectedBaseClassNames() {
+		try {
+			return this.allBaseClassNames;
+		} finally {
+			this.allBaseClassNames = new ArrayList<String>();
+		}
+	}
+	
+	/** 
+	 * Get the names of all member roles encountered while reading the byte code attributes. 
+	 * (Destructive read).
+	 */
+	public Collection<String> getCollectedRoleClassNames() {
+		return this.roleClassNames;
+	}
+	
+	/*
+	 * Recurse into member types scanning OT attributes.
+	 */
+	private void readMemberTypeAttributes(Bundle			     bundle,
+										  String                 className, 
+										  ObjectTeamsTransformer transformer)
+	{
+		List<String> roles = CallinBindingManager.getRolePerTeam(className);
+		if (roles != null) {
+			for (@SuppressWarnings("null")@NonNull String roleName: roles) {
+				log(IStatus.OK, "scanning role "+roleName);
+				try {
+					this.roleClassNames.add(roleName);
+					readOTAttributes(bundle, roleName);					
+				} catch (Throwable t) {
+					log(t, "Failed to read OT-Attributes of role "+roleName);
+				}
+				readMemberTypeAttributes(bundle, roleName, transformer);
+			}
+		}
+	}
+};
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Logger.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Logger.java
new file mode 100644
index 0000000..7f548d4
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Logger.java
@@ -0,0 +1,79 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2007, 2013 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute for Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and Technical University Berlin,
+ * Germany, and others
+ * 
+ * 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
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.objectteams.otequinox.Constants;
+import org.eclipse.osgi.framework.log.FrameworkLog;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+
+
+/**
+ * Log either to console or - as soon as it is initialized - via the TransformerPlugin.
+ * 
+ * @author stephan
+ * @since OTDT 1.1.4
+ */
+public class Logger {
+	private FrameworkLog fwLog;
+	
+	public Logger(FrameworkLog fwLog) {
+		this.fwLog = fwLog;
+	}
+
+	public void log(Throwable t, String msg) {
+		log(Constants.TRANSFORMER_PLUGIN_ID, t, msg);
+	}
+	public void log(String pluginID, Throwable t, String msg) {
+		if (this.fwLog != null) {
+			this.fwLog.log(new FrameworkLogEntry(pluginID, FrameworkLogEntry.ERROR, 0, msg, 0, t, null));
+			return;
+		} else {			
+			// no success logging, print to console instead:
+			System.err.println("OT/Equinox: "+msg); //$NON-NLS-1$
+			t.printStackTrace();
+		}
+	}
+	
+	public void log(int status, String msg) {
+		if (status >= Util.WARN_LEVEL)		
+			doLog(Constants.TRANSFORMER_PLUGIN_ID, status, msg);
+	}
+	public void log(String pluginID, int status, String msg) {
+		if (status >= Util.WARN_LEVEL)
+			doLog(pluginID, status, msg);
+	}
+	
+	public void doLog(int status, String msg) {
+		doLog(Constants.TRANSFORMER_PLUGIN_ID, status, msg);
+	}
+	public void doLog(String pluginID, int status, String msg) {
+		if (this.fwLog != null) {
+			this.fwLog.log(new FrameworkLogEntry(pluginID, status, 0, msg, 0, null, null));
+		} else {
+			// no success logging, print to console instead:
+			msg = "OT/Equinox: "+msg; //$NON-NLS-1$
+			if ((status & IStatus.ERROR) != 0)
+				System.err.println(msg);
+			else
+				System.out.println(msg);
+		}
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
new file mode 100644
index 0000000..54fe7f6
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
@@ -0,0 +1,309 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2013 GK Software AG
+ *  
+ * 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
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.otequinox.TransformerPlugin.log;
+
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.BaseBundle;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.TeamBinding;
+import org.eclipse.objectteams.internal.osgi.weaving.Util.ProfileKind;
+import org.eclipse.objectteams.otequinox.Constants;
+import org.eclipse.objectteams.otequinox.TransformerPlugin;
+import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.hooks.weaving.WovenClass;
+import org.osgi.framework.hooks.weaving.WovenClassListener;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Wire;
+
+
+/**
+ * This class integrates the OT/J weaver into OSGi using the standard API {@link WeavingHook}.
+ * <p>
+ * Additionally, we listen to events of woven classes changing to state {@link WovenClass#DEFINED}:
+ * </p>
+ * <ul>
+ * <li>Given that {@link AspectBindingRegistry#addDeferredTeamClasses} was used to record
+ * teams that could not be instantiated due to some required class being reported
+ * as {@link NoClassDefFoundError}.</li>
+ * <li>Assuming further that this error happened because the required class was in the process
+ * of being loaded further down the call stack.</li>
+ * <li>If later one of the not-found classes has been defined we use that trigger to
+ * re-attempt instantiating the dependent team(s).</li>
+ * </ul>
+ */
+public class OTWeavingHook implements WeavingHook, WovenClassListener {
+
+	enum WeavingReason { None, Aspect, Base }
+	
+	/** Interface to data about aspectBinding extensions. */
+	private @NonNull AspectBindingRegistry aspectBindingRegistry = new AspectBindingRegistry();
+	
+	/** Map of trip wires to be fired when a particular base bundle is loaded. */
+	private @NonNull HashMap<String, BaseBundleLoadTrigger> baseTripWires = new HashMap<>();
+
+	/** Set of classes for which processing has started but which are not yet defined in the class loader. */
+	private @NonNull Set<String> beingDefined = new HashSet<>();
+
+	/** Records of teams that have been deferred due to unresolved class dependencies: */
+	private @NonNull List<WaitingTeamRecord> deferredTeams = new ArrayList<>();
+
+	/** Call-back once the extension registry is up and running. */
+	public void activate(BundleContext bundleContext, ServiceReference<IExtensionRegistry> serviceReference) {
+		loadAspectBindingRegistry(bundleContext, serviceReference);
+		TransformerPlugin.getDefault().registerAspectBindingRegistry(this.aspectBindingRegistry);
+	}
+
+	// ====== Aspect Binding: ======
+
+	@SuppressWarnings("deprecation")
+	private void loadAspectBindingRegistry(BundleContext context, ServiceReference<IExtensionRegistry> serviceReference) {
+		org.osgi.service.packageadmin.PackageAdmin packageAdmin = null;
+		
+		ServiceReference<?> ref= context.getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName());
+		if (ref!=null)
+			packageAdmin = (org.osgi.service.packageadmin.PackageAdmin)context.getService(ref);
+		else
+			log(IStatus.ERROR, "Failed to load PackageAdmin service. Will not be able to handle fragments.");
+
+		IExtensionRegistry extensionRegistry = context.getService(serviceReference);
+		if (extensionRegistry == null)
+			log(IStatus.ERROR, "Failed to acquire ExtensionRegistry service, cannot load aspect bindings.");
+		else
+			aspectBindingRegistry.loadAspectBindings(extensionRegistry, packageAdmin, this);
+	}
+
+	// ====== Base Bundle Trip Wires: ======
+	
+	/**
+	 * Callback during AspectBindingRegistry#loadAspectBindings():
+	 * Set-up a trip wire to fire when the mentioned base bundle is loaded.
+	 */
+	void setBaseTripWire(@SuppressWarnings("deprecation") @Nullable org.osgi.service.packageadmin.PackageAdmin packageAdmin, @NonNull String baseBundleId, BaseBundle baseBundle) 
+	{
+		if (!baseTripWires.containsKey(baseBundleId))
+			baseTripWires.put(baseBundleId, new BaseBundleLoadTrigger(baseBundleId, baseBundle, aspectBindingRegistry, packageAdmin));
+	}
+
+	/** Check if the given base bundle / base class mandate any loading/instantiation/activation of teams. */
+	void triggerBaseTripWires(@Nullable String bundleName, @NonNull WovenClass baseClass) {
+		BaseBundleLoadTrigger activation = baseTripWires.get(bundleName);
+		if (activation != null) {
+			activation.fire(baseClass, beingDefined, this);
+			if (activation.isDone())
+				baseTripWires.remove(bundleName);
+		}
+	}
+
+	// ====== Main Weaving Entry: ======
+
+	@Override
+	public void weave(WovenClass wovenClass) {
+		beingDefined.add(wovenClass.getClassName());
+
+		try {
+			BundleWiring bundleWiring = wovenClass.getBundleWiring();
+			String bundleName = bundleWiring.getBundle().getSymbolicName();
+			String className = wovenClass.getClassName();
+			
+			if (bundleName.equals(Constants.TRANSFORMER_PLUGIN_ID))
+				return;
+
+			if (BCELPatcher.BCEL_PLUGIN_ID.equals(bundleName)) {
+				BCELPatcher.fixBCEL(wovenClass);
+				return;
+			}
+
+			WeavingReason reason = requiresWeaving(bundleWiring);
+			if (className.equals("org.eclipse.objectteams.otdt.test.builder.OTTestingEnvironment"))
+				log(IStatus.INFO, "Weaving reason for org.eclipse.objectteams.otdt.test.builder.OTTestingEnvironment:"+reason);
+			if (reason != WeavingReason.None) {
+				// do whatever is needed *before* loading this class:
+				triggerBaseTripWires(bundleName, wovenClass);
+
+				ObjectTeamsTransformer transformer = new ObjectTeamsTransformer();
+				Class<?> classBeingRedefined = null; // TODO prepare for otre-dyn
+				ProtectionDomain protectionDomain = wovenClass.getProtectionDomain();
+				byte[] bytes = wovenClass.getBytes();
+				try {
+					log(IStatus.OK, "About to transform class "+className);
+					long time = 0;
+					if (Util.PROFILE) time= System.nanoTime();
+					byte[] newBytes = transformer.transform(bundleWiring.getBundle(),
+										className, classBeingRedefined, protectionDomain, bytes);
+					if (newBytes != bytes && !Arrays.equals(newBytes, bytes)) {
+						if (Util.PROFILE) Util.profile(time, ProfileKind.Transformation, className);
+						log(IStatus.INFO, "Transformation performed on "+className);
+						wovenClass.setBytes(newBytes);
+						if (reason == WeavingReason.Aspect)
+							recordBaseClasses(transformer, bundleName, className);
+					} else {
+						if (Util.PROFILE) Util.profile(time, ProfileKind.NoTransformation, className);
+					}
+				} catch (IllegalClassFormatException e) {
+					log(e, "Failed to transform class "+className);
+				}
+			}
+		} catch (ClassCircularityError cce) {
+			log(cce, "Weaver encountered a circular class dependency");
+		}
+	}
+
+	WeavingReason requiresWeaving(BundleWiring bundleWiring) {
+		@SuppressWarnings("null")@NonNull
+		Bundle bundle = bundleWiring.getBundle();
+		if (aspectBindingRegistry.getAdaptedBasePlugins(bundle) != null)
+			return WeavingReason.Aspect;
+		if (aspectBindingRegistry.isAdaptedBasePlugin(bundle.getSymbolicName()))
+			return WeavingReason.Base;
+		return WeavingReason.None;
+	}
+
+	private void recordBaseClasses(ObjectTeamsTransformer transformer, @NonNull String aspectBundle, String className) {
+		if (className.equals("org.eclipse.objectteams.otdt.test.builder.OTTestingEnvironment")) {
+			loggingRecord(transformer, aspectBundle, className);
+			return;
+		}
+			
+		Collection<String> adaptedBases = transformer.fetchAdaptedBases();
+		if (adaptedBases == null || adaptedBases.isEmpty()) return;
+		List<AspectBinding> aspectBindings = aspectBindingRegistry.getAspectBindings(aspectBundle);
+		if (aspectBindings != null)
+			for (AspectBinding aspectBinding : aspectBindings)
+				if (!aspectBinding.hasScannedTeams)
+					for (TeamBinding team : aspectBinding.teams)
+						if (team.teamName.equals(className))
+							if (!team.hasScannedBases) {
+								for (TeamBinding equivalent : team.equivalenceSet) {
+									equivalent.addBaseClassNames(adaptedBases);
+									equivalent.hasScannedBases = true;
+								}
+								return; // done all equivalent teams
+							}
+	}
+
+	private void loggingRecord(ObjectTeamsTransformer transformer, String aspectBundle, String className) {
+		Collection<String> adaptedBases = transformer.fetchAdaptedBases();
+		if (adaptedBases == null || adaptedBases.isEmpty()) return;
+		List<AspectBinding> aspectBindings = aspectBindingRegistry.getAspectBindings(aspectBundle);
+		if (aspectBindings != null)
+			for (AspectBinding aspectBinding : aspectBindings) {
+				log(IStatus.INFO, "\taspectBinding: "+aspectBinding);
+				if (!aspectBinding.hasScannedTeams) {
+					log(IStatus.INFO, "\thas not scanned yet");
+					for (TeamBinding team : aspectBinding.teams)
+						if (team.teamName.equals(className)) {
+							log(IStatus.INFO, "Found team");
+							if (!team.hasScannedBases) {
+								log(IStatus.INFO, "\tteam has not scanned yet");
+								for (TeamBinding equivalent : team.equivalenceSet) {
+									log(IStatus.INFO, "\t\tadding "+adaptedBases.size()+" bases to "+team);
+									equivalent.addBaseClassNames(adaptedBases);
+									equivalent.hasScannedBases = true;
+								}
+								return; // done all equivalent teams
+							}
+						}
+				}
+			}		
+	}
+
+	// ===== handling deferred teams: ======
+
+	/**
+	 * Record the given team classes as waiting for instantiation/activation.
+	 * Callback during {@link BaseBundleLoadTrigger#fire()}
+	 */
+	public void addDeferredTeamClasses(List<WaitingTeamRecord> teamClasses) {
+		synchronized (deferredTeams) {
+			deferredTeams.addAll(teamClasses);
+		}
+	}
+
+	/**
+	 * Try to instantiate/activate any deferred teams that may be unblocked
+	 * by the definition of the given trigger class.
+	 */
+	public void instantiateScheduledTeams(String triggerClassName) {
+		List<WaitingTeamRecord> scheduledTeams = null;
+		synchronized(deferredTeams) {
+			for (WaitingTeamRecord record : new ArrayList<>(deferredTeams)) {
+				if (record.notFoundClass.equals(triggerClassName)) {
+					if (scheduledTeams == null)
+						scheduledTeams = new ArrayList<>();
+					if (deferredTeams.remove(record))
+						scheduledTeams.add(record);
+				}
+			}
+		}
+		if (scheduledTeams == null) return;
+		for(WaitingTeamRecord record : scheduledTeams) {
+			if (record.team.isActivated)
+				continue;
+			String teamName = record.team.teamName;
+			log(IStatus.INFO, "Consider for instantiation/activation: team "+teamName);
+			try {
+				TeamLoader loader = new TeamLoader(deferredTeams, beingDefined);
+				// Instantiate (we only get here if activationKind != NONE)
+				loader.instantiateAndActivate(record.aspectBinding, record.team, record.activationKind); // may re-insert to deferredTeams
+			} catch (Exception e) {
+				log(e, "Failed to instantiate team "+teamName);
+				continue;
+			}
+		}
+	}
+
+	@Override
+	public void modified(WovenClass wovenClass) {
+		if (wovenClass.getState() == WovenClass.DEFINED) {
+			beingDefined.remove(wovenClass.getClassName());
+			@SuppressWarnings("null") @NonNull String className = wovenClass.getClassName();
+			instantiateScheduledTeams(className);
+		}
+	}
+
+	static boolean hasImport(WovenClass clazz, String packageName, String packageWithAttribute) {
+		List<String> imports = clazz.getDynamicImports();
+		for (String imp : imports)
+			if (imp.equals(packageName) || imp.equals(packageWithAttribute))
+				return true;
+		for (Wire wire : clazz.getBundleWiring().getRequiredResourceWires(PackageNamespace.PACKAGE_NAMESPACE)) {
+			Object packageValue = wire.getRequirement().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+			if (packageName.equals(packageValue) || packageWithAttribute.equals(packageValue))
+				return true;
+		}
+		return false;
+	
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Pair.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Pair.java
new file mode 100644
index 0000000..516fa33
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Pair.java
@@ -0,0 +1,28 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2013 GK Software AG
+ *  
+ * 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
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+@NonNullByDefault
+class Pair<A, B> {
+	public A first;
+	public B second;
+	public Pair(A first, B second) {
+		this.first = first;
+		this.second = second;
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/TeamLoader.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/TeamLoader.java
new file mode 100644
index 0000000..9e5e72d
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/TeamLoader.java
@@ -0,0 +1,212 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2013 GK Software AG
+ *  
+ * 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
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.otequinox.TransformerPlugin.log;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.TeamBinding;
+import org.eclipse.objectteams.internal.osgi.weaving.Util.ProfileKind;
+import org.eclipse.objectteams.otequinox.ActivationKind;
+import org.eclipse.objectteams.otequinox.TransformerPlugin;
+import org.objectteams.Team;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.hooks.weaving.WovenClass;
+
+/**
+ * This class triggers the actual loading/instantiation/activation of teams.
+ * <p>
+ * It implements a strategy of deferring those teams that are not ready for
+ * instantiating / activating, which we check by comparing the sets of
+ * bound base classes of the team vs. the set of classes currently being
+ * processed by class loading & weaving.
+ * This reflects that fact that classes for which loading has already been
+ * started would otherwise trigger an irrecoverable NoClassDefFoundError. 
+ * </p><p>
+ * Which teams participate in deferred instantiation is communicated via the 
+ * shared list {@link #deferredTeams}.
+ * </p>
+ */
+@NonNullByDefault
+public class TeamLoader {
+
+	/** Collect here any teams that cannot yet be handled and should be scheduled later. */
+	private List<WaitingTeamRecord> deferredTeams;
+
+	private Set<String> beingDefined;
+	
+	public TeamLoader(List<WaitingTeamRecord> deferredTeams, Set<String> beingDefined) {
+		this.deferredTeams = deferredTeams;
+		this.beingDefined = beingDefined;
+	}
+
+	/**
+	 * Team loading, 1st attempt before the base class is even loaded
+	 * Trying to do these phases: load (now) instantiate/activate (if ready),
+	 */
+	public void loadTeamsForBase(Bundle aspectBundle, AspectBinding aspectBinding, WovenClass baseClass) {
+		@SuppressWarnings("null")@NonNull String className = baseClass.getClassName();
+		Collection<TeamBinding> teamsForBase = aspectBinding.getTeamsForBase(className);
+		if (teamsForBase == null) 
+			return; // not done
+		for (TeamBinding teamForBase : teamsForBase) {
+			if (teamForBase.isActivated) continue;
+			// Load:
+			Class<? extends Team> teamClass;
+			teamClass = teamForBase.loadTeamClass(aspectBundle);
+			if (teamClass == null) {
+				log(new ClassNotFoundException("Not found: "+teamForBase), "Failed to load team "+teamForBase);
+				continue;
+			}
+			// Try to instantiate & activate, failures are recorded in deferredTeams
+			ActivationKind activationKind = teamForBase.activation;
+			if (activationKind == ActivationKind.NONE) {
+				teamForBase = aspectBinding.getOtherTeamToActivate(teamForBase);
+				if (teamForBase != null) {
+					if (teamForBase.isActivated) continue;
+					activationKind = teamForBase.activation;
+					teamClass = teamForBase.loadTeamClass(aspectBundle);
+					if (teamClass == null) {
+						log(new ClassNotFoundException("Not found: "+teamForBase.teamName+" in bundle "+aspectBundle.getSymbolicName()), "Failed to load team "+teamForBase);
+						continue;						
+					}
+				} else {
+					continue;
+				}
+			}
+			if (activationKind == ActivationKind.NONE) 
+				continue;
+			instantiateAndActivate(aspectBinding, teamForBase, activationKind);
+		}
+	}
+
+	public static @Nullable Pair<URL,String> findTeamClassResource(String className, Bundle bundle) {
+		for (String candidate : possibleTeamNames(className)) {
+			URL result = bundle.getResource(candidate.replace('.', '/')+".class");
+			if (result != null)
+				return new Pair<>(result, candidate);
+		}
+		return null;
+	}
+
+	/** 
+	 * Starting from currentName compute a list of potential binary names of (nested) teams
+	 * using "$__OT__" as the separator, to find class parts of nested teams.  
+	 */
+	public static List<String> possibleTeamNames(String currentName) {
+		List<String> result = new ArrayList<String>();
+		result.add(currentName);
+		char sep = '.'; // assume source name
+		if (currentName.indexOf('$') > -1)
+			// binary name
+			sep = '$';
+		int from = currentName.length()-1;
+		while (true) {
+			int pos = currentName.lastIndexOf(sep, from);
+			if (pos == -1)
+				break;
+			String prefix = currentName.substring(0, pos); 
+			String postfix = currentName.substring(pos+1);
+			if (sep=='$') {
+				if (!postfix.startsWith("__OT__"))
+					result.add(0, currentName = prefix+"$__OT__"+postfix);
+			} else {
+				// heuristic: 
+				// only replace if parent element looks like a class (expected to start with uppercase)
+				int prevDot = prefix.lastIndexOf('.');
+				if (prevDot > -1 && Character.isUpperCase(prefix.charAt(prevDot+1))) 
+					result.add(0, currentName = prefix+"$__OT__"+postfix);
+				else 
+					break;
+			}
+			from = pos-1;
+		}
+		return result;
+	}
+
+	/**
+	 * Check if the given team is ready. If so instantiate it and if activationKind requires also activate it.
+	 */
+	void instantiateAndActivate(AspectBinding aspectBinding, TeamBinding team, ActivationKind activationKind)
+	{
+		String teamName = team.teamName;
+		// don't try to instantiate before all base classes successfully loaded.
+		synchronized(aspectBinding) {
+			if (!isReadyToLoad(aspectBinding, team, teamName, activationKind))
+				return;
+			for (TeamBinding equivalent : team.equivalenceSet)
+				equivalent.isActivated = true;
+		}
+
+		try {
+			long time = 0;
+			if (Util.PROFILE) time= System.nanoTime();
+
+			@SuppressWarnings("null")@NonNull Team instance = team.teamClass.newInstance();
+			TransformerPlugin.registerTeamInstance(instance);
+			log(IStatus.INFO, "Instantiated team "+teamName);
+			
+			try {
+				switch (activationKind) {
+				case ALL_THREADS:
+					instance.activate(Team.ALL_THREADS);
+					log(IStatus.INFO, "Activated team "+teamName);
+					break;
+				case THREAD:
+					instance.activate();
+					log(IStatus.INFO, "Activated team "+teamName);
+					break;
+				//$CASES-OMITTED$
+				default:
+					break;
+				}
+				if (Util.PROFILE) Util.profile(time, ProfileKind.Activation, teamName);
+			} catch (Throwable t) {
+				// application errors during activation
+				log(t, "Failed to activate team "+teamName);
+			}
+		} catch (Throwable e) {
+			// application error during constructor execution?
+			log(e, "Failed to instantiate team "+teamName);
+		}
+	}
+
+	private boolean isReadyToLoad(AspectBinding aspectBinding,
+									TeamBinding team, String teamName,
+									ActivationKind activationKind)
+	{
+		for (@SuppressWarnings("null")@NonNull String baseclass : team.baseClassNames) {
+			if (this.beingDefined.contains(baseclass)) {
+				synchronized (deferredTeams) {
+					WaitingTeamRecord record = new WaitingTeamRecord(team, aspectBinding, activationKind, baseclass);
+					deferredTeams.add(record);
+				}
+				log(IStatus.INFO, "Defer instantation/activation of team "+teamName);
+				return false;
+			}
+		}
+		return true;
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Util.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Util.java
new file mode 100644
index 0000000..a4a0c35
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/Util.java
@@ -0,0 +1,78 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
+ * for its Fraunhofer Institute for Computer Architecture and Software
+ * Technology (FIRST), Berlin, Germany and 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: Util.java 23461 2010-02-04 22:10:39Z stephan $
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.otequinox.TransformerPlugin.doLog;
+import static org.eclipse.core.runtime.IStatus.*;
+
+public class Util 
+{
+
+	// configure OT/Equinox debugging:
+	public static int WARN_LEVEL = INFO;
+	public static boolean PROFILE= false;
+	static {
+		String level = System.getProperty("otequinox.debug"); //$NON-NLS-1$
+		if (level != null) {
+			level = level.toUpperCase();
+			if (level.equals("OK"))            //$NON-NLS-1$
+				WARN_LEVEL = OK;
+			else if (level.equals("INFO"))     //$NON-NLS-1$
+				WARN_LEVEL = INFO;
+			else if (level.startsWith("WARN")) //$NON-NLS-1$
+				WARN_LEVEL = WARNING;
+			else if (level.startsWith("ERR"))  //$NON-NLS-1$
+				WARN_LEVEL = ERROR;
+			else
+				WARN_LEVEL = OK;
+		}
+		PROFILE= (System.getProperty("otequinox.profile") != null); //$NON-NLS-1$
+	}
+
+	/** Profiling data: */
+	enum ProfileKind { Transformation, NoTransformation, Activation, Scan }
+	private static long[] profileTimes= new long[ProfileKind.values().length];
+	private static long systemStartTime= System.nanoTime();
+
+	@SuppressWarnings("nls")
+	public static void profile(long startTime, ProfileKind kind, String msg) 
+	{
+		long now= System.nanoTime();
+		long delta= (now-startTime);// / getActiveCount();
+		long total= (profileTimes[kind.ordinal()]+= delta);
+		msg = msg.substring(msg.lastIndexOf('.')+1);
+		doLog(INFO, "Profile "+kind.name()+": "+m(delta)+"("+m(total)+"/"+m(now-systemStartTime)+") ["+msg+"]");
+	}
+	// nano-to milli conversion
+	private static double m(long l) {
+		return (l/1000000.0);
+	}
+
+	private static int getActiveCount() {
+		ThreadGroup group= Thread.currentThread().getThreadGroup();
+		ThreadGroup parent= group.getParent();
+		while (parent != null) {
+			group= parent;
+			parent= group.getParent();
+		}
+		return group.activeCount();
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/WaitingTeamRecord.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/WaitingTeamRecord.java
new file mode 100644
index 0000000..b954565
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/WaitingTeamRecord.java
@@ -0,0 +1,36 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2013 GK Software AG
+ *  
+ * 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
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.TeamBinding;
+import org.eclipse.objectteams.otequinox.ActivationKind;
+
+/** Record for one team waiting for instantiation & activation. */
+@NonNullByDefault
+class WaitingTeamRecord {
+	TeamBinding team;
+	AspectBinding aspectBinding;
+	ActivationKind activationKind;
+	String notFoundClass;
+	
+	public WaitingTeamRecord(TeamBinding team, AspectBinding aspectBinding, ActivationKind activationKind, String notFoundClass) {
+		this.team = team;
+		this.aspectBinding = aspectBinding;
+		this.notFoundClass = notFoundClass;
+		this.activationKind = activationKind;
+	}	
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/AspectBindingRequestAnswer.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/AspectBindingRequestAnswer.java
deleted file mode 100644
index 87b7c6e..0000000
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/AspectBindingRequestAnswer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- * 
- * Copyright 2009 Germany and 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
- * 
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- * 
- * Contributors:
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otequinox;
-
-import org.eclipse.objectteams.otequinox.hook.AspectPermission;
-
-/** 
- * Answer for an aspect binding request. See extension point org.eclipse.objectteams.otequinox.aspectBindingNegotiators.
- * 
- * @author stephan
- * @since 1.2.6
- */
-public class AspectBindingRequestAnswer 
-{
-	/** Should this answer be remembered persistently? */
-	public boolean persistent;
-	/** Should this answer be applied to all subsequent requests? */
-	public boolean allRequests;
-	/** The actual answer. */
-	public AspectPermission permission;
-	
-	/**
-	 * @param persistent  Should this answer be remembered persistently?
-	 * @param allRequests Should this answer be applied to all subsequent requests?
-	 * @param permission  One of DENY, GRANT, UNDEFINED (let others decide).
-	 */
-	public AspectBindingRequestAnswer(boolean persistent, boolean allRequests, AspectPermission permission) {
-		this.persistent = persistent;
-		this.allRequests = allRequests;
-		this.permission = permission;
-	}
-	
-}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/IAspectRegistry.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/IAspectRegistry.java
new file mode 100644
index 0000000..0fc118a
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/IAspectRegistry.java
@@ -0,0 +1,67 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2007, 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
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * Fraunhofer FIRST - Initial API and implementation
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otequinox;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.osgi.framework.Bundle;
+
+/**
+ * This slice of the IOTEquinoxService provides features to query the
+ * registry of aspectBindings.
+ * 
+ * @author stephan
+ * @since OTDT 1.1.4
+ */
+public interface IAspectRegistry {
+
+	/** Are we running within the OTDT? */
+	public boolean isOTDT();
+	
+	/** Is `symbolicName' the name of a base plugin for which an adapting team is registered? */
+	public boolean isAdaptedBasePlugin(String baseBundleName);
+
+	/**
+  	 * Get the names of aspect plugins adapting a given base plugin.
+	 * @param basePlugin base plugin.
+	 * @return non-null array of symbolic names of aspect plugins.
+ 	 */
+	public @NonNull String[] getAdaptingAspectPlugins(Bundle baseBundle);
+
+	/**
+	 *  Get the plugin IDs of all base plugins adapted by this aspect plugin.
+	 *  If this plugin is not an aspect plugin return null.
+	 *  @param aspectBundle potential aspect plugin
+	 *  @return array of base plugin IDs or null.
+	 */
+	public @Nullable String[] getAdaptedBasePlugins(Bundle aspectBundle);
+
+	/**
+	 * Does `bundle' have internal teams, i.e., teams that adapt classes from their
+	 * enclosing plug-in only?
+	 * @param bundle
+	 * @return
+	 */
+	public boolean hasInternalTeams(Bundle bundle);
+
+	/**
+	 * Does the symbolic name refer to an aspect bundle for which some permission was denied?
+	 * @param symbolicName
+	 * @return
+	 */
+	public boolean isDeniedAspectPlugin(String symbolicName);
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/IAspectRequestNegotiator.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/IAspectRequestNegotiator.java
deleted file mode 100644
index 3e16c0d..0000000
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/IAspectRequestNegotiator.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- * 
- * Copyright 2009 Germany and 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
- * 
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- * 
- * Contributors:
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otequinox;
-
-import org.eclipse.objectteams.otequinox.hook.AspectPermission;
-
-/**
- * Interface for extenders wishing to participate in negotiation about aspect binding requests
- * including forced exports.
- * 
- * @author stephan
- * @since 1.2.6
- */
-public interface IAspectRequestNegotiator {
-	
-	/** 
-	 * Check whether a request for forced exports should be granted.
-	 * @param aspectBundleSymbolicName the aspect issuing the request
-	 * @param baseBundleSymbolicName   the affected base bundle
-	 * @param basePackage              the affected base package
-	 * @param previousNegotiation      the result of negotations up-to this point
-	 * @return a structure holding the answer, must not be null.
-	 */
-	AspectBindingRequestAnswer checkForcedExport(String aspectBundleSymbolicName, String baseBundleSymbolicName, String basePackage, AspectPermission previousNegotiation);
-
-	/** 
-	 * Check whether a request for an aspect binding should be granted.
-	 * @param aspectBundleSymbolicName the aspect issuing the request
-	 * @param baseBundleSymbolicName   the affected base bundle
-	 * @param teamClass 	           an affecting team class involved in this aspect binding
-	 * @param previousNegotiation      the result of negotations up-to this point
-	 * @return a structure holding the answer, must not be null.
-	 */
-	AspectBindingRequestAnswer checkAspectBinding(String aspectBundleSymbolicName, String baseBundleSymbolicName, String teamClass, AspectPermission previousNegotiation);
-}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java
index b4893f0..9a9217a 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java
@@ -1,624 +1,220 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- * 
- * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
- * for its Fraunhofer Institute for Computer Architecture and Software
- * Technology (FIRST), Berlin, Germany and Technical University Berlin,
- * Germany.
- * 
- * 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
- * 
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- * 
- * Contributors:
- * Fraunhofer FIRST - Initial API and implementation
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
 package org.eclipse.objectteams.otequinox;
 
-import static org.eclipse.objectteams.otequinox.Constants.*;
+import static org.eclipse.objectteams.otequinox.Constants.TRANSFORMER_PLUGIN_ID;
 
-import java.lang.reflect.Field;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
 import java.util.List;
-import java.util.Set;
 
-import org.eclipse.core.internal.runtime.InternalPlatform;
-import org.eclipse.core.runtime.IConfigurationElement; //from: org.eclipse.equinox.registry
-import org.eclipse.core.runtime.RegistryFactory;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.objectteams.otequinox.internal.ASMByteCodeAnalyzer;
-import org.eclipse.objectteams.otequinox.internal.AspectBinding;
-import org.eclipse.objectteams.otequinox.internal.AspectPermissionManager;
-import org.eclipse.objectteams.otequinox.internal.JobAndThreadListener;
-import org.eclipse.objectteams.otequinox.internal.MasterTeamLoader;
-import org.eclipse.objectteams.otequinox.internal.TransformerServiceDelegate;
-import org.eclipse.objectteams.otequinox.hook.ClassScanner;
-import org.eclipse.objectteams.otequinox.hook.HookConfigurator;
-import org.eclipse.objectteams.otequinox.hook.IAspectRegistry;
-import org.eclipse.objectteams.otequinox.hook.IByteCodeAnalyzer;
-import org.eclipse.objectteams.otequinox.hook.ILogger;
-import org.eclipse.objectteams.otequinox.hook.IOTEquinoxService;
-import org.eclipse.objectteams.otequinox.hook.IOTTransformer;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBindingRegistry;
+import org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook;
+import org.eclipse.objectteams.otre.ClassLoaderAccess;
+import org.objectteams.Team;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.hooks.weaving.WovenClassListener;
 
-/**
- * The main class (activator) of the transformer plugin.
- * It maintains the aspect registry of this plugin.
- * This class optionally uses  {@link InternalPlatform} for the purpose of accessing the workspace location,
- * i.e., if this class is not found, no workspace location will be used.
- * 
- * @author stephan
- */
-@SuppressWarnings("restriction") // accessing InternalPlatform
-public class TransformerPlugin implements BundleActivator, IOTEquinoxService
-{	
-	private static List<String> KNOWN_OTDT_ASPECTS = new ArrayList<String>();
-	static {
-		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.jdt.ui");
-		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.compiler.adaptor");
-		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.refactoring");
-		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.pde.ui");
-		KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.samples");
-	}
-	/** main internal registry of aspect bindings. */
-	private static HashMap<String, ArrayList<AspectBinding>> aspectBindingsByBasePlugin = 
-			   new HashMap<String, ArrayList<AspectBinding>>();
-	private static HashMap<String, ArrayList<AspectBinding>> aspectBindingsByAspectPlugin = 
-		       new HashMap<String, ArrayList<AspectBinding>>();
-	// map base bundle name to list of adapted base class names
-	private static HashMap<String, ArrayList<String>> adaptedBaseClassNames =
-		       new HashMap<String, ArrayList<String>>();
-	// set of aspect plug-ins which have internal teams:
-	private Set<String> selfAdaptingAspects= new HashSet<String>();
-	
-	/** Aspect Permissions and Negotiation (delegate to dedicated manager). */
-	private AspectPermissionManager permissionManager;
-	
-	/** The instance that is created by the framework. */
-	private static TransformerPlugin instance;
-	private ServiceRegistration<IOTEquinoxService> serviceRegistration;
-	private ServiceRegistration<IOTTransformer> serviceRegistration2;
+public class TransformerPlugin implements BundleActivator, IAspectRegistry {
 
-	/* unevaluated content of liftingParticipant extension: */
-	private IConfigurationElement liftingParticipantConfig; 
-	/* Field of <code>org.objectteams.Team</code> holding a configured lifting participant: */
-	private static final String LIFTING_PARTICIPANT_FIELD = "_OT$liftingParticipant";
+	private static BundleContext context;
 
-	private ILogger log;
-	
-	/** instances which may have pending team classes waiting for instantiation. */
-	private HashMap<Bundle,List<MasterTeamLoader>> masterTeamLoaders = new HashMap<Bundle, List<MasterTeamLoader>>();
-	
-	/** Service needed for handling fragments */
-	private PackageAdmin packageAdmin;
-
-	// note: actually List<Team> but Team cannot be mentioned in this plugin.
-	private List<Object> teamInstances = new ArrayList<Object>();
-	
-	public static boolean IS_OTDT = false;
-	
-	public boolean isOTDT() {
-		return IS_OTDT;
-	}
-	
-	public TransformerPlugin() {
-		instance = this;
-	}
-	public void start(BundleContext context) throws Exception {
-		if (!HookConfigurator.OT_EQUINOX_ENABLED)
-			throw new BundleException("Not starting the transformer plugin because OT/Equinox has not been enabled (set system property \"ot.equinox\").");
-
-		this.log = HookConfigurator.getLogger();
-		log(ILogger.INFO, "activating org.eclipse.objectteams.otequinox");
-		
-		ServiceReference<?> ref= context.getServiceReference(PackageAdmin.class.getName());
-		if (ref!=null)
-			this.packageAdmin = (PackageAdmin)context.getService(ref);
-		else
-			this.log(ILogger.ERROR, "Failed to load PackageAdmin service. Will not be able to handle fragments.");
-
-		this.permissionManager = new AspectPermissionManager(this.log, context.getBundle(), this.packageAdmin);
-		this.permissionManager.loadAspectBindingNegotiators(context);
-		loadAspectBindings();
-		loadLiftingParticipant();
-		this.serviceRegistration = context.registerService(IOTEquinoxService.class, this, new Hashtable<String, Object>());		
-		this.serviceRegistration2 = context.registerService(IOTTransformer.class, new TransformerServiceDelegate(), new Hashtable<String, Object>());
-		Job.getJobManager().addJobChangeListener(new JobAndThreadListener());
-	}
-		
-	/* be a good citizen: clean up. */
-	public void stop(BundleContext context) throws Exception {
-		serviceRegistration.unregister();
-		serviceRegistration2.unregister();
+	public static Bundle getBundle() {
+		return context.getBundle();
 	}
 
-	public static TransformerPlugin getDefault() {
-		return instance;
-	}
+	private static ILog log;
+	private static TransformerPlugin plugin;
+	
+	private AspectBindingRegistry aspectBindingRegistry;
+	private List<Team> teamInstances = new ArrayList<>();
 
-	/** public API: Do we know about any team that has not yet been initiaized as requested? */
-	public static boolean isWaitingForTeams() {
-		synchronized (instance.masterTeamLoaders) {
-			if (!instance.masterTeamLoaders.isEmpty())
-				return true;
-		}		
-		synchronized (aspectBindingsByBasePlugin) {
-			for (ArrayList<AspectBinding> aspects : aspectBindingsByBasePlugin.values())
-				for (AspectBinding aspectBinding : aspects) 
-					if (!aspectBinding.activated)
-						return true;	
-		}
-		return false;
-	}
-
-	/** 
-	 * Internal API for TransformerHook:
-	 * see {@link IAspectRegistry#isDeniedAspectPlugin(String)}
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
 	 */
-	public boolean isDeniedAspectPlugin(String symbolicName) {
-		return this.permissionManager.isDeniedAspectPlugin(symbolicName);
-	}
-
-	/* Load extensions for org.eclipse.objectteams.otequinox.aspectBindings and check aspect permissions. */
-	private void loadAspectBindings() {
-		IConfigurationElement[] aspectBindingConfigs = RegistryFactory.getRegistry().getConfigurationElementsFor(
-				TRANSFORMER_PLUGIN_ID, ASPECT_BINDING_EXTPOINT_ID);
+	public void start(final BundleContext bundleContext) throws Exception {
+		plugin = this;
+		TransformerPlugin.context = bundleContext;
 		
-		for (int i = 0; i < aspectBindingConfigs.length; i++) {
-			IConfigurationElement currentBindingConfig = aspectBindingConfigs[i];
-
-			//aspect:
-			String aspectBundleId= currentBindingConfig.getContributor().getName();
-			IS_OTDT |= KNOWN_OTDT_ASPECTS.contains(aspectBundleId);
-			Bundle[] aspectBundles = packageAdmin.getBundles(aspectBundleId, null);
-			if (aspectBundles == null || aspectBundles.length == 0 || (aspectBundles[0].getState() < Bundle.RESOLVED)) {
-				log(ILogger.ERROR, "aspect bundle "+aspectBundleId+" is not resolved - not loading aspectBindings.");
-				continue;
-			}
-			
-			//base:
-			IConfigurationElement[] basePlugins = currentBindingConfig.getChildren(BASE_PLUGIN);
-			if (basePlugins.length != 1) {
-				log(ILogger.ERROR, "aspectBinding of "+aspectBundleId+" must declare exactly one basePlugin");
-				continue;
-			}
-			String baseBundleId = basePlugins[0].getAttribute(ID);
-			
-			//base fragments?
-			IConfigurationElement[] fragments = basePlugins[0].getChildren(REQUIRED_FRAGMENT);
-			if (fragments != null && !checkRequiredFragments(aspectBundleId, baseBundleId, fragments)) // reported inside
-				continue;
-			
-			AspectBinding binding = new AspectBinding(aspectBundleId, baseBundleId, basePlugins[0].getChildren(Constants.FORCED_EXPORTS_ELEMENT));
-			// TODO(SH): maybe enforce that every bundle id is given only once?
-
-			//teams:
-			IConfigurationElement[] teams = currentBindingConfig.getChildren(TEAM);
-			binding.initTeams(teams.length);
-			try {
-				for (int j = 0; j < teams.length; j++) {
-					String teamClass = teams[j].getAttribute(CLASS);
-					binding.teamClasses[j] = teamClass;
-					String activation = teams[j].getAttribute(ACTIVATION);
-					binding.setActivation(j, activation);
-				}
-				
-				String realBaseBundleId = baseBundleId.toUpperCase().equals(SELF) ? aspectBundleId : baseBundleId;
-				addBindingForBaseBundle(realBaseBundleId, binding);
-				addBindingForAspectBundle(aspectBundleId, binding);
-				
-				// now that binding.teamClasses is filled connect to super team, if requested:
-				for (int j = 0; j < teams.length; j++) {
-					String superTeamName = teams[j].getAttribute(SUPERCLASS);
-					if (superTeamName != null)
-						addSubTeam(aspectBundleId, binding.teamClasses[j], superTeamName);
-				}
-				log(ILogger.INFO, "registered:\n"+binding);
-			} catch (Throwable t) {
-				log(t, "Invalid aspectBinding extension");
-			}
-		}
-	}
-
-	private boolean checkRequiredFragments(String aspectBundleId, String baseBundleId, IConfigurationElement[] fragments) 
-	{
-		// checking only, no real action needed.
-		boolean hasError = false;
-		for (IConfigurationElement fragment : fragments) {
-			String fragId = fragment.getAttribute(ID);
-			if (fragId == null) {
-				log(ILogger.ERROR, "Mandatory attribute \"id\" missing from element \"requiredFragment\" of aspect binding in "+aspectBundleId);
-				return false;
-			} 
-			if (packageAdmin == null) {
-				log(ILogger.ERROR, "Not checking required fragment "+fragId+" in aspect binding of "+aspectBundleId+", package admin service not present");
-				return false; // report only once.
-			}
-			
-			Bundle[] fragmentBundles = packageAdmin.getBundles(fragId, null);
-			if (fragmentBundles == null || fragmentBundles.length == 0) {
-				log(ILogger.ERROR, "Required fragment "+fragId+" not found in aspect binding of "+aspectBundleId);
-				hasError = true;
-				continue;
-			}
-			Bundle fragmentBundle = fragmentBundles[0];
-			String aspectBindingHint = " (aspect binding of "+aspectBundleId+")";
-			if (packageAdmin.getBundleType(fragmentBundle) != PackageAdmin.BUNDLE_TYPE_FRAGMENT) {
-				log(ILogger.ERROR, "Required fragment " + fragId + " is not a fragment" + aspectBindingHint);
-				hasError = true;
-				continue;
-			}
-			Bundle[] hosts = packageAdmin.getHosts(fragmentBundle);
-			if (hosts == null || hosts.length == 0) {
-				if (fragmentBundle.getState() < Bundle.RESOLVED) {
-					log(ILogger.ERROR, "Required fragment " + fragId + " is not resolved" + aspectBindingHint);
-					hasError = true;
-					continue;
-				}
-				log(ILogger.ERROR, "Required fragment "+fragId+" has no host bundle"+aspectBindingHint);
-				hasError = true;					
-				continue;
-			}
-			Bundle host = hosts[0];
-			if (!host.getSymbolicName().equals(baseBundleId)) {
-				log(ILogger.ERROR, "Required fragment "+fragId+" has wrong host "+host.getSymbolicName()+aspectBindingHint);
-				hasError = true;
-			}
-		}
-		return !hasError;
-	}
-
-
-	private static void addBindingForBaseBundle(String baseBundleId, AspectBinding binding) {
-		ArrayList<AspectBinding> bindingList = aspectBindingsByBasePlugin.get(baseBundleId);
-		if (bindingList == null) {
-			bindingList = new ArrayList<AspectBinding>();
-			aspectBindingsByBasePlugin.put(baseBundleId, bindingList);
-		}
-		bindingList.add(binding);
-	}
-
-	private void addBindingForAspectBundle(String aspectBundleId, AspectBinding binding) {
-		ArrayList<AspectBinding> bindingList = aspectBindingsByAspectPlugin.get(aspectBundleId);
-		if (bindingList == null) {
-			bindingList = new ArrayList<AspectBinding>();
-			aspectBindingsByAspectPlugin.put(aspectBundleId, bindingList);
-		}
-		bindingList.add(binding);
-		if (binding.basePlugin.toUpperCase().equals(SELF))
-			selfAdaptingAspects.add(aspectBundleId);
-	}
+		acquireLog(bundleContext);
 	
-	/**
-	 * Record a sub-class relationship of two teams within the same aspect bundle.
-	 * 
-	 * @param aspectBundleId
-	 * @param subTeamName
-	 * @param teamName
-	 */
-	private void addSubTeam(String aspectBundleId, String subTeamName, String teamName) {
-		ArrayList<AspectBinding> bindingList = aspectBindingsByAspectPlugin.get(aspectBundleId);
-		if (bindingList == null) {
-			Exception e = new Exception("No such aspect binding");
-			log(e, "Class "+teamName+" not registered (declared to be superclass of team "+subTeamName);
-		} else {
-			for (AspectBinding binding : bindingList)
-				if (binding.teamClasses != null)
-					for (int i=0; i < binding.teamClasses.length; i++) 
-						if (binding.teamClasses[i].equals(teamName)) {
-							if (binding.subTeamClasses[i] == null)
-								binding.subTeamClasses[i] = new ArrayList<String>();
-							binding.subTeamClasses[i].add(subTeamName);
-							return;
-						}
-			Exception e = new Exception("No such aspect binding");
-			log(e, "Class "+teamName+" not registered(2) (declared to be superclass of team "+subTeamName);
-		}		
-	}
-
-	/* Load extension for org.eclipse.objectteams.otequinox.liftingParticipant. */
-	private void loadLiftingParticipant() {
-		IConfigurationElement[] liftingParticipantConfigs = RegistryFactory.getRegistry().getConfigurationElementsFor(
-				TRANSFORMER_PLUGIN_ID, LIFTING_PARTICIPANT_EXTPOINT_ID);
+		OTREInit();
 		
-		if (liftingParticipantConfigs.length != 1) {
-			if (liftingParticipantConfigs.length > 1)
-				log(ILogger.ERROR, "Cannot install more than one lifting participant.");
-			return;
-		}
-		this.liftingParticipantConfig = liftingParticipantConfigs[0];
-		// defer initialization until when o.o.Team is naturally being loaded.
-	}
-
-	/** 
-	 * Callback to initialize class <code>org.objectteams.Team</code> after it has been loaded.
-	 * Here it is used to initialized a lifting participant if such an extension is defined.
-	 */
-	public void initializeOOTeam(Class<?> ooTeam) {
-		if (this.liftingParticipantConfig == null)
-			return;
+		// register our weaving service:
+		final OTWeavingHook otWeavingHook = new OTWeavingHook();
+		context.registerService(new String[] { WeavingHook.class.getName(), WovenClassListener.class.getName() },
+				otWeavingHook, null);
+		
+		// but wait until the extension registry is available for reading aspectBindings:
 		try {
-			// can't directly access class Team in this plugin:
-			Field participantField = ooTeam.getDeclaredField(TransformerPlugin.LIFTING_PARTICIPANT_FIELD);
-			
-			Object participantInstance = liftingParticipantConfig.createExecutableExtension(CLASS);
-			
-			participantField.set(null/*no target, field is static*/, participantInstance);
-			
-			log(ILogger.INFO, "registered lifting participant:\n\t"+participantInstance.getClass().getName());
-			
-		} catch (Throwable t) {
-			log(t, "Invalid lifting participant extension");
-		}
-	}
-
-	/**
-	 * Internal API for TransformerHook:
-	 * see {@link IAspectRegistry#getAdaptedBasePlugins(Bundle)}
-	 */
-	public String[] getAdaptedBasePlugins(Bundle aspectBundle) {
-		ArrayList<AspectBinding> bindings = aspectBindingsByAspectPlugin.get(aspectBundle.getSymbolicName());
-		if (bindings == null) return null;
-		String[] basePlugins = new String[bindings.size()];
-		for (int i=0; i<basePlugins.length; i++) {
-			basePlugins[i] = bindings.get(i).basePlugin;
-		}
-		return basePlugins;
-	}
-
-	/** Is `symbolicName' the name of a base plugin for which an adapting team is registered? */
-	public boolean isAdaptedBasePlugin(String symbolicName) {
-		ArrayList<AspectBinding> list = aspectBindingsByBasePlugin.get(symbolicName);
-		return list != null && !list.isEmpty();
-	}
-	
-	/**
-	 * public API:
-	 * {@link IAspectRegistry#getAdaptingAspectPlugins(Bundle)} 
-	 */
-	public String[] getAdaptingAspectPlugins(Bundle basePlugin) {
-		return getAdaptingAspectPlugins(basePlugin.getSymbolicName());
-	}
-	/**
-	 * public API:
-  	 * Get the names of aspect plugins adapting a given base plugin.
-	 * @param basePluginName symbolic name of a base plugin.
-	 * @return non-null array of symbolic names of aspect plugins.
-	 */
-	public String[] getAdaptingAspectPlugins(String basePluginName) {
-		ArrayList<AspectBinding> list = aspectBindingsByBasePlugin.get(basePluginName);
-		
-		if (list == null)
-			return new String[0];
-		
-		String[] aspects = new String[list.size()];
-		for (int i=0; i< list.size(); i++) 
-			aspects[i] = list.get(i).aspectPlugin;
-		
-		return aspects;
-	}
-	
-	/**
-     * Recored the names of base classes adapted by a given team from a given aspect bundle.
-	 */
-	public void storeAdaptedBaseClassNames(String aspectBundleName, String teamName, Collection<String> baseClassNames) 
-	{
-		// search the base plugin being adapted by the given team:
-		String basePlugin = null;
-		bindings:
-		for (AspectBinding aspectBinding : aspectBindingsByAspectPlugin.get(aspectBundleName)) {
-			for (String aspectTeamClass : aspectBinding.teamClasses)
-				if (aspectTeamClass.equals(teamName)) {
-					basePlugin = aspectBinding.basePlugin;
-					break bindings;
-				}
-		}
-		if (basePlugin == null && selfAdaptingAspects.contains(aspectBundleName))
-			basePlugin = aspectBundleName;
-		if (basePlugin == null) {
-			log(ILogger.ERROR, "Base plugin for team "+teamName+" from "+aspectBundleName+" not found!");
-			return;
-		}
-		// merge base class names into existing:
-		synchronized (adaptedBaseClassNames) {
-			ArrayList<String> baseBundleClassNames = adaptedBaseClassNames.get(basePlugin);
-			if (baseBundleClassNames == null) {
-				baseBundleClassNames = new ArrayList<String>();
-				adaptedBaseClassNames.put(basePlugin, baseBundleClassNames);
-			}
-			baseBundleClassNames.addAll(baseClassNames);
-		}
-	}
-
-	/**
-	 * Internal API for TransformerHook:
-	 * see {@link org.eclipse.objectteams.otequinox.hook.ITeamLoader#loadTeams(Bundle, IClassScanner)}
-	 */
-	public boolean loadTeams(Bundle baseBundle, ClassScanner classScanner) {
-		ArrayList<AspectBinding> bindings = aspectBindingsByBasePlugin.get(baseBundle.getSymbolicName());
-		return delegateToMasterTeamLoader(baseBundle, classScanner, bindings);
-	}
-	
-	/**
-	 * Internal API for TransformerHook:
-	 * see {@link org.eclipse.objectteams.otequinox.hook.IAspectRegistry#hasInternalTeams(Bundle)}
-	 */
-	public boolean hasInternalTeams(Bundle bundle) {
-		return selfAdaptingAspects.contains(bundle.getSymbolicName());
-	}
-	
-	/**
-	 * Internal API for TransformerHook:
-	 * see {@link org.eclipse.objectteams.otequinox.hook.ITeamLoader#loadInternalTeams(Bundle,ClassScanner)}
-	 */
-	public boolean loadInternalTeams(Bundle bundle, ClassScanner scanner) {
-		ArrayList<AspectBinding> selfBindings = new ArrayList<AspectBinding>();
-		synchronized (aspectBindingsByAspectPlugin) {
-			ArrayList<AspectBinding> bindings = aspectBindingsByAspectPlugin.get(bundle.getSymbolicName());
-			if (bindings == null)
-				return false;
-			for (int i = 0; i < bindings.size(); )
-				if (bindings.get(i).basePlugin.toUpperCase().equals(SELF))
-					selfBindings.add(bindings.remove(i));
-				else
-					i++;
-		}
-		return delegateToMasterTeamLoader(bundle, scanner, selfBindings);
-	}
-
-	// this performs some work for load[Internal]Teams:
-	// create&register a MasterTeamLoader and use it for loading the teams.
-	private boolean delegateToMasterTeamLoader(Bundle baseBundle,
-											   ClassScanner scanner,
-											   ArrayList<AspectBinding> bindings) 
-	{
-		if (bindings == null || bindings.isEmpty())
-			return false;
-		MasterTeamLoader masterTeamLoader = new MasterTeamLoader(baseBundle);
-		boolean success = masterTeamLoader.loadTeams(baseBundle, scanner, bindings);
-		if (success)
-			addMasterTeamLoader(baseBundle, masterTeamLoader);
-		return success;
-	}
-	
-	/**
-	 * Internal API for TransformerHook:
-	 * see {@link org.eclipse.objectteams.otequinox.hook.ITeamLoader#instantiateTeams(Bundle)}
-	 */
-	public void instantiateTeams(Bundle baseBundle, String triggerClassname) {
-		instance.internalInstantiateTeams(baseBundle, triggerClassname);
-	}
-	
-	/** Add a master team loader which may hold a list of teams waiting for instantiation.
-	 */
-	private void addMasterTeamLoader(Bundle baseBundle, MasterTeamLoader masterTeamLoader) {
-		synchronized (this.masterTeamLoaders) {
-			List<MasterTeamLoader> loaders = this.masterTeamLoaders.get(baseBundle);
-			if (loaders == null) {
-				loaders = new ArrayList<MasterTeamLoader>();
-				this.masterTeamLoaders.put(baseBundle, loaders);
-			}
-			loaders.add(masterTeamLoader);
-		}
-	}
-	
-
-	/**
-	 * Instantiate all teams affecting the given base bundle. Don't, however, load the class who's loading
-	 * triggered this call.
-	 * 
-	 * This method checks whether the AspectPermissionManager.isReady(). If not, defer instantiation and 
-	 * return the set of all affected base classes for use as a trigger for deferred instantiation. 
-	 *  
-	 * @param baseBundle
-     * @param triggerClassname if non-null: the name of a base class who's loading triggered this instantiation.
-	 */
-	private void internalInstantiateTeams(Bundle baseBundle, String triggerClassname) 
-	{			
-		List<MasterTeamLoader> loaders = null;
-		synchronized (this.masterTeamLoaders) {
-			loaders= this.masterTeamLoaders.get(baseBundle);
-			if (this.masterTeamLoaders.isEmpty() || loaders == null)
-				return;
-			
-			// check permission for forcedExports of all adapting aspect bundles
-			// (do this only if team loaders are found, but before any side effects occur)
-			synchronized (aspectBindingsByBasePlugin) {
-				List<AspectBinding> aspects= aspectBindingsByBasePlugin.get(baseBundle.getSymbolicName());
-				if (aspects != null) {
-					if (this.permissionManager.isReady()) {
-						for (AspectBinding aspectBinding : aspects)
-							if (!this.permissionManager.checkForcedExports(aspectBinding.aspectPlugin, baseBundle.getSymbolicName(), aspectBinding.forcedExports))
-								return; // don't activate teams of rejected aspect bundle
-					} else {
-						this.permissionManager.addForcedExportsObligations(aspects, baseBundle);
+			context.addServiceListener(
+				new ServiceListener() { 
+					public void serviceChanged(ServiceEvent event) {
+						if(event.getType() == ServiceEvent.REGISTERED)
+							otWeavingHook.activate(bundleContext, context.getServiceReference(IExtensionRegistry.class));
 					}
-				}
-			}
-
-			loaders = new ArrayList<MasterTeamLoader>(loaders);
-			this.masterTeamLoaders.remove(baseBundle);
+				},
+				"(objectclass="+IExtensionRegistry.class.getName()+")"); //$NON-NLS-1$ //$NON-NLS-2$
 		}
-		while (!loaders.isEmpty()) {
-			// be sure not to hold any lock during this statement:
-			List<Object> newInstances = loaders.remove(0).instantiateLoadedTeams(baseBundle, triggerClassname, this.permissionManager);
-			synchronized (this.teamInstances) {
-				this.teamInstances.addAll(newInstances);
-			}
-		}
-		// mark the fact that all teams adapting this base bundle have now been activated:
-		synchronized (aspectBindingsByBasePlugin) {
-			List<AspectBinding> aspects= aspectBindingsByBasePlugin.get(baseBundle.getSymbolicName());
-			if (aspects != null)
-				for (AspectBinding aspectBinding : aspects)
-					aspectBinding.activated= true;
+		catch (InvalidSyntaxException ex) {
+			log(ex, "Failed to register service listener");
 		}
 	}
 
-	/** Copy all registered team instances into the given list,
-	 *  which must by of type List<Team>; (can't mention Team in this plugin).
-     */
-	@SuppressWarnings({ "unchecked", "rawtypes" })
-	public static synchronized void getTeamInstances(List list) {
-		list.addAll(instance.teamInstances);
+	@SuppressWarnings("restriction")
+	private static void acquireLog(BundleContext bundleContext) {
+		try {
+			TransformerPlugin.log = org.eclipse.core.internal.runtime.InternalPlatform.getDefault().getLog(bundleContext.getBundle());
+		} catch (NullPointerException npe) {
+			// WTF?
+		}
 	}
-	
+
+	private void OTREInit() {
+		// this influences the OTRE behavior (see e.g., JPLISEnhancer):
+		System.setProperty("ot.equinox", "true");
+		try {
+			ClassLoaderAccess.setLoadClass(Bundle.class.getMethod("loadClass", String.class));
+			ClassLoaderAccess.setGetResource(Bundle.class.getMethod("getResource", String.class));
+		} catch (NoSuchMethodException | SecurityException e) {
+			log(e, "Failed to wire an OSGi class into the OTRE");
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext bundleContext) throws Exception {
+		TransformerPlugin.context = null;
+	}
+
 	// configure OT/Equinox debugging:
-	public static int WARN_LEVEL = ILogger.ERROR;
+	public static int WARN_LEVEL = IStatus.ERROR;
 	static {
 		String level = System.getProperty("otequinox.debug");
 		if (level != null) {
 			level = level.toUpperCase();
 			if (level.equals("OK"))
-				WARN_LEVEL = ILogger.OK;
+				WARN_LEVEL = IStatus.OK;
 			else if (level.equals("INFO"))
-				WARN_LEVEL = ILogger.INFO;
+				WARN_LEVEL = IStatus.INFO;
 			else if (level.startsWith("WARN"))
-				WARN_LEVEL = ILogger.WARNING;
+				WARN_LEVEL = IStatus.WARNING;
 			else if (level.startsWith("ERR"))
-				WARN_LEVEL = ILogger.ERROR;
+				WARN_LEVEL = IStatus.ERROR;
 			else
-				WARN_LEVEL = ILogger.OK;
+				WARN_LEVEL = IStatus.OK;
 		}
 	}
 
-	public void log (Throwable ex, String msg) {
+	public static void log (Throwable ex, String msg) {
 		msg = "OT/Equinox: "+msg;
 		System.err.println(msg);
 		ex.printStackTrace();
-		this.log.log(TRANSFORMER_PLUGIN_ID, ex, msg);
+		if (log != null)
+			log.log(new Status(IStatus.ERROR, TRANSFORMER_PLUGIN_ID, msg, ex));
+		else
+			System.err.println(msg);
 	}
 	
-	public void log(int status, String msg) {
+	public static void log(int status, String msg) {
 		if (status >= WARN_LEVEL)
 			doLog(status, msg);
 	}
 
-	public void doLog(int status, String msg) {
+	public static void doLog(int status, String msg) {
 		msg = "OT/Equinox: "+msg;
-		this.log.log(TRANSFORMER_PLUGIN_ID, status, msg);
+// this seems to cause java.lang.NoClassDefFoundError: org/eclipse/ui/statushandlers/StatusAdapter etc.
+//		if (log == null) acquireLog(context);
+		if (log != null) {
+			log.log(new Status(status, TRANSFORMER_PLUGIN_ID, msg));
+		} else {
+			if ((status & IStatus.ERROR) != 0)
+				System.err.println(msg);
+			else
+				System.out.println(msg);
+		}
+	}
+	
+	
+
+	public static TransformerPlugin getDefault() {
+		return plugin;
 	}
 
-	public IByteCodeAnalyzer getByteCodeAnalyzer() {
-		return new ASMByteCodeAnalyzer();
+	public void registerAspectBindingRegistry(AspectBindingRegistry aspectBindingRegistry) {
+		this.aspectBindingRegistry = aspectBindingRegistry;
+	}
+
+	/**
+	 * public API:
+	 * {@link IAspectRegistry#getAdaptingAspectPlugins(Bundle)} 
+	 */
+	public @NonNull String[] getAdaptingAspectPlugins(Bundle basePlugin) {
+		return getAdaptingAspectPlugins(basePlugin.getSymbolicName());
+	}
+
+	public @NonNull String[] getAdaptingAspectPlugins(String id) {
+		List<AspectBinding> aspectBindings = this.aspectBindingRegistry.getAdaptingAspectBindings(id);
+		if (aspectBindings == null)
+			return new String[0];
+		String[] result = new String[aspectBindings.size()];
+		for (int i = 0; i < result.length; i++)
+			result[i] = aspectBindings.get(i).aspectPlugin;
+		return result;
+	}
+
+	public static synchronized void registerTeamInstance(Team instance) {
+		plugin.teamInstances.add(instance);
+	}
+	/**
+	 * Copy all registered team instances into the given list,
+     */
+	public static synchronized void getTeamInstances(List<Team> list) {
+		list.addAll(plugin.teamInstances);
+	}
+
+	@Override
+	public boolean isOTDT() {
+		// TODO Auto-generated method stub
+		return false;
 	}
 	
 	public static boolean useDynamicWeaving() {
 		return false;
 	}
-}
 
+	@Override
+	public boolean isAdaptedBasePlugin(String baseBundleName) {
+		return this.aspectBindingRegistry.isAdaptedBasePlugin(baseBundleName);
+	}
+
+	@Override
+	public String[] getAdaptedBasePlugins(Bundle aspectBundle) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public boolean hasInternalTeams(Bundle bundle) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean isDeniedAspectPlugin(String symbolicName) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/ASMByteCodeAnalyzer.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/ASMByteCodeAnalyzer.java
deleted file mode 100644
index f2906d3..0000000
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/ASMByteCodeAnalyzer.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**********************************************************************

- * This file is part of "Object Teams Development Tooling"-Software

- * 

- * Copyright 2008 Oliver Frank.

- * 

- * 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

- * 

- * Please visit http://www.eclipse.org/objectteams for updates and contact.

- * 

- * Contributors:

- * 		Oliver Frank - Initial API and implementation

- **********************************************************************/

-package org.eclipse.objectteams.otequinox.internal;

-

-import java.io.IOException;

-import java.io.InputStream;

-import java.util.Map;

-import java.util.concurrent.ConcurrentHashMap;

-

-import org.eclipse.objectteams.otequinox.hook.IByteCodeAnalyzer;

-import org.objectweb.asm.ClassReader;

-import org.objectweb.asm.commons.EmptyVisitor;

-

-/**

- * This class performs some fast readClass analyses

- * to determine further processing.

- * 

- * @author Oliver Frank

- * @since 1.2.3

- */

-public class ASMByteCodeAnalyzer implements IByteCodeAnalyzer {

-	private static final int ACC_TEAM = 0x8000;

-

-	private static class ClassInformation {

-		private boolean isTeam;

-		private String superClassName;

-

-		public ClassInformation(boolean isTeam, String superClassName) {

-			super();

-			this.isTeam = isTeam;

-			this.superClassName = superClassName;

-		}

-

-		public boolean isTeam() {

-			return isTeam;

-		}

-

-		public String getSuperClassName() {

-			if (superClassName != null)

-				return superClassName.replace('/', '.');

-			return null;

-		}

-	}

-

-	private static class MyVisitor extends EmptyVisitor {

-		MyVisitor() { super();}

-		private boolean isTeam;

-		private String superClassName;

-

-		public boolean isTeam() {

-			return isTeam;

-		}

-

-		public String getSuperClassName() {

-			return superClassName;

-		}

-

-		@Override

-		public void visit(int version, int access, String name,

-				String signature, String superName, String[] interfaces) {

-			superClassName = superName;

-			isTeam = (access & ACC_TEAM) != 0;

-		}

-	}

-

-	private Map<String, ClassInformation> classInformationMap =

-			new ConcurrentHashMap<String, ClassInformation>(512, 0.75f, 4);

-

-	/** 

-	 * {@inheritDoc}

-	 */

-	public String getSuperclass(InputStream classStream, String className) {

-		try {

-			return getClassInformation(null, classStream, className)

-					.getSuperClassName();

-		} catch (IOException e) {

-			return null;

-		}

-	}

-	

-	/** 

-	 * {@inheritDoc}

-	 */

-	public String getSuperclass(byte[] classBytes, String className) {

-		try {

-			return getClassInformation(classBytes, null, className)

-					.getSuperClassName();

-		} catch (IOException e) {

-			return null;

-		}

-	}

-

-	public boolean isTeam(byte[] classBytes, String className)

-			throws IOException {

-		return getClassInformation(classBytes, null, className).isTeam();

-	}

-

-	private ClassInformation getClassInformation(byte[] classBytes,

-			InputStream classStream, String className) throws IOException 

-	{

-		ClassInformation classInformation = classInformationMap.get(className);

-		if (classInformation != null) {

-			return classInformation;

-		}

-		if (classBytes != null) {

-			classInformation = this.getClassInformationPrivate(classBytes);

-		} else {

-			classInformation = this.getClassInformationPrivate(classStream);

-		}

-		classInformationMap.put(className, classInformation);

-		return classInformation;

-	}

-

-

-	private ClassInformation getClassInformationPrivate(InputStream classStream)

-			throws IOException {

-		return getClassInformationPrivate(new ClassReader(classStream));

-	}

-

-	private ClassInformation getClassInformationPrivate(byte[] classBytes) {

-		return getClassInformationPrivate(new ClassReader(classBytes));

-	}

-

-	private ClassInformation getClassInformationPrivate(ClassReader reader) {

-		MyVisitor visitor = new MyVisitor();

-

-		reader.accept(visitor, 0);

-		return new ClassInformation(visitor.isTeam(), visitor

-				.getSuperClassName());

-	}

-}

diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/AspectBinding.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/AspectBinding.java
deleted file mode 100644
index c33deec..0000000
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/AspectBinding.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- * 
- * Copyright 2009 Germany and 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
- * 
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- * 
- * Contributors:
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otequinox.internal;
-
-import java.util.List;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.objectteams.otequinox.ActivationKind;
-
-/** 
- * A simple record representing the information read from an extension to org.eclipse.objectteams.otequinox.aspectBindings.
- * @author stephan
- * @since 1.3.0 (was a nested class before that) 
- */
-public class AspectBinding {
-	public String aspectPlugin;
-	public String basePlugin;
-	public IConfigurationElement[] forcedExports;
-	public ActivationKind[] activations = null; 
-	public String[]         teamClasses;
-	public List<String>[]   subTeamClasses;
-	public boolean          activated= false;
-	
-	public AspectBinding(String aspectId, String baseId, IConfigurationElement[] forcedExportsConfs) {
-		this.aspectPlugin= aspectId;
-		this.basePlugin= baseId;
-		this.forcedExports= forcedExportsConfs;
-	}
-	
-	@SuppressWarnings("unchecked")
-	public void initTeams(int count) {
-		this.teamClasses    = new String[count];
-		this.subTeamClasses = new List[count]; // new List<String>[count] is illegal!
-		this.activations    = new ActivationKind[count];
-	}
-	
-	public void setActivation(int i, String specifier) {
-		if (specifier == null)
-			this.activations[i] = ActivationKind.NONE;
-		else
-			this.activations[i] = ActivationKind.valueOf(specifier);
-	}
-	public String toString() {
-		String result = "\tbase plugin "+basePlugin+"\n\tadapted by aspect pluging "+aspectPlugin;
-		for (String teamClass : teamClasses) {
-			result += "\n\t\t + team "+teamClass;
-		}
-		return result;
-	}
-}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/AspectPermissionManager.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/AspectPermissionManager.java
deleted file mode 100644
index befb818..0000000
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/AspectPermissionManager.java
+++ /dev/null
@@ -1,615 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- * 
- * Copyright 2009 Germany and 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
- * 
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- * 
- * Contributors:
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otequinox.internal;
-
-import static org.eclipse.objectteams.otequinox.hook.AspectPermission.*;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
-import org.eclipse.core.internal.runtime.InternalPlatform;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.RegistryFactory;
-import org.eclipse.objectteams.otequinox.ActivationKind;
-import org.eclipse.objectteams.otequinox.AspectBindingRequestAnswer;
-import org.eclipse.objectteams.otequinox.Constants;
-import org.eclipse.objectteams.otequinox.IAspectRequestNegotiator;
-import org.eclipse.objectteams.otequinox.TransformerPlugin;
-import org.eclipse.objectteams.otequinox.internal.MasterTeamLoader.TeamClassRecord;
-import org.eclipse.osgi.service.datalocation.Location;
-import org.eclipse.objectteams.otequinox.hook.AspectPermission;
-import org.eclipse.objectteams.otequinox.hook.HookConfigurator;
-import org.eclipse.objectteams.otequinox.hook.ILogger;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.service.packageadmin.PackageAdmin;
-
-/**
- * Manage permissions of aspect bundles requesting to apply aspectBindings and forcedExports.
- * The following pieces of information are checked:
- * <ul>
- * <li>properties set in installation-wide config.ini or as command line args (handled by {@link HookConfigurator} (plus internal class OTStorageHook))</li>
- * <li>defaults set per workspace (file negotiationDefaults.txt)</li>
- * <li>individual GRANT/DENY per workspace (files grantedForcedExports.txt, deniedForcedExports.txt)</li>
- * <li>answers from registered negotiators (extension point org.eclipse.objectteams.otequinox.aspectBindingNegotiators, see {@link IAspectRequestNegotiator})</li>
- * </ul>
- *
- * <p>
- * The final answer for a given request is combined from all sources where the priority of any {@link #DENY} answer is highest, 
- * of {@link #UNDEFINED} is lowest.
- * </p>
- * <p>
- * If a negotiator has determined a decision and its answer has the <code>persistent</code> flag set,
- * this particular aspect permission is stored as per-workspace configuration.
- * </p>
- * @author stephan
- * @since 1.2.6
- */
-@SuppressWarnings("restriction")
-public class AspectPermissionManager {
-
-	// property names for default configuration:
-	private static final String FORCED_EXPORT_DEFAULT  = "forced.export.default";
-	private static final String ASPECT_BINDING_DEFAULT = "aspect.binding.default";
-	
-	// workspace files where negotiation configuration is stored:
-	private static final String NEGOTIATION_DEFAULTS_FILE   = "negotiationDefaults.txt";  
-	private static final String GRANTED_FORCED_EXPORTS_FILE = "grantedForcedExports.txt";
-	private static final String DENIED_FORCED_EXPORTS_FILE  = "deniedForcedExports.txt";
-
-
-	// set of aspect plug-ins for which some permission has been denied:
-	private Set<String> deniedAspects = new HashSet<String>();
-	// default permission for aspect bindings:
-	private AspectPermission defaultAspectBindingPermission = GRANT;
-	// default permission for forced exports:
-	private AspectPermission defaultForcedExportPermission = UNDEFINED; // not yet granted, but open for receiving a GRANT
-	// for negotiation of aspect binding requests (incl. forced export):
-	private List<IAspectRequestNegotiator> negotiators = new ArrayList<IAspectRequestNegotiator>();
-	
-	
-	// collect all forced exports (denied/granted), granted should balance to an empty structure.
-	// structure is: aspect-id -> (base bundle x base package)*
-	private HashMap<String, ArrayList<String[]>> deniedForcedExportsByAspect= new HashMap<String, ArrayList<String[]>>();
-	private HashMap<String, ArrayList<String[]>> grantedForcedExportsByAspect= new HashMap<String, ArrayList<String[]>>();
-	
-	// key is aspectId+"->"+baseId, value is array of team names
-	private HashMap<String, Set<String>> deniedTeamsByAspectBinding = new HashMap<String, Set<String>>();
-	private HashMap<String, Set<String>> grantedTeamsByAspectBinding = new HashMap<String, Set<String>>();
-
-	// the workspace directory for storing the state of this plugin
-	private IPath otequinoxState;
-	// back link needed for accessing the state location:
-	private Bundle transformerBundle;
-	// helper instance needed to stop bundles by name
-	private PackageAdmin packageAdmin;
-	// shared logger:
-	private ILogger log;
-	
-	public AspectPermissionManager(ILogger log, Bundle bundle, PackageAdmin packageAdmin) {
-		this.log = log;
-		this.transformerBundle = bundle;
-		this.packageAdmin = packageAdmin;
-	}
-		
-	/* local cache for isReady(): */
-	private boolean isWaitingForLocation = true;
-	
-	/** Before using this permission manager a client must check whether we're ready (instance location set). */
-	public boolean isReady() {
-		if (!isWaitingForLocation)
-			return true;
-		try {
-			InternalPlatform platform = InternalPlatform.getDefault();
-			Location instanceLocation = platform.getInstanceLocation();
-			if (!instanceLocation.isSet())
-				return false; // not yet capable
-			this.isWaitingForLocation = false;
-			fetchAspectBindingPermssionsFromWorkspace();
-		} catch (NoClassDefFoundError ncdfe) {
-			this.log.log(ILogger.WARNING, "Optional class InternalPlatform not found, cannot access workspace location");
-			this.isWaitingForLocation = false;
-			return true;
-		}
-		if (!this.obligations.isEmpty())
-			for (Runnable job : this.obligations)
-				job.run();
-		return true;
-	}
-
-	/** 
-	 * Fetch stored permissions from this plugin's workspace state.
-	 * 
-	 * @pre instance location should be set (see {@link #isReady()}),
-	 *    otherwise will silently return without accessing workspace settings. 
-	 */
-	private void fetchAspectBindingPermssionsFromWorkspace() 
-	{		
-		try {
-			this.otequinoxState = InternalPlatform.getDefault().getStateLocation(this.transformerBundle, true);
-		} catch (NoClassDefFoundError ncdfe) {
-			this.log.log(ILogger.WARNING, "Optional class InternalPlatform not found, cannot access workspace location");
-			return;
-		}
-
-		// defaults:
-		IPath configFilePath = this.otequinoxState.append(NEGOTIATION_DEFAULTS_FILE);
-		File configFile = new File(configFilePath.toOSString());		
-		if (configFile.exists()) {
-			Properties props = new Properties();
-			try {
-				boolean migrated = false; // TODO(SH): remove this migration support in 1.3.0
-				props.load(new FileInputStream(configFile));
-				String value = (String) props.get(ASPECT_BINDING_DEFAULT);
-				if (value != null)
-					try {
-						defaultAspectBindingPermission = AspectPermission.valueOf(value);
-					} catch (IllegalArgumentException iae) {
-						if ("DONT_CARE".equals(value)) {
-							defaultAspectBindingPermission = AspectPermission.UNDEFINED;
-							migrated = true;
-						} else {
-							// this code should remain even after 1.3.0:
-							defaultAspectBindingPermission = AspectPermission.DENY;
-							log(iae, "Cannot set default aspect permission from file "+NEGOTIATION_DEFAULTS_FILE+", assuming DENY.");
-						}
-					}
-				value = (String) props.get(FORCED_EXPORT_DEFAULT);
-				if (value != null)
-					try {
-						defaultForcedExportPermission = AspectPermission.valueOf(value);
-					} catch (IllegalArgumentException iae) {
-						if ("DONT_CARE".equals(value)) {
-							defaultForcedExportPermission = AspectPermission.UNDEFINED;
-							migrated = true;
-						} else {
-							// this code should remain even after 1.3.0:
-							defaultForcedExportPermission = AspectPermission.DENY;
-							log(iae, "Cannot set default forced exports permission from file "+NEGOTIATION_DEFAULTS_FILE+", assuming DENY.");
-						}
-					}
-				if (migrated)
-					writeNegotiationDefaults(configFile);
-			} catch (IOException ioex) {
-				log(ioex, "Failed to read configuration file "+configFilePath.toOSString());
-			}
-		} else {
-			try {
-				File stateDir = new File(this.otequinoxState.toOSString());
-				if (!stateDir.exists())
-					stateDir.mkdirs();
-				configFile.createNewFile();
-				writeNegotiationDefaults(configFile);
-			} catch (IOException ioex) {
-				log(ioex, "Failed to create configuration file "+configFilePath.toOSString());
-			}
-		}
-		
-		// explicitly denied:
-		configFilePath = this.otequinoxState.append(DENIED_FORCED_EXPORTS_FILE);
-		configFile = new File(configFilePath.toOSString());
-		if (configFile.exists())
-			HookConfigurator.parseForcedExportsFile(configFile, DENY);
-		
-		// explicitly granted:
-		configFilePath = this.otequinoxState.append(GRANTED_FORCED_EXPORTS_FILE);
-		configFile = new File(configFilePath.toOSString());
-		if (configFile.exists())
-			HookConfigurator.parseForcedExportsFile(configFile, GRANT);
-	}
-
-	private void writeNegotiationDefaults(File configFile)
-			throws IOException 
-	{
-		FileWriter writer = new FileWriter(configFile);
-		writer.append(ASPECT_BINDING_DEFAULT+'='+defaultAspectBindingPermission.toString()+'\n');
-		writer.append(FORCED_EXPORT_DEFAULT+'='+defaultForcedExportPermission.toString()+'\n');
-		writer.flush();
-		writer.close();
-		log(ILogger.INFO, "Created aspect binding defaults file "+configFile.getCanonicalPath());
-	}
-
-		
-	/** Load extensions for EP org.eclipse.objectteams.otequinox.aspectBindingNegotiators. */
-	public void loadAspectBindingNegotiators(BundleContext context) {
-		IConfigurationElement[] aspectBindingNegotiatorsConfigs = RegistryFactory.getRegistry().getConfigurationElementsFor(
-				Constants.TRANSFORMER_PLUGIN_ID, Constants.ASPECT_NEGOTIATOR_EXTPOINT_ID);		
-		for (int i = 0; i < aspectBindingNegotiatorsConfigs.length; i++) {
-			IConfigurationElement currentNegotiatorConfig = aspectBindingNegotiatorsConfigs[i];
-			try {
-				Object negotiator = currentNegotiatorConfig.createExecutableExtension("class");
-				if (negotiator != null)
-					this.negotiators.add(((IAspectRequestNegotiator)negotiator));
-			} catch (CoreException e) {
-				log(e, "Failed to instantiate extension "+currentNegotiatorConfig);
-			}
-		}
-	}
-
-	/** Delegatee of internal API {@link TransformerPlugin#isDeniedAspectPlugin(String)}. */
-	public boolean isDeniedAspectPlugin(String symbolicName) {
-		return this.deniedAspects.contains(symbolicName);
-	}
-
-	
-	/**
-	 * Check whether a given aspect requests forced exports from base, 
-	 * and whether these requests are granted/denied by checking all available sources.
-	 * 
-	 * Clients should ask {@link #isReady()} (ie., instance location is set) before calling this method,
-	 * otherwise workspace settings have to be silently ignored (any error should be signaled by client).
-	 * 
-	 * @param aspectId      symbolic name of the aspect bundle
-	 * @param baseBundleId  symbolic name of the bound base bundle
-     * @param forcedExports any forced exports requested in this aspect binding.
-	 * @return whether all requests (if any) have been granted
-	 */
-	public boolean checkForcedExports(String aspectId, String baseBundleId, IConfigurationElement[] forcedExports) 
-	{
-		if (forcedExports == null || forcedExports.length == 0)
-			return true;
-		
-		ArrayList<String[]> deniedForcedExports = getConfiguredForcedExports(aspectId, DENY,  deniedForcedExportsByAspect);
-		ArrayList<String[]> grantedForcedExports= getConfiguredForcedExports(aspectId, GRANT, grantedForcedExportsByAspect);
-
-		// iterate all requested forcedExports to search for a matching permission:
-		for (IConfigurationElement forcedExport : forcedExports) { // [0..1] (as defined in the schema)
-			String forcedExportsRequest = forcedExport.getValue();
-			if (forcedExportsRequest == null)
-				continue;
-			for (String singleForcedExportRequest : forcedExportsRequest.split(",")) 
-			{
-				singleForcedExportRequest = singleForcedExportRequest.trim();
-
-				String[] listEntry;
-				boolean grantReported = false;
-				AspectPermission negotiatedPermission = this.defaultForcedExportPermission;
-				
-				// DENY by default?
-				if (negotiatedPermission == DENY) {
-					log(ILogger.ERROR, "Default denial of forced export regarding package "+singleForcedExportRequest+
-									   " from bundle "+baseBundleId+" as requested by bundle "+aspectId+"; bundle not activated");
-					this.deniedAspects.add(aspectId); // keep for answering the TransformerHook.
-					return false; // NOPE!					
-				}
-				
-				// DENY from configuration?
-				listEntry = findRequestInList(baseBundleId, singleForcedExportRequest, deniedForcedExports);
-				if (listEntry != null) {
-					log(ILogger.ERROR, "Explicit denial of forced export regarding package "+singleForcedExportRequest+
-									   " from bundle "+baseBundleId+" as requested by bundle "+aspectId+"; bundle not activated");
-					this.deniedAspects.add(aspectId); // keep for answering the TransformerHook.
-					return false; // NOPE!
-				}
-
-				// GRANT from configuration?
-				listEntry = findRequestInList(baseBundleId, singleForcedExportRequest, grantedForcedExports);
-				if (listEntry != null) {
-					log(ILogger.INFO, "Forced export granted for "+aspectId+": "+singleForcedExportRequest+" (from bundle "+baseBundleId+")");
-					grantReported = true;
-					grantedForcedExports.remove(listEntry);
-					negotiatedPermission = GRANT;
-				}
-
-				// default and persistent configuration did not DENY, proceed to the negotiators:
-				boolean shouldPersist = false;
-				for (IAspectRequestNegotiator negotiator : this.negotiators) {
-					AspectBindingRequestAnswer answer = negotiator.checkForcedExport(aspectId, baseBundleId, singleForcedExportRequest, negotiatedPermission);
-					if (answer != null) {
-						if (answer.permission.compareTo(negotiatedPermission) > 0) // increasing priority of answer?
-						{ 
-							shouldPersist = answer.persistent;
-							negotiatedPermission = answer.permission;
-							// locally store as default for subsequent requests (not persistent, see below):
-							if (answer.allRequests)
-								this.defaultForcedExportPermission = negotiatedPermission;
-							if (negotiatedPermission == DENY)
-								break; // end of discussion.
-						}
-					}
-				}
-
-				// make decision persistent?
-				if (shouldPersist && negotiatedPermission != UNDEFINED)
-					// FIXME(SH): handle "allRequests":
-					persistForcedExportsAnswer(aspectId, baseBundleId, singleForcedExportRequest, negotiatedPermission);
-				
-				// report:
-				if (negotiatedPermission == GRANT) {
-					if (!grantReported)
-						log(ILogger.INFO, "Negotiation granted forced export for "+aspectId+
-										  ": "+singleForcedExportRequest+" (from bundle "+baseBundleId+')');
-				} else {
-					String verb = "did not grant";
-					if (negotiatedPermission == DENY)
-						verb = "denied";
-					log(ILogger.ERROR, "Negotiation "+verb+" forced export for "+aspectId+
-									   ": "+singleForcedExportRequest+" (from bundle "+baseBundleId+")"+
-									   ". Aspect is not activated.");
-					this.deniedAspects.add(aspectId); // keep for answering the TransformerHook.
-					return false; // don't install illegal aspect
-				}
-			}
-		}
-		if (!grantedForcedExports.isEmpty())
-			reportUnmatchForcedExports(aspectId, grantedForcedExports);
-		return true;
-	}
-
-	/**
-	 * Get the forced exports configured for a given aspect bundle with permission <code>perm</code>.
-	 * Consult {@link HookConfigurator} and store the result in <code>map</code>.
-	 * 
-	 * @param aspectId  symbolic name of the aspect in focus
-	 * @param perm		are we asking about DENY or GRANT?
-	 * @param map		in/out param for storing results from OTStorageHook
-	 * @return		 	list of pairs (base bundle x base package)
-	 */
-	private ArrayList<String[]> getConfiguredForcedExports(String                               aspectId, 
-														   AspectPermission 				    perm, 
-														   HashMap<String, ArrayList<String[]>> map) 
-    {
-		ArrayList<String[]> forcedExports= map.get(aspectId);
-		if (forcedExports == null) {
-			// fetch declarations from config.ini or other locations.
-			forcedExports= HookConfigurator.getForcedExportsByAspect(aspectId, perm);
-			map.put(aspectId, forcedExports);
-		}
-		return forcedExports;
-	}
-
-	private String[] findRequestInList(String baseBundleId, String basePackage, ArrayList<String[]> list) {
-		if (list != null)
-			for (String[] singleExport : list)
-				if (   singleExport[0].equals(baseBundleId)
-					&& singleExport[1].equals(basePackage))
-				{
-					return singleExport;
-				}
-		return null;
-	}
-
-	/**
-	 * If the structure of grantedForcedExports is not empty we have mismatches between forced-export declarations.
-	 * Report these mismatches as warnings.
-	 */
-	void reportUnmatchForcedExports(String aspectId, ArrayList<String[]> unmatchedForcedExports) 
-	{
-		for (String[] export: unmatchedForcedExports) {
-			String baseId = export[0];
-			String pack   = export[1];
-			log(ILogger.WARNING, "Aspect "+aspectId+
-							  " does not declare forced export of package "+
-							  pack+" from bundle "+baseId+
-							  " as declared in config.ini (or system property)");
-		}
-	}
-
-	/* Simple strategy to append a forced export to a file (existing or to be created). */
-	private void persistForcedExportsAnswer(String aspectId, String baseBundleId, String basePackage, AspectPermission negotiatedPermission) 
-	{
-		if (this.otequinoxState == null) {
-			log(ILogger.ERROR, "Can't persist forcedExports permission, no workspace location accessable.");
-			return;
-		}
-		try {
-			String fileName = (negotiatedPermission == DENY) ? DENIED_FORCED_EXPORTS_FILE : GRANTED_FORCED_EXPORTS_FILE;
-			IPath forcedExportsPath = this.otequinoxState.append(fileName);
-			File forcedExportsFile = new File(forcedExportsPath.toOSString());
-			if (!forcedExportsFile.exists())
-				forcedExportsFile.createNewFile();
-			FileWriter writer = new FileWriter(forcedExportsFile, true); // FIXME(SH): consider merge (after decision about file format)
-			writer.append('\n');
-			writer.append(baseBundleId);
-			writer.append("\n[\n\t");
-			writer.append(basePackage);
-			writer.append(";x-friends:=\"");
-			writer.append(aspectId);
-			writer.append("\"\n]\n");
-			writer.flush();
-			writer.close();
-		} catch (IOException ioe) {
-			log(ioe, "Failed to persist negotiation result");
-		}
-	}
-	
-	/**
-	 * Check permission for the aspect binding of one specific team.
-	 * 
-	 * Clients should ask {@link #isReady()} (ie., instance location is set) before calling this method,
-	 * otherwise workspace settings have to be silently ignored (any error should be signaled by client).
- 	 * 
-	 * @param aspectBundleId
-	 * @param baseBundleId
-	 * @param teamClass
-	 * @return whether this team is permitted to adapt classes from the given base bundle.
-	 */
-	boolean checkTeamBinding(String aspectBundleId, String baseBundleId, String teamClass) 
-	{
-		boolean shouldReportGrant = false; // grant by default should not be reported
-		AspectPermission negotiatedPermission = this.defaultAspectBindingPermission;
-
-		// DENY by default?
-		if (negotiatedPermission == DENY) {
-			log(ILogger.ERROR, "Default denial of aspect binding regarding base bundle "+baseBundleId+
-							   " as requested by bundle "+aspectBundleId+"; bundle not activated");
-			this.deniedAspects.add(aspectBundleId); // keep for answering the TransformerHook.
-			return false; // NOPE!					
-		}
-
-		
-		String key = aspectBundleId+"->"+baseBundleId;
-		
-		// denied from configuration?
-		Set<String> deniedTeams = deniedTeamsByAspectBinding.get(key);
-		if (deniedTeams != null && !deniedTeams.isEmpty()) {
-			if (deniedTeams.contains(teamClass)) {
-				deniedAspects.add(aspectBundleId);
-				return false;
-			}
-		}
-		
-		// granted from configuration?
-		Set<String> grantedTeams = grantedTeamsByAspectBinding.get(key);
-		if (grantedTeams != null && grantedTeams.contains(teamClass)) {
-			negotiatedPermission = GRANT;
-			shouldReportGrant = true;
-		}
-		
-		// default and persistent configuration did not DENY, proceed to the negotiators:
-		boolean shouldPersist = false;
-		for (IAspectRequestNegotiator negotiator : this.negotiators) {
-			AspectBindingRequestAnswer answer = negotiator.checkAspectBinding(aspectBundleId, baseBundleId, teamClass, negotiatedPermission);
-			if (answer != null) {
-				if (answer.permission.compareTo(negotiatedPermission) > 0) // increasing priority of answer?
-				{ 
-					shouldPersist = answer.persistent;
-					negotiatedPermission = answer.permission;
-					shouldReportGrant = negotiatedPermission == GRANT;
-					// locally store as default for subsequent requests:
-					if (answer.allRequests)
-						this.defaultAspectBindingPermission = negotiatedPermission;
-
-					if (negotiatedPermission == DENY)
-						break; // end of discussion.
-				}
-			}
-		}
-
-		// make decision persistent?
-		if (shouldPersist && negotiatedPermission != UNDEFINED)
-			persistTeamBindingAnswer(aspectBundleId, baseBundleId, teamClass, negotiatedPermission);
-		
-		// report:
-		if (negotiatedPermission == GRANT) {
-			if (shouldReportGrant)
-				log(ILogger.INFO, "Negotiation granted aspect binding for "+aspectBundleId+
-								  " to base bundle "+baseBundleId+" by means of team "+teamClass+'.');
-		} else {
-			String verb = "did not grant";
-			if (negotiatedPermission == DENY)
-				verb = "denied";
-			log(ILogger.ERROR, "Negotiation "+verb+" aspect binding for "+aspectBundleId+
-							   " to base bundle "+baseBundleId+" by means of team "+teamClass+
-							   ". Aspect is not activated.");
-			this.deniedAspects.add(aspectBundleId); // keep for answering the TransformerHook.
-			return false; // don't install illegal aspect
-		}
-		return true;
-	}
-
-	private void persistTeamBindingAnswer(String aspectBundleId, String baseBundleId, String teamClass, AspectPermission negotiatedPermission) 
-	{
-		// FIXME(SH): implement persisting these!		
-	}
-
-	void log (Throwable ex, String msg) {
-		msg = "OT/Equinox: "+msg;
-		this.log.log(Constants.TRANSFORMER_PLUGIN_ID, ex, msg);
-	}
-		
-	void log(int status, String msg) {
-		if (status >= TransformerPlugin.WARN_LEVEL)
-			this.log.log(Constants.TRANSFORMER_PLUGIN_ID, status, "OT/Equinox: "+msg);
-	}
-		
-	List<Runnable> obligations = new ArrayList<Runnable>();
-	public void addBaseBundleObligations(final List<Object> teamInstances, final ArrayList<TeamClassRecord> teamClasses, final Bundle baseBundle) {
-		schedule(new Runnable() {
-			public void run() {
-				List<TeamClassRecord> teamsToRevert = new ArrayList<TeamClassRecord>();
-				// aspect bindings:
-				for (TeamClassRecord teamClass : teamClasses)
-					if (!checkTeamBinding(teamClass.aspectBundle.getSymbolicName(), baseBundle.getSymbolicName(), teamClass.teamName))
-						teamsToRevert.add(teamClass);
-				if (!teamsToRevert.isEmpty())
-					revert(teamsToRevert);
-			}
-			void revert(List<TeamClassRecord> teamsToRevert) {
-				try {
-					Set<Bundle> bundlesToStop = new HashSet<Bundle>();
-					Class<?>[] deactivationArgumentTypes = new Class[]{Thread.class};
-					Object[] deactivationArguments       = new Object[] {TeamClassRecord.get_ALL_THREADS()};
-					for (int i=0, c=0; c< teamsToRevert.size(); c++) {
-						TeamClassRecord teamClass = teamClasses.get(c);
-						if (teamClass.activation != ActivationKind.NONE) {
-							Object teamInstance = teamInstances.get(i++);
-							Method deactivationMethod = teamClass.clazz.getMethod("deactivate", deactivationArgumentTypes);
-							deactivationMethod.invoke(teamInstance, deactivationArguments);
-							// could also check if roles are present already ...
-						}
-						bundlesToStop.add(teamClass.aspectBundle);
-					}
-					for (Bundle bundle : bundlesToStop) {
-						log(ILogger.ERROR, "Stopping aspect bundle "+bundle.getSymbolicName()+" with denied aspect binding(s)");
-						bundle.stop();
-					}
-				} catch (Exception e) {
-					log(e, "Failed to revert aspect bundle with denied aspect bindings.");
-				}
-			}
-		});
-	}
-
-	public void addForcedExportsObligations(final List<AspectBinding> aspects, final Bundle baseBundle) {
-		schedule(new Runnable () {
-			public void run() {
-				for (AspectBinding aspectBinding : aspects)
-					if (!checkForcedExports(aspectBinding.aspectPlugin, baseBundle.getSymbolicName(), aspectBinding.forcedExports))
-						stopIllegalBundle(aspectBinding.aspectPlugin);
-			}
-		});
-	}
-
-	void schedule(Runnable job) {
-		if (isReady()) // became ready since last query?
-			job.run();
-		else
-			synchronized(obligations) {
-				obligations.add(job);
-			}
-	}
-		
-	void stopIllegalBundle(String symbolicName) {
-		String msgCore = "stop bundle "+symbolicName+" whose requests for forced exports have been denied";
-		if (this.packageAdmin == null) {
-			log(ILogger.ERROR, "Needing to "+msgCore+" but package admin is not available");
-		} else {
-			Bundle[] bundles = this.packageAdmin.getBundles(symbolicName, null);
-			if (bundles == null)
-				log(ILogger.ERROR, "Needing to "+msgCore+" but bundle cannot be retrieved");
-			else
-				try {
-					bundles[0].stop();
-				} catch (BundleException e) {
-					log(e, "Failed to " + msgCore);
-				}
-		}
-	}
-	
-}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/JobAndThreadListener.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/JobAndThreadListener.java
deleted file mode 100644
index 47bdc55..0000000
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/JobAndThreadListener.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- * 
- * Copyright 2010 GK Software AG
- * 
- * 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.eclipse.objectteams.otequinox.internal;
-
-import java.util.HashSet;
-
-import org.eclipse.core.runtime.jobs.IJobChangeEvent;
-import org.eclipse.core.runtime.jobs.IJobChangeListener;
-import org.objectteams.TeamThreadManager;
-
-/**
- * This listener ensures that each worker threads is made known to the OTRE 
- * as soon as is starts running Jobs.
- * 
- * @since 0.7.1 (incubation)
- */
-public class JobAndThreadListener implements IJobChangeListener {
-
-	private HashSet<Thread> knownThreads = new HashSet<Thread>();
-	
-	public void aboutToRun(IJobChangeEvent event) {
-		Thread current = Thread.currentThread();
-		synchronized (this.knownThreads) {
-			if (this.knownThreads.contains(current))
-				return;
-			this.knownThreads.add(current);
-		}
-		TeamThreadManager.newThreadStarted(false, null);
-	}
-
-	public void awake(IJobChangeEvent event) {
-	}
-
-	public void done(IJobChangeEvent event) {
-		// FIXME(SH): implement thread ended strategy
-	}
-
-	public void running(IJobChangeEvent event) {
-	}
-
-	public void scheduled(IJobChangeEvent event) {
-	}
-
-	public void sleeping(IJobChangeEvent event) {
-	}
-
-}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/MasterTeamLoader.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/MasterTeamLoader.java
deleted file mode 100644
index 7333aeb..0000000
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/MasterTeamLoader.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- * 
- * Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
- * for its Fraunhofer Institute for Computer Architecture and Software
- * Technology (FIRST), Berlin, Germany and 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: MasterTeamLoader.java 23468 2010-02-04 22:34:27Z stephan $
- * 
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- * 
- * Contributors:
- * Fraunhofer FIRST - Initial API and implementation
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otequinox.internal;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.internal.registry.osgi.OSGIUtils;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.objectteams.otequinox.ActivationKind;
-import org.eclipse.objectteams.otequinox.TransformerPlugin;
-import org.eclipse.osgi.framework.internal.core.BundleHost;
-import org.eclipse.objectteams.otequinox.hook.ClassScanner;
-import org.eclipse.objectteams.otequinox.hook.ILogger;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-
-/**
- * Each instance of this class is responsible for loading all teams adapting a specific base plugin.
- * It stores the team classes loaded successfully.
- * After team loading a call to instantiateLoadedTeams() shall be issued to instantiate
- * those teams, but that call pre-assumes that adapted base classes have already been loaded.
- * 
- * @author stephan
- * @version $Id: MasterTeamLoader.java 23468 2010-02-04 22:34:27Z stephan $
- */
-@SuppressWarnings("restriction")
-public class MasterTeamLoader {
-	
-	/** A simple record describing a configured and loaded team class: */
-	static class TeamClassRecord {
-		// store these info to check consistency among different aspectBindings mentioning the same team class:
-		static Set<Class<?>> allInstantiatedTeams = new HashSet<Class<?>>();
-		static Map<Class<?>, ActivationKind> allActivations = new HashMap<Class<?>, ActivationKind>();
-		
-		/** The bundle providing this team classs. */
-		Bundle aspectBundle;
-		/** The qualified team name. */
-		String teamName;
-		/** The loaded team class. */
-		Class<?> clazz;
-		/** The activation kind which was requested from the extension. */
-		ActivationKind activation;
-		/**
-		 * @param clazz      the loaded team class
-		 * @param activation the activation kind which was requested from the extension
-		 */
-		TeamClassRecord(Class<?> clazz, ActivationKind activation) {
-			this.clazz = clazz;
-			this.activation = activation;
-		}
-
-		public TeamClassRecord(Bundle aspectBundle, String teamName, ActivationKind activation) throws Exception {
-			this.activation = activation;
-			this.aspectBundle = aspectBundle;
-			this.teamName = teamName;
-			// enable to revert to early loading:
-			//this.clazz = this.aspectBundle.loadClass(this.teamName);
-		}
-		
-		/** Constant from org.objectteams.Team acquired via reflection. */
-		static Thread ALL_THREADS = null;
-		
-		/** Retrieve org.objectteams.Team.ALL_THREADS. */
-		static synchronized Thread get_ALL_THREADS()
-			throws Exception
-		{
-			if (ALL_THREADS == null) {
-				Class<?> ooTeam = Class.forName("org.objectteams.Team");
-				Field constantField = ooTeam.getDeclaredField("ALL_THREADS");
-				ALL_THREADS = (Thread)constantField.get(null);
-			}
-			return ALL_THREADS;
-		}
-		void readOTAttributes(ClassScanner scanner)
-				throws Exception, IOException
-		{
-			readOTAttributes(scanner, this.teamName);
-		}
-		
-		void readOTAttributes(ClassScanner scanner, String teamName)
-				throws Exception, IOException 
-		{
-			TransformerPlugin.getDefault().log(IStatus.OK, "reading attributes of team "+teamName);
-			ClassLoader loader = (ClassLoader) ((BundleHost)aspectBundle).getLoaderProxy().getBundleLoader().createClassLoader();
-			trying: {
-				for(String candidateName : possibleTeamNames(teamName)) {
-					try {
-						scanner.readOTAttributes(aspectBundle, candidateName, loader);
-						break trying;
-					} catch (ClassNotFoundException e) {
-						// keep going if we still have candidates
-					}				
-				}
-				throw new ClassNotFoundException(teamName);
-			}
-			Collection<String> baseClassNames = scanner.getCollectedBaseClassNames(teamName);
-			if (baseClassNames != null && !baseClassNames.isEmpty())
-				TransformerPlugin.getDefault().storeAdaptedBaseClassNames(this.aspectBundle.getSymbolicName(), teamName, baseClassNames);
-		}
-		
-		public boolean isAlreadyHandled() throws ClassNotFoundException {
-			if (this.clazz == null)
-				loadClass();
-			return allInstantiatedTeams.contains(this.clazz);
-		}
-
-		public Object newInstance() throws Exception {
-			if (this.clazz == null)
-				loadClass();
-			allInstantiatedTeams.add(this.clazz); // do this before accessing the constructor to avoid circularity (see Trac #257).
-			Object newInstance = this.clazz.newInstance();
-			return newInstance;
-		}
-		
-		private void loadClass() throws ClassNotFoundException {
-			for (String candidateName : possibleTeamNames(this.teamName)) {
-				try {
-					this.clazz = this.aspectBundle.loadClass(candidateName);
-					return; 
-				} catch (ClassNotFoundException ex) {
-					// keep going if we still have candidates
-				}
-			}
-			throw new ClassNotFoundException(this.teamName);
-		}
-
-		/** 
-		 * Starting from currentName compute a list of potential binary names of (nested) teams
-		 * using "$__OT__" as the separator, to find class parts of nested teams.  
-		 */
-		private List<String> possibleTeamNames(String currentName) {
-			List<String> result = new ArrayList<String>();
-			result.add(currentName);
-			char sep = '.'; // assume source name
-			if (currentName.indexOf('$') > -1)
-				// binary name
-				sep = '$';
-			int from = currentName.length()-1;
-			while (true) {
-				int pos = currentName.lastIndexOf(sep, from);
-				if (pos == -1)
-					break;
-				String prefix = currentName.substring(0, pos); 
-				String postfix = currentName.substring(pos+1);
-				if (sep=='$') {
-					if (!postfix.startsWith("__OT__"))
-						result.add(0, currentName = prefix+"$__OT__"+postfix);
-				} else {
-					// heuristic: 
-					// only replace if parent element looks like a class (expected to start with uppercase)
-					int prevDot = prefix.lastIndexOf('.');
-					if (prevDot > -1 && Character.isUpperCase(prefix.charAt(prevDot+1))) 
-						result.add(0, currentName = prefix+"$__OT__"+postfix);
-					else 
-						break;
-				}
-				from = pos-1;
-			}
-			return result;
-		}
-
-		public void markAsActivated() {
-			allActivations.put(this.clazz, this.activation);			
-		}
-		
-		public ActivationKind getActualActivation() {
-			ActivationKind kind = allActivations.get(this.clazz);
-			if (kind == null)
-				return ActivationKind.NONE;
-			return kind;
-		}		
-	}
-	
-	Bundle baseBundle;
-	
-	/** Team classes waiting for activation. */
-	private List<TeamClassRecord> teamClasses = new ArrayList<TeamClassRecord>();
-	
-	private HashMap<Bundle,List<String>> baseBundleToAspectName = new HashMap<Bundle, List<String>>(); 
-
-	public MasterTeamLoader(Bundle baseBundle) {
-		this.baseBundle = baseBundle;
-	}
-
-	/** 
-	 * Load all teams adapting baseBundle and the adapted base classes.
-	 * TODO(SH): No checks are yet performed, whether the teams found in extensions actually
-	 * match the given baseBundle.
-	 *
-	 * @param baseBundle   an adaptable base bundle which was just activated.
-	 * @param classScanner helper for reading OT bytecode attributes.
-	 * @param bindings     declared aspect bindings for this bundle
-	 * @return whether or not teams have been loaded successfully
-	 */
-	public boolean loadTeams(Bundle baseBundle, ClassScanner classScanner, ArrayList<AspectBinding> bindings) 
-	{
-		for (final AspectBinding binding : bindings) {
-			String aspectBundleName = binding.aspectPlugin;
-			
-			log(IStatus.OK, ">>> TransformerPlugin loading aspect plugin "+aspectBundleName+" <<<");
-			
-			final Bundle aspectBundle = OSGIUtils.getDefault().getBundle(aspectBundleName);
-			if (aspectBundle == null) {
-				Throwable t = new Exception("Aspect bundle "+aspectBundleName+" does not exist.");
-				t.fillInStackTrace();
-				log(t, "Failed to load teams for an aspect plugin.");
-			}
-
-			// load and store the team classes:
-			for (int i = 0; i < binding.teamClasses.length; i++) {
-				try {
-					TeamClassRecord teamClassRecord = new TeamClassRecord(
-												aspectBundle, binding.teamClasses[i],
-												binding.activations[i]
-										);
-					this.teamClasses.add(teamClassRecord);
-					teamClassRecord.readOTAttributes(classScanner); // disable to revert to early loading
-					if (binding.subTeamClasses[i] != null)
-						for (String subTeamName : binding.subTeamClasses[i])
-							teamClassRecord.readOTAttributes(classScanner, subTeamName); // FIXME(SH): really use the same TeamClassRecord??
-
-				} catch (Throwable t) {
-					log(t, "Exception occurred while loading team class"); //$NON-NLS-1$				
-				}
-			}
-			
-			// store aspectBundleName for PHASE 2:
-			List<String> aspectNames = baseBundleToAspectName.get(baseBundle);
-			if (aspectNames == null) 
-				baseBundleToAspectName.put(baseBundle, aspectNames = new ArrayList<String>()); 
-			aspectNames.add(aspectBundleName);			
-		}
-		return !this.teamClasses.isEmpty();
-	}
-
-	/**
-	 * Instantiate all team classes loaded before. 
-	 * Before doing so all adapted base classes have to be loaded, too.
-     * 
-	 * @pre the AspectPermissionManager should be ready (ie., instance location is set), otherwise
-	 * 	workspace settings have to be ignored (error should be signaled by client).
-	 * 
-	 * @param  baseBundle		 only teams adapting this base bundle should be instantiated
-	 * @param  triggerClassname  loading of this class triggered this instantiation (may be null)
-     * @param  permissionManager helper for checking permissions of aspectBinding / forcedExport
-	 * @return list of team instances (maybe empty). Null signal that instantiation had to be deferred.
-	 */
-	public List<Object> instantiateLoadedTeams(Bundle baseBundle, String triggerClassname, AspectPermissionManager permissionManager) 
-	{
-		List<Object> teamInstances = new ArrayList<Object>(this.teamClasses.size());
-
-		// permission checking can be performed now or later, depending on readiness:
-		boolean permissionManagerReady = permissionManager.isReady();
-		
-		// ==== check permissions before we start activating:
-		if (permissionManagerReady) { // otherwise we will register pending obligations below.
-			boolean hasDenial = false;
-			for (TeamClassRecord teamClass : this.teamClasses)
-				if (!permissionManager.checkTeamBinding(teamClass.aspectBundle.getSymbolicName(), baseBundle.getSymbolicName(), teamClass.teamName)) 
-				{
-					hasDenial = true;
-					try {
-						teamClass.aspectBundle.stop();
-						log(ILogger.ERROR, "Stopped bundle "+teamClass.aspectBundle.getSymbolicName()+" which requests unconfirmed aspect binding(s).");
-					} catch (BundleException e) {
-						log(e, "Failed to stop bundle "+teamClass.aspectBundle.getSymbolicName()+" which requests unconfirmed aspect binding(s).");
-					}
-				}
-			if (hasDenial)
-				return teamInstances; // still empty list
-		}
-
-		// ==== instantiate the teams:
-		for (TeamClassRecord teamClass : this.teamClasses) {
-			if (teamClass.activation ==  ActivationKind.NONE)
-				continue;
-			try {
-				if (teamClass.isAlreadyHandled()) { // previously instantiated due to a different aspectBinding/basePlugin?
-					ActivationKind actualActivation = teamClass.getActualActivation();
-					if (   actualActivation     != teamClass.activation
-						&& actualActivation     != ActivationKind.NONE
-						&& teamClass.activation != ActivationKind.NONE)
-					{
-						log(IStatus.WARNING, "Conflicting activation requests in aspect bindings for team class "+teamClass.teamName);
-					}
-				} else {
-					Object newTeam = teamClass.newInstance();
-					teamInstances.add(newTeam);
-				
-					Class<?>[] activationArgumentTypes = new Class[0];
-					Object[] activationArguments    = null;
-					switch(teamClass.activation) {
-					case ALL_THREADS:
-						 activationArgumentTypes = new Class[]{Thread.class};
-						 activationArguments = new Object[] {TeamClassRecord.get_ALL_THREADS()};
-						 // fall through
-					case THREAD:
-						Method activationMethod = teamClass.clazz.getMethod("activate", activationArgumentTypes);
-						activationMethod.invoke(newTeam, activationArguments);
-						log(IStatus.OK, ">>> instantiated team: "+teamClass.clazz+", activation: "+teamClass.activation+" <<<");
-						teamClass.markAsActivated();
-						break;
-					case NONE:
-						// nothing ;-)
-					}
-				}
-			} catch (Throwable t) {
-				t.printStackTrace();
-			}
-		}
-		if (!permissionManagerReady)
-			permissionManager.addBaseBundleObligations(teamInstances, new ArrayList<TeamClassRecord>(this.teamClasses), baseBundle);
-		return teamInstances;
-	}
-	
-	void log(int status, String msg) {
-		TransformerPlugin.getDefault().log(status, msg);
-	}
-	void log(Throwable t, String msg) {
-		TransformerPlugin.getDefault().log(t, msg);
-	}
-}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/TransformerServiceDelegate.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/TransformerServiceDelegate.java
deleted file mode 100644
index 7918543..0000000
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/internal/TransformerServiceDelegate.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- * 
- * 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.eclipse.objectteams.otequinox.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.instrument.ClassFileTransformer;
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
-import org.eclipse.objectteams.otre.util.CallinBindingManager;
-
-import org.eclipse.objectteams.otequinox.hook.IOTTransformer;
-
-/**
- * Service implementation for providing org.eclipse.objectteams.otequinox.hook with an
- * access to the OTRE.
- * 
- * @author stephan
- * @since 0.7.0
- */
-public class TransformerServiceDelegate implements IOTTransformer {
-
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.objectteams.otequinox.hook.IOTTransformer#getNewTransformer()
-	 */
-	public ClassFileTransformer getNewTransformer() {
-		return new ObjectTeamsTransformer();
-	}
-	
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.objectteams.otequinox.hook.IOTTransformer#readOTAttributes(java.io.InputStream, java.lang.String, java.lang.ClassLoader)
-	 */
-	public Object readOTAttributes(InputStream openStream, String file, ClassLoader loader) 
-			throws ClassFormatError, IOException 
-	{
-		ObjectTeamsTransformer transformer = new ObjectTeamsTransformer();
-		transformer.readOTAttributes(openStream, file, loader);
-		return transformer;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.objectteams.otequinox.hook.IOTTransformer#fetchAdaptedBases(java.lang.Object)
-	 */
-	public Collection<String> fetchAdaptedBases(Object token) {
-		try {
-			return ((ObjectTeamsTransformer)token).fetchAdaptedBases();
-		} catch (ClassCastException cce) {
-			throw new IllegalArgumentException("Provided token is not an ObjectTeamsTransformer");
-		}
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.objectteams.otequinox.hook.IOTTransformer#getRolesPerTeam(java.lang.String)
-	 */
-	public List<String> getRolesPerTeam(String teamClassName) {
-		return CallinBindingManager.getRolePerTeam(teamClassName);
-	}
-
-}
diff --git a/plugins/org.eclipse.objectteams.runtime/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.runtime/META-INF/MANIFEST.MF
index 0b3fbfd..dc04807 100644
--- a/plugins/org.eclipse.objectteams.runtime/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.runtime/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.objectteams.runtime
-Bundle-Version: 2.2.0.qualifier
+Bundle-Version: 2.3.0.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
-Export-Package: org.eclipse.objectteams.otre;version="2.1.0",
+Export-Package: org.eclipse.objectteams.otre;version="2.3.0",
  org.eclipse.objectteams.otre.bcel;version="2.1.0",
- org.eclipse.objectteams.otre.jplis;version="2.1.0",
+ org.eclipse.objectteams.otre.jplis;version="2.3.0",
  org.eclipse.objectteams.otre.util;version="2.0.0",
  org.objectteams;version="2.0.0"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/BaseCallRedirection.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/BaseCallRedirection.java
index 639a870..c1357e3 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/BaseCallRedirection.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/BaseCallRedirection.java
@@ -58,7 +58,7 @@
 		public InstructionHandle snd() {return _ih2; }
 	}
 
-    public BaseCallRedirection(ClassLoader loader) {
+    public BaseCallRedirection(Object loader) {
     	super(loader);
     }
     
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java
index 2118419..ad2d6b4 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/BaseMethodTransformation.java
@@ -142,7 +142,7 @@
 
 	public boolean useReflection = false;
 
-	public BaseMethodTransformation(ClassLoader loader) {
+	public BaseMethodTransformation(Object loader) {
 		super(loader);
 	}
 	/**
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/ClassLoaderAccess.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/ClassLoaderAccess.java
new file mode 100644
index 0000000..a92e184
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/ClassLoaderAccess.java
@@ -0,0 +1,69 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ * 
+ * Copyright 2013 GK Software AG
+ *  
+ * 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
+ * 
+ * Please visit http://www.objectteams.org for updates and contact.
+ * 
+ * Contributors:
+ * 	Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otre;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+
+/**
+ * Generalization over different strategies for obtaining a resource / class on the classpath.
+ * <p>
+ * If a {@link ClassLoader} is provided use its method {@link ClassLoader#getResource(String)} 
+ * and {@link ClassLoader#loadClass(String)}.
+ * </p><p>
+ * Otherwise we need a {@link Method} instance for each kind of access which needs to match
+ * the type of the object passed as "loader". The latter method is used in Equinox settings,
+ * where the "loader" will be an <code>org.osgi.framework.Bundle</code>.
+ * </p><p>
+ * Selecting one of the above strategies happens globally when the system start up,
+ * which implies that {@link #setGetResource(Method)} and {@link #setLoadClass(Method)}
+ * need to be called before any weaving is triggered.
+ * </p>
+ */
+public class ClassLoaderAccess {
+
+	private static Method getResourceMethod;
+	private static Method loadClassMethod;
+
+	public static void setGetResource(Method method) {
+		getResourceMethod = method;
+	}
+	public static void setLoadClass(Method method) {
+		loadClassMethod = method;
+	}
+
+	public static InputStream getResourceAsStream(Object loader, String name) {
+		if (loader instanceof ClassLoader)
+			return ((ClassLoader) loader).getResourceAsStream(name);
+		try {
+			URL url = (URL) getResourceMethod.invoke(loader, name);
+			return url.openStream();
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	public static Class<?> loadClass(Object loader, String name) 
+			throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException 
+	{
+		if (loader instanceof ClassLoader)
+			return ((ClassLoader) loader).loadClass(name);
+		else
+			return (Class<?>)loadClassMethod.invoke(loader, name);
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/Decapsulation.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/Decapsulation.java
index c91e352..c9c8ae1 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/Decapsulation.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/Decapsulation.java
@@ -53,7 +53,7 @@
 	private HashSet<String/*callout accessed fields*/> generatedFieldCalloutAccessors = new HashSet<String>();
 	private HashSet<String/*super-accessed methods (sign)*/> generatedSuperAccessors  = new HashSet<String>();
 	
-    public Decapsulation(ClassLoader loader) {
+    public Decapsulation(Object loader) {
     	super(loader);
     }
 
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java
index 0dcdb56..14c402c 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/LiftingParticipantTransformation.java
@@ -69,7 +69,7 @@
 	private static final String CREATE_ROLE_METHOD = "createRole";
 	private static final String LIFTING_PARTICIPANT_FIELD = "_OT$liftingParticipant";
 	
-	public LiftingParticipantTransformation(ClassLoader loader) { super(loader); }
+	public LiftingParticipantTransformation(Object loader) { super(loader); }
 
 	public void doTransformCode(ClassGen cg) 
 	{
@@ -116,7 +116,7 @@
 			if (participant != null)
 				throw new IllegalStateException("liftingParticipant already installed.");				
 			// install a shared instance into class Team:
-			Class<?> participantClass = loader.loadClass(PARTICIPANT_NAME);
+			Class<?> participantClass = ClassLoaderAccess.loadClass(loader, PARTICIPANT_NAME); 
 			participantField.set(null, participantClass.newInstance());
 		} 
 		else if (participant != null) 
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java
index 1463e2a..7d4d736 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/ObjectTeamsTransformation.java
@@ -34,7 +34,6 @@
 import org.eclipse.objectteams.otre.util.AttributeReadingGuard;
 import org.eclipse.objectteams.otre.util.CallinBindingManager;
 import org.eclipse.objectteams.otre.util.RoleBaseBinding;
-
 import org.apache.bcel.Constants;
 import org.apache.bcel.classfile.Attribute;
 import org.apache.bcel.classfile.Constant;
@@ -95,9 +94,9 @@
 	InstructionFactory factory;
    
     /** Which class loader are we working for? */
-    protected ClassLoader loader;
+    protected Object loader; // standalone: ClassLoader, new equinox.weaving: Bundle
 
-	public ObjectTeamsTransformation(ClassLoader loader) {
+	public ObjectTeamsTransformation(Object loader) {
 		this.loader = loader;
 	}
 
@@ -558,12 +557,31 @@
 								  		 String class_name,
 								  		 ConstantPoolGen cpg)
     {
+    	checkReadClassAttributes(ce, cg, class_name, cpg, false);
+    }
+    public void checkReadClassAttributes(ClassEnhancer ce,
+	         ClassGen cg,
+	  		 String class_name,
+	  		 ConstantPoolGen cpg,
+	  		 boolean isScanOnly)
+    {
+
     	AttributeReadingGuard guard = AttributeReadingGuard.getInstanceForLoader(this.loader);
     	boolean addTeamInitializations = false;
     	List<String> classesToLoad;
     	synchronized (guard) {
-    		if (!guard.iAmTheFirst(class_name))
-    			return;
+    		if (!guard.iAmTheFirst(class_name)) {
+    			if (isScanOnly && class_name.equals("org.eclipse.objectteams.otdt.test.builder.OTTestingEnvironment")) {
+    				System.err.println("I'm not the first "+this);
+    				System.err.println(" guard ="+guard);
+    				System.err.println(" loader="+this.loader);
+    				System.err.println(" class ="+class_name);
+    				new Exception("I'm not the first "+this).printStackTrace();
+    			}
+				return;
+			}
+    		if (class_name.equals("org.eclipse.objectteams.otdt.test.builder.OTTestingEnvironment"))
+    			new Exception("I AM the first "+this).printStackTrace();
 			if (AttributeReadingGuard.isFirstLoadedClass())
 				addTeamInitializations = true;
 			// scan for attributes here, because this transformer is applied first:
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/RepositoryAccess.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/RepositoryAccess.java
index 04b6fd0..15cd23c 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/RepositoryAccess.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/RepositoryAccess.java
@@ -32,7 +32,7 @@
 public class RepositoryAccess {
 
 	/** One class repository per class loader. */
-	private static HashMap<ClassLoader,DietClassLoaderRepository> repositories = new HashMap<ClassLoader,DietClassLoaderRepository>();
+	private static HashMap<Object,DietClassLoaderRepository> repositories = new HashMap<Object,DietClassLoaderRepository>();
 	/** One current repository per thread. */
 	private static ThreadLocal<DietClassLoaderRepository> currentRepository = new ThreadLocal<DietClassLoaderRepository>();
 	 
@@ -41,7 +41,7 @@
 	 * @param loader class loader, may be null
 	 * @return the previously active class repository for this thread
 	 */
-	public static synchronized DietClassLoaderRepository setClassLoader(ClassLoader loader) {
+	public static synchronized DietClassLoaderRepository setClassLoader(Object loader) {
 		DietClassLoaderRepository clr = null;
 		if (loader != null) { // avoid creating ClassLoaderRepository with null loader
 			clr = repositories.get(loader);
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java
index 7d75263..92faa22 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/StaticSliceBaseTransformation.java
@@ -21,7 +21,6 @@
 import org.apache.bcel.classfile.*;
 import org.apache.bcel.generic.*;
 import org.apache.bcel.*;
-
 import org.eclipse.objectteams.otre.util.*;
 import org.eclipse.objectteams.otre.util.CallinBindingManager.BoundSuperKind;
 
@@ -50,7 +49,7 @@
 	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(ClassLoader loader) { super(loader); }
+	public StaticSliceBaseTransformation(Object loader) { super(loader); }
 	
 	private HashMap<String,String> rejectReasons = new HashMap<String, String>();
 
@@ -209,8 +208,6 @@
                                                     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());
@@ -306,13 +303,10 @@
 			// 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);
-
+	  InstructionHandle exit =
 		il.append(InstructionFactory.createReturn(Type.VOID));
+	    earlyExit.setTarget(exit);
+
 
 		addTeamMethod.setMaxStack();
 		addTeamMethod.setMaxLocals();
@@ -370,9 +364,6 @@
                                                     "_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);
@@ -522,14 +513,10 @@
 			// 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);
-
+	  InstructionHandle exit =
 		il.append(InstructionFactory.createReturn(Type.VOID));
+	  	earlyExit.setTarget(exit);
+	  	notFound.setTarget(exit);
 
 		removeTeamMethod.setMaxStack();
 		removeTeamMethod.setMaxLocals();
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java
index 92e2656..9dc5691 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/SubBoundBaseMethodRedefinition.java
@@ -38,7 +38,7 @@
 public class SubBoundBaseMethodRedefinition 
 	extends ObjectTeamsTransformation {
 
-	public SubBoundBaseMethodRedefinition(ClassLoader loader) { super(loader); }
+	public SubBoundBaseMethodRedefinition(Object loader) { super(loader); }
 
 	/**
 	 * Main entry for this transformer.
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java
index ce29d45..6bacee9 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/TeamInterfaceImplementation.java
@@ -46,7 +46,7 @@
 	extends ObjectTeamsTransformation {
 
 
-	public TeamInterfaceImplementation(ClassLoader loader) {
+	public TeamInterfaceImplementation(Object loader) {
 		super(loader);
 	}
 
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/bcel/DietClassLoaderRepository.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/bcel/DietClassLoaderRepository.java
index f5654cf..c67b14a 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/bcel/DietClassLoaderRepository.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/bcel/DietClassLoaderRepository.java
@@ -38,6 +38,7 @@
 
 import org.apache.bcel.classfile.JavaClass;
 import org.apache.bcel.util.ClassLoaderRepository;
+import org.eclipse.objectteams.otre.ClassLoaderAccess;
 
 /**
  * Class loader repository that retains less memory than BCEL's original.
@@ -46,10 +47,10 @@
 public class DietClassLoaderRepository extends ClassLoaderRepository {
 
 	// repeat a field that is private in the super class:
-	ClassLoader dietClassLoaderRepository_loader;
+	Object dietClassLoaderRepository_loader;
 	
-	public DietClassLoaderRepository(ClassLoader loader) {
-		super(loader);
+	public DietClassLoaderRepository(Object loader) {
+		super(loader instanceof ClassLoader ? (ClassLoader) loader : null);
 		dietClassLoaderRepository_loader = loader;
 	}
 
@@ -61,13 +62,15 @@
             return c;
         }
         try {
-            InputStream is = dietClassLoaderRepository_loader.getResourceAsStream(classFile + ".class");
+            InputStream is = ClassLoaderAccess.getResourceAsStream(dietClassLoaderRepository_loader, classFile + ".class");
             if (is == null) {
                 throw new ClassNotFoundException(className + " not found.");
             }
             DietClassParser parser = new DietClassParser(is, className);
             c = parser.parse();
-            storeClass(c);
+            synchronized(this) {
+           		storeClass(c);
+            }
             return c;
         } catch (IOException e) {
             throw new ClassNotFoundException(e.toString());
@@ -78,7 +81,9 @@
         if (c != null) { 
         	if (! (c instanceof DietJavaClass))
         		return c; // found fully parsed class, OK.
-        	removeClass(c); // force new loading
+        	synchronized(this) {
+        		removeClass(c); // force new loading
+        	}
         }
 		return super.loadClass(className);
 	}
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java
index e752986..29d0c11 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/jplis/JPLISEnhancer.java
@@ -21,9 +21,9 @@
 import java.io.InputStream;
 
 import org.eclipse.objectteams.otre.ClassEnhancer;
+import org.eclipse.objectteams.otre.ClassLoaderAccess;
 import org.eclipse.objectteams.otre.OTREInternalError;
 import org.eclipse.objectteams.otre.ObjectTeamsTransformation;
-
 import org.apache.bcel.Constants;
 import org.apache.bcel.classfile.ClassParser;
 import org.apache.bcel.classfile.Field;
@@ -44,9 +44,9 @@
 
 public class JPLISEnhancer implements ClassEnhancer {
 
-	private ClassLoader loader;
+	private Object loader;
 	
-	public JPLISEnhancer(ClassGen cg, ClassLoader loader) {
+	public JPLISEnhancer(ClassGen cg, Object loader) {
 		this.loader = loader;
 	}
 	
@@ -109,7 +109,7 @@
 		InputStream is = null;
 		try {
 			String binaryName = className.replace('.', '/');
-			is = loader.getResourceAsStream(binaryName+".class");
+			is = ClassLoaderAccess.getResourceAsStream(this.loader, binaryName+".class");
 			if (is != null) {
 				ClassGen cg = new ClassGen(new ClassParser(is, className).parse());
 				client.checkReadClassAttributes(this, cg, className, cg.getConstantPool());
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java
index 5944db4..0f0e3f6 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/jplis/ObjectTeamsTransformer.java
@@ -65,6 +65,7 @@
 	};
 
 	static boolean warmedUp = false;
+
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -72,7 +73,13 @@
 	 *      java.lang.String, java.lang.Class, java.security.ProtectionDomain,
 	 *      byte[])
 	 */
-	public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
+	public byte[] transform(ClassLoader loader, String className,
+			Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
+			byte[] classfileBuffer) throws IllegalClassFormatException {
+		return transform((Object)loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
+	}
+	
+	public byte[] transform(Object loader, String className, Class<?> classBeingRedefined,
 			ProtectionDomain protectionDomain, byte[] classfileBuffer)
 			throws IllegalClassFormatException
 	{
@@ -86,7 +93,7 @@
 			}		
 		}
 	}
-	public byte[] internalTransform(ClassLoader loader, String className, Class<?> classBeingRedefined,
+	public byte[] internalTransform(Object loader, String className, Class<?> classBeingRedefined,
 			ProtectionDomain protectionDomain, byte[] classfileBuffer)
 			throws IllegalClassFormatException
 	{
@@ -191,7 +198,8 @@
 			
 			JavaClass new_java_class = cg.getJavaClass(); 
 			if (dumping) {
-				new_java_class.dump("jplis_dump/" + className + ".class");
+				String binaryName = className.replace('.','/');
+				new_java_class.dump("jplis_dump/" + binaryName + ".class");
 			}
 			return new_java_class.getBytes();
 		} catch (IOException e) {
@@ -228,7 +236,7 @@
 	 * @throws IOException 
 	 * @throws ClassFormatError 
 	 */
-	public void readOTAttributes(InputStream file, String fileName, ClassLoader loader) 
+	public void readOTAttributes(InputStream file, String fileName, Object loader) 
 			throws ClassFormatError, IOException 
 	{
 		ClassParser   cp  = new ClassParser(file, fileName);
@@ -237,7 +245,7 @@
 		DietClassLoaderRepository prevRepository = RepositoryAccess.setClassLoader(loader);
 		try {
 			setFirstTransformation(new ObjectTeamsTransformation(loader) {});
-			firstTransformation.checkReadClassAttributes(jpe, cg, cg.getClassName(), cg.getConstantPool());
+			firstTransformation.checkReadClassAttributes(jpe, cg, cg.getClassName(), cg.getConstantPool(), true);
 		} finally {
 			RepositoryAccess.resetRepository(prevRepository);
 		}
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java
index 4d72e02..cbda8f2 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otre/util/AttributeReadingGuard.java
@@ -25,7 +25,7 @@
  */
 public class AttributeReadingGuard {
 	
-	private static Map<ClassLoader, AttributeReadingGuard> instances = new HashMap<ClassLoader, AttributeReadingGuard>();
+	private static Map<Object, AttributeReadingGuard> instances = new HashMap<Object, AttributeReadingGuard>();
     private static AttributeReadingGuard defaultInstance = new AttributeReadingGuard();
     
     private ArrayList<String> servedClasses = new ArrayList<String>();
@@ -49,6 +49,15 @@
     	this.servedClasses.add(className);    
     }
     
+    @Override
+    public String toString() {
+    	StringBuilder buf = new StringBuilder("AttributeReadingGuard with served classes:");
+    	for (String clazz : servedClasses) {
+			buf.append("\n\t"+clazz);
+		}
+    	return buf.toString();
+    }
+    
     /**
      * @return whether this class is the first being loaded => possibly the main class.
      */
@@ -66,15 +75,15 @@
 
 	/**
 	 * Since actual data are stored in an instance, static methods need to retrieve the appropriate
-     * instance regarding the given class loader.
+     * instance regarding the given token (s.t. like a class loader).
 	 */
-	public static AttributeReadingGuard getInstanceForLoader(ClassLoader loader) {
-		if (loader == null)
+	public static AttributeReadingGuard getInstanceForLoader(Object token) {
+		if (token == null)
 			return defaultInstance;
 		
-		AttributeReadingGuard instance = instances.get(loader);
+		AttributeReadingGuard instance = instances.get(token);
 		if (instance == null)
-			instances.put(loader, instance = new AttributeReadingGuard());
+			instances.put(token, instance = new AttributeReadingGuard());
 		return instance;
 	}
 }
diff --git a/releng/build-scripts/build/run.properties b/releng/build-scripts/build/run.properties
index b366f4a..72cb0ef 100644
--- a/releng/build-scripts/build/run.properties
+++ b/releng/build-scripts/build/run.properties
@@ -22,12 +22,12 @@
 
 # ------------- insert current versions here ---------------
 # Details of the Eclipse SDK built upon:
-run.eclipseScriptDir=plugins/org.eclipse.pde.build_3.8.100.v20130514-1028/scripts
-org.eclipse.equinox.launcher_jar=org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar
+run.eclipseScriptDir=plugins/org.eclipse.pde.build_3.9.0.N20130724-2000/scripts
+org.eclipse.equinox.launcher_jar=org.eclipse.equinox.launcher_1.3.0.N20130724-2000.jar
 
 # for patching our patch feature to match this version with any suffix:
-jdt.feature.version=3.10.0.v20130709-08003.10.0.v20130709-0800
-jdt.feature.version.next=3.10.0.v20130709-0800
+jdt.feature.version=3.10.0.N20130724-20003.10.0.N20130724-2000
+jdt.feature.version.next=3.10.0.N20130724-2000
 # -----------------------------------------------------------
 
 #Git Support for PDE BUILD:
diff --git a/releng/build-scripts/build/run.xml b/releng/build-scripts/build/run.xml
index cf7c241..ed00d8f 100644
--- a/releng/build-scripts/build/run.xml
+++ b/releng/build-scripts/build/run.xml
@@ -137,6 +137,7 @@
 		<echo message="Starting BuildProcess in ${build.root.dir}"/>
 		<antcall target="verifyAntInstall"/>
 		<antcall target="createOTDTEclipse"/>
+		<antcall target="setupTests" />
 	</target>
 
 	<target name="ot-compiler-build" depends="setupProperties,checkOS" description="build only the compiler (for debugging the build)">
@@ -150,6 +151,11 @@
 		<antcall target="runAllTests" />
 	</target>
 
+	<target name="ot-junit-run-ot" depends="setupProperties,checkOS" description="Run OT tests without building">
+		<echo message="Starting Testrun ${test.root.dir}"/>
+		<antcall target="runOTDTTests" />
+	</target>
+
 	<!-- =================== END Public Targets ==================== -->
 
 	<!-- === Setup Targets: === -->
diff --git a/releng/build-scripts/build/test.properties.in b/releng/build-scripts/build/test.properties.in
index afc529f..ed47270 100644
--- a/releng/build-scripts/build/test.properties.in
+++ b/releng/build-scripts/build/test.properties.in
@@ -2,8 +2,8 @@
 
 # ----
 org.eclipse.jdt.core.tests.builder=org.eclipse.jdt.core.tests.builder_3.8.2.@SDK_QUALIFIER@
-org.eclipse.jdt.debug.tests=org.eclipse.jdt.debug.tests_3.8.100.@SDK_QUALIFIER@
-org.eclipse.jdt.ui.tests=org.eclipse.jdt.ui.tests_3.9.0.@SDK_QUALIFIER@
+org.eclipse.jdt.debug.tests=org.eclipse.jdt.debug.tests_3.8.200.@SDK_QUALIFIER@
+org.eclipse.jdt.ui.tests=org.eclipse.jdt.ui.tests_3.10.0.@SDK_QUALIFIER@
 org.eclipse.jdt.ui.tests.refactoring=org.eclipse.jdt.ui.tests.refactoring_3.9.0.@SDK_QUALIFIER@
 org.eclipse.test.performance=org.eclipse.test.performance_3.7.0.@SDK_QUALIFIER@
 # ----
@@ -12,10 +12,10 @@
 org.eclipse.jdt.core.tests.compiler=org.eclipse.jdt.core.tests.compiler_3.8.3

 org.eclipse.jdt.core.tests.model=org.eclipse.jdt.core.tests.model_3.8.2

 
-org.eclipse.objectteams.otdt.tests=org.eclipse.objectteams.otdt.tests_1.3.0
-org.eclipse.objectteams.otdt.ui.tests=org.eclipse.objectteams.otdt.ui.tests_1.3.0
-org.eclipse.objectteams.otdt.ui.tests.dom=org.eclipse.objectteams.otdt.ui.tests.dom_1.3.0
-org.eclipse.objectteams.otdt.debug.tests=org.eclipse.objectteams.otdt.debug.tests_1.3.0
-org.eclipse.objectteams.otdt.ui.tests.refactoring=org.eclipse.objectteams.otdt.ui.tests.refactoring_1.3.0
-org.eclipse.objectteams.otdt.test.builder=org.eclipse.objectteams.otdt.test.builder_1.3.0
+org.eclipse.objectteams.otdt.tests=org.eclipse.objectteams.otdt.tests_2.0.0
+org.eclipse.objectteams.otdt.ui.tests=org.eclipse.objectteams.otdt.ui.tests_2.0.0
+org.eclipse.objectteams.otdt.ui.tests.dom=org.eclipse.objectteams.otdt.ui.tests.dom_2.0.0
+org.eclipse.objectteams.otdt.debug.tests=org.eclipse.objectteams.otdt.debug.tests_2.0.0
+org.eclipse.objectteams.otdt.ui.tests.refactoring=org.eclipse.objectteams.otdt.ui.tests.refactoring_2.0.0
+org.eclipse.objectteams.otdt.test.builder=org.eclipse.objectteams.otdt.test.builder_2.0.0
 
diff --git a/testplugins/org.eclipse.objectteams.otdt.debug.tests/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.debug.tests/META-INF/MANIFEST.MF
index 0a69cae..de01f9d 100644
--- a/testplugins/org.eclipse.objectteams.otdt.debug.tests/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.debug.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2

 Bundle-Name: OTDT DebugTest Plug-in

 Bundle-SymbolicName: org.eclipse.objectteams.otdt.debug.tests;singleton:=true

-Bundle-Version: 1.3.0

+Bundle-Version: 1.0.0

 Bundle-ClassPath: otdt-debugtests.jar

 Bundle-Activator: org.eclipse.objectteams.otdt.debug.tests.DebugTestsPlugin

 Bundle-Vendor: Fraunhofer FIRST

diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.test.builder/META-INF/MANIFEST.MF
index 5c4ae8a..392cf0e 100644
--- a/testplugins/org.eclipse.objectteams.otdt.test.builder/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Builder Plug-in
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.test.builder;singleton:=true
-Bundle-Version: 1.3.0
+Bundle-Version: 2.0.0
 Bundle-ClassPath: otdt-buildertests.jar
 Bundle-Activator: org.eclipse.objectteams.otdt.test.builder.BuilderTestPlugin
 Bundle-Vendor: objectteams.org
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/src/org/eclipse/objectteams/otdt/test/builder/OTEquinoxBuilderTests.java b/testplugins/org.eclipse.objectteams.otdt.test.builder/src/org/eclipse/objectteams/otdt/test/builder/OTEquinoxBuilderTests.java
index 7ccd59c..68825e9 100644
--- a/testplugins/org.eclipse.objectteams.otdt.test.builder/src/org/eclipse/objectteams/otdt/test/builder/OTEquinoxBuilderTests.java
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/src/org/eclipse/objectteams/otdt/test/builder/OTEquinoxBuilderTests.java
@@ -368,6 +368,19 @@
 				});
 	}
 
+	public void testAspectExport () throws CoreException, IOException {
+		IJavaProject aeb= fileManager.setUpJavaProject("AspectExportBase"); 
+		env.addProject(aeb.getProject());
+		IJavaProject aea= fileManager.setUpJavaProject("AspectExportAspect"); 
+		aea.setOption("org.eclipse.objectteams.otdt.compiler.problem.binding_conventions", "error");
+		env.addProject(aea.getProject());
+		fullBuild();
+		expectingNoProblemsFor(aeb.getPath());
+		expectingOnlySpecificProblemsFor(aea.getPath(), 
+				new Problem[] {
+					getMissingAspectExportProblem(aea, "aea")});
+	}
+
 	// ---------------- HELPERS: ---------------------------
 	private Problem getDecapsulationProblem(IJavaProject project, String baseclassName, String teamPath, int start, int end) {
 		return new Problem("", "Decapsulating base class "+baseclassName+" by means of a forced export. Note, that additionally a corresponing declaration is needed in config.ini (OTJLD 2.1.2(c) + OT/Equinox).",
@@ -389,4 +402,10 @@
 						CategorizedProblem.CAT_RESTRICTION, IMarker.SEVERITY_ERROR)
 		);
 	}
+	private Problem getMissingAspectExportProblem(IJavaProject project, String packageName) {
+		return new Problem("", "Package "+packageName+" containing one or more bound teams must be exported.",
+				project.getPath().append(new Path("META-INF/MANIFEST.MF")), 
+				-1, -1,
+				-1, IMarker.SEVERITY_ERROR);
+	}
 }
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.classpath b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.classpath
new file mode 100644
index 0000000..9b7e6c5
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.classpath
@@ -0,0 +1,8 @@
+<?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 kind="con" path="OTRE"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.project b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.project
new file mode 100644
index 0000000..9f1f3c0
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>AspectExportAspect</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.objectteams.otdt.builder.OTJBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.objectteams.otdt.OTJavaNature</nature>
+	</natures>
+</projectDescription>
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.settings/org.eclipse.jdt.core.prefs b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..509e627
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,3 @@
+#Sat Nov 10 00:41:15 CET 2007
+eclipse.preferences.version=1
+org.eclipse.objectteams.otdt.compiler.problem.binding_conventions=error
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..00c4eff
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: AspectExportAspect Plug-in
+Bundle-SymbolicName: AspectExportAspect; singleton:=true
+Bundle-Version: 1.0.0
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.objectteams.otequinox,
+ AspectExportBase
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/build.properties b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/build.properties
new file mode 100644
index 0000000..2b0d95b
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+               META-INF/,\
+               .
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/plugin.xml b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/plugin.xml
new file mode 100644
index 0000000..b1fc5f3
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/plugin.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+
+   <extension
+         point="org.eclipse.ui.actionSets">
+      <actionSet
+            label="Sample Action Set"
+            visible="true"
+            id="Trac18a.actionSet">
+         <menu
+               label="Sample &amp;Menu"
+               id="sampleMenu">
+            <separator
+                  name="sampleGroup">
+            </separator>
+         </menu>
+         <action
+               label="&amp;Sample Action"
+               class="aea.actions.SampleAction"
+               tooltip="Hello, Eclipse world"
+               menubarPath="sampleMenu/sampleGroup"
+               toolbarPath="sampleGroup"
+               id="aea.actions.SampleAction">
+         </action>
+      </actionSet>
+   </extension>
+   <extension
+         point="org.eclipse.objectteams.otequinox.aspectBindings">
+      <aspectBinding
+            icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/calloutbinding_obj.gif">
+         <basePlugin
+               icon="platform:/plugin/org.eclipse.pde.ui/icons/obj16/plugin_obj.gif"
+               id="AspectExportBase">
+         </basePlugin>
+         <team
+               activation="ALL_THREADS"
+               class="aea.Team18"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+      </aspectBinding>
+   </extension>
+
+</plugin>
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/src/aea/Team18.java b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/src/aea/Team18.java
new file mode 100644
index 0000000..961dae3
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/src/aea/Team18.java
@@ -0,0 +1,16 @@
+/**
+ * 
+ */
+package aea;
+
+import base aeb.api.PublicBase;
+
+/**
+ * @author stephan
+ *
+ */
+public team class Team18 {
+	protected class RoleOfPublic playedBy PublicBase {
+		
+	}
+}
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/src/aea/actions/SampleAction.java b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/src/aea/actions/SampleAction.java
new file mode 100644
index 0000000..200fdcf
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportAspect/src/aea/actions/SampleAction.java
@@ -0,0 +1,64 @@
+package aea.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+/**
+ * Our sample action implements workbench action delegate.
+ * The action proxy will be created by the workbench and
+ * shown in the UI. When the user tries to use the action,
+ * this delegate will be created and execution will be 
+ * delegated to it.
+ * @see IWorkbenchWindowActionDelegate
+ */
+public class SampleAction implements IWorkbenchWindowActionDelegate {
+	private IWorkbenchWindow window;
+	/**
+	 * The constructor.
+	 */
+	public SampleAction() {
+	}
+
+	/**
+	 * The action has been activated. The argument of the
+	 * method represents the 'real' action sitting
+	 * in the workbench UI.
+	 * @see IWorkbenchWindowActionDelegate#run
+	 */
+	public void run(IAction action) {
+		MessageDialog.openInformation(
+			window.getShell(),
+			"Trac18a Plug-in",
+			"Hello, Aspect world");
+	}
+
+	/**
+	 * Selection in the workbench has been changed. We 
+	 * can change the state of the 'real' action here
+	 * if we want, but this can only happen after 
+	 * the delegate has been created.
+	 * @see IWorkbenchWindowActionDelegate#selectionChanged
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+
+	/**
+	 * We can use this method to dispose of any system
+	 * resources we previously allocated.
+	 * @see IWorkbenchWindowActionDelegate#dispose
+	 */
+	public void dispose() {
+	}
+
+	/**
+	 * We will cache window object in order to
+	 * be able to provide parent shell for the message dialog.
+	 * @see IWorkbenchWindowActionDelegate#init
+	 */
+	public void init(IWorkbenchWindow window) {
+		this.window = window;
+	}
+}
\ No newline at end of file
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/.classpath b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/.classpath
new file mode 100644
index 0000000..304e861
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/.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 kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/.project b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/.project
new file mode 100644
index 0000000..864c268
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>AspectBindingExport</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..39e732c
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/META-INF/MANIFEST.MF
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: AspectExportBase Plug-in
+Bundle-SymbolicName: AspectExportBase; singleton:=true
+Bundle-Version: 1.0.0
+Require-Bundle: org.eclipse.ui
+Export-Package: aeb.api
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/build.properties b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/build.properties
new file mode 100644
index 0000000..2b0d95b
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+               META-INF/,\
+               .
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/plugin.xml b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/plugin.xml
new file mode 100644
index 0000000..c6697a6
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/plugin.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+
+   <extension
+         point="org.eclipse.ui.actionSets">
+      <actionSet
+            label="Sample Action Set"
+            visible="true"
+            id="Trac18b.actionSet">
+         <menu
+               label="Sample &amp;Menu"
+               id="sampleMenu">
+            <separator
+                  name="sampleGroup">
+            </separator>
+         </menu>
+         <action
+               label="&amp;Sample Action"
+               class="aeb"
+               tooltip="Hello, Eclipse world"
+               menubarPath="sampleMenu/sampleGroup"
+               toolbarPath="sampleGroup"
+               id="aeb.actions.SampleAction">
+         </action>
+      </actionSet>
+   </extension>
+
+</plugin>
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/src/aeb/actions/SampleAction.java b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/src/aeb/actions/SampleAction.java
new file mode 100644
index 0000000..f44c5b6
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/src/aeb/actions/SampleAction.java
@@ -0,0 +1,64 @@
+package aeb.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+/**
+ * Our sample action implements workbench action delegate.
+ * The action proxy will be created by the workbench and
+ * shown in the UI. When the user tries to use the action,
+ * this delegate will be created and execution will be 
+ * delegated to it.
+ * @see IWorkbenchWindowActionDelegate
+ */
+public class SampleAction implements IWorkbenchWindowActionDelegate {
+	private IWorkbenchWindow window;
+	/**
+	 * The constructor.
+	 */
+	public SampleAction() {
+	}
+
+	/**
+	 * The action has been activated. The argument of the
+	 * method represents the 'real' action sitting
+	 * in the workbench UI.
+	 * @see IWorkbenchWindowActionDelegate#run
+	 */
+	public void run(IAction action) {
+		MessageDialog.openInformation(
+			window.getShell(),
+			"Trac18b Plug-in",
+			"Hello, Eclipse world");
+	}
+
+	/**
+	 * Selection in the workbench has been changed. We 
+	 * can change the state of the 'real' action here
+	 * if we want, but this can only happen after 
+	 * the delegate has been created.
+	 * @see IWorkbenchWindowActionDelegate#selectionChanged
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+
+	/**
+	 * We can use this method to dispose of any system
+	 * resources we previously allocated.
+	 * @see IWorkbenchWindowActionDelegate#dispose
+	 */
+	public void dispose() {
+	}
+
+	/**
+	 * We will cache window object in order to
+	 * be able to provide parent shell for the message dialog.
+	 * @see IWorkbenchWindowActionDelegate#init
+	 */
+	public void init(IWorkbenchWindow window) {
+		this.window = window;
+	}
+}
\ No newline at end of file
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/src/aeb/api/PublicBase.java b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/src/aeb/api/PublicBase.java
new file mode 100644
index 0000000..85f278e
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/AspectExportBase/src/aeb/api/PublicBase.java
@@ -0,0 +1,5 @@
+package aeb.api;
+
+public class PublicBase {
+
+}
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/Trac213a/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/Trac213a/META-INF/MANIFEST.MF
index ac78220..02d517f 100644
--- a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/Trac213a/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/Trac213a/META-INF/MANIFEST.MF
@@ -10,3 +10,4 @@
  Trac213b2;bundle-version="1.0.0"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: trac213a
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/Trac304ot/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/Trac304ot/META-INF/MANIFEST.MF
index deb3ef3..93a32d2 100644
--- a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/Trac304ot/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/Trac304ot/META-INF/MANIFEST.MF
@@ -10,3 +10,4 @@
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Import-Package: trac304b
+Export-Package: trac304ot;ot-aspect-host=Trac304ot
diff --git a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/UnresolvedBasePlugin/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/UnresolvedBasePlugin/META-INF/MANIFEST.MF
index fcd8fbf..bbd6824 100644
--- a/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/UnresolvedBasePlugin/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.test.builder/workspace/UnresolvedBasePlugin/META-INF/MANIFEST.MF
@@ -7,3 +7,4 @@
  org.eclipse.objectteams.runtime
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: pack
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.tests/META-INF/MANIFEST.MF
index eedbb14..5d29bc9 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: OTDTTest Plug-in
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.tests;singleton:=true
-Bundle-Version: 1.3.0
+Bundle-Version: 2.0.0
 Bundle-ClassPath: otdt-tests.jar
 Bundle-Vendor: The TOPPrax consortium
 Export-Package: org.eclipse.objectteams.otdt.tests,
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests.dom/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.ui.tests.dom/META-INF/MANIFEST.MF
index 066d2c4..06ad01f 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests.dom/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests.dom/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Manifest-Version: 1.0
 Bundle-Name: OTDT DOMTest Plug-in
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.ui.tests.dom;singleton:=true
-Bundle-Version: 1.3.0
+Bundle-Version: 2.0.0
 Bundle-ClassPath: otdt-domtests.jar
 Bundle-Activator: org.eclipse.objectteams.otdt.ui.tests.dom.DOMTestPlugin
 Bundle-Vendor: The TOPPrax consortium
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/META-INF/MANIFEST.MF
index 63dd412..14cb7e9 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: OT Refactoring Test Plug-in
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.ui.tests.refactoring;singleton:=true
-Bundle-Version: 1.3.0
+Bundle-Version: 2.0.0
 Bundle-ClassPath: otrefactoringtests.jar
 Bundle-Activator: org.eclipse.objectteams.otdt.ui.tests.refactoring.OTRefactoringTestPlugin
 Bundle-Vendor: The TOPPrax consortium
@@ -12,7 +12,8 @@
  org.eclipse.objectteams.otdt.ui.tests.refactoring.rename,
  org.eclipse.objectteams.otdt.ui.tests.refactoring.reorg,
  org.eclipse.objectteams.otdt.ui.tests.refactoring.requiredfeatures,
- org.eclipse.objectteams.otdt.ui.tests.refactoring.util
+ org.eclipse.objectteams.otdt.ui.tests.refactoring.util,
+ org.eclipse.objectteams.otdt.ui.tests.refactoring.adapt
 Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.core.resources,
  org.eclipse.jdt.core,
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/plugin.xml b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/plugin.xml
index 4ded421..77ee219 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/plugin.xml
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests.refactoring/plugin.xml
@@ -16,7 +16,7 @@
          </team>
          <team
                activation="NONE"
-               class="org.eclipse.objectteams.otdt.ui.tests.refactoring.adapt.JdtTests.ChangeSignature"
+               class="org.eclipse.objectteams.otdt.ui.tests.refactoring.adapt.JdtTests$ChangeSignature"
                icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
          </team>
          <team
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests/META-INF/MANIFEST.MF b/testplugins/org.eclipse.objectteams.otdt.ui.tests/META-INF/MANIFEST.MF
index fabe568..867fdf8 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests/META-INF/MANIFEST.MF
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: OTDT UITests Plug-in
 Bundle-SymbolicName: org.eclipse.objectteams.otdt.ui.tests;singleton:=true
-Bundle-Version: 1.3.0
+Bundle-Version: 2.0.0
 Bundle-ClassPath: otdt-uitests.jar
 Bundle-Activator: org.eclipse.objectteams.otdt.ui.tests.TestPlugin
 Bundle-Vendor: The TOPPrax consortium