Bug 559847 - Null-safety cleanup in OT/Equinox implementation

- include otredyn
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 155789e..f70fda0 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
@@ -2,8 +2,11 @@
 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.nonnull.secondary=
 org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
 org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
 org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
@@ -13,6 +16,8 @@
 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.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info
 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@@ -51,12 +56,14 @@
 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.nonnullTypeVariableFromLegacyInvocation=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.pessimisticNullAnalysisForFreeTypeVariables=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
@@ -72,21 +79,28 @@
 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.suppressWarningsNotFullyAnalysed=info
 org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
 org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
 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.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
 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.unstableAutoModuleName=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.unusedExceptionParameter=ignore
 org.eclipse.jdt.core.compiler.problem.unusedImport=warning
 org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
 org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
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
index e35230a..9f8dae9 100644
--- 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
@@ -43,7 +43,6 @@
  * @author stephan
  * @since 1.2.0
  */
-@SuppressWarnings("nls")
 @NonNullByDefault
 public class ClassScanner 
 {
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java
index e8026f1..e16bd78 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java
@@ -199,7 +199,7 @@
 			}
 			
 			@Override
-			public boolean scheduleReweaving(String className, /*@NonNull*/ IReweavingTask task) {
+			public boolean scheduleReweaving(@NonNull String className, @NonNull IReweavingTask task) {
 				return hook.scheduleReweaving(className, task);
 			}
 		};
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 b04af75..9e8e0ef 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
@@ -47,7 +47,6 @@
 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.internal.osgi.weaving.AspectPermissionManager;
 import org.eclipse.objectteams.internal.osgi.weaving.DelegatingTransformer.OTAgentNotInstalled;
 import org.eclipse.objectteams.otequinox.Constants;
 import org.eclipse.objectteams.otequinox.TransformerPlugin;
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
index c424230..15eb337 100644
--- 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
@@ -54,7 +54,6 @@
 	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();
diff --git a/plugins/org.eclipse.objectteams.otredyn/.classpath b/plugins/org.eclipse.objectteams.otredyn/.classpath
index eca7bdb..55b0568 100644
--- a/plugins/org.eclipse.objectteams.otredyn/.classpath
+++ b/plugins/org.eclipse.objectteams.otredyn/.classpath
@@ -1,6 +1,10 @@
 <?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.8"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="annotationpath" value="/org.eclipse.objectteams.otredyn/annotations/jre"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="output" path="bin"/>
diff --git a/plugins/org.eclipse.objectteams.otredyn/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.objectteams.otredyn/.settings/org.eclipse.jdt.core.prefs
index a28dedc..b78991f 100644
--- a/plugins/org.eclipse.objectteams.otredyn/.settings/org.eclipse.jdt.core.prefs
+++ b/plugins/org.eclipse.objectteams.otredyn/.settings/org.eclipse.jdt.core.prefs
@@ -2,16 +2,22 @@
 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.nonnull.secondary=
 org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
 org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
 org.eclipse.jdt.core.compiler.compliance=1.8
 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.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info
 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@@ -22,6 +28,7 @@
 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.enablePreviewFeatures=disabled
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
 org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning
 org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
@@ -49,14 +56,16 @@
 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.nonnullTypeVariableFromLegacyInvocation=warning
 org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
+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.pessimisticNullAnalysisForFreeTypeVariables=warning
 org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=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
@@ -65,21 +74,28 @@
 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.reportPreviewFeatures=warning
 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.suppressWarningsNotFullyAnalysed=info
 org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
 org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
 org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
 org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
 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.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
 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.unstableAutoModuleName=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
@@ -97,5 +113,6 @@
 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.release=disabled
 org.eclipse.jdt.core.compiler.source=1.8
 org.eclipse.objectteams.otdt.compiler.option.pure_java=enabled
diff --git a/plugins/org.eclipse.objectteams.otredyn/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otredyn/META-INF/MANIFEST.MF
index 879656f..a61225f 100644
--- a/plugins/org.eclipse.objectteams.otredyn/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otredyn/META-INF/MANIFEST.MF
@@ -19,4 +19,5 @@
  org.objectweb.asm.tree;bundle-version="[7.1.0,8.0.0)",
  org.objectweb.asm.commons;bundle-version="[7.1.0,8.0.0)",
  org.objectweb.asm.util;bundle-version="[7.1.0,8.9.0)",
- org.objectweb.asm.analysis;bundle-version="[7.1.0,8.0.0)"
+ org.objectweb.asm.analysis;bundle-version="[7.1.0,8.0.0)",
+ org.eclipse.jdt.annotation;bundle-version="2.2.400";resolution:=optional
diff --git a/plugins/org.eclipse.objectteams.otredyn/annotations/jre/java/lang/String.eea b/plugins/org.eclipse.objectteams.otredyn/annotations/jre/java/lang/String.eea
new file mode 100644
index 0000000..dddfac1
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/annotations/jre/java/lang/String.eea
@@ -0,0 +1,10 @@
+class java/lang/String
+replace
+ (CC)Ljava/lang/String;
+ (CC)L1java/lang/String;
+split
+ (Ljava/lang/String;)[Ljava/lang/String;
+ (Ljava/lang/String;)[L1java/lang/String;
+substring
+ (II)Ljava/lang/String;
+ (II)L1java/lang/String;
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
index cc08486..4d56e7f 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
@@ -40,6 +40,8 @@
 import org.eclipse.objectteams.runtime.IReweavingTask;
 import org.objectweb.asm.Opcodes;
 
+import org.eclipse.jdt.annotation.*;
+
 /**
  * This class represents a java class.
  * It stores the information about a class parsed from the bytecode and
@@ -189,7 +191,7 @@
 	protected boolean parsed;
 
 	//FQN (e.g. "foo.bar.MyClass")
-	private String name;
+	private @NonNull String name;
 	
 	//internal FQN (e.g. "foo/bar/MyClass.class")
 	private String internalName;
@@ -233,7 +235,7 @@
 	 * @param id unique identifier, able to differentiate same-named classes from different classloaders
 	 * @param loader classloader responsible for loading this class
 	 */
-	protected AbstractBoundClass(String name, String id, ClassLoader loader) {
+	protected AbstractBoundClass(@NonNull String name, String id, ClassLoader loader) {
 //		if (name.indexOf('/')!= -1)
 //			new RuntimeException(name).printStackTrace(System.out);
 		this.name = name;
@@ -260,7 +262,7 @@
 	 * Returns the name of the Class
 	 * @return
 	 */
-	public String getName() {
+	public @NonNull String getName() {
 		return name;
 	}
 
@@ -406,12 +408,13 @@
 		if (superclass == null) {
 			synchronized (this) {
 				parseBytecode();
-				if (superClassName != null && superclass == null) {
+				String checkedSuperClassName = superClassName;
+				if (checkedSuperClassName != null && superclass == null) {
 					String superclassId = ClassIdentifierProviderFactory.getClassIdentifierProvider().getSuperclassIdentifier(id, internalSuperClassName);
 					
 					//if superclassId is null the class could be "Object" or an interface
 					if (superclassId != null) {
-						superclass = ClassRepository.getInstance().getBoundClass(superClassName, superclassId, loader);
+						superclass = ClassRepository.getInstance().getBoundClass(checkedSuperClassName, superclassId, loader);
 						superclass.addSubclass(this);
 						// FIXME(SH): can we avoid adding all subclasses to j.l.Object?
 					}
@@ -672,7 +675,7 @@
 	 * @param definedClass previously defined class if available
 	 * @throws IllegalClassFormatException various bytecode problems, e.g., unexpected RET instruction etc.
 	 */
-	public void handleTaskList(Class<?> definedClass) throws IllegalClassFormatException {
+	public void handleTaskList(@Nullable Class<?> definedClass) throws IllegalClassFormatException {
 		if (isTransformationActive()) return;
 
 		if (this.isUnweavable)
@@ -883,7 +886,7 @@
 				for (final AbstractBoundClass affected : affectedClasses)
 					if (affected.isLoaded) {
 						IReweavingTask task = new IReweavingTask() {
-							@Override public void reweave(Class<?> definedClass) throws IllegalClassFormatException {
+							@Override public void reweave(@Nullable Class<?> definedClass) throws IllegalClassFormatException {
 								affected.handleTaskList(definedClass);
 							}
 						};
@@ -969,7 +972,7 @@
 	}
 
 	@Override
-	public synchronized void commitTransaction(Class<?> definedClass) {
+	public synchronized void commitTransaction(@Nullable Class<?> definedClass) {
 		--this.transactionCount;
 		if (this.transactionCount == 0 && this.isLoaded) {
 			try {
@@ -1027,6 +1030,7 @@
 				openAccessTasks.put(null, task);
 				return true;
 			}
+			if (member == null) return false;
 			
 			synchronized (member) {
 				WeavingTask prevTask = completedAccessTasks.get(member);
@@ -1283,7 +1287,7 @@
 
 	public void dump(byte[] classfileBuffer, String postfix) {}
 
-	public Collection<String> getBoundBaseClasses() { return null; }
+	public Collection<@NonNull String> getBoundBaseClasses() { return null; }
 
 	public abstract int compare(String callinLabel1, String callinLabel2);
 
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractTeam.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractTeam.java
index 5a3d332..1acc835 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractTeam.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractTeam.java
@@ -23,6 +23,7 @@
 import java.util.Set;

 import java.util.TreeSet;

 

+import org.eclipse.jdt.annotation.NonNull;

 import org.eclipse.objectteams.otredyn.runtime.IBinding;

 import org.eclipse.objectteams.otredyn.runtime.IBoundClass;

 import org.eclipse.objectteams.otredyn.runtime.IBoundTeam;

@@ -44,7 +45,7 @@
 	 */

 	private int highestAccessId;

 

-	protected AbstractTeam(String name, String id, ClassLoader loader) {

+	protected AbstractTeam(@NonNull String name, String id, ClassLoader loader) {

 		super(name, id, loader);

 		bindings = new TreeSet<IBinding>();

 	}

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/ClassRepository.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/ClassRepository.java
index 293ca40..9349cfd 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/ClassRepository.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/ClassRepository.java
@@ -22,6 +22,7 @@
 import java.util.IdentityHashMap;
 import java.util.Map;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.objectteams.otredyn.bytecode.asm.AsmBoundClass;
 import org.eclipse.objectteams.otredyn.bytecode.asm.AsmClassRepository;
 import org.eclipse.objectteams.otredyn.runtime.IClassRepository;
@@ -89,7 +90,7 @@
 	 * @param id a globally unique identifier for the class 
 	 * @return
 	 */
-	public synchronized AbstractBoundClass getBoundClass(String className, String id, ClassLoader loader) {
+	public synchronized AbstractBoundClass getBoundClass(@NonNull String className, String id, ClassLoader loader) {
 		AbstractTeam clazz = boundClassMap.get(id);
 		if (clazz == null) {
 			clazz = createClass(className, id, BytecodeProviderFactory.getBytecodeProvider(), loader);
@@ -123,7 +124,7 @@
 	 * @param isHCR true if invoked during hot code replace, in which case transformation must restart using the new bytes
 	 * @return
 	 */
-	public synchronized AbstractBoundClass getBoundClass(String className, String id, byte[] classBytes, ClassLoader loader, boolean isHCR) 
+	public synchronized AbstractBoundClass getBoundClass(@NonNull String className, String id, byte[] classBytes, ClassLoader loader, boolean isHCR) 
 	{
 		AbstractTeam clazz = boundClassMap.get(id);
 		// set the bytecode in the BytecodeProvider
@@ -193,7 +194,7 @@
 	 * @param id a globally unique identifier for the team 
 	 * @return
 	 */
-	public AbstractTeam getTeam(String teamName, String id, ClassLoader loader) {
+	public AbstractTeam getTeam(@NonNull String teamName, String id, ClassLoader loader) {
 		return (AbstractTeam) getBoundClass(teamName, id, loader);
 	}
 	
@@ -228,5 +229,5 @@
 	 * @param bytecodeProvider
 	 * @return
 	 */
-	protected abstract AbstractTeam createClass(String name, String id, IBytecodeProvider bytecodeProvider, ClassLoader loader);
+	protected abstract AbstractTeam createClass(@NonNull String name, String id, IBytecodeProvider bytecodeProvider, ClassLoader loader);
 }
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmBoundClass.java
index c630adb..b31c9d7 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmBoundClass.java
@@ -30,6 +30,8 @@
 import org.objectweb.asm.ClassReader;

 import org.objectweb.asm.Opcodes;

 

+import org.eclipse.jdt.annotation.*;

+

 /**

  * This class implements the bytecode parsing for {@link AbstractBoundClass}.

  * It parses the bytecode with ASM.

@@ -58,9 +60,9 @@
 	 * Set of base classes to which the current class or one of its roles as playedBy bindings.

 	 * Qualified class names are '.' separated.

 	 */

-	public Set<String> boundBaseClasses;

+	public Set<@NonNull String> boundBaseClasses;

 

-	protected AsmBoundClass(String name, String id, IBytecodeProvider bytecodeProvider, ClassLoader loader) {

+	protected AsmBoundClass(@NonNull String name, String id, IBytecodeProvider bytecodeProvider, ClassLoader loader) {

 		super(name, id, loader);

 		this.bytecodeProvider = bytecodeProvider;

 	}

@@ -129,7 +131,7 @@
     }

 

 	@Override

-	public Collection<String> getBoundBaseClasses() {

+	public Collection<@NonNull String> getBoundBaseClasses() {

 		return this.boundBaseClasses;

 	}

 

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmClassRepository.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmClassRepository.java
index 2b062ad..7832cb2 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmClassRepository.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmClassRepository.java
@@ -16,6 +16,7 @@
  **********************************************************************/

 package org.eclipse.objectteams.otredyn.bytecode.asm;

 

+import org.eclipse.jdt.annotation.NonNull;

 import org.eclipse.objectteams.otredyn.bytecode.AbstractTeam;

 import org.eclipse.objectteams.otredyn.bytecode.ClassRepository;

 import org.eclipse.objectteams.otredyn.bytecode.IBytecodeProvider;

@@ -29,7 +30,7 @@
 

 	

 	@Override

-	protected AbstractTeam createClass(String name, String id, IBytecodeProvider bytecodeProvider, ClassLoader loader) {

+	protected AbstractTeam createClass(@NonNull String name, String id, IBytecodeProvider bytecodeProvider, ClassLoader loader) {

 		return new AsmWritableBoundClass(name, id, bytecodeProvider, loader);

 	}

 }

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmClassVisitor.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmClassVisitor.java
index 8b9e2f4..5038a11 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmClassVisitor.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmClassVisitor.java
@@ -104,7 +104,7 @@
 			System.err.println(attribute);

 		}

 		if (clazz.boundBaseClasses == null)

-			clazz.boundBaseClasses = new HashSet<String>();

+			clazz.boundBaseClasses = new HashSet<>();

 		if (attribute.type == null) {

 			System.err.println("OTDRE: bytecode attribute in class "+this.clazz.getName()+" has no type "+attribute.getClass().getName());

 			return;

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
index a3b6d97..5d99742 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
@@ -22,6 +22,8 @@
 import java.util.ArrayList;

 import java.util.List;

 

+import org.eclipse.jdt.annotation.NonNull;

+import org.eclipse.jdt.annotation.Nullable;

 import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;

 import org.eclipse.objectteams.otredyn.bytecode.AbstractTeam;

 import org.eclipse.objectteams.otredyn.bytecode.Field;

@@ -67,7 +69,7 @@
 	private boolean isTransformationActive;

 	private Boolean superIsWeavable;

 

-	protected AsmWritableBoundClass(String name, String id, IBytecodeProvider bytecodeProvider, ClassLoader loader) {

+	protected AsmWritableBoundClass(@NonNull String name, String id, IBytecodeProvider bytecodeProvider, ClassLoader loader) {

 		super(name, id, bytecodeProvider, loader);

 	}

 	

@@ -523,7 +525,7 @@
 			// are created by visitors of the multiAdapter, see prepareAsPossibleBaseClass().

 		} else if (this.weavingContext != null) {

 			IReweavingTask task = new IReweavingTask() {

-				@Override public void reweave(Class<?> definedClass) throws IllegalClassFormatException {

+				@Override public void reweave(@Nullable Class<?> definedClass) throws IllegalClassFormatException {

 					startTransaction();

 					if (!isTransformationActive) {

 						startTransformation();

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/Attributes.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/Attributes.java
index affd685..e105509 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/Attributes.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/Attributes.java
@@ -19,6 +19,7 @@
 import java.util.ArrayList;

 import java.util.List;

 

+import org.eclipse.jdt.annotation.NonNull;

 import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;

 import org.eclipse.objectteams.otredyn.bytecode.Binding;

 import org.eclipse.objectteams.otredyn.bytecode.ClassRepository;

@@ -292,9 +293,9 @@
 		class DecapsField {

 			String accessMode;

 			boolean isStatic;

-			String baseclass, name, desc;

+			@NonNull String baseclass, name, desc;

 			public int perTeamAccessId;

-			public DecapsField(String baseclass, String name, String desc, int accessId, String accessMode, boolean isStatic) {

+			public DecapsField(@NonNull String baseclass, @NonNull String name, @NonNull String desc, int accessId, String accessMode, boolean isStatic) {

 				this.baseclass = baseclass;

 				this.name = name;

 				this.desc = desc;

@@ -304,11 +305,11 @@
 			}

 		}

 		class DecapsMethod {

-			String[] weaveIntoClasses;

-			String declaringClass, name, desc;

+			@NonNull String[] weaveIntoClasses;

+			@NonNull String declaringClass, name, desc;

 			int perTeamAccessId;

 			boolean isStatic;

-			DecapsMethod(String weaveIntoClasses, String declaringClass, String name, String desc, int id, boolean isStatic) {

+			DecapsMethod(@NonNull String weaveIntoClasses, @NonNull String declaringClass, @NonNull String name, @NonNull String desc, int id, boolean isStatic) {

 				this.weaveIntoClasses = weaveIntoClasses.split(":");

 				this.declaringClass = declaringClass;

 				this.name = name;

@@ -377,7 +378,11 @@
 				declaringClass = encodedName.substring(0, pos);

 				methodName = encodedName.substring(pos+1);

 			}

-			this.methods.add(new DecapsMethod(className, declaringClass, methodName, methodDesc, accessId, isStatic));

+			if (className != null && declaringClass != null && methodName != null && methodDesc != null) {

+				this.methods.add(new DecapsMethod(className, declaringClass, methodName, methodDesc, accessId, isStatic));

+			} else {

+				System.err.println("Class attribute has unexpected null value: "+className+":"+declaringClass+":"+methodName+":"+methodDesc);

+			}

 		}

 		private void readFieldAccess(ClassReader cr, int off, char[] buf) {

 			int accessId = cr.readUnsignedShort(off);

@@ -387,7 +392,12 @@
 			String fieldDesc  = cr.readUTF8(off+7, buf);

 			boolean isStatic = (flags & 2) != 0;

 			String accessMode = (flags & 1) == 1 ? "set" : "get";

-			this.fields.add(new DecapsField(className, fieldName, fieldDesc, accessId, accessMode, isStatic));

+			if (className != null && fieldName != null && fieldDesc != null) {

+				this.fields.add(new DecapsField(className, fieldName, fieldDesc, accessId, accessMode, isStatic));

+			} else {

+				System.err.println("Class attribute has unexpected null value: "+className+":"+fieldName+":"+fieldDesc);

+			}

+

 		}

 		public void registerAt(AsmBoundClass clazz) {

 			ClassRepository repo = ClassRepository.getInstance();

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java
index 49528c5..c942205 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java
@@ -17,6 +17,7 @@
  */
 package org.eclipse.objectteams.otredyn.transformer;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.objectteams.runtime.IReweavingTask;
 
 /**
@@ -60,5 +61,5 @@
 	 * @param task
 	 * @return <code>true</code> indicates the task has been scheduled for later.
 	 */
-	boolean scheduleReweaving(String className, IReweavingTask task);
+	boolean scheduleReweaving(@NonNull String className, @NonNull IReweavingTask task);
 }
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
index f3a960d..306f719 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
@@ -33,6 +33,7 @@
 import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
 import org.eclipse.objectteams.runtime.IReweavingTask;
 
+import org.eclipse.jdt.annotation.*;
 
 /**
  * This class does all needed transformations at load time.
@@ -49,7 +50,7 @@
 
 	private IWeavingContext weavingContext;
 	
-	private Set<String> boundBaseClassNames = new HashSet<String>();
+	private Set<@NonNull String> boundBaseClassNames = new HashSet<>();
 
 	public ObjectTeamsTransformer() {
 		this.weavingContext = new IWeavingContext() {
@@ -57,7 +58,7 @@
 				return ObjectTeamsTransformer.isWeavable(className.replace('.', '/'))
 						&& WeavableRegionReader.isWeavable(className);
 			}
-			@Override public boolean scheduleReweaving(String className, IReweavingTask task) {
+			@Override public boolean scheduleReweaving(@NonNull String className, @NonNull IReweavingTask task) {
 				return false; // default is to let the transformer work immediately
 			}
 		};
@@ -147,7 +148,7 @@
 if (PWR_DEBUG) System.out.println("\tweave3");
 		clazz.dump(classfileBuffer, "initial");
 		
-		Collection<String> boundBaseClasses = clazz.getBoundBaseClasses();
+		Collection<@NonNull String> boundBaseClasses = clazz.getBoundBaseClasses();
 		if (boundBaseClasses != null)
 			this.boundBaseClassNames.addAll(boundBaseClasses);
 
@@ -218,7 +219,7 @@
 			t.printStackTrace();
 		}
 		
-		Collection<String> boundBaseClasses = clazz.getBoundBaseClasses();
+		Collection<@NonNull String> boundBaseClasses = clazz.getBoundBaseClasses();
 		if (boundBaseClasses != null)
 			this.boundBaseClassNames.addAll(boundBaseClasses);
 	}
@@ -227,11 +228,11 @@
 	 * After {@link #transform(ClassLoader, String, Class, ProtectionDomain, byte[])} or {@link #readOTAttributes(String, String, InputStream, ClassLoader)}
 	 * this method will answer the qualified names (dot-separated) of all base classes adapated by the current team and its roles.
 	 */
-	public Collection<String> fetchAdaptedBases() {
+	public Collection<@NonNull String> fetchAdaptedBases() {
 		try {
 			return this.boundBaseClassNames;
 		} finally {
-			this.boundBaseClassNames = new HashSet<String>();
+			this.boundBaseClassNames = new HashSet<>();
 		}
 	}
 }
diff --git a/plugins/org.eclipse.objectteams.runtime/.classpath b/plugins/org.eclipse.objectteams.runtime/.classpath
index 22f3064..779c14c 100644
--- a/plugins/org.eclipse.objectteams.runtime/.classpath
+++ b/plugins/org.eclipse.objectteams.runtime/.classpath
@@ -1,7 +1,11 @@
 <?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/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="annotationpath" value="/org.eclipse.objectteams.runtime/annotations/jre"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/lang/Class.eea b/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/lang/Class.eea
new file mode 100644
index 0000000..5084d60
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/lang/Class.eea
@@ -0,0 +1,4 @@
+class java/lang/Class
+getName
+ ()Ljava/lang/String;
+ ()L1java/lang/String;
diff --git a/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/lang/String.eea b/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/lang/String.eea
new file mode 100644
index 0000000..ef8fc40
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/lang/String.eea
@@ -0,0 +1,4 @@
+class java/lang/String
+replace
+ (CC)Ljava/lang/String;
+ (CC)L1java/lang/String;
diff --git a/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/util/Map.eea b/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/util/Map.eea
new file mode 100644
index 0000000..97ab712
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.runtime/annotations/jre/java/util/Map.eea
@@ -0,0 +1,7 @@
+class java/util/Map
+get
+ (Ljava/lang/Object;)TV;
+ (Ljava/lang/Object;)T0V;
+remove
+ (Ljava/lang/Object;)TV;
+ (Ljava/lang/Object;)T0V;
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otredyn/runtime/IClassRepository.java b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otredyn/runtime/IClassRepository.java
index 160ae3f..9892bbd 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otredyn/runtime/IClassRepository.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/eclipse/objectteams/otredyn/runtime/IClassRepository.java
@@ -17,6 +17,8 @@
  **********************************************************************/
 package org.eclipse.objectteams.otredyn.runtime;
 
+import org.eclipse.jdt.annotation.NonNull;
+
 /**
  * Interface through which the {@link TeamManager} reaches into the OTREDyn.
  * Representation of a repository of {@link IBoundClass}es.
@@ -37,7 +39,7 @@
 	 * @param id a globally unique identifier for the class 
 	 * @return
 	 */
-	public IBoundClass getBoundClass(String className, String id, ClassLoader loader);
+	public IBoundClass getBoundClass(@NonNull String className, String id, ClassLoader loader);
 
 	/**
 	 * Returns a instance of AbstractBoundClass for the
@@ -54,7 +56,7 @@
 	 * @param isHCR true if invoked during hot code replace, in which case transformation must restart using the new bytes
 	 * @return
 	 */
-	public IBoundClass getBoundClass(String className, String id, byte[] classBytes, ClassLoader loader, boolean isHCR);
+	public IBoundClass getBoundClass(@NonNull String className, String id, byte[] classBytes, ClassLoader loader, boolean isHCR);
 
 	/**
 	 * Returns a instance of AbstractTeam for the
@@ -70,6 +72,6 @@
 	 * @param id a globally unique identifier for the team 
 	 * @return
 	 */
-	public IBoundTeam getTeam(String teamName, String id, ClassLoader loader);
+	public IBoundTeam getTeam(@NonNull String teamName, String id, ClassLoader loader);
 
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/objectteams/DoublyWeakHashMap.java b/plugins/org.eclipse.objectteams.runtime/src/org/objectteams/DoublyWeakHashMap.java
index 82a65fa..5763864 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/objectteams/DoublyWeakHashMap.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/objectteams/DoublyWeakHashMap.java
@@ -24,6 +24,8 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 
+import org.eclipse.jdt.annotation.Nullable;
+
 /**
  * This class defines hash maps where both key and value are weak references.
  * It is implemented by delegating to a WeakHashMap and additionally
@@ -60,7 +62,7 @@
 	}
 
 	// used from getRole()
-	public V get(Object key) {
+	public @Nullable V get(Object key) {
 		WeakReference<V> valRef = this.map.get(key);
 		return valRef == null ? null : valRef.get();
 	}
@@ -72,7 +74,7 @@
 	}
 
 	// used from unregisterRole(), migrateToBase()
-	public synchronized V remove(Object key) {
+	public synchronized @Nullable V remove(Object key) {
 		WeakReference<V> value = this.map.remove(key);
 		return (value == null) ? null : value.get();
 	}
diff --git a/plugins/org.eclipse.objectteams.runtime/src/org/objectteams/Team.java b/plugins/org.eclipse.objectteams.runtime/src/org/objectteams/Team.java
index 57c3dc8..f60f76b 100644
--- a/plugins/org.eclipse.objectteams.runtime/src/org/objectteams/Team.java
+++ b/plugins/org.eclipse.objectteams.runtime/src/org/objectteams/Team.java
@@ -213,10 +213,10 @@
 	}
 
 	private void _OT$activateForAllThreads() {
-		HashSet threads = TeamThreadManager.getExistingThreads();
-		Iterator it = threads.iterator();
+		HashSet<Thread> threads = TeamThreadManager.getExistingThreads();
+		Iterator<Thread> it = threads.iterator();
 		while (it.hasNext()) {
-			Thread a_thread = (Thread) it.next();
+			Thread a_thread = it.next();
 			activate(a_thread); // use smaller activate version (no ALL_THREADS, no registerAtBases,...
 		}
 	}