More warnings (under existing irritants):
 - directly dereferencing nullable message send results
 - comparing nonnull message send result against null
Cleanup messages: don't terminate with full stop.
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
index 8bd42dc..25d37cc 100644
--- 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
@@ -53,6 +53,7 @@
 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.EqualExpression;
 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;
@@ -132,15 +133,9 @@
 
 		@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;
-			}
+			int status = getNullStatus();
+			if (status != FlowInfo.UNKNOWN)
+				return status;
 			return base.nullStatus(flowInfo);
 		}
 		
@@ -168,6 +163,61 @@
 				}
 			}
 		}
+
+		checkNPE <- after checkNPE;
+		/** Detect and signal directly dereferencing a nullable message send result. */
+		void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+			if (getNullStatus() == FlowInfo.POTENTIALLY_NULL)
+				scope.problemReporter().messageSendPotentialNullReference(getBinding(), this);
+		}
+		
+		protected int getNullStatus() {
+			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 FlowInfo.UNKNOWN;
+		}
+	}
+	
+	protected class EqualExpression playedBy EqualExpression {
+		
+		MessageSend getLeftMessage() 		 -> get Expression left
+			with { result					 <- (left instanceof MessageSend) ? (MessageSend) left : null }
+		int getLeftNullStatus(FlowInfo info) -> get Expression left
+			with { result					 <- left.nullStatus(info) }
+		MessageSend getRightMessage() 		 -> get Expression right
+			with { result					 <- (right instanceof MessageSend) ? (MessageSend) right : null }
+		int getRightNullStatus(FlowInfo info)-> get Expression right
+			with { result					 <- right.nullStatus(info) }
+		
+		
+		checkNullComparison <- before checkNullComparison;
+
+		/** Detect and signal when comparing a non-null message send against null. */
+		void checkNullComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo,
+				FlowInfo initsWhenTrue, FlowInfo initsWhenFalse) 
+		{
+			MessageSend leftMessage = getLeftMessage();
+			if (   leftMessage != null 
+				&& leftMessage.getNullStatus() == FlowInfo.NON_NULL
+				&& getRightNullStatus(flowInfo) == FlowInfo.NULL) 
+			{
+				scope.problemReporter().messageSendRedundantCheckOnNonNull(leftMessage.getBinding(), leftMessage);
+			}
+			MessageSend rightMessage = getRightMessage();
+			if (   rightMessage != null 
+				&& rightMessage.getNullStatus() == FlowInfo.NON_NULL 
+				&& getLeftNullStatus(flowInfo) == FlowInfo.NULL) 
+			{
+				scope.problemReporter().messageSendRedundantCheckOnNonNull(rightMessage.getBinding(), rightMessage);
+			}
+		}		
 	}
 	
 	/** Analyse the expression within a return statement, check against method return annotation. */
@@ -296,6 +346,7 @@
 		boolean isStatic() 						-> boolean isStatic();
 		boolean isValidBinding() 				-> boolean isValidBinding();
 		AbstractMethodDeclaration sourceMethod()-> AbstractMethodDeclaration sourceMethod();
+		char[] readableName() 					-> char[] readableName();
 
 		/** After method verifier has finished, fill in missing nullness values from the default. */
 		protected void fillInDefaultNullness(long defaultNullness) {
@@ -333,6 +384,7 @@
 		void fillInDefaultNullNess() <- after void checkMethods();
 		
 		void checkNullContractInheritance(MethodBinding currentMethod, MethodBinding[] methods, int length) {
+			// TODO: change traversal: process all methods at once!
 			for (int i = length; --i >= 0;)
 				if (!currentMethod.isStatic() && !methods[i].isStatic())
 					checkNullContractInheritance(currentMethod, methods[i]);
@@ -698,6 +750,10 @@
 				case IProblem.NonNullParameterInsufficientInfo:
 				case IProblem.NonNullReturnInsufficientInfo:
 					return CompilerOptions.NullContractInsufficientInfo;
+				case IProblem.PotentialNullMessageSendReference:
+					return org.eclipse.jdt.internal.compiler.impl.CompilerOptions.PotentialNullReference;
+				case IProblem.RedundantNullCheckOnNonNullMessageSend:
+					return org.eclipse.jdt.internal.compiler.impl.CompilerOptions.RedundantNullCheck;
 			}
 			return 0;
 		}
@@ -771,8 +827,27 @@
 				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);	
-		}								
+				methodDecl.sourceEnd);
+		}
+		public void messageSendPotentialNullReference(MethodBinding method, ASTNode location) {
+			String[] arguments = new String[] {new String(method.readableName())};
+			this.handle(
+				IProblem.PotentialNullMessageSendReference,
+				arguments,
+				arguments,
+				location.sourceStart,
+				location.sourceEnd);
+		}
+		public void messageSendRedundantCheckOnNonNull(MethodBinding method, ASTNode location) {
+			String[] arguments = new String[] {new String(method.readableName())  };
+			this.handle(
+				IProblem.RedundantNullCheckOnNonNullMessageSend,
+				arguments,
+				arguments,
+				location.sourceStart,
+				location.sourceEnd);
+		}
+
 		public void missingNullAnnotationType(char[][] nullAnnotationName) {
 			String[] args = { new String(CharOperation.concatWith(nullAnnotationName, '.')) };
 			this.handle(IProblem.MissingNullAnnotationType, args, args, 0, 0);	
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
index 6a95761..d98a8c5 100644
--- 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
@@ -63,5 +63,9 @@
 		int IllegalRedefinitionToNonNullParameter = MethodRelated + 892;
 		/** @since 3.7 */
 		int IllegalDefinitionToNonNullParameter = MethodRelated + 893;
+		/** @since 3.7 */
+		int PotentialNullMessageSendReference = Internal + 894;
+		/** @since 3.7 */
+		int RedundantNullCheckOnNonNullMessageSend = 895;
 	}
 }
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
index 11576f7..a4bd5f0 100644
--- 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
@@ -11,17 +11,19 @@
 
 ### 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.
+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
+894 = Potential null pointer access: The method {0} may return null
+895 = Redundant null check: The method {0} cannot return null
\ No newline at end of file