Update to a8944173670c6319cce2438add6b3e87f478a46c from jdt.core
- includes fixing some patch-mistakes
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 4fde541..78a3e35 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
@@ -23,6 +23,7 @@
  *								bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
  *								bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
  *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -371,6 +372,7 @@
 		expectedProblemAttributes.put("ArgumentTypeNotFound", DEPRECATED);
 		expectedProblemAttributes.put("ArgumentTypeNotVisible", DEPRECATED);
 		expectedProblemAttributes.put("ArrayConstantsOnlyInArrayInitializers", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
+		expectedProblemAttributes.put("ArrayReferencePotentialNullReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("ArrayReferenceRequired", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
 		expectedProblemAttributes.put("AssignmentHasNoEffect", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("AssignmentToMultiCatchParameter", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
@@ -422,6 +424,7 @@
 		expectedProblemAttributes.put("DeadCode", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("DefaultMethodNotBelow18", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
 		expectedProblemAttributes.put("DefaultMethodOverridesObjectMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
+		expectedProblemAttributes.put("DereferencingNullableExpression", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("DiamondNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
 		expectedProblemAttributes.put("DirectInvocationOfAbstractMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
 		expectedProblemAttributes.put("DisallowedTargetForAnnotation", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
@@ -780,6 +783,8 @@
 		expectedProblemAttributes.put("NullLocalVariableComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("NullLocalVariableInstanceofYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("NullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("NullityMismatchingTypeAnnotation", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("NullityMismatchingTypeAnnotationUnchecked", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("NullSourceString", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
 		expectedProblemAttributes.put("NumericValueOutOfRange", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
 		expectedProblemAttributes.put("ObjectCannotBeGeneric", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
@@ -1182,6 +1187,7 @@
 		expectedProblemAttributes.put("ArgumentTypeNotFound", SKIP);
 		expectedProblemAttributes.put("ArgumentTypeNotVisible", SKIP);
 		expectedProblemAttributes.put("ArrayConstantsOnlyInArrayInitializers", SKIP);
+		expectedProblemAttributes.put("ArrayReferencePotentialNullReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
 		expectedProblemAttributes.put("ArrayReferenceRequired", SKIP);
 		expectedProblemAttributes.put("AssignmentHasNoEffect", new ProblemAttributes(JavaCore.COMPILER_PB_NO_EFFECT_ASSIGNMENT));
 		expectedProblemAttributes.put("AssignmentToMultiCatchParameter", SKIP);
@@ -1233,6 +1239,7 @@
 		expectedProblemAttributes.put("DeadCode", new ProblemAttributes(JavaCore.COMPILER_PB_DEAD_CODE));
 		expectedProblemAttributes.put("DefaultMethodNotBelow18", SKIP);
 		expectedProblemAttributes.put("DefaultMethodOverridesObjectMethod", SKIP);
+		expectedProblemAttributes.put("DereferencingNullableExpression", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
 		expectedProblemAttributes.put("DiamondNotBelow17", SKIP);
 		expectedProblemAttributes.put("DirectInvocationOfAbstractMethod", SKIP);
 		expectedProblemAttributes.put("DisallowedTargetForAnnotation", SKIP);
@@ -1588,6 +1595,8 @@
 		expectedProblemAttributes.put("NotVisibleField", SKIP);
 		expectedProblemAttributes.put("NotVisibleMethod", SKIP);
 		expectedProblemAttributes.put("NotVisibleType", SKIP);
+		expectedProblemAttributes.put("NullityMismatchingTypeAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+		expectedProblemAttributes.put("NullityMismatchingTypeAnnotationUnchecked", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_UNCHECKED_CONVERSION));
 		expectedProblemAttributes.put("NullLocalVariableComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
 		expectedProblemAttributes.put("NullLocalVariableInstanceofYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
 		expectedProblemAttributes.put("NullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_REFERENCE));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java
index 39cb314..a7c87e0 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GrammarCoverageTests308.java
@@ -1482,24 +1482,24 @@
 				"----------\n" + 
 				"4. ERROR in X.java (at line 4)\n" + 
 				"	Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" + 
+				"	            ^^^^^^^\n" + 
+				"Syntax error, type annotations are illegal here\n" + 
+				"----------\n" + 
+				"5. ERROR in X.java (at line 4)\n" + 
+				"	Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" + 
 				"	             ^^^^^^\n" + 
 				"Marker cannot be resolved to a type\n" + 
 				"----------\n" + 
-				"5. ERROR in X.java (at line 4)\n" + 
+				"6. ERROR in X.java (at line 4)\n" + 
 				"	Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" + 
 				"	                          ^^^^^^^\n" + 
 				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n" + 
-				"6. ERROR in X.java (at line 4)\n" + 
+				"7. ERROR in X.java (at line 4)\n" + 
 				"	Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" + 
 				"	                           ^^^^^^\n" + 
 				"Marker cannot be resolved to a type\n" + 
 				"----------\n" + 
-				"7. ERROR in X.java (at line 4)\n" + 
-				"	Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" + 
-				"	                                        ^^^^^^^\n" + 
-				"Syntax error, type annotations are illegal here\n" + 
-				"----------\n" + 
 				"8. ERROR in X.java (at line 4)\n" + 
 				"	Object q = (@Marker java. @Marker util. @Marker List<@Marker String> []) null;\n" + 
 				"	                                         ^^^^^^\n" + 
@@ -1513,7 +1513,7 @@
 				"10. ERROR in X.java (at line 5)\n" + 
 				"	Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" + 
 				"	            ^^^^^^^\n" + 
-				"Type annotations are not allowed on type names used to access static members\n" + 
+				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n" + 
 				"11. ERROR in X.java (at line 5)\n" + 
 				"	Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" + 
@@ -1535,10 +1535,10 @@
 				"	                           ^^^^^^\n" + 
 				"Marker cannot be resolved to a type\n" + 
 				"----------\n" + 
-				"15. ERROR in X.java (at line 5)\n" + 
-				"	Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" + 
-				"	                                       ^^^^^^^\n" + 
-				"Syntax error, type annotations are illegal here\n" + 
+				"15. ERROR in X.java (at line 5)\n" +
+				"	Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" +
+				"	                                       ^^^^^^^\n" +
+				"Type annotations are not allowed on type names used to access static members\n" +
 				"----------\n" + 
 				"16. ERROR in X.java (at line 5)\n" + 
 				"	Object r = (@Marker java. @Marker util.@Marker Map<@Marker String, @Marker String>.@Marker Entry @Marker []) null;\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
index 7452605..283bac7 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeTypeAnnotationTest.java
@@ -2350,7 +2350,7 @@
 					"public class X {    \n " +
 					"	Object o1 = (@Marker java.lang.Integer) null;   // 1. Right.\n" +
 					"	Object o2 = (java. @Marker lang.Integer) null;  // 2. Wrong.\n" +
-					"	Object o3 = (java.lang. @Marker Integer) null;  // 3. Wrong.\n" +
+					"	Object o3 = (java.lang. @Marker Integer) null;  // 3. Legal.\n" +
 					"	public void foo(java. @Marker lang.Integer arg) {}\n" +
 					"	public void bar(java.lang. @Marker Integer arg) {}\n" +
 					"	public void foobar(@Marker java.lang.Integer arg) {}\n" +
@@ -2374,25 +2374,20 @@
 					"}\n"
 				},
 				"----------\n" + 
-				"1. ERROR in X.java (at line 5)\n" + 
-				"	Object o2 = (java. @Marker lang.Integer) null;  // 2. Wrong.\n" + 
-				"	                   ^^^^^^^\n" + 
+				"1. ERROR in X.java (at line 4)\n" + 
+				"	Object o1 = (@Marker java.lang.Integer) null;   // 1. Right.\n" + 
+				"	             ^^^^^^^\n" + 
 				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n" + 
-				"2. ERROR in X.java (at line 6)\n" + 
-				"	Object o3 = (java.lang. @Marker Integer) null;  // 3. Wrong.\n" + 
-				"	                        ^^^^^^^\n" + 
+				"2. ERROR in X.java (at line 5)\n" + 
+				"	Object o2 = (java. @Marker lang.Integer) null;  // 2. Wrong.\n" + 
+				"	                   ^^^^^^^\n" + 
 				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n" + 
 				"3. ERROR in X.java (at line 7)\n" + 
 				"	public void foo(java. @Marker lang.Integer arg) {}\n" + 
 				"	                      ^^^^^^^\n" + 
 				"Syntax error, type annotations are illegal here\n" + 
-				"----------\n" + 
-				"4. ERROR in X.java (at line 8)\n" + 
-				"	public void bar(java.lang. @Marker Integer arg) {}\n" + 
-				"	                           ^^^^^^^\n" + 
-				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n");
 	}
 	public void test0390882a() {
@@ -2402,8 +2397,8 @@
 					"import java.lang.annotation.Target;\n" +
 					"import static java.lang.annotation.ElementType.*;\n" +
 					"public class X {    \n " +
-					"	Object o1 = (java. @Marker @Annot lang.Integer) null;  // 2. Wrong.\n" +
-					"	Object o2 = (java.lang. @Marker @Annot Integer) null;  // 3. Wrong.\n" +
+					"	Object o1 = (java. @Marker @Annot lang.Integer) null;  // 1. Wrong.\n" +
+					"	Object o2 = (java.lang. @Marker @Annot Integer) null;  // 2. Legal\n" +
 					"	Object o3 = (java.@lang lang) null;  // 3. Wrong.\n" +
 					"}\n" +
 					"@Target(TYPE_USE)\n" +
@@ -2428,16 +2423,11 @@
 				},
 				"----------\n" + 
 				"1. ERROR in X.java (at line 4)\n" + 
-				"	Object o1 = (java. @Marker @Annot lang.Integer) null;  // 2. Wrong.\n" + 
+				"	Object o1 = (java. @Marker @Annot lang.Integer) null;  // 1. Wrong.\n" + 
 				"	                   ^^^^^^^^^^^^^^\n" + 
 				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n" + 
-				"2. ERROR in X.java (at line 5)\n" + 
-				"	Object o2 = (java.lang. @Marker @Annot Integer) null;  // 3. Wrong.\n" + 
-				"	                        ^^^^^^^^^^^^^^\n" + 
-				"Syntax error, type annotations are illegal here\n" + 
-				"----------\n" + 
-				"3. ERROR in X.java (at line 6)\n" + 
+				"2. ERROR in X.java (at line 6)\n" + 
 				"	Object o3 = (java.@lang lang) null;  // 3. Wrong.\n" + 
 				"	             ^^^^^^^^^^^^^^^\n" + 
 				"java.lang cannot be resolved to a type\n" + 
@@ -2450,10 +2440,11 @@
 					"import java.lang.annotation.Target;\n" +
 					"import static java.lang.annotation.ElementType.*;\n" +
 					"public class X {    \n " +
-					"	Object o1 = (java.util.@Marker @Annot List<String>) null; 	// 1. Wrong.\n" +
-					"	Object o2 = (java.lang.@Marker @Annot Integer[]) null;		// 2. Wrong.\n" +
-					"	Object o3 = (java.util.@Marker @Annot List<String>[]) null; // 3. Wrong.\n" +
-					"	Object o4 = (java.lang.Integer @Marker []) null;	// 4. Right.\n" +
+					"	Object o1 = (@Marker @Annot java.util.List<String>) null; 	// 1. Wrong.\n" +
+					"	Object o2 = (java. @Marker @Annot lang.Integer[]) null;		// 2. Wrong.\n" +
+					"	Object o3 = (@Marker @Annot java.util.List<String>[]) null; // 3. Wrong.\n" +
+					"	Object o4 = (java.util.List<String> @Marker @Annot []) null; // 4. Right.\n" +
+					"	Object o5 = (java.lang.Integer @Marker @Annot []) null;	// 5. Right.\n" +
 					"}\n" +
 					"@Target(TYPE_USE)\n" +
 					"@interface Marker {}\n" +
@@ -2477,18 +2468,18 @@
 				},
 				"----------\n" + 
 				"1. ERROR in X.java (at line 4)\n" + 
-				"	Object o1 = (java.util.@Marker @Annot List<String>) null; 	// 1. Wrong.\n" + 
-				"	                       ^^^^^^^^^^^^^^\n" + 
+				"	Object o1 = (@Marker @Annot java.util.List<String>) null; 	// 1. Wrong.\n" + 
+				"	             ^^^^^^^^^^^^^^\n" + 
 				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n" + 
 				"2. ERROR in X.java (at line 5)\n" + 
-				"	Object o2 = (java.lang.@Marker @Annot Integer[]) null;		// 2. Wrong.\n" + 
-				"	                       ^^^^^^^^^^^^^^\n" + 
+				"	Object o2 = (java. @Marker @Annot lang.Integer[]) null;		// 2. Wrong.\n" + 
+				"	                   ^^^^^^^^^^^^^^\n" + 
 				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n" + 
 				"3. ERROR in X.java (at line 6)\n" + 
-				"	Object o3 = (java.util.@Marker @Annot List<String>[]) null; // 3. Wrong.\n" + 
-				"	                       ^^^^^^^^^^^^^^\n" + 
+				"	Object o3 = (@Marker @Annot java.util.List<String>[]) null; // 3. Wrong.\n" + 
+				"	             ^^^^^^^^^^^^^^\n" + 
 				"Syntax error, type annotations are illegal here\n" + 
 				"----------\n");
 	}
@@ -2547,7 +2538,7 @@
 					"4. ERROR in A.java (at line 7)\n" + 
 					"	Object o2 = (@Marker p.@Marker A.@Marker B.@Marker C) null;\n" + 
 					"	             ^^^^^^^\n" + 
-					"Type annotations are not allowed on type names used to access static members\n" + 
+					"Syntax error, type annotations are illegal here\n" + 
 					"----------\n" + 
 					"5. WARNING in A.java (at line 7)\n" + 
 					"	Object o2 = (@Marker p.@Marker A.@Marker B.@Marker C) null;\n" + 
@@ -2557,7 +2548,7 @@
 					"6. ERROR in A.java (at line 7)\n" + 
 					"	Object o2 = (@Marker p.@Marker A.@Marker B.@Marker C) null;\n" + 
 					"	                       ^^^^^^^\n" + 
-					"Syntax error, type annotations are illegal here\n" + 
+					"Type annotations are not allowed on type names used to access static members\n" + 
 					"----------\n" + 
 					"7. ERROR in A.java (at line 7)\n" + 
 					"	Object o2 = (@Marker p.@Marker A.@Marker B.@Marker C) null;\n" + 
@@ -2606,12 +2597,12 @@
 					"1. ERROR in A.java (at line 6)\n" + 
 					"	Object o1 = (@Marker p.@Marker A.@Marker B.@Marker C[]) null;\n" + 
 					"	             ^^^^^^^\n" + 
-					"Type annotations are not allowed on type names used to access static members\n" + 
+					"Syntax error, type annotations are illegal here\n" + 
 					"----------\n" + 
 					"2. ERROR in A.java (at line 6)\n" + 
 					"	Object o1 = (@Marker p.@Marker A.@Marker B.@Marker C[]) null;\n" + 
 					"	                       ^^^^^^^\n" + 
-					"Syntax error, type annotations are illegal here\n" + 
+					"Type annotations are not allowed on type names used to access static members\n" + 
 					"----------\n" + 
 					"3. ERROR in A.java (at line 6)\n" + 
 					"	Object o1 = (@Marker p.@Marker A.@Marker B.@Marker C[]) null;\n" + 
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 4d40987..030d647 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
@@ -84,7 +84,7 @@
 				  "        System.out.print(l.get(0).toString()); // problem: retrieved element can be null\n" +
 				  "        l.add(null);\n" +
 				  "    }\n" +
-				  "    void bar(java.util.List<@Nullable java.lang.Object> l) {\n" +
+				  "    void bar(java.util.List<@Nullable Object> l) {\n" +
 				  "        System.out.print(l.get(1).toString()); // problem: retrieved element can be null\n" +
 				  "        l.add(null);\n" +
 				  "    }\n" +
@@ -133,7 +133,7 @@
 				  "        System.out.print(l.get(0).toString()); // problem: retrieved element can be null\n" +
 				  "        l.add(null);\n" +
 				  "    }\n" +
-				  "    void bar(java.util.List<@Dummy @Nullable java.lang.Object> l) {\n" +
+				  "    void bar(java.util.List<@Dummy @Nullable Object> l) {\n" +
 				  "        System.out.print(l.get(1).toString()); // problem: retrieved element can be null\n" +
 				  "        l.add(null);\n" +
 				  "    }\n" +
@@ -175,7 +175,7 @@
 				  "        System.out.print(l.get(0).toString()); // problem: l may be null\n" +
 				  "        l.add(null); // problem: cannot insert 'null' into this list\n" +
 				  "    }\n" +
-				  "    void bar(@Nullable java.util.List<@NonNull java.lang.Object> l) {\n" +
+				  "    void bar(@Nullable List<@NonNull Object> l) {\n" +
 				  "        System.out.print(l.get(0).toString()); // problem: l may be null\n" +
 				  "        l.add(0, null); // problem: cannot insert 'null' into this list\n" +
 				  "    }\n" +
@@ -376,7 +376,7 @@
 			"1. ERROR in B.java (at line 4)\n" + 
 			"	ai.foo(null); // problems: ai can be null, arg must not be null\n" + 
 			"	^^\n" + 
-			"Potential null pointer access: The variable ai may be null at this location\n" + 
+			"Potential null pointer access: this expression has a '@Nullable' type\n" + 
 			"----------\n" + 
 			"2. ERROR in B.java (at line 4)\n" + 
 			"	ai.foo(null); // problems: ai can be null, arg must not be null\n" + 
@@ -409,4 +409,394 @@
 			"Missing2 cannot be resolved to a type\n" + 
 			"----------\n");
 	}
+
+	// bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+	// annotation on leaf type in 1-dim array
+	public void testArrayType_01() {
+		Map customOptions = getCompilerOptions();
+		customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable");
+		customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull");
+		runNegativeTest(
+			new String[] {
+				ELEMENT_TYPE_JAVA,
+				ELEMENT_TYPE_SOURCE,
+				CUSTOM_NULLABLE_NAME,
+				CUSTOM_NULLABLE_CONTENT_JSR308,
+				CUSTOM_NONNULL_NAME,
+				CUSTOM_NONNULL_CONTENT_JSR308,
+				"Wrapper.java",
+				  "public class Wrapper<T> {\n" +
+				  "	T content;" +
+				  "	public T content() { return content; }\n" +
+				  "}\n",
+				"A.java",
+				  "import org.foo.*;\n" +
+				  "public class A {\n" +
+// Using Wrapper is a workaround until bug 391331 is fixed (to force the interesting annotation to be consumed as a type annotation):
+				  "    void bar(Wrapper<@NonNull String[]> realStrings, Wrapper<@Nullable String[]> maybeStrings) {\n" +
+				  "        System.out.println(realStrings.content()[0].toUpperCase()); // no problem\n" +
+				  "        realStrings.content()[0] = null; // problem: cannot assign null as @NonNull element\n" +
+				  "        System.out.println(maybeStrings.content()[0].toUpperCase()); // problem: element can be null\n" +
+				  "        maybeStrings.content()[0] = null; // no problem\n" +
+				  "    }\n" +
+				  "}\n"},
+		    "----------\n" + 
+			"1. ERROR in A.java (at line 5)\n" + 
+			"	realStrings.content()[0] = null; // problem: cannot assign null as @NonNull element\n" + 
+			"	^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+			"Null type mismatch: required \'@NonNull String\' but the provided value is null\n" + 
+			"----------\n" + 
+			"2. ERROR in A.java (at line 6)\n" + 
+			"	System.out.println(maybeStrings.content()[0].toUpperCase()); // problem: element can be null\n" + 
+			"	                   ^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+			"Potential null pointer access: array element may be null\n" + 
+			"----------\n",
+			null,
+			true, /* shouldFlush*/
+			customOptions);
+	}
+
+	// bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+	// annotation on leaf type in 2-dim array
+	public void testArrayType_02() {
+		Map customOptions = getCompilerOptions();
+		customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable");
+		customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull");
+		runNegativeTest(
+			new String[] {
+				ELEMENT_TYPE_JAVA,
+				ELEMENT_TYPE_SOURCE,
+				CUSTOM_NULLABLE_NAME,
+				CUSTOM_NULLABLE_CONTENT_JSR308,
+				CUSTOM_NONNULL_NAME,
+				CUSTOM_NONNULL_CONTENT_JSR308,
+				"Wrapper.java",
+				  "public class Wrapper<T> {\n" +
+				  "	T content;" +
+				  "	public T content() { return content; }\n" +
+				  "}\n",
+				"A.java",
+				  "import org.foo.*;\n" +
+				  "public class A {\n" +
+// Using Wrapper is a workaround until bug 391331 is fixed (to force the interesting annotation to be consumed as a type annotation):
+				  "    void bar(Wrapper<@NonNull String[][]> realStrings, Wrapper<@Nullable String[][]> maybeStrings) {\n" +
+				  "        System.out.println(realStrings.content()[0][0].toUpperCase()); // no problem\n" +
+				  "        realStrings.content()[0][0] = null; // problem: cannot assign null as @NonNull element\n" +
+				  "        System.out.println(maybeStrings.content()[0][0].toUpperCase()); // problem: element can be null\n" +
+				  "        maybeStrings.content()[0][0] = null; // no problem\n" +
+				  "    }\n" +
+				  "}\n"},
+		    "----------\n" + 
+			"1. ERROR in A.java (at line 5)\n" + 
+			"	realStrings.content()[0][0] = null; // problem: cannot assign null as @NonNull element\n" + 
+			"	^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+			"Null type mismatch: required \'@NonNull String\' but the provided value is null\n" + 
+			"----------\n" + 
+			"2. ERROR in A.java (at line 6)\n" + 
+			"	System.out.println(maybeStrings.content()[0][0].toUpperCase()); // problem: element can be null\n" + 
+			"	                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+			"Potential null pointer access: array element may be null\n" + 
+			"----------\n",
+			null,
+			true, /* shouldFlush*/
+			customOptions);
+	}
+
+	// bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+	// annotation on array type (1-dim array)
+	public void testArrayType_03() {
+		Map customOptions = getCompilerOptions();
+		customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable");
+		customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull");
+		runNegativeTest(
+			new String[] {
+				ELEMENT_TYPE_JAVA,
+				ELEMENT_TYPE_SOURCE,
+				CUSTOM_NULLABLE_NAME,
+				CUSTOM_NULLABLE_CONTENT_JSR308,
+				CUSTOM_NONNULL_NAME,
+				CUSTOM_NONNULL_CONTENT_JSR308,
+				"A.java",
+				  "import org.foo.*;\n" +
+				  "public class A {\n" +
+				  "    void array(String @NonNull[] realStringArray, String @Nullable[] maybeStringArray) {\n" +
+				  "        @NonNull Object array;\n" +
+				  "        array = realStringArray;  // no problem\n" +
+				  "        realStringArray = null; 	 // problem: cannot assign null as @NonNull array\n" +
+				  "        array = maybeStringArray; // problem: array can be null\n" +
+				  "        maybeStringArray = null;  // no problem\n" +
+				  "    }\n" +
+				  "    void leaf(String @NonNull[] realStringArray, String @Nullable[] maybeStringArray) {\n" +
+				  "        @NonNull String string;\n" +
+				  "        string = realStringArray[0];  // problem: unchecked conversion\n" +
+				  "        realStringArray[0] = null; 	 // no problem\n" +
+				  "        string = maybeStringArray[0]; // problems: indexing nullable array & unchecked conversion\n" +
+				  "        maybeStringArray[0] = null; 	 // problem: indexing nullable array\n" +
+				  "    }\n" +
+				  "}\n"},
+		    "----------\n" + 
+    		"1. ERROR in A.java (at line 7)\n" + 
+    		"	array = maybeStringArray; // problem: array can be null\n" + 
+    		"	        ^^^^^^^^^^^^^^^^\n" + 
+    		"Null type mismatch: required \'@NonNull Object\' but the provided value is inferred as @Nullable\n" + 
+    		"----------\n" + 
+    		"2. WARNING in A.java (at line 12)\n" + 
+    		"	string = realStringArray[0];  // problem: unchecked conversion\n" + 
+    		"	         ^^^^^^^^^^^^^^^^^^\n" + 
+    		"Null type safety: The expression of type String needs unchecked conversion to conform to \'@NonNull String\'\n" + 
+    		"----------\n" + 
+    		"3. ERROR in A.java (at line 14)\n" + 
+    		"	string = maybeStringArray[0]; // problems: indexing nullable array & unchecked conversion\n" + 
+    		"	         ^^^^^^^^^^^^^^^^\n" + 
+    		"Potential null pointer access: this expression has a '@Nullable' type\n" + 
+    		"----------\n" + 
+    		"4. WARNING in A.java (at line 14)\n" + 
+    		"	string = maybeStringArray[0]; // problems: indexing nullable array & unchecked conversion\n" + 
+    		"	         ^^^^^^^^^^^^^^^^^^^\n" + 
+    		"Null type safety: The expression of type String needs unchecked conversion to conform to \'@NonNull String\'\n" + 
+    		"----------\n" + 
+    		"5. ERROR in A.java (at line 15)\n" + 
+    		"	maybeStringArray[0] = null; 	 // problem: indexing nullable array\n" + 
+    		"	^^^^^^^^^^^^^^^^\n" + 
+    		"Potential null pointer access: this expression has a '@Nullable' type\n" + 
+			"----------\n",
+			null,
+			true, /* shouldFlush*/
+			customOptions);
+	}
+
+	// bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+	// annotation on intermediate type in 2-dim array
+	public void testArrayType_04() {
+		Map customOptions = getCompilerOptions();
+		customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable");
+		customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull");
+		runNegativeTest(
+			new String[] {
+				ELEMENT_TYPE_JAVA,
+				ELEMENT_TYPE_SOURCE,
+				CUSTOM_NULLABLE_NAME,
+				CUSTOM_NULLABLE_CONTENT_JSR308,
+				CUSTOM_NONNULL_NAME,
+				CUSTOM_NONNULL_CONTENT_JSR308,
+				"A.java",
+				  "import org.foo.*;\n" +
+				  "public class A {\n" +
+				  "    void outer(String [] @NonNull[] realArrays, String [] @Nullable[] maybeArrays) {\n" +
+				  "        @NonNull Object array;\n" +
+				  "        array = realArrays; 		// problem: unchecked conversion\n" +
+				  "        realArrays = null; 		// no problem, outer array is unspecified\n" +
+				  "        array = maybeArrays; 	// problem: unchecked conversion\n" +
+				  "        maybeArrays = null; 		// no problem\n" +
+				  "    }\n" +
+				  "    void inner(String [] @NonNull[] realArrays, String [] @Nullable[] maybeArrays) {\n" +
+				  "        @NonNull Object array;\n" +
+				  "        array = realArrays[0]; 	// no problem\n" +
+				  "        realArrays[0] = null; 	// problem: cannot assign null to @NonNull array\n" +
+				  "        array = maybeArrays[0]; 	// problem: element can be null\n" +
+				  "        maybeArrays[0] = null; 	// no problem\n" +
+				  "    }\n" +
+				  "    void leaf(String [] @NonNull[] realArrays, String [] @Nullable[] maybeArrays) {\n" +
+				  "        @NonNull Object array;\n" +
+				  "        array = realArrays[0][0]; // problem: unchecked conversion\n" +
+				  "        realArrays[0][0] = null;  // no problem, element type is unspecified\n" +
+				  "        array = maybeArrays[0][0]; // problems: indexing nullable array & unchecked conversion\n" +
+				  "        maybeArrays[0][0] = null; // problem: indexing nullable array\n" +
+				  "    }\n" +
+				  "}\n"},
+		    "----------\n" + 
+    		"1. WARNING in A.java (at line 5)\n" + 
+    		"	array = realArrays; 		// problem: unchecked conversion\n" + 
+    		"	        ^^^^^^^^^^\n" + 
+    		"Null type safety: The expression of type String[][] needs unchecked conversion to conform to \'@NonNull Object\'\n" + 
+		    "----------\n" + 
+			"2. WARNING in A.java (at line 7)\n" + 
+    		"	array = maybeArrays; 	// problem: unchecked conversion\n" + 
+    		"	        ^^^^^^^^^^^\n" + 
+    		"Null type safety: The expression of type String[][] needs unchecked conversion to conform to \'@NonNull Object\'\n" + 
+			"----------\n" + 
+			"3. ERROR in A.java (at line 13)\n" + 
+			"	realArrays[0] = null; 	// problem: cannot assign null to @NonNull array\n" + 
+			"	^^^^^^^^^^^^^\n" + 
+			"Null type mismatch: required \'String @NonNull[]\' but the provided value is null\n" + 
+			"----------\n" + 
+			"4. ERROR in A.java (at line 14)\n" +
+			"	array = maybeArrays[0]; 	// problem: element can be null\n" +
+			"	        ^^^^^^^^^^^^^^\n" + 
+			"Null type mismatch: required '@NonNull Object' but the provided value is inferred as @Nullable\n" + 
+			"----------\n" + 
+			"5. WARNING in A.java (at line 19)\n" +
+			"	array = realArrays[0][0]; // problem: unchecked conversion\n" +
+			"	        ^^^^^^^^^^^^^^^^\n" +
+    		"Null type safety: The expression of type String needs unchecked conversion to conform to \'@NonNull Object\'\n" + 
+			"----------\n" + 
+			"6. ERROR in A.java (at line 21)\n" +
+			"	array = maybeArrays[0][0]; // problems: indexing nullable array & unchecked conversion\n" +
+			"	        ^^^^^^^^^^^^^^\n" +
+    		"Potential null pointer access: array element may be null\n" + 
+			"----------\n" + 
+			"7. WARNING in A.java (at line 21)\n" +
+			"	array = maybeArrays[0][0]; // problems: indexing nullable array & unchecked conversion\n" +
+			"	        ^^^^^^^^^^^^^^^^^\n" +
+			"Null type safety: The expression of type String needs unchecked conversion to conform to \'@NonNull Object\'\n" +
+			"----------\n" + 
+			"8. ERROR in A.java (at line 22)\n" + 
+			"	maybeArrays[0][0] = null; // problem: indexing nullable array\n" + 
+			"	^^^^^^^^^^^^^^\n" + 
+			"Potential null pointer access: array element may be null\n" + 
+			"----------\n",
+			null,
+			true, /* shouldFlush*/
+			customOptions);
+	}
+
+	// bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+	// mismatches against outer array type, test display of type annotation in error messages
+	public void testArrayType_05() {
+		Map customOptions = getCompilerOptions();
+		customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable");
+		customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull");
+		runNegativeTest(
+			new String[] {
+				ELEMENT_TYPE_JAVA,
+				ELEMENT_TYPE_SOURCE,
+				CUSTOM_NULLABLE_NAME,
+				CUSTOM_NULLABLE_CONTENT_JSR308,
+				CUSTOM_NONNULL_NAME,
+				CUSTOM_NONNULL_CONTENT_JSR308,
+				"A.java",
+				  "import org.foo.*;\n" +
+				  "public class A {\n" +
+				  "    void outer(String @NonNull[] @NonNull[] realArrays, String @NonNull[] @Nullable[] maybeArrays, String @Nullable[][] unknownArrays) {\n" +
+				  "        realArrays[0] = maybeArrays[0];		// problem: inner array can be null\n" +
+				  "        realArrays[0] = unknownArrays[0];	// problems: inner array is unspecified, outer can be null\n" +
+				  "    }\n" +
+				  "    void oneDim(String @Nullable[] maybeStrings, String[] unknownStrings) {\n" +
+				  "        String @NonNull[] s = maybeStrings;\n" +
+				  "        s = unknownStrings;\n" +
+				  "        consume(maybeStrings);\n" +
+				  "        consume(unknownStrings);\n" +
+				  "    }\n" +
+				  "    void consume(String @NonNull[] s) {};\n" +
+				  "}\n"},
+			"----------\n" + 
+			"1. ERROR in A.java (at line 4)\n" + 
+			"	realArrays[0] = maybeArrays[0];		// problem: inner array can be null\n" + 
+			"	^^^^^^^^^^^^^\n" + 
+			"Null type mismatch: required \'String @NonNull[]\' but the provided value is inferred as @Nullable\n" + 
+			"----------\n" + 
+			"2. WARNING in A.java (at line 5)\n" + 
+			"	realArrays[0] = unknownArrays[0];	// problems: inner array is unspecified, outer can be null\n" + 
+			"	^^^^^^^^^^^^^\n" + 
+			"Null type safety: The expression of type String[] needs unchecked conversion to conform to \'String @NonNull[]\'\n" + 
+			"----------\n" + 
+			"3. ERROR in A.java (at line 5)\n" + 
+			"	realArrays[0] = unknownArrays[0];	// problems: inner array is unspecified, outer can be null\n" + 
+			"	                ^^^^^^^^^^^^^\n" + 
+			"Potential null pointer access: this expression has a \'@Nullable\' type\n" + 
+			"----------\n" + 
+			"4. ERROR in A.java (at line 8)\n" + 
+			"	String @NonNull[] s = maybeStrings;\n" + 
+			"	                      ^^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required \'String @NonNull[]\' but this expression has type \'String @Nullable[]\'\n" + 
+			"----------\n" + 
+			"5. WARNING in A.java (at line 9)\n" + 
+			"	s = unknownStrings;\n" + 
+			"	    ^^^^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): the expression of type \'String[]\' needs unchecked conversion to conform to \'String @NonNull[]\'\n" + 
+			"----------\n" + 
+			"6. ERROR in A.java (at line 10)\n" + 
+			"	consume(maybeStrings);\n" + 
+			"	        ^^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required \'String @NonNull[]\' but this expression has type \'String @Nullable[]\'\n" + 
+			"----------\n" + 
+			"7. WARNING in A.java (at line 11)\n" + 
+			"	consume(unknownStrings);\n" + 
+			"	        ^^^^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): the expression of type \'String[]\' needs unchecked conversion to conform to \'String @NonNull[]\'\n" + 
+			"----------\n",
+			null,
+			true, /* shouldFlush*/
+			customOptions);
+	}
+
+	// bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+	// more compiler messages
+	public void testArrayType_10() {
+		Map customOptions = getCompilerOptions();
+		customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable");
+		customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull");
+		runNegativeTest(
+			new String[] {
+				ELEMENT_TYPE_JAVA,
+				ELEMENT_TYPE_SOURCE,
+				CUSTOM_NULLABLE_NAME,
+				CUSTOM_NULLABLE_CONTENT_JSR308,
+				CUSTOM_NONNULL_NAME,
+				CUSTOM_NONNULL_CONTENT_JSR308,
+				"A.java",
+				  "import org.foo.*;\n" +
+				  "public class A {\n" +
+				  "    void outer(String @NonNull[] @NonNull[] realArrays, String @NonNull[] @Nullable[] maybeArrays, String @Nullable[][] unknownArrays, String @NonNull[][] mixedArrays) {\n" +
+				  "        realArrays = maybeArrays;			// problem on inner dimension!\n" +
+				  "        realArrays = unknownArrays; 			// problems on both dimensions\n" +
+				  "        maybeArrays = realArrays;			// problem on inner dimension\n" +
+				  "        unknownArrays = maybeArrays;			// problsm on outer dimension\n" +
+				  "        realArrays = mixedArrays;			// problem on inner\n" +
+				  "        maybeArrays = mixedArrays;			// problem on inner\n" +
+				  "        consume(maybeArrays, mixedArrays, maybeArrays);\n" +
+				  "    }\n" +
+				  "    void consume(String @NonNull[] @NonNull[] realStrings, String @NonNull[] @Nullable[] maybeArrays, String @Nullable[][] unknownArrays) {\n" +
+				  "    }\n" +
+				  "}\n"},
+			"----------\n" + 
+			"1. ERROR in A.java (at line 4)\n" + 
+			"	realArrays = maybeArrays;			// problem on inner dimension!\n" + 
+			"	             ^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required \'String @NonNull[] @NonNull[]\' but this expression has type \'String @NonNull[] @Nullable[]\'\n" + 
+			"----------\n" + 
+			"2. ERROR in A.java (at line 5)\n" + 
+			"	realArrays = unknownArrays; 			// problems on both dimensions\n" + 
+			"	             ^^^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required \'String @NonNull[] @NonNull[]\' but this expression has type \'String @Nullable[] []\'\n" + 
+			"----------\n" + 
+			"3. ERROR in A.java (at line 6)\n" + 
+			"	maybeArrays = realArrays;			// problem on inner dimension\n" + 
+			"	              ^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required \'String @NonNull[] @Nullable[]\' but this expression has type \'String @NonNull[] @NonNull[]\'\n" + 
+			"----------\n" + 
+			"4. ERROR in A.java (at line 7)\n" + 
+			"	unknownArrays = maybeArrays;			// problsm on outer dimension\n" + 
+			"	                ^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required \'String @Nullable[] []\' but this expression has type \'String @NonNull[] @Nullable[]\'\n" + 
+			"----------\n" + 
+			"5. WARNING in A.java (at line 8)\n" + 
+			"	realArrays = mixedArrays;			// problem on inner\n" + 
+			"	             ^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): the expression of type \'String @NonNull[] []\' needs unchecked conversion to conform to \'String @NonNull[] @NonNull[]\'\n" + 
+			"----------\n" + 
+			"6. WARNING in A.java (at line 9)\n" + 
+			"	maybeArrays = mixedArrays;			// problem on inner\n" + 
+			"	              ^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): the expression of type \'String @NonNull[] []\' needs unchecked conversion to conform to \'String @NonNull[] @Nullable[]\'\n" + 
+			"----------\n" + 
+			"7. ERROR in A.java (at line 10)\n" + 
+			"	consume(maybeArrays, mixedArrays, maybeArrays);\n" + 
+			"	        ^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required \'String @NonNull[] @NonNull[]\' but this expression has type \'String @NonNull[] @Nullable[]\'\n" + 
+			"----------\n" + 
+			"8. WARNING in A.java (at line 10)\n" + 
+			"	consume(maybeArrays, mixedArrays, maybeArrays);\n" + 
+			"	                     ^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): the expression of type \'String @NonNull[] []\' needs unchecked conversion to conform to \'String @NonNull[] @Nullable[]\'\n" + 
+			"----------\n" + 
+			"9. ERROR in A.java (at line 10)\n" + 
+			"	consume(maybeArrays, mixedArrays, maybeArrays);\n" + 
+			"	                                  ^^^^^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required \'String @Nullable[] []\' but this expression has type \'String @NonNull[] @Nullable[]\'\n" + 
+			"----------\n",
+			null,
+			true, /* shouldFlush*/
+			customOptions);
+	}
 }
diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin1.8.jar b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin1.8.jar
new file mode 100644
index 0000000..3ac44e9
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin1.8.jar
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin1.8src.zip b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin1.8src.zip
new file mode 100644
index 0000000..50607ff
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin1.8src.zip
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8.jar b/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8.jar
new file mode 100644
index 0000000..2b78416
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8.jar
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8src.zip b/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8src.zip
new file mode 100644
index 0000000..0757f3a
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin1.8src.zip
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava8Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava8Tests.java
index e2798de..c77fcd0 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava8Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava8Tests.java
@@ -11,6 +11,8 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.core.tests;
 
@@ -31,6 +33,7 @@
 import org.eclipse.jdt.core.tests.compiler.regression.GrammarCoverageTests308;
 import org.eclipse.jdt.core.tests.compiler.regression.NegativeLambdaExpressionsTest;
 import org.eclipse.jdt.core.tests.compiler.regression.NegativeTypeAnnotationTest;
+import org.eclipse.jdt.core.tests.compiler.regression.NullTypeAnnotationTest;
 import org.eclipse.jdt.core.tests.dom.ASTConverter15JLS8Test;
 import org.eclipse.jdt.core.tests.dom.ASTConverterAST8Test;
 import org.eclipse.jdt.core.tests.dom.ASTConverterBugsTestJLS8;
@@ -52,7 +55,8 @@
 			ReferenceExpressionSyntaxTest.class,
 			DefaultMethodsTest.class,
 			ComplianceDiagnoseTest.class,
-			GrammarCoverageTests308.class
+			GrammarCoverageTests308.class,
+			NullTypeAnnotationTest.class
 		};
 	}
 	
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
index fd3c570..8fea5b7 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -995,11 +995,10 @@
 
 	/* no need to take action if not inside completed identifiers */
 	if ((index = indexOfAssistIdentifier(true)) < 0) {
-// orig: FIXME
+/* orig: 
 		return super.getTypeReference(dim);
-// :giro */
-// OT PREVIOUS:
-//		return super.getUnannotatedTypeReference(dim, liftingTypeAllowed);
+ :giro */
+		return super.getTypeReference(dim, liftingTypeAllowed);
 // SH}
 	}
 	int length = this.identifierLengthStack[this.identifierLengthPtr];
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 0cc18be..b0a1846 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
@@ -159,6 +159,10 @@
  *									InheritedDefaultMethodConflictsWithOtherInherited
  *									ConflictingNullAnnotations
  *									ConflictingInheritedNullAnnotations
+ *									ArrayReferencePotentialNullReference
+ *									DereferencingNullableExpression
+ *									NullityMismatchingTypeAnnotation
+ *									NullityMismatchingTypeAnnotationUnchecked
  *******************************************************************************/
 package org.eclipse.jdt.core.compiler;
 
@@ -1554,6 +1558,15 @@
 	/** @since 3.9 */
 	int ConflictingInheritedNullAnnotations = MethodRelated + 940;
 	
+	/** @since 3.9 */
+	int ArrayReferencePotentialNullReference = Internal + 951;
+	/** @since 3.9 */
+	int DereferencingNullableExpression = Internal + 952;
+	/** @since 3.9 */
+	int NullityMismatchingTypeAnnotation = Internal + 953;
+	/** @since 3.9 */
+	int NullityMismatchingTypeAnnotationUnchecked = Internal + 954;
+
 	// Java 8 work
 	/** @since 3.9 */
 	int IllegalModifiersForElidedType = Internal + 1001;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
index 55d4cac..24e87d4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
@@ -5,10 +5,15 @@
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for
  *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -19,6 +24,7 @@
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 
@@ -40,12 +46,19 @@
 	if (assignment.expression == null) {
 		return analyseCode(currentScope, flowContext, flowInfo);
 	}
-	return assignment
+	flowInfo = assignment
 		.expression
 		.analyseCode(
 			currentScope,
 			flowContext,
 			analyseCode(currentScope, flowContext, flowInfo).unconditionalInits());
+	if ((this.resolvedType.tagBits & TagBits.AnnotationNonNull) != 0) {
+		int nullStatus = assignment.expression.nullStatus(flowInfo);
+		if (nullStatus != FlowInfo.NON_NULL) {
+			currentScope.problemReporter().nullityMismatch(this, assignment.expression.resolvedType, this.resolvedType, nullStatus, currentScope.environment().getNonNullAnnotationName());
+		}
+	}
+	return flowInfo;
 }
 
 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
@@ -57,6 +70,14 @@
 	return flowInfo;
 }
 
+public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	if ((this.resolvedType.tagBits & TagBits.AnnotationNullable) != 0) {
+		scope.problemReporter().arrayReferencePotentialNullReference(this);
+	} else {
+		super.checkNPE(scope, flowContext, flowInfo);
+	}
+}
+
 public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
 	int pc = codeStream.position;
 	this.receiver.generateCode(currentScope, codeStream, true);
@@ -167,10 +188,6 @@
 	codeStream.arrayAtPut(this.resolvedType.id, false);
 }
 
-public int nullStatus(FlowInfo flowInfo) {
-	return FlowInfo.UNKNOWN;
-}
-
 public StringBuffer printExpression(int indent, StringBuffer output) {
 	this.receiver.printExpression(0, output).append('[');
 	return this.position.printExpression(0, output).append(']');
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 8d122c9..8a74c00 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -6,6 +6,10 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * $Id: Expression.java 23404 2010-02-03 14:10:22Z stephan $
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
@@ -13,6 +17,7 @@
  *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
  *								bug 292478 - Report potentially null across variable assignment
  *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -712,6 +717,16 @@
  * @param flowInfo the upstream flow info; caveat: may get modified
  */
 public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (this.resolvedType != null) {
+		if ((this.resolvedType.tagBits & TagBits.AnnotationNonNull) != 0) {
+			return; // no danger
+		} else if ((this.resolvedType.tagBits & TagBits.AnnotationNullable) != 0) {
+			scope.problemReporter().dereferencingNullableExpression(this, scope.environment());
+			return; // danger is definite.
+			// stopping analysis at this point requires that the above error is not suppressable
+			// unless suppressing all null warnings (otherwise we'd miss a stronger warning below).
+		}
+	}
 	LocalVariableBinding local = localVariableBinding();
 	if (local != null &&
 			(local.type.tagBits & TagBits.IsBaseType) == 0) {
@@ -1054,7 +1069,7 @@
 
 	if (/* (this.bits & IsNonNull) != 0 || */
 		this.constant != null && this.constant != Constant.NotAConstant)
-	return FlowInfo.NON_NULL; // constant expression cannot be null
+		return FlowInfo.NON_NULL; // constant expression cannot be null
 
 	LocalVariableBinding local = localVariableBinding();
 	if (local != null)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 8f31fc5..0fa52d3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -6,6 +6,10 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * $Id: MessageSend.java 23405 2010-02-03 17:02:18Z stephan $
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
@@ -22,6 +26,7 @@
  *								bug 379784 - [compiler] "Method can be static" is not getting reported
  *								bug 379834 - Wrong "method can be static" in presence of qualified super and different staticness of nested super class.
  *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -291,9 +296,10 @@
 }
 // SH}
 public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
-	super.checkNPE(scope, flowContext, flowInfo);
-	if ((nullStatus(flowInfo) & FlowInfo.POTENTIALLY_NULL) != 0)
+	if ((nullStatus(flowInfo) & FlowInfo.POTENTIALLY_NULL) != 0) // note that flowInfo is not used inside nullStatus(..)
 		scope.problemReporter().messageSendPotentialNullReference(this.binding, this);
+	else
+		super.checkNPE(scope, flowContext, flowInfo);
 }
 /**
  * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
index 799d2a2..6824d55 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
@@ -235,7 +235,7 @@
 						: scope.environment().convertToParameterizedType(qualifyingType);
 				}
 			} else {
-				 rejectAnnotationsOnStaticMemberQualififer(scope, currentType, packageBinding, i);
+				 rejectAnnotationsOnStaticMemberQualififer(scope, currentType, i);
 				if (typeIsConsistent && currentType.isStatic()
 						&& (qualifyingType.isParameterizedTypeWithActualArguments() || qualifyingType.isGenericType())) {
 					scope.problemReporter().staticMemberOfParameterizedType(this, scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifyingType), i);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
index 57c1c8c..f3f6680 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
@@ -150,7 +150,7 @@
 		if (packageBinding == null || this.annotations == null) return;
 
 		int i = packageBinding.compoundName.length;
-		for (int j = i; j > 0; j--) {
+		for (int j = 0; j < i; j++) {
 			Annotation[] qualifierAnnot = this.annotations[j];
 			if (qualifierAnnot != null && qualifierAnnot.length > 0) {
 				scope.problemReporter().misplacedTypeAnnotations(qualifierAnnot[0], qualifierAnnot[qualifierAnnot.length - 1]);
@@ -159,7 +159,7 @@
 		}
 	}
 
-	protected void rejectAnnotationsOnStaticMemberQualififer(Scope scope, ReferenceBinding currentType, PackageBinding packageBinding, int tokenIndex) {
+	protected void rejectAnnotationsOnStaticMemberQualififer(Scope scope, ReferenceBinding currentType, int tokenIndex) {
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385137
 		if (this.annotations != null && currentType.isMemberType() && currentType.isStatic()) {
 			Annotation[] qualifierAnnot = this.annotations[tokenIndex - 1];
@@ -167,14 +167,6 @@
 				scope.problemReporter().illegalTypeAnnotationsInStaticMemberAccess(qualifierAnnot[0],
 						qualifierAnnot[qualifierAnnot.length - 1]);
 			}
-			// For the case: @Marker p.X.StaticNestedType, where 'p' is a package and 'X' is a class
-			if (packageBinding != null && packageBinding.compoundName.length == (tokenIndex - 1)) {
-				qualifierAnnot = this.annotations[0];
-				if (qualifierAnnot != null) {
-					scope.problemReporter().illegalTypeAnnotationsInStaticMemberAccess(qualifierAnnot[0],
-							qualifierAnnot[qualifierAnnot.length - 1]);
-				}
-			}
 		}
 	}
 
@@ -244,7 +236,7 @@
 					return null;
 			ReferenceBinding currentType = (ReferenceBinding) this.resolvedType;
 			if (qualifiedType != null) {
-				rejectAnnotationsOnStaticMemberQualififer(scope, currentType, packageBinding, i);
+				rejectAnnotationsOnStaticMemberQualififer(scope, currentType, i);
 				ReferenceBinding enclosingType = currentType.enclosingType();
 				if (enclosingType != null && enclosingType.erasure() != qualifiedType.erasure()) {
 					qualifiedType = enclosingType; // inherited member type, leave it associated with its enclosing rather than subtype
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
index ee157de..d228167 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
@@ -4,13 +4,18 @@
  * 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
- * $Id: Reference.java 23404 2010-02-03 14:10:22Z stephan $
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *								bug 185682 - Increment/decrement operators mark local variables as read
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -27,6 +32,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;
@@ -115,6 +121,16 @@
 
 public abstract void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired);
 
+public int nullStatus(FlowInfo flowInfo) {
+	if (this.resolvedType != null) {
+		if ((this.resolvedType.tagBits & TagBits.AnnotationNonNull) != 0)
+			return FlowInfo.NON_NULL;
+		else if ((this.resolvedType.tagBits & TagBits.AnnotationNullable) != 0)
+			return FlowInfo.POTENTIALLY_NULL;
+	}
+	return FlowInfo.UNKNOWN;
+}
+
 /* report if a private field is only read from a 'special operator',
  * i.e., in a postIncrement expression or a compound assignment,
  * where the information is never flowing out off the field. */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 9f79f10..f2c21f5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -4,7 +4,10 @@
  * 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
- * $Id: Statement.java 23404 2010-02-03 14:10:22Z stephan $
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -18,12 +21,15 @@
  *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
  *								bug 370930 - NonNull annotation not considered for enhanced for loops
  *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
@@ -79,35 +85,57 @@
 protected void analyseArguments(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, MethodBinding methodBinding, Expression[] arguments)
 {
 	// compare actual null-status against parameter annotations of the called method:
-	if (arguments != null && methodBinding.parameterNonNullness != null) {
-
-		// check if varargs need special treatment:
+	if (arguments != null) {
+		CompilerOptions compilerOptions = currentScope.compilerOptions();
+		boolean considerTypeAnnotations = compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8
+				&& compilerOptions.isAnnotationBasedNullAnalysisEnabled;
+		boolean hasJDK15NullAnnotations = methodBinding.parameterNonNullness != null;
 		int numParamsToCheck = methodBinding.parameters.length;
-		boolean passThrough = false;
-		if (methodBinding.isVarargs()) {
-			int varArgPos = numParamsToCheck-1;
-			// this if-block essentially copied from generateArguments(..):
-			if (numParamsToCheck == arguments.length) {
-				TypeBinding varArgsType = methodBinding.parameters[varArgPos];
-				TypeBinding lastType = arguments[varArgPos].resolvedType;
-				if (lastType == TypeBinding.NULL
-						|| (varArgsType.dimensions() == lastType.dimensions()
-						&& lastType.isCompatibleWith(varArgsType)))
-					passThrough = true; // pass directly as-is
+		if (considerTypeAnnotations || hasJDK15NullAnnotations) {
+			// check if varargs need special treatment:
+			boolean passThrough = false;
+			if (methodBinding.isVarargs()) {
+				int varArgPos = numParamsToCheck-1;
+				// this if-block essentially copied from generateArguments(..):
+				if (numParamsToCheck == arguments.length) {
+					TypeBinding varArgsType = methodBinding.parameters[varArgPos];
+					TypeBinding lastType = arguments[varArgPos].resolvedType;
+					if (lastType == TypeBinding.NULL
+							|| (varArgsType.dimensions() == lastType.dimensions()
+							&& lastType.isCompatibleWith(varArgsType)))
+						passThrough = true; // pass directly as-is
+				}
+				if (!passThrough)
+					numParamsToCheck--; // with non-passthrough varargs last param is fed from individual args -> don't check
 			}
-			if (!passThrough)
-				numParamsToCheck--; // with non-passthrough varargs last param is fed from individual args -> don't check
 		}
-
-		for (int i = 0; i < numParamsToCheck; i++) {
-			if (methodBinding.parameterNonNullness[i] == Boolean.TRUE) {
+		if (considerTypeAnnotations) {
+			for (int i=0; i<numParamsToCheck; i++) {
 				TypeBinding expectedType = methodBinding.parameters[i];
 				Expression argument = arguments[i];
-				int nullStatus = argument.nullStatus(flowInfo); // slight loss of precision: should also use the null info from the receiver.
-				if (nullStatus != FlowInfo.NON_NULL) // if required non-null is not provided
-					flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, nullStatus);
+				// prefer check based on type annotations:
+				int severity = findNullTypeAnnotationMismatch(expectedType, argument.resolvedType);
+				if (severity > 0) {
+					// immediate reporting:
+					currentScope.problemReporter().nullityMismatchingTypeAnnotation(argument, argument.resolvedType, expectedType, severity==1, currentScope.environment());
+					// next check flow-based null status against null JDK15-style annotations:
+				} else if (hasJDK15NullAnnotations && methodBinding.parameterNonNullness[i] == Boolean.TRUE) {
+					int nullStatus = argument.nullStatus(flowInfo); // slight loss of precision: should also use the null info from the receiver.
+					if (nullStatus != FlowInfo.NON_NULL) // if required non-null is not provided
+						flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, nullStatus);
+				}
 			}
-		}
+		} else if (hasJDK15NullAnnotations) {
+			for (int i = 0; i < numParamsToCheck; i++) {
+				if (methodBinding.parameterNonNullness[i] == Boolean.TRUE) {
+					TypeBinding expectedType = methodBinding.parameters[i];
+					Expression argument = arguments[i];
+					int nullStatus = argument.nullStatus(flowInfo); // slight loss of precision: should also use the null info from the receiver.
+					if (nullStatus != FlowInfo.NON_NULL) // if required non-null is not provided
+						flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, nullStatus);
+				}
+			}
+		} 
 	}
 }
 
@@ -116,10 +144,13 @@
 												   LocalVariableBinding local, int nullStatus, Expression expression, TypeBinding providedType)
 {
 	if (local != null) {
+		int severity = 0;
 		if ((local.tagBits & TagBits.AnnotationNonNull) != 0
 				&& nullStatus != FlowInfo.NON_NULL) {
 			flowContext.recordNullityMismatch(currentScope, expression, providedType, local.type, nullStatus);
 			return FlowInfo.NON_NULL;
+		} else if ((severity = findNullTypeAnnotationMismatch(local.type, providedType)) > 0) {
+			currentScope.problemReporter().nullityMismatchingTypeAnnotation(expression, providedType, local.type, severity==1, currentScope.environment());
 		} else if ((local.tagBits & TagBits.AnnotationNullable) != 0
 				&& nullStatus == FlowInfo.UNKNOWN) {	// provided a legacy type?
 			return FlowInfo.POTENTIALLY_NULL;			// -> use more specific info from the annotation
@@ -127,7 +158,33 @@
 	}
 	return nullStatus;
 }
-
+protected int findNullTypeAnnotationMismatch(TypeBinding requiredType, TypeBinding providedType) {
+	int severity = 0;
+	if (requiredType instanceof ArrayBinding) {
+		long[] requiredDimsTagBits = ((ArrayBinding)requiredType).nullTagBitsPerDimension;
+		if (requiredDimsTagBits != null) {
+			int dims = requiredType.dimensions();
+			if (requiredType.dimensions() == providedType.dimensions()) {
+				long[] providedDimsTagBits = ((ArrayBinding)providedType).nullTagBitsPerDimension;
+				if (providedDimsTagBits == null) {
+					severity = 1; // required is annotated, provided not, need unchecked conversion
+				} else {
+					for (int i=0; i<dims; i++) {
+						long requiredBits = requiredDimsTagBits[i] & TagBits.AnnotationNullMASK;
+						long providedBits = providedDimsTagBits[i] & TagBits.AnnotationNullMASK;
+						if (requiredBits != 0 && requiredBits != providedBits) {
+							if (providedBits == 0)
+								severity = 1; // need unchecked conversion regarding type detail
+							else
+								return 2; // mismatching annotations
+						}
+					}
+				}
+			}
+		}
+	}
+	return severity;
+}
 /**
  * INTERNAL USE ONLY.
  * This is used to redirect inter-statements jumps.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index 7f8ac4f..67298e9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -15,6 +15,7 @@
  *     Technical University Berlin - extended API and implementation
  *     Stephan Herrmann - Contribution for
  *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -535,13 +536,15 @@
 			&& scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
 		scope.problemReporter().rawTypeReference(this, type);
 	}
-	resolveAnnotations(scope);
-
 	if (hasError) {
-		// do not store the computed type, keep the problem type instead
+		resolveAnnotations(scope);		
 		return type;
+	} else {
+		// store the computed type only if no error, otherwise keep the problem type instead
+		this.resolvedType = type;
+		resolveAnnotations(scope);
+		return this.resolvedType; // pick up value that may have been changed in resolveAnnotations(..)
 	}
-	return this.resolvedType = type;
 }
 
 //{ObjectTeams: alternative strategies for resolving:
@@ -685,11 +688,27 @@
 	if (this.annotations != null || annotationsOnDimensions != null) {
 		BlockScope resolutionScope = Scope.typeAnnotationsResolutionScope(scope);
 		if (resolutionScope != null) {
+			long[] tagBitsPerDimension = null;
+			int dimensions = this.dimensions();
+			boolean shouldAnalyzeArrayNullAnnotations = scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled && this instanceof ArrayTypeReference;
 			if (this.annotations != null) {
 				int annotationsLevels = this.annotations.length;
 				for (int i = 0; i < annotationsLevels; i++) {
-					if (this.annotations[i] != null) {
-						resolveAnnotations(resolutionScope, this.annotations[i], new Annotation.TypeUseBinding(isWildcard() ? Binding.TYPE_PARAMETER : Binding.TYPE_USE));
+					Annotation[] currentAnnotations = this.annotations[i];
+					if (currentAnnotations != null) {
+						resolveAnnotations(resolutionScope, currentAnnotations, new Annotation.TypeUseBinding(isWildcard() ? Binding.TYPE_PARAMETER : Binding.TYPE_USE));
+						if (shouldAnalyzeArrayNullAnnotations) {
+							int len = currentAnnotations.length;
+							for (int j=0; j<len; j++) {
+								Binding recipient = currentAnnotations[j].recipient;
+								if (recipient instanceof Annotation.TypeUseBinding) {
+									if (tagBitsPerDimension == null)
+										tagBitsPerDimension = new long[dimensions+1]; // each dimension plus leaf component type at last position
+									// @NonNull Foo [][][] means the leaf component type is @NonNull:
+									tagBitsPerDimension[dimensions] = ((Annotation.TypeUseBinding)recipient).tagBits & TagBits.AnnotationNullMASK;
+								}
+							}
+						}
 					}
 				}
 			}
@@ -699,9 +718,25 @@
 					Annotation [] dimensionAnnotations = annotationsOnDimensions[i];
 					if (dimensionAnnotations  != null) {
 						resolveAnnotations(resolutionScope, dimensionAnnotations, new Annotation.TypeUseBinding(Binding.TYPE_USE));
+						if (shouldAnalyzeArrayNullAnnotations) {
+							int len = dimensionAnnotations.length;
+							for (int j=0; j<len; j++) {
+								Binding recipient = dimensionAnnotations[j].recipient;
+								if (recipient instanceof Annotation.TypeUseBinding) {
+									if (tagBitsPerDimension == null)
+										tagBitsPerDimension = new long[dimensions+1];
+									tagBitsPerDimension[i] = ((Annotation.TypeUseBinding)recipient).tagBits & TagBits.AnnotationNullMASK;
+								}
+							}
+						}
 					}
 				}
 			}
+			if (tagBitsPerDimension != null && this.resolvedType.isValidBinding()) {
+				// TODO(stephan): wouldn't it be more efficient to store the array bindings inside the type binding rather than the environment?
+				// cf. LocalTypeBinding.createArrayType()
+				this.resolvedType = scope.environment().createArrayType(this.resolvedType.leafComponentType(), dimensions, tagBitsPerDimension);
+			}
 		}
 	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index 16b3854..be06999 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -1,13 +1,19 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 IBM Corporation 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
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -29,7 +35,15 @@
 	char[] constantPoolName;
 	char[] genericTypeSignature;
 
+	// One bitset for each dimension plus one more for the leaf component type at position 'dimensions',
+	// possible bits are TagBits.AnnotationNonNull and TagBits.AnnotationNullable
+	// (only ever set when CompilerOptions.isAnnotationBasedNullAnalysisEnabled == true):
+	public long[] nullTagBitsPerDimension;
+
 public ArrayBinding(TypeBinding type, int dimensions, LookupEnvironment environment) {
+	this(type, dimensions, environment, null);
+}
+public ArrayBinding(TypeBinding type, int dimensions, LookupEnvironment environment, long[] nullTagBitsPerDimension) {
 	this.tagBits |= TagBits.IsArrayType;
 	this.leafComponentType = type;
 	this.dimensions = dimensions;
@@ -38,6 +52,11 @@
 		((UnresolvedReferenceBinding) type).addWrapper(this, environment);
 	else
 		this.tagBits |= type.tagBits & (TagBits.HasTypeVariable | TagBits.HasDirectWildcard | TagBits.HasMissingType | TagBits.ContainsNestedTypeReferences);
+	
+	if (nullTagBitsPerDimension != null) {
+		this.tagBits |= nullTagBitsPerDimension[0]; // outer-most dimension
+		this.nullTagBitsPerDimension = nullTagBitsPerDimension;
+	}
 }
 
 public TypeBinding closestMatch() {
@@ -130,8 +149,17 @@
 */
 
 public TypeBinding elementsType() {
-	if (this.dimensions == 1) return this.leafComponentType;
-	return this.environment.createArrayType(this.leafComponentType, this.dimensions - 1);
+	long[] nullTagBitsSub = null;
+	if (this.nullTagBitsPerDimension != null) {
+		int len = this.nullTagBitsPerDimension.length-1;
+		System.arraycopy(this.nullTagBitsPerDimension, 1, nullTagBitsSub = new long[len], 0, len);
+	}
+	if (this.dimensions == 1) {
+		if (nullTagBitsSub != null && nullTagBitsSub[0] != 0L && this.leafComponentType instanceof ReferenceBinding)
+			return this.environment.createParameterizedType((ReferenceBinding) this.leafComponentType, null, nullTagBitsSub[0], null);
+		return this.leafComponentType;
+	}
+	return this.environment.createArrayType(this.leafComponentType, this.dimensions - 1, nullTagBitsSub);
 }
 /**
  * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#erasure()
@@ -222,6 +250,35 @@
 	return this.leafComponentType;
 }
 
+public char[] nullAnnotatedReadableName(LookupEnvironment env, boolean shortNames) /* java.lang.Object @o.e.j.a.NonNull[] */ {
+	if (this.nullTagBitsPerDimension == null)
+		return shortNames ? shortReadableName() : readableName();
+	char[][] brackets = new char[this.dimensions][];
+	for (int i = 0; i < this.dimensions; i++) {
+		if ((this.nullTagBitsPerDimension[i] & TagBits.AnnotationNullMASK) != 0) {
+			char[][] fqAnnotationName;
+			if ((this.nullTagBitsPerDimension[i] & TagBits.AnnotationNonNull) != 0)
+				fqAnnotationName = env.getNonNullAnnotationName();
+			else
+				fqAnnotationName = env.getNullableAnnotationName();
+			char[] annotationName = shortNames 
+										? fqAnnotationName[fqAnnotationName.length-1] 
+										: CharOperation.concatWith(fqAnnotationName, '.');
+			brackets[i] = new char[annotationName.length+3];
+			brackets[i][0] = '@';
+			System.arraycopy(annotationName, 0, brackets[i], 1, annotationName.length);
+			brackets[i][annotationName.length+1] = '[';
+			brackets[i][annotationName.length+2] = ']';
+		} else {
+			brackets[i] = new char[]{'[', ']'}; 
+		}
+	}
+	char[] leafTypeName = shortNames ? this.leafComponentType.shortReadableName() : this.leafComponentType.readableName();
+	return CharOperation.concat(leafTypeName, 
+								 CharOperation.concatWith(brackets, ' '),
+								 ' ');
+}
+
 /* API
 * Answer the problem id associated with the receiver.
 * NoError if the receiver is a valid binding.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 65fecfa..6dd21eb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -18,10 +18,12 @@
  *								bug 186342 - [compiler][null] Using annotations for null checking
  *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
  *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -823,6 +825,9 @@
  *  Used to guarantee array type identity.
  */
 public ArrayBinding createArrayType(TypeBinding leafComponentType, int dimensionCount) {
+	return createArrayType(leafComponentType, dimensionCount, null);
+}
+public ArrayBinding createArrayType(TypeBinding leafComponentType, int dimensionCount, long[] nullTagBitsPerDimension) {
 	if (leafComponentType instanceof LocalTypeBinding) // cache local type arrays with the local type itself
 		return ((LocalTypeBinding) leafComponentType).createArrayType(dimensionCount, this);
 
@@ -847,8 +852,9 @@
 	while (++index < length) {
 		ArrayBinding currentBinding = arrayBindings[index];
 		if (currentBinding == null) // no matching array, but space left
-			return arrayBindings[index] = new ArrayBinding(leafComponentType, dimensionCount, this);
-		if (currentBinding.leafComponentType == leafComponentType)
+			return arrayBindings[index] = new ArrayBinding(leafComponentType, dimensionCount, this, nullTagBitsPerDimension);
+		if (currentBinding.leafComponentType == leafComponentType
+				&& (nullTagBitsPerDimension == null || Arrays.equals(currentBinding.nullTagBitsPerDimension, nullTagBitsPerDimension)))
 			return currentBinding;
 	}
 
@@ -858,7 +864,7 @@
 		(arrayBindings = new ArrayBinding[length * 2]), 0,
 		length);
 	this.uniqueArrayBindings[dimIndex] = arrayBindings;
-	return arrayBindings[length] = new ArrayBinding(leafComponentType, dimensionCount, this);
+	return arrayBindings[length] = new ArrayBinding(leafComponentType, dimensionCount, this, nullTagBitsPerDimension);
 }
 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
 	return createBinaryTypeFrom(binaryType, packageBinding, true, accessRestriction);
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 9f54faf..5ad6d96 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
@@ -5,6 +5,10 @@
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
@@ -16,6 +20,7 @@
  *								bug 358903 - Filter practically unimportant resource leak warnings
  *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
  *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -1789,6 +1794,24 @@
 	return Binding.NO_METHODS;
 }
 
+public char[] nullAnnotatedReadableName(LookupEnvironment env, boolean shortNames) /* java.lang.Object @o.e.j.a.NonNull[] */ {
+	char[] typeName = shortNames ? shortReadableName() : readableName();
+	if ((this.tagBits & TagBits.AnnotationNullMASK) == 0)
+		return typeName;
+	char[][] fqAnnotationName;
+	if ((this.tagBits & TagBits.AnnotationNonNull) != 0)
+		fqAnnotationName = env.getNonNullAnnotationName();
+	else
+		fqAnnotationName = env.getNullableAnnotationName();
+	char[] annotationName = shortNames
+								? fqAnnotationName[fqAnnotationName.length-1]
+								: CharOperation.concatWith(fqAnnotationName, '.');				
+	char[] prefix = new char[annotationName.length+1];
+	prefix[0] = '@';
+	System.arraycopy(annotationName, 0, prefix, 1, annotationName.length);
+	return CharOperation.concat(prefix, typeName, ' ');
+}
+
 public final ReferenceBinding outermostEnclosingType() {
 	ReferenceBinding current = this;
 	while (true) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index b45fb89..bceeae0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -4,13 +4,18 @@
  * 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
- * $Id: TypeBinding.java 23405 2010-02-03 17:02:18Z stephan $
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- *      Stephen Herrmann <stephan@cs.tu-berlin.de> -  Contribution for bug 317046
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
+ *      Stephen Herrmann <stephan@cs.tu-berlin.de> -  Contributions for
+ *								bug 317046 - Exception during debugging when hover mouse over a field
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -1215,6 +1220,14 @@
 	return false;
 }
 
+/** Answer a readable name (for error reporting) that includes nullness type annotations. */
+public char[] nullAnnotatedReadableName(LookupEnvironment env, boolean shortNames) /* e.g.: java.lang.Object @o.e.j.a.NonNull[] */ {
+	if (shortNames)
+		return shortReadableName();
+	else
+		return readableName();
+}
+
 /**
  * Returns the orignal generic type instantiated by the receiver type, or itself if not.
  * This is similar to erasure process, except it doesn't erase type variable, wildcard, intersection types etc...
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 1d3767f..35d751f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -9146,19 +9146,19 @@
 		    consumeTypeArgument();  
 			break;
  
-    case 737 : if (DEBUG) { System.out.println("TypeAnchor ::= AT Name"); }  //$NON-NLS-1$
+    case 737 : if (DEBUG) { System.out.println("TypeAnchor ::= ATOT Name"); }  //$NON-NLS-1$
 		    consumeTypeAnchor(false);  
 			break;
  
-    case 738 : if (DEBUG) { System.out.println("TypeAnchor ::= AT base"); }  //$NON-NLS-1$
+    case 738 : if (DEBUG) { System.out.println("TypeAnchor ::= ATOT base"); }  //$NON-NLS-1$
 		    consumeTypeAnchor(true);  
 			break;
  
-    case 739 : if (DEBUG) { System.out.println("TypeAnchor ::= AT this"); }  //$NON-NLS-1$
+    case 739 : if (DEBUG) { System.out.println("TypeAnchor ::= ATOT this"); }  //$NON-NLS-1$
 		    skipThisAnchor();  
 			break;
  
-    case 740 : if (DEBUG) { System.out.println("TypeAnchor ::= AT Name DOT base"); }  //$NON-NLS-1$
+    case 740 : if (DEBUG) { System.out.println("TypeAnchor ::= ATOT Name DOT base"); }  //$NON-NLS-1$
 		    consumeQualifiedBaseTypeAnchor();  
 			break;
  
@@ -13039,7 +13039,7 @@
 	int stackTopState = this.stack[stackTop]; // single cell non write through "alternate stack" - the automaton's stack pointer either stays fixed during this manoeuvre or monotonically decreases.
 	int highWaterMark = stackTop;
 	
-	if (token != TokenNameAT) {
+	if (token != TokenNameAT && token != TokenNameATOT) {
 		token = token == TokenNameLPAREN ? TokenNameBeginLambda : TokenNameBeginTypeArguments;
 	}
 	
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
index 3909b0d..a3a5a46 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
@@ -23,19 +23,19 @@
 public interface ParserBasicInformation {
     public final static int
 
-      ERROR_SYMBOL      = 136,
+      ERROR_SYMBOL      = 137,
       MAX_NAME_LENGTH   = 41,
       NUM_STATES        = 1313,
 
-      NT_OFFSET         = 136,
+      NT_OFFSET         = 137,
       SCOPE_UBOUND      = 354,
       SCOPE_SIZE        = 355,
       LA_STATE_OFFSET   = 17809,
       MAX_LA            = 1,
       NUM_RULES         = 935,
-      NUM_TERMINALS     = 136,
+      NUM_TERMINALS     = 137,
       NUM_NON_TERMINALS = 417,
-      NUM_SYMBOLS       = 553,
+      NUM_SYMBOLS       = 554,
       START_STATE       = 1185,
       EOFT_SYMBOL       = 65,
       EOLT_SYMBOL       = 65,
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 eb561d3..87c90f3 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
@@ -27,6 +27,7 @@
  *								bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
  *								bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
  *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.problem;
 
@@ -119,6 +120,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
@@ -368,6 +370,8 @@
 
 		case IProblem.PotentialNullLocalVariableReference:
 		case IProblem.PotentialNullMessageSendReference:
+		case IProblem.ArrayReferencePotentialNullReference:
+		case IProblem.DereferencingNullableExpression:
 			return CompilerOptions.PotentialNullReference;
 
 		case IProblem.RedundantLocalVariableNullAssignment:
@@ -391,11 +395,13 @@
 		case IProblem.CannotImplementIncompatibleNullness:
 		case IProblem.ConflictingNullAnnotations:
 		case IProblem.ConflictingInheritedNullAnnotations:
+		case IProblem.NullityMismatchingTypeAnnotation:
 			return CompilerOptions.NullSpecViolation;
 
 		case IProblem.RequiredNonNullButProvidedPotentialNull:
 			return CompilerOptions.NullAnnotationInferenceConflict;
 		case IProblem.RequiredNonNullButProvidedUnknown:
+		case IProblem.NullityMismatchingTypeAnnotationUnchecked:
 			return CompilerOptions.NullUncheckedConversion;
 		case IProblem.RedundantNullAnnotation:
 		case IProblem.RedundantNullDefaultAnnotation:
@@ -9160,12 +9166,10 @@
 public void nullityMismatchIsNull(Expression expression, TypeBinding requiredType, char[][] annotationName) {
 	int problemId = IProblem.RequiredNonNullButProvidedNull;
 	String[] arguments = new String[] {
-			String.valueOf(CharOperation.concatWith(annotationName, '.')),
-			String.valueOf(requiredType.readableName())
+			annotatedTypeName(requiredType, annotationName)
 	};
 	String[] argumentsShort = new String[] {
-			String.valueOf(annotationName[annotationName.length-1]),
-			String.valueOf(requiredType.shortReadableName())
+			shortAnnotatedTypeName(requiredType, annotationName)
 	};
 	this.handle(problemId, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
 }
@@ -9173,13 +9177,11 @@
 	int problemId = IProblem.RequiredNonNullButProvidedSpecdNullable;
 	char[][] nullableName = this.options.nullableAnnotationName;
 	String[] arguments = new String[] {
-			String.valueOf(CharOperation.concatWith(annotationName, '.')),
-			String.valueOf(requiredType.readableName()),
+			annotatedTypeName(requiredType, annotationName),
 			String.valueOf(CharOperation.concatWith(nullableName, '.'))
 	};
 	String[] argumentsShort = new String[] {
-			String.valueOf(annotationName[annotationName.length-1]),
-			String.valueOf(requiredType.shortReadableName()),
+			shortAnnotatedTypeName(requiredType, annotationName),
 			String.valueOf(nullableName[nullableName.length-1])
 	};
 	this.handle(problemId, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
@@ -9188,13 +9190,11 @@
 	int problemId = IProblem.RequiredNonNullButProvidedPotentialNull;
 	char[][] nullableName = this.options.nullableAnnotationName;
 	String[] arguments = new String[] {
-			String.valueOf(CharOperation.concatWith(annotationName, '.')),
-			String.valueOf(requiredType.readableName()),
+			annotatedTypeName(requiredType, annotationName),
 			String.valueOf(CharOperation.concatWith(nullableName, '.'))
 	};
 	String[] argumentsShort = new String[] {
-			String.valueOf(annotationName[annotationName.length-1]),
-			String.valueOf(requiredType.shortReadableName()),
+			shortAnnotatedTypeName(requiredType, annotationName),
 			String.valueOf(nullableName[nullableName.length-1])
 	};
 	this.handle(problemId, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
@@ -9203,13 +9203,11 @@
 	int problemId = IProblem.RequiredNonNullButProvidedUnknown;
 	String[] arguments = new String[] {
 			String.valueOf(providedType.readableName()),
-			String.valueOf(CharOperation.concatWith(annotationName, '.')),
-			String.valueOf(requiredType.readableName())
+			annotatedTypeName(requiredType, annotationName)
 	};
 	String[] argumentsShort = new String[] {
 			String.valueOf(providedType.shortReadableName()),
-			String.valueOf(annotationName[annotationName.length-1]),
-			String.valueOf(requiredType.shortReadableName())
+			shortAnnotatedTypeName(requiredType, annotationName)
 	};
 	this.handle(problemId, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
 }
@@ -13005,6 +13003,50 @@
 			type.sourceEnd);
 }
 
+private String annotatedTypeName(TypeBinding type, char[][] annotationName) {
+	int dims = 0;
+	if (type instanceof ArrayBinding && ((ArrayBinding)type).nullTagBitsPerDimension != null) {
+		dims = type.dimensions();
+		type = type.leafComponentType();
+	}
+	char[] typeName = type.readableName();
+	char[] annotationDisplayName = CharOperation.concatWith(annotationName, '.');
+	return internalAnnotatedTypeName(annotationDisplayName, typeName, dims);
+}
+private String shortAnnotatedTypeName(TypeBinding type, char[][] annotationName) {
+	int dims = 0;
+	if (type instanceof ArrayBinding && ((ArrayBinding)type).nullTagBitsPerDimension != null) {
+		// if type has annotations on dimensions show the annotation on the outer most dimension:
+		dims = type.dimensions();
+		type = type.leafComponentType();
+	}
+	char[] typeName = type.shortReadableName();
+	char[] annotationDisplayName = annotationName[annotationName.length-1];
+	return internalAnnotatedTypeName(annotationDisplayName, typeName, dims);
+}
+
+String internalAnnotatedTypeName(char[] annotationName, char[] typeName, int dims) {
+	char[] fullName;
+	if (dims > 0) {
+		int plainLen = annotationName.length+typeName.length+2; // adding '@' and ' ' ...
+		fullName = new char[plainLen+(2*dims)]; // ... and []* 
+		System.arraycopy(typeName, 0, fullName, 0, typeName.length);
+		fullName[typeName.length] = ' ';
+		fullName[typeName.length+1] = '@';
+		System.arraycopy(annotationName, 0, fullName, typeName.length+2, annotationName.length);
+		for (int i=0; i<dims; i++) {
+			fullName[plainLen+i] = '[';
+			fullName[plainLen+i+1] = ']';
+		}
+	} else {
+		fullName = new char[annotationName.length+typeName.length+2]; // adding '@' and ' ' 
+		fullName[0] = '@';
+		System.arraycopy(annotationName, 0, fullName, 1, annotationName.length);
+		fullName[annotationName.length+1] = ' ';
+		System.arraycopy(typeName, 0, fullName, annotationName.length+2, typeName.length);
+	}
+	return String.valueOf(fullName);
+}
 private Annotation findAnnotation(Annotation[] annotations, int typeId) {
 	if (annotations != null) {
 		// should have a @NonNull/@Nullable annotation, search for it:
@@ -13057,4 +13099,38 @@
 			argument.declarationSourceStart,
 			argument.declarationSourceEnd);
 }
+
+public void arrayReferencePotentialNullReference(ArrayReference arrayReference) {
+	// TODO(stephan): merge with other expressions
+	this.handle(IProblem.ArrayReferencePotentialNullReference, NoArgument, NoArgument, arrayReference.sourceStart, arrayReference.sourceEnd);
+	
+}
+public void nullityMismatchingTypeAnnotation(Expression expression, TypeBinding providedType, TypeBinding requiredType, 
+		boolean uncheckedConversion, LookupEnvironment env) 
+{
+	String[] arguments = new String[] {
+		String.valueOf(requiredType.nullAnnotatedReadableName(env, false)),
+		String.valueOf(providedType.nullAnnotatedReadableName(env, false))
+	};
+	String[] shortArguments = new String[] {
+		String.valueOf(requiredType.nullAnnotatedReadableName(env, true)),
+		String.valueOf(providedType.nullAnnotatedReadableName(env, true))
+	};
+	this.handle(
+			uncheckedConversion ? IProblem.NullityMismatchingTypeAnnotationUnchecked : IProblem.NullityMismatchingTypeAnnotation,
+			arguments, shortArguments, expression.sourceStart, expression.sourceEnd);
+}
+public void dereferencingNullableExpression(Expression expression, LookupEnvironment env) {
+	if (expression instanceof MessageSend) {
+		MessageSend send = (MessageSend) expression;
+		messageSendPotentialNullReference(send.binding, send);
+		return;
+	}
+	char[][] nullableName = env.getNullableAnnotationName();
+	char[] nullableShort = nullableName[nullableName.length-1];
+	String[] arguments = { String.valueOf(nullableShort) };
+	// TODO(stephan): more sophisticated handling for various kinds of expressions
+	this.handle(IProblem.DereferencingNullableExpression, arguments, arguments, expression.sourceStart, expression.sourceEnd);
+	
+}
 }
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 43d77eb..c30428e 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
@@ -26,6 +26,7 @@
 #							bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
 #							bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
 #							bug 388281 - [compiler][null] inheritance of null annotations as an option
+#							bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
 ###############################################################################
 0 = {0}
 1 = super cannot be used in java.lang.Object
@@ -695,9 +696,9 @@
 890 = Cannot switch on an enum value for source level below 1.5. Only convertible int values are permitted
 
 ### NULL ANNOTATIONS
-910 = Null type mismatch: required ''@{0} {1}'' but the provided value is null
-911 = Null type mismatch: required ''@{0} {1}'' but the provided value is inferred as @{2}
-912 = Null type safety: The expression of type {0} needs unchecked conversion to conform to ''@{1} {2}''
+910 = Null type mismatch: required ''{0}'' but the provided value is null
+911 = Null type mismatch: required ''{0}'' but the provided value is inferred as @{1}
+912 = Null type safety: The expression of type {0} needs unchecked conversion to conform to ''{1}''
 913 = A default nullness annotation has not been specified for the package {0}
 914 = The return type is incompatible with the @{1} return from {0}
 915 = Illegal redefinition of parameter {0}, inherited method from {1} declares this parameter as @{2}
@@ -717,10 +718,14 @@
 930 = A default nullness annotation has not been specified for the type {0}
 931 = Redundant null check: The variable {0} is specified as @{1}
 932 = Null comparison always yields false: The variable {0} is specified as @{1}
-933 = Null type mismatch: required ''@{0} {1}'' but the provided value is specified as @{2}
+933 = Null type mismatch: required ''{0}'' but the provided value is specified as @{1}
 939 = The default ''@{0}'' conflicts with the inherited ''@{1}'' annotation in the overridden method from {2} 
 940 = Conflict between inherited null annotations ''@{0}'' declared in {1} versus ''@{2}'' declared in {3} 
 
+951 = Potential null pointer access: array element may be null
+952 = Potential null pointer access: this expression has a ''@{0}'' type
+953 = Null type mismatch (type annotations): required ''{0}'' but this expression has type ''{1}''
+954 = Null type mismatch (type annotations): the expression of type ''{1}'' needs unchecked conversion to conform to ''{0}''
 
 // Java 8
 1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided