Bug 446442 - [1.8] merge null annotations from super methods
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index b6c4cc8..98ea5fd 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -35,6 +35,7 @@
  *								Bug 430150 - [1.8][null] stricter checking against type variables
  *								Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
  *								Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *     Jesper S Moller - Contributions for
  *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
  *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
@@ -432,9 +433,10 @@
 		expectedProblemAttributes.put("ContainerAnnotationTypeHasShorterRetention", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
 		expectedProblemAttributes.put("ContainerAnnotationTypeHasWrongValueType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
 		expectedProblemAttributes.put("ContainerAnnotationTypeMustHaveValue", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
-		expectedProblemAttributes.put("ContradictoryNullAnnotations", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
-		expectedProblemAttributes.put("ContradictoryNullAnnotationsOnBound", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
-		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferred", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+		expectedProblemAttributes.put("ContradictoryNullAnnotations", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsOnBound", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferred", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferredFunctionType", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("ConflictingImport", new ProblemAttributes(CategorizedProblem.CAT_IMPORT));
 		expectedProblemAttributes.put("ConflictingNullAnnotations", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
@@ -1264,9 +1266,10 @@
 		expectedProblemAttributes.put("ContainerAnnotationTypeHasShorterRetention", SKIP);
 		expectedProblemAttributes.put("ContainerAnnotationTypeHasWrongValueType", SKIP);
 		expectedProblemAttributes.put("ContainerAnnotationTypeMustHaveValue", SKIP);
-		expectedProblemAttributes.put("ContradictoryNullAnnotations", SKIP);
-		expectedProblemAttributes.put("ContradictoryNullAnnotationsOnBound", SKIP);
-		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferred", SKIP);
+		expectedProblemAttributes.put("ContradictoryNullAnnotations", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsOnBound", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferred", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferredFunctionType", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
 		expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(JavaCore.COMPILER_PB_VARARGS_ARGUMENT_NEED_CAST));
 		expectedProblemAttributes.put("CorruptedSignature", SKIP);
 		expectedProblemAttributes.put("DanglingReference", SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index 923c96f..564c6c5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -6960,4 +6960,342 @@
 		"Contradictory null annotations: method was inferred as \'@NonNull @Nullable String a(@NonNull @Nullable String)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
 		"----------\n");
 }
+public void testBug446442_comment2a() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"\n" + 
+			"	void m(@Nullable T arg1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public void m(@NonNull Integer i) {}\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		x= null;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 11)\n" + 
+		"	public void m(@NonNull Integer i) {}\n" + 
+		"	              ^^^^^^^^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo<Integer,Integer> declares this parameter as @Nullable\n" + 
+		"----------\n");
+}
+// swapped order of method declarations
+public void testBug446442_comment2b() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(@Nullable T arg1);\n" + 
+			"\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public void m(@NonNull Integer i) {}\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		x= null;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 11)\n" + 
+		"	public void m(@NonNull Integer i) {}\n" + 
+		"	              ^^^^^^^^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo<Integer,Integer> declares this parameter as @Nullable\n" + 
+		"----------\n");
+}
+// inherit from two different supers
+public void testBug446442_comment2c() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo0<T, N extends Number> {\n" + 
+			"	void m(@Nullable T arg1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Foo1<T, N extends Number> {\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo1<Integer, Integer>,  Foo0<Integer, Integer> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public void m(@NonNull Integer i) {}\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		x= null;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 13)\n" + 
+		"	public void m(@NonNull Integer i) {}\n" + 
+		"	              ^^^^^^^^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo0<Integer,Integer> declares this parameter as @Nullable\n" + 
+		"----------\n");
+}
+// merging @NonNull & unannotated in arg-position must answer unannotated
+public void testBug446442_2a() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"\n" + 
+			"	void m(T arg1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		@NonNull Object o = x;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in Test.java (at line 12)\n" + 
+		"	@NonNull Object o = x;\n" + 
+		"	                    ^\n" + 
+		"Null type safety (type annotations): The expression of type \'Integer\' needs unchecked conversion to conform to \'@NonNull Object\'\n" + 
+		"----------\n");
+}
+// merging @NonNull & unannotated in arg-position must answer unannotated - swapped order
+public void testBug446442_2b() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(T arg1);\n" + 
+			"\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		@NonNull Object o = x;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in Test.java (at line 12)\n" + 
+		"	@NonNull Object o = x;\n" + 
+		"	                    ^\n" + 
+		"Null type safety (type annotations): The expression of type \'Integer\' needs unchecked conversion to conform to \'@NonNull Object\'\n" + 
+		"----------\n");
+}
+// using inherited implementation to fulfill both contracts
+public void testBug446442_3() {
+	runConformTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"\n" + 
+			"	void m(T arg1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"class Impl {\n" + 
+			"  public void m(Integer a) {}\n" + 
+			"}\n" + 
+			"class BazImpl extends Impl implements Baz {}\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"	void test(BazImpl b) {\n" + 
+			"		b.m(null);\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+// unsuccessful attempt to trigger use of MostSpecificExceptionMethodBinding
+public void testBug446442_4() {
+	runConformTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"interface Foo<T, N extends Number> {\n" + 
+			"	abstract void m(@NonNull N arg2) throws Exception;\n" + 
+			"\n" + 
+			"	default void m(T arg1) throws java.io.IOException {}\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"abstract class Impl {\n" + 
+			"  public void m(Integer a) throws java.io.IOException {}\n" + 
+			"}\n" + 
+			"class BazImpl extends Impl implements Baz {}\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"	void test(BazImpl b) throws java.io.IOException {\n" + 
+			"		b.m(null);\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+// annotated return types
+public void testBug446442_5() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	T m(T t);\n" + 
+			"\n" + 
+			"	@NonNull N m(N n);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public Integer m(Integer i) { return new Integer(0); }\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> null;\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 11)\n" + 
+		"	public Integer m(Integer i) { return new Integer(0); }\n" + 
+		"	       ^^^^^^^\n" + 
+		"The return type is incompatible with \'@NonNull Integer\' returned from Foo<Integer,Integer>.m(Integer) (mismatching null constraints)\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 15)\n" + 
+		"	Baz baz= x -> null;\n" + 
+		"	              ^^^^\n" + 
+		"Null type mismatch: required \'@NonNull Integer\' but the provided value is null\n" + 
+		"----------\n");
+}
+// conflicting annotations on type arguments
+public void testBug446442_6a() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"import java.util.*;\n" +
+			"interface Foo<T,C1 extends Collection<T>, C2 extends List<T>> {\n" + 
+			"	void m(C1 a1);\n" + 
+			"\n" + 
+			"	void m(C2 a2);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, ArrayList<@NonNull Integer>, ArrayList<@Nullable Integer>> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public void m(ArrayList<@NonNull Integer> i) {} // contradictory type cannot be implemented\n" +
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> { // contradictory type cannot be used as SAM\n" +
+			"		x.add(null); // contradictory type cause errors at call sites\n" +
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 12)\n" + 
+		"	public void m(ArrayList<@NonNull Integer> i) {} // contradictory type cannot be implemented\n" + 
+		"	              ^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo<Integer,ArrayList<Integer>,ArrayList<Integer>> declares this parameter as \'ArrayList<@Nullable Integer>\' (mismatching null constraints)\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 16)\n" + 
+		"	Baz baz= x -> { // contradictory type cannot be used as SAM\n" + 
+		"		x.add(null); // contradictory type cause errors at call sites\n" + 
+		"	}; \n" + 
+		"	         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Contradictory null annotations: function type was inferred as \'void (ArrayList<@NonNull @Nullable Integer>)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n" + 
+		"3. ERROR in Test.java (at line 17)\n" + 
+		"	x.add(null); // contradictory type cause errors at call sites\n" + 
+		"	^^^^^^^^^^^\n" + 
+		"Contradictory null annotations: method was inferred as \'boolean add(@NonNull @Nullable Integer)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n");
+}
+// swapped order of method declarations + added return type
+public void testBug446442_6b() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"import java.util.*;\n" +
+			"interface Foo<T,C1 extends Collection<T>, C2 extends List<T>> {\n" + 
+			"	C2 m(C2 a2);\n" + 
+			"\n" + 
+			"	C1 m(C1 a1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, ArrayList<@NonNull Integer>, ArrayList<@Nullable Integer>> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public ArrayList<@NonNull Integer> m(ArrayList<@Nullable Integer> i) { return i; }\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		x.add(null);\n" +
+			"		x.get(0);\n" +
+			"		return x;\n" + 
+			"	};\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 12)\n" + 
+		"	public ArrayList<@NonNull Integer> m(ArrayList<@Nullable Integer> i) { return i; }\n" + 
+		"	       ^^^^^^^^^\n" + 
+		"The return type is incompatible with \'ArrayList<@Nullable Integer>\' returned from Foo<Integer,ArrayList<Integer>,ArrayList<Integer>>.m(ArrayList<Integer>) (mismatching null constraints)\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 12)\n" + 
+		"	public ArrayList<@NonNull Integer> m(ArrayList<@Nullable Integer> i) { return i; }\n" + 
+		"	                                     ^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo<Integer,ArrayList<Integer>,ArrayList<Integer>> declares this parameter as \'ArrayList<@NonNull Integer>\' (mismatching null constraints)\n" + 
+		"----------\n" + 
+		"3. ERROR in Test.java (at line 16)\n" + 
+		"	Baz baz= x -> {\n" + 
+		"		x.add(null);\n" + 
+		"		x.get(0);\n" + 
+		"		return x;\n" + 
+		"	};\n" + 
+		"	         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Contradictory null annotations: function type was inferred as \'ArrayList<@NonNull @Nullable Integer> (ArrayList<@NonNull @Nullable Integer>)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n" + 
+		"4. ERROR in Test.java (at line 17)\n" + 
+		"	x.add(null);\n" + 
+		"	^^^^^^^^^^^\n" + 
+		"Contradictory null annotations: method was inferred as \'boolean add(@NonNull @Nullable Integer)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n" + 
+		"5. ERROR in Test.java (at line 18)\n" + 
+		"	x.get(0);\n" + 
+		"	^^^^^^^^\n" + 
+		"Contradictory null annotations: method was inferred as \'@NonNull @Nullable Integer get(int)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n");
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 1b27d3c..d1df0cd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -194,6 +194,7 @@
  *									NullityMismatchAgainstFreeTypeVariable
  *									ImplicitObjectBoundNoNullDefault
  *									IllegalParameterNullityRedefinition
+ *									ContradictoryNullAnnotationsInferredFunctionType
  *      Jesper S Moller  - added the following constants
  *									TargetTypeNotAFunctionalInterface
  *									OuterLocalMustBeEffectivelyFinal
@@ -1798,6 +1799,8 @@
 	int ImplicitObjectBoundNoNullDefault = 971;
 	/** @since 3.11 */
 	int IllegalParameterNullityRedefinition = MethodRelated + 972;
+	/** @since 3.11 */
+	int ContradictoryNullAnnotationsInferredFunctionType = MethodRelated + 973;
 
 
 	// Java 8 work
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 5dd8d3b..6564b8a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -32,6 +32,7 @@
  *								Bug 440143 - [1.8][null] one more case of contradictory null annotations regarding type variables
  *								Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
  *								Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *     Jesper S Moller - Contributions for
  *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
  *								bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
@@ -947,7 +948,7 @@
 		AnnotationBinding [] se8Annotations = null;
 		int se8count = 0;
 		long se8nullBits = 0;
-		Annotation se8NullAnnotation = null;
+		Annotation se8NullAnnotation = null; // just any involved annotation so we have a location for error reporting
 		int firstSE8 = -1;
 		for (int i = 0, length = annotations.length; i < length; i++) {
 			AnnotationBinding annotation = annotations[i].getCompilerAnnotation();
@@ -970,10 +971,10 @@
 					se8Annotations[se8count++] = annotation;
 				}
 				if (annotationType.id == TypeIds.T_ConfiguredAnnotationNonNull) {
-					se8nullBits = TagBits.AnnotationNonNull;
+					se8nullBits |= TagBits.AnnotationNonNull;
 					se8NullAnnotation = annotations[i];
 				} else if (annotationType.id == TypeIds.T_ConfiguredAnnotationNullable) {
-					se8nullBits = TagBits.AnnotationNullable;
+					se8nullBits |= TagBits.AnnotationNullable;
 					se8NullAnnotation = annotations[i];
 				}
 			}
@@ -1038,13 +1039,14 @@
 		
 		// for arrays: @T X[] SE7 associates @T to the type, but in SE8 it affects the leaf component type
 		long prevNullBits = existingType.leafComponentType().tagBits & TagBits.AnnotationNullMASK;
-		if (se8nullBits != 0 && prevNullBits != se8nullBits && ((prevNullBits | se8nullBits) == TagBits.AnnotationNullMASK)) {
-			if (existingType instanceof TypeVariableBinding) {
-				// let type-use annotations override annotations on the type parameter declaration
-				existingType = existingType.withoutToplevelNullAnnotation();
-			} else {
-				scope.problemReporter().contradictoryNullAnnotations(se8NullAnnotation);
+		if ((prevNullBits | se8nullBits) == TagBits.AnnotationNullMASK) { // contradiction after merge?
+			if (!(existingType instanceof TypeVariableBinding)) { // let type-use annotations override annotations on the type parameter declaration
+				if (prevNullBits != TagBits.AnnotationNullMASK && se8nullBits != TagBits.AnnotationNullMASK) { // conflict caused by the merge?
+					scope.problemReporter().contradictoryNullAnnotations(se8NullAnnotation);
+				}
+				se8Annotations = Binding.NO_ANNOTATIONS;
 			}
+			existingType = existingType.withoutToplevelNullAnnotation();
 		}
 		TypeBinding oldLeafType = (unionRef == null) ? existingType.leafComponentType() : unionRef.resolvedType;
 		AnnotationBinding [][] goodies = new AnnotationBinding[typeRef.getAnnotatableLevels()][];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
index 4f992eb..8cd39d8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
@@ -19,6 +19,7 @@
  *							Bug 424403 - [1.8][compiler] Generic method call with method reference argument fails to resolve properly.
  *							Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
  *							Bug 428352 - [1.8][compiler] Resolution errors don't always surface
+ *							Bug 446442 - [1.8] merge null annotations from super methods
  *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
  *******************************************************************************/
@@ -179,6 +180,8 @@
 		
 		this.descriptor = sam;
 		if (kosherDescriptor(blockScope, sam, true)) {
+			if (blockScope.environment().globalOptions.isAnnotationBasedNullAnalysisEnabled)
+				NullAnnotationMatching.checkForContradictions(sam, this, blockScope);
 			return this.resolvedType = this.expectedType;		
 		}
 		
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
index be01e6f..1a979f7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
@@ -13,11 +13,13 @@
 import org.eclipse.jdt.internal.compiler.flow.FlowContext;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
@@ -418,8 +420,8 @@
 	 * After a method has substituted type parameters, check if this resulted in any contradictory null annotations.
 	 * Problems are either reported directly (if scope != null) or by returning a ProblemMethodBinding.
 	 */
-	public static MethodBinding checkForContraditions(
-			final MethodBinding method, final InvocationSite invocationSite, final Scope scope) {
+	public static MethodBinding checkForContradictions(
+			final MethodBinding method, final Object location, final Scope scope) {
 		
 		class SearchContradictions extends TypeBindingVisitor {
 			ReferenceBinding typeWithContradiction;
@@ -441,19 +443,27 @@
 			}
 		}
 
+		int start = 0, end = 0;
+		if (location instanceof InvocationSite) {
+			start = ((InvocationSite) location).sourceStart();
+			end = ((InvocationSite) location).sourceEnd();
+		} else if (location instanceof ASTNode) {
+			start = ((ASTNode) location).sourceStart;
+			end = ((ASTNode) location).sourceEnd;
+		}
 		SearchContradictions searchContradiction = new SearchContradictions();
 		TypeBindingVisitor.visit(searchContradiction, method.returnType);
 		if (searchContradiction.typeWithContradiction != null) {
 			if (scope == null)
 				return new ProblemMethodBinding(method, method.selector, method.parameters, ProblemReasons.ContradictoryNullAnnotations);
-			scope.problemReporter().contradictoryNullAnnotationsInferred(method, invocationSite);
+			scope.problemReporter().contradictoryNullAnnotationsInferred(method, start, end, location instanceof FunctionalExpression);
 			// note: if needed, we might want to update the method by removing the contradictory annotations??
 			return method;
 		}
 
 		Expression[] arguments = null;
-		if (invocationSite instanceof Invocation)
-			arguments = ((Invocation)invocationSite).arguments();
+		if (location instanceof Invocation)
+			arguments = ((Invocation)location).arguments();
 		for (int i = 0; i < method.parameters.length; i++) {
 			TypeBindingVisitor.visit(searchContradiction, method.parameters[i]);
 			if (searchContradiction.typeWithContradiction != null) {
@@ -462,10 +472,53 @@
 				if (arguments != null && i < arguments.length)
 					scope.problemReporter().contradictoryNullAnnotationsInferred(method, arguments[i]);
 				else
-					scope.problemReporter().contradictoryNullAnnotationsInferred(method, invocationSite);
+					scope.problemReporter().contradictoryNullAnnotationsInferred(method, start, end, location instanceof FunctionalExpression);
 				return method;
 			}
 		}
 		return method;
 	}
+
+	public static TypeBinding strongerType(TypeBinding type1, TypeBinding type2, LookupEnvironment environment) {
+		if ((type1.tagBits & TagBits.AnnotationNonNull) != 0)
+			return mergeTypeAnnotations(type1, type2, true, environment);
+		return mergeTypeAnnotations(type2, type1, true, environment); // don't bother to distinguish unannotated vs. @Nullable, since both can accept null
+	}
+
+	public static TypeBinding[] weakerTypes(TypeBinding[] parameters1, TypeBinding[] parameters2, LookupEnvironment environment) {
+		TypeBinding[] newParameters = new TypeBinding[parameters1.length];
+		for (int i = 0; i < newParameters.length; i++) {
+			long tagBits1 = parameters1[i].tagBits;
+			long tagBits2 = parameters2[i].tagBits;
+			if ((tagBits1 & TagBits.AnnotationNullable) != 0)
+				newParameters[i] = mergeTypeAnnotations(parameters1[i], parameters2[i], true, environment);		// @Nullable must be preserved
+			else if ((tagBits2 & TagBits.AnnotationNullable) != 0)
+				newParameters[i] = mergeTypeAnnotations(parameters2[i], parameters1[i], true, environment);		// @Nullable must be preserved
+			else if ((tagBits1 & TagBits.AnnotationNonNull) == 0)
+				newParameters[i] = mergeTypeAnnotations(parameters1[i], parameters2[i], true, environment);		// unannotated must be preserved
+			else
+				newParameters[i] = mergeTypeAnnotations(parameters2[i], parameters1[i], true, environment);		// either unannotated, or both are @NonNull
+		}
+		return newParameters;
+	}
+	private static TypeBinding mergeTypeAnnotations(TypeBinding type, TypeBinding otherType, boolean top, LookupEnvironment environment) {
+		TypeBinding mainType = type;
+		if (!top) {
+			// for all but the top level type superimpose other's type annotation onto type
+			AnnotationBinding[] otherAnnotations = otherType.getTypeAnnotations();
+			if (otherAnnotations != Binding.NO_ANNOTATIONS)
+				mainType = environment.createAnnotatedType(type, otherAnnotations);
+		}
+		if (mainType instanceof ParameterizedTypeBinding && otherType instanceof ParameterizedTypeBinding) {
+			ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) type, otherPTB = (ParameterizedTypeBinding) otherType;
+			TypeBinding[] typeArguments = ptb.arguments;
+			TypeBinding[] otherTypeArguments = otherPTB.arguments;
+			TypeBinding[] newTypeArguments = new TypeBinding[typeArguments.length];
+			for (int i = 0; i < typeArguments.length; i++) {
+				newTypeArguments[i] = mergeTypeAnnotations(typeArguments[i], otherTypeArguments[i], false, environment);
+			}
+			return environment.createParameterizedType(ptb.genericType(), newTypeArguments, ptb.enclosingType());
+		}
+		return mainType;
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
index 36e08a6..80370ea 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
@@ -112,7 +112,7 @@
 						// recurse to prepare currentSuper
 						checkImplicitNullAnnotations(currentSuper, null, false, scope); // TODO (stephan) complain=true if currentSuper is source method??
 					}
-					checkNullSpecInheritance(currentMethod, srcMethod, needToApplyReturnNonNullDefault, needToApplyParameterNonNullDefault, complain, currentSuper, scope, inheritedNonNullnessInfos);
+					checkNullSpecInheritance(currentMethod, srcMethod, needToApplyReturnNonNullDefault, needToApplyParameterNonNullDefault, complain, currentSuper, null, scope, inheritedNonNullnessInfos);
 					needToApplyNonNullDefault = false;
 				}
 				
@@ -192,16 +192,18 @@
 	{
 		MethodBinding [] ifcMethods = superType.getMethods(selector, suggestedParameterLength);
 		int length = ifcMethods.length;
+		boolean added = false;
 		for  (int i=0; i<length; i++) {
 			MethodBinding currentMethod = ifcMethods[i];
 			if (currentMethod.isStatic())
 				continue;
 			if (MethodVerifier.doesMethodOverride(original, currentMethod, this.environment)) {
 				result.add(currentMethod);
-				return; // at most one method is overridden from any supertype
+				added = true; // when overriding one or more methods from superType don't traverse to transitive superTypes
 			}
 		}
-		findAllOverriddenMethods(original, selector, suggestedParameterLength, superType, ifcsSeen, result);
+		if (!added)
+			findAllOverriddenMethods(original, selector, suggestedParameterLength, superType, ifcsSeen, result);
 	}
 
 	/**
@@ -213,6 +215,7 @@
 	 * @param shouldComplain should we report any errors found? 
 	 *   (see also comment about flows into this method, below).
 	 * @param inheritedMethod one overridden method from a super type
+	 * @param allInheritedMethods look here to see if nonnull-unannotated conflict already exists in one super type
 	 * @param scope provides context for error reporting etc.
 	 * @param inheritedNonNullnessInfos if non-null, this array of non-null elements is used for
 	 * 	 interim recording of nullness information from inheritedMethod rather than prematurely updating currentMethod.
@@ -220,7 +223,7 @@
 	 */
 	void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod, 
 			boolean hasReturnNonNullDefault, boolean hasParameterNonNullDefault, boolean shouldComplain,
