update jdt.core to S4_15_0_M1
diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
index 3c8e3e4..d87f8fc 100644
--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core.tests.compiler;singleton:=true
-Bundle-Version: 3.12.1000.qualifier
+Bundle-Version: 3.12.1100.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.core.tests.compiler,
diff --git a/org.eclipse.jdt.core.tests.compiler/pom.xml b/org.eclipse.jdt.core.tests.compiler/pom.xml
index f3fd207..db6c935 100644
--- a/org.eclipse.jdt.core.tests.compiler/pom.xml
+++ b/org.eclipse.jdt.core.tests.compiler/pom.xml
@@ -15,12 +15,12 @@
   <parent>
     <artifactId>tests-pom</artifactId>
     <groupId>eclipse.jdt.core</groupId>
-    <version>4.14.0-SNAPSHOT</version>
+    <version>4.15.0-SNAPSHOT</version>
     <relativePath>../tests-pom/</relativePath>
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.core.tests.compiler</artifactId>
-  <version>3.12.1000-SNAPSHOT</version>
+  <version>3.12.1100-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 582f257..f8d2b76 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -2449,7 +2449,7 @@
 		if (!directory.exists())
 			return;
 		Files.walk(directory.toPath())
-			.filter(f -> f.endsWith(SuffixConstants.SUFFIX_STRING_java))
+			.filter(f -> f.toString().endsWith(SuffixConstants.SUFFIX_STRING_java))
 			.map(java.nio.file.Path::toFile)
 			.filter(File::isFile)
 			.forEach(File::delete);
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 51fdf97..401638e 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2019 IBM Corporation and others.
+ * Copyright (c) 2006, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -632,6 +632,7 @@
 		expectedProblemAttributes.put("InheritedIncompatibleReturnType", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
 		expectedProblemAttributes.put("InheritedMethodHidesEnclosingName", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
 		expectedProblemAttributes.put("InheritedMethodReducesVisibility", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
+		expectedProblemAttributes.put("InheritedParameterLackingNonNullAnnotation", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("InheritedTypeHidesEnclosingName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
 		expectedProblemAttributes.put("InitializerMustCompleteNormally", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
 		expectedProblemAttributes.put("InstanceFieldDuringConstructorInvocation", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
@@ -814,6 +815,7 @@
 		expectedProblemAttributes.put("MissingEnumDefaultCase", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("MissingNonNullByDefaultAnnotationOnPackage", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("MissingNonNullByDefaultAnnotationOnType", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("MissingNullAnnotationImplicitlyUsed", new ProblemAttributes(CategorizedProblem.CAT_BUILDPATH));
 		expectedProblemAttributes.put("MissingOverrideAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
 		expectedProblemAttributes.put("MissingOverrideAnnotationForInterfaceMethodImplementation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
 		expectedProblemAttributes.put("MissingRequiresTransitiveForTypeInAPI", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
@@ -1698,6 +1700,7 @@
 		expectedProblemAttributes.put("InheritedIncompatibleReturnType", SKIP);
 		expectedProblemAttributes.put("InheritedMethodHidesEnclosingName", SKIP);
 		expectedProblemAttributes.put("InheritedMethodReducesVisibility", SKIP);
+		expectedProblemAttributes.put("InheritedParameterLackingNonNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED));
 		expectedProblemAttributes.put("InheritedTypeHidesEnclosingName", SKIP);
 		expectedProblemAttributes.put("InitializerMustCompleteNormally", SKIP);
 		expectedProblemAttributes.put("InstanceFieldDuringConstructorInvocation", SKIP);
@@ -1883,6 +1886,7 @@
 		expectedProblemAttributes.put("MissingEnumDefaultCase", new ProblemAttributes(JavaCore.COMPILER_PB_SWITCH_MISSING_DEFAULT_CASE));
 		expectedProblemAttributes.put("MissingNonNullByDefaultAnnotationOnPackage", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION));
 		expectedProblemAttributes.put("MissingNonNullByDefaultAnnotationOnType", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION));
+		expectedProblemAttributes.put("MissingNullAnnotationImplicitlyUsed", SKIP);
 		expectedProblemAttributes.put("MissingOverrideAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION));
 		expectedProblemAttributes.put("MissingOverrideAnnotationForInterfaceMethodImplementation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION));
 		expectedProblemAttributes.put("MissingRequiresTransitiveForTypeInAPI", new ProblemAttributes(JavaCore.COMPILER_PB_API_LEAKS));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index 2ca01b8..9b8512e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -52829,7 +52829,7 @@
 
 	@Override
 	public String toString() {
-		return "#"+index + " " + durationMs + "ms" + (isExcluded?" (excluded)":"");
+		return "#"+this.index + " " + this.durationMs + "ms" + (this.isExcluded?" (excluded)":"");
 	}
 }
 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index fcf06d9..65a5618 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -10006,4 +10006,39 @@
 			"The method define(FuncN, TODO[]) is ambiguous for the type Test\n" + 
 			"----------\n");
 	}
+
+	public void testBug534223() {
+		Runner runner = new Runner();
+		String sourceX =
+				"package p;\n" +
+				"public class X {\n" +
+				"	<S> void m() {\n" +
+				"		Runnable r = () -> {\n" +
+				"			IFC<S> i = new IFC<S>() {\n" +
+				"				public void n(S s) {}\n" +
+				"			};\n" +
+				"			if (i != null)\n" +
+				"				System.out.println(i);\n" +
+				"		};\n" +
+				"		r.run();\n" +
+				"	}\n" +
+				"}\n";
+		runner.testFiles = new String[] {
+				"p/IFC.java",
+				"package p;\n" +
+				"public interface IFC<T> {\n" +
+				"	void n(T t);\n" +
+				"}\n",
+				"p/X.java",
+				sourceX
+			};
+		runner.runConformTest();
+		runner.shouldFlushOutputDirectory = false;
+		runner.testFiles = new String[] {
+				"p/X.java",
+				sourceX			
+			};
+		runner.runConformTest(); // don't use pre-compiled p/X$1.class
+	}
+
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index 5be3c39..b110757 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -6846,6 +6846,109 @@
 		"A.m"		
 	);
 }
+public void testBug553885a() {
+	runConformTest(
+			new String[] {
+					"p2/Test.java",
+						"package p2;\n" +
+						"import java.util.Optional;\n" +
+						"import p1.B;\n" +
+						"import p1.BImpl;\n" +
+						"\n" +
+						"public class Test {\n" +
+						"    public static void main(String[] args) {\n" +
+						"        Optional<Integer> map = Optional.of(new BImpl()).map(B::amount);\n" +
+						"        System.out.print(map);\n" +
+						"    }\n" +
+						"}",
+					"p1/A.java",
+							"package p1;\n" +
+							"interface A {\n" +
+							"    default int amount() {\n" +
+							"        return 0;\n" +
+							"    }\n" +
+							"}\n",
+					"p1/B.java",
+							"package p1;\n" +
+							"public interface B extends A {}\n" +
+							"\n",
+					"p1/BImpl.java",
+							"package p1;\n" +
+							"public class BImpl implements B {}\n",
+			},
+			"Optional[0]"
+			);
+}
+public void testBug553885b() {
+	runConformTest(
+			new String[] {
+					"p2/Test.java",
+						"package p2;\n" +
+						"import java.util.Optional;\n" +
+						"import p1.B;\n" +
+						"import p1.BImpl;\n" +
+						"\n" +
+						"public class Test {\n" +
+						"    public static void main(String[] args) {\n" +
+						"        B b = new BImpl();\n" + // lead inference towards Optional<B> instead of Optional<BImpl>
+						"        Optional<Integer> map = Optional.of(b).map(B::amount);\n" +
+						"        System.out.print(map);\n" +
+						"    }\n" +
+						"}",
+					"p1/A.java",
+							"package p1;\n" +
+							"interface A {\n" +
+							"    default int amount() {\n" +
+							"        return 0;\n" +
+							"    }\n" +
+							"}\n",
+					"p1/B.java",
+							"package p1;\n" +
+							"public interface B extends A {}\n" +
+							"\n",
+					"p1/BImpl.java",
+							"package p1;\n" +
+							"public class BImpl implements B {}\n",
+			},
+			"Optional[0]"
+			);
+}
+public void testBug553885c() {
+	// classes instead of interface with default method
+	runConformTest(
+			new String[] {
+					"p2/Test.java",
+						"package p2;\n" +
+						"import java.util.Optional;\n" +
+						"import p1.B;\n" +
+						"import p1.BImpl;\n" +
+						"\n" +
+						"public class Test {\n" +
+						"    public static void main(String[] args) {\n" +
+						"        B b = new BImpl();\n" +
+						"        Optional<Integer> map = Optional.of(b).map(B::amount);\n" +
+						"        System.out.print(map);\n" +
+						"    }\n" +
+						"}",
+					"p1/A.java",
+							"package p1;\n" +
+							"class A {\n" +
+							"    public int amount() {\n" +
+							"        return 0;\n" +
+							"    }\n" +
+							"}\n",
+					"p1/B.java",
+							"package p1;\n" +
+							"public class B extends A {}\n" +
+							"\n",
+					"p1/BImpl.java",
+							"package p1;\n" +
+							"public class BImpl extends B {}\n",
+			},
+			"Optional[0]"
+			);
+}
+
 public void testBug521182() {
 	runConformTest(
 		new String[] {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
index 242673e..2f147da 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
@@ -1286,44 +1286,44 @@
 		"----------\n" +
 		"1. ERROR in p1\\Y.java (at line 2)\n" +
 		"	public class Y extends X implements IY {\n" +
-		"	             ^\n" +
+		"	                       ^\n" +
 		"The method getString1(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
 		"----------\n" +
 		"2. ERROR in p1\\Y.java (at line 2)\n" +
 		"	public class Y extends X implements IY {\n" +
-		"	             ^\n" +
+		"	                       ^\n" +
 		"The method getString2(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
 		"----------\n" +
 		"3. ERROR in p1\\Y.java (at line 2)\n" +
 		"	public class Y extends X implements IY {\n" +
-		"	             ^\n" +
+		"	                       ^\n" +
 		"The method getString5(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
 		"----------\n" +
 		"4. ERROR in p1\\Y.java (at line 2)\n" +
 		"	public class Y extends X implements IY {\n" +
-		"	             ^\n" +
+		"	                       ^\n" +
 		"The method getString3(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
 		"----------\n"
 		: // at 1.8 we show null type annotations in the message:
 		"----------\n" + 
 		"1. ERROR in p1\\Y.java (at line 2)\n" + 
 		"	public class Y extends X implements IY {\n" + 
-		"	             ^\n" + 
+		"	                       ^\n" + 
 		"The method @Nullable String getString1(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" + 
 		"----------\n" + 
 		"2. ERROR in p1\\Y.java (at line 2)\n" + 
 		"	public class Y extends X implements IY {\n" + 
-		"	             ^\n" + 
+		"	                       ^\n" + 
 		"The method String getString2(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" + 
 		"----------\n" + 
 		"3. ERROR in p1\\Y.java (at line 2)\n" + 
 		"	public class Y extends X implements IY {\n" + 
-		"	             ^\n" + 
+		"	                       ^\n" + 
 		"The method getString5(@NonNull String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" + 
 		"----------\n" + 
 		"4. ERROR in p1\\Y.java (at line 2)\n" + 
 		"	public class Y extends X implements IY {\n" + 
-		"	             ^\n" + 
+		"	                       ^\n" + 
 		"The method getString3(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" + 
 		"----------\n"));
 }
@@ -1411,8 +1411,8 @@
 		"----------\n" + 
 		"1. WARNING in XSub.java (at line 1)\n" + 
 		"	public class XSub extends X implements IX {\n" + 
-		"	             ^^^^\n" + 
-		"Missing non-null annotation: inherited method from IX specifies this parameter as @NonNull\n" + 
+		"	                          ^\n" + 
+		"Parameter 1 of method foo(String) lacks a @NonNull annotation as specified in type IX\n" + 
 		"----------\n");
 }
 
@@ -6123,24 +6123,24 @@
 		"----------\n" + 
 		"1. ERROR in ctest\\C.java (at line 2)\n" + 
 		"	public class C extends c.C2 implements i2.I2A {\n" + 
-		"	             ^\n" + 
+		"	                       ^^^^\n" + 
 		"The method m2(Object) from C2 cannot implement the corresponding method from I2A due to incompatible nullness constraints\n" + 
 		"----------\n" + 
 		"2. ERROR in ctest\\C.java (at line 2)\n" + 
 		"	public class C extends c.C2 implements i2.I2A {\n" + 
-		"	             ^\n" + 
+		"	                       ^^^^\n" + 
 		"The method m1(Object) from C2 cannot implement the corresponding method from I2A due to incompatible nullness constraints\n" + 
 		"----------\n"
 		: // at 1.8 we show null type annotations:
 		"----------\n" + 
 		"1. ERROR in ctest\\C.java (at line 2)\n" + 
 		"	public class C extends c.C2 implements i2.I2A {\n" + 
-		"	             ^\n" + 
+		"	                       ^^^^\n" + 
 		"The method m2(@NonNull Object) from C2 cannot implement the corresponding method from I2A due to incompatible nullness constraints\n" + 
 		"----------\n" + 
 		"2. ERROR in ctest\\C.java (at line 2)\n" + 
 		"	public class C extends c.C2 implements i2.I2A {\n" + 
-		"	             ^\n" + 
+		"	                       ^^^^\n" + 
 		"The method m1(@NonNull Object) from C2 cannot implement the corresponding method from I2A due to incompatible nullness constraints\n" + 
 		"----------\n"),
 		libs,		
@@ -9139,24 +9139,24 @@
 		"----------\n" + 
 		"1. ERROR in test\\X.java (at line 22)\n" + 
 		"	class Y extends A implements I {\n" + 
-		"	      ^\n" + 
+		"	                ^\n" + 
 		"The method m2() from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" + 
 		"----------\n" + 
 		"2. ERROR in test\\X.java (at line 22)\n" + 
 		"	class Y extends A implements I {\n" + 
-		"	      ^\n" + 
+		"	                ^\n" + 
 		"The method m1(Object) from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" + 
 		"----------\n"		
 		:
 		"----------\n" + 
 		"1. ERROR in test\\X.java (at line 22)\n" + 
 		"	class Y extends A implements I {\n" + 
-		"	      ^\n" + 
+		"	                ^\n" + 
 		"The method @Nullable String m2() from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" + 
 		"----------\n" + 
 		"2. ERROR in test\\X.java (at line 22)\n" + 
 		"	class Y extends A implements I {\n" + 
-		"	      ^\n" + 
+		"	                ^\n" + 
 		"The method m1(Object) from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" + 
 		"----------\n"
 		)
@@ -10973,4 +10973,139 @@
 	runner.javacTestOptions = Excuse.EclipseWarningConfiguredAsError;
 	runner.runNegativeTest();
 }
+public void testBug459397() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"NonNullBug.java",
+			"import org.eclipse.jdt.annotation.NonNull;\n" + 
+			"import org.eclipse.jdt.annotation.Nullable;\n" + 
+			"\n" + 
+			"public class NonNullBug {\n" + 
+			"	public static final String PACKid_$metamodel$ = null;\n" + 
+			"	public static final String PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_SimpleRDBMS = null;\n" + 
+			"	public static final String PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_UMLtoRDBMS = null;\n" + 
+			"	public static final String PACKid_http_c_s_s_www_eclipse_org_s_qvt_s_examples_s_0_1_s_simpleUML = null;\n" + 
+			"	public static final String CLSSid_Association = null;\n" + 
+			"	public static final String CLSSid_AssociationToForeignKey = null;\n" + 
+			"	public static final String CLSSid_Attribute = null;\n" + 
+			"	public static final String CLSSid_AttributeToColumn = null;\n" + 
+			"	public static final String CLSSid_Class = null;\n" + 
+			"	public static final String CLSSid_ClassToTable = null;\n" + 
+			"	public static final String CLSSid_Class_0 = null;\n" + 
+			"	public static final String CLSSid_Classifier = null;\n" + 
+			"	public static final String CLSSid_Column = null;\n" + 
+			"	public static final String CLSSid_ForeignKey = null;\n" + 
+			"	public static final String CLSSid_FromAttribute = null;\n" + 
+			"	public static final String CLSSid_Key = null;\n" + 
+			"	public static final String CLSSid_NonLeafAttribute = null;\n" + 
+			"	public static final String CLSSid_Package = null;\n" + 
+			"	public static final String CLSSid_PackageElement = null;\n" + 
+			"	public static final String CLSSid_PackageToSchema = null;\n" + 
+			"	public static final String CLSSid_PrimitiveDataType = null;\n" + 
+			"	public static final String CLSSid_PrimitiveToName = null;\n" + 
+			"	public static final String CLSSid_Schema = null;\n" + 
+			"	public static final String CLSSid_Table = null;\n" + 
+			"	public static final String STR_2 = \"2\";\n" + 
+			"	public static final String STR_BOOLEAN = \"BOOLEAN\";\n" + 
+			"	public static final String STR_Boolean = \"Boolean\";\n" + 
+			"	public static final String STR_Integer = \"Integer\";\n" + 
+			"	public static final String STR_NUMBER = \"NUMBER\";\n" + 
+			"	public static final String STR_String = \"String\";\n" + 
+			"	public static final String STR_VARCHAR = \"VARCHAR\";\n" + 
+			"	public static final String STR__ = \"_\";\n" + 
+			"	public static final String STR__pk = \"_pk\";\n" + 
+			"	public static final String STR__tid = \"_tid\";\n" + 
+			"	public static final String STR_base = \"base\";\n" + 
+			"	public static final String STR_persistent = \"persistent\";\n" + 
+			"	public static final String STR_primary = \"primary\";\n" + 
+			"	public static final String BAG_CLSSid_AttributeToColumn = null;\n" + 
+			"	public static final String BAG_CLSSid_FromAttribute = null;\n" + 
+			"	public static final String ORD_CLSSid_AssociationToForeignKey = null;\n" + 
+			"	public static final String ORD_CLSSid_Attribute = null;\n" + 
+			"	public static final String ORD_CLSSid_Column = null;\n" + 
+			"	public static final String ORD_CLSSid_ForeignKey = null;\n" + 
+			"	public static final String ORD_CLSSid_Key = null;\n" + 
+			"	public static final String ORD_CLSSid_PackageElement = null;\n" + 
+			"	public static final String SET_CLSSid_Association = null;\n" + 
+			"	public static final String SET_CLSSid_Attribute = null;\n" + 
+			"	public static final String SET_CLSSid_AttributeToColumn = null;\n" + 
+			"	public static final String SET_CLSSid_Class = null;\n" + 
+			"	public static final String SET_CLSSid_ClassToTable = null;\n" + 
+			"	public static final String SET_CLSSid_FromAttribute = null;\n" + 
+			"	public static final String SET_CLSSid_NonLeafAttribute = null;\n" + 
+			"	public static final String SET_CLSSid_Package = null;\n" + 
+			"	public static final String SET_CLSSid_PrimitiveToName = null;\n" + 
+			"\n" + 
+			"	protected final String OPPOSITE_OF_ClassToTable_table = null;\n" + 
+			"	protected final String OPPOSITE_OF_ClassToTable_umlClass = null;\n" + 
+			"	protected final String OPPOSITE_OF_FromAttribute_attribute = null;\n" + 
+			"	protected final String OPPOSITE_OF_PrimitiveToName_primitive = null;\n" + 
+			"\n" + 
+			"	@SuppressWarnings(\"unused\")\n" + 
+			"	private static final String[] classIndex2classId = new String[] {};\n" + 
+			"	@SuppressWarnings(\"unused\")\n" + 
+			"	private final static int[][] classIndex2allClassIndexes = new int[][] {};\n" + 
+			"\n" + 
+			"	protected String x(final @NonNull Exception a, final @NonNull String p_4, final @Nullable String p2s_9) throws Exception {\n" + 
+			"		final @Nullable Throwable destination = a.getCause();\n" + 
+			"		final @Nullable Throwable dc = a.getCause();\n" + 
+			"		if (dc == null) {\n" + 
+			"			throw new Exception();\n" + 
+			"		}\n" + 
+			"		try {\n" + 
+			"			if (dc instanceof Exception) {\n" + 
+			"				throw (Exception) dc;\n" + 
+			"			}\n" + 
+			"			boolean eq_2 = (destination != null) ? destination.equals(dc) : (dc == null);\n" + 
+			"		} catch (Exception e) {\n" + 
+			"		}\n" + 
+			"		boolean ne = (destination != null) ? !destination.equals(dc) : (dc != null);\n" + 
+			"		return dc.toString();\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"----------\n" + 
+		"1. ERROR in NonNullBug.java (at line 80)\n" + 
+		"	boolean eq_2 = (destination != null) ? destination.equals(dc) : (dc == null);\n" + 
+		"	                                                                 ^^\n" + 
+		"Null comparison always yields false: The variable dc cannot be null at this location\n" + 
+		"----------\n" + 
+		"2. ERROR in NonNullBug.java (at line 83)\n" + 
+		"	boolean ne = (destination != null) ? !destination.equals(dc) : (dc != null);\n" + 
+		"	                                                                ^^\n" + 
+		"Redundant null check: The variable dc cannot be null at this location\n" + 
+		"----------\n");
+}
+public void testBug466477() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"SuperI.java",
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"\n" + 
+			"public interface SuperI {\n" + 
+			"  void testNN(@NonNull String s);\n" + 
+			"  void testNu(@Nullable String s);\n" + 
+			"}\n",
+			"Base.java",
+			"public class Base {\n" + 
+			"  public void testNN(String s) { }\n" + 
+			"  public void testNu(String s) { }\n" + 
+			"}\n",
+			"Custom.java",
+			"public class Custom extends Base implements SuperI {\n" + 
+			"}"
+		},
+		"----------\n" + 
+		"1. ERROR in Custom.java (at line 1)\n" + 
+		"	public class Custom extends Base implements SuperI {\n" + 
+		"	                            ^^^^\n" + 
+		"The method testNu(String) from Base cannot implement the corresponding method from SuperI due to incompatible nullness constraints\n" + 
+		"----------\n" + 
+		"2. WARNING in Custom.java (at line 1)\n" + 
+		"	public class Custom extends Base implements SuperI {\n" + 
+		"	                            ^^^^\n" + 
+		"Parameter 1 of method testNN(String) lacks a @NonNull annotation as specified in type SuperI\n" + 
+		"----------\n");
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java
index 9c0232a..14bd6d2 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java
@@ -4821,7 +4821,9 @@
 		false,
 		false
 	);
-	this.runConformTest(
+	Runner runner = new Runner();
+	runner.javacTestOptions = JavacTestOptions.SKIP; // javac did not produce p1/p2/X.class which is needed below
+	runner.testFiles =
 		new String[] {
 			"a/b/A.java", // =================
 			"package a.b;\n" + 
@@ -4833,13 +4835,10 @@
 			"p2/p3/Z.java", // =================
 			"package p2.p3;\n" + 
 			"public class Z {}\n"
-		},
-		"",
-		null,
-		false,
-		null
-	);
-	this.runConformTest(
+		};
+	runner.shouldFlushOutputDirectory = false;
+	runner.runConformTest();
+	runner.testFiles =
 		new String[] {
 			"a/b/A.java", // =================
 			"package a.b;\n" + 
@@ -4848,12 +4847,8 @@
 			"	void test() { x.z(); }\n" + 
 			"	void foo(p2.p3.Z z) {}\n" + 
 			"}\n"
-		},
-		"",
-		null,
-		false,
-		null
-	);
+		};
+	runner.runConformTest();
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=250297 - variation
 public void test093() {
@@ -8183,8 +8178,6 @@
 		"	      ^\n" + 
 		"Read access to enclosing field X.o is emulated by a synthetic accessor method\n" + 
 		"----------\n";
-	runner.javacTestOptions =
-		JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings;
 	runner.runWarningTest();
 }
 
@@ -8762,6 +8755,8 @@
 		"----------\n";
 	runner.runNegativeTest();
 
+	runner.javacTestOptions = JavacTestOptions.SKIP; // javac did not produce b/Roken.class which is needed below
+
 	// restore the class as binary:
 	runner.testFiles = new String[] {
 		nameMissing,
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index 8e078ef..a0b7fb6 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -53,7 +53,7 @@
 	"}\n";
 
 static {
-//	TESTS_NAMES = new String[] { "testBug542707" };
+//	TESTS_NAMES = new String[] { "testBug463320" };
 //	TESTS_NUMBERS = new int[] { 50 };
 //	TESTS_RANGE = new int[] { 11, -1 };
 }
@@ -3088,7 +3088,12 @@
 			"}\n"
 		},
 		"----------\n" +
-		"1. ERROR in X.java (at line 18)\n" +
+		"1. ERROR in X.java (at line 15)\n" + 
+		"	return wc.open(getObjectId(), type).openStream();\n" + 
+		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + 
+		"----------\n" + 
+		"2. ERROR in X.java (at line 18)\n" + 
 		"	return new ObjectStream.Filter(type, size, in);\n" +
 		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
 		"Potential resource leak: \'in\' may not be closed at this location\n" +
@@ -4215,13 +4220,13 @@
 		null);
 }
 
-// Bug 395977 - Resource leak warning behavior possibly incorrect for anonymous inner class
-// variant with named local class - don't accept as a secure resource wrapper
+//Bug 395977 - Resource leak warning behavior possibly incorrect for anonymous inner class
+//variant with named local class - accept as a secure resource wrapper since no close method
 public void testBug395977_1() {
 	Map options = getCompilerOptions();
 	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
 	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
-	runLeakTest(
+	runConformTest(
 		new String[] {
 			"WriterTest.java",
 			"import java.io.*;\n" + 
@@ -4271,8 +4276,68 @@
 			"   }\n" + 
 			"}"
 		},
+		"",
+		options);
+}
+//Bug 395977 - Resource leak warning behavior possibly incorrect for anonymous inner class
+//variant with named local class - don't accept as a secure resource wrapper since close() method exist
+public void testBug395977_1a() {
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runLeakTest(
+		new String[] {
+			"WriterTest.java",
+			"import java.io.*;\n" + 
+			"\n" + 
+			"public class WriterTest implements Runnable\n" + 
+			"{\n" + 
+			"   private BufferedWriter m_Writer;\n" + 
+			"   \n" + 
+			"   public void run()\n" + 
+			"   {\n" + 
+			"      try\n" + 
+			"      {\n" + 
+			"         initializeWriter();\n" + 
+			"         \n" + 
+			"         m_Writer.write(\"string\");\n" + 
+			"         m_Writer.newLine();\n" + 
+			"         \n" + 
+			"         closeWriter();\n" + 
+			"      }\n" + 
+			"      catch (IOException ioe)\n" + 
+			"      {\n" + 
+			"         ioe.printStackTrace();\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private void initializeWriter()\n" + 
+			"      throws UnsupportedEncodingException, FileNotFoundException\n" + 
+			"   {\n" + 
+			"      class MyBufferedWriter extends BufferedWriter\n" + 
+			"      {\n" +
+			"         MyBufferedWriter(OutputStreamWriter writer) { super(writer); }\n" +
+			"         /**\n" + 
+			"          * Writes an LF character on all platforms, to avoid constantly flipping the line terminator style.\n" + 
+			"          */\n" + 
+			"         public void newLine() throws IOException\n" + 
+			"         {\n" + 
+			"            write('\\n');\n" + 
+			"         }\n" +
+			"         public void close() {}\n" + 
+			"      };" +
+			"      m_Writer = new MyBufferedWriter(new OutputStreamWriter(new FileOutputStream(\"file\"), \"UTF-8\"));\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private void closeWriter()\n" + 
+			"      throws IOException\n" + 
+			"   {\n" + 
+			"      m_Writer.close();\n" + 
+			"   }\n" + 
+			"}"
+		},
 		"----------\n" + 
-		"1. ERROR in WriterTest.java (at line 37)\n" + 
+		"1. ERROR in WriterTest.java (at line 38)\n" + 
 		"	};      m_Writer = new MyBufferedWriter(new OutputStreamWriter(new FileOutputStream(\"file\"), \"UTF-8\"));\n" + 
 		"	                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
 		"Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + 
@@ -5358,7 +5423,8 @@
 	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // using diamond
 	Map<String, String> compilerOptions = getCompilerOptions();
 	compilerOptions.put(JavaCore.COMPILER_PB_SYNTHETIC_ACCESS_EMULATION, JavaCore.IGNORE);
-	runLeakTest(
+	Runner runner = new Runner();
+	runner.testFiles =
 		new String[] {
 			"AutoCloseableEnhancedForTest.java",
 			"import java.util.Iterator;\n" + 
@@ -5422,7 +5488,8 @@
 			"      }\n" + 
 			"   }\n" + 
 			"}\n"
-		},
+		};
+	runner.expectedCompilerLog =
 		"----------\n" + 
 		"1. WARNING in AutoCloseableEnhancedForTest.java (at line 44)\n" + 
 		"	for (Object value : new MyIterable<>())\n" + 
@@ -5433,8 +5500,9 @@
 		"	MyIterable<Object> iterable = new MyIterable<>();\n" + 
 		"	                   ^^^^^^^^\n" + 
 		"Resource leak: \'iterable\' is never closed\n" + 
-		"----------\n",
-		compilerOptions);
+		"----------\n";
+	runner.customOptions = compilerOptions;
+	runner.runWarningTest(); // javac warns about exception thrown from close() method
 }
 public void testBug541705() {
 	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // uses diamond
@@ -5702,4 +5770,633 @@
 		"----------\n",
 		options);
 }
+public void testBug463320() {
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	runLeakTest(
+		new String[] {
+			"Try17.java",
+			"import java.util.zip.*;\n" +
+			"import java.io.*;\n" +
+			"public class Try17 {\n" + 
+			"    void potential() throws IOException {\n" + 
+			"        String name= getZipFile().getName();\n" + 
+			"        System.out.println(name);\n" + 
+			"    }\n" + 
+			"    void definite() throws IOException {\n" + 
+			"        String name= new ZipFile(\"bla.jar\").getName();\n" + 
+			"        System.out.println(name);\n" + 
+			"    }\n" +
+			"	 void withLocal() throws IOException {\n" +
+			"		 ZipFile zipFile = getZipFile();\n" +
+			"        String name= zipFile.getName();\n" + 
+			"        System.out.println(name);\n" + 
+			"	 }\n" + 
+			"\n" + 
+			"    ZipFile getZipFile() throws IOException {\n" + 
+			"        return new ZipFile(\"bla.jar\");\n" + 
+			"    }\n" + 
+			"}"
+		},
+		"----------\n" + 
+		"1. ERROR in Try17.java (at line 5)\n" + 
+		"	String name= getZipFile().getName();\n" + 
+		"	             ^^^^^^^^^^^^\n" + 
+		"Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + 
+		"----------\n" + 
+		"2. ERROR in Try17.java (at line 9)\n" + 
+		"	String name= new ZipFile(\"bla.jar\").getName();\n" + 
+		"	             ^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"2. ERROR in Try17.java (at line 13)\n" + 
+		"	ZipFile zipFile = getZipFile();\n" + 
+		"	        ^^^^^^^\n" + 
+		"Potential resource leak: \'zipFile\' may not be closed\n" + 
+		"----------\n",
+		options);
+}
+public void testBug463320_comment8() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // required version of java.nio.file.*
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	runLeakTest(
+		new String[] {
+			"Try17.java",
+			"import java.io.*;\n" +
+			"import java.nio.file.*;\n" +
+			"import java.net.*;\n" +
+			"public class Try17 {\n" + 
+			"   public InputStream openInputStream(URI uri) {\n" + 
+			"		try {\n" + 
+			"			System.out.println(FileSystems.getFileSystem(uri));\n" + 
+			"			return Files.newInputStream(Paths.get(uri));\n" + 
+			"		} catch (FileSystemNotFoundException e) {\n" + 
+			"			throw new IllegalArgumentException(e);\n" + 
+			"		} catch (IOException e) {\n" + 
+			"			throw new IllegalStateException(e);\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"	public InputStream delegateGet(URI uri) {\n" +
+			"		return openInputStream(uri);\n" + // no problem here!
+			"	}\n" + 
+			"}"
+		},
+		"----------\n" + 
+		"1. ERROR in Try17.java (at line 7)\n" + 
+		"	System.out.println(FileSystems.getFileSystem(uri));\n" + 
+		"	                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential resource leak: \'<unassigned Closeable value from line 7>\' may not be closed\n" + 
+		"----------\n",
+		options);
+}
+public void testBug558574() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses varargs signatures
+
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+
+	runConformTest(
+		new String[] {
+			"X.java",
+			"import java.io.*;\n" +
+			"public class X {\n" +
+			"	void m1() throws FileNotFoundException {\n" +
+			"		PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(\"/tmp/out\")));\n" +
+			"		pw.printf(\"%d\", 42).close();\n" +
+			"	}\n" +
+			"	void m2(PrintWriter pw) throws FileNotFoundException {\n" +
+			"		pw.printf(\"%d\", 42).append(\"end\").close();\n" +
+			"	}\n" +
+			"	void m3() throws FileNotFoundException {\n" +
+			"		new PrintWriter(new OutputStreamWriter(new FileOutputStream(\"/tmp/out\")))\n" +
+			"			.format(\"%d\", 42)\n" +
+			"			.append(\"end\")\n" +
+			"			.close();\n" +
+			"	}\n" +
+			"	void m4(PrintWriter pw) throws FileNotFoundException {\n" +
+			"		pw.printf(\"%d\", 42).append(\"end\");\n" +
+			"	}\n" +
+			"}\n"
+		},
+		"",
+		options);
+}
+public void testBug463320_comment19() {
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+
+	runConformTest(
+		new String[] {
+			"Try17.java",
+			"import java.util.zip.*;\n" +
+			"import java.io.*;\n" +
+			"public class Try17 {\n" + 
+			"	void withLocal() throws IOException {\n" +
+			"		ZipFile zipFile = null;\n" +
+			"		if (zipFile != null)" +
+			"			zipFile = getZipFile();\n" + // not reachable
+			"		String name= zipFile.getName();\n" + 
+			"		System.out.println(name);\n" + 
+			"	 }\n" + 
+			"\n" + 
+			"    ZipFile getZipFile() throws IOException {\n" + 
+			"        return new ZipFile(\"bla.jar\");\n" + 
+			"    }\n" + 
+			"}"
+		},
+		options);
+}
+public void testBug552521() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // uses try-with-resources
+
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+	runLeakTest(
+		new String[] {
+			"EclipseBug552521getChannel.java",
+			"import java.io.File;\n" + 
+			"import java.io.FileInputStream;\n" + 
+			"import java.io.FileOutputStream;\n" + 
+			"import java.nio.channels.FileChannel;\n" + 
+			"\n" + 
+			"public class EclipseBug552521getChannel {\n" + 
+			"\n" + 
+			"	@SuppressWarnings(\"unused\")\n" + 
+			"	public void copyFile(final File srcFile, final File dstFile) throws Exception {\n" + 
+			"		/*\n" + 
+			"		 * TODO Eclipse Setting: Window/Preferences/Java/Compiler/Errors-Warnings/\n" + 
+			"		 * Resource not managed via try-with-resource = Ignore (default)\n" + 
+			"		 */\n" + 
+			"        try (\n" + 
+			"        		final FileInputStream srcStream  = new FileInputStream (srcFile);\n" + 
+			"        		final FileChannel     srcChannel =                      srcStream.getChannel();\n" + 
+			"				final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 17
+			"        		//                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  TODO Warning ok\n" + 
+			"        		)\n" + 
+			"        {\n" + 
+			"    		srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        if (srcFile.isFile()) { // \"if\" (resolved at runtime) -> Warning suppressed\n" + 
+			"            try (\n" + 
+			"            		final FileInputStream srcStream  = new FileInputStream (srcFile);\n" + 
+			"            		final FileChannel     srcChannel =                      srcStream.getChannel();\n" + 
+			"    				final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 28
+			"            		//                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  FIXME Warning missing!\n" + 
+			"            		)\n" + 
+			"            {\n" + 
+			"        		srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" + 
+			"            }\n" + 
+			"        } else { // \"else\" (resolved at runtime) -> Warning suppressed\n" + 
+			"            try (\n" + 
+			"            		final FileInputStream srcStream  = new FileInputStream (srcFile);\n" + 
+			"            		final FileChannel     srcChannel =                      srcStream.getChannel();\n" + 
+			"    				final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 38
+			"            		//                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  FIXME Warning missing!\n" + 
+			"            		)\n" + 
+			"            {\n" + 
+			"        		srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" + 
+			"            }\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        if (true) { // Dummy \"if\" (= constant true) -> Warning\n" + 
+			"            try (\n" + 
+			"            		final FileInputStream srcStream  = new FileInputStream (srcFile);\n" + 
+			"            		final FileChannel     srcChannel =                      srcStream.getChannel();\n" + 
+			"    				final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 50
+			"            		//                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  TODO Warning ok\n" + 
+			"            		)\n" + 
+			"            {\n" + 
+			"        		srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" + 
+			"            }\n" + 
+			"        } else { // Dummy \"else\" (= constant false) -> Warning suppressed\n" + 
+			"            try (\n" + 
+			"            		final FileInputStream srcStream  = new FileInputStream (srcFile);\n" + 
+			"            		final FileChannel     srcChannel =                      srcStream.getChannel();\n" + 
+			"    				final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 60
+			"            		//                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  FIXME Warning missing!\n" + 
+			"            		)\n" + 
+			"            {\n" + 
+			"        		srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" + 
+			"            }\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        if (false) { // Dummy \"if\" (= constant false) -> Warning suppressed\n" + 
+			"            try (\n" + 
+			"            		final FileInputStream srcStream  = new FileInputStream (srcFile);\n" + 
+			"            		final FileChannel     srcChannel =                      srcStream.getChannel();\n" + 
+			"    				final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 72
+			"            		//                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  FIXME Warning missing!\n" + 
+			"            		)\n" + 
+			"            {\n" + 
+			"        		srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" + 
+			"            }\n" + 
+			"        } else { // Dummy \"else\" (= constant true) -> Warning\n" + 
+			"            try (\n" + 
+			"            		final FileInputStream srcStream  = new FileInputStream (srcFile);\n" + 
+			"            		final FileChannel     srcChannel =                      srcStream.getChannel();\n" + 
+			"    				final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 82
+			"            		//                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  TODO Warning ok\n" + 
+			"            		)\n" + 
+			"            {\n" + 
+			"        		srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" + 
+			"            }\n" + 
+			"        }\n" + 
+			"        /*\n" + 
+			"         * Following test-case differs from all the above as follows:\n" + 
+			"         * FileInputStream is unassigned, instead of FileOutputStream\n" + 
+			"         */\n" + 
+			"        try (\n" + 
+			"        		final FileChannel      srcChannel = new FileInputStream (srcFile) .getChannel();\n" + // line 94
+			"        		//                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  TODO Warning ok\n" + 
+			"        		final FileOutputStream dstStream  = new FileOutputStream(srcFile);\n" + 
+			"				final FileChannel      dstChannel =                      dstStream.getChannel();\n" + 
+			"        		)\n" + 
+			"        {\n" + 
+			"    		srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" + 
+			"        }\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in EclipseBug552521getChannel.java (at line 17)\n" + 
+		"	final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + 
+		"	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"2. ERROR in EclipseBug552521getChannel.java (at line 28)\n" + 
+		"	final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + 
+		"	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"3. ERROR in EclipseBug552521getChannel.java (at line 38)\n" + 
+		"	final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + 
+		"	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"4. ERROR in EclipseBug552521getChannel.java (at line 50)\n" + 
+		"	final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + 
+		"	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"5. ERROR in EclipseBug552521getChannel.java (at line 60)\n" + 
+		"	final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + 
+		"	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"6. ERROR in EclipseBug552521getChannel.java (at line 72)\n" + 
+		"	final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + 
+		"	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"7. ERROR in EclipseBug552521getChannel.java (at line 82)\n" + 
+		"	final FileChannel     dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + 
+		"	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"8. ERROR in EclipseBug552521getChannel.java (at line 94)\n" + 
+		"	final FileChannel      srcChannel = new FileInputStream (srcFile) .getChannel();\n" + 
+		"	                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n",
+		options);
+}
+public void testBug552521_comment14() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses foreach
+
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	runLeakTest(
+		new String[] {
+			"X.java",
+			"import java.io.*;\n" +
+			"import java.util.*;\n" +
+			"public class X {\n" +
+			"	List<String> process(InputStream is) throws IOException {\n" +
+			"		is.close();\n" +
+			"		return Collections.emptyList();\n" +
+			"	}\n" +
+			"	void test(String fileName) throws IOException {\n" +
+			"		for (String string : process(new FileInputStream(fileName))) {\n" + 
+			"			System.out.println(string);\n" + 
+			"		}\n" +
+			"	}\n" +
+			"	void test2(String fileName) throws IOException {\n" +
+			"		for (String string : process(new FileInputStream(fileName)))\n" + 
+			"			System.out.println(string);\n" + 
+			"	}\n" +
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in X.java (at line 9)\n" + 
+		"	for (String string : process(new FileInputStream(fileName))) {\n" + 
+		"	                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + 
+		"----------\n" + 
+		"2. ERROR in X.java (at line 14)\n" + 
+		"	for (String string : process(new FileInputStream(fileName)))\n" + 
+		"	                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + 
+		"----------\n",
+		options);
+}
+public void testBug552521_comment14b() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses foreach
+
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	runLeakTest(
+		new String[] {
+			"X.java",
+			"import java.io.*;\n" +
+			"public class X {\n" +
+			"	boolean check(InputStream is) throws IOException {\n" +
+			"		is.close();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	void test1(String fileName) throws IOException {\n" +
+			"		while (check(new FileInputStream(fileName)))\n" + 
+			"			System.out.println(\"while\");\n" + 
+			"	}\n" +
+			"	void test2(String fileName) throws IOException {\n" +
+			"		do {\n" +
+			"			System.out.println(\"while\");\n" + 
+			"		} while (check(new FileInputStream(fileName)));\n" + 
+			"	}\n" +
+			"	void test3(String fileName) throws IOException {\n" +
+			"		for (int i=0;check(new FileInputStream(fileName));i++)\n" + 
+			"			System.out.println(i);\n" + 
+			"	}\n" +
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in X.java (at line 8)\n" + 
+		"	while (check(new FileInputStream(fileName)))\n" + 
+		"	             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + 
+		"----------\n" + 
+		"2. ERROR in X.java (at line 14)\n" + 
+		"	} while (check(new FileInputStream(fileName)));\n" + 
+		"	               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + 
+		"----------\n" + 
+		"3. ERROR in X.java (at line 17)\n" + 
+		"	for (int i=0;check(new FileInputStream(fileName));i++)\n" + 
+		"	                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + 
+		"----------\n",
+		options);
+}
+public void testBug519740() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // uses try-with-resources
+
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"Snippet.java",
+			"class Snippet {\n" + 
+			"  static void foo() throws Exception {\n" + 
+			"    try (java.util.Scanner scanner = new java.util.Scanner(new java.io.FileInputStream(\"abc\"))) {\n" + 
+			"      while (scanner.hasNext()) \n" + 
+			"        if (scanner.hasNextInt())\n" + 
+			"          throw new RuntimeException();  /* Potential resource leak: 'scanner' may not be closed at this location */\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug552441() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // uses try-with-resources
+
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"import java.io.BufferedOutputStream;\n" + 
+			"import java.io.FileOutputStream;\n" + 
+			"import java.io.IOException;\n" + 
+			"import java.io.OutputStream;\n" + 
+			"import java.util.concurrent.atomic.AtomicLong;\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"    public static class CountingBufferedOutputStream extends BufferedOutputStream {\n" + 
+			"        private final AtomicLong bytesWritten;\n" + 
+			"\n" + 
+			"        public CountingBufferedOutputStream(OutputStream out, AtomicLong bytesWritten) throws IOException {\n" + 
+			"            super(out);\n" + 
+			"            this.bytesWritten = bytesWritten;\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        @Override\n" + 
+			"        public void write(byte[] b) throws IOException {\n" + 
+			"            super.write(b);\n" + 
+			"            bytesWritten.addAndGet(b.length);\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        @Override\n" + 
+			"        public void write(byte[] b, int off, int len) throws IOException {\n" + 
+			"            super.write(b, off, len);\n" + 
+			"            bytesWritten.addAndGet(len);\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        @Override\n" + 
+			"        public synchronized void write(int b) throws IOException {\n" + 
+			"            super.write(b);\n" + 
+			"            bytesWritten.incrementAndGet();\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"\n" + 
+			"    public static void test(String[] args) throws IOException {\n" + 
+			"        AtomicLong uncompressedBytesOut = new AtomicLong();\n" + 
+			"        int val = 0;\n" + 
+			"        try (CountingBufferedOutputStream out = new CountingBufferedOutputStream(\n" + 
+			"                new FileOutputStream(\"outputfile\"), uncompressedBytesOut)) {\n" + 
+			"\n" + 
+			"            for (int i = 0; i < 1; i++) {\n" + 
+			"                if (val > 2) {\n" + 
+			"                    throw new RuntimeException(\"X\");\n" + 
+			"                }\n" + 
+			"            }\n" + 
+			"            if (val > 2) {\n" + 
+			"                throw new RuntimeException(\"Y\");\n" + 
+			"            }\n" + 
+			"            throw new RuntimeException(\"Z\");\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug400523() {
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+
+	runConformTest(
+		new String[] {
+			"LeakWarning.java",
+			"import java.sql.Connection;\n" + 
+			"import java.sql.PreparedStatement;\n" + 
+			"import java.sql.ResultSet;\n" + 
+			"import java.sql.SQLException;\n" + 
+			"\n" + 
+			"public class LeakWarning {\n" + 
+			"	String value = null;\n" + 
+			"	\n" + 
+			"    public void setValue(Connection conn)\n" + 
+			"	{        \n" + 
+			"        PreparedStatement stmt = null;\n" + 
+			"        ResultSet rs = null;\n" + 
+			"        try {            \n" + 
+			"            stmt = conn.prepareStatement(\"SELECT 'value'\");  /* marked as potential resource leak */\n" + 
+			"            rs = stmt.executeQuery();                        /* marked as potential resource leak */\n" + 
+			"            if (rs.next()) value = rs.getString(1);\n" + 
+			"        } catch(SQLException e) {\n" + 
+			"        }\n" + 
+			"        finally {\n" + 
+			"        	if (null != rs)   try { rs.close();   } catch (SQLException e) {} finally { rs = null;   }\n" + 
+			"        	if (null != stmt) try { stmt.close(); } catch (SQLException e) {} finally { stmt = null; }\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"    \n" + 
+			"    public void setValueReturn(Connection conn)\n" + 
+			"	{        \n" + 
+			"        PreparedStatement stmt = null;\n" + 
+			"        ResultSet rs = null;\n" + 
+			"        try {            \n" + 
+			"            stmt = conn.prepareStatement(\"SELECT 'value'\");\n" + 
+			"            rs = stmt.executeQuery();\n" + 
+			"            if (rs.next()) value = rs.getString(1);\n" + 
+			"        } catch(SQLException e) {\n" + 
+			"        }\n" + 
+			"        finally {\n" + 
+			"        	if (null != rs)   try { rs.close();   } catch (SQLException e) {} finally { rs = null;   }\n" + 
+			"        	if (null != stmt) try { stmt.close(); } catch (SQLException e) {} finally { stmt = null; }\n" + 
+			"        }\n" + 
+			"        return; /* no warning now */\n" + 
+			"    }\n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug527761() {
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"X.java",
+			"class BAOSWrapper extends java.io.ByteArrayOutputStream {}\n" +
+			"public class X {\n" +
+			"	public static void warningCauser() {\n" + 
+			"		BAOSWrapper baos = new BAOSWrapper();\n" + 
+			"		//WARNING HAS BEEN CAUSED\n" + 
+			"		baos.write(0);\n" + 
+			"	}\n" +
+			"}\n"
+		},
+		options);
+}
+public void testBug527761_otherClose() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses generics
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	String xSource =
+			"public class X {\n" +
+			"	public static void warningCauser() {\n" + 
+			"		BAOSWrapper<String> baos = new BAOSWrapper<String>();\n" + 
+			"		//WARNING HAS BEEN CAUSED\n" + 
+			"		baos.write(0);\n" + 
+			"	}\n" +
+			"}\n";
+	runConformTest(
+		new String[] {
+			"BAOSWrapper.java",
+			"class BAOSWrapper<T> extends java.io.ByteArrayOutputStream {\n" +
+			"	public void close(java.util.List<?> l) {}\n" + // not relevant, param challenges treatment of unresolved types
+			"}\n",
+			"X.java",
+			xSource
+		},
+		options);
+	// consume BAOSWrapper from .class:
+	runConformTest(false,
+			new String[] { "X.java", xSource },
+			"", "", "", null);
+}
+public void testBug527761_neg() {
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	runLeakTest(
+		new String[] {
+			"X.java",
+			"class BAOSWrapper extends java.io.ByteArrayOutputStream {\n" +
+			"	public void close() {}\n" + // indicates that resource could be relevant
+			"}\n" +
+			"public class X {\n" +
+			"	public static void warningCauser() {\n" + 
+			"		BAOSWrapper baos = new BAOSWrapper();\n" + 
+			"		//WARNING HAS BEEN CAUSED\n" + 
+			"		baos.write(0);\n" + 
+			"	}\n" +
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in X.java (at line 6)\n" + 
+		"	BAOSWrapper baos = new BAOSWrapper();\n" + 
+		"	            ^^^^\n" + 
+		"Resource leak: \'baos\' is never closed\n" + 
+		"----------\n",
+		options);
+}
+// regression caused by Bug 527761
+public void testBug558759() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses generics
+	Map options = getCompilerOptions(); 
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	String ySource =
+		"public class Y {\n" +
+		"	class YInner extends X<I> {}\n" +
+		"}\n";
+	runConformTest(
+		new String[] {
+			"I.java",
+			"import java.io.Closeable;\n" +
+			"public interface I extends Closeable {\n" +
+			"	interface Location {}\n" +
+			"	void m(Location l);\n" +
+			"}\n",
+			"X0.java",
+			"public abstract class X0<T extends I> implements I {\n" +
+			"	public void close() {}\n" +
+			"}\n",
+			"X.java",
+			"public class X<T extends I> extends X0<T> implements I {\n" +
+			"	public void m(Location l) {}\n" +
+			"}\n",
+			"Y.java",
+			ySource
+		},
+		options);
+	runConformTest(false,
+			new String[] { "Y.java", ySource },
+			"", "", "", null);
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
index ce9e6cf..ed924e0 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
@@ -8830,4 +8830,35 @@
             },
 			"SUCCESS");
 	}
+	public void test558844() {
+		this.runConformTest(
+            new String[] {
+        		"X.java",
+        		"public class X {\n" + 
+        		"	\n" + 
+        		"	public static void main( String[] args ) {\n" + 
+        		"		System.out.println(new X().getText());\n" + 
+        		"	}\n" + 
+        		"\n" + 
+        		"	public String getText() {\n" + 
+        		"		Long lValue1 = getValue1();\n" + 
+        		"		Long lValue2 = getValue2();\n" + 
+        		"		return ( isValue1() ? \"\" : ( lValue1 == null ? \"\" : lValue1.toString() ) + \"-\" ) + ( lValue2 == null ? \"\" : lValue2.toString() );\n" + 
+        		"	}\n" + 
+        		"\n" + 
+        		"	private Long getValue1() {\n" + 
+        		"		return Long.valueOf( 1 );\n" + 
+        		"	}\n" + 
+        		"\n" + 
+        		"	private Long getValue2() {\n" + 
+        		"		return Long.valueOf( 1 );\n" + 
+        		"	}\n" + 
+        		"\n" + 
+        		"	private boolean isValue1() {\n" + 
+        		"		return false;\n" + 
+        		"	}\n" + 
+        		"}",
+            },
+			"1-1");
+	}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java
index 5aac8b3..0fb0606 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java
@@ -21,6 +21,7 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.Writer;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
@@ -84,6 +85,13 @@
 		parser.setUnitName(unitName);
 		return parser.createAST(null);
 	}
+	protected File createFile(File dir, String fileName, String contents) throws IOException {
+		File file = new File(dir, fileName);
+		try (Writer writer = new BufferedWriter(new FileWriter(file))) {
+			writer.write(contents);
+		}
+		return file;
+	}
 	public void testBug529654_001() {
 		String contents =
 				"module m {\n" + 
@@ -1825,5 +1833,53 @@
 		SwitchExpression se = (SwitchExpression) fragment.getInitializer();
 		YieldStatement yieldStatement = (YieldStatement) ((Block)se.statements().get(1)).statements().get(0);
 		assertNotNull("Expression null", yieldStatement.getExpression());
-	}	
+	}
+	public void testBug558517() throws IOException {
+		File f1 = null, f2 = null, packDir = null;
+		try {
+			File rootDir = new File(System.getProperty("java.io.tmpdir"));
+			packDir = new File(rootDir, "P/src/x");
+			packDir.mkdirs();
+
+			String fileName1 = "EnsureImpl$1.java";
+			String fileName2 = "C9947f.java";
+			f1 = createFile(
+					packDir, fileName1,
+					"package x;\n" + 
+					"\n" + 
+					"class EnsureImpl$1 {\n" + 
+					"}\n");
+			f2 = createFile(
+					packDir, fileName2,
+					"package x;\n" + 
+					"public final class C9947f {\n" + 
+					"    public C9947f() {\n" + 
+					"        try {\n" + 
+					"            new x.EnsureImpl$1();\n" + 
+					"        } catch (Throwable unused) {\n" + 
+					"        }\n" + 
+					"    }\n" + 
+					"}\n");
+			ASTParser parser = ASTParser.newParser(AST_JLS_LATEST);
+			parser.setResolveBindings(true);
+			Map<String, String> options = new HashMap<>();
+			JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
+			parser.setCompilerOptions(options );
+			parser.setEnvironment(null,
+					new String[] { rootDir + "/P/src" },
+					null,
+					true);
+			parser.createASTs(new String[] { packDir + "/" + fileName1, packDir + "/" + fileName2 },
+					null,
+					new String[] { "Lx/C9947f;" },
+					new FileASTRequestor() {
+					},
+					null);
+			// just ensure the above doesn't throw NPE
+		} finally {
+			f1.delete();
+			f2.delete();
+			packDir.delete();
+		}
+	}
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
index 7aad03c..e6a93d4 100644
--- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core.tests.model;singleton:=true
-Bundle-Version: 3.10.1000.qualifier
+Bundle-Version: 3.10.1100.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.core.tests,
diff --git a/org.eclipse.jdt.core.tests.model/pom.xml b/org.eclipse.jdt.core.tests.model/pom.xml
index 471dcd0..986a7a6 100644
--- a/org.eclipse.jdt.core.tests.model/pom.xml
+++ b/org.eclipse.jdt.core.tests.model/pom.xml
@@ -15,12 +15,12 @@
   <parent>
     <artifactId>tests-pom</artifactId>
     <groupId>eclipse.jdt.core</groupId>
-    <version>4.14.0-SNAPSHOT</version>
+    <version>4.15.0-SNAPSHOT</version>
     <relativePath>../tests-pom/</relativePath>
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.core.tests.model</artifactId>
-  <version>3.10.1000-SNAPSHOT</version>
+  <version>3.10.1100-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
index 3296f5a..26bab5a 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
@@ -1745,8 +1745,8 @@
 		"public class Test {\n" + 
 		"\n" + 
 		"int foo() {\n" + 
-		"		return 0;\n" + 
-		"	}\n" + 
+		"	return 0;\n" + 
+		"}\n" + 
 		"void bar(){}\n" + 
 		"}\n"
 	);
@@ -1765,8 +1765,8 @@
 		"public class Test {\n" + 
 		"\n" + 
 		"int foo() {\n" + 
-		"		return 0;\n" + 
-		"	}\n" + 
+		"	return 0;\n" + 
+		"}\n" + 
 		"void bar(){}\n" + 
 		"}\n"
 	);
@@ -13055,4 +13055,34 @@
 		"	}\n" + 
 		"}");
 }
+/**
+ * https://bugs.eclipse.org/558421 [formatter] Generate getter/setter creates unnecessary blank line
+ */
+public void testBug() {
+	this.formatterPrefs.blank_lines_after_last_class_body_declaration = 1;
+	String source =
+		"public int getA() {\n" + 
+		"	return a;\n" + 
+		"}";
+	formatSource(source, source, CodeFormatter.K_CLASS_BODY_DECLARATIONS);
+}
+/**
+ * https://bugs.eclipse.org/250656 - [formatter] Formatting selection destroys correct indentation
+ */
+public void testBug250656() {
+	this.formatterPrefs.page_width = 50;
+	formatSource(
+		"class C {\n" + 
+		"	void f() {\n" + 
+		"		doSomething(aaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbb\n" + 
+		"[#				+ ccccccccccccccccccc);#]\n" + 
+		"	}\n" + 
+		"}",
+		"class C {\n" + 
+		"	void f() {\n" + 
+		"		doSomething(aaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbb\n" + 
+		"				+ ccccccccccccccccccc);\n" + 
+		"	}\n" + 
+		"}");
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java
index c913cd2..1c6de96 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java
@@ -1002,9 +1002,9 @@
 		"public class C {\n" +
 		"	\n" +
 		"        /**\n" +
-		"	 * a b c d .\n" +
-		"	 */\n" +
-		"	void m1  (   )   {\n" +
+		"		 * a b c d .\n" +
+		"		 */\n" +
+		"		void m1  (   )   {\n" +
 		"	\n" +
 		"        }     \n" +
 		"\n" +
@@ -1099,8 +1099,8 @@
 		"   public     class			C{    \n" +
 		"	\n" +
 		"        /**\n" +
-		"	 * a b c d .\n" +
-		"	 */\n" +
+		"		 * a b c d .\n" +
+		"		 */\n" +
 		"        void		m1  (   )   {\n" +
 		"	\n" +
 		"        }     \n" +
@@ -1195,9 +1195,9 @@
 		"public class D {\n" +
 		"	\n" +
 		"        /*\n" +
-		"	 * a b c d .\n" +
-		"	 */\n" +
-		"	void m2  (   )   {\n" +
+		"		 * a b c d .\n" +
+		"		 */\n" +
+		"		void m2  (   )   {\n" +
 		"	\n" +
 		"        }     \n" +
 		"\n" +
@@ -1292,8 +1292,8 @@
 		"   public     class			D{    \n" +
 		"	\n" +
 		"        /*\n" +
-		"	 * a b c d .\n" +
-		"	 */\n" +
+		"		 * a b c d .\n" +
+		"		 */\n" +
 		"        void		m2  (   )   {\n" +
 		"	\n" +
 		"        }     \n" +
@@ -1362,9 +1362,9 @@
 		"\n" +
 		"        void            m3()         { // this        is a bug\n" +
 		"\n" +
-		"	}\n" +
+		"		}\n" +
 		"\n" +
-		"}"
+		"	}"
 	);
 }
 public void testBug232768_Line04() throws JavaModelException {
@@ -1449,7 +1449,7 @@
 		"	\n" +
 		"\n" +
 		"        void            m3()         {     \n" +
-		"		// this is a bug\n" +
+		"			// this is a bug\n" +
 		"\n" +
 		"        }\n" +
 		"   \n" +
@@ -1567,11 +1567,11 @@
 		"\n" +
 		"public class E01 {\n" +
 		"        /**\n" +
-		"	 * Javadoc comment\n" +
-		"	 */\n" +
+		"		 * Javadoc comment\n" +
+		"		 */\n" +
 		"        /*\n" +
-		"	 * block comment\n" +
-		"	 */\n" +
+		"		 * block comment\n" +
+		"		 */\n" +
 		"        // single line comment\n" +
 		"}"
 	);
@@ -6042,7 +6042,7 @@
 		"			{\n" + 
 		"\n" + 
 		"\n" + 
-		"			return;\n" + 
+		"				return;\n" + 
 		"			}\n" + 
 		"		}\n" + 
 		"	}\n" + 
@@ -6072,7 +6072,7 @@
 		"			{\r\n" + 
 		"\r\n" + 
 		"\r\n" + 
-		"			return;\r\n" + 
+		"				return;\r\n" + 
 		"			}\r\n" + 
 		"		}\r\n" + 
 		"	}\r\n" + 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
index 4c83d91..f94c749 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
@@ -8689,6 +8689,31 @@
 			deleteProject("lib");
 		}
 	}
+
+	public void testBug558004() throws CoreException {
+		IJavaProject prj = createJava9Project("A");
+		try {
+			String moduleinfopath = "A/src/module-info.java";
+			String moduleinfosrc =
+				"/**\n" +
+				" * The {@link java.nio.file.FileSystems#newFileSystem FileSystems.newFileSystem(URI.create(\"jrt:/\"))}\n" +
+				" */\n" +
+				"module modulartest11 {\n" +
+				"}\n";
+			createFile(moduleinfopath, moduleinfosrc);
+			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+			assertNoErrors();
+			this.problemRequestor.initialize(moduleinfosrc.toCharArray());
+			getCompilationUnit("A/src/module-info.java").getWorkingCopy(this.wcOwner, null);
+			assertProblems("unexpected problems",
+					"----------\n" +
+					"----------\n",
+					this.problemRequestor);
+		} finally {
+			deleteProject(prj);
+		}
+	}
+
 	public void testBug547479() throws CoreException {
 		int max = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;
 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
index b36337b..0cf01c8 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2019 GK Software AG and others.
+ * Copyright (c) 2011, 2020 GK Software AG and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -1094,4 +1094,46 @@
 		IAnnotationBinding[] annotations = typeBinding.getAnnotations();
 		assertEquals(0, annotations.length);
 	}
+	public void testBug479389() throws CoreException, IOException {
+		IJavaProject project = null;
+		try {
+			project = createJavaProject("Bug479389", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin", "1.8");
+			project.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+			
+			createFolder("Bug479389/src/nullAnalysis");
+			String testSource =
+					"package nullAnalysis;\n" + 
+					"interface MyList<T> {\n" +
+					"	public Stream<T> stream();\n" +
+					"}\n" +
+					"interface Stream<T> {\n" +
+					"	T[] toArray(IntFunction<T[]> supplier);" +
+					"}\n" +
+					"interface IntFunction<T> {\n" +
+					"	T apply(int i);\n" +
+					"}\n" + 
+					"public class X {\n" + 
+					"\n" + 
+					"	public String[] method(MyList<String> in) {\n" + 
+					"		return in.stream().toArray(String[]::new);\n" + 
+					"	}\n" + 
+					"}\n";
+			String testSourcePath = "Bug479389/src/nullAnalysis/X.java";
+			createFile(testSourcePath, testSource);
+			char[] testSourceChars = testSource.toCharArray();
+			this.problemRequestor.initialize(testSourceChars);
+
+			getCompilationUnit(testSourcePath).getWorkingCopy(this.wcOwner, null);
+			assertProblems(
+					"Unexpected problems",
+					"----------\n" + 
+					"1. ERROR in /Bug479389/src/nullAnalysis/X.java (at line 13)\n" + 
+					"	return in.stream().toArray(String[]::new);\n" + 
+					"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+					"Annotation type \'org.eclipse.jdt.annotation.NonNull\' cannot be found on the build path, which is implicitly needed for null analysis\n" + 
+					"----------\n"					);
+		} finally {
+			deleteProject(project);
+		}
+	}
 }
diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
deleted file mode 100644
index f5f3fac..0000000
--- a/org.eclipse.jdt.core/.settings/.api_filters
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.jdt.core" version="2">
-    <resource path="compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java" type="org.eclipse.jdt.core.compiler.CategorizedProblem">
-        <filter comment="PREVIEW RELATED" id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.compiler.CategorizedProblem"/>
-                <message_argument value="CAT_PREVIEW_RELATED"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="compiler/org/eclipse/jdt/core/compiler/IProblem.java" type="org.eclipse.jdt.core.compiler.IProblem">
-        <filter comment="BETA_JAVA13 addition of preview related base" id="388194388">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.compiler.IProblem"/>
-                <message_argument value="IgnoreCategoriesMask"/>
-                <message_argument value="4194303"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="dom/org/eclipse/jdt/core/dom/ASTVisitor.java" type="org.eclipse.jdt.core.dom.ASTVisitor">
-        <filter comment="Not required as it is a part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.ASTVisitor"/>
-                <message_argument value="visit(SwitchExpression)"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="dom/org/eclipse/jdt/core/dom/BreakStatement.java" type="org.eclipse.jdt.core.dom.BreakStatement">
-        <filter comment="No more an API as part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.BreakStatement"/>
-                <message_argument value="getExpression()"/>
-            </message_arguments>
-        </filter>
-        <filter comment="No more an API as part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.BreakStatement"/>
-                <message_argument value="isImplicit()"/>
-            </message_arguments>
-        </filter>
-        <filter comment="preview feature - transient" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.BreakStatement"/>
-                <message_argument value="propertyDescriptors(int, boolean)"/>
-            </message_arguments>
-        </filter>
-        <filter comment="Not valid for Java 13" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.BreakStatement"/>
-                <message_argument value="setExpression(Expression)"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="dom/org/eclipse/jdt/core/dom/SwitchCase.java" type="org.eclipse.jdt.core.dom.SwitchCase">
-        <filter comment="No more an API as part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.SwitchCase"/>
-                <message_argument value="expressions()"/>
-            </message_arguments>
-        </filter>
-        <filter comment="No more an API as part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.SwitchCase"/>
-                <message_argument value="isSwitchLabeledRule()"/>
-            </message_arguments>
-        </filter>
-        <filter comment="No more an API as part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.SwitchCase"/>
-                <message_argument value="setSwitchLabeledRule(boolean)"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="dom/org/eclipse/jdt/core/dom/SwitchExpression.java" type="org.eclipse.jdt.core.dom.SwitchExpression">
-        <filter comment="No more an API as part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.SwitchExpression"/>
-                <message_argument value="getExpression()"/>
-            </message_arguments>
-        </filter>
-        <filter comment="No more an API as part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.SwitchExpression"/>
-                <message_argument value="propertyDescriptors(int)"/>
-            </message_arguments>
-        </filter>
-        <filter comment="preview feature - transient" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.SwitchExpression"/>
-                <message_argument value="propertyDescriptors(int, boolean)"/>
-            </message_arguments>
-        </filter>
-        <filter comment="No more an API as part of preview feature" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.SwitchExpression"/>
-                <message_argument value="setExpression(Expression)"/>
-            </message_arguments>
-        </filter>
-        <filter comment="Only for Java 13" id="338944126">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.dom.SwitchExpression"/>
-                <message_argument value="statements()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-</component>
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index 6c317c4..ea4fc8e 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
-Bundle-Version: 3.20.0.OTDT_r276_qualifier
+Bundle-Version: 3.21.0.OTDT_r276_qualifier
 Bundle-Activator: org.eclipse.jdt.core.JavaCore
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
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 b0bd5c0..1a4d44d 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -1838,6 +1838,8 @@
 	int RedundantNullCheckOnConstNonNullField = Internal + 944;
 	/** @since 3.20 */
 	int ConstNonNullFieldComparisonYieldsFalse = Internal + 945;
+	/** @since 3.21 */
+	int InheritedParameterLackingNonNullAnnotation = MethodRelated + 946;
 
 	/** @since 3.10 */
 	int ArrayReferencePotentialNullReference = Internal + 951;
@@ -1901,6 +1903,8 @@
 	int NonNullTypeVariableFromLegacyMethod = TypeRelated + 980;
 	/** @since 3.12 */
 	int NonNullMethodTypeVariableFromLegacyMethod = TypeRelated + 981;
+	/** @since 3.21 */
+	int MissingNullAnnotationImplicitlyUsed = Internal + 982;
 
 
 	// Java 8 work
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 80c0575..32dfb67 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -6110,24 +6110,33 @@
 
 	private TypeBinding getNewTypeBinding(char[] typeConstantPoolName, Scope scope) {
 		char[] typeName = typeConstantPoolName;
+		if (this.innerClassesBindings != null && isLikelyLocalTypeName(typeName)) {
+			// find local type in innerClassesBindings:
+			Set<TypeBinding> innerTypeBindings = this.innerClassesBindings.keySet();
+			for (TypeBinding binding : innerTypeBindings) {
+				if (CharOperation.equals(binding.constantPoolName(), typeName))
+					return binding;
+			}
+		}
 		TypeBinding type = (TypeBinding) scope.getTypeOrPackage(CharOperation.splitOn('/', typeName));
 		if (!type.isValidBinding()) {
 			ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
 			if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0) {
 				type = problemReferenceBinding.closestMatch();
-			} else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
-				// check local inner types to see if this is a anonymous type
-				Set<TypeBinding> innerTypeBindings = this.innerClassesBindings.keySet();
-				for (TypeBinding binding : innerTypeBindings) {
-					if (CharOperation.equals(binding.constantPoolName(), typeName)) {
-						type = binding;
-						break;
-					}
-				}
 			}
 		}
 		return type;
 	}
+	
+	private boolean isLikelyLocalTypeName(char[] typeName) {
+		int dollarPos = CharOperation.lastIndexOf('$', typeName);
+		while (dollarPos != -1) {
+			if (Character.isDigit(typeName[dollarPos+1]))
+				return true; // name segment starts with a digit => likely a local type (but still "$0" etc. could be part of the source name)
+			dollarPos = CharOperation.lastIndexOf('$', typeName, 0, dollarPos-1);
+		}
+		return false;
+	}
 
 	private TypeBinding getANewArrayTypeBinding(char[] typeConstantPoolName, Scope scope) {
 		if (typeConstantPoolName[0] == '[') {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
index 5736ac4..cd4d6c5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -81,6 +81,7 @@
 	private static final int REPORTED_DEFINITIVE_LEAK = 64;
 	// a local declarations that acts as the element variable of a foreach loop (should never suggest to use t-w-r):
 	private static final int FOREACH_ELEMENT_VAR = 128;
+	public MessageSend acquisition;
 
 	public static boolean TEST_372319 = false; // see https://bugs.eclipse.org/372319
 
@@ -215,7 +216,10 @@
 		} else if (expression instanceof AllocationExpression) {
 			// return any preliminary tracking variable from analyseCloseableAllocation 
 			return ((AllocationExpression) expression).closeTracker;
-		}		
+		} else if (expression instanceof MessageSend) {
+			// return any preliminary tracking variable from analyseCloseableAcquisition
+			return ((MessageSend) expression).closeTracker;
+		}
 		return null;
 	}
 
@@ -231,7 +235,7 @@
 	 * @param rhs the rhs of the assignment resp. the initialization of the local variable declaration.
 	 * 		<strong>Precondition:</strong> client has already checked that the resolved type of this expression is either a closeable type or NULL.
 	 */
-	public static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, Expression rhs, FlowInfo flowInfo) {
+	public static FakedTrackingVariable preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, Expression rhs, FlowInfo flowInfo) {
 		FakedTrackingVariable closeTracker = null;
 		if (containsAllocation(rhs)) {
 			closeTracker = local.closeTracker;
@@ -247,7 +251,18 @@
 				closeTracker.currentAssignment = location;
 				preConnectTrackerAcrossAssignment(location, local, flowInfo, closeTracker, rhs);
 			}
+		} else if (rhs instanceof MessageSend) {
+			closeTracker = local.closeTracker;
+			if (closeTracker != null) {
+				handleReassignment(flowInfo, closeTracker, location);
+			} 
+			if (rhs.resolvedType != TypeBinding.NULL) { // not NULL means valid closeable as per method precondition
+				closeTracker = new FakedTrackingVariable(local, location, flowInfo, null, FlowInfo.UNKNOWN);
+				closeTracker.currentAssignment = location;
+				((MessageSend) rhs).closeTracker = closeTracker;
+			}
 		}
+		return closeTracker;
 	}
 
 	private static boolean containsAllocation(SwitchExpression location) {
@@ -302,7 +317,9 @@
 		allocationExpression.closeTracker = closeTracker;
 		if (allocationExpression.arguments != null && allocationExpression.arguments.length > 0) {
 			// also push into nested allocations, see https://bugs.eclipse.org/368709
-			preConnectTrackerAcrossAssignment(location, local, allocationExpression.arguments[0], flowInfo);
+			FakedTrackingVariable inner = preConnectTrackerAcrossAssignment(location, local, allocationExpression.arguments[0], flowInfo);
+			if (inner != closeTracker && closeTracker.innerTracker == null)
+				closeTracker.innerTracker = inner;
 		}
 	}
 
@@ -382,6 +399,56 @@
 		}
 	}
 
+	/** 
+	 * Check if a message send acquires a closeable from its receiver, see:
+	 * Bug 463320 - [compiler][resource] potential "resource leak" problem disappears when local variable inlined
+	 */
+	public static FlowInfo analyseCloseableAcquisition(BlockScope scope, FlowInfo flowInfo, MessageSend acquisition) {
+		if (isFluentMethod(acquisition.binding)) {
+			// share the existing close tracker of the receiver (if any):
+			acquisition.closeTracker = findCloseTracker(scope, flowInfo, acquisition.receiver);
+			return flowInfo;
+		}
+		// client has checked that the resolvedType is an AutoCloseable, hence the following cast is safe:
+		if (((ReferenceBinding)acquisition.resolvedType).hasTypeBit(TypeIds.BitResourceFreeCloseable)) {
+			// remove unnecessary attempts (closeable is not relevant)
+			if (acquisition.closeTracker != null) {
+				acquisition.closeTracker.withdraw();
+				acquisition.closeTracker = null;
+			}
+			return flowInfo;
+		} else { // regular resource
+			FakedTrackingVariable tracker = acquisition.closeTracker;
+			if (tracker != null) {
+				// pre-connected tracker means: directly assigning the acquisition to a local, forget special treatment:
+				tracker.withdraw();
+				acquisition.closeTracker = null;
+				return flowInfo;
+			} else {
+				tracker = new FakedTrackingVariable(scope, acquisition, flowInfo, FlowInfo.UNKNOWN); // no local available, closeable is unassigned
+				acquisition.closeTracker = tracker;
+			}
+			tracker.acquisition = acquisition;
+			FlowInfo outsideInfo = flowInfo.copy();
+			outsideInfo.markAsDefinitelyNonNull(tracker.binding);
+			flowInfo.markAsDefinitelyNull(tracker.binding);
+			return FlowInfo.conditional(outsideInfo, flowInfo);
+		}
+	}
+
+	private static boolean isFluentMethod(MethodBinding binding) {
+		if (binding.isStatic())
+			return false;
+		ReferenceBinding declaringClass = binding.declaringClass;
+		if (declaringClass.equals(binding.returnType)) {
+			for (char[][] compoundName : TypeConstants.FLUENT_RESOURCE_CLASSES) {
+				if (CharOperation.equals(compoundName, declaringClass.compoundName))
+					return true;
+			}
+		}
+		return false;
+	}
+
 	private static FakedTrackingVariable pickMoreUnsafe(FakedTrackingVariable tracker1, FakedTrackingVariable tracker2, BlockScope scope, FlowInfo info) {
 		// whichever of the two trackers has stronger indication to be leaking will be returned,
 		// the other one will be removed from the scope (considered to be merged into the former).
@@ -404,18 +471,22 @@
 		if (presetTracker != null && presetTracker.originalBinding != null) {
 			// the current assignment forgets a previous resource in the LHS, may cause a leak
 			// report now because handleResourceAssignment can't distinguish this from a self-wrap situation
-			int closeStatus = flowInfo.nullStatus(presetTracker.binding);
-			if (closeStatus != FlowInfo.NON_NULL		// old resource was not closed
-					&& closeStatus != FlowInfo.UNKNOWN	// old resource had some flow information
-					&& !flowInfo.isDefinitelyNull(presetTracker.originalBinding)		// old resource was not null
-					&& !(presetTracker.currentAssignment instanceof LocalDeclaration))	// forgetting old val in local decl is syntactically impossible
-				allocation.closeTracker.recordErrorLocation(presetTracker.currentAssignment, closeStatus);
+			handleReassignment(flowInfo, presetTracker, presetTracker.currentAssignment);
 		} else {
 			allocation.closeTracker = new FakedTrackingVariable(scope, allocation, flowInfo, FlowInfo.UNKNOWN); // no local available, closeable is unassigned
 		}
 		flowInfo.markAsDefinitelyNull(allocation.closeTracker.binding);
 	}
 
+	private static void handleReassignment(FlowInfo flowInfo, FakedTrackingVariable existingTracker, ASTNode location) {
+		int closeStatus = flowInfo.nullStatus(existingTracker.binding);
+		if (closeStatus != FlowInfo.NON_NULL		// old resource was not closed
+				&& closeStatus != FlowInfo.UNKNOWN	// old resource had some flow information
+				&& !flowInfo.isDefinitelyNull(existingTracker.originalBinding)		// old resource was not null
+				&& !(location instanceof LocalDeclaration))	// forgetting old val in local decl is syntactically impossible
+			existingTracker.recordErrorLocation(location, closeStatus);
+	}
+
 	/** Find an existing tracking variable for the argument of an allocation for a resource wrapper. */
 	private static FakedTrackingVariable findCloseTracker(BlockScope scope, FlowInfo flowInfo, Expression arg)
 	{
@@ -438,6 +509,8 @@
 		} else if (arg instanceof AllocationExpression) {
 			// nested allocation
 			return ((AllocationExpression)arg).closeTracker;
+		} else if (arg instanceof MessageSend) {
+			return ((MessageSend) arg).closeTracker;
 		}
 		return null; // not a tracked expression
 	}
@@ -482,7 +555,7 @@
 						rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR);
 					}
 				} else {
-					if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression || rhs instanceof SwitchExpression) {
+					if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression || rhs instanceof SwitchExpression || rhs instanceof MessageSend) {
 						if (rhsTrackVar == disconnectedTracker)
 							return;									// 		b.: self wrapper: res = new Wrap(res); -> done!
 						if (local.closeTracker == rhsTrackVar 
@@ -645,6 +718,12 @@
 				tracker.withdraw();
 				((AllocationExpression) expression).closeTracker = null;
 			}
+		} else if (expression instanceof MessageSend) {
+			FakedTrackingVariable tracker = ((MessageSend) expression).closeTracker;
+			if (tracker != null && tracker.originalBinding == null) {
+				tracker.withdraw();
+				((MessageSend) expression).closeTracker = null;
+			}
 		} else {
 			// assignment passing a local into a field?
 			LocalVariableBinding local = expression.localVariableBinding();
@@ -714,8 +793,13 @@
 			if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
 				return FlowInfo.POTENTIALLY_NULL;	// non-null + doubt = pot null
 			return FlowInfo.NON_NULL;
-		} else if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
+		} else if ((status & FlowInfo.POTENTIALLY_NULL) != 0) {
 			return FlowInfo.POTENTIALLY_NULL;
+		} else if (status == FlowInfo.UNKNOWN) {
+			// if unassigned resource (not having an originalBinding) is not withdrawn it is unclosed:
+			if (this.originalBinding == null)
+				return FlowInfo.NULL;
+		}
 		return status;
 	}
 
@@ -775,7 +859,7 @@
 			if (owned) {
 				return infoResourceIsClosed; // don't let downstream signal any problems on this flow
 			} else {
-				return FlowInfo.conditional(flowInfo, infoResourceIsClosed); // only report potential problems on this flow
+				return FlowInfo.conditional(flowInfo, infoResourceIsClosed).unconditionalCopy(); // only report potential problems on this flow
 			}
 		}
 		return flowInfo;
@@ -1003,6 +1087,10 @@
 		if (isPotentialProblem) {
 			if ((this.globalClosingState & (REPORTED_POTENTIAL_LEAK|REPORTED_DEFINITIVE_LEAK)) != 0)
 				return 0;
+//			if ((this.globalClosingState & (ACQUIRED_FROM_OUTSIDE)) != 0 
+//					&& location instanceof ReturnStatement
+//					&& ((ReturnStatement) location).expression == this.acquisition)
+//				return 0; // directly returning a resource acquired from a message send: don't assume responsibility
 			problemReporter.potentiallyUnclosedCloseable(this, location);	
 		} else {
 			if ((this.globalClosingState & (REPORTED_DEFINITIVE_LEAK)) != 0)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
index 88a26f4..ff342dd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -238,6 +238,7 @@
 			}
 		}
 		this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+		this.scope.checkUnclosedCloseables(mergedInfo, loopingContext, null, null);
 		return mergedInfo;
 	}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index 57950da..9b18f38 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -144,11 +144,10 @@
 
 			if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
 				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy();
-				if (this.action instanceof Block) {
-					FakedTrackingVariable.markForeachElementVar(this.elementVariable);
-					// action.analyseCode() missed the following check due to identical scopes of ForeachStatement and Block:
-					this.scope.checkUnclosedCloseables(actionInfo, loopingContext, null, null);
-				}
+				FakedTrackingVariable.markForeachElementVar(this.elementVariable);
+				// action.analyseCode() missed the following check due to identical scopes of ForeachStatement and action:
+				FlowInfo actionNullInfo = condInfo.copy().addNullInfoFrom(actionInfo); // previously action did not see nullinfo from condInfo
+				this.scope.checkUnclosedCloseables(actionNullInfo, loopingContext, null, null);
 			}
 
 			// code generation can be optimized when no need to continue in the loop
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index 635ad28..8b957d7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -479,7 +479,8 @@
 					scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers);
 				}
 				else if (fieldRef.actualReceiverType != null) {
-					if (scope.enclosingSourceType().isCompatibleWith(fieldRef.actualReceiverType)) {
+					SourceTypeBinding stb = scope.enclosingSourceType();
+					if (stb != null && stb.isCompatibleWith(fieldRef.actualReceiverType)) {
 						fieldRef.bits |= ASTNode.SuperAccess;
 					}
 					ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.actualReceiverType;
@@ -1020,8 +1021,9 @@
 
 				ClassScope topLevelScope = scope.classScope();
 				// when scope is not on compilation unit type, then inner class may not be visible...
-				if (topLevelScope.parent.kind != Scope.COMPILATION_UNIT_SCOPE ||
-					!CharOperation.equals(topLevelType.sourceName, topLevelScope.referenceContext.name)) {
+				if (topLevelScope != null &&
+					(topLevelScope.parent.kind != Scope.COMPILATION_UNIT_SCOPE ||
+					!CharOperation.equals(topLevelType.sourceName, topLevelScope.referenceContext.name))) {
 					topLevelScope = topLevelScope.outerMostClassScope();
 					if (typeReference instanceof JavadocSingleTypeReference) {
 						// inner class single reference can only be done in same unit
@@ -1070,7 +1072,7 @@
 					// partially qualified references from a different CU should be warned
 					char[][] typeRefName = ((JavadocQualifiedTypeReference) typeReference).getTypeName();
 					int skipLength = 0;
-					if (topLevelScope.getCurrentPackage() == resolvedType.getPackage()
+					if (topLevelScope != null && topLevelScope.getCurrentPackage() == resolvedType.getPackage()
 							&& typeRefName.length < computedCompoundName.length) {
 						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=221539: references can be partially qualified
 						// in same package and hence if the package name is not given, ignore package name check
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 6d26fa3..b9a231f 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
@@ -217,6 +217,7 @@
 	public TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
 	public boolean argumentsHaveErrors = false;
 	
+	public FakedTrackingVariable closeTracker;
 
 //{ObjectTeams:
 	private boolean isDecapsulation = false;
@@ -324,6 +325,10 @@
 		//               checkExceptionHandlers; consider protecting there instead of here;
 		//               NullReferenceTest#test0510
 	}
+	// after having analysed exceptions above start tracking newly allocated resource:
+	if (analyseResources && FakedTrackingVariable.isAnyCloseable(this.resolvedType))
+		flowInfo = FakedTrackingVariable.analyseCloseableAcquisition(currentScope, flowInfo, this);
+
 	manageSyntheticAccessIfNecessary(currentScope, flowInfo);
 //{ObjectTeams: base calls via super:
 	flowInfo = checkBaseCallsIfSuper(currentScope, flowInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index cfa3925..dc687c5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -287,9 +287,11 @@
 				if (TypeBinding.notEquals(this.binding.declaringClass, this.lhs.resolvedType.erasure())) {
 					// reference to a method declared by an inaccessible type accessed via a
 					// subtype - normally a bridge method would be present to facilitate
-					// this access, unless the method is final/static, in which case, direct access to
+					// this access, unless the method is final/static/default, in which case, direct access to
 					// the method is not possible, an implicit lambda is needed
 					if (!this.binding.declaringClass.canBeSeenBy(this.enclosingScope)) {
+						if (this.binding.isDefaultMethod())
+							return false; // workaround for bug in MethodHandle lookup, see https://bugs.openjdk.java.net/browse/JDK-8068253
 						return !(this.binding.isFinal() || this.binding.isStatic());
 					}
 				}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index aa65304..56afed0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -6271,12 +6271,12 @@
 	this.bCodeStream[this.classFileOffset++] = (byte) dimensions;
 }
 
-// We didn't call it new, because there is a conflit with the new keyword
+// We didn't call it new, because there is a conflict with the new keyword
 public void new_(TypeBinding typeBinding) {
 	this.new_(null, typeBinding);
 }
 
-// We didn't call it new, because there is a conflit with the new keyword
+// We didn't call it new, because there is a conflict with the new keyword
 public void new_(TypeReference typeReference, TypeBinding typeBinding) {
 	this.countLabels = 0;
 	this.stackDepth++;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java
index c2ef996..a0fc8e2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java
@@ -129,7 +129,7 @@
 		return result;
 	}
 
-	private VerificationTypeInfo getCachedValue(Map<VerificationTypeInfo, VerificationTypeInfo> cache, VerificationTypeInfo value) {
+	private static VerificationTypeInfo getCachedValue(Map<VerificationTypeInfo, VerificationTypeInfo> cache, VerificationTypeInfo value) {
 		VerificationTypeInfo cachedValue = value;
 		if (value != null) {
 			if (value.tag == VerificationTypeInfo.ITEM_UNINITIALIZED || value.tag == VerificationTypeInfo.ITEM_UNINITIALIZED_THIS) {
@@ -393,7 +393,7 @@
 		return 0;
 	}
 
-	private boolean equals(VerificationTypeInfo info, VerificationTypeInfo info2) {
+	private static boolean equals(VerificationTypeInfo info, VerificationTypeInfo info2) {
 		if (info == null) {
 			return info2 == null;
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java
index d3afd5b..7f3be5a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java
@@ -195,14 +195,16 @@
 	public boolean equals(Object obj) {
 		if (obj instanceof VerificationTypeInfo) {
 			VerificationTypeInfo info1 = (VerificationTypeInfo) obj;
-			return info1.tag == this.tag && CharOperation.equals(info1.constantPoolName(), constantPoolName());
+			return info1.tag == this.tag
+					&& info1.offset == this.offset
+					&& CharOperation.equals(info1.constantPoolName(), constantPoolName());
 		}
 		return false;
 	}
 
 	@Override
 	public int hashCode() {
-		return this.tag + this.id + this.binding.constantPoolName().length;
+		return this.tag + this.offset + CharOperation.hashCode(constantPoolName());
 	}
 
 	public char[] constantPoolName() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
index 700b96f..a78dbb7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -1952,11 +1952,9 @@
 		}
 		// refine null bits requirements
 		if (!otherHasNulls) {
-		  if (resetLimit < mergeLimit) {
-			resetLimit = mergeLimit;
-		  }
 		  copyLimit = 0; // no need to carry inexisting nulls
 		  mergeLimit = 0;
+		  resetLimit = 0;
 		}
 		if (!thisHadNulls) {
 		  resetLimit = 0; // no need to reset anything
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
index 1f2618b..aab7eac 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -97,7 +97,7 @@
 }
 
 private static AnnotationBinding buildMarkerAnnotationForMemberType(char[][] compoundName, ModuleBinding module, LookupEnvironment env) {
-	ReferenceBinding type = env.getResolvedType(compoundName, module, null);
+	ReferenceBinding type = env.getResolvedType(compoundName, module, null, false);
 	// since this is a member type name using '$' the return binding is a
 	// problem reference binding with reason ProblemReasons.InternalNameProvided
 	if (!type.isValidBinding()) {
@@ -107,7 +107,7 @@
 }
 
 private static AnnotationBinding buildMarkerAnnotation(char[][] compoundName, ModuleBinding module, LookupEnvironment env) {
-	ReferenceBinding type = env.getResolvedType(compoundName, module, null);
+	ReferenceBinding type = env.getResolvedType(compoundName, module, null, false);
 	return env.createAnnotation(type, Binding.NO_ELEMENT_VALUE_PAIRS);
 }
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 9e2aebf..17b2c09 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -2548,7 +2548,7 @@
 	}
 	this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits);
 	if ((this.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0) // avoid the side-effects of hasTypeBit()! 
-		this.typeBits |= applyCloseableClassWhitelists();
+		this.typeBits |= applyCloseableClassWhitelists(this.environment.globalOptions);
 	detectCircularHierarchy();
 	return this.superclass;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index 2c1023a..9d35871 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -1348,8 +1348,19 @@
 		int trackVarCount = this.trackingVariables.size();
 		for (int i=0; i<trackVarCount; i++) {
 			FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
-			if (trackingVar.originalBinding == null)
+			if (trackingVar.originalBinding == null) {
+				// avoid problem weakened to 'potential' if unassigned resource exists only in one branch:
+				boolean hasNullInfoInThen = thenFlowInfo.hasNullInfoFor(trackingVar.binding);
+				boolean hasNullInfoInElse = elseFlowInfo.hasNullInfoFor(trackingVar.binding);
+				if (hasNullInfoInThen && !hasNullInfoInElse) {
+					int nullStatus = thenFlowInfo.nullStatus(trackingVar.binding);
+					elseFlowInfo.markNullStatus(trackingVar.binding, nullStatus);
+				} else if (!hasNullInfoInThen && hasNullInfoInElse) {
+					int nullStatus = elseFlowInfo.nullStatus(trackingVar.binding);
+					thenFlowInfo.markNullStatus(trackingVar.binding, nullStatus);					
+				}
 				continue;
+			}
 			if (   thenFlowInfo.isDefinitelyNonNull(trackingVar.binding)			// closed in then branch
 				&& elseFlowInfo.isDefinitelyNull(trackingVar.originalBinding))		// null in else branch
 			{
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index 8c6353c..1b98ff1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -1649,7 +1649,7 @@
 				sourceType.typeBits |= (superclass.typeBits & TypeIds.InheritableBits);
 				// further analysis against white lists for the unlikely case we are compiling java.io.*:
 				if ((sourceType.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0)
-					sourceType.typeBits |= sourceType.applyCloseableClassWhitelists();
+					sourceType.typeBits |= sourceType.applyCloseableClassWhitelists(this.compilerOptions());
 				return true;
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index 77162c0..d1e42b2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -995,7 +995,7 @@
 		problemReporter().isClassPathCorrect(
 				TypeConstants.JAVA_LANG_OBJECT,
 			this.referenceContext,
-			this.environment.missingClassFileLocation);
+			this.environment.missingClassFileLocation, false);
 		BinaryTypeBinding missingObject = this.environment.createMissingType(null, TypeConstants.JAVA_LANG_OBJECT);
 		importBinding = missingObject.fPackage;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
index e012e27..dfdd9b9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2018 GK Software AG, IBM Corporation and others.
+ * Copyright (c) 2012, 2020 GK Software SE, IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
 import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching.CheckMode;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.WeakenedTypeBinding;
@@ -448,10 +449,13 @@
 								if (TypeBinding.equalsEquals(inheritedMethod.declaringClass, one.declaringClass) && getParameterNonNullness(one, i, useTypeAnnotations) != Boolean.TRUE)
 									continue parameterLoop;
 						}
-						scope.problemReporter().parameterLackingNonnullAnnotation(
-								currentArgument,
-								inheritedMethod.declaringClass,
-								annotationName);
+						if (currentArgument != null) {
+							scope.problemReporter().parameterLackingNonnullAnnotation(currentArgument, inheritedMethod.declaringClass, annotationName);
+						} else {
+							TypeDeclaration type = scope.classScope().referenceContext;
+							ASTNode location = type.superclass != null ? type.superclass : type; 
+							scope.problemReporter().inheritedParameterLackingNonnullAnnotation(currentMethod, i+1, inheritedMethod.declaringClass, location, annotationName);
+						}
 						continue;
 					}
 				} 
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 35e8fd8..3e72f06 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -1777,7 +1777,7 @@
 	if (this.root != this) {
 		return this.nonNullAnnotation = this.root.getNonNullAnnotation();
 	}
-	ReferenceBinding nonNull = getResolvedType(this.globalOptions.nonNullAnnotationName, null);
+	ReferenceBinding nonNull = getResolvedType(this.globalOptions.nonNullAnnotationName, this.UnNamedModule, null, true);
 	return this.nonNullAnnotation = this.typeSystem.getAnnotationType(nonNull, true);
 }
 
@@ -1885,11 +1885,11 @@
 * Fail with a classpath error if the type cannot be found.
 */
 public ReferenceBinding getResolvedType(char[][] compoundName, Scope scope) {
-	return getResolvedType(compoundName, scope == null ? this.UnNamedModule : scope.module(), scope);
+	return getResolvedType(compoundName, scope == null ? this.UnNamedModule : scope.module(), scope, false);
 }
-public ReferenceBinding getResolvedType(char[][] compoundName, ModuleBinding moduleBinding, Scope scope) {
+public ReferenceBinding getResolvedType(char[][] compoundName, ModuleBinding moduleBinding, Scope scope, boolean implicitAnnotationUse) {
 	if (this.module != moduleBinding)
-		return moduleBinding.environment.getResolvedType(compoundName, moduleBinding, scope);
+		return moduleBinding.environment.getResolvedType(compoundName, moduleBinding, scope, implicitAnnotationUse);
 	ReferenceBinding type = getType(compoundName, moduleBinding);
 	if (type != null) return type;
 
@@ -1898,11 +1898,11 @@
 	this.problemReporter.isClassPathCorrect(
 		compoundName,
 		scope == null ? this.root.unitBeingCompleted : scope.referenceCompilationUnit(),
-		this.missingClassFileLocation);
+		this.missingClassFileLocation, implicitAnnotationUse);
 	return createMissingType(null, compoundName);
 }
 public ReferenceBinding getResolvedJavaBaseType(char[][] compoundName, Scope scope) {
-	return getResolvedType(compoundName, javaBaseModule(), scope);
+	return getResolvedType(compoundName, javaBaseModule(), scope, false);
 }
 
 /* Answer the top level package named name.
@@ -2080,7 +2080,7 @@
 			 * misconfiguration now that did not also exist in some equivalent form while producing the class files which encode 
 			 * these missing types. So no need to bark again. Note that wasMissingType == true signals a type referenced in a .class 
 			 * file which could not be found when the binary was produced. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450 */
-			this.problemReporter.isClassPathCorrect(compoundName, this.root.unitBeingCompleted, this.missingClassFileLocation);
+			this.problemReporter.isClassPathCorrect(compoundName, this.root.unitBeingCompleted, this.missingClassFileLocation, false);
 		}
 		// create a proxy for the missing BinaryType
 		binding = createMissingType(null, compoundName);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index 28c87e4..f4f1622 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -1618,7 +1618,7 @@
 		    this.superclass = (ReferenceBinding) Scope.substitute(this, genericSuperclass);
 			this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits);
 			if ((this.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0) // avoid the side-effects of hasTypeBit()! 
-				this.typeBits |= applyCloseableClassWhitelists();
+				this.typeBits |= applyCloseableClassWhitelists(this.environment.globalOptions);
 	    }
 		return this.superclass;
 	}
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 b7c11f4..2fb6f0e 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
@@ -2539,7 +2539,7 @@
  * If a type - known to be a Closeable - is mentioned in one of our white lists
  * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable).
  */
-protected int applyCloseableClassWhitelists() {
+protected int applyCloseableClassWhitelists(CompilerOptions options) {
 	switch (this.compoundName.length) {
 		case 3:
 			if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
@@ -2577,10 +2577,27 @@
 	for (int i = 0; i < l; i++) {
 		if (CharOperation.equals(this.compoundName, TypeConstants.OTHER_WRAPPER_CLOSEABLES[i]))
 			return TypeIds.BitWrapperCloseable;
-	}	
+	}
+	if (options.analyseResourceLeaks) {
+		ReferenceBinding mySuper = this.superclass();
+		if (mySuper != null && mySuper.id != TypeIds.T_JavaLangObject) {
+			if (hasMethodWithNumArgs(TypeConstants.CLOSE, 0))
+				return 0; // close methods indicates: class may need more closing than super
+			return mySuper.applyCloseableClassWhitelists(options);
+		}
+	}
 	return 0;
 }
 
+protected boolean hasMethodWithNumArgs(char[] selector, int numArgs) {
+	for (MethodBinding methodBinding : unResolvedMethods()) {
+		if (CharOperation.equals(methodBinding.selector, TypeConstants.CLOSE)
+				&& methodBinding.parameters.length == numArgs) {
+			return true;
+		}
+	}
+	return false;
+}
 /*
  * If a type - known to be a Closeable - is mentioned in one of our white lists
  * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable).
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 10cac23..3500325 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -3046,6 +3046,28 @@
 	    && method.declaringClass.isRole();
 }
 // SH}
+
+@Override
+protected boolean hasMethodWithNumArgs(char[] selector, int numArgs) {
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+		return super.hasMethodWithNumArgs(selector, numArgs);
+	// otherwise don't trigger unResolvedMethods() which would actually resolve!
+	if (this.scope != null) {
+		for (AbstractMethodDeclaration method : this.scope.referenceContext.methods) {
+			if (CharOperation.equals(method.selector, TypeConstants.CLOSE)) {
+				if (numArgs == 0) {
+					if (method.arguments == null)
+						return true;
+				} else {
+					if (method.arguments != null && method.arguments.length == numArgs)
+						return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+
 @Override
 public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
 	if (!isPrototype())
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
index e096688..c553d38 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -43,6 +43,7 @@
 	char[] JAVAX = "javax".toCharArray(); //$NON-NLS-1$
 	char[] LANG = "lang".toCharArray(); //$NON-NLS-1$
 	char[] IO = "io".toCharArray(); //$NON-NLS-1$
+	char[] NIO = "nio".toCharArray(); //$NON-NLS-1$
 	char[] UTIL = "util".toCharArray(); //$NON-NLS-1$
 	char[] ZIP = "zip".toCharArray(); //$NON-NLS-1$
 	char[] ANNOTATION = "annotation".toCharArray(); //$NON-NLS-1$
@@ -310,7 +311,27 @@
 		"LongStream".toCharArray(), //$NON-NLS-1$
 		"IntStream".toCharArray() //$NON-NLS-1$
 	};
-	
+
+	// closeable classes containing one or more 'fluent' methods (returning 'this'):
+	char[] CHANNELS = "channels".toCharArray(); //$NON-NLS-1$
+	char[][][] FLUENT_RESOURCE_CLASSES = {
+		new char[][] {JAVA, IO, "CharArrayWriter".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, IO, "Console".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, IO, "PrintStream".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, IO, "PrintWriter".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, IO, "StringWriter".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, IO, "Writer".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, NIO, CHANNELS, "AsynchronousFileChannel".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, NIO, CHANNELS, "AsynchronousServerSocketChannel".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, NIO, CHANNELS, "FileChannel".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, NIO, CHANNELS, "NetworkChannel".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, NIO, CHANNELS, "SeekableByteChannel".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, NIO, CHANNELS, "SelectableChannel".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, NIO, CHANNELS, "Selector".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, NIO, CHANNELS, "ServerSocketChannel".toCharArray() }, //$NON-NLS-1$
+		new char[][] {JAVA, UTIL, "Formatter".toCharArray() } //$NON-NLS-1$
+	};
+
 	// different assertion utilities:
 	char[] ASSERT_CLASS = "Assert".toCharArray(); //$NON-NLS-1$
 	char[][] ORG_ECLIPSE_CORE_RUNTIME_ASSERT = new char[][] { ORG, ECLIPSE, CORE, RUNTIME, ASSERT_CLASS };
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
index 552325c..953b9ad 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -136,7 +136,7 @@
 				environment.problemReporter.isClassPathCorrect(
 					this.compoundName,
 					environment.root.unitBeingCompleted,
-					environment.missingClassFileLocation);
+					environment.missingClassFileLocation, false);
 			}
 			// create a proxy for the missing BinaryType
 			targetType = environment.createMissingType(null, this.compoundName);
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 19f3dbb..4bd0876 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -539,6 +539,7 @@
 			return CompilerOptions.NonNullTypeVariableFromLegacyInvocation;
 
 		case IProblem.ParameterLackingNonNullAnnotation:
+		case IProblem.InheritedParameterLackingNonNullAnnotation:
 			return CompilerOptions.NonnullParameterAnnotationDropped;
 
 		case IProblem.RequiredNonNullButProvidedPotentialNull:
@@ -1008,6 +1009,7 @@
 		case IProblem.IsClassPathCorrect :
 		case IProblem.CorruptedSignature :
 		case IProblem.UndefinedModuleAddReads :
+		case IProblem.MissingNullAnnotationImplicitlyUsed :
 			return CategorizedProblem.CAT_BUILDPATH;
 //{ObjectTeams:
 		case IProblem.BaseImportFromSplitPackage :
@@ -5631,7 +5633,7 @@
 			first.sourceStart,
 			last.sourceEnd);
 }
-public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl, Object location) {
+public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl, Object location, boolean implicitAnnotationUse) {
 	// ProblemReporter is not designed to be reentrant. Just in case, we discovered a build path problem while we are already 
 	// in the midst of reporting some other problem, save and restore reference context thereby mimicking a stack.
 	// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=442755.
@@ -5652,7 +5654,7 @@
 	}
 	try {
 		this.handle(
-				IProblem.IsClassPathCorrect,
+				implicitAnnotationUse ? IProblem.MissingNullAnnotationImplicitlyUsed : IProblem.IsClassPathCorrect,
 				arguments,
 				arguments,
 				start,
@@ -10667,7 +10669,8 @@
 }
 public void potentiallyUnclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
 	String[] args = { trackVar.nameForReporting(location, this.referenceContext) };
-	if (location == null) {
+	if (location == null || trackVar.acquisition != null) {
+		// if acquisition is set, the problem is not location specific
 		this.handle(
 			IProblem.PotentiallyUnclosedCloseable,
 			args,
@@ -14534,20 +14537,26 @@
 		argument.type.sourceEnd);
 }
 public void parameterLackingNonnullAnnotation(Argument argument, ReferenceBinding declaringClass, char[][] inheritedAnnotationName) {
-	int sourceStart = 0, sourceEnd = 0;
-	if (argument != null) {
-		sourceStart = argument.type.sourceStart;
-		sourceEnd = argument.type.sourceEnd;
-	} else if (this.referenceContext instanceof TypeDeclaration) {
-		sourceStart = ((TypeDeclaration) this.referenceContext).sourceStart;
-		sourceEnd =   ((TypeDeclaration) this.referenceContext).sourceEnd;
-	}
 	this.handle(
 		IProblem.ParameterLackingNonNullAnnotation, 
 		new String[] { new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)},
 		new String[] { new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])},
-		sourceStart,
-		sourceEnd);
+		argument.type.sourceStart,
+		argument.type.sourceEnd);
+}
+public void inheritedParameterLackingNonnullAnnotation(MethodBinding currentMethod, int paramRank, ReferenceBinding specificationType,
+		ASTNode location, char[][] annotationName) {
+	this.handle(IProblem.InheritedParameterLackingNonNullAnnotation,
+		new String[] {
+			String.valueOf(paramRank), new String(currentMethod.readableName()),
+			new String(specificationType.readableName()), CharOperation.toString(annotationName)
+		},
+		new String[] {
+			String.valueOf(paramRank), new String(currentMethod.shortReadableName()),
+			new String(specificationType.shortReadableName()), new String(annotationName[annotationName.length-1])
+		},
+		location.sourceStart, location.sourceEnd
+		);
 }
 public void illegalParameterRedefinition(Argument argument, ReferenceBinding declaringClass, TypeBinding inheritedParameter) {
 	int sourceStart = argument.type.sourceStart;
@@ -14705,8 +14714,14 @@
 public void cannotImplementIncompatibleNullness(ReferenceContext context, MethodBinding currentMethod, MethodBinding inheritedMethod, boolean showReturn) {
 	int sourceStart = 0, sourceEnd = 0;
 	if (context instanceof TypeDeclaration) {
-		sourceStart = ((TypeDeclaration) context).sourceStart;
-		sourceEnd =   ((TypeDeclaration) context).sourceEnd;
+		TypeDeclaration type = (TypeDeclaration) context;
+		if (type.superclass != null) {
+			sourceStart = type.superclass.sourceStart;
+			sourceEnd =   type.superclass.sourceEnd;
+		} else {
+			sourceStart = type.sourceStart;
+			sourceEnd =   type.sourceEnd;
+		}
 	}
 	String[] problemArguments = {
 			showReturn 
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 894ad69..5d3b03f 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
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2019 IBM Corporation and others.
+# Copyright (c) 2000, 2020 IBM Corporation and others.
 #
 # This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License 2.0
@@ -820,6 +820,7 @@
 943 = Nullness default is redundant with a default specified for the enclosing module {0}
 944 = Redundant null check: The field {0} is a nonnull constant
 945 = Null comparison always yields false: The field {0} is a nonnull constant
+946 = Parameter {0} of method {1} lacks a @{3} annotation as specified in type {2}
 
 
 951 = Potential null pointer access: array element may be null
@@ -853,7 +854,7 @@
 979 = Null type safety: required ''@{0}'' but this expression has type ''{1}'', a free type variable that may represent a ''@{2}'' type
 980 = Unsafe interpretation of method return type as ''@{0}'' based on the receiver type ''{1}''. Type ''{2}'' doesn''t seem to be designed with null type annotations in mind
 981 = Unsafe interpretation of method return type as ''@{0}'' based on substitution ''{1}={2}''. Declaring type ''{3}'' doesn''t seem to be designed with null type annotations in mind
-
+982 = Annotation type ''{0}'' cannot be found on the build path, which is implicitly needed for null analysis
 
 # Java 8
 1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
index 6a4156c..7c364c8 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -435,7 +435,7 @@
 	private void prepareLineBreaks() {
 		LineBreaksPreparator breaksPreparator = new LineBreaksPreparator(this.tokenManager, this.workingOptions);
 		this.astRoot.accept(breaksPreparator);
-		breaksPreparator.finishUp();
+		breaksPreparator.finishUp(this.formatRegions);
 		this.astRoot.accept(new OneLineEnforcer(this.tokenManager, this.workingOptions));
 	}
 
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
index 18026f7..5206a33 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
@@ -91,6 +91,7 @@
 import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions.Alignment;
 import org.eclipse.jdt.internal.formatter.Token.WrapMode;
 import org.eclipse.jdt.internal.formatter.Token.WrapPolicy;
+import org.eclipse.jface.text.IRegion;
 
 public class LineBreaksPreparator extends ASTVisitor {
 	final private TokenManager tm;
@@ -168,8 +169,8 @@
 // SH}
 		handleBodyDeclarations(node.bodyDeclarations());
 
-		if (node.getName().getStartPosition() == -1)
-			return true; // this is a fake type created by parsing in class body mode
+		if (this.tm.isFake(node))
+			return true;
 
 		breakLineBefore(node);
 
@@ -208,9 +209,11 @@
 			previous = bodyDeclaration;
 		}
 		if (previous != null) {
-			Token lastToken = this.tm.lastTokenIn(previous.getParent(), -1);
-			if (lastToken.tokenType == TokenNameRBRACE) // otherwise it's a fake type
+			ASTNode parent = previous.getParent();
+			if (!(parent instanceof TypeDeclaration && this.tm.isFake((TypeDeclaration) parent))) {
+				Token lastToken = this.tm.lastTokenIn(parent, -1);
 				putBlankLinesBefore(lastToken, this.options.blank_lines_after_last_class_body_declaration);
+			}
 		}
 	}
 
@@ -853,13 +856,35 @@
 			this.tm.get(lastIndex + 1).unindent();
 	}
 
-	public void finishUp() {
+	public void finishUp(List<IRegion> regions) {
 		// the visits only noted where indents increase and decrease,
-		// now prepare actual indent values
-		int currentIndent = this.options.initial_indentation_level;
+		// now prepare actual indent values, preserving indents outside formatting regions
+		int currentIndent = this.options.initial_indentation_level * this.options.indentation_size;
+		Token previous = null;
 		for (Token token : this.tm) {
-			currentIndent += token.getIndent();
-			token.setIndent(currentIndent * this.options.indentation_size);
+			if (isFixedLineStart(token, previous, regions)) {
+				currentIndent = this.tm.findSourcePositionInLine(token.originalStart);
+			} else {
+				currentIndent = Math.max(currentIndent + token.getIndent() * this.options.indentation_size, 0);
+			}
+			token.setIndent(currentIndent);
+			previous = token;
 		}
 	}
+
+	private boolean isFixedLineStart(Token token, Token previous, List<IRegion> regions) {
+		if (previous == null && this.options.initial_indentation_level >0)
+			return false; // must be handling ast rewrite
+		if (previous != null && this.tm.countLineBreaksBetween(previous, token) == 0)
+			return false;
+		int lineStart = token.originalStart;
+		char c;
+		while (lineStart > 0 && (c = this.tm.charAt(lineStart - 1)) != '\r' && c != '\n')
+			lineStart--;
+		for (IRegion r : regions) {
+			if (token.originalStart >= r.getOffset() && lineStart <= r.getOffset() + r.getLength())
+				return false;
+		}
+		return true;
+	}
 }
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
index 50b0382..428bde7 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
@@ -180,8 +180,8 @@
 
 	@Override
 	public boolean visit(TypeDeclaration node) {
-		if (node.getName().getStartPosition() == -1)
-			return true; // this is a fake type created by parsing in class body mode
+		if (this.tm.isFake(node))
+			return true;
 
 		handleToken(node.getName(), TokenNameIdentifier, true, false);
 
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
index 071f282..9a066ad 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
@@ -29,6 +29,7 @@
 import org.eclipse.jdt.core.dom.Expression;
 import org.eclipse.jdt.core.dom.InfixExpression;
 import org.eclipse.jdt.core.dom.StringLiteral;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
 import org.eclipse.jdt.core.dom.InfixExpression.Operator;
 import org.eclipse.jdt.internal.formatter.Token.WrapMode;
 import org.eclipse.jdt.internal.formatter.linewrap.CommentWrapExecutor;
@@ -412,6 +413,11 @@
 		return false;
 	}
 
+	public boolean isFake(TypeDeclaration node) {
+		// might be a fake type created by parsing in class body mode
+		return node.getName().getStartPosition() == -1;
+	}
+
 	public void addNLSAlignIndex(int index, int align) {
 		if (this.tokenIndexToNLSAlign == null)
 			this.tokenIndexToNLSAlign = new HashMap<Integer, Integer>();
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
index d3b453f..aa84460 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapExecutor.java
@@ -35,6 +35,7 @@
 import org.eclipse.jdt.internal.formatter.Token.WrapPolicy;
 import org.eclipse.jdt.internal.formatter.TokenManager;
 import org.eclipse.jdt.internal.formatter.TokenTraverser;
+import org.eclipse.jface.text.IRegion;
 
 public class WrapExecutor {
 
@@ -148,7 +149,7 @@
 			if (token.hasNLSTag())
 				this.isNLSTagInLine = true;
 
-			if (token.isWrappable()) {
+			if (token.isWrappable() && isInsideFormatRegion(token)) {
 				WrapPolicy wrapPolicy = token.getWrapPolicy();
 				if (wrapPolicy.wrapMode == WrapMode.TOP_PRIORITY && getLineBreaksBefore() == 0
 						&& index > this.currentTopPriorityGroupEnd) {
@@ -408,12 +409,14 @@
 
 	final TokenManager tm;
 	final DefaultCodeFormatterOptions options;
+	final List<IRegion> regions;
 
 	private final WrapInfo wrapInfoTemp = new WrapInfo();
 
-	public WrapExecutor(TokenManager tokenManager, DefaultCodeFormatterOptions options) {
+	public WrapExecutor(TokenManager tokenManager, DefaultCodeFormatterOptions options, List<IRegion> regions) {
 		this.tm = tokenManager;
 		this.options = options;
+		this.regions = regions;
 		this.lineAnalyzer = new LineAnalyzer(tokenManager, options);
 	}
 
@@ -542,7 +545,8 @@
 			if (!token.isWrappable()
 					|| (activeTopPriorityWrap >= 0 && i != activeTopPriorityWrap)
 					|| policiesTried.contains(wrapPolicy)
-					|| wrapPolicy.structureDepth >= depthLimit)
+					|| wrapPolicy.structureDepth >= depthLimit
+					|| !isInsideFormatRegion(token))
 				continue;
 			policiesTried.add(wrapPolicy);
 
@@ -674,6 +678,11 @@
 		return result;
 	}
 
+	boolean isInsideFormatRegion(Token token) {
+		int pos = token.originalStart;
+		return this.regions.stream().anyMatch(r -> pos >= r.getOffset() && pos < r.getOffset() + r.getLength());
+	}
+
 	int getWrapIndent(Token token) {
 		WrapPolicy policy = token.getWrapPolicy();
 		if (policy == null)
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
index 6e10134..4d02c61 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
@@ -1321,7 +1321,7 @@
 	public void finishUp(ASTNode astRoot, List<IRegion> regions) {
 		preserveExistingLineBreaks();
 		applyBreaksOutsideRegions(regions);
-		new WrapExecutor(this.tm, this.options).executeWraps();
+		new WrapExecutor(this.tm, this.options, regions).executeWraps();
 		this.aligner.alignComments();
 		wrapComments();
 		fixEnumConstantIndents(astRoot);
diff --git a/org.eclipse.jdt.core/pom.xml b/org.eclipse.jdt.core/pom.xml
index c2ce2e6..a57fe11 100644
--- a/org.eclipse.jdt.core/pom.xml
+++ b/org.eclipse.jdt.core/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (c) 2012, 2019 Eclipse Foundation and others.
+  Copyright (c) 2012, 2020 Eclipse Foundation and others.
   All rights reserved. This program and the accompanying materials
   are made available under the terms of the Eclipse Distribution License v1.0
   which accompanies this distribution, and is available at
@@ -14,11 +14,11 @@
   <parent>
     <artifactId>eclipse.jdt.core</artifactId>
     <groupId>eclipse.jdt.core</groupId>
-    <version>4.14.0-SNAPSHOT</version>
+    <version>4.15.0-SNAPSHOT</version>
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.core</artifactId>
-  <version>3.20.0-SNAPSHOT</version>
+  <version>3.21.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <properties>
@@ -34,14 +34,14 @@
 			<execution>
 				<phase>prepare-package</phase>
 				<configuration>
-					<tasks>
+					<target>
 						<replace token="bundle_qualifier," value="${buildQualifier}," dir="${project.build.directory}/classes">
 							<include name="org/eclipse/jdt/internal/compiler/batch/messages.properties"/>
 						</replace>
 						<replace token="bundle_version" value="${unqualifiedVersion}" dir="${project.build.directory}/classes">
 							<include name="org/eclipse/jdt/internal/compiler/batch/messages.properties"/>
 						</replace>
-					</tasks>
+					</target>
 				</configuration>
 				<goals>
 					<goal>run</goal>