Bug 406518 - migrate OT/Equinox to the standard OSGi WeavingHook
- initial draft implementation
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/.classpath b/plugins/org.eclipse.objectteams.osgi.weaving/.classpath
new file mode 100644
index 0000000..098194c
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<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.osgi.weaving/.project b/plugins/org.eclipse.objectteams.osgi.weaving/.project
new file mode 100644
index 0000000..028edf2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.objectteams.osgi.weaving</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/plugins/org.eclipse.objectteams.osgi.weaving/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.objectteams.osgi.weaving/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2e0f716
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,100 @@
+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.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+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=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+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=disabled
+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.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=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+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=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+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=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+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.7
+org.eclipse.objectteams.otdt.compiler.option.pure_java=enabled
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9abb555
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: OT/J Weaving for OSGi
+Bundle-SymbolicName: org.eclipse.objectteams.osgi.weaving;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.objectteams.osgi.weaving.Activator
+Bundle-Vendor: Eclipse.org - Object Teams
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.objectteams.runtime;bundle-version="2.1.0",
+ org.eclipse.osgi
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/build.properties b/plugins/org.eclipse.objectteams.osgi.weaving/build.properties
new file mode 100644
index 0000000..6ac8fd1
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
+additional.bundles=org.eclipse.jdt.annotation
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/plugin.xml b/plugins/org.eclipse.objectteams.osgi.weaving/plugin.xml
new file mode 100644
index 0000000..0be0f57
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/plugin.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+   <extension-point id="aspectBindings" name="OT/J Aspect Bindings" schema="schema/aspectBindings.exsd"/>
+   <extension-point id="aspectBindingNegotiators" name="OT/Equinox negotiators for aspect binding requests" schema="schema/aspectBindingNegotiators.exsd"/>
+   <extension-point id="liftingParticipant" name="OT/J Lifting Participant" schema="schema/liftingParticipant.exsd"/>
+</plugin>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindingNegotiators.exsd b/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindingNegotiators.exsd
new file mode 100644
index 0000000..9d54188
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindingNegotiators.exsd
@@ -0,0 +1,145 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.objectteams.otequinox" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.objectteams.otequinox" id="aspectBindingNegotiators" name="OT/Equinox negotiators for aspect binding requests"/>
+      </appInfo>
+      <documentation>
+         Allow client plugins to participate in negotiation whether aspect binding requests 
+(incl. forced exports) should be denied or granted.
+&lt;p&gt;
+All extensions will be asked whenever an aspect plugin requests an aspect binding 
+or a forced export for which no permission could be found in persistent storage 
+of neither the eclipse installation nor the workspace.
+&lt;ul&gt;
+&lt;li&gt;As soon as any extension DENYs a given request this aspect plugin is blocked.&lt;/li&gt;
+&lt;li&gt;If no extension GRANTs the request the aspect plugin is blocked, too.&lt;/li&gt;
+&lt;li&gt;Only if at least one extension GRANTs the request and no extension DENYs
+the aspect may proceed and will be woven into its base entities.&lt;/li&gt;
+&lt;/ul&gt;
+&lt;/p&gt;
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="negotiator" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="negotiator">
+      <annotation>
+         <documentation>
+            A participant in the protocol for aspect binding negotiation,
+which is able to grant or deny a request by an aspect bundle.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Fully qualified name of the class that shall participate in the negotiation protocol.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.objectteams.otequinox.IAspectRequestNegotiator"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         OTDT 1.2.6
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         Example of a declaration of a &lt;code&gt;negotiator&lt;/code&gt;:&lt;pre&gt;
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;?eclipse version=&quot;3.2&quot;?&gt;
+&lt;plugin&gt;
+   &lt;extension
+         point=&quot;org.eclipse.objectteams.otequinox.aspectBindingNegotiators&quot;&gt;
+      &lt;negotiator
+            class=&quot;yesser.AspectRequestGranter&quot;&gt;
+      &lt;/negotiator&gt;
+   &lt;/extension&gt;
+&lt;/plugin&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         The class named in the &lt;code&gt;class&lt;/code&gt; property must implement the &lt;code&gt;org.eclipse.objectteams.otequinox.IAspectRequestNegotiator&lt;/code&gt; interface.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         &lt;em&gt;
+&lt;p&gt;
+This file is part of &quot;Object Teams Development Tooling&quot;-Software
+&lt;/p&gt;&lt;p&gt;
+Copyright 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
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+&lt;/p&gt;&lt;p&gt;
+Please visit &lt;a href=&quot;http://www.objectteams.org&quot;&gt;www.objectteams.org&lt;/a&gt; for updates and contact.
+&lt;/p&gt;&lt;p&gt;
+Contributors:&lt;br&gt;
+Technical University Berlin - Initial API and implementation
+&lt;/p&gt;
+&lt;/em&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindings.exsd b/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindings.exsd
new file mode 100644
index 0000000..7ed4fb7
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindings.exsd
@@ -0,0 +1,279 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.objectteams.otequinox" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.objectteams.otequinox" id="aspectBindings" name="OT/J Aspect Bindings"/>
+      </appInfo>
+      <documentation>
+         This extension point allows to define a new &lt;strong&gt;relationship&lt;/strong&gt; between plug-ins 
+called &lt;strong&gt;&quot;aspectBinding&quot;&lt;/strong&gt;.
+By an aspectBinding an aspect plug-in declares which &lt;strong&gt;base plug-ins&lt;/strong&gt; it wishes to adapt 
+and which &lt;strong&gt;team classes&lt;/strong&gt; are used for that purpose.
+Only teams in this list are allowed to adapt classes from another plug-in, and such
+adaptation is restricted to classes residing in the specified base plug-in.
+
+Each team class mentioned in an aspectBinding is automatically &lt;strong&gt;instantiated&lt;/strong&gt; 
+before the corresponding base plug-in is fully activated.
+In addition extensions may specify that a given team is also &lt;strong&gt;activated&lt;/strong&gt; 
+after instantiation.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="aspectBinding" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="aspectBinding">
+      <annotation>
+         <appInfo>
+            <meta.element icon="icon"/>
+         </appInfo>
+         <documentation>
+            Specifies an individual aspect binding by which a given team class adapts classes from a given base plugin.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="basePlugin"/>
+            <element ref="team" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="icon" type="string" use="default" value="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/calloutbinding_obj.gif">
+            <annotation>
+               <documentation>
+                  &lt;i&gt;Default value to provide an icon for this element kind. No need to edit&lt;/i&gt;
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="resource"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="basePlugin">
+      <annotation>
+         <appInfo>
+            <meta.element icon="icon"/>
+         </appInfo>
+         <documentation>
+            &lt;p&gt;
+The base plug-in whose classes may be adapted by the given team(s). 
+The base bundle must be a regular bundle, not a fragment.
+If a bundle &lt;b&gt;fragment&lt;/b&gt; should be adapted the aspect binding must refer to the fragment&apos;s host bundle
+and additionally a &lt;code&gt;requiredFragment&lt;/code&gt; should be added.
+&lt;/p&gt;
+&lt;p&gt;
+By specifying &lt;code&gt;SELF&lt;/code&gt; as the basePlugin, a team may adapt classes from its own bundle.
+&lt;/p&gt;
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="forcedExports" minOccurs="0" maxOccurs="1"/>
+            <element ref="requiredFragment" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Qualified identifier of the base plug-in.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="icon" type="string" use="default" value="platform:/plugin/org.eclipse.pde.ui/icons/obj16/plugin_obj.gif">
+            <annotation>
+               <documentation>
+                  &lt;i&gt;Default value to provide an icon for this element kind. No need to edit&lt;/i&gt;
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="resource"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="team">
+      <annotation>
+         <appInfo>
+            <meta.element labelAttribute="class" icon="icon"/>
+         </appInfo>
+         <documentation>
+            The team class of this plug-in which is allowed to adapt classes of the given base plug-in.&lt;br/&gt;
+If a nested team shall be used it can be specified using either its source name (using &apos;.&apos; as the separator) or its binary name (using a &apos;$&apos; separator).
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Fully qualified name of a team class.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn=":org.objectteams.ITeam"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="superclass" type="string">
+            <annotation>
+               <documentation>
+                  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"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="activation">
+            <annotation>
+               <documentation>
+                  Request activation of this team class: 
+NONE:        don&apos;t automatically activate (default)
+THREAD:      activate for one thread (discouraged)
+ALL_THREADS: activate for all threads
+               </documentation>
+            </annotation>
+            <simpleType>
+               <restriction base="string">
+                  <enumeration value="NONE">
+                  </enumeration>
+                  <enumeration value="THREAD">
+                  </enumeration>
+                  <enumeration value="ALL_THREADS">
+                  </enumeration>
+               </restriction>
+            </simpleType>
+         </attribute>
+         <attribute name="icon" type="string" use="default" value="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+            <annotation>
+               <documentation>
+                  &lt;i&gt;Default value to provide an icon for this element kind. No need to edit&lt;/i&gt;
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="resource"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="forcedExports" type="string">
+      <annotation>
+         <documentation>
+            Declare any requests to access packages from the base plugin which are not exported.
+Provide comma separated list of package names (as in the OSGi Export-Package: header).
+         </documentation>
+      </annotation>
+   </element>
+
+   <element name="requiredFragment">
+      <annotation>
+         <documentation>
+            Name of a fragment of the base bundle that is required by the aspect.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Symbolic name of the fragment.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         OTDT 0.9.1 based on Eclipse 3.2.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         See example plugin org.eclipse.objectteams.otequinox.branding.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         The &lt;code&gt;class&lt;/code&gt; named in the class property must be a team class thus implementing the &lt;code&gt;org.objectteams.ITeam&lt;/code&gt; interface.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         None.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         &lt;em&gt;
+&lt;p&gt;
+This file is part of &quot;Object Teams Development Tooling&quot;-Software
+&lt;/p&gt;&lt;p&gt;
+Copyright 2006, 2010 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
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+&lt;/p&gt;&lt;p&gt;
+Please visit &lt;a href=&quot;http://www.objectteams.org&quot;&gt;www.objectteams.org&lt;/a&gt; for updates and contact.
+&lt;/p&gt;&lt;p&gt;
+Contributors:&lt;br&gt;
+Technical University Berlin - Initial API and implementation
+&lt;/p&gt;
+&lt;/em&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/schema/liftingParticipant.exsd b/plugins/org.eclipse.objectteams.osgi.weaving/schema/liftingParticipant.exsd
new file mode 100644
index 0000000..b41e21a
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/schema/liftingParticipant.exsd
@@ -0,0 +1,133 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.objectteams.otequinox" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appInfo>