-			MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos) 
+			MethodBinding inheritedMethod, MethodBinding[] allInheritedMethods, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos) 
 	{
 		// Note that basically two different flows lead into this method:
 		// (1) during MethodVerifyer15.checkMethods() we want to report errors (against srcMethod or against the current type)
@@ -324,6 +327,7 @@
 		else if (currentMethod.parameterNonNullness != null)
 			length = currentMethod.parameterNonNullness.length;
 
+		parameterLoop:
 		for (int i = 0; i < length; i++) {
 			if (currentMethod.parameters[i].isBaseType()) continue;
 
@@ -404,6 +408,12 @@
 						continue;
 					} else if (inheritedNonNullNess == Boolean.TRUE) {
 						// not strictly a conflict, but a configurable warning is given anyway:
+						if (allInheritedMethods != null) {
+							// avoid this optional warning if the conflict already existed in one supertype (merging of two methods into one?)
+							for (MethodBinding one : allInheritedMethods)
+								if (TypeBinding.equalsEquals(inheritedMethod.declaringClass, one.declaringClass) && getParameterNonNullness(one, i, useTypeAnnotations) != Boolean.TRUE)
+									continue parameterLoop;
+						}
 						scope.problemReporter().parameterLackingNonnullAnnotation(
 								currentArgument,
 								inheritedMethod.declaringClass,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index 359f71e..905fdf8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -28,6 +28,7 @@
  *								Bug 390889 - [1.8][compiler] Evaluate options to support 1.7- projects against 1.8 JRE.
  *								Bug 440773 - [1.8][null]DefaultLocation.RETURN_TYPE erroneously affects method parameters in @NonNullByDefault
  *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -103,7 +104,7 @@
 					this.type.addSyntheticBridgeMethod(originalInherited, concreteMethod.original());
 		}
 		if (analyseNullAnnotations && !concreteMethod.isStatic() && !abstractMethod.isStatic()) {
-			checkNullSpecInheritance(concreteMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, abstractMethod, this.type.scope, null);
+			checkNullSpecInheritance(concreteMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, abstractMethod, abstractMethods, this.type.scope, null);
 		}
 	}
 }
@@ -400,12 +401,12 @@
 		boolean hasParameterNonNullDefault = currentMethod.hasNonNullDefaultFor(Binding.DefaultLocationParameter, useTypeAnnotations);
 		for (int i = length; --i >= 0;)
 			if (!currentMethod.isStatic() && !methods[i].isStatic())
-				checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, methods[i], this.type.scope, null);
+				checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, methods[i], methods, this.type.scope, null);
 	}
 }
 
 void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod, 
-		boolean hasReturnNonNullDefault, boolean hasParameterNonNullDefault, boolean complain, MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos)
+		boolean hasReturnNonNullDefault, boolean hasParameterNonNullDefault, boolean complain, MethodBinding inheritedMethod, MethodBinding[] allInherited, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos)
 {
 	complain &= !currentMethod.isConstructor();
 	if (!hasReturnNonNullDefault && !hasParameterNonNullDefault && !complain && !this.environment.globalOptions.inheritNullAnnotations) {
@@ -419,7 +420,7 @@
 	{
 		this.buddyImplicitNullAnnotationsVerifier.checkImplicitNullAnnotations(currentMethod, srcMethod, complain, scope);
 	}
-	super.checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, complain, inheritedMethod, scope, inheritedNonNullnessInfos);
+	super.checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, complain, inheritedMethod, allInherited, scope, inheritedNonNullnessInfos);
 }
 
 void reportRawReferences() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
