OT/Equinox version of patch v7: https://bugs.eclipse.org/bugs/attachment.cgi?id=186890
from https://bugs.eclipse.org/186342 - [compiler][null] Using annotations for null checking
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/.classpath b/plugins/org.eclipse.objectteams.jdt.nullity/.classpath
new file mode 100644
index 0000000..cee6929
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/.classpath
@@ -0,0 +1,8 @@
+<?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/J2SE-1.5"/>
+	<classpathentry kind="con" path="OTRE"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/.project b/plugins/org.eclipse.objectteams.jdt.nullity/.project
new file mode 100644
index 0000000..7a34e08
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.objectteams.jdt.nullity</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.objectteams.otdt.builder.OTJBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.objectteams.otdt.OTJavaNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.objectteams.jdt.nullity/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..5f39a6f
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,76 @@
+#Fri Jan 21 21:57:41 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+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.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=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=enabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.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.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.objectteams.otdt.compiler.option.pure_java=enabled
+org.eclipse.objectteams.otdt.compiler.problem.binding_conventions=error
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.jdt.nullity/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ea5100d
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: JDT Null Annotation Checker
+Bundle-SymbolicName: org.eclipse.objectteams.jdt.nullity;singleton:=true
+Bundle-Version: 0.7.0.qualifier
+Bundle-Activator: org.eclipse.objectteams.internal.jdt.nullity.Activator
+Bundle-Vendor: Eclipse Object Teams Project
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.objectteams.otequinox,
+ org.eclipse.jdt.core;bundle-version="3.7.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.objectteams.internal.jdt.nullity;x-friends:="org.eclipse.objectteams.jdt.nullity.tests"
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/build.properties b/plugins/org.eclipse.objectteams.jdt.nullity/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/plugin.xml b/plugins/org.eclipse.objectteams.jdt.nullity/plugin.xml
new file mode 100644
index 0000000..f4f619f
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.objectteams.otequinox.aspectBindings">
+      <aspectBinding
+            icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/calloutbinding_obj.gif">
+         <basePlugin
+               icon="platform:/plugin/org.eclipse.pde.ui/icons/obj16/plugin_obj.gif"
+               id="org.eclipse.jdt.core">
+         </basePlugin>
+         <team
+               activation="ALL_THREADS"
+               class="org.eclipse.objectteams.internal.jdt.nullity.CompilerAdaptation"
+               icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+         </team>
+      </aspectBinding>
+   </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/Activator.java b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/Activator.java
new file mode 100644
index 0000000..f9536d2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/Activator.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GK Software AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Stephan Herrmann - initial API and implementation 
+ *******************************************************************************/
+package org.eclipse.objectteams.internal.jdt.nullity;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+	private static BundleContext context;
+
+	static BundleContext getContext() {
+		return context;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext bundleContext) throws Exception {
+		Activator.context = bundleContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext bundleContext) throws Exception {
+		Activator.context = null;
+	}
+
+}
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/CompilerAdaptation.java b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/CompilerAdaptation.java
new file mode 100644
index 0000000..00643d2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/CompilerAdaptation.java
@@ -0,0 +1,904 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GK Software AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Stephan Herrmann - initial API and implementation 
+ *******************************************************************************/
+package org.eclipse.objectteams.internal.jdt.nullity;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ImportBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfInt;
+
+import static org.eclipse.objectteams.internal.jdt.nullity.IConstants.IProblem;
+import static org.eclipse.objectteams.internal.jdt.nullity.IConstants.TagBits;
+import static org.eclipse.objectteams.internal.jdt.nullity.IConstants.TypeIds;
+
+import base org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import base org.eclipse.jdt.internal.compiler.ast.Annotation;
+import base org.eclipse.jdt.internal.compiler.ast.Assignment;
+import base org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import base org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import base org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import base org.eclipse.jdt.internal.compiler.ast.Statement;
+import base org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import base org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
+import base org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import base org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import base org.eclipse.jdt.internal.compiler.lookup.MethodVerifier15;
+import base org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import base org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import base org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import base org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+/**
+ * This team class adds the implementation from
+ * https://bugs.eclipse.org/bugs/186342 - [compiler][null] Using annotations for null checking
+ * to the compiler.
+ * 
+ * It essentially reflects the state of https://bugs.eclipse.org/bugs/attachment.cgi?id=186890
+ */
+@SuppressWarnings("restriction")
+public team class CompilerAdaptation {
+	
+	public CompilerAdaptation () {
+		// add more irritants to IrritantSet:
+		IrritantSet.COMPILER_DEFAULT_ERRORS.set( NullCompilerOptions.NullContractViolation
+				 							    |NullCompilerOptions.PotentialNullContractViolation);
+		IrritantSet.COMPILER_DEFAULT_WARNINGS.set(NullCompilerOptions.NullContractInsufficientInfo);
+		IrritantSet.NULL.set( NullCompilerOptions.NullContractViolation
+							 |NullCompilerOptions.PotentialNullContractViolation
+							 |NullCompilerOptions.NullContractInsufficientInfo);
+	}
+
+	// ======================= Statement level analysis ============================
+	
+	@SuppressWarnings("abstractrelevantrole")
+	protected abstract class Statement playedBy Statement {
+		abstract Expression getExpression();
+		
+		// use custom hook from JDT/Core (https://bugs.eclipse.org/335093)
+		checkAgainstNullAnnotation <- replace checkAgainstNullAnnotation;
+		/** Check assignment to local with null annotation. */
+		@SuppressWarnings("basecall")
+		callin int checkAgainstNullAnnotation(BlockScope currentScope, LocalVariableBinding local,int nullStatus)
+		{
+			if (   local != null
+				&& (local.tagBits & TagBits.AnnotationNonNull) != 0 
+				&& nullStatus != FlowInfo.NON_NULL)
+			{
+				currentScope.problemReporter().possiblyNullToNonNullLocal(local.name, getExpression(), nullStatus,
+						currentScope.environment().getNonNullAnnotationName());
+				nullStatus=FlowInfo.NON_NULL;
+			}
+			return nullStatus;
+		}
+		
+	}
+	protected class Assignment extends Statement playedBy Assignment {
+		/** Wire required method of super class. */
+		Expression getExpression() -> get Expression expression;		
+	}
+	protected class LocalDeclaration extends Statement playedBy LocalDeclaration {
+		/** Wire required method of super class. */
+		Expression getExpression() -> get Expression initialization;
+	}
+	
+	/** Infrastructure for context dependend hooking into null analysis. */
+	protected team class AnalyseContext playedBy Statement {
+		
+		callin FlowInfo analyseCode() { // void return breaks _OT$result passing!
+			within (this)	// temporarily activate this team to enable callin in nested role (ContextualExpression)
+				return base.analyseCode();
+		}
+		
+		@SuppressWarnings({ "abstractrelevantrole", "bindingconventions" })
+		protected abstract class ContextualExpression playedBy Expression {
+
+			int nullStatus(FlowInfo flowInfo) -> int nullStatus(FlowInfo flowInfo);
+
+			void analyseNull(BlockScope currentScope, FlowInfo flowInfo)
+			<- after FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo)
+				with { currentScope <- currentScope, flowInfo <- result }
+			
+			abstract void analyseNull(BlockScope currentScope, FlowInfo flowInfo);
+		}
+	}
+	
+	/** Analyse argument expressions as part of a MessageSend, check against method parameter annotation. */
+	protected team class MessageSend extends AnalyseContext playedBy MessageSend {
+
+		Expression[] getArguments() -> get Expression[] arguments;
+		MethodBinding getBinding() -> get MethodBinding binding;
+
+		nullStatus <- replace nullStatus;
+
+		@SuppressWarnings("basecall")
+		callin int nullStatus(FlowInfo flowInfo) {
+			MethodBinding binding = this.getBinding();
+			if (binding.isValidBinding()) {
+				// try to retrieve null status of this message send from an annotation of the called method:
+				long tagBits = binding.getTagBits();
+				if ((tagBits & TagBits.AnnotationNonNull) != 0)
+					return FlowInfo.NON_NULL;
+				if ((tagBits & TagBits.AnnotationNullable) != 0)
+					return FlowInfo.POTENTIALLY_NULL;
+			}
+			return base.nullStatus(flowInfo);
+		}
+		
+		// helper to recover some lost information:
+		public int findArgumentIndex(Expression argumentExpression) {
+			Expression[] arguments = this.getArguments();
+			for (int i=0; i<arguments.length; i++)
+				if (arguments[i] == argumentExpression)
+					return i;
+			return -1;
+		}
+		
+		FlowInfo analyseCode() <- replace FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo);
+
+		@SuppressWarnings("bindingconventions")
+		protected class ContextualExpression  {
+
+			void analyseNull(BlockScope currentScope, FlowInfo flowInfo) {
+				// compare actual null-status against parameter annotations of the called method:
+				int nullStatus = nullStatus(flowInfo);
+				MethodBinding methodBinding = MessageSend.this.getBinding();
+				if (   nullStatus != FlowInfo.NON_NULL 
+					&& methodBinding.parameterNonNullness != null)
+				{
+					int i = MessageSend.this.findArgumentIndex(this);
+					if (i != -1) { // is it an argument (vs. receiver)?
+						if (methodBinding.parameterNonNullness[i].booleanValue()) // if @NonNull is required
+						{
+							char[][] annotationName = currentScope.environment().getNonNullAnnotationName();
+							currentScope.problemReporter().possiblyNullToNonNullParameter(this, nullStatus, annotationName[annotationName.length-1]);
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	/** Analyse the expression within a return statement, check against method return annotation. */
+	protected team class ReturnStatement extends AnalyseContext playedBy ReturnStatement {
+
+		int getSourceStart() -> get int sourceStart;
+
+		int getSourceEnd() -> get int sourceEnd;
+		
+		
+		FlowInfo analyseCode() <- replace FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo);
+
+		@SuppressWarnings("bindingconventions")
+		protected class ContextualExpression {
+
+			void analyseNull(BlockScope currentScope, FlowInfo flowInfo) {
+				int nullStatus = nullStatus(flowInfo);
+				if (nullStatus != FlowInfo.NON_NULL) {
+					// if we can't prove non-null check against declared null-ness of the enclosing method:
+					long tagBits;
+					try {
+						tagBits = currentScope.methodScope().referenceMethod().binding.tagBits;
+					} catch (NullPointerException npe) {
+						return;
+					}
+					if ((tagBits & TagBits.AnnotationNonNull) != 0) {
+						char[][] annotationName = currentScope.environment().getNonNullAnnotationName();
+						// FIXME(SH): problem in the OT/J compiler: broken lowering of ReturnStatement.this
+						currentScope.problemReporter().possiblyNullFromNonNullMethod(ReturnStatement.this, nullStatus, 
+																					 annotationName[annotationName.length-1]);
+					}
+				}
+			}			
+		}
+	}
+
+	// ======================= Method level annotations ============================
+
+	protected class Annotation playedBy Annotation {
+
+		@SuppressWarnings("decapsulation")
+		detectStandardAnnotation <- replace detectStandardAnnotation;
+
+		callin long detectStandardAnnotation(Scope scope, ReferenceBinding annotationType, MemberValuePair valueAttribute) 
+		{
+			long tagBits = base.detectStandardAnnotation(scope, annotationType, valueAttribute);
+			switch (annotationType.id) {
+			case TypeIds.T_ConfiguredAnnotationNullable :
+				tagBits |= TagBits.AnnotationNullable;
+				break;
+			case TypeIds.T_ConfiguredAnnotationNonNull :
+				tagBits |= TagBits.AnnotationNonNull;
+				break;
+			}
+			return tagBits;
+		}
+	}
+	
+	protected class AbstractMethodDeclaration playedBy AbstractMethodDeclaration {
+
+		Argument[] getArguments()  -> get Argument[] arguments;
+		MethodBinding getBinding() -> get MethodBinding binding;
+		void bindArguments()       -> void bindArguments();
+		
+		
+		void resolveArgumentNullAnnotations() <- replace void bindArguments();
+
+		@SuppressWarnings("basecall")
+		callin void resolveArgumentNullAnnotations() {
+			MethodBinding binding = getBinding();
+			if (binding != null) {
+				if ((binding.getTagBits() & TagBits.HasBoundArguments) != 0) // avoid double execution
+					return;
+				binding.addTagBit(TagBits.HasBoundArguments);
+			}
+			base.resolveArgumentNullAnnotations();
+			Argument[] arguments = this.getArguments();
+			if (arguments != null) {
+				for (int i = 0, length = arguments.length; i < length; i++) {
+					Argument argument = arguments[i];
+					// transfer nullness info from the argument to the method:
+					if ((argument.binding.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) != 0) {
+						if (binding.parameterNonNullness == null)
+							binding.parameterNonNullness = new Boolean[arguments.length];
+						binding.parameterNonNullness[i] = Boolean.valueOf((argument.binding.tagBits & TagBits.AnnotationNonNull) != 0);
+					}
+				}
+			}
+		}
+
+		/** Feed null status from parameter annotation into the analysis of the method's body. */
+		void analyseArgumentNullity(FlowInfo info)
+		<- before void analyseCode(ClassScope classScope, InitializationFlowContext initializationContext, FlowInfo info)
+			with { info <- info }
+
+		private void analyseArgumentNullity(FlowInfo info) {
+			Argument[] arguments = this.getArguments();
+			if (arguments != null) {
+				for (int i = 0, count = arguments.length; i < count; i++) {
+					// leverage null-info from parameter annotations:
+					long argumentTagBits = arguments[i].binding.tagBits;
+					if ((argumentTagBits & TagBits.AnnotationNullable) != 0)
+						info.markPotentiallyNullBit(arguments[i].binding);
+					else if ((argumentTagBits & TagBits.AnnotationNonNull) != 0)
+						info.markAsDefinitelyNonNull(arguments[i].binding);
+				}
+			}
+		}
+	}
+
+	/** Add a field to store parameter nullness information. */
+	protected class MethodBinding playedBy MethodBinding {
+
+		/** Store nullness information from annotation (incl. inherited contracts). */
+		public Boolean[] parameterNonNullness;  // TRUE means @NonNull declared, FALSE means @Nullable declared, null means nothing declared
+
+		ReferenceBinding getDeclaringClass() 	-> get ReferenceBinding declaringClass;
+		TypeBinding[] getParameters() 			-> get TypeBinding[] parameters;
+		long getTagBits() 					 	-> get long tagBits;
+		public void addTagBit(long bit) 	 	-> set long tagBits 
+			with { bit | getTagBits() 			-> tagBits }
+
+		boolean isStatic() 						-> boolean isStatic();
+		boolean isValidBinding() 				-> boolean isValidBinding();
+		AbstractMethodDeclaration sourceMethod()-> AbstractMethodDeclaration sourceMethod();
+	}
+
+	/** Transfer inherited null contracts and check compatibility. */
+	@SuppressWarnings("decapsulation")
+	protected class MethodVerifier15 playedBy MethodVerifier15 {
+
+		LookupEnvironment getEnvironment() 	-> get LookupEnvironment environment;
+		ProblemReporter problemReporter() 	-> get SourceTypeBinding type
+				with  {  result 			<- type.scope.problemReporter() }
+		AbstractMethodDeclaration[] getMethodDeclarations() -> get SourceTypeBinding type
+				with { 	result 				<- type.scope.referenceContext.methods }
+
+		
+		void checkNullContractInheritance(MethodBinding currentMethod, MethodBinding[] methods, int length)
+		<- after
+		void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length, MethodBinding[] allInheritedMethods);
+
+		void bindMethodArguments() <- after void computeMethods();
+
+		
+		
+		void checkNullContractInheritance(MethodBinding currentMethod, MethodBinding[] methods, int length) {
+			for (int i = length; --i >= 0;)
+				if (!currentMethod.isStatic() && !methods[i].isStatic())
+					checkNullContractInheritance(currentMethod, methods[i]);
+		}
+		
+		void checkNullContractInheritance(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+			long inheritedBits = inheritedMethod.getTagBits();
+			long currentBits = currentMethod.getTagBits();
+			LookupEnvironment environment = this.getEnvironment();
+			
+			// return type:
+			if ((inheritedBits & TagBits.AnnotationNonNull) != 0) {
+				if ((currentBits & TagBits.AnnotationNullable) != 0) {
+					AbstractMethodDeclaration methodDecl = currentMethod.sourceMethod();
+					problemReporter().illegalRedefinitionToNullableReturn(methodDecl, inheritedMethod.getDeclaringClass(), 
+																		environment.getNonNullAnnotationName());
+				}
+			}
+			if ((currentBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) == 0)
+				currentMethod.addTagBit(inheritedBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable));
+
+			// parameters:
+			Argument[] currentArguments = currentMethod.sourceMethod().getArguments();
+			if (inheritedMethod.parameterNonNullness != null) {
+				// inherited method has null-annotations, check and possibly transfer:
+				
+				// prepare for transferring (contract inheritance):
+				if (currentMethod.parameterNonNullness == null)
+					currentMethod.parameterNonNullness = new Boolean[currentMethod.getParameters().length];
+				
+				for (int i = 0; i < inheritedMethod.parameterNonNullness.length; i++) {
+					
+					Boolean inheritedNonNullNess = inheritedMethod.parameterNonNullness[i];
+					if (inheritedNonNullNess != Boolean.TRUE) { 	 				 // super parameter is not restricted to @NonNull
+						if (currentMethod.parameterNonNullness[i] == Boolean.TRUE) { // current parameter is restricted to @NonNull
+							problemReporter().illegalRedefinitionToNonNullParameter(
+																currentArguments[i],
+																inheritedMethod.getDeclaringClass(),
+																inheritedNonNullNess == null
+																? null
+																: environment.getNullableAnnotationName());
+							continue;
+						} 
+					}
+					
+					if (currentMethod.parameterNonNullness[i] == null && inheritedNonNullNess != null) {
+						// inherit this annotation as the current method has no annotation:
+						currentMethod.parameterNonNullness[i] = inheritedNonNullNess;
+						VariableBinding argumentBinding = currentArguments[i].binding;
+						argumentBinding.tagBits |= inheritedNonNullNess.booleanValue()
+														? TagBits.AnnotationNonNull : TagBits.AnnotationNullable;
+					}
+				}
+			} else if (currentMethod.parameterNonNullness != null) {
+				// super method has no annotations but current has
+				for (int i = 0; i < currentMethod.parameterNonNullness.length; i++) {
+					if (currentMethod.parameterNonNullness[i] == Boolean.TRUE) { // tightening from unconstrained to @NonNull
+						problemReporter().illegalRedefinitionToNonNullParameter(
+																		currentArguments[i],
+																		inheritedMethod.getDeclaringClass(),
+																		null);
+					}
+				}
+			}
+		}
+
+		void bindMethodArguments() {
+			// binding the arguments is required for null contract checking, which needs argument annotations
+			AbstractMethodDeclaration[] methodDeclarations = getMethodDeclarations();
+			if (methodDeclarations != null)
+				for (AbstractMethodDeclaration methodDecl : methodDeclarations)
+					methodDecl.bindArguments();
+		}
+	}
+
+	/** Retrieve null annotations from binary methods. */
+	protected class BinaryTypeBinding playedBy BinaryTypeBinding {
+		@SuppressWarnings("decapsulation")
+		LookupEnvironment getEnvironment() -> get LookupEnvironment environment;
+
+		/** Constructor for emulated annotation type. */
+		@SuppressWarnings({ "inferredcallout", "decapsulation" })
+		protected BinaryTypeBinding(char[][] compoundName, ReferenceBinding superclass, org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding, int typeId) 
+		{
+			base();
+			this.compoundName = compoundName;
+			this.sourceName = compoundName[compoundName.length-1];
+			this.modifiers = ClassFileConstants.AccAnnotation | ClassFileConstants.AccPublic;
+			this.fields = Binding.NO_FIELDS;
+			this.methods = Binding.NO_METHODS;
+			this.memberTypes = Binding.NO_MEMBER_TYPES;
+			this.superclass = superclass;
+			this.superInterfaces = Binding.NO_SUPERINTERFACES;
+			this.fPackage = packageBinding;
+			this.typeVariables = Binding.NO_TYPE_VARIABLES;
+			this.tagBits = TagBits.AreFieldsComplete | TagBits.AreFieldsSorted 
+									| TagBits.AreMethodsComplete | TagBits.AreMethodsSorted 
+									| TagBits.HasNoMemberTypes | TagBits.TypeVariablesAreConnected
+									| TagBits.AnnotationClassRetention 
+									| TagBits.AnnotationForMethod | TagBits.AnnotationForParameter 
+									| TagBits.AnnotationForLocalVariable ;
+			this.id = typeId;
+		}
+		
+		void scanForNullAnnotation(IBinaryMethod method, MethodBinding methodBinding) 
+		<- after MethodBinding createMethod(IBinaryMethod method, long sourceLevel, char[][][] missingTypeNames)
+			with { method <- method, methodBinding <- result }
+		
+		void scanForNullAnnotation(IBinaryMethod method, MethodBinding methodBinding) {
+			LookupEnvironment environment = this.getEnvironment();
+			char[][] nullableAnnotationName = environment.getNullableAnnotationName();
+			char[][] nonNullAnnotationName = environment.getNonNullAnnotationName();
+			if (nullableAnnotationName == null || nonNullAnnotationName == null)
+				return; // not configured to use null annotations
+
+			// return:
+			IBinaryAnnotation[] annotations = method.getAnnotations();
+			if (annotations != null) {
+				for (int i = 0; i < annotations.length; i++) {
+					char[] annotationTypeName = annotations[i].getTypeName();
+					if (annotationTypeName[0] != 'L')
+						continue;
+					char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
+					if (CharOperation.equals(typeName, nonNullAnnotationName)) {
+						methodBinding.addTagBit(TagBits.AnnotationNonNull);
+						break;
+					}
+					if (CharOperation.equals(typeName, nullableAnnotationName)) {
+						methodBinding.addTagBit(TagBits.AnnotationNullable);
+						break;
+					}
+				}
+			}
+
+			// parameters:
+			TypeBinding[] parameters = methodBinding.getParameters();
+			for (int j = 0; j < parameters.length; j++) {
+				IBinaryAnnotation[] paramAnnotations = method.getParameterAnnotations(j); 
+				if (paramAnnotations != null) {
+					for (int i = 0; i < paramAnnotations.length; i++) {
+						char[] annotationTypeName = paramAnnotations[i].getTypeName();
+						if (annotationTypeName[0] != 'L')
+							continue;
+						char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
+						if (CharOperation.equals(typeName, nonNullAnnotationName)) {
+							if (methodBinding.parameterNonNullness == null)
+								methodBinding.parameterNonNullness = new Boolean[parameters.length];
+							methodBinding.parameterNonNullness[j] = Boolean.TRUE;
+							break;
+						} else if (CharOperation.equals(typeName, nullableAnnotationName)) {
+							if (methodBinding.parameterNonNullness == null)
+								methodBinding.parameterNonNullness = new Boolean[parameters.length];
+							methodBinding.parameterNonNullness[j] = Boolean.FALSE;
+							break;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	// ========================== Configuration of null annotation types =========================
+
+	/** Initiate setup of configured null annotation types. */
+	protected class LookupEnvironment playedBy LookupEnvironment {
+
+		ProblemReporter getProblemReporter() 				-> get ProblemReporter problemReporter;
+		ReferenceBinding getType(char[][] compoundName) 	-> ReferenceBinding getType(char[][] compoundName);
+		PackageBinding createPackage(char[][] compoundName) -> PackageBinding createPackage(char[][] compoundName);
+
+		boolean packageInitialized = false;
+		
+		/** The first time a package is requested initialize the null annotation type package. */
+		void initNullAnnotationPackage()
+					<- before PackageBinding getTopLevelPackage(char[] name),
+							  PackageBinding createPackage(char[][] compoundName)
+			when (!this.packageInitialized);
+
+		private void initNullAnnotationPackage() {
+			this.packageInitialized = true;
+			char[][] compoundName = getNullableAnnotationName();
+			if (compoundName != null)
+				setupNullAnnotationPackage(compoundName, TypeIds.T_ConfiguredAnnotationNullable);
+			compoundName = getNonNullAnnotationName();
+			if (compoundName != null)
+				setupNullAnnotationPackage(compoundName, TypeIds.T_ConfiguredAnnotationNonNull);
+		}
+		
+		/** 
+		 * Create or retrieve the package holding the specified type.
+		 * If emulation is enabled fill it with an emulated type of the given name.
+		 * Prepare the package with all information to do the second stage of initialization/checking.
+		 */
+		void setupNullAnnotationPackage(char[][] typeName, int typeId) {
+			char[][] packageName = CharOperation.subarray(typeName, 0, typeName.length-1);
+			PackageBinding packageBinding = createPackage(packageName);
+			char[] simpleTypeName = typeName[typeName.length-1];
+			if (getGlobalOptions().emulateNullAnnotationTypes) {
+				// before adding an emulated type, check if type this type already exists:
+				ReferenceBinding existingType = packageBinding.getType(simpleTypeName);
+				if (existingType != null && existingType.isValidBinding())
+					getProblemReporter().conflictingTypeEmulation(typeName);
+				else
+					packageBinding.addType(new BinaryTypeBinding(
+												typeName,
+												getType(TypeConstants.JAVA_LANG_OBJECT),
+												packageBinding,
+												typeId));
+				packageBinding.shouldEmulate = true;
+			}
+			if (typeId == TypeIds.T_ConfiguredAnnotationNullable)
+				packageBinding.nullableName = simpleTypeName;
+			else
+				packageBinding.nonNullName = simpleTypeName;
+		}
+
+		CompilerOptions getGlobalOptions() -> get CompilerOptions globalOptions;
+
+		public char[][] getNullableAnnotationName() {
+			return getGlobalOptions().nullableAnnotationName;
+		}
+
+		public char[][] getNonNullAnnotationName() {
+			return getGlobalOptions().nonNullAnnotationName;
+		}
+	}
+
+	/** The package holding the configured null annotation types detects and marks these annotation types. */
+	@SuppressWarnings("decapsulation")
+	protected class PackageBinding playedBy PackageBinding {
+
+		LookupEnvironment getEnvironment() 				-> get LookupEnvironment environment;
+		protected ReferenceBinding getType(char[] name) -> ReferenceBinding getType(char[] name);
+		protected void addType(ReferenceBinding element)-> void addType(ReferenceBinding element);
+		
+		protected char[] nullableName = null;
+		protected char[] nonNullName = null;
+		protected boolean shouldEmulate = false;
+
+		void setupNullAnnotationType(ReferenceBinding type) <- after void addType(ReferenceBinding type)
+			when (this.nullableName != null || this.nullableName != null);
+
+		void setupNullAnnotationType(ReferenceBinding type) {
+			int id = 0;
+			if (CharOperation.equals(this.nullableName, type.sourceName))
+				id = TypeIds.T_ConfiguredAnnotationNullable;
+			else if (CharOperation.equals(this.nonNullName, type.sourceName))
+				id = TypeIds.T_ConfiguredAnnotationNonNull;
+			else 
+				return;
+			
+			// we're adding a null annotation type to this package:			
+			if (this.shouldEmulate) // unfortunately here we don't have any source to report the error against.
+				getEnvironment().getProblemReporter().conflictingTypeEmulation(type.compoundName);
+			else
+				type.id = id;	// ensure annotations of this type are detected as standard annotations.
+		}		
+	}
+
+	/** Intermediate role to provide access to environment and problemReporter as roles, too. */
+	protected class BlockScope playedBy BlockScope {
+		ProblemReporter problemReporter() 	-> ProblemReporter problemReporter();
+		MethodScope methodScope() 			-> MethodScope methodScope();
+		LookupEnvironment environment() 	-> LookupEnvironment environment();
+	}
+
+	// ======================= Problem reporting ==================================
+	
+	/** 
+	 * Adapt the base class for handling new problem ids and irritants.
+	 * Add new problem reporting methods.
+	 */
+	protected class ProblemReporter playedBy ProblemReporter {
+
+		@SuppressWarnings("decapsulation")
+		void handle(int problemId, String[] problemArguments, String[] messageArguments, int severity,
+				int problemStartPosition, int problemEndPosition)
+		->
+		void handle(int problemId, String[] problemArguments, String[] messageArguments, int severity,
+				int problemStartPosition, int problemEndPosition);
+		@SuppressWarnings("decapsulation")
+		void handle(int problemId, String[] problemArguments, String[] messageArguments, int problemStartPosition, int problemEndPosition)
+		->
+		void handle(int problemId, String[] problemArguments, String[] messageArguments, int problemStartPosition, int problemEndPosition);
+		
+		void abortDueToInternalError(String errorMessage) -> void abortDueToInternalError(String errorMessage);
+		
+		
+		getProblemCategory <- replace getProblemCategory;
+		
+		getNullIrritant <- replace getIrritant;
+
+		
+		@SuppressWarnings("basecall")
+		static callin int getProblemCategory(int severity, int problemID) {
+			categorizeOnIrritant: {
+				// fatal problems even if optional are all falling into same category (not irritant based)
+				if ((severity & ProblemSeverities.Fatal) != 0)
+					break categorizeOnIrritant;
+				int irritant = getIrritant(problemID);
+				switch (irritant) {
+				case CompilerOptions.NullContractViolation :
+				case CompilerOptions.PotentialNullContractViolation :
+				case CompilerOptions.NullContractInsufficientInfo :
+					return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
+				}
+				// categorize fatal problems per ID
+				switch (problemID) {
+					case IProblem.ConflictingTypeEmulation :
+					case IProblem.MissingNullAnnotationType :
+						return CategorizedProblem.CAT_BUILDPATH;
+				}
+			}
+			return base.getProblemCategory(severity, problemID);
+		}
+		
+		@SuppressWarnings("basecall")
+		static callin int getNullIrritant(int problemID) {
+			int irritant = getIrritant(problemID);
+			if (irritant != 0)
+				return irritant;
+			return base.getNullIrritant(problemID);
+		}
+
+		private static int getIrritant(int problemID) {
+			switch(problemID) {
+				case IProblem.DefiniteNullFromNonNullMethod:
+				case IProblem.DefiniteNullToNonNullLocal:
+				case IProblem.DefiniteNullToNonNullParameter:
+				case IProblem.IllegalRedefinitionToNullableReturn:
+				case IProblem.IllegalRedefinitionToNonNullParameter:
+				case IProblem.IllegalDefinitionToNonNullParameter:
+					return CompilerOptions.NullContractViolation;
+				case IProblem.PotentialNullFromNonNullMethod:
+				case IProblem.PotentialNullToNonNullLocal:
+				case IProblem.PotentialNullToNonNullParameter:
+					return CompilerOptions.PotentialNullContractViolation;
+				case IProblem.NonNullLocalInsufficientInfo:
+				case IProblem.NonNullParameterInsufficientInfo:
+				case IProblem.NonNullReturnInsufficientInfo:
+					return CompilerOptions.NullContractInsufficientInfo;
+			}
+			return 0;
+		}
+	
+		public void possiblyNullFromNonNullMethod(ReturnStatement returnStatement, int nullStatus, char[] annotationName) {
+			int problemId = IProblem.NonNullReturnInsufficientInfo;
+			if ((nullStatus & FlowInfo.NULL) != 0)
+				problemId = IProblem.DefiniteNullFromNonNullMethod;
+			if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
+				problemId = IProblem.PotentialNullFromNonNullMethod;
+			String[] arguments = new String[] { String.valueOf(annotationName) };
+			this.handle(
+				problemId,
+				arguments,
+				arguments,
+				returnStatement.getSourceStart(),
+				returnStatement.getSourceEnd());
+		}
+		public void possiblyNullToNonNullLocal(char[] variableName, org.eclipse.jdt.internal.compiler.ast.Expression expression, int nullStatus, char[][] annotationName) {
+			int problemId = IProblem.NonNullLocalInsufficientInfo;
+			if ((nullStatus & FlowInfo.NULL) != 0)
+				problemId = IProblem.DefiniteNullToNonNullLocal;
+			else if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
+				problemId = IProblem.PotentialNullToNonNullLocal;
+			String[] arguments = new String[] {
+					String.valueOf(variableName),
+					String.valueOf(annotationName[annotationName.length-1]) 
+			};
+			this.handle(
+				problemId,
+				arguments,
+				arguments,
+				expression.sourceStart,
+				expression.sourceEnd);
+		}
+		public void possiblyNullToNonNullParameter(org.eclipse.jdt.internal.compiler.ast.Expression argument, int nullStatus, char[] annotationName) {
+			int problemId = IProblem.NonNullParameterInsufficientInfo;
+			if ((nullStatus & FlowInfo.NULL) != 0)
+				problemId = IProblem.DefiniteNullToNonNullParameter;
+			else if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
+				problemId = IProblem.PotentialNullToNonNullParameter;
+			String[] arguments = new String[] { String.valueOf(annotationName) };
+			this.handle(
+				problemId,
+				arguments,
+				arguments,
+				argument.sourceStart,
+				argument.sourceEnd);
+		}
+		public void illegalRedefinitionToNonNullParameter(Argument argument, ReferenceBinding declaringClass, char[][] inheritedAnnotationName) {
+			if (inheritedAnnotationName == null) {
+				this.handle(
+					IProblem.IllegalDefinitionToNonNullParameter, 
+					new String[] { new String(argument.name), new String(declaringClass.readableName()) },
+					new String[] { new String(argument.name), new String(declaringClass.shortReadableName()) },
+					argument.sourceStart, 
+					argument.sourceEnd);
+				
+			} else {
+				this.handle(
+					IProblem.IllegalRedefinitionToNonNullParameter, 
+					new String[] { new String(argument.name), new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)},
+					new String[] { new String(argument.name), new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])},
+					argument.sourceStart, 
+					argument.sourceEnd);
+			}
+		}
+		public void illegalRedefinitionToNullableReturn(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDecl, ReferenceBinding declaringClass, char[][] nonNullAnnotationName) {
+			this.handle(
+				IProblem.IllegalRedefinitionToNullableReturn, 
+				new String[] { new String(declaringClass.readableName()), CharOperation.toString(nonNullAnnotationName)},
+				new String[] { new String(declaringClass.shortReadableName()), new String(nonNullAnnotationName[nonNullAnnotationName.length-1])},
+				methodDecl.sourceStart, 
+				methodDecl.sourceEnd);	
+		}								
+		public void missingNullAnnotationType(char[][] nullAnnotationName) {
+			String[] args = { new String(CharOperation.concatWith(nullAnnotationName, '.')) };
+			this.handle(IProblem.MissingNullAnnotationType, args, args, 0, 0);	
+		}
+		public void conflictingTypeEmulation(char[][] compoundName) {
+			String[] arguments = new String[] {CharOperation.toString(compoundName)};
+			this.handle(
+				IProblem.ConflictingTypeEmulation,
+				arguments,
+				arguments,
+				ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal, // not configurable
+				0, 0);	
+		}
+	}
+	
+	/** Supply more error messages. */
+	protected class ProblemFactory playedBy DefaultProblemFactory {
+		
+		@SuppressWarnings("decapsulation")
+		int keyFromID(int id) -> int keyFromID(int id);
+
+		void loadMessageTemplates(HashtableOfInt templates, Locale loc)
+		<- after HashtableOfInt loadMessageTemplates(Locale loc)
+			with { templates <- result, loc <- loc }
+		
+		@SuppressWarnings("rawtypes") // copied from its base class, only bundleName has been changed
+		public static void loadMessageTemplates(HashtableOfInt templates, Locale loc) {
+			ResourceBundle bundle = null;
+			String bundleName = "org.eclipse.objectteams.internal.jdt.nullity.problem_messages"; //$NON-NLS-1$
+			try {
+				bundle = ResourceBundle.getBundle(bundleName, loc);
+			} catch(MissingResourceException e) {
+				System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + loc); //$NON-NLS-1$//$NON-NLS-2$
+				throw e;
+			}
+			Enumeration keys = bundle.getKeys();
+			while (keys.hasMoreElements()) {
+			    String key = (String)keys.nextElement();
+			    try {
+			        int messageID = Integer.parseInt(key);
+					templates.put(keyFromID(messageID), bundle.getString(key));
+			    } catch(NumberFormatException e) {
+			        // key ill-formed
+				} catch (MissingResourceException e) {
+					// available ID
+			    }
+			}
+		}
+	}
+
+	// ================================== Compiler Options: ==================================
+	// pushed out from role CompilerOptions:
+	private static final char[][] DEFAULT_NONNULL_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNull".toCharArray()); //$NON-NLS-1$
+	private static final char[][] DEFAULT_NULLABLE_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.Nullable".toCharArray()); //$NON-NLS-1$
+
+	@SuppressWarnings("rawtypes")
+	protected class CompilerOptions implements org.eclipse.objectteams.internal.jdt.nullity.NullCompilerOptions playedBy CompilerOptions 
+	{
+		// copies from orig:
+		public static final String ENABLED = "enabled"; //$NON-NLS-1$
+		public static final String DISABLED = "disabled"; //$NON-NLS-1$
+
+
+		@SuppressWarnings("decapsulation")
+		void updateSeverity(int irritant, Object severityString) 	-> void updateSeverity(int irritant, Object severityString);
+		String getSeverityString(int irritant) 						-> String getSeverityString(int irritant);
+		
+
+		/** Fully qualified name of annotation to use as marker for nullable types. */
+		public char[][] nullableAnnotationName;
+		/** Fully qualified name of annotation to use as marker for nonnull types. */
+		public char[][] nonNullAnnotationName;
+		/** Should null annotation types be emulated by synthetic bindings? */
+		public boolean emulateNullAnnotationTypes;
+		
+		String optionKeyFromIrritant(int irritant) <- replace String optionKeyFromIrritant(int irritant);
+		@SuppressWarnings("basecall")
+		static callin String optionKeyFromIrritant(int irritant) {
+			switch(irritant) {
+			case NullContractViolation :
+				return OPTION_ReportNullContractViolation;
+			case PotentialNullContractViolation :
+				return OPTION_ReportPotentialNullContractViolation;
+			case NullContractInsufficientInfo :
+				return OPTION_ReportNullContractInsufficientInfo;
+			default:
+				return base.optionKeyFromIrritant(irritant);
+			}
+		}
+		String warningTokenFromIrritant(int irritant) <- replace String warningTokenFromIrritant(int irritant);
+		@SuppressWarnings("basecall")
+		static callin String warningTokenFromIrritant(int irritant) {
+			switch(irritant) {
+			case NullContractViolation :
+			case PotentialNullContractViolation :
+			case NullContractInsufficientInfo :
+				return "null"; //$NON-NLS-1$
+			default:
+				return base.warningTokenFromIrritant(irritant);
+			}
+		}
+		void getMap(Map optionsMap) <- after Map getMap()
+			with {optionsMap <- result}
+		@SuppressWarnings("unchecked")
+		private void getMap(Map optionsMap) {
+			optionsMap.put(OPTION_ReportNullContractViolation, getSeverityString(NullContractViolation));
+			optionsMap.put(OPTION_ReportPotentialNullContractViolation, getSeverityString(PotentialNullContractViolation));
+			optionsMap.put(OPTION_ReportNullContractInsufficientInfo, getSeverityString(NullContractInsufficientInfo));
+			if (this.nullableAnnotationName != null) {
+				char[] compoundName = CharOperation.concatWith(this.nullableAnnotationName, '.');
+				optionsMap.put(OPTION_NullableAnnotationName, String.valueOf(compoundName));
+			}
+			if (this.nonNullAnnotationName != null) {
+				char[] compoundName = CharOperation.concatWith(this.nonNullAnnotationName, '.');
+				optionsMap.put(OPTION_NonNullAnnotationName, String.valueOf(compoundName));
+			}
+			optionsMap.put(OPTION_EmulateNullAnnotationTypes, this.emulateNullAnnotationTypes ? ENABLED : DISABLED);
+		}
+		void set(Map optionsMap) <- before void set(Map optionsMap);
+		private void set(Map optionsMap) {
+			Object optionValue;
+			if ((optionValue = optionsMap.get(OPTION_ReportNullContractViolation)) != null) updateSeverity(NullContractViolation, optionValue);
+			if ((optionValue = optionsMap.get(OPTION_ReportPotentialNullContractViolation)) != null) updateSeverity(PotentialNullContractViolation, optionValue);
+			if ((optionValue = optionsMap.get(OPTION_ReportNullContractInsufficientInfo)) != null) updateSeverity(NullContractInsufficientInfo, optionValue);
+			if ((optionValue = optionsMap.get(OPTION_NullableAnnotationName)) != null) {
+				this.nullableAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray());
+			}
+			if ((optionValue = optionsMap.get(OPTION_NonNullAnnotationName)) != null) {
+				this.nonNullAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray());
+			}
+			if ((optionValue = optionsMap.get(OPTION_EmulateNullAnnotationTypes)) != null) {
+				if (ENABLED.equals(optionValue)) {
+					this.emulateNullAnnotationTypes = true;
+					// ensure that we actually have annotation names to emulate:
+					if (this.nullableAnnotationName == null)
+						this.nullableAnnotationName = DEFAULT_NULLABLE_ANNOTATION_NAME;
+					if (this.nonNullAnnotationName == null)
+						this.nonNullAnnotationName = DEFAULT_NONNULL_ANNOTATION_NAME;
+				} else if (DISABLED.equals(optionValue)) {
+					this.emulateNullAnnotationTypes = false;
+				}
+			}
+		}
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/IConstants.java b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/IConstants.java
new file mode 100644
index 0000000..6a95761
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/IConstants.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GK Software AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Stephan Herrmann - initial API and implementation 
+ *******************************************************************************/
+package org.eclipse.objectteams.internal.jdt.nullity;
+
+import static org.eclipse.jdt.core.compiler.IProblem.ImportRelated;
+import static org.eclipse.jdt.core.compiler.IProblem.Internal;
+import static org.eclipse.jdt.core.compiler.IProblem.MethodRelated;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+
+@SuppressWarnings("restriction")
+public interface IConstants {
+
+	/** Additional constants for {@link org.eclipse.jdt.internal.compiler.lookup.TagBits}. */
+	static interface TagBits extends org.eclipse.jdt.internal.compiler.lookup.TagBits {
+		long HasBoundArguments = ASTNode.Bit13; // for method bindings to avoid duplicate invocation of bindArguments()
+		 // the following two should be added to TagBits.AllStandardAnnotationsMask:
+		long AnnotationNullable = ASTNode.Bit54L;
+		long AnnotationNonNull = ASTNode.Bit55L;
+	}
+	
+	/** Additional constants for {@link org.eclipse.jdt.internal.compiler.lookup.TypeIds}. */
+	static interface TypeIds {
+		final int T_ConfiguredAnnotationNullable = 60;
+		final int T_ConfiguredAnnotationNonNull = 61;
+	}
+
+	/** Additional constants for {@link org.eclipse.jdt.core.compiler.IProblem}. */
+	static interface IProblem {
+		/** @since 3.7 */
+		int DefiniteNullFromNonNullMethod = MethodRelated + 880;
+		/** @since 3.7 */
+		int PotentialNullFromNonNullMethod = MethodRelated + 881;
+		/** @since 3.7 */
+		int NonNullReturnInsufficientInfo = MethodRelated + 882;
+		/** @since 3.7 */
+		int DefiniteNullToNonNullParameter = MethodRelated + 883;
+		/** @since 3.7 */
+		int PotentialNullToNonNullParameter = MethodRelated + 884;
+		/** @since 3.7 */
+		int NonNullParameterInsufficientInfo = MethodRelated + 885;
+		/** @since 3.7 */
+		int DefiniteNullToNonNullLocal = Internal + 886;
+		/** @since 3.7 */
+		int PotentialNullToNonNullLocal = Internal + 887;
+		/** @since 3.7 */
+		int NonNullLocalInsufficientInfo = Internal + 888;
+		/** @since 3.7 */
+		int ConflictingTypeEmulation = ImportRelated + 889;
+		/** @since 3.7 */
+		int MissingNullAnnotationType = ImportRelated + 890;
+		/** @since 3.7 */
+		int IllegalRedefinitionToNullableReturn = MethodRelated + 891;
+		/** @since 3.7 */
+		int IllegalRedefinitionToNonNullParameter = MethodRelated + 892;
+		/** @since 3.7 */
+		int IllegalDefinitionToNonNullParameter = MethodRelated + 893;
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/NullCompilerOptions.java b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/NullCompilerOptions.java
new file mode 100644
index 0000000..48e56e3
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/NullCompilerOptions.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GK Software AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Stephan Herrmann - initial API and implementation 
+ *******************************************************************************/
+package org.eclipse.objectteams.internal.jdt.nullity;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
+
+/** Additional constants for {@link CompilerOptions}. */
+@SuppressWarnings("restriction")
+public interface NullCompilerOptions {
+	public static final String OPTION_ReportNullContractViolation = "org.eclipse.jdt.core.compiler.problem.nullContractViolation";  //$NON-NLS-1$
+	public static final String OPTION_ReportPotentialNullContractViolation = "org.eclipse.jdt.core.compiler.problem.potentialNullContractViolation";  //$NON-NLS-1$
+	public static final String OPTION_ReportNullContractInsufficientInfo = "org.eclipse.jdt.core.compiler.problem.nullContractInsufficientInfo";  //$NON-NLS-1$
+
+	public static final String OPTION_NullableAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nullable"; //$NON-NLS-1$
+	public static final String OPTION_NonNullAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nonnull"; //$NON-NLS-1$
+	public static final String OPTION_EmulateNullAnnotationTypes = "org.eclipse.jdt.core.compiler.annotation.emulate"; //$NON-NLS-1$
+	
+	public static final int NullContractViolation = IrritantSet.GROUP2 | ASTNode.Bit7;
+	public static final int PotentialNullContractViolation = IrritantSet.GROUP2 | ASTNode.Bit8;
+	public static final int NullContractInsufficientInfo = IrritantSet.GROUP2 | ASTNode.Bit9;
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/problem_messages.properties b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/problem_messages.properties
new file mode 100644
index 0000000..11576f7
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/problem_messages.properties
@@ -0,0 +1,27 @@
+##############################################################################
+# Copyright (c) 2011 GK Software AG and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     Stephan Herrmann - initial API and implementation 
+##############################################################################
+
+### addition for /org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+### NULL ANNOTATIONS
+880 = Null contract violation: returning null from a method declared as @{0}.
+881 = Null contract violation: return value can be null but method is declared as @{0}.
+882 = Potential null contract violation: insufficient nullness information regarding return value while the method is declared as @{0}.
+883 = Null contract violation: passing null to a parameter declared as @{0}.
+884 = Null contract violation: potentially passing null to a parameter declared as @{0}.
+885 = Potential null contract violation: insufficient nullness information regarding a value that is passed to a parameter declared as @{0}.
+886 = Null contract violation: assigning null to local variable {0}, which is declared as @{1}.
+887 = Null contract violation: potentially assigning null to local variable {0}, which is declared as @{1}.
+888 = Potential null contract violation: insufficient nullness information regarding a value that is assigned to local variable {0}, which is declared as @{1}.
+889 = Buildpath problem: emulation of type {0} is requested (for null annotations) but a type of this name exists on the build path.
+890 = Buildpath problem: the type {0} which is configured as a null annotation type cannot be resolved.
+891 = Cannot relax null contract for method return, inherited method from {0} is declared as @{1}.
+892 = Cannot tighten null contract for parameter {0}, inherited method from {1} declares this parameter as @{2}.
+893 = Cannot tighten null contract for parameter {0}, inherited method from {1} does not constrain this parameter.