+         <meta.schema plugin="org.eclipse.objectteams.otequinox" id="liftingParticipant" name="OT/J Lifting Participant"/>

+      </appInfo>

+      <documentation>

+         Allow a client plug-in to install a lifting participant in order to hook into the OT/J lifting process.

+This can be used to avoid default on-demand role creation, such that an application specific strategy

+can be used for creating and initializing role objects on behalf of the lifting operation.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appInfo>

+            <meta.element />

+         </appInfo>

+      </annotation>

+      <complexType>

+         <sequence>

+            <element ref="liftingParticipant"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appInfo>

+                  <meta.attribute translatable="true"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="liftingParticipant">

+      <complexType>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  Fully qualified name of a class implementing &lt;code&gt;org.objectteams.ILiftingParticipant&lt;/code&gt;

+               </documentation>

+               <appInfo>

+                  <meta.attribute kind="java" basedOn=":org.objectteams.ILiftingParticipant"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="since"/>

+      </appInfo>

+      <documentation>

+         OTDT 0.7.0 (from Eclipse.org) based on Eclipse 3.6.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="examples"/>

+      </appInfo>

+      <documentation>

+         The concept of &quot;lifting participants&quot; was initially requested for the OT/JPA integration

+where roles may need to be retrieved from persistent storage instead of the default on-demand creation.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="apiinfo"/>

+      </appInfo>

+      <documentation>

+         The &lt;code&gt;class&lt;/code&gt; named in the class property must implement the &lt;code&gt;org.objectteams.ILiftingParticipant&lt;/code&gt; interface 

+of the Object Teams Runtime Environment.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="implementation"/>

+      </appInfo>

+      <documentation>

+         None.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="copyright"/>

+      </appInfo>

+      <documentation>

+         &lt;em&gt;

+&lt;p&gt;

+This file is part of &quot;Object Teams Development Tooling&quot;-Software

+&lt;/p&gt;

+&lt;p&gt;

+Copyright 2010 Fraunhofer Gesellschaft, Munich, Germany,

+for its Fraunhofer Institute for Computer Architecture and Software Technology (FIRST), 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

+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;

+&lt;/p&gt;

+&lt;p&gt;

+Please visit &lt;a href=&quot;http://www.eclipse.org/objectteams&quot;&gt;www.eclipse.org/objectteams&lt;/a&gt; for updates and contact.

+&lt;/p&gt;

+&lt;p&gt;

+Contributors:&lt;br&gt;

+Fraunhofer FIRST - Initial API and implementation

+&lt;/p&gt;

+&lt;/em&gt;

+      </documentation>

+   </annotation>

+

+</schema>

diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java
new file mode 100644
index 0000000..9836ec3
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java
@@ -0,0 +1,100 @@
+/**********************************************************************
+ * 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.internal.osgi.weaving;
+
+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.IConfigurationElement;
+import org.eclipse.objectteams.osgi.weaving.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; // FIXME: consistently set?
+	private HashMap<String, Set<String>> teamsPerBase = new HashMap<>();
+	
+	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;
+	}
+
+	public List<String> getAllTeams() {
+		List<String> all = Arrays.asList(this.teamClasses);
+		if (subTeamClasses != null)
+			for (int i = 0; i < subTeamClasses.length; i++)
+				if (subTeamClasses[i] != null)
+					all.addAll(subTeamClasses[i]);
+		return all;
+	}
+
+	public void addBaseClassNames(String teamName, Collection<String> baseClassNames) {
+		for (String baseClassName : baseClassNames) {
+			Set<String> teams = teamsPerBase.get(baseClassName);
+			if (teams == null)
+				teamsPerBase.put(baseClassName, teams = new HashSet<>());
+			teams.add(teamName);
+		}
+	}
+
+	/** Destructively read the names of teams to load for a given base class. */
+	public Collection<String> getTeamsForBase(String baseClassName) {
+		return teamsPerBase.remove(baseClassName);		
+	}
+
+	public ActivationKind getActivation(String teamClassName) {
+		for (int i=0; i<teamClasses.length; i++) {
+			if (teamClasses[i].equals(teamClassName))
+				return activations[i];
+		}
+		return ActivationKind.NONE;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
new file mode 100644
index 0000000..bc366f9
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
@@ -0,0 +1,348 @@
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Activator.log;
+import static org.eclipse.objectteams.osgi.weaving.Constants.ACTIVATION;
+import static org.eclipse.objectteams.osgi.weaving.Constants.ASPECT_BINDING_EXTPOINT_ID;
+import static org.eclipse.objectteams.osgi.weaving.Constants.BASE_PLUGIN;
+import static org.eclipse.objectteams.osgi.weaving.Constants.CLASS;
+import static org.eclipse.objectteams.osgi.weaving.Constants.ID;
+import static org.eclipse.objectteams.osgi.weaving.Constants.SELF;
+import static org.eclipse.objectteams.osgi.weaving.Constants.SUPERCLASS;
+import static org.eclipse.objectteams.osgi.weaving.Constants.TEAM;
+import static org.eclipse.objectteams.osgi.weaving.Constants.TRANSFORMER_PLUGIN_ID;
+
+import java.util.ArrayList;
+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.IConfigurationElement;
+import org.eclipse.core.runtime.RegistryFactory;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.osgi.weaving.Constants;
+import org.eclipse.objectteams.otequinox.hook.IAspectRegistry;
+import org.eclipse.objectteams.otequinox.hook.ILogger;
+import org.objectteams.ITeam;
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+@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>>();
+	// 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>();
+	
+	private HashMap<String, BaseBundleActivation> baseTripWires = new HashMap<>();
+
+	static class WaitingTeamRecord {
+		@Nullable Class<? extends ITeam> teamClass;
+		@Nullable ITeam teamInstance;
+		AspectBinding aspectBinding;
+		String notFoundClass;
+		
+		public WaitingTeamRecord(Class<? extends ITeam> teamClass, AspectBinding aspectBinding, String notFoundClass) {
+			this.teamClass = teamClass;
+			this.aspectBinding = aspectBinding;
+			this.notFoundClass = notFoundClass;
+		}
+		public WaitingTeamRecord(ITeam teamInstance, AspectBinding aspectBinding, String notFoundClass) {
+			this.teamInstance = teamInstance;
+			this.aspectBinding = aspectBinding;
+			this.notFoundClass = notFoundClass;
+		}
+		public WaitingTeamRecord(WaitingTeamRecord record, String notFoundClass) {
+			this.teamClass = record.teamClass;
+			this.teamInstance = record.teamInstance;
+			this.aspectBinding = record.aspectBinding;
+			this.notFoundClass = notFoundClass;
+		}
+		public @Nullable String getTeamName() {
+			final Class<? extends ITeam> clazz = teamClass;
+			if (clazz != null) {
+				return clazz.getName();
+			} else {
+				final ITeam instance = teamInstance;
+				if (instance != null)
+					return instance.getClass().getName();
+			}
+			return "<unknown team>";
+		}		
+	}
+	// records of teams that have been deferred due to unresolved class dependencies:
+	private List<WaitingTeamRecord> deferredTeams = new ArrayList<>();
+	// records of teams whose class dependencies should/could be unblocked by now:
+	private List<WaitingTeamRecord> scheduledTeams = new ArrayList<>();
+
+	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(@Nullable PackageAdmin packageAdmin) {
+		IConfigurationElement[] aspectBindingConfigs = RegistryFactory.getRegistry().getConfigurationElementsFor(
+				TRANSFORMER_PLUGIN_ID, ASPECT_BINDING_EXTPOINT_ID);
+		
+		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);
+			if (packageAdmin != null) {
+				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);
+			
+// FIXME(SH):
+//			//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);
+				}
+				
+				@NonNull String realBaseBundleId = baseBundleId.toUpperCase().equals(SELF) ? aspectBundleId : baseBundleId;
+				addBindingForBaseBundle(realBaseBundleId, binding);
+				addBindingForAspectBundle(aspectBundleId, binding);
+				if (!baseTripWires.containsKey(realBaseBundleId))
+					baseTripWires.put(realBaseBundleId, new BaseBundleActivation(realBaseBundleId, this, packageAdmin));
+
+				
+				// 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 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);
+	}
+	
+	/**
+	 * Record a sub-class relationship of two teams within the same aspect bundle.
+	 * 
+	 * @param aspectBundleId
+	 * @param subTeamName (nullable only until we have JSR 308)
+	 * @param teamName
+	 */
+	private void addSubTeam(String aspectBundleId, @Nullable 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);
+		}		
+	}
+
+
+	/**
+	 * Internal API for TransformerHook:
+	 * see {@link IAspectRegistry#getAdaptedBasePlugins(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).basePlugin;
+		}
+		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();
+	}
+	
+	/**
+	 * 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(@Nullable 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;
+	}
+	
+	/**
+	 * Get the list of aspect bindings affecting the given base plugin.
+	 */
+	public @Nullable List<AspectBinding> getAdaptingAspectBindings(@Nullable String basePluginName) {
+		return aspectBindingsByBasePlugin.get(basePluginName);
+	}
+	
+	/**
+     * 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);
+		}
+	}
+
+	/** Check if the given base bundle / base class mandate any loading/instantiation/activation of teams. */
+	public void triggerLoadingHooks(@Nullable String bundleName, @Nullable String className) {
+		BaseBundleActivation activation = baseTripWires.get(bundleName);
+		if (activation != null)
+			activation.fire(className);
+	}
+
+	/** Record the given team classes as waiting for instantiation/activation. */
+	public synchronized void addDeferredTeamClasses(List<WaitingTeamRecord> teamClasses) {
+		deferredTeams.addAll(teamClasses);		
+	}
+
+	/**
+	 * Check if the given class has been recorded as not-found before,
+	 * If so, unblock the team class(es) that depend on this class
+	 */
+	public synchronized void scheduleTeamClassesFor(@Nullable String className) {
+		List<WaitingTeamRecord> currentList = deferredTeams;
+		deferredTeams = new ArrayList<>();
+		for (WaitingTeamRecord record : currentList) {
+			if (record.notFoundClass.equals(className))
+				scheduledTeams.add(record);
+			else
+				deferredTeams.add(record);
+		}
+	}
+
+	/**
+	 * Try to instantiate/activate any deferred teams that have been unblocked by now.
+	 */
+	public void instantiateScheduledTeams() {
+		List<WaitingTeamRecord> currentList;
+		synchronized (this) {			
+			currentList = scheduledTeams;
+			scheduledTeams = new ArrayList<>();
+		}
+		for(WaitingTeamRecord record : currentList) {
+			try {
+				BaseBundleActivation.instantiateWaitingTeam(record, deferredTeams);
+			} catch (Exception e) {
+				log(e, "Failed to instantiate team "+record.getTeamName());
+				continue;
+			}
+		}
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleActivation.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleActivation.java
new file mode 100644
index 0000000..c35d734
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleActivation.java
@@ -0,0 +1,174 @@
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Activator.log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBindingRegistry.WaitingTeamRecord;
+import org.eclipse.objectteams.osgi.weaving.ActivationKind;
+import org.eclipse.objectteams.otequinox.hook.ILogger;
+import org.objectteams.ITeam;
+import org.objectteams.Team;
+import org.osgi.framework.Bundle;
+
+/**
+ * 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.
+ */
+public class BaseBundleActivation {
+
+	private AspectBindingRegistry aspectBindingRegistry;
+	@SuppressWarnings("deprecation")
+	private org.osgi.service.packageadmin.PackageAdmin admin;
+
+	private String baseBundleName;
+	
+	private boolean teamsScanned = false;
+	
+
+	public BaseBundleActivation(String bundleSymbolicName, AspectBindingRegistry aspectBindingRegistry, 
+			@SuppressWarnings("deprecation") org.osgi.service.packageadmin.PackageAdmin admin) 
+	{
+		this.baseBundleName = bundleSymbolicName;
+		this.aspectBindingRegistry = aspectBindingRegistry;
+		this.admin = admin;
+	}
+	
+	/** Signal that the given class is being loaded and trigger any necessary loading/instantiation/activation. */
+	public void fire(String className) {
+		List<AspectBindingRegistry.WaitingTeamRecord> deferredTeamClasses = new ArrayList<>();
+		List<AspectBinding> aspectBindings = aspectBindingRegistry.getAdaptingAspectBindings(baseBundleName);
+		if (aspectBindings != null) {
+			for (AspectBinding aspectBinding : aspectBindings) {
+				if (aspectBinding.activated)
+					continue;
+				Bundle[] aspectBundles = admin.getBundles(aspectBinding.aspectPlugin, null);
+				if (aspectBundles == null || aspectBundles.length == 0) {
+					log(IStatus.ERROR, "Cannot find aspect bundle "+aspectBinding.aspectPlugin);
+					continue;
+				}
+				Bundle aspectBundle = aspectBundles[0];
+				if (shouldScan())
+					scanTeamClasses(aspectBundle, aspectBinding);
+				if (loadTeams(aspectBundle, aspectBinding, className, deferredTeamClasses))
+//					aspectBinding.activated = true; // FIXME(SH): this still spoils team activation, the given class may not be the trigger
+					;
+			}
+			if (!deferredTeamClasses.isEmpty())
+				aspectBindingRegistry.addDeferredTeamClasses(deferredTeamClasses);
+		}
+	}
+
+	private synchronized boolean shouldScan() {
+		boolean shouldScan = !teamsScanned;
+		teamsScanned = true;
+		return shouldScan;
+	}
+
+	/** Read OT attributes of all teams in aspectBinding and collect affected base classes. */
+	private void scanTeamClasses(Bundle bundle, AspectBinding aspectBinding) { 
+		List<String> allTeams = aspectBinding.getAllTeams();
+		ClassScanner scanner = new ClassScanner();
+		for (String teamName : allTeams) {
+			try {
+				scanner.readOTAttributes(bundle, teamName);
+				aspectBinding.addBaseClassNames(teamName, scanner.getCollectedBaseClassNames());
+			} catch (Exception e) {
+				log(e, "Failed to load team class "+teamName);
+			}
+		}
+	}
+
+	/** Team loading, 1st attempt (trying to do all three phases load/instantiate/activate). */
+	private boolean loadTeams(Bundle aspectBundle, AspectBinding aspectBinding, String className, List<WaitingTeamRecord> deferredTeamClasses) {
+		Collection<String> teamsForBase = aspectBinding.getTeamsForBase(className);
+		if (teamsForBase == null) return true;
+		TeamLoading delegate = new TeamLoading(deferredTeamClasses);
+		for (String teamForBase : teamsForBase) {
+			// Load:
+			Class<? extends ITeam> teamClass;
+			try {
+				teamClass = (Class<? extends ITeam>) aspectBundle.loadClass(teamForBase);
+			} catch (ClassNotFoundException e) {
+				log(e, "Failed to load team "+teamForBase);
+				continue;
+			}
+			// Instantiate?
+			ActivationKind activationKind = aspectBinding.getActivation(teamForBase);
+			if (activationKind == ActivationKind.NONE)
+				continue;
+			ITeam teamInstance = delegate.instantiateTeam(aspectBinding, teamClass, teamForBase);
+			if (teamInstance == null)
+				continue;
+			// Activate?
+			delegate.activateTeam(aspectBinding, teamForBase, teamInstance, activationKind);
+		}
+		return !delegate.needDeferring; // TODO, need to figure out whether we're done with aspectBinding.
+	}
+
+	/** Team loading, subsequent attempts. */
+	public static void instantiateWaitingTeam(WaitingTeamRecord record, List<WaitingTeamRecord> deferredTeams)
+			throws InstantiationException, IllegalAccessException 
+	{
+		ITeam teamInstance = record.teamInstance;
+		String teamName = record.getTeamName();
+		TeamLoading delegate = new TeamLoading(deferredTeams);
+		if (teamInstance == null) {
+			// Instantiate (we only get here if activationKind != NONE)
+			teamInstance = delegate.instantiateTeam(record.aspectBinding, record.teamClass, teamName);
+			if (teamInstance == null)
+				return;
+		}
+		// Activate?
+		ActivationKind activationKind = record.aspectBinding.getActivation(teamName);
+		delegate.activateTeam(record.aspectBinding, teamName, teamInstance, activationKind);
+	}
+
+	/* Common parts for both first and subsequent loading attempts. */
+	private static class TeamLoading {
+		List<WaitingTeamRecord> deferredTeams;
+		boolean needDeferring; // did we record the fact that a team needs deferring?
+		
+		public TeamLoading(List<WaitingTeamRecord> deferredTeams) {
+			this.deferredTeams = deferredTeams;
+		}
+
+		@Nullable ITeam instantiateTeam(AspectBinding aspectBinding, Class<? extends ITeam> teamClass, String teamName) {
+			try {
+				ITeam instance = teamClass.newInstance();
+				log(ILogger.INFO, "Instantiated team "+teamName);
+				return instance;
+			} catch (NoClassDefFoundError ncdfe) {
+				needDeferring = true;
+				deferredTeams.add(new WaitingTeamRecord(teamClass, aspectBinding, ncdfe.getMessage().replace('/','.')));
+			} catch (Throwable e) {
+				// application error during constructor execution?
+				log(e, "Failed to instantiate team "+teamName);
+			}
+			return null;
+		}
+		void activateTeam(AspectBinding aspectBinding, String teamName, ITeam teamInstance, ActivationKind activationKind)
+		{
+			try {
+				switch (activationKind) {
+				case ALL_THREADS:
+					teamInstance.activate(Team.ALL_THREADS);
+					break;
+				case THREAD:
+					teamInstance.activate();
+					break;
+					//$CASES-OMITTED$
+				}
+			} catch (NoClassDefFoundError e) {
+				deferredTeams.add(new WaitingTeamRecord(teamInstance, aspectBinding, e.getMessage().replace('/','.'))); // TODO(SH): synchronization
+			} catch (Throwable t) {
+				// application errors during activation
+				log(t, "Failed to activate team "+teamName);
+			}
+		}
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java
new file mode 100644
index 0000000..377fe1d
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java
@@ -0,0 +1,143 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2008, 2010 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: ClassScanner.java 23461 2010-02-04 22:10:39Z stephan $
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Activator.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.objectteams.otequinox.hook.ILogger;
+import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
+import org.eclipse.objectteams.otre.util.CallinBindingManager;
+import org.osgi.framework.Bundle;
+
+/**
+ * Bridge for the TransformerPlugin by which it can access the ObjectTeamsTransformer
+ * without accessing that OTRE class.
+ * 
+ * @author stephan
+ * @since 1.2.0
+ */
+@SuppressWarnings("nls")
+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
+	 * @throws ClassFormatError
+	 * @throws IOException
+	 * @throws ClassNotFoundException the team or role class was not found
+	 */
+	public void readOTAttributes(Bundle bundle, String className)
+			throws ClassFormatError, IOException, ClassNotFoundException 
+	{
+		Object loader = REPOSITORY_USE_RESOURCE_LOADER ? bundle : null;
+		URL classFile = bundle.getResource(className.replace('.', '/')+".class");
+		if (classFile == null) 
+			throw new ClassNotFoundException(className);
+		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);
+	}
+	
+	/** 
+	 * Get the names of the base classes adapted by the given team and 
+	 * encountered while reading the byte code attributes.
+	 * (Destructive read). 
+	 */
+	public 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 (String roleName: roles) {
+				log(ILogger.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.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
new file mode 100644
index 0000000..8eeb123
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
@@ -0,0 +1,68 @@
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Activator.log;
+
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.hooks.weaving.WovenClass;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class OTWeavingHook implements WeavingHook {
+
+	private AspectBindingRegistry aspectBindingRegistry;
+	private ObjectTeamsTransformer objectTeamsTransformer;
+	
+	public OTWeavingHook(AspectBindingRegistry aspectBindingRegistry) {
+		this.aspectBindingRegistry = aspectBindingRegistry;
+		this.objectTeamsTransformer = new ObjectTeamsTransformer();
+	}
+
+	@Override
+	public void weave(WovenClass wovenClass) {
+		try {
+			// TODO(SH): ideally this trigger would be inserted into the previous woven class
+			// do whatever left-overs we find from previous invocations:
+			aspectBindingRegistry.instantiateScheduledTeams();
+			
+			BundleWiring bundleWiring = wovenClass.getBundleWiring();
+			String bundleName = bundleWiring.getBundle().getSymbolicName();
+			String className = wovenClass.getClassName();
+			
+			// do whatever is needed *before* loading this class:
+			aspectBindingRegistry.triggerLoadingHooks(bundleName, className);
+			
+			if (requiresWeaving(bundleWiring)) {
+				Class<?> classBeingRedefined = null; // TODO
+				ProtectionDomain protectionDomain = null; // TODO
+				byte[] bytes = wovenClass.getBytes();
+				try {
+					log(IStatus.INFO, "About to transform class "+wovenClass);
+					byte[] newBytes = objectTeamsTransformer.transform(bundleWiring.getClassLoader(),
+										className, classBeingRedefined, protectionDomain, bytes);
+					if (newBytes != bytes)
+						wovenClass.setBytes(newBytes);
+				} catch (IllegalClassFormatException e) {
+					log(e, "Failed to transform class "+className);
+				}
+			}
+			// unblock any waiting teams depending on this class:
+			aspectBindingRegistry.scheduleTeamClassesFor(className);
+		} catch (ClassCircularityError cce) {
+			log(cce, "Weaver encountered a circular class dependency");
+		}
+	}
+
+	private boolean requiresWeaving(BundleWiring bundleWiring) {
+		@SuppressWarnings("null")@NonNull
+		Bundle bundle = bundleWiring.getBundle();
+		return aspectBindingRegistry.getAdaptedBasePlugins(bundle) != null
+				|| aspectBindingRegistry.isAdaptedBasePlugin(bundle.getSymbolicName());
+	}
+
+}
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/ActivationKind.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/ActivationKind.java
new file mode 100644
index 0000000..57d1546
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/ActivationKind.java
@@ -0,0 +1,31 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 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:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.osgi.weaving;
+
+/**
+ * Possible values for the "activation" attribute of a "team" element within an "aspectBinding" extension.
+ *  
+ * @author stephan
+ * @since 1.2.7 (was inline previously)
+ */
+public enum ActivationKind {
+	/** Don't activate team by default. */
+	NONE, 
+	/** Activate team for current thread. */
+	THREAD, 
+	/** Globally activate team. */
+	ALL_THREADS;
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java
new file mode 100644
index 0000000..ac7605f
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java
@@ -0,0 +1,126 @@
+package org.eclipse.objectteams.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Constants.TRANSFORMER_PLUGIN_ID;
+
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBindingRegistry;
+import org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook;
+import org.eclipse.objectteams.otequinox.hook.ILogger;
+import org.eclipse.objectteams.otre.ClassLoaderAccess;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+
+public class Activator implements BundleActivator {
+
+	private static BundleContext context;
+
+	static BundleContext getContext() {
+		return context;
+	}
+
+	private ServiceRegistration<WeavingHook> serviceRegistration;
+	private AspectBindingRegistry aspectBindingRegistry;
+
+	@SuppressWarnings("deprecation")
+	private org.osgi.service.packageadmin.PackageAdmin packageAdmin;
+
+	private static ILog log;
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext bundleContext) throws Exception {
+		Activator.context = bundleContext;
+		
+		frameworkInit(bundleContext);
+
+		this.aspectBindingRegistry = new AspectBindingRegistry();
+		this.aspectBindingRegistry.loadAspectBindings(this.packageAdmin);
+
+		OTWeavingHook otWeavingHook = new OTWeavingHook(this.aspectBindingRegistry);
+		this.serviceRegistration = context.registerService(WeavingHook.class, otWeavingHook, new Hashtable<String, Object>());
+		
+		OTREInit();
+	}
+
+	@SuppressWarnings({ "restriction", "deprecation" })
+	private void frameworkInit(BundleContext bundleContext) {
+		try {
+			Activator.log = org.eclipse.core.internal.runtime.InternalPlatform.getDefault().getLog(bundleContext.getBundle());
+		} catch (NullPointerException npe) {
+			// WTF?
+		}
+		
+		ServiceReference<?> ref= context.getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName());
+		if (ref!=null)
+			this.packageAdmin = (org.osgi.service.packageadmin.PackageAdmin)context.getService(ref);
+		else
+			log(ILogger.ERROR, "Failed to load PackageAdmin service. Will not be able to handle fragments.");
+	}
+
+	private void OTREInit() {
+		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 {
+		Activator.context = null;
+		this.serviceRegistration.unregister();
+	}
+
+	// configure OT/Equinox debugging:
+	public static int WARN_LEVEL = ILogger.ERROR;
+	static {
+		String level = System.getProperty("otequinox.debug");
+		if (level != null) {
+			level = level.toUpperCase();
+			if (level.equals("OK"))
+				WARN_LEVEL = ILogger.OK;
+			else if (level.equals("INFO"))
+				WARN_LEVEL = ILogger.INFO;
+			else if (level.startsWith("WARN"))
+				WARN_LEVEL = ILogger.WARNING;
+			else if (level.startsWith("ERR"))
+				WARN_LEVEL = ILogger.ERROR;
+			else
+				WARN_LEVEL = ILogger.OK;
+		}
+	}
+
+	public static void log (Throwable ex, String msg) {
+		msg = "OT/Equinox: "+msg;
+		System.err.println(msg);
+		ex.printStackTrace();
+		log.log(new Status(IStatus.ERROR, TRANSFORMER_PLUGIN_ID, msg, ex));
+	}
+	
+	public static void log(int status, String msg) {
+		if (status >= WARN_LEVEL)
+			doLog(status, msg);
+	}
+
+	private static void doLog(int status, String msg) {
+		msg = "OT/Equinox: "+msg;
+		if (log != null)
+			log.log(new Status(status, TRANSFORMER_PLUGIN_ID, msg));
+		else
+			System.err.println(msg);
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Constants.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Constants.java
new file mode 100644
index 0000000..e3dfc58
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Constants.java
@@ -0,0 +1,62 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 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:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.osgi.weaving;
+
+/**
+ * Constants used for OT/Equinox.
+ * 
+ * @author stephan
+ * @since 1.2.7
+ */
+public interface Constants {
+	
+	/** ID of this plugin. */
+	public static final String TRANSFORMER_PLUGIN_ID         = "org.eclipse.objectteams.osgi.weaving" ; //$NON-NLS-1$
+	
+	// === Extension point elements: ===
+	
+	/** Simple name of the extension point org.eclipse.objectteams.otequinox.aspectBindings. */
+	static final String ASPECT_BINDING_EXTPOINT_ID    = "aspectBindings";
+	static final String ASPECT_BINDING_FQEXTPOINT_ID  = TRANSFORMER_PLUGIN_ID+'.'+ASPECT_BINDING_EXTPOINT_ID;
+	
+	/** Simple name of the extension point org.eclipse.objectteams.otequinox.liftingParticipant. */
+	static final String LIFTING_PARTICIPANT_EXTPOINT_ID    = "liftingParticipant";
+
+	/** Attribute of "team" and "basePlugin" elements. */
+	static final String ID = "id";
+
+	/** Element of EP aspectBindings denoting a team class. */
+	static final String TEAM = "team";
+	/** Attribute of a "team" element denoting the fully qualified class name. */
+	static final String CLASS = "class";
+	/** Attribute of a "team" element denoting the team's superclass. */
+	static final String SUPERCLASS = "superclass";
+	/** Attribute of a "team" element denoting the requested activation: one of "NONE", "THREAD", "ALL_THREADS". */
+	static final String ACTIVATION = "activation";
+	
+	/** Element of EP aspectBindings denoting an adapted base plugin. */
+	static final String BASE_PLUGIN = "basePlugin";
+	/** Subelement of a "basePlugin" denoting a framgment of the base plugin that is required by the aspect. */
+	static final String REQUIRED_FRAGMENT = "requiredFragment";
+	/** Pseudo ID of a basePlugin specifying that the team(s) adapt base classes from their own plugin. */
+	static final String SELF = "SELF";
+
+	/** Element of EP aspectBinding - child of basePlugin node - requesting exports forced on the given base plug-in. */
+	public static final String FORCED_EXPORTS_ELEMENT = "forcedExports";
+	
+	/** Simple name of the extension point org.eclipse.objectteams.otequinox.aspectBindingNegotiators. */
+	public static final String ASPECT_NEGOTIATOR_EXTPOINT_ID = "aspectBindingNegotiators";
+}