index 11c7909..4168962 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -21,6 +21,7 @@
  *								Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
  *								Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations
  *								Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -239,7 +240,7 @@
 					}
 					if (invocationTypeInferred) {
 						if (compilerOptions.isAnnotationBasedNullAnalysisEnabled)
-							NullAnnotationMatching.checkForContraditions(methodSubstitute, invocationSite, scope);
+							NullAnnotationMatching.checkForContradictions(methodSubstitute, invocationSite, scope);
 						MethodBinding problemMethod = methodSubstitute.boundCheck18(scope, arguments);
 						if (problemMethod != null) {
 							return problemMethod;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index b158d42..1c82ac8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -686,7 +686,7 @@
 		    	// substitute methods, so as to get updated declaring class at least
 	            parameterizedMethods[i] = createParameterizedMethod(originalMethods[i]);
 	            if (useNullTypeAnnotations)
-	            	parameterizedMethods[i] = NullAnnotationMatching.checkForContraditions(parameterizedMethods[i], null, null);
+	            	parameterizedMethods[i] = NullAnnotationMatching.checkForContradictions(parameterizedMethods[i], null, null);
 		    }
 		    if (this.methods == null) {
 				MethodBinding[] temp = new MethodBinding[length];
@@ -967,7 +967,7 @@
 		    	// substitute all methods, so as to get updated declaring class at least
 	            parameterizedMethods[i] = createParameterizedMethod(originalMethods[i]);
 	            if (useNullTypeAnnotations)
-	            	parameterizedMethods[i] = NullAnnotationMatching.checkForContraditions(parameterizedMethods[i], null, null);
+	            	parameterizedMethods[i] = NullAnnotationMatching.checkForContradictions(parameterizedMethods[i], null, null);
 		    }
 
 		    this.methods = parameterizedMethods;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
index 36ae9ab..61cb9f9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -33,6 +33,7 @@
  *								Bug 431581 - Eclipse compiles what it should not
  *								Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
  *								Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *      Jesper S Moller - Contributions for
  *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
  *								bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
@@ -46,6 +47,7 @@
 import org.eclipse.jdt.core.compiler.InvalidInputException;
 import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
@@ -1984,11 +1986,14 @@
 	final LookupEnvironment environment = scope.environment();
 	boolean genericMethodSeen = false;
 	int length = methods.length;
+	boolean analyseNullAnnotations = environment.globalOptions.isAnnotationBasedNullAnalysisEnabled;
 	
 	next:for (int i = length - 1; i >= 0; --i) {
 		MethodBinding method = methods[i], otherMethod = null;
 		if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
 			genericMethodSeen = true;
+		TypeBinding returnType = method.returnType;
+		TypeBinding[] parameters = method.parameters;
 		for (int j = 0; j < length; j++) {
 			if (i == j) continue;
 			otherMethod = methods[j];
@@ -2001,7 +2006,11 @@
 					continue next;
 			}
 			if (!MethodVerifier.isSubstituteParameterSubsignature(method, otherMethod, environment) || !MethodVerifier.areReturnTypesCompatible(method, otherMethod, environment)) 
-				continue next; 
+				continue next;
+			if (analyseNullAnnotations) {
+				returnType = NullAnnotationMatching.strongerType(returnType, otherMethod.returnType, environment);
+				parameters = NullAnnotationMatching.weakerTypes(parameters, otherMethod.parameters, environment);
+			}
 		}
 		// If we reach here, we found a method that is override equivalent with every other method and is also return type substitutable. Compute kosher exceptions now ...
 		ReferenceBinding [] exceptions = new ReferenceBinding[0];
@@ -2067,8 +2076,8 @@
 		}
 		this.singleAbstractMethod[index] = new MethodBinding(theAbstractMethod.modifiers | ClassFileConstants.AccSynthetic, 
 				theAbstractMethod.selector, 
-				theAbstractMethod.returnType, 
-				theAbstractMethod.parameters, 
+				returnType, 
+				parameters, 
 				exceptions, 
 				theAbstractMethod.declaringClass);
 	    this.singleAbstractMethod[index].typeVariables = theAbstractMethod.typeVariables;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 99be8dc..634f423 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -54,6 +54,7 @@
  *								Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
  *								Bug 439298 - [null] "Missing code implementation in the compiler" when using @NonNullByDefault in package-info.java
  *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *      Jesper S Moller <jesper@selskabet.org> -  Contributions for
  *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
  *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
@@ -406,6 +407,10 @@
 		case IProblem.UninitializedNonNullFieldHintMissingDefault:
 		case IProblem.ReferenceExpressionParameterNullityMismatch:
 		case IProblem.ReferenceExpressionReturnNullRedef:
+		case IProblem.ContradictoryNullAnnotations:
+		case IProblem.ContradictoryNullAnnotationsOnBound:
+		case IProblem.ContradictoryNullAnnotationsInferred:
+		case IProblem.ContradictoryNullAnnotationsInferredFunctionType:
 			return CompilerOptions.NullSpecViolation;
 
 		case IProblem.ParameterLackingNonNullAnnotation:
@@ -4295,7 +4300,7 @@
 			return;
 		case ProblemReasons.ContradictoryNullAnnotations:
 			problemMethod = (ProblemMethodBinding) method;
-			contradictoryNullAnnotationsInferred(problemMethod.closestMatch, (ASTNode)messageSend);
+			contradictoryNullAnnotationsInferred(problemMethod.closestMatch, messageSend);
 			return;
 		case ProblemReasons.NoError : // 0
 		default :
@@ -9566,12 +9571,9 @@
 }
 
 public void contradictoryNullAnnotationsInferred(MethodBinding inferredMethod, ASTNode location) {
-	contradictoryNullAnnotationsInferred(inferredMethod, location.sourceStart, location.sourceEnd);
+	contradictoryNullAnnotationsInferred(inferredMethod, location.sourceStart, location.sourceEnd, false);
 }
-public void contradictoryNullAnnotationsInferred(MethodBinding inferredMethod, InvocationSite location) {
-	contradictoryNullAnnotationsInferred(inferredMethod, location.sourceStart(), location.sourceEnd());
-}
-public void contradictoryNullAnnotationsInferred(MethodBinding inferredMethod, int sourceStart, int sourceEnd) {
+public void contradictoryNullAnnotationsInferred(MethodBinding inferredMethod, int sourceStart, int sourceEnd, boolean isFunctionalExpression) {
 	// when this error is triggered we can safely assume that both annotations have been configured
 	char[][] nonNullAnnotationName = this.options.nonNullAnnotationName;
 	char[][] nullableAnnotationName = this.options.nullableAnnotationName;
@@ -9589,7 +9591,9 @@
 			new String(inferredMethod.selector),
 			typesAsString(inferredMethod, true, true)
 		};
-	this.handle(IProblem.ContradictoryNullAnnotationsInferred, arguments, shortArguments, sourceStart, sourceEnd);
+	this.handle(
+			isFunctionalExpression ? IProblem.ContradictoryNullAnnotationsInferredFunctionType : IProblem.ContradictoryNullAnnotationsInferred, 
+			arguments, shortArguments, sourceStart, sourceEnd);
 }
 
 public void contradictoryNullAnnotationsOnBounds(Annotation annotation, long previousTagBit) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index ee7ee45..2cacfa0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -828,6 +828,7 @@
 970 = Null type mismatch (type annotations): required ''{0}'' but this expression has type ''{1}'', where ''{0}'' is a free type variable
 971 = The explicit type bound 'Object' is not affected by the nullness default for DefaultLocation.TYPE_BOUND.
 972 = Illegal redefinition of parameter {0}, inherited method from {1} declares this parameter as ''{2}'' (mismatching null constraints)
+973 = Contradictory null annotations: function type was inferred as ''{2} ({4})'', but only one of ''@{0}'' and ''@{1}'' can be effective at any location
 
 # Java 8
 1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided