Experimental application of external null annotations
diff --git a/plugins/org.eclipse.objectteams.otequinox/.classpath b/plugins/org.eclipse.objectteams.otequinox/.classpath
index 098194c..8d9a643 100644
--- a/plugins/org.eclipse.objectteams.otequinox/.classpath
+++ b/plugins/org.eclipse.objectteams.otequinox/.classpath
@@ -1,7 +1,15 @@
 <?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="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
+		<attributes>
+			<attribute name="annotationpath" value="annotations/jre"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+		<attributes>
+			<attribute name="annotationpath" value="annotations/plugins"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/lang/Class.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/lang/Class.eea
new file mode 100644
index 0000000..0d35465
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/lang/Class.eea
@@ -0,0 +1,5 @@
+class java/lang/Class
+
+newInstance
+ ()TT;
+ ()T1T;
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/lang/String.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/lang/String.eea
new file mode 100644
index 0000000..2178297
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/lang/String.eea
@@ -0,0 +1,9 @@
+class java/lang/String
+
+trim
+ ()Ljava/lang/String;
+ ()L1java/lang/String;
+
+replace
+ (CC)Ljava/lang/String;
+ (CC)L1java/lang/String;
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/util/Collections.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/util/Collections.eea
new file mode 100644
index 0000000..9da7b53
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/annotations/jre/java/util/Collections.eea
@@ -0,0 +1,6 @@
+class java/util/Collections
+
+emptyList
+ <T:Ljava/lang/Object;>()Ljava/util/List<TT;>;
+ <T:Ljava/lang/Object;>()L1java/util/List<TT;>;
+ 
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/core/internal/runtime/InternalPlatform.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/core/internal/runtime/InternalPlatform.eea
new file mode 100644
index 0000000..ee081b2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/core/internal/runtime/InternalPlatform.eea
@@ -0,0 +1,5 @@
+class org/eclipse/core/internal/runtime/InternalPlatform
+
+getStateLocation
+ (Lorg/osgi/framework/Bundle;Z)Lorg/eclipse/core/runtime/IPath;
+ (Lorg/osgi/framework/Bundle;Z)L1org/eclipse/core/runtime/IPath;
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/core/runtime/IContributor.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/core/runtime/IContributor.eea
new file mode 100644
index 0000000..e392379
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/core/runtime/IContributor.eea
@@ -0,0 +1,5 @@
+class org/eclipse/core/runtime/IContributor
+
+getName
+ ()Ljava/lang/String;
+ ()L1java/lang/String;
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/BundleContext.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/BundleContext.eea
new file mode 100644
index 0000000..5b8b11b
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/BundleContext.eea
@@ -0,0 +1,5 @@
+class org/osgi/framework/BundleContext
+
+getBundle
+ ()Lorg/osgi/framework/Bundle;
+ ()L1org/osgi/framework/Bundle;
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/hooks/weaving/WovenClass.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/hooks/weaving/WovenClass.eea
new file mode 100644
index 0000000..ea820c2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/hooks/weaving/WovenClass.eea
@@ -0,0 +1,6 @@
+class org/osgi/framework/hooks/weaving/WovenClass
+
+getClassName
+ ()Ljava/lang/String;
+ ()L1java/lang/String;
+ 
\ No newline at end of file
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
index 8e9043f..0d2795b 100644
--- 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
@@ -225,7 +225,7 @@
 			}
 			Class<? extends Team> cl = this.teamClass;
 			assert cl != null : "Precondition";
-			@SuppressWarnings("null")@NonNull Team nnInst = cl.newInstance();
+			Team nnInst = cl.newInstance();
 			TransformerPlugin.registerTeamInstance(nnInst);
 			log(IStatus.INFO, "Instantiated team "+teamName);
 			return this.instance = nnInst;
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
index 3c81fca..a56fe00 100644
--- 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
@@ -92,7 +92,7 @@
 			IConfigurationElement currentBindingConfig = aspectBindingConfigs[i];
 
 			//aspect:
-			@SuppressWarnings("null")@NonNull String aspectBundleId= currentBindingConfig.getContributor().getName();
+			String aspectBundleId= currentBindingConfig.getContributor().getName();
 			IS_OTDT |= KNOWN_OTDT_ASPECTS.contains(aspectBundleId);
 			Bundle aspectBundle = null;
 			if (packageAdmin != null) {
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectPermissionManager.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectPermissionManager.java
index 36cddb7..00993e4 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectPermissionManager.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectPermissionManager.java
@@ -160,8 +160,7 @@
 	 */
 	private void fetchAspectBindingPermssionsFromWorkspace() {
 		try {
-			@SuppressWarnings("null") // known API
-			@NonNull IPath state = InternalPlatform.getDefault().getStateLocation(this.transformerBundle, true);
+			IPath state = InternalPlatform.getDefault().getStateLocation(this.transformerBundle, true);
 			this.otequinoxState = state;
 			internalFetchAspectBindingPermssionsFromWorkspace(state);
 		} catch (NoClassDefFoundError ncdfe) {
@@ -229,7 +228,7 @@
 			String forcedExportsRequest = forcedExport.getValue();
 			if (forcedExportsRequest == null)
 				continue;
-			for (@NonNull String singleForcedExportRequest : forcedExportsRequest.split(",")) // well-known API
+			for (@SuppressWarnings("null")@NonNull String singleForcedExportRequest : forcedExportsRequest.split(","))
 			{
 				singleForcedExportRequest = singleForcedExportRequest.trim(); // well-known API
 
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/ForcedExportsDelegate.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/ForcedExportsDelegate.java
index bb0438a..9581a68 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/ForcedExportsDelegate.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/ForcedExportsDelegate.java
@@ -46,11 +46,12 @@
 		return registryClass != null;
 	}
 
-	@SuppressWarnings({ "unchecked", "null" }) // neither reflection nor Collections.emptyList() knows about nullness
 	public @NonNull List<String[]> getForcedExportsByAspect(String aspectBundleId, AspectPermission perm) {
 		if (getForcedExportsByAspect != null) {
 			try {
-				return (List<String[]>) getForcedExportsByAspect.invoke(null, new Object[] {aspectBundleId, perm.ordinal()});
+				@SuppressWarnings({ "unchecked", "null" })@NonNull // reflection knows nothing about nullness, nor generics
+				List<String[]> result = (List<String[]>) getForcedExportsByAspect.invoke(null, new Object[] {aspectBundleId, perm.ordinal()});
+				return result;
 			} catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
 				TransformerPlugin.log(e, "Failed to access forced exports");
 			}
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
index ccdcb0a..b973667 100644
--- 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
@@ -265,7 +265,7 @@
 	WeavingReason requiresWeaving(BundleWiring bundleWiring, String className, byte[] bytes) {
 		
 		// 1. consult the aspect binding registry (for per-bundle info):
-		@SuppressWarnings("null")@NonNull
+		@SuppressWarnings("null")@NonNull // FIXME: org.eclipse.osgi.internal.resolver.BundleDescriptionImpl.getBundle() can return null!
 		Bundle bundle = bundleWiring.getBundle();
 		if (aspectBindingRegistry.getAdaptedBasePlugins(bundle) != null)
 			return WeavingReason.Aspect;
@@ -396,12 +396,12 @@
 	@Override
 	public void modified(WovenClass wovenClass) {
 		if (wovenClass.getState() == WovenClass.DEFINED) {
-			if (wovenClass.getClassName().equals(ORG_OBJECTTEAMS_TEAM)) {
+			@NonNull String className = wovenClass.getClassName();
+			if (className.equals(ORG_OBJECTTEAMS_TEAM)) {
 				this.ooTeam = wovenClass.getDefinedClass();
 				installLiftingParticipant();
 			}
-			beingDefined.remove(wovenClass.getClassName());
-			@SuppressWarnings("null") @NonNull String className = wovenClass.getClassName();
+			beingDefined.remove(className);
 			instantiateScheduledTeams(className);
 
 			TransformerPlugin.flushLog();
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
index 610864f..c379093 100644
--- 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
@@ -71,7 +71,7 @@
 	 * Trying to do these phases: load (now) instantiate/activate (if ready),
 	 */
 	public void loadTeamsForBase(BaseBundle baseBundle, WovenClass baseClass, AspectPermissionManager permissionManager) {
-		@SuppressWarnings("null")@NonNull String className = baseClass.getClassName();
+		@NonNull String className = baseClass.getClassName();
 		Collection<TeamBinding> teamsForBase = baseBundle.teamsPerBase.get(className);
 		if (teamsForBase == null) 
 			return; // not done
@@ -225,7 +225,6 @@
 				} catch (Throwable t) { /* ignore */ }
 				for (TeamBinding eq : team.equivalenceSet)
 					eq.isActivated = false;
-				@SuppressWarnings("null") @NonNull // known API
 				String notFoundName = e.getMessage().replace('/', '.');
 				synchronized (this.deferredTeams) {
 					this.deferredTeams.add(new WaitingTeamRecord(team, activationKind, notFoundName));
@@ -238,7 +237,6 @@
 		} catch (ClassCircularityError e) {
 			for (TeamBinding eq : team.equivalenceSet)
 				eq.isActivated = false;
-			@SuppressWarnings("null") @NonNull // known API
 			String notFoundName = e.getMessage().replace('/', '.');
 			synchronized (this.deferredTeams) {
 				this.deferredTeams.add(new WaitingTeamRecord(team, activationKind, notFoundName));