Releng: update jdt.core to I20181206-0815 (candidate 4.10 RC2)

Change-Id: Ida2cdecd963b8c11ba64ac6daad63ec951baa282
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 ab71b71..b2121e1 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
@@ -246,6 +246,10 @@
 		StringBuffer classpathBuffer = new StringBuffer(" -classpath ");
 		this.classpath = classpathBuffer.toString();
 	}
+	/** Call this if " -classpath " should be replaced by some other option token. */
+	protected void usePathOption(String option) {
+		this.classpath = option;
+	}
 	static String getVersion(String javacPathName) throws IOException, InterruptedException {
 		Process fetchVersionProcess = null;
 		try {
@@ -1013,7 +1017,7 @@
 	// list of available javac compilers, as defined by the jdk.roots
 	// variable, which should hold a File.pathSeparatorChar separated
 	// list of paths for to-be-tested JDK root directories
-	protected static List javacCompilers = null;
+	protected static List<JavacCompiler> javacCompilers = null;
 
 	public static final String OUTPUT_DIR = Util.getOutputDirectory() + File.separator + "regression";
 	public static final String LIB_DIR = Util.getOutputDirectory() + File.separator + "lib";
@@ -1869,7 +1873,15 @@
 				expectedSuccessOutputString,
 				null,
 				javacTestOptions);
+	}
+
+	protected static void javacUsePathOption(String option) {
+		if (AbstractRegressionTest.javacCompilers != null) {
+			for (JavacCompiler compiler : AbstractRegressionTest.javacCompilers) {
+				compiler.usePathOption(option);
+			}
 		}
+	}
 
 	/*
 	 * Run Sun compilation using javac.
@@ -2184,9 +2196,9 @@
 		}
 	}
 	String testName = testName();
-	Iterator compilers = javacCompilers.iterator();
+	Iterator<JavacCompiler> compilers = javacCompilers.iterator();
 	while (compilers.hasNext()) {
-		JavacCompiler compiler = (JavacCompiler) compilers.next();
+		JavacCompiler compiler = compilers.next();
 		if (!options.skip(compiler) && compiler.compliance == this.complianceLevel) {
 			// WORK this may exclude some compilers under some conditions (when
 			//      complianceLevel is not set); consider accepting the compiler
@@ -2208,6 +2220,7 @@
 				for (int i = 0, length = testFiles.length; i < length; ) {
 					String fileName = testFiles[i++];
 					String contents = testFiles[i++];
+					fileName = expandFileNameForJavac(fileName);
 					File file = new File(javacOutputDirectory, fileName);
 					if (fileName.lastIndexOf('/') >= 0) {
 						File dir = file.getParentFile();
@@ -2221,7 +2234,7 @@
 				int testFilesLength = testFiles.length;
 				sourceFileNames = new String[testFilesLength / 2];
 				for (int i = 0, j = 0; i < testFilesLength; i += 2, j++) {
-					sourceFileNames[j] = testFiles[i];
+					sourceFileNames[j] = expandFileNameForJavac(testFiles[i]);
 				}
 
 				// compile
@@ -2324,6 +2337,10 @@
 		}
 	}
 }
+/** Hook for AbstractRegressionTest9 */
+protected String expandFileNameForJavac(String fileName) {
+	return fileName;
+}
 void handleMismatch(JavacCompiler compiler, String testName, String[] testFiles, String expectedCompilerLog,
 		String expectedOutputString, String expectedErrorString, StringBuffer compilerLog, String output, String err,
 		JavacTestOptions.Excuse excuse, int mismatch) {
@@ -3606,7 +3623,7 @@
 					System.out.println("* Sun Javac compiler output archived into file:");
 					System.out.println("* " + javacFullLogFileName);
 					System.out.println("***************************************************************************");
-					javacCompilers = new ArrayList();
+					javacCompilers = new ArrayList<>();
 					String jdkRoots = System.getProperty("jdk.roots");
 					if (jdkRoots == null) {
 						javacCompilers.add(new JavacCompiler(jdkRootDirPath.toString()));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest9.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest9.java
index cc49625..57db3e4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest9.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest9.java
@@ -89,6 +89,18 @@
 		return compilationUnits;
 	}
 
+	/**
+	 * javac cannot leverage our internal map  {@code file2module}, so we better
+	 * neatly place each file into a sub directory matching the module name.
+	 */
+	protected String expandFileNameForJavac(String fileName) {
+		String fileNameAsKey = fileName.replace(File.separator, "/");
+		if (this.file2module != null && this.file2module.containsKey(fileNameAsKey)) {
+			fileName = new String(this.file2module.get(fileNameAsKey))+File.separator+fileName;
+		}
+		return fileName;
+	}
+
 	private IModule extractModuleDesc(String fileName, String fileContent, ICompilationUnit cu) {
 		if (fileName.toLowerCase().endsWith(IModule.MODULE_INFO_JAVA)) {
 			Parser parser = createParser();
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
index 9a7deef..6f12b7d 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
@@ -688,7 +688,8 @@
 		runner.runNegativeTest();
 	}
 	public void testDeprecatedProvidedServices() {
-		associateToModule("mod0", "p1/IServiceDep.java", "p1/IServiceDepSince.java", "p1/IServiceTermDep.java", "p1/IServiceTermDepSince.java");
+		javacUsePathOption(" --module-source-path ");
+		associateToModule("mod0", "module-info.java", "p1/IServiceDep.java", "p1/IServiceDepSince.java", "p1/IServiceTermDep.java", "p1/IServiceTermDepSince.java");
 		associateToModule("mod1", "p1impl/ServiceDep.java", "p1impl/ServiceDepSince.java", "p1impl/ServiceTermDep.java", "p1impl/ServiceTermDepSince.java");
 		Runner runner = new Runner();
 		runner.customOptions = new HashMap<>();
@@ -732,7 +733,7 @@
 				"package p1impl;\n" +
 				"@Deprecated(since=\"3\",forRemoval=true)\n" +
 				"public class ServiceTermDepSince implements p1.IServiceTermDepSince {}\n",
-				"folder2/module-info.java",
+				"mod1/module-info.java",
 				"module mod1 {\n" +
 				"	requires mod0;\n" +
 				"	provides p1.IServiceDep with p1impl.ServiceDep;\n" +
@@ -743,42 +744,42 @@
 			};
 		runner.expectedCompilerLog =
 			"----------\n" + 
-			"1. INFO in folder2\\module-info.java (at line 3)\n" + 
+			"1. INFO in mod1\\module-info.java (at line 3)\n" + 
 			"	provides p1.IServiceDep with p1impl.ServiceDep;\n" + 
 			"	            ^^^^^^^^^^^\n" + 
 			"The type IServiceDep is deprecated\n" + 
 			"----------\n" + 
-			"2. INFO in folder2\\module-info.java (at line 3)\n" + 
+			"2. INFO in mod1\\module-info.java (at line 3)\n" + 
 			"	provides p1.IServiceDep with p1impl.ServiceDep;\n" + 
 			"	                                    ^^^^^^^^^^\n" + 
 			"The type ServiceDep is deprecated\n" + 
 			"----------\n" + 
-			"3. INFO in folder2\\module-info.java (at line 4)\n" + 
+			"3. INFO in mod1\\module-info.java (at line 4)\n" + 
 			"	provides p1.IServiceDepSince with p1impl.ServiceDepSince;\n" + 
 			"	            ^^^^^^^^^^^^^^^^\n" + 
 			"The type IServiceDepSince is deprecated since version 2\n" + 
 			"----------\n" + 
-			"4. INFO in folder2\\module-info.java (at line 4)\n" + 
+			"4. INFO in mod1\\module-info.java (at line 4)\n" + 
 			"	provides p1.IServiceDepSince with p1impl.ServiceDepSince;\n" + 
 			"	                                         ^^^^^^^^^^^^^^^\n" + 
 			"The type ServiceDepSince is deprecated since version 2\n" + 
 			"----------\n" + 
-			"5. WARNING in folder2\\module-info.java (at line 5)\n" + 
+			"5. WARNING in mod1\\module-info.java (at line 5)\n" + 
 			"	provides p1.IServiceTermDep with p1impl.ServiceTermDep;\n" + 
 			"	            ^^^^^^^^^^^^^^^\n" + 
 			"The type IServiceTermDep has been deprecated and marked for removal\n" + 
 			"----------\n" + 
-			"6. WARNING in folder2\\module-info.java (at line 5)\n" + 
+			"6. WARNING in mod1\\module-info.java (at line 5)\n" + 
 			"	provides p1.IServiceTermDep with p1impl.ServiceTermDep;\n" + 
 			"	                                        ^^^^^^^^^^^^^^\n" + 
 			"The type ServiceTermDep has been deprecated and marked for removal\n" + 
 			"----------\n" + 
-			"7. WARNING in folder2\\module-info.java (at line 6)\n" + 
+			"7. WARNING in mod1\\module-info.java (at line 6)\n" + 
 			"	provides p1.IServiceTermDepSince with p1impl.ServiceTermDepSince;\n" + 
 			"	            ^^^^^^^^^^^^^^^^^^^^\n" + 
 			"The type IServiceTermDepSince has been deprecated since version 3 and marked for removal\n" + 
 			"----------\n" + 
-			"8. WARNING in folder2\\module-info.java (at line 6)\n" + 
+			"8. WARNING in mod1\\module-info.java (at line 6)\n" + 
 			"	provides p1.IServiceTermDepSince with p1impl.ServiceTermDepSince;\n" + 
 			"	                                             ^^^^^^^^^^^^^^^^^^^\n" + 
 			"The type ServiceTermDepSince has been deprecated since version 3 and marked for removal\n" + 
@@ -786,6 +787,8 @@
 		runner.runWarningTest();
 	}
 	public void testDeprecatedUsedServices() {
+		javacUsePathOption(" --module-path ");
+
 		associateToModule("mod0", "p1/IServiceDep.java", "p1/IServiceDepSince.java", "p1/IServiceTermDep.java", "p1/IServiceTermDepSince.java");
 		Runner runner = new Runner();
 		runner.customOptions = new HashMap<>();
@@ -888,6 +891,8 @@
 		}
 	}
 	public void testBug533063_2() throws Exception {
+		javacUsePathOption(" --module-path ");
+
 		runConformTest(new String[] {
 			"dont.use/module-info.java",
 			"@Deprecated(forRemoval=true,since=\"9\") module dont.use {}\n"
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
index cf2ad8a..5f7992e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
@@ -897,6 +897,8 @@
 			"    }\n" + 
 			"}\n"
 		},
+		this.complianceLevel < ClassFileConstants.JDK11
+		?
 		"----------\n" + 
 		"1. WARNING in ShowBug.java (at line 9)\n" + 
 		"	final X x = new X() {\n" + 
@@ -907,6 +909,13 @@
 		"	x.x(val - 1);\n" + 
 		"	^\n" + 
 		"The local variable x may not have been initialized\n" + 
+		"----------\n"
+		:
+		"----------\n" + 
+		"1. ERROR in ShowBug.java (at line 13)\n" + 
+		"	x.x(val - 1);\n" + 
+		"	^\n" + 
+		"The local variable x may not have been initialized\n" + 
 		"----------\n");
 }
 public static Class testClass() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
index f1745d8..422f84f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
@@ -40,7 +40,7 @@
 public class ModuleCompilationTests extends AbstractBatchCompilerTest {
 
 	static {
-//		 TESTS_NAMES = new String[] { "test_npe_bug535107" };
+//		 TESTS_NAMES = new String[] { "testBug540067e" };
 		// TESTS_NUMBERS = new int[] { 1 };
 		// TESTS_RANGE = new int[] { 298, -1 };
 	}
@@ -162,8 +162,7 @@
 			if (javacCommandLine == null) {
 				javacCommandLine = adjustForJavac(commandLine, null);
 			}
-			for (Object comp : javacCompilers) {
-				JavacCompiler javacCompiler = (JavacCompiler) comp;
+			for (JavacCompiler javacCompiler : javacCompilers) {
 				if (javacCompiler.compliance < ClassFileConstants.JDK9)
 					continue;
 				if (options.skip(javacCompiler)) {
@@ -240,8 +239,7 @@
 			File outputDir = new File(OUTPUT_DIR);
 			final Set<String> outFiles = new HashSet<>();
 			walkOutFiles(output, outFiles, true);
-			for (Object comp : javacCompilers) {
-				JavacCompiler javacCompiler = (JavacCompiler) comp;
+			for (JavacCompiler javacCompiler : javacCompilers) {
 				if (javacCompiler.compliance < ClassFileConstants.JDK9)
 					continue;
 				JavacTestOptions.Excuse excuse = options.excuseFor(javacCompiler);
@@ -3632,11 +3630,7 @@
 			"	        ^^\n" + 
 			"The package p1 does not exist or is empty\n" + 
 			"----------\n" +
-			"----------\n" + 
-			"2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/p1/X.java\n" + 
-			"Must declare a named package because this compilation unit is associated to the named module \'mod.one\'\n" + 
-			"----------\n" + 
-			"2 problems (2 errors)\n",
+			"1 problem (1 error)\n",
 			false,
 			"empty",
 			OUTPUT_DIR + File.separator + out);
@@ -5008,4 +5002,200 @@
 		        "",
 		        true);
 	}
+	public void testBug540067a() {
+		File outputDirectory = new File(OUTPUT_DIR);
+		Util.flushDirectoryContent(outputDirectory);
+		String out = "bin";
+		String directory = OUTPUT_DIR + File.separator + "src";
+		String moduleLoc = directory + File.separator + "mod.one";
+		List<String> files = new ArrayList<>(); 
+		writeFileCollecting(files, moduleLoc, "module-info.java", 
+						"module mod.one { \n" +
+						" exports p;\n" +
+						"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java", 
+				"package p;\n" +
+				"public class X {\n" +
+				"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java", 
+				"/*nothing in it */");
+
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+			.append(" -9 ")
+			.append(" -classpath \"")
+			.append(Util.getJavaClassLibsAsString())
+			.append("\" ")
+			.append(" --module-source-path " + "\"" + directory + "\" ")
+			.append(moduleLoc + File.separator + "module-info.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+		runConformModuleTest(
+				new String[0],
+				buffer.toString(),
+				"",
+				"",
+				false);
+	}
+	public void testBug540067b() {
+		File outputDirectory = new File(OUTPUT_DIR);
+		Util.flushDirectoryContent(outputDirectory);
+		String out = "bin";
+		String directory = OUTPUT_DIR + File.separator + "src";
+		String moduleLoc = directory + File.separator + "mod.one";
+		List<String> files = new ArrayList<>(); 
+		writeFileCollecting(files, moduleLoc, "module-info.java", 
+						"module mod.one { \n" +
+						" exports p;\n" +
+						"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java", 
+				"package p;\n" +
+				"public class X {\n" +
+				"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java", 
+				"package p.q;");
+
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+			.append(" -9 ")
+			.append(" -classpath \"")
+			.append(Util.getJavaClassLibsAsString())
+			.append("\" ")
+			.append(" --module-source-path " + "\"" + directory + "\" ")
+			.append(moduleLoc + File.separator + "module-info.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+		runConformModuleTest(
+				new String[0],
+				buffer.toString(),
+				"",
+				"",
+				false);
+	}
+	public void testBug540067c() {
+		File outputDirectory = new File(OUTPUT_DIR);
+		Util.flushDirectoryContent(outputDirectory);
+		String out = "bin";
+		String directory = OUTPUT_DIR + File.separator + "src";
+		String moduleLoc = directory + File.separator + "mod.one";
+		List<String> files = new ArrayList<>(); 
+		writeFileCollecting(files, moduleLoc, "module-info.java", 
+						"module mod.one { \n" +
+						" exports p;\n" +
+						"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java", 
+				"package p;\n" +
+				"public class X {\n" +
+				"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java", 
+				"package p.q;\n"
+				+ "class Test {}");
+
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+			.append(" -9 ")
+			.append(" -classpath \"")
+			.append(Util.getJavaClassLibsAsString())
+			.append("\" ")
+			.append(" --module-source-path " + "\"" + directory + "\" ")
+			.append(moduleLoc + File.separator + "module-info.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+		runConformModuleTest(
+				new String[0],
+				buffer.toString(),
+				"",
+				"",
+				false);
+	}
+	public void testBug540067d() {
+		File outputDirectory = new File(OUTPUT_DIR);
+		Util.flushDirectoryContent(outputDirectory);
+		String out = "bin";
+		String directory = OUTPUT_DIR + File.separator + "src";
+		String moduleLoc = directory + File.separator + "mod.one";
+		List<String> files = new ArrayList<>(); 
+		writeFileCollecting(files, moduleLoc, "module-info.java", 
+						"module mod.one { \n" +
+						" exports p;\n" +
+						"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java", 
+				"package p;\n" +
+				"public class X {\n" +
+				"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java", 
+				"class Test {}");
+
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+			.append(" -9 ")
+			.append(" -classpath \"")
+			.append(Util.getJavaClassLibsAsString())
+			.append("\" ")
+			.append(" --module-source-path " + "\"" + directory + "\" ")
+			.append(moduleLoc + File.separator + "module-info.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+		runNegativeModuleTest(
+				new String[0],
+				buffer.toString(),
+				"",
+				"----------\n" + 
+				"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/p/q/Test.java (at line 1)\n" + 
+				"	class Test {}\n" + 
+				"	^\n" + 
+				"Must declare a named package because this compilation unit is associated to the named module \'mod.one\'\n" + 
+				"----------\n" + 
+				"1 problem (1 error)\n",
+				false,
+				"unnamed package is not allowed in named modules");
+	}
+	public void testBug540067e() {
+		File outputDirectory = new File(OUTPUT_DIR);
+		Util.flushDirectoryContent(outputDirectory);
+		String out = "bin";
+		String directory = OUTPUT_DIR + File.separator + "src";
+		String moduleLoc = directory + File.separator + "mod.one";
+		List<String> files = new ArrayList<>(); 
+		writeFileCollecting(files, moduleLoc, "module-info.java", 
+						"module mod.one { \n" +
+						" exports p;\n" +
+						"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p", "X.java", 
+				"package p;\n" +
+				"public class X {\n" +
+				"}");
+		writeFileCollecting(files, moduleLoc + File.separator + "p" + File.separator + "q", "Test.java", 
+				"import java.lang.*;");
+
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("-d " + OUTPUT_DIR + File.separator + out )
+			.append(" -9 ")
+			.append(" -classpath \"")
+			.append(Util.getJavaClassLibsAsString())
+			.append("\" ")
+			.append(" -warn:-unused")
+			.append(" --module-source-path " + "\"" + directory + "\" ")
+			.append(moduleLoc + File.separator + "module-info.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "X.java ")
+			.append(moduleLoc + File.separator + "p" + File.separator + "q" + File.separator + "Test.java");
+
+		runNegativeModuleTest(
+				new String[0],
+				buffer.toString(),
+				"",
+				"----------\n" + 
+				"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/p/q/Test.java (at line 1)\n" + 
+				"	import java.lang.*;\n" + 
+				"	^\n" + 
+				"Must declare a named package because this compilation unit is associated to the named module \'mod.one\'\n" + 
+				"----------\n" + 
+				"1 problem (1 error)\n",
+				false,
+				"unnamed package is not allowed in named modules");
+	}
 }
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 8d45ff2..6988995 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
@@ -5354,4 +5354,145 @@
 		"----------\n",
 		options);
 }
+public void testBug473317() {
+	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(
+		new String[] {
+			"AutoCloseableEnhancedForTest.java",
+			"import java.util.Iterator;\n" + 
+			"\n" + 
+			"public class AutoCloseableEnhancedForTest\n" + 
+			"{\n" + 
+			"   private static class MyIterator<T> implements Iterator<T>\n" + 
+			"   {\n" + 
+			"      private T value;\n" + 
+			"      \n" + 
+			"      public MyIterator(T value)\n" + 
+			"      {\n" + 
+			"         this.value = value;\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      @Override\n" + 
+			"      public boolean hasNext()\n" + 
+			"      {\n" + 
+			"         return false;\n" + 
+			"      }\n" + 
+			"\n" + 
+			"      @Override\n" + 
+			"      public T next()\n" + 
+			"      {\n" + 
+			"         return value;\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private static class MyIterable<T> implements Iterable<T>, AutoCloseable\n" + 
+			"   {\n" + 
+			"      @Override\n" + 
+			"      public Iterator<T> iterator()\n" + 
+			"      {\n" + 
+			"         return new MyIterator<>(null);\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      @Override\n" + 
+			"      public void close() throws Exception\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   public static void main(String[] args)\n" + 
+			"   {\n" + 
+			"      // Not flagged as \"never closed.\"\n" + 
+			"      for (Object value : new MyIterable<>())\n" + 
+			"      {\n" + 
+			"         System.out.println(String.valueOf(value));\n" + 
+			"         \n" + 
+			"         break;\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      // Flagged as \"never closed.\"\n" + 
+			"      MyIterable<Object> iterable = new MyIterable<>();\n" + 
+			"      \n" + 
+			"      for (Object value : iterable)\n" + 
+			"      {\n" + 
+			"         System.out.println(String.valueOf(value));\n" + 
+			"         \n" + 
+			"         break;\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in AutoCloseableEnhancedForTest.java (at line 44)\n" + 
+		"	for (Object value : new MyIterable<>())\n" + 
+		"	                    ^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"2. WARNING in AutoCloseableEnhancedForTest.java (at line 52)\n" + 
+		"	MyIterable<Object> iterable = new MyIterable<>();\n" + 
+		"	                   ^^^^^^^^\n" + 
+		"Resource leak: \'iterable\' is never closed\n" + 
+		"----------\n",
+		compilerOptions);
+}
+public void testBug541705() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // uses diamond
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.customOptions.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+	runner.testFiles = new String[] {
+		"Test.java",
+		"import java.util.*;\n" +
+		"import java.util.zip.*;\n" +
+		"import java.io.*;\n" +
+		"public class Test {\n" +
+		"	private static HashMap<String, ZipFile> fgZipFileCache = new HashMap<>(5);\n" + 
+		"	public static void closeArchives() {\n" + 
+		"		synchronized (fgZipFileCache) {\n" + 
+		"			for (ZipFile file : fgZipFileCache.values()) {\n" +
+		"				synchronized (file) {\n" + 
+		"					try {\n" + 
+		"						file.close();\n" + 
+		"					} catch (IOException e) {\n" + 
+		"						System.out.println(e);\n" + 
+		"					}\n" + 
+		"				}\n" + 
+		"			}\n" + 
+		"			fgZipFileCache.clear();\n" + 
+		"		}\n" + 
+		"	}\n" +
+		"}\n"
+	};
+	runner.runConformTest();
+}
+public void testBug541705b() {
+	if (this.complianceLevel < ClassFileConstants.JDK9) return; // variable used in t-w-r
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.customOptions.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+	runner.testFiles = new String[] {
+		"Test.java",
+		"import java.util.*;\n" +
+		"import java.util.zip.*;\n" +
+		"import java.io.*;\n" +
+		"public class Test {\n" +
+		"	private static HashMap<String, ZipFile> fgZipFileCache = new HashMap<>(5);\n" + 
+		"	public static void closeArchives() {\n" + 
+		"		synchronized (fgZipFileCache) {\n" + 
+		"			for (ZipFile file : fgZipFileCache.values()) {\n" + 
+		"				synchronized (file) {\n" + 
+		"					try (file) {\n" + 
+		"					} catch (IOException e) {\n" + 
+		"						System.out.println(e);\n" + 
+		"					}\n" + 
+		"				}\n" + 
+		"			}\n" + 
+		"			fgZipFileCache.clear();\n" + 
+		"		}\n" + 
+		"	}\n" +
+		"}\n"
+	};
+	runner.runConformTest();
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
index eec3753..33aa81c 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
@@ -383,6 +383,10 @@
 			if (version.startsWith("1.8.0_")) {
 				int build = Integer.parseInt(version.substring("1.8.0_".length()));
 				reflectNestedClassUseDollar = build >= 171; 
+			} else if (version.startsWith("1.8.0-")) {
+				// Some versions start with 1.8.0- but don't have build qualifier.
+				// Just assume they are > 171 build. Nothing much can be done.
+				reflectNestedClassUseDollar = true;
 			} else {
 				throw new IllegalStateException("Unrecognized Java version: "+version);
 			}
diff --git a/org.eclipse.jdt.core/.options b/org.eclipse.jdt.core/.options
index 1549d65..443e2fd 100644
--- a/org.eclipse.jdt.core/.options
+++ b/org.eclipse.jdt.core/.options
@@ -1,5 +1,5 @@
 # Turn on debug tracing for org.eclipse.jdt.core plugin
-org.eclipse.jdt.core/debug=true
+org.eclipse.jdt.core/debug=false
 
 # Reports buffer manager activity
 org.eclipse.jdt.core/debug/buffermanager=false
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 d093225..8498b31 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
@@ -79,7 +79,9 @@
 	private static final int REPORTED_POTENTIAL_LEAK = 32;
 	// a location independent definitive problem has been reported against this resource:
 	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 static boolean TEST_372319 = false; // see https://bugs.eclipse.org/372319
 
 	/**
@@ -449,9 +451,9 @@
 					if (rhsTrackVar.originalBinding != null)
 						local.closeTracker = rhsTrackVar;			//		a.: let fresh LHS share it
 					if (rhsTrackVar.currentAssignment == location) {
-						// pre-set tracker from lhs - passed from outside?
+						// pre-set tracker from lhs - passed from outside (or foreach)?
 						// now it's a fresh resource
-						rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE);
+						rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR);
 					}
 				} else {
 					if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression) {
@@ -484,7 +486,7 @@
 						}
 					}
 					// re-assigning from a fresh value, mark as not-closed again:
-					if ((previousTracker.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0
+					if ((previousTracker.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR)) == 0
 							&& flowInfo.hasNullInfoFor(previousTracker.binding)) // avoid spilling info into a branch that doesn't see the corresponding resource
 						flowInfo.markAsDefinitelyNull(previousTracker.binding);
 					local.closeTracker = analyseCloseableExpression(flowInfo, flowContext, local, location, rhs, previousTracker);
@@ -494,7 +496,7 @@
 				if (rhsTrackVar != null) {
 					local.closeTracker = rhsTrackVar;
 					// a fresh resource, mark as not-closed:
-					if ((rhsTrackVar.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0)
+					if ((rhsTrackVar.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR)) == 0)
 						flowInfo.markAsDefinitelyNull(rhsTrackVar.binding);
 // TODO(stephan): this might be useful, but I could not find a test case for it: 
 //					if (flowContext.initsOnFinally != null)
@@ -753,6 +755,12 @@
 		return flowInfo;
 	}
 
+	public static void markForeachElementVar(LocalDeclaration local) {
+		if (local.binding != null && local.binding.closeTracker != null) {
+			local.binding.closeTracker.globalClosingState |= FOREACH_ELEMENT_VAR;
+		}
+	}
+
 	/**
 	 * Iterator for a set of FakedTrackingVariable, which dispenses the elements 
 	 * according to the priorities defined by enum {@link Stage}.
@@ -987,7 +995,7 @@
 	}
 
 	public void reportExplicitClosing(ProblemReporter problemReporter) {
-		if ((this.globalClosingState & (OWNED_BY_OUTSIDE|REPORTED_EXPLICIT_CLOSE)) == 0) { // can't use t-w-r for OWNED_BY_OUTSIDE
+		if ((this.globalClosingState & (OWNED_BY_OUTSIDE|REPORTED_EXPLICIT_CLOSE|FOREACH_ELEMENT_VAR)) == 0) { // can't use t-w-r for OWNED_BY_OUTSIDE
 			this.globalClosingState |= REPORTED_EXPLICIT_CLOSE;
 			problemReporter.explicitlyClosedAutoCloseable(this);
 		}
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 afafc2e..57950da 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
@@ -112,7 +112,7 @@
 		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
 
 		// process the element variable and collection
-		flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);		
+		flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);
 		FlowInfo condInfo = this.collection.analyseCode(this.scope, flowContext, flowInfo.copy());
 		this.collection.checkNPE(currentScope, flowContext, condInfo.copy(), 1);
 		LocalVariableBinding elementVarBinding = this.elementVariable.binding;
@@ -144,6 +144,11 @@
 
 			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);
+				}
 			}
 
 			// code generation can be optimized when no need to continue in the loop
@@ -160,6 +165,9 @@
 			}
 		} else {
 			exitBranch = condInfo.initsWhenFalse();
+			if (this.action instanceof Block && !this.action.isEmptyBlock()) {
+				this.scope.checkUnclosedCloseables(actionInfo, loopingContext, null, null);
+			}
 		}
 
 		// we need the variable to iterate the collection even if the
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 9dce583..2df636f 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, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -176,8 +176,8 @@
 				moduleDecl.createScope(this);
 				moduleDecl.checkAndSetModifiers();
 			}
-		} else if (this.environment.module != this.environment.UnNamedModule) {
-			problemReporter().unnamedPackageInNamedModule(this.environment.module);
+		} else if (module() != this.environment.UnNamedModule) {
+			problemReporter().unnamedPackageInNamedModule(module());
 		}
 	} else {
 //{ObjectTeams: ROFI consider team packages, different creation time, different conflict rule
@@ -989,6 +989,18 @@
 	return this.captureID++;
 }
 
+@Override
+public ModuleBinding module() {
+	if (!this.referenceContext.isModuleInfo() &&
+			this.referenceContext.types == null &&
+			this.referenceContext.currentPackage == null &&
+			this.referenceContext.imports == null) {
+		this.environment = this.environment.UnNamedModule.environment;
+		return this.environment.UnNamedModule;
+	}
+	return super.module();
+}
+
 /* Answer the problem reporter to use for raising new problems.
 *
 * Note that as a side-effect, this updates the current reference context
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
index ec3fdcd..d6117ed 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
@@ -684,8 +684,8 @@
 			for (ModuleBinding moduleBinding : otherRelevantModules(declaringModuleNames)) {
 				if (!moduleBinding.isPackageLookupActive) {
 					PackageBinding nextBinding = parent != null 
-							? moduleBinding.getVisiblePackage(parent, singleName, true)
-							: moduleBinding.getVisiblePackage(compoundName, true);
+							? moduleBinding.getVisiblePackage(parent, singleName, false)
+							: moduleBinding.getVisiblePackage(compoundName, false);
 					currentBinding = SplitPackageBinding.combine(nextBinding, currentBinding, this);
 				}
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 4b69153..9eba05a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -824,7 +824,7 @@
 		} while (scope != null);
 		return (CompilationUnitScope) lastScope;
 	}
-	public final ModuleBinding module() {
+	public ModuleBinding module() {
 		return environment().module;
 	}
 	public boolean isLambdaScope() {