/*******************************************************************************
 * Copyright (c) 2016, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IProblemRequestor;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.core.ClasspathAttribute;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.internal.core.builder.ClasspathJrt;
import org.eclipse.jdt.internal.core.util.Messages;

import junit.framework.Test;

public class ModuleBuilderTests extends ModifyingResourceTests {
	public ModuleBuilderTests(String name) {
		super(name);
	}

	static {
//		 TESTS_NAMES = new String[] { "testReleaseOption8" };
	} 
	private String sourceWorkspacePath = null;
	protected ProblemRequestor problemRequestor;
	public static Test suite() {
		if (!isJRE9) {
			// almost empty suite, since we need JRE9+
			Suite suite = new Suite(ModuleBuilderTests.class.getName());
			suite.addTest(new ModuleBuilderTests("thisSuiteRunsOnJRE9plus"));
			return suite;
		}
		return buildModelTestSuite(ModuleBuilderTests.class, BYTECODE_DECLARATION_ORDER);
	}
	public void thisSuiteRunsOnJRE9plus() {}

	public String getSourceWorkspacePath() {
		return this.sourceWorkspacePath == null ? super.getSourceWorkspacePath() : this.sourceWorkspacePath;
	}
	public void setUp() throws Exception {
		super.setUp();
		this.problemRequestor =  new ProblemRequestor();
		this.wcOwner = new WorkingCopyOwner() {
			public IProblemRequestor getProblemRequestor(ICompilationUnit unit) {
				return ModuleBuilderTests.this.problemRequestor;
			}
		};
	}
	public void setUpSuite() throws Exception {
		super.setUpSuite();
		this.currentProject = createJava9Project("P1");
		this.createFile("P1/src/module-info.java", "");
		this.createFolder("P1/src/com/greetings");
		this.createFile("P1/src/com/greetings/Main.java", "");
		waitForManualRefresh();
		waitForAutoBuild();
	}
	
	public void tearDownSuite() throws Exception {
		super.tearDownSuite();
		deleteProject("P1");
	}
	
	// Test that the java.base found as a module package fragment root in the project 
	public void test001() throws CoreException {
		try {
			IJavaProject project = createJava9Project("Test01", new String[]{"src"});
			this.createFile("Test01/src/module-info.java", "");
			this.createFolder("Test01/src/com/greetings");
			this.createFile("Test01/src/com/greetings/Main.java", "");
			waitForManualRefresh();
			waitForAutoBuild();
			project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
			IPackageFragmentRoot base = null;
			for (IPackageFragmentRoot iRoot : roots) {
				IModuleDescription moduleDescription = iRoot.getModuleDescription();
				if (moduleDescription != null && moduleDescription.getElementName().equals("java.base")) {
					base = iRoot;
					break;
				}
			}
			assertNotNull("Java.base module should not null", base);
			assertMarkers("Unexpected markers", "", project);
		} finally {
			deleteProject("Test01");
		}
	}
	// Test the project compiles without errors with a simple module-info.java
	public void test002() throws CoreException {
		try {
			this.editFile("P1/src/module-info.java",
							"module M1 {\n" +
							"	exports com.greetings;\n" +
							"	requires java.base;\n" +
							"}");
			waitForManualRefresh();
			this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertMarkers("Unexpected markers", "", this.currentProject);
		} finally {
		}
	}
	// Test that types from java.base module are seen by the compiler
	// even without an explicit 'requires java.base' declaration.
	public void test003() throws CoreException {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
							"	exports com.greetings;\n" +
					"}");
			this.editFile("P1/src/com/greetings/Main.java",
					"package com.greetings;\n" +
					"public class Main {\n" +
					"	public static void main(String[] args) {\n" +
					"	}\n" +
					"}");
			waitForManualRefresh();
			this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
		}
	}
	// Test that a type that is present in the JDK, but not observable to the source module,
	// is reported as a compilation error.
	public void test004() throws CoreException {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"	requires java.base;\n" +
					"}");
			this.editFile("P1/src/com/greetings/Main.java",
					"package com.greetings;\n" +
					"import java.sql.Connection;\n" +
					"public class Main {\n" +
					"	public Connection con = null;\n" +
					"}");
			waitForManualRefresh();
			this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The type java.sql.Connection is not accessible\n" + 
					"Connection cannot be resolved to a type", markers);
		} finally {
		}
	}
	// Test that a type that is outside java.base module is available to the compiler
	// when the module is specified as 'requires'.
	public void test005() throws CoreException {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"	requires java.base;\n" +
					"	requires java.sql;\n" +
					"}");
			waitForManualRefresh();
			this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					// just an API leak warning:
					"The type Connection from module java.sql may not be accessible to clients due to missing \'requires transitive\'",
					markers);
		} finally {
		}
	}
	// Test that a module that doesn't exist but specified as requires in module-info
	// doesn't affect rest of the compilation.
	public void _test006() throws CoreException {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"	requires java.base;\n" +
					"	requires java.sql;\n" +
					"	requires java.idontexist;\n" +
					"}");
			this.editFile("P1/src/com/greetings/Main.java",
					"package com.greetings;\n" +
					"public class Main {\n" +
					"}");
			waitForManualRefresh();
			this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
		}
	}
	private IJavaProject setupP2() throws CoreException {
		IJavaProject project = createJava9Project("P2");
		IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
		IClasspathEntry projectEntry = JavaCore.newProjectEntry(new Path("/P1"), null, false,
			new IClasspathAttribute[] {modAttr},
			true);
		IClasspathEntry[] old = project.getRawClasspath();
		IClasspathEntry[] newPath = new IClasspathEntry[old.length +1];
		System.arraycopy(old, 0, newPath, 0, old.length);
		newPath[old.length] = projectEntry;
		project.setRawClasspath(newPath, null);
		this.editFile("P1/src/module-info.java",
				"module M1 {\n" +
				"	exports com.greetings;\n" +
				"	requires java.base;\n" +
				"}");
		this.editFile("P1/src/com/greetings/Main.java",
				"package com.greetings;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"	}\n" +
				"}");
		this.createFile("P2/src/module-info.java",
				"module M2 {\n" +
				"	exports org.astro;\n" +
				"	requires M1;\n" +
				"}");
		this.createFolder("P2/src/org/astro");
		this.createFile("P2/src/org/astro/Test.java",
				"package org.astro;\n" +
				"import com.greetings.Main;\n" +
				"public class Test {\n" +
				"	public static void main(String[] args) {\n" +
				"		Main.main(args);\n" +
				"	}\n" +
				"}");
		return project;
	}
	/*
	 * Two Java projects, each with one module. P2 has P1 in its build path but
	 * module M2 has no 'requires' M1. Should report unresolved type, import etc.  
	 *
	 */
	public void test007() throws Exception {
		try {
			IJavaProject project = setupP2();
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"}");
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	//requires M1;\n" +
					"}");
			waitForManualRefresh();
			project.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The type com.greetings.Main is not accessible\n" + 
					"Main cannot be resolved", 
					markers);
		} finally {
			deleteProject("P2");
		}
	}
	/*
	 * Two Java project, each with one module. P2 has P1 in its build path and
	 * module M2 'requires' M1. Should report unresolved type, import etc. But M1
	 * does not export the package that is used by M2. Test that M2 does not see
	 * the types in unexported packages.
	 *
	 */
	public void test008() throws Exception {
		try {
			IJavaProject project = setupP2();
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	//exports com.greetings;\n" +
					"}");
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires M1;\n" +
					"}");
			waitForManualRefresh();
			project.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The type com.greetings.Main is not accessible\n" + 
					"Main cannot be resolved", 
					markers);
		} finally {
			deleteProject("P2");
		}
	}
	/*
	 * Two Java projects, each with one module. P2 has P1 in its build path.
	 * Module M2 has "requires M1" in module-info and all packages used by M2 
	 * are exported by M1. No errors expected. 
	 */
	public void test009() throws Exception {
		try {
			IJavaProject project = setupP2();
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"}");
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires M1;\n" +
					"}");
			waitForManualRefresh();
			project.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"", markers);
		} finally {
			deleteProject("P2");
		}
	}
	/*
	 * Two Java projects, each with a module. Project P2 depends on P1.
	 * Module M1 exports a package to a specific module, which is not M2.
	 * Usage of types from M1 in M2 should be reported.
	 */
	public void _test010() throws Exception {
		try {
			IJavaProject project = setupP2();
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings to org.main;\n" +
					"}");
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires M1;\n" +
					"}");
			waitForManualRefresh();
			project.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The import com.greetings.Main cannot be resolved\n" + 
					"Main cannot be resolved", 
					markers);
		} finally {
			deleteProject("P2");
		}
	}
	private IJavaProject setupP3() throws CoreException {
		IJavaProject project = createJava9Project("P3");
		IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
		IClasspathEntry projectEntry = JavaCore.newProjectEntry(new Path("/P2"), null, false,
			new IClasspathAttribute[] {modAttr},
			true);
		IClasspathEntry[] old = project.getRawClasspath();
		IClasspathEntry[] newPath = new IClasspathEntry[old.length +1];
		System.arraycopy(old, 0, newPath, 0, old.length);
		newPath[old.length] = projectEntry;
		project.setRawClasspath(newPath, null);
		this.createFile("P3/src/module-info.java",
				"module M3 {\n" +
				"	exports org.main;\n" +
				"	requires M2;\n" +
				"}");
		this.createFolder("P3/src/org/main");
		this.createFile("P3/src/org/main/TestMain.java",
				"package org.main;\n" +
				"import com.greetings.*;\n" +
				"public class TestMain {\n" +
				"	public static void main(String[] args) {\n" +
				"		Main.main(args);\n" +
				"	}\n" +
				"}");
		return project;
	}
	/*
	 * Three Java projects, each with one module. Project P3 depends on P2, which depends on P1.
	 * Module M1 exports a package (to all), M2 requires M1 and M3 requires M2. Usage of types from
	 * M1 in M3 should be reported as errors.
	 */
	public void test011() throws Exception {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"}");
			IJavaProject p2 = setupP2();
			IJavaProject p3 = setupP3();
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"The package com.greetings is not accessible\n" +
					"Main cannot be resolved",
					markers);
		} finally {
			deleteProject("P2");
			deleteProject("P3");
		}
	}
	/*
	 * Three Java projects, each with one module. Project P3 depends on P2, which depends on P1.
	 * Module M1 exports a package only to M2, M2 requires M1 and M3 requires M2. Usage of types from
	 * M1 in M3 should not be allowed.
	 */
	public void test012() throws Exception {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings to M2;\n" +
					"}");
			IJavaProject p2 = setupP2();
			IJavaProject p3 = setupP3();
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires M1;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
			markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The package com.greetings is not accessible\n" + 
					"Main cannot be resolved", 
					markers);
		} finally {
			deleteProject("P2");
			deleteProject("P3");
		}
	}
	/*
	 * Three Java projects, each with one module. Project P3 depends on P2, which depends on P1.
	 * Module M1 exports a package (to all), M2 requires 'transitive' M1 and M3 requires M2. Usage of types from
	 * M1 in M3 should be allowed.
	 */
	public void test013() throws Exception {
		try {
			IJavaProject p2 = setupP2();
			IJavaProject p3 = setupP3();
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires transitive M1;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
		} finally {
			deleteProject("P2");
			deleteProject("P3");
		}
	}
	/*
	 * Three Java projects, each with one module. Project P3 depends on P2, which depends on P1.
	 * Module M1 exports a package only to M2, M2 requires 'public' M1 and M3 requires M2. Usage of types from
	 * M1 in M3 should be allowed. And no errors reported on M2.
	 */
	public void test014() throws Exception {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings to M2;\n" +
					"}");
			IJavaProject p2 = setupP2();
			IJavaProject p3 = setupP3();
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires transitive M1;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
			markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
		} finally {
			deleteProject("P2");
			deleteProject("P3");
		}
	}
	public void test015() throws CoreException, IOException {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings to M2;\n" +
					"}");
			IJavaProject p2 = setupP2();
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires transitive M1;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IFolder folder = getFolder("P1/src");
			assertNotNull("Should be a module", this.currentProject.getModuleDescription());
			folder = getFolder("P2/src");
			folder = getFolder("P1/bin");
			IPath jarPath = p2.getResource().getLocation().append("m0.jar");
			org.eclipse.jdt.core.tests.util.Util.zip(new File(folder.getLocation().toOSString()), jarPath.toOSString());
			IClasspathEntry[] old = p2.getRawClasspath();
			for (int i = 0; i < old.length; i++) {
				if (old[i].isExported()) {
					old[i] = JavaCore.newLibraryEntry(new Path("/P2/m0.jar"), null, null);
					break;
				}
			}
			p2.setRawClasspath(old, null);
			p2.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNotNull("Should be a module", p2.getModuleDescription());
		} finally {
			deleteProject("P2");
			deleteProject("P3");
		}
	}
	/*
	 * Change the module-info and wait for autobuild to 
	 * report expected errors.
	 */
	public void test016() throws CoreException, IOException {
		try {
			IJavaProject p2 = setupP2();
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires java.base;\n" +
					"	requires transitive M1;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"The type com.greetings.Main is not accessible\n" + 
					"Main cannot be resolved",  markers);
		} finally {
			deleteProject("P2");
		}
	}
	/*
	 * Change the module-info of a required module and wait for autobuild to 
	 * report expected errors.
	 */
	public void test017() throws CoreException, IOException {
		try {
			IJavaProject p2 = setupP2();
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires java.base;\n" +
					"	requires transitive M1;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	requires java.base;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"The type com.greetings.Main is not accessible\n" + 
					"Main cannot be resolved",  markers);
		} finally {
			deleteProject("P2");
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"	requires java.base;\n" +
					"}");
		}
	}
	/*
	 * Change the module-info of a required module and wait for autobuild to 
	 * report expected errors.
	 */
	public void test018() throws CoreException, IOException {
		try {
			String wkspEncoding = System.getProperty("file.encoding");
			final String encoding = "UTF-8".equals(wkspEncoding) ? "Cp1252" : "UTF-8";
			IJavaProject p2 = setupP2();
			this.editFile("P2/src/module-info.java",
					"module M2 {\n" +
					"	exports org.astro;\n" +
					"	requires java.base;\n" +
					"	requires transitive M1;\n" +
					"}");
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
			IFile bin = getFile("P1/bin/com/greetings/Main.class");
			long old = bin.getLocalTimeStamp();
			IFile file = getFile("P1/src/module-info.java");
			file.setCharset(encoding, null);
			waitForManualRefresh();
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"",  markers);
			long latest = getFile("P1/bin/com/greetings/Main.class").getLocalTimeStamp();
			assertTrue("Should not have been recompiled", old == latest);
		} finally {
			deleteProject("P2");
		}
	}
	/*
	 * Test that adding or removing java.base does not result in
	 * re-compilation of module.
	 */
	public void _test019() throws CoreException, IOException {
		try {
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"	requires java.base;\n" +
					"}");
			waitForManualRefresh();
			this.currentProject.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
			IFile bin = getFile("P1/bin/com/greetings/Main.class");
			long old = bin.getLocalTimeStamp();
			waitForManualRefresh();
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"}");
			this.currentProject.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null);
			long latest = getFile("P1/bin/com/greetings/Main.class").getLocalTimeStamp();
			assertTrue("Should not have been recompiled", old == latest);
		} finally {
			deleteProject("P2");
			this.editFile("P1/src/module-info.java",
					"module M1 {\n" +
					"	exports com.greetings;\n" +
					"	requires java.base;\n" +
					"}");
		}
	}
	public void testConvertToModule() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			IJavaProject project = setUpJavaProject("ConvertToModule");
			Map<String, String> options = new HashMap<>();
			// Make sure the new options map doesn't reset.
			options.put(CompilerOptions.OPTION_Compliance, "9");
			options.put(CompilerOptions.OPTION_Source, "9");
			options.put(CompilerOptions.OPTION_TargetPlatform, "9");
			options.put(CompilerOptions.OPTION_Release, "enabled");
			project.setOptions(options);
			project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
			IPackageFragmentRoot theRoot = null;
			for (IPackageFragmentRoot root : roots) {
				if (root.getElementName().equals("jdt.test")) {
					theRoot = root;
					break;
				}
			}
			assertNotNull("should not be null", theRoot);
			String[] modules = JavaCore.getReferencedModules(project);
			if (isJRE12)
				assertStringsEqual("incorrect result", new String[]{"java.desktop", "java.rmi", "java.sql"}, modules);
			else if (isJRE11)
				assertStringsEqual("incorrect result", new String[]{"java.datatransfer", "java.desktop", "java.net.http", "java.rmi", "java.sql"}, modules);
			else if (isJRE10)
				assertStringsEqual("incorrect result", new String[]{"java.datatransfer", "java.desktop", "java.rmi", "java.sql"}, modules);
			else // 9
				assertStringsEqual("incorrect result", new String[]{"java.desktop", "java.rmi", "java.sql"}, modules);
		} finally {
			this.deleteProject("ConvertToModule");
			 JavaCore.setOptions(javaCoreOptions);
		}
	}
	public void test_services_abstractImpl() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides org.astro.World with com.greetings.MyWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public abstract class MyWorld implements World { }\n"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Invalid service implementation, the type com.greetings.MyWorld is abstract", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_invalidImpl() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides org.astro.World with com.greetings.MyWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"public class MyWorld { }\n"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Type mismatch: cannot convert from MyWorld to World", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_NoDefaultConstructor() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyWorld;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public MyWorld(String name) { }\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"The service implementation com.greetings.MyWorld must define a public static provider method or a no-arg constructor",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_DefaultConstructorNotVisible() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyWorld;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	MyWorld() { }\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"The no-arg constructor of service implementation com.greetings.MyWorld is not public",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_DuplicateEntries() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyWorld;\n" +
				"	provides org.astro.World with com.greetings.MyWorld;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Duplicate service entry: org.astro.World",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_NestedClass() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyWorld.Nested;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld {\n" +
				"	public static class Nested implements World {\n" +
				"		public String name() {\n" +
				"			return \" My World!!\";\n" +
				"		}\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_NonStatic_NestedClass() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyWorld.Nested;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld {\n" +
				"	public class Nested implements World {\n" +
				"		public String name() {\n" +
				"			return \" My World!!\";\n" +
				"		}\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Invalid service implementation, the type com.greetings.MyWorld.Nested is an inner class",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_ImplDefinedInAnotherModule() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}",
				"src/org/astro/AstroWorld.java",
				"package org.astro;\n" +
				"public class AstroWorld implements World{\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	provides org.astro.World with org.astro.AstroWorld;\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Service implementation org.astro.AstroWorld is not defined in the module with the provides directive",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_ProviderMethod() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyImpl;\n" +
				"}",
				"src/com/greetings/MyImpl.java",
				"package com.greetings;\n" +
				"public class MyImpl {\n" +
				"	public static MyWorld provider() {\n" +
				"		return new MyWorld(\"Name\");\n" +
				"	}\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public MyWorld(String name) { }\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_ProviderMethod_ReturnTypeFromAnotherModule() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources, true);
			sources = new String[] {
				"src/module-info.java",
				"module other.mod {\n" +
				"	requires org.astro;\n" + 
				"	exports org.impl;\n" + 
				"}",
				"src/org/impl/MyWorld.java",
				"package org.impl;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			setupModuleProject("other.mod", sources, true);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	requires transitive other.mod;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyImpl;\n" +
				"}",
				"src/com/greetings/MyImpl.java",
				"package com.greetings;\n" +
				"import org.impl.MyWorld;\n" +
				"public class MyImpl {\n" +
				"	public static MyWorld provider() {\n" +
				"		return new MyWorld();\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p3 = setupModuleProject("com.greetings", src, true);
			p3.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("other.mod");
			deleteProject("com.greetings");
		}
	}
	public void test_services_ProviderMethod_ReturnTypeInvisible() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources, true);
			sources = new String[] {
				"src/module-info.java",
				"module other.mod {\n" +
				"	requires org.astro;\n" + 
				"}",
				"src/org/impl/MyWorld.java",
				"package org.impl;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			setupModuleProject("other.mod", sources, true);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	requires other.mod;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyImpl;\n" +
				"}",
				"src/com/greetings/MyImpl.java",
				"package com.greetings;\n" +
				"import org.impl.MyWorld;\n" +
				"public class MyImpl {\n" +
				"	public static MyWorld provider() {\n" +
				"		return new MyWorld();\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p3 = setupModuleProject("com.greetings", src, true);
			p3.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().getFile(new Path("src/module-info.java")).findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"MyWorld cannot be resolved to a type",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("other.mod");
			deleteProject("com.greetings");
		}
	}
	public void test_services_ProviderMethod_InvalidReturnType() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyImpl;\n" +
				"}",
				"src/com/greetings/MyImpl.java",
				"package com.greetings;\n" +
				"public class MyImpl {\n" +
				"	public static MyWorld provider() {\n" +
				"		return new MyWorld(\"Name\");\n" +
				"	}\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"public class MyWorld {\n" +
				"	public MyWorld(String name) { }\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"Type mismatch: cannot convert from MyWorld to World",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_DuplicateImplEntries() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyWorld, com.greetings.MyWorld;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Duplicate service entry: com.greetings.MyWorld",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_InvalidIntfType() throws CoreException {
		try {
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	exports com.greetings;\n" +
				"	provides com.greetings.MyEnum with com.greetings.MyEnum;\n" +
				"}",
				"src/com/greetings/MyEnum.java",
				"package com.greetings;\n" +
				"public enum MyEnum {}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src);
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"Invalid service interface com.greetings.MyEnum, must be a class, interface or annotation type\n" +
					"Invalid service implementation com.greetings.MyEnum, must be a public class or interface type",  markers);
		} finally {
			deleteProject("com.greetings");
		}
	}
	public void test_services_InvalidImplType() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyEnum;\n" +
				"}",
				"src/com/greetings/MyEnum.java",
				"package com.greetings;\n" +
				"public enum MyEnum implements org.astro.World {}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Invalid service implementation com.greetings.MyEnum, must be a public class or interface type",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_services_nonPublicImpl() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"	provides org.astro.World with com.greetings.MyWorld;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"The type com.greetings.MyWorld is not visible",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_Exports_Error() throws CoreException {
		try {
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	exports com.greetings;\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src);
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	
					"The package com.greetings does not exist or is empty",  markers);
		} finally {
			deleteProject("com.greetings");
		}
	}
	public void test_DuplicateExports() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	
					"Duplicate exports entry: org.astro",  markers);
		} finally {
			deleteProject("org.astro");
		}
	}
	public void test_TargetedExports_Duplicates() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro to com.greetings, com.greetings;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath());
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	
					"Duplicate module name: com.greetings",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	// Types from source module should be resolved in target module
	// when package is exported specifically to the target module
	public void test_TargetedExports() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro to com.greetings;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	// Types in one module should not be visible in target module when
	// source module exports packages to a specific module which is not
	// the same as the target module
	public void test_TargetedExports_Error() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module some.mod { }",
			};
			setupModuleProject("some.mod", sources);
			sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro to some.mod;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",	
					"The type org.astro.World is not accessible\n" +
					"World cannot be resolved to a type",
					markers);
		} finally {
			deleteProject("some.mod");
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	// It is permitted for the to clause of an exports or opens statement to 
	// specify a module which is not observable
	public void test_TargetedExports_Unresolved() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro to some.mod;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("org.astro");
		}
	}
	// Target module of an exports statement should be resolved without having an explicit
	// dependency to the project that defines the module
	public void test_TargetedExports_Resolution() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"}"
			};
			setupModuleProject("some.mod", sources);
			sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro to some.mod;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
		}
	}
	// Make sure modules in the workspace are resolved via the module source path container
	// without needing to add a dependency to the project explicitly
	public void test_ModuleSourcePathContainer() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	// Make sure module path container picks up changes to module-info
	public void _test_ModuleSourcePath_update() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"}"
			};
			setupModuleProject("some.mod", sources);
			sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			this.editFile("com.greetings/src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	requires some.mod;\n" +
				"	exports com.greetings;\n" +
				"}");
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
			deleteProject("com.greetings");
		}
	}
	// Implicit module dependencies via the 'requires transitive' directive should be
	// resolved via the module path container
	public void test_ModuleSourcePath_implicitdeps() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"	requires transitive org.astro;\n" +
				"}"
			};
			setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires some.mod;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
			deleteProject("com.greetings");
		}
	}
	// Changes to implicit dependencies should be reflected // FIXME: container JavaCore.MODULE_PATH_CONTAINER_ID is unreliable
	public void _test_ModuleSourcePath_implicitdeps2() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"	requires transitive org.astro;\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires some.mod;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			this.editFile("some.mod/src/module-info.java",
				"module some.mod {\n" +
				"	requires org.astro;\n" +
				"}");
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The type org.astro.World is not accessible\n" +
					"World cannot be resolved to a type",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
			deleteProject("com.greetings");
		}
	}
	// Changes to implicit dependencies should be reflected
	//TODO enable once we know how to update project cache
	public void _test_ModuleSourcePath_implicitdeps3() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"	requires org.astro;\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires some.mod;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			this.editFile("some.mod/src/module-info.java",
				"module some.mod {\n" +
				"	requires transitive org.astro;\n" +
				"}");
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
			deleteProject("com.greetings");
		}
	}
	public void test_Cycle_In_Module_Dependency() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" +
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"	requires org.astro;\n" +
				"}"
			};
			setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires some.mod;\n" +
				"	exports com.greetings;\n" +
				"}"
			};
			
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			editFile("org.astro/src/module-info.java", 
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"	requires com.greetings;\n" +
					"}");
			waitForAutoBuild();
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertTrue("Should detect cycle", p2.hasClasspathCycle(null));
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
			deleteProject("com.greetings");
		}
	}
	public void test_Cycle_In_Implicit_Module_Dependency() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" +
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"	requires transitive org.astro;\n" +
				"}"
			};
			setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires some.mod;\n" +
				"	exports com.greetings;\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			editFile("org.astro/src/module-info.java", 
				"module org.astro {\n" +
				"	exports org.astro;\n" +
				"	requires transitive com.greetings;\n" +
				"}");
			waitForAutoBuild();
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertTrue("Should detect cycle", p2.hasClasspathCycle(null));
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
			deleteProject("com.greetings");
		}
	}
	public void test_bug506479() throws CoreException {
		try {
			String[] sources = new String[] {
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
				};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			IWorkspaceDescription desc = p1.getProject().getWorkspace().getDescription();
			desc.setAutoBuilding(false);
			p1.getProject().getWorkspace().setDescription(desc);
			this.deleteFile("org.astro/src/module-info.java");
			this.createFile(
					"org.astro/src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}");
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
		} finally {
			deleteProject("org.astro");
		}
	}
	public void test_Multiple_SourceFolders() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}",
				"othersrc/org/astro/OtherWorld.java",
				"package org.astro;\n" +
				"import org.astro.World;\n" +
				"public interface OtherWorld {\n" +
				"	default public String name() {\n" +
				"		return \" Other World!!\";\n" +
				"	}\n" +
				"}"
			};
			setupModuleProject("org.astro", new String[]{"src", "othersrc"}, sources, null);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}",
				"othersrc/com/greetings/AnotherWorld.java",
				"package com.greetings;\n" +
				"import org.astro.OtherWorld;\n" +
				"public class AnotherWorld implements OtherWorld {\n" +
				"	public String name() {\n" +
				"		return \" Another World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p2 = setupModuleProject("com.greetings", new String[]{"src", "othersrc"}, src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_Multiple_SourceFolders_WithModuleInfo() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}",
				"othersrc/org/astro/OtherWorld.java",
				"package org.astro;\n" +
				"import org.astro.World;\n" +
				"public interface OtherWorld {\n" +
				"	default public String name() {\n" +
				"		return \" Other World!!\";\n" +
				"	}\n" +
				"}"
			};
			setupModuleProject("org.astro", new String[]{"src", "othersrc"}, sources, null);
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}",
				"othersrc/module-info.java",
				"module com.greetings1 {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"othersrc/com/greetings/AnotherWorld.java",
				"package com.greetings;\n" +
				"import org.astro.OtherWorld;\n" +
				"public class AnotherWorld implements OtherWorld {\n" +
				"	public String name() {\n" +
				"		return \" Another World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p2 = setupModuleProject("com.greetings", new String[]{"src", "othersrc"}, src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ZERO);
			assertEquals(1, markers.length);
			String msg = markers[0].getAttribute(IMarker.MESSAGE, "");
			String expected = Messages.bind(Messages.classpath_duplicateEntryPath, TypeConstants.MODULE_INFO_FILE_NAME_STRING, p2.getElementName());
			assertTrue("Unexpected result", msg.indexOf(expected) != -1);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_Multiple_SourceFolders_addModuleInfo() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}",
				"othersrc/org/astro/OtherWorld.java",
				"package org.astro;\n" +
				"import org.astro.World;\n" +
				"public interface OtherWorld {\n" +
				"	default public String name() {\n" +
				"		return \" Other World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", new String[]{"src", "othersrc"}, sources, null);
			this.createFile("org.astro/othersrc/module-info.java", 
					"module org.astro1 {\n" +
					"	exports org.astro;\n" + 
					"}");
			waitForAutoBuild();
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ZERO);
			assertEquals(1, markers.length);
			String msg = markers[0].getAttribute(IMarker.MESSAGE, "");
			String expected = Messages.bind(Messages.classpath_duplicateEntryPath, TypeConstants.MODULE_INFO_FILE_NAME_STRING, p1.getElementName());
			assertTrue("Unexpected result", msg.indexOf(expected) != -1);
		} finally {
			deleteProject("org.astro");
		}
	}
	public void test_Multiple_SourceFolders_removeModuleInfo() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}",
				"othersrc/module-info.java",
				"module org.astro1 {\n" +
				"	exports org.astro;\n" + 
				"}",
				"othersrc/org/astro/OtherWorld.java",
				"package org.astro;\n" +
				"import org.astro.World;\n" +
				"public interface OtherWorld {\n" +
				"	default public String name() {\n" +
				"		return \" Other World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", new String[]{"src", "othersrc"}, sources, null);
			waitForAutoBuild();
			this.deleteFile("org.astro/othersrc/module-info.java");
			waitForAutoBuild();
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ZERO);
			assertEquals(0, markers.length);
		} finally {
			deleteProject("org.astro");
		}
	}
	public void test_services_multipleImpl() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"import org.astro.World;\n" +
					"import com.greetings.*;\n" +
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides World with MyWorld, AnotherWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}",
					"src/com/greetings/AnotherWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class AnotherWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" Another World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_imports_in_moduleinfo() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"import org.astro.World;\n" +
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides World with com.greetings.MyWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}

	public void test_Opens_Nonexistent_Package() throws CoreException {
		try {
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	opens com.greetings;\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src);
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			deleteProject("com.greetings");
		}
	}
	public void test_Opens_Alien_Package() throws CoreException {
		try {
			String[] src = new String[] {
				"src/module-info.java",
				"module org.astro {}",
				"src/org/astro/World.java",
				"package org.astro;\n" + 
				"public interface World {\n" + 
				"    public String name();\n" + 
				"}\n"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	opens org.astro;\n" +
				"}",
				"src/test/Test.java",
				"package test;\n" +
				"public class Test {\n" +
				"	org.astro.World w = null;\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute(IClasspathAttribute.MODULE, "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",	
					"The type org.astro.World is not accessible\n" +
					"The package org.astro does not exist or is empty",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_DuplicateOpens() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	opens org.astro;\n" + 
				"	opens org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	
					"Duplicate opens entry: org.astro",  markers);
		} finally {
			deleteProject("org.astro");
		}
	}
	public void test_TargetedOpens_Duplicates() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	opens org.astro to com.greetings, com.greetings;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath());
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	
					"Duplicate module name: com.greetings",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	// It is permitted for the to clause of an exports or opens statement to 
	// specify a module which is not observable
	public void test_TargetedOpens_Unresolved() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	opens org.astro to some.mod;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("org.astro");
		}
	}
	// It is a compile-time error if an opens statement appears in the declaration of an open module. 
	public void test_OpensStatment_in_OpenModule() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"open module org.astro {\n" +
				"	opens org.astro to some.mod;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	
				"opens statement is not allowed, as module org.astro is declared open",  markers);
		} finally {
			deleteProject("org.astro");
		}
	}
	public void test_uses_DuplicateEntries() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" +
				"	uses org.astro.World;\n" +
				"	uses org.astro.World;\n" +
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Duplicate uses entry: org.astro.World",  markers);
		} finally {
			deleteProject("org.astro");
		}
	}
	public void test_uses_InvalidIntfType() throws CoreException {
		try {
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	exports com.greetings;\n" +
				"	uses com.greetings.MyEnum;\n" +
				"}",
				"src/com/greetings/MyEnum.java",
				"package com.greetings;\n" +
				"public enum MyEnum {}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src);
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"Invalid service interface com.greetings.MyEnum, must be a class, interface or annotation type",  markers);
		} finally {
			deleteProject("com.greetings");
		}
	}
	public void test_ReconcilerModuleLookup1() throws CoreException {
		try {
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires java.sql;\n" +
				"}"};
			setupModuleProject("com.greetings", src);
			this.workingCopies = new ICompilationUnit[1];
			char[] sourceChars = src[1].toCharArray();
			this.problemRequestor.initialize(sourceChars);
			this.workingCopies[0] = getCompilationUnit("/com.greetings/src/module-info.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject("com.greetings");
		}
	}
	public void test_ReconcilerModuleLookup2() throws CoreException {
		try {
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires java.sq;\n" +
				"}"};
			setupModuleProject("com.greetings", src);
			this.workingCopies = new ICompilationUnit[1];
			char[] sourceChars = src[1].toCharArray();
			this.problemRequestor.initialize(sourceChars);
			this.workingCopies[0] = getCompilationUnit("/com.greetings/src/module-info.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"1. ERROR in /com.greetings/src/module-info.java (at line 2)\n" + 
					"	requires java.sq;\n" + 
					"	         ^^^^^^^\n" + 
					"java.sq cannot be resolved to a module\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject("com.greetings");
		}
	}
	public void testSystemLibAsJMod() throws CoreException {
		try {
			IJavaProject project = createJava9Project("Test01", new String[]{"src"});
			IClasspathEntry[] rawClasspath = project.getRawClasspath();
			for (int i = 0; i < rawClasspath.length; i++) {
				IPath path = rawClasspath[i].getPath();
				if (path.lastSegment().equals("jrt-fs.jar")) {
					path = path.removeLastSegments(2).append("jmods").append("java.base.jmod");
					IClasspathEntry newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), new Path("java.base"));
					rawClasspath[i] = newEntry;
				}
			}
			project.setRawClasspath(rawClasspath, null);
			this.createFile("Test01/src/module-info.java", "");
			this.createFolder("Test01/src/com/greetings");
			this.createFile("Test01/src/com/greetings/Main.java", "");
			waitForManualRefresh();
			waitForAutoBuild();
			project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
			IPackageFragmentRoot base = null;
			for (IPackageFragmentRoot iRoot : roots) {
				IModuleDescription moduleDescription = iRoot.getModuleDescription();
				if (moduleDescription != null) {
					base = iRoot;
					break;
				}
			}
			assertNotNull("Java.base module should not null", base);
			assertMarkers("Unexpected markers", "", project);
		} finally {
			deleteProject("Test01");
		}
	}
	public void testSystemLibAsJMod_2() throws CoreException {
		try {
			IJavaProject project = createJava9Project("Test01", new String[]{"src"});
			IClasspathEntry[] rawClasspath = project.getRawClasspath();
			IClasspathEntry[] newClasspath = new IClasspathEntry[rawClasspath.length + 1];
			IClasspathEntry desktop = null;
			for (int i = 0; i < rawClasspath.length; i++) {
				IPath path = rawClasspath[i].getPath();
				if (path.lastSegment().equals("jrt-fs.jar")) {
					path = path.removeLastSegments(2).append("jmods").append("java.base.jmod");
					IClasspathAttribute[] attributes = {
							JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
					IClasspathEntry newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(),
							new Path("java.base"), null, attributes, rawClasspath[i].isExported());
					newClasspath[i] = newEntry;
					path = path.removeLastSegments(2).append("jmods").append("java.desktop.jmod");
					desktop = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(),
							new Path("java.desktop"), null, attributes, rawClasspath[i].isExported());
				} else {
					newClasspath[i] = rawClasspath[i];
				}
			}
			newClasspath[rawClasspath.length] = desktop;
			project.setRawClasspath(newClasspath, null);
			this.createFile("Test01/src/module-info.java", 
					"module org.eclipse {\n" + 
					"	requires java.desktop;\n" + 
					"	requires java.base;\n" + 
					"}");
			waitForManualRefresh();
			waitForAutoBuild();
			project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
			assertMarkers("unexpected markers", "", markers);

			// Check the reconciler
			ICompilationUnit cu = getCompilationUnit("/Test01/src/module-info.java");
			cu.getWorkingCopy(this.wcOwner, null);
			markers = project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
			editFile("Test01/src/module-info.java", 
					"//Just touching \n" +
					"module org.eclipse {\n" + 
					"	requires java.desktop;\n" + 
					"	requires java.base;\n" + 
					"}");
			project.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			markers = project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
			assertMarkers("unexpected markers", "", markers);
		} finally {
			deleteProject("Test01");
		}
	}
	public void testBug510617() throws CoreException {
		try {
			String[] src = new String[] {
				"src/module-info.java",
				"module Test {\n" +
				"	exports p;\n" +
				"	requires java.sql;\n" + 
				"	provides java.sql.Driver with p.C;\n" +
				"}",
				"src/p/C.java",
				"package p;\n" + 
				"import java.lang.SecurityManager;\n" + 
				"import java.sql.Connection;\n" + 
				"import java.sql.Driver;\n" + 
				"import java.sql.DriverPropertyInfo;\n" + 
				"import java.sql.SQLException;\n" + 
				"import java.sql.SQLFeatureNotSupportedException;\n" + 
				"import java.util.Properties;\n" + 
				"import java.util.logging.Logger;\n" + 
				"public class C implements Driver {\n" + 
				"	SecurityManager s;\n" + 
				"	@Override\n" + 
				"	public boolean acceptsURL(String arg0) throws SQLException {\n" + 
				"		return false;\n" + 
				"	}\n" + 
				"	@Override\n" + 
				"	public Connection connect(String arg0, Properties arg1) throws SQLException {\n" + 
				"		return null;\n" + 
				"	}\n" + 
				"	@Override\n" + 
				"	public int getMajorVersion() {\n" + 
				"		return 0;\n" + 
				"	}\n" + 
				"	@Override\n" + 
				"	public int getMinorVersion() {\n" + 
				"		return 0;\n" + 
				"	}\n" + 
				"	@Override\n" + 
				"	public Logger getParentLogger() throws SQLFeatureNotSupportedException {\n" + 
				"		return null;\n" + 
				"	}\n" + 
				"	@Override\n" + 
				"	public DriverPropertyInfo[] getPropertyInfo(String arg0, Properties arg1) throws SQLException {\n" + 
				"		return null;\n" + 
				"	}\n" + 
				"	@Override\n" + 
				"	public boolean jdbcCompliant() {\n" + 
				"		return false;\n" + 
				"	} \n" + 
				"}"
			};
			setupModuleProject("Test", src);
			this.workingCopies = new ICompilationUnit[1];
			char[] sourceChars = src[1].toCharArray();
			this.problemRequestor.initialize(sourceChars);
			this.workingCopies[0] = getCompilationUnit("/Test/src/module-info.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" + 
				"----------\n",
				this.problemRequestor);
		} finally {
			deleteProject("Test");
		}
	}
	public void test_annotations_in_moduleinfo() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}",
					"src/org/astro/Foo.java",
					"package org.astro;\n" +
					"public @interface Foo {}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"import org.astro.Foo;\n" +
					"import org.astro.World;\n" +
					"@Foo\n" +
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides World with com.greetings.MyWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_unresolved_annotations() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}",
					"src/org/astro/Foo.java",
					"package org.astro;\n" +
					"public @interface Foo {}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"import org.astro.Foo;\n" +
					"import org.astro.World;\n" +
					"@Foo @Bar\n" +
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides World with com.greetings.MyWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"Bar cannot be resolved to a type", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_illegal_modifiers() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}",
					"src/org/astro/Foo.java",
					"package org.astro;\n" +
					"public @interface Foo {}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"import org.astro.Foo;\n" +
					"import org.astro.World;\n" +
					"@Foo\n" +
					"private static module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides World with com.greetings.MyWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"Illegal modifier for module com.greetings; only open is permitted", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_annotations_with_target() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}",
					"src/org/astro/Foo.java",
					"package org.astro;\n" +
					"import java.lang.annotation.ElementType;\n" +
					"import java.lang.annotation.Target;\n" +
					"@Target(ElementType.MODULE)\n" +
					"public @interface Foo {}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"import org.astro.Foo;\n" +
					"import org.astro.World;\n" +
					"@Foo\n" +
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides World with com.greetings.MyWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void test_annotations_with_wrong_target() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}",
					"src/org/astro/Foo.java",
					"package org.astro;\n" +
					"import java.lang.annotation.ElementType;\n" +
					"import java.lang.annotation.Target;\n" +
					"@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE})\n" +
					"public @interface Foo {}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			String[] src = new String[] { 
					"src/module-info.java",
					"import org.astro.Foo;\n" +
					"import org.astro.World;\n" +
					"@Foo\n" +
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports com.greetings;\n" +
					"	provides World with com.greetings.MyWorld;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"The annotation @Foo is disallowed for this location", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void testBug518334() throws CoreException, IOException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	requires java.sql;\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			waitForAutoBuild();
			// set options
			Map<String, String> options = new HashMap<>();
			options.put(CompilerOptions.OPTION_Compliance, "1.8");
			options.put(CompilerOptions.OPTION_Source, "1.8");
			options.put(CompilerOptions.OPTION_TargetPlatform, "1.8");
			p1.setOptions(options);
//			waitForAutoBuild();
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertTrue("Module declaration incorrectly accepted below 9", markers.length > 0);
		} finally {
			deleteProject("org.astro");
		}
	}
	public void testBug518334a() throws CoreException {
		try {
			String[] sources = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}" 
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources);
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath());
			String[] src = new String[] { 
					"src/module-info.java",
					"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			waitForAutoBuild();
			// set options
			Map<String, String> options = new HashMap<>();
			options.put(CompilerOptions.OPTION_Compliance, "1.8");
			options.put(CompilerOptions.OPTION_Source, "1.8");
			options.put(CompilerOptions.OPTION_TargetPlatform, "1.8");
			p1.setOptions(options);

			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"org.astro cannot be resolved to a module", markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}

	public void test_api_leak_1() throws CoreException {
		try {
			String[] sources1 = {
								"src/module-info.java", 
								"module mod.one { \n" +
								"	exports pm;\n" +
								"}",
								"src/impl/Other.java", 
								"package impl;\n" +
								"public class Other {\n" +
								"}\n",
								"src/pm/C1.java", 
								"package pm;\n" +
								"import impl.Other;\n" + 
								"public class C1 extends Other {\n" +
								"	public void m1(Other o) {}\n" + 
								"}\n"
							};
			IJavaProject p1 = setupModuleProject("mod.one", sources1);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);

			String[] sources2 = {
								"src/module-info.java", 
								"module mod.two { \n" +
								"	requires mod.one;\n" +
								"}",
								"src/impl/Other.java", 
								"package impl;\n" +
								"public class Other {\n" +
								"}\n",
								"src/po/Client.java", 
								"package po;\n" + 
								"import pm.C1;\n" + 
								"public class Client {\n" + 
								"    void test1(C1 one) {\n" + 
								"        one.m1(one);\n" + 
								"    }\n" + 
								"}\n"
							};
			IJavaProject p2 = setupModuleProject("mod.two", sources2, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);

			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject("mod.one");
			deleteProject("mod.two");
		}
	}

	/**
	 * Same-named classes should not conflict, since one is not accessible.
	 * Still a sub class of the inaccessible class can be accessed and used for a method argument.
	 */
	public void test_api_leak_2() throws CoreException {
		try {
			String[] sources1 = {
						"src/module-info.java", 
						"module mod.one { \n" +
						"	exports pm;\n" +
						"}",
						"src/impl/SomeImpl.java", 
						"package impl;\n" +
								"public class SomeImpl {\n" +
						"}\n",
						"src/pm/C1.java", 
						"package pm;\n" +
						"import impl.SomeImpl;\n" + 
						"public class C1 {\n" +
						"	public void m1(SomeImpl o) {}\n" + 
						"}\n",
						"src/pm/Other.java", 
						"package pm;\n" +
								"import impl.SomeImpl;\n" + 
								"public class Other extends SomeImpl {\n" +
						"}\n"
					};
			IJavaProject p1 = setupModuleProject("mod.one", sources1);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);

			String[] sources2 = {
						"src/module-info.java",
						"module mod.two { \n" +
						"	requires mod.one;\n" +
						"}",
						"src/impl/SomeImpl.java", 
						"package impl;\n" +
								"public class SomeImpl {\n" + // pseudo-conflict to same named, but inaccessible class from mod.one
						"}\n",
						"src/po/Client.java", 
						"package po;\n" + 
						"import pm.C1;\n" + 
						"import pm.Other;\n" +
						"import impl.SomeImpl;\n" + 
						"public class Client {\n" + 
						"    void test1(C1 one) {\n" +
						"		 SomeImpl impl = new SomeImpl();\n" + // our own version 
						"        one.m1(impl);\n" + // incompatible to what's required 
						"		 one.m1(new Other());\n" + // OK
						"    }\n" + 
						"}\n",
					};
			String expectedError = "The method m1(impl.SomeImpl) in the type C1 is not applicable for the arguments (impl.SomeImpl)";
			IJavaProject p2 = setupModuleProject("mod.two", sources2, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", expectedError, markers);

			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", expectedError, markers);
		} finally {
			deleteProject("mod.one");
			deleteProject("mod.two");
		}
	}
	
	public void testNonPublic1() throws CoreException {
		try {
			String[] sources1 = {
					"src/module-info.java", 
					"module mod.one { \n" +
					"	exports pm;\n" +
					"}",
					"src/pm/C1.java", 
					"package pm;\n" +
					"class C1 {\n" +
					"	public void test() {}\n" +
					"}\n"
			};
			IJavaProject p1 = setupModuleProject("mod.one", sources1);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);

			String[] sources2 = {
					"src/module-info.java", 
					"module mod.two { \n" +
					"	requires mod.one;\n" +
					"}",
					"src/pm/sub/C2.java", 
					"package pm.sub;\n" +
					"class C2 {\n" +
					"	public void foo() {}\n" +
					"}\n",
					"src/po/Client.java", 
					"package po;\n" + 
					"import pm.*;\n" + // package is exported but type C1 is not public
					"public class Client {\n" + 
					"    void test1(C1 one) {\n" +
					"        one.test();\n" + 
					"    }\n" + 
					"}\n"
			};

			IJavaProject p2 = setupModuleProject("mod.two", sources2, new IClasspathEntry[] { dep });
			this.workingCopies = new ICompilationUnit[3];
			this.workingCopies[0] = getCompilationUnit("/mod.two/src/module-info.java").getWorkingCopy(this.wcOwner, null);
			this.workingCopies[1] = getCompilationUnit("/mod.two/src/pm/sub/C2.java").getWorkingCopy(this.wcOwner, null);
			this.problemRequestor.initialize(sources2[5].toCharArray());
			this.workingCopies[2] = getCompilationUnit("/mod.two/src/po/Client.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"1. ERROR in /mod.two/src/po/Client.java (at line 4)\n" + 
					"	void test1(C1 one) {\n" + 
					"	           ^^\n" + 
					"The type C1 is not visible\n" + 
					"----------\n" + 
					"2. ERROR in /mod.two/src/po/Client.java (at line 5)\n" + 
					"	one.test();\n" + 
					"	^^^\n" + 
					"The type C1 is not visible\n" + 
					"----------\n",
					this.problemRequestor);

			String expectedError = "The type C1 is not visible\n" + 
									"The type C1 is not visible";
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", expectedError, markers);

			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", expectedError, markers);
		} finally {
			deleteProject("mod.one");
			deleteProject("mod.two");
		}
	}
	// test that two packages with the same name result in conflict if they are both
	// accessible to a module
	public void test_conflicting_packages() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"	exports org.astro;\n" +
				"}",
				"src/org/astro/Test.java",
				"package org.astro;\n" +
				"public class Test { }"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires some.mod;\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					// reported against both 'requires' directives & against the import:
					"The package org.astro is accessible from more than one module: org.astro, some.mod\n" +
					"The package org.astro is accessible from more than one module: org.astro, some.mod\n" +
					"The package org.astro is accessible from more than one module: org.astro, some.mod\n" +
					"World cannot be resolved to a type",
					markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
			deleteProject("com.greetings");
		}
	}

	// test that the compilation of a class using same package defined in the java.util module
	// works if a special option is given
	public void test_no_conflicting_packages_for_debugger_global() throws CoreException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			Hashtable<String, String> newOptions=new Hashtable<>(javaCoreOptions);
			newOptions.put(CompilerOptions.OPTION_JdtDebugCompileMode, JavaCore.ENABLED);
			JavaCore.setOptions(newOptions);
			String[] sources = new String[] {
					"src/java/util/Map___.java",
					"package java.util;\n" +
					"abstract class Map___ implements java.util.Map {\n" +
					"  Map___() {\n" +
					"    super();\n" +
					"  }\n" +
					"  Object[] ___run() throws Throwable {\n" +
					"    return entrySet().toArray();\n" +
					"  }\n" +
					"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p1= setupModuleProject("debugger_project", sources, new IClasspathEntry[]{dep});
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();

			assertNull("Option should not be stored", JavaCore.getOption(CompilerOptions.OPTION_JdtDebugCompileMode));
		} finally {
			deleteProject("debugger_project");
			JavaCore.setOptions(javaCoreOptions);
		}
	}

	// test that the special OPTION_JdtDebugCompileMode cannot be persisted on a project
	public void test_no_conflicting_packages_for_debugger_project() throws CoreException {
		try {
			String[] sources = new String[] {
					"src/java/util/Map___.java",
					"package java.util;\n" +
					"abstract class Map___ implements java.util.Map {\n" +
					"  Map___() {\n" +
					"    super();\n" +
					"  }\n" +
					"  Object[] ___run() throws Throwable {\n" +
					"    return entrySet().toArray();\n" +
					"  }\n" +
					"}"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p1= setupModuleProject("debugger_project", sources, new IClasspathEntry[]{dep});
			p1.setOption(CompilerOptions.OPTION_JdtDebugCompileMode, JavaCore.ENABLED);
			assertNull("Option should not be stored", p1.getOption(CompilerOptions.OPTION_JdtDebugCompileMode, false));
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The package java.util conflicts with a package accessible from another module: java.base\n" +
					"The package java.util is accessible from more than one module: <unnamed>, java.base\n" +
					"The method entrySet() is undefined for the type Map___",
					markers);
		} finally {
			deleteProject("debugger_project");
		}
	}

	// test that a package declared in a module conflicts with an accessible package
	// of the same name declared in another required module
	public void test_conflicting_packages_declaredvsaccessible() throws CoreException {
		try {
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/org/astro/Test.java",
				"package org.astro;\n" +
				"public class Test {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"public class MyWorld implements org.astro.World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The package org.astro conflicts with a package accessible from another module: org.astro\n" +
					"The package org.astro is accessible from more than one module: com.greetings, org.astro",
					markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	// accessible package bundle.org contains type astro
	// accessible package bundle.org.astro contains type World
	// Type bundle.org.astro.World should not be resolved, because type
	// bundle.org.astro trumps package bundle.org.astro
	public void test_conflict_packagevstype() throws CoreException {
		try {
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports bundle.org.astro;\n" + 
				"}",
				"src/bundle/org/astro/World.java",
				"package bundle.org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
					"src/module-info.java",
					"module other.mod {\n" +
					"	exports bundle.org;\n" + 
					"}",
					"src/bundle/org/astro.java",
					"package bundle.org;\n" +
					"public class astro {}"
				};
			setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	requires other.mod;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"public class MyWorld implements bundle.org.astro.World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"bundle.org.astro.World cannot be resolved to a type",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("other.mod");
			deleteProject("com.greetings");
		}
	}
	// package bundle.org contains type astro, but the package is not accessible
	// accessible package bundle.org.astro contains type World
	// type bundle.org.astro.World should be resolved because type bundle.org.astro
	// cannot be seen
	// TODO - to be confirmed with spec
	public void test_noconflict_concealedtype_accessiblepackage() throws CoreException {
		try {
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports bundle.org.astro;\n" + 
				"}",
				"src/bundle/org/astro/World.java",
				"package bundle.org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
					"src/module-info.java",
					"module other.mod {\n" +
					"}",
					"src/bundle/org/astro.java",
					"package bundle.org;\n" +
					"public class astro {}"
				};
			setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	requires other.mod;\n" +
				"	exports com.greetings;\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"public class MyWorld implements bundle.org.astro.World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("other.mod");
			deleteProject("com.greetings");
		}
	}
	// test that two packages of the same name exported by two named modules result in
	// a conflict in the context of a non-modular project
	public void test_conflicting_packages_unnamed() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/module-info.java",
				"module some.mod {\n" +
				"	exports org.astro;\n" +
				"}",
				"src/org/astro/Test.java",
				"package org.astro;\n" +
				"public class Test { }"
			};
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p1 = setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p2 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"import org.astro.World;\n" +
				"public class MyWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p3 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1, dep2 });
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The package org.astro is accessible from more than one module: org.astro, some.mod\n" +
					"World cannot be resolved to a type",
					markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("some.mod");
			deleteProject("com.greetings");
		}
	}
	// test that a package declared in a non-modular project conflicts with a package with the same name
	// exported by a named module on it's build path
	public void test_conflict_unnamed_declaredvsexported() throws CoreException {
		try {
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" + 
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/org/astro/Test.java",
				"package org.astro;\n" +
				"public class Test {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"public class MyWorld implements org.astro.World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1 });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The package org.astro conflicts with a package accessible from another module: org.astro\n" +
					"The package org.astro is accessible from more than one module: <unnamed>, org.astro",
					markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	// test that a type in an accessible package trumps an accessible package with the same name
	// in the context of a non-modular project
	public void test_conflict_packagevstype_unnamed() throws CoreException {
		try {
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports bundle.org.astro;\n" + 
				"}",
				"src/bundle/org/astro/World.java",
				"package bundle.org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
					"src/module-info.java",
					"module other.mod {\n" +
					"	exports bundle.org;\n" + 
					"}",
					"src/bundle/org/astro.java",
					"package bundle.org;\n" +
					"public class astro {}"
				};
			IJavaProject p2 = setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"public class MyWorld implements bundle.org.astro.World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p3 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1, dep2 });
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"bundle.org.astro.World cannot be resolved to a type",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("other.mod");
			deleteProject("com.greetings");
		}
	}
	// test that a conflicting package does not cause an error when resolving a sub package name
	// when the sub package is accessible in the context of a non-modular project
	public void test_noconflict_subpkg_unnamed() throws CoreException {
		try {
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports bundle.org.astro;\n" + 
				"}",
				"src/bundle/org/astro/World.java",
				"package bundle.org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
					"src/module-info.java",
					"module other.mod {\n" +
					"	exports bundle.org;\n" + 
					"}",
					"src/bundle/org/astro.java",
					"package bundle.org;\n" +
					"public class astro {}"
				};
			IJavaProject p2 = setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/bundle/org/Test.java",
				"package bundle.org;\n" +
				"public class Test {}",
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"public class MyWorld implements bundle.org.astro.World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p3 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1, dep2 });
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The package bundle.org conflicts with a package accessible from another module: other.mod\n" + 
					"The package bundle.org is accessible from more than one module: <unnamed>, other.mod",
					markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("other.mod");
			deleteProject("com.greetings");
		}
	}
	// test that a type in a non-accessible package does not conflict with an accessible package
	// in the context of a non-modular project
	public void test_noconflict_concealedtype_accessiblepackage_unnamed() throws CoreException {
		try {
			IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			String[] sources = new String[] {
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports bundle.org.astro;\n" + 
				"}",
				"src/bundle/org/astro/World.java",
				"package bundle.org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep});
			sources = new String[] {
					"src/module-info.java",
					"module other.mod {\n" +
					"}",
					"src/bundle/org/astro.java",
					"package bundle.org;\n" +
					"public class astro {}"
				};
			IJavaProject p2 = setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep});
			String[] src = new String[] {
				"src/com/greetings/MyWorld.java",
				"package com.greetings;\n" +
				"public class MyWorld implements bundle.org.astro.World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p3 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1, dep2 });
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("other.mod");
			deleteProject("com.greetings");
		}
	}
	public void testBug512053() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		this.sourceWorkspacePath = super.getSourceWorkspacePath() + java.io.File.separator + "bug512053"; 
		try {
			setUpJavaProject("bundle.test.a.callable", "9");
			setUpJavaProject("bundle.test.a", "9");
			setUpJavaProject("bundle.test.b", "9");
			setUpJavaProject("jpms.test.a", "9");
			setUpJavaProject("jpms.test.b", "9");
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
			//assertNoErrors(p2);
		} finally {
			this.deleteProject("bundle.test.a.callable");
			this.deleteProject("bundle.test.a");
			this.deleteProject("bundle.test.b");
			this.deleteProject("jpms.test.a");
			this.deleteProject("jpms.test.b");
			this.sourceWorkspacePath = null;
			 JavaCore.setOptions(javaCoreOptions);
		}
	}
	// basic test for automatic modules - external jars
	public void testBug518280() throws CoreException, IOException {
		try {
			String libPath = "externalLib/test.jar";
			Util.createJar(
					new String[] {
						"test/src/org/astro/World.java", //$NON-NLS-1$
						"package org.astro;\n" +
						"public interface World {\n" +
						"	public String name();\n" +
						"}",
					},
					null,
					new HashMap<>(),
					null,
					getExternalResourcePath(libPath));
			String[] src = new String[] { 
					"src/module-info.java",
					"module com.greetings {\n" +
					"	requires test;\n" +
					"	exports com.greetings;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, ClasspathEntry.NO_ACCESS_RULES,
					new IClasspathAttribute[] {modAttr},
					false/*not exported*/);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE);

			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteExternalResource("externalLib");
			this.deleteProject("com.greetings");
		}
	}
	// basic test for automatic modules - workspace jars
	public void testBug518282() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			setUpJavaProject("test_automodules", "9");
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			this.deleteProject("test_automodules");
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	// Only the project using a jar as an automatic module should be able to
	// resolve one as such
	public void testBug518282a() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			IJavaProject p1 = setUpJavaProject("test_automodules", "9");
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
			String[] src = new String[] { 
					"src/module-info.java",
					"module com.greetings {\n" +
					"	requires junit; // This should not be resolved\n" +
					"	exports com.greetings;\n" +
					"}",
					"src/com/greetings/Test.java",
					"package com.greetings;\n" +
					"public class Test {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "false");
			IClasspathEntry dep = JavaCore.newLibraryEntry(p1.getProject().findMember("lib/junit.jar").getFullPath(), null, null,
					ClasspathEntry.NO_ACCESS_RULES,
					new IClasspathAttribute[] {modAttr},
					false/*not exported*/);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });

			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"junit cannot be resolved to a module", markers);
		} finally {
			this.deleteProject("test_automodules");
			this.deleteProject("com.greetings");
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	// A modular jar on the module path of a project should behave as a regular module and not
	// as an automatic module
	public void testBug518282b() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		String libPath = "externalLib/test.jar";
		try {
			String[] src = new String[] { 
					"src/module-info.java",
					"module com.greetings {\n" +
					"	exports com.greetings;\n" +
					"}",
					"src/com/greetings/Test.java",
					"package com.greetings;\n" +
					"public class Test {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("test", src);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			File rootDir = new File(p1.getProject().findMember("bin").getLocation().toString());
			Util.zip(rootDir, getExternalResourcePath(libPath));
			src = new String[] { 
					"src/module-info.java",
					"module test_automodules {\n" +
					"	requires com.greetings;\n" +
					"}",
					"src/test/Main.java",
					"package test;\n" +
					"import com.greetings.Test;\n" +
					"public class Main {\n" +
					"	public static void main(String[] args) {\n" +
					"		System.out.println(new Test().name());\n" +
					"	}\n" +
					"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null,
				ClasspathEntry.NO_ACCESS_RULES,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p2 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			this.deleteProject("test");
			this.deleteProject("test_automodules");
			deleteExternalResource(libPath);
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	// A modular jar on the class path of a module project - shouldn't be
	// treated as a module and shouldn't be readable
	public void testBug518282c() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		String libPath = "externalLib/test.jar";
		try {
			String[] src = new String[] { 
					"src/module-info.java",
					"module test {\n" +
					"	exports com.greetings;\n" +
					"}",
					"src/com/greetings/Test.java",
					"package com.greetings;\n" +
					"public class Test {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("test", src);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			File rootDir = new File(p1.getProject().findMember("bin").getLocation().toString());
			Util.zip(rootDir, getExternalResourcePath(libPath));
			src = new String[] { 
					"src/module-info.java",
					"module test_automodules {\n" +
					"	requires test;\n" +
					"}",
					"src/test/Main.java",
					"package test;\n" +
					"import com.greetings.Test;\n" +
					"public class Main {\n" +
					"	public static void main(String[] args) {\n" +
					"		System.out.println(new Test().name());\n" +
					"	}\n" +
					"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "false");
			IClasspathEntry dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null,
				ClasspathEntry.NO_ACCESS_RULES,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p2 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertTrue("Compilation succeeds unexpectedly", markers.length > 0);
		} finally {
			this.deleteProject("test");
			this.deleteProject("test_automodules");
			deleteExternalResource(libPath);
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	// An automatic module grants implied readability to all other automatic modules
	public void testBug518282d() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		String libPath = "externalLib/test.jar";
		try {
			String[] src = new String[] { 
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] { 
				"src/org/greetings/Test.java",
				"package org.greetings;\n" +
				"import  org.astro.World;\n" +
				"public class Test implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath());
			IJavaProject p2 = setupModuleProject("test", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			File rootDir = new File(p2.getProject().findMember("bin").getLocation().toString());
			Util.zip(rootDir, getExternalResourcePath(libPath));
			src = new String[] { 
				"src/module-info.java",
				"module test_automodules {\n" +
				"	requires test;\n" +
				"}",
				"src/test/Main.java",
				"package test;\n" +
				"import org.greetings.Test;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"		org.astro.World world = new Test();\n" +
				"		System.out.println(world.name());\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null,
				ClasspathEntry.NO_ACCESS_RULES,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IClasspathEntry dep2 = JavaCore.newLibraryEntry(p1.getProject().findMember("bin").getFullPath(), null, null,
				ClasspathEntry.NO_ACCESS_RULES,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p3 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep, dep2});
			p3.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			this.deleteProject("test");
			this.deleteProject("test_automodules");
			this.deleteProject("org.astro");
			deleteExternalResource(libPath);
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	// Automatic module should not allow access to other explicit modules without
	// requires
	public void testBug518282e() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		String libPath = "externalLib/test.jar";
		try {
			String[] src = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] { 
				"src/com/greetings/Test.java",
				"package com.greetings;\n" +
				"import  org.astro.World;\n" +
				"public class Test implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath());
			IJavaProject p2 = setupModuleProject("test", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			File rootDir = new File(p2.getProject().findMember("bin").getLocation().toString());
			Util.zip(rootDir, getExternalResourcePath(libPath));
			src = new String[] { 
				"src/module-info.java",
				"module test_automodules {\n" +
				"	requires test;\n" +
				"}",
				"src/test/Main.java",
				"package test;\n" +
				"import com.greetings.Test;\n" +
				"import org.astro.*;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"		World world = new Test();\n" +
				"		System.out.println(world.name());\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null,
				ClasspathEntry.NO_ACCESS_RULES,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p1.getPath(), null, true,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p3 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep, dep2});
			p3.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The package org.astro is not accessible\n" +
					"World cannot be resolved to a type", markers);
		} finally {
			this.deleteProject("test");
			this.deleteProject("test_automodules");
			this.deleteProject("org.astro");
			deleteExternalResource(libPath);
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	// An automatic module shouldn't allow access to classpath
	public void testBug518282f() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		String libPath = "externalLib/test.jar";
		try {
			String[] src = new String[] { 
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] { 
				"src/com/greetings/Test.java",
				"package com.greetings;\n" +
				"import  org.astro.World;\n" +
				"public class Test implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath());
			IJavaProject p2 = setupModuleProject("test", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			File rootDir = new File(p2.getProject().findMember("bin").getLocation().toString());
			Util.zip(rootDir, getExternalResourcePath(libPath));
			src = new String[] { 
				"src/module-info.java",
				"module test_automodules {\n" +
				"	requires test;\n" +
				"}",
				"src/test/Main.java",
				"package test;\n" +
				"import com.greetings.Test;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"		org.astro.World world = new Test();\n" +
				"		System.out.println(world.name());\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null,
				ClasspathEntry.NO_ACCESS_RULES,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			modAttr = new ClasspathAttribute("module", "false");
			IClasspathEntry dep2 = JavaCore.newLibraryEntry(p1.getProject().findMember("bin").getFullPath(), null, null,
				ClasspathEntry.NO_ACCESS_RULES,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			IJavaProject p3 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep, dep2});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"The project was not built since its build path is incomplete. Cannot find the class file for org.astro.World. Fix the build path then try building this project\n" + 
					"The type org.astro.World cannot be resolved. It is indirectly referenced from required .class files",
					markers);
		} finally {
			this.deleteProject("test");
			this.deleteProject("test_automodules");
			this.deleteProject("org.astro");
			deleteExternalResource(libPath);
			JavaCore.setOptions(javaCoreOptions);
		}
	}

	public void testUnnamedModule_bug519674() throws CoreException {
		try {
			IJavaProject p1 = createJava9Project("Project1");
			createFolder("/Project1/src/pack1");
			createFile("/Project1/src/pack1/Class1.java",
					"package pack1;\n" +
					"public class Class1 {}\n");
			
			IJavaProject p2 = createJava9Project("Project2");
			{
				IClasspathEntry[] old = p2.getRawClasspath();
				IClasspathEntry[] newPath = new IClasspathEntry[old.length + 1];
				System.arraycopy(old, 0, newPath, 0, old.length);
				newPath[old.length] = JavaCore.newProjectEntry(p1.getPath());
				p2.setRawClasspath(newPath, null);
			}
			createFolder("/Project2/src/pack2");
			createFile("/Project2/src/pack2/Class2.java",
					"package pack2;\n" +
					"import pack1.Class1;\n" +
					"public class Class2 extends Class1 {}\n");
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			this.deleteProject("Project1");
			this.deleteProject("Project2");
		}

	}
	public void testBug520246() throws CoreException {
		try {
			String[] src = new String[] { 
				"src/module-info.java",
				"module test_automodules {\n" +
				"	requires java.sql;\n" +
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"import some.pack.Type;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "The import some cannot be resolved", markers);
		} finally {
			this.deleteProject("org.astro");
		}

	}	
	public void testBug520147() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			String[] src = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/bundle/org/SomeClass.java",
					"package bundle.org;\n" +
					"public class SomeClass {}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports bundle.org;\n" +
					"}",
				"src/bundle/org/SomeWorld.java",
				"package bundle.org;\n" +
				"import  org.astro.World;\n" +
				"public class SomeWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" Some World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			src = new String[] { 
				"src/module-info.java",
				"module test {\n" +
				"	exports test;\n" +
				"	requires org.astro;\n" +
				"	requires com.greetings;\n" +
				"}",
				"src/test/Main.java",
				"package test;\n" +
				"import bundle.org.SomeWorld;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"		org.astro.World world = new SomeWorld();\n" +
				"		System.out.println(world.name());\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			this.deleteProject("test");
			this.deleteProject("com.greetings");
			this.deleteProject("org.astro");
			JavaCore.setOptions(javaCoreOptions);
		}
	}	
	public void testBug520147a() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			String[] src = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/bundle/org/SomeClass.java",
					"package bundle.org;\n" +
					"public class SomeClass {}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports bundle.org;\n" +
					"}",
				"src/bundle/org/SomeWorld.java",
				"package bundle.org;\n" +
				"import  org.astro.World;\n" +
				"public class SomeWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" Some World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			src = new String[] { 
				"src/module-info.java",
				"module test {\n" +
				"	exports test;\n" +
				"	requires com.greetings;\n" +
				"}",
				"src/test/Main.java",
				"package test;\n" +
				"import bundle.org.SomeWorld;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"		org.astro.World world = new SomeWorld();\n" +
				"		System.out.println(world.name());\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"The type org.astro.World is not accessible", markers);
		} finally {
			this.deleteProject("test");
			this.deleteProject("com.greetings");
			this.deleteProject("org.astro");
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	public void testBug520147b() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			String[] src = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"	exports bundle.org to com.greetings;\n" +
					"}",
					"src/bundle/org/SomeClass.java",
					"package bundle.org;\n" +
					"public class SomeClass {}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
					"	requires org.astro;\n" +
					"	exports bundle.org;\n" +
					"}",
				"src/bundle/org/SomeWorld.java",
				"package bundle.org;\n" +
				"import  org.astro.World;\n" +
				"public class SomeWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" Some World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("markers on com.greetings", 
					"The package bundle.org conflicts with a package accessible from another module: org.astro",
					markers);

			src = new String[] { 
				"src/module-info.java",
				"module test {\n" +
				"	exports test;\n" +
				"	requires org.astro;\n" +
				"	requires com.greetings;\n" +
				"}",
				"src/test/Main.java",
				"package test;\n" +
				"import bundle.org.SomeWorld;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"		org.astro.World world = new SomeWorld();\n" +
				"		System.out.println(world.name());\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2});
			p3.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			this.deleteProject("test");
			this.deleteProject("com.greetings");
			this.deleteProject("org.astro");
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	public void testSourceFolders_Bug519673() throws CoreException {
		try {
			// Setup project PSources1:
			String[] src = new String[] { 
					"src/module-info.java",
					"module PSources1 {\n" +
					"	//exports p.q;\n" +
					"}",
					"src2/p/q/SomeClass.java",
					"package p.q;\n" +
					"public class SomeClass {}",
			};
			IJavaProject p1 = setupModuleProject("PSources1", new String[] { "src", "src2" }, src, new IClasspathEntry[0]);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);

			// Edit PSources1/src/module-info.java:
			String infoSrc =
					"module PSources1 {\n" +
					"	exports p.q;\n" +
					"}";
			String infoPath = "/PSources1/src/module-info.java";
			editFile(infoPath, infoSrc);
			this.workingCopies = new ICompilationUnit[1];
			char[] sourceChars = src[1].toCharArray();
			this.problemRequestor.initialize(sourceChars);
			this.workingCopies[0] = getCompilationUnit(infoPath).getWorkingCopy(this.wcOwner, null);
			// was: ERROR: The package pkg does not exist or is empty
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			// Setup project PClient2:
			String[] src2 = new String[] { 
					"src/module-info.java",
					"module PClient2 {\n" +
					"	requires PSources1;\n" +
					"}",
					"src/x/Client.java",
					"package x;\n" +
					"public class Client {\n" +
					"	p.q.SomeClass f;\n" +
					"\n}",
			};
			setupModuleProject("PClient2", src2);
			getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);

			// Edit PClient2/src/module-info.java:
			// was NPE in ModuleBinding.canAccess()
			char[] info2Chars = src2[2].toCharArray();
			this.problemRequestor.initialize(info2Chars);
			this.workingCopies[0] = getCompilationUnit("PClient2/src/module-info.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			// Failed attempt to trigger NPE in ModuleBinding.isPackageExportedTo() by editing Client.java
			char[] source2Chars = src2[3].toCharArray();
			this.problemRequestor.initialize(source2Chars);
			this.workingCopies[0] = getCompilationUnit("PClient2/src/x/Client.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject("PSources1");
			deleteProject("PClient2");
		}
	}
	public void testPrivateMethod_Bug515985() throws CoreException {
		try {
			String[] src = new String[] {
					"src/module-info.java", 
					"module mod.one { \n" +
					"	exports pm;\n" +
					"}",
					"src/impl/Other.java", 
					"package impl;\n" +
					"public class Other {\n" +
					"    public void privateMethod() {}" + 
					"}\n",
					"src/pm/C1.java", 
					"package pm;\n" +
					"import impl.Other;\n" + 
					"public class C1 extends Other {\n" + 
					"}\n"
			};
			IJavaProject p1 = setupModuleProject("mod.one", src);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
	
			String[] src2 = new String[] {
					"src/module-info.java", 
					"module mod.two { \n" +
					"	requires mod.one;\n" +
					"}",
					"src/po/Client.java", 
					"package po;\n" + 
					"import pm.C1;\n" + 
					"public class Client {\n" + 
					"    void test1(C1 one) {\n" + 
					"        one.privateMethod(); // ecj: The method privateMethod() is undefined for the type C1\n" + 
					"    }\n" + 
					"}\n"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p2 = setupModuleProject("mod.two", src2, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject("mod.one");
			deleteProject("mod.two");
		}
	}
	public void testAddExports() throws CoreException {
		try {
			String[] sources = new String[] {
					"src/module-info.java",
					"module morg.astro {\n" +
//					"	exports org.astro to com.greetings;\n" + // this export will be added via add-exports
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("morg.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathAttribute addExports = new ClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "morg.astro/org.astro=com.greetings");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
															new IClasspathAttribute[] {modAttr, addExports},
															false/*not exported*/);
			String[] src = new String[] {
					"src/module-info.java",
					"module com.greetings {\n" +
					"	requires morg.astro;\n" +
					"	exports com.greetings;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n" +
					"public class MyWorld implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("morg.astro");
			deleteProject("com.greetings");
		}
	}
	public void testAddExports2() throws CoreException {
		try {
			String[] sources = new String[] {
					"src/module-info.java",
					"module morg.astro {\n" +
//					"	exports org.astro to com.greetings;\n" + // this export will be added via add-exports
//					"	exports org.eclipse to com.greetings;\n" + // this export will be added via add-exports
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}",
					"src/org/eclipse/Planet.java",
					"package org.eclipse;\n" +
					"public class Planet {}\n"
			};
			IJavaProject p1 = setupModuleProject("morg.astro", sources);
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathAttribute addExports = new ClasspathAttribute(IClasspathAttribute.ADD_EXPORTS,
						"morg.astro/org.astro=com.greetings:morg.astro/org.eclipse=com.greetings");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
															new IClasspathAttribute[] {modAttr, addExports},
															false/*not exported*/);
			String[] src = new String[] {
					"src/module-info.java",
					"module com.greetings {\n" +
					"	requires morg.astro;\n" +
					"	exports com.greetings;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n" +
					"public class MyWorld implements World {\n" +
					"	org.eclipse.Planet planet;\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);
		} finally {
			deleteProject("morg.astro");
			deleteProject("com.greetings");
		}
	}
	public void testAddReads() throws CoreException, IOException {
		try {
			// org.astro defines the "real" org.astro.World:
			String[] sources = new String[] {
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" + 
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p = setupModuleProject("org.astro", sources);

			// build mod.one with a private copy of org.astro.World:
			String[] src1 = new String[] {
					"src/module-info.java",
					"module mod.one {\n" +
					"	exports one.p;\n" +
					"}\n",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World { public String name(); }\n",
					"src/one/p/C.java",
					"package one.p;\n" +
					"public class C {\n" +
					"	public void test(org.astro.World w) {\n" +
					"		System.out.println(w.name());\n" +
					"	}\n" +
					"}\n"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p.getPath(), null, false,
															new IClasspathAttribute[] { modAttr },
															false/*not exported*/);
			IJavaProject p1 = setupModuleProject("mod.one", src1, new IClasspathEntry[] { dep });
			p1.setOption(JavaCore.COMPILER_PB_API_LEAKS, JavaCore.IGNORE); // the stub org.astro.World is not exported but used in API
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);

			// jar-up without the private copy:
			deleteFile("/mod.one/src/org/astro/World.java");
			deleteFile("/mod.one/bin/org/astro/World.class");
			String modOneJarPath = getWorkspacePath()+File.separator+"mod.one.jar";
			Util.zip(new File(getWorkspacePath()+"/mod.one/bin"), modOneJarPath);

			// com.greetings depends on both other modules:
			String[] src2 = new String[] {
				"src/module-info.java",
				"module com.greetings {\n" +
				"	requires org.astro;\n" +
				"	requires mod.one;\n" +
				"}",
				"src/com/greetings/MyTest.java",
				"package com.greetings;\n" +
				"public class MyTest {\n" +
				"	public void test(one.p.C c, org.astro.World w) {\n" +
				"		c.test(w);\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep1 = JavaCore.newProjectEntry(p.getPath(), null, false,
															new IClasspathAttribute[] {new ClasspathAttribute("module", "true")},
															false/*not exported*/);
			// need to re-wire dependency mod.one -> org.astro for resolving one.p.C:
			IClasspathEntry dep2 = JavaCore.newLibraryEntry(new Path(modOneJarPath), null, null, null,
															new IClasspathAttribute[] {
																	new ClasspathAttribute("module", "true"),
																	new ClasspathAttribute(IClasspathAttribute.ADD_READS, "mod.one=org.astro")
															},
															false/*not exported*/);
			IJavaProject p2 = setupModuleProject("com.greetings", src2, new IClasspathEntry[] { dep1, dep2 });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",	"",  markers);

			// check that reconcile respects --add-reads, too:
			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/com.greetings/src/com/greetings/MyTest.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

		} finally {
			deleteProject("mod.one");
			deleteProject("org.astro");
			deleteProject("com.greetings");
		}
	}
	public void testBug520147c() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			String[] src = new String[] { 
					"src/module-info.java",
					"module org.astro {\n" +
					"	exports org.astro;\n" +
					"}",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"public interface World {\n" +
					"	public String name();\n" +
					"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] {
				"src/org/eclipse/pack1/SomeWorld.java",
				"package org.eclipse.pack1;\n" +
				"import  org.astro.World;\n" +
				"public class SomeWorld implements World {\n" +
				"	public String name() {\n" +
				"		return \" Some World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			src = new String[] { 
				"src/module-info.java",
				"module test {\n" +
				"	exports test;\n" +
				"	requires com.greetings;\n" +
				"	requires org.astro;\n" +
				"}",
				"src/test/Main.java",
				"package test;\n" +
				"import org.eclipse.pack1.SomeWorld;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"		org.astro.World world = new SomeWorld();\n" +
				"		System.out.println(world.name());\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false);
			IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", 
					"Name of automatic module \'com.greetings\' is unstable, it is derived from the module\'s file name.",
					markers);
		} finally {
			this.deleteProject("test");
			this.deleteProject("com.greetings");
			this.deleteProject("org.astro");
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	@Deprecated
	public void testBug519935() throws CoreException, IOException {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			String[] src = new String[] { 
				"src/module-info.java",
				"module org.astro {\n" +
				"	exports org.astro;\n" +
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IJavaProject p1 = setupModuleProject("org.astro", src);
			src = new String[] { 
				"src/org/eclipse/pack/Test.java",
				"package org.eclipse.pack;\n" +
				"import org.astro.World;\n" +
				"public class Test implements World {\n" +
				"	public String name() {\n" +
				"		return \" My World!!\";\n" +
				"	}\n" +
				"}"
			};
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath());
			IJavaProject p2 = setupModuleProject("test", src, new IClasspathEntry[] {dep});
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			src = new String[] { 
				"src/module-info.java",
				"module test_automodules {\n" +
				"	requires bin;\n" +
				"	requires org.astro;\n" +
				"}",
				"src/test/Main.java",
				"package test;\n" +
				"import org.eclipse.pack.Test;\n" +
				"import org.astro.*;\n" +
				"public class Main {\n" +
				"	public static void main(String[] args) {\n" +
				"		World world = new Test();\n" +
				"		System.out.println(world.name());\n" +
				"	}\n" +
				"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			dep = JavaCore.newLibraryEntry(p2.getProject().findMember("bin").getFullPath(), null, null,
				ClasspathEntry.NO_ACCESS_RULES,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p1.getPath(), null, true,
				new IClasspathAttribute[] {modAttr},
				false/*not exported*/);
			setupModuleProject("testSOE", src, new IClasspathEntry[] {dep, dep2});
			this.workingCopies = new ICompilationUnit[1];
			this.workingCopies[0] = getCompilationUnit("/testSOE/src/test/Main.java").getWorkingCopy(this.wcOwner, null);
			this.problemRequestor.initialize(src[3].toCharArray());
			CompilationUnit unit = this.workingCopies[0].reconcile(AST.JLS9, true, this.wcOwner, null);
			assertNotNull("Could not reconcile", unit);
		} finally {
			this.deleteProject("test");
			this.deleteProject("testSOE");
			this.deleteProject("org.astro");
			JavaCore.setOptions(javaCoreOptions);
		}
	}
	@Deprecated
	public void testBug520310() throws CoreException, IOException {
		try {
			String[] src = new String[] { 
				"src/module-info.java",
				"module mod.one {\n" +
//				"	requires mod.two;\n" +
				"	exports org.astro;\n" +
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public interface World {\n" +
				"	public String name();\n" +
				"}"
			};
			IClasspathEntry modDep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID));
			IJavaProject p1 = setupModuleProject("mod.one", src, new IClasspathEntry[] {modDep});

			src = new String[] { 
					"src/module-info.java",
					"module mod.two {\n" +
					"	requires mod.one;\n" +
					"	exports test;\n" +
					"}",
					"src/test/Test.java",
					"package test;\n" +
					"import org.astro.World;\n" +
					"public class Test implements World {\n" +
					"	public String name() {\n" +
					"		return \" My World!!\";\n" +
					"	}\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("mod.two", src, new IClasspathEntry[] {modDep});
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers in mod.one", "", markers);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers in mod.two", "", markers);
			
			editFile("/mod.one/src/module-info.java",
				"module mod.one {\n" +
				"	requires mod.two;\n" + // added
				"	exports org.astro;\n" +
				"}");
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); // modules see each other only on 2nd attempt, don't ask me...
			markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers in mod.one", 
					"Cycle exists in module dependencies, Module mod.one requires itself via mod.two",
					markers);
			markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers in mod.two", 
					"The type org.astro.World is not accessible\n" + // cannot use cyclic requires 
					"Cycle exists in module dependencies, Module mod.two requires itself via mod.one\n" + 
					"World cannot be resolved to a type",
					markers);

			this.workingCopies = new ICompilationUnit[1];
			this.workingCopies[0] = getCompilationUnit("/mod.two/src/module-info.java").getWorkingCopy(this.wcOwner, null);
			this.problemRequestor.initialize(src[1].toCharArray());
			CompilationUnit unit = this.workingCopies[0].reconcile(AST.JLS9, true, this.wcOwner, null);
			assertNotNull("Could not reconcile", unit);
		} finally {
			this.deleteProject("mod.one");
			this.deleteProject("mod.two");
		}
	}
	public void testBug521346() throws CoreException, IOException {
		IJavaProject javaProject = null;
		try {
			String src =
					"import java.*;\n" + 
					"public class X {\n" + 
					"    public static void main(String[] args) {\n" + 
					"        System.out.println(true);\n" + 
					"    }\n" + 
					"}";
			javaProject = createJava9Project("Test");
			this.problemRequestor.initialize(src.toCharArray());
			getWorkingCopy("/Test/src/X.java", src, true);
			assertProblems("should have not problems",
					"----------\n" + 
					"1. ERROR in /Test/src/X.java (at line 1)\n" + 
					"	import java.*;\n" + 
					"	       ^^^^\n" + 
					"The package java is not accessible\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
		}
	}
	public void testAutoModule1() throws Exception {
		IJavaProject javaProject = null;
		try {
			String[] sources = {
				"p/a/X.java",
				"package p.a;\n" +
				"public class X {}\n;"
			};
			String outputDirectory = Util.getOutputDirectory();
	
			String jarPath = outputDirectory + File.separator + "lib-x.jar";
			Util.createJar(sources, jarPath, "1.8");
			
			javaProject = createJava9Project("mod.one", new String[] {"src"});
			IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			addClasspathEntry(javaProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false));

			String srcMod =
				"module mod.one { \n" +
				"	requires lib.x;\n" + // lib.x is derived from lib-x.jar
				"}";
			createFile("/mod.one/src/module-info.java", 
				srcMod);
			createFolder("mod.one/src/q");
			String srcX =
				"package q;\n" +
				"public class X {\n" +
				"	p.a.X f;\n" +
				"}";
			createFile("/mod.one/src/q/X.java", srcX);
			
			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod.one/module-info.java", srcMod, true);
			assertProblems("module-info should have one warning",
					"----------\n" + 
					"1. WARNING in /mod.one/module-info.java (at line 2)\n" + 
					"	requires lib.x;\n" + 
					"	         ^^^^^\n" + 
					"Name of automatic module \'lib.x\' is unstable, it is derived from the module\'s file name.\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcX.toCharArray());
			getWorkingCopy("/mod.one/src/q/X.java", srcX, true);
			assertProblems("X should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
		}
	}
	public void testAutoModule2() throws Exception {
		IJavaProject javaProject = null;
		try {
			String[] sources = {
				"p/a/X.java",
				"package p.a;\n" +
				"public class X {}\n;",
			};
			String[] mfSource = {
				"META-INF/MANIFEST.MF",
				"Manifest-Version: 1.0\n" + 
				"Automatic-Module-Name: org.eclipse.lib.x\n"
			};
			String outputDirectory = Util.getOutputDirectory();

			String jarPath = outputDirectory + File.separator + "lib-x.jar";
			Util.createJar(sources, mfSource, jarPath, "1.8");
			
			javaProject = createJava9Project("mod.one", new String[] {"src"});
			IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			addClasspathEntry(javaProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false));

			String srcMod =
				"module mod.one { \n" +
				"	requires org.eclipse.lib.x;\n" + // from jar attribute
				"}";
			createFile("/mod.one/src/module-info.java", 
				srcMod);
			createFolder("mod.one/src/q");
			String srcX =
				"package q;\n" +
				"public class X {\n" +
				"	p.a.X f;\n" +
				"}";
			createFile("/mod.one/src/q/X.java", srcX);

			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod.one/module-info.java", srcMod, true);
			assertProblems("module-info should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcX.toCharArray());
			getWorkingCopy("/mod.one/src/q/X.java", srcX, true);
			assertProblems("X should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
		}
	}
	public void testAutoModule3() throws Exception {
		IJavaProject javaProject = null, auto = null;
		try {
			auto = createJava9Project("auto", new String[] {"src"});
			createFolder("auto/src/p/a");
			createFile("auto/src/p/a/X.java",
				"package p.a;\n" +
				"public class X {}\n;");
			createFolder("auto/META-INF");
			createFile("auto/META-INF/MANIFEST.MF",
				"Manifest-Version: 1.0\n" + 
				"Automatic-Module-Name: org.eclipse.lib.x\n");

			javaProject = createJava9Project("mod.one", new String[] {"src"});
			IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			addClasspathEntry(javaProject, JavaCore.newProjectEntry(auto.getPath(), null, false, attributes, false));

			String srcMod =
				"module mod.one { \n" +
				"	requires org.eclipse.lib.x;\n" + // from manifest attribute
				"}";
			createFile("/mod.one/src/module-info.java", 
				srcMod);
			createFolder("mod.one/src/q");
			String srcX =
				"package q;\n" +
				"public class X {\n" +
				"	p.a.X f;\n" +
				"}";
			createFile("/mod.one/src/q/X.java", srcX);
			auto.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);

			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod.one/module-info.java", srcMod, true);
			assertProblems("module-info should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcX.toCharArray());
			getWorkingCopy("/mod.one/src/q/X.java", srcX, true);
			assertProblems("X should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
			if (auto != null)
				deleteProject(auto);
		}
	}

	public void testAutoModule4() throws Exception {
		IJavaProject javaProject = null;
		IJavaProject javaProject2 = null;
		try {
			// auto module as jar:
			String[] sources = {
				"p/a/X.java",
				"package p.a;\n" +
				"public class X {}\n;",
			};
			String[] mfSource = {
				"META-INF/MANIFEST.MF",
				"Manifest-Version: 1.0\n" + 
				"Automatic-Module-Name: org.eclipse.lib.x\n" // automatic module reads all (incl. mod.one below)
			};
			String outputDirectory = Util.getOutputDirectory();

			String jarPath = outputDirectory + File.separator + "lib-x.jar";
			Util.createJar(sources, mfSource, jarPath, "1.8");
			
			// first source module:
			javaProject = createJava9Project("mod.one", new String[] {"src"});
			IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			addClasspathEntry(javaProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false));

			String srcMod =
				"module mod.one { \n" +
				"	requires org.eclipse.lib.x;\n" + // creates cycle mod.one -> org.eclipse.lib.x -> mod.one
				"	exports p.q.api;\n" +
				"}";
			createFile("/mod.one/src/module-info.java", srcMod);
			createFolder("mod.one/src/p/q/api");
			String srcX =
				"package p.q.api;\n" +
				"public class X {\n" +
				"	p.a.X f;\n" +
				"}";
			createFile("/mod.one/src/p/q/api/X.java", srcX);

			// second source module:
			javaProject2 = createJava9Project("mod.two", new String[] {"src"});
			addClasspathEntry(javaProject2, JavaCore.newProjectEntry(new Path("/mod.one"), null, false, attributes, false));
			addClasspathEntry(javaProject2, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false));
			String srcMod2 =
				"module mod.two { \n" +
				"	requires mod.one;\n" +
				"}";
			createFile("/mod.two/src/module-info.java", srcMod2);
			createFolder("mod.two/src/p/q");
			String srcY =
				"package p.q;\n" +
				"import p.q.api.X;\n" + // here we saw "The package p.q.api is accessible from more than one module: mod.one, mod.one"
				"public class Y {\n" +
				"	X f;\n" +
				"}";
			createFile("/mod.two/src/p/q/Y.java", srcY);

			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod.one/module-info.java", srcMod, true);
			assertProblems("module-info should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcX.toCharArray());
			getWorkingCopy("/mod.one/src/p/q/api/X.java", srcX, true);
			assertProblems("X should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcY.toCharArray());
			getWorkingCopy("/mod.two/src/p/q/Y.java", srcY, true);
			assertProblems("Y should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertMarkers("markers in mod.one", "", javaProject);
			
			javaProject2.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertMarkers("markers in mod.two", "", javaProject2);

			javaProject.getProject().getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null);
			assertNoErrors();
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
			if (javaProject2 != null)
				deleteProject(javaProject2);
		}
	}
	// like testAutoModule3 without name derived from project, not manifest - warning suppressed
	public void testAutoModule5() throws Exception {
		IJavaProject javaProject = null, auto = null;
		try {
			auto = createJava9Project("auto", new String[] {"src"});
			createFolder("auto/src/p/a");
			createFile("auto/src/p/a/X.java",
				"package p.a;\n" +
				"public class X {}\n;");

			javaProject = createJava9Project("mod.one", new String[] {"src"});
			IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			addClasspathEntry(javaProject, JavaCore.newProjectEntry(auto.getPath(), null, false, attributes, false));

			String srcMod =
				"@SuppressWarnings(\"module\")\n" +
				"module mod.one { \n" +
				"	requires auto;\n" +
				"}";
			createFile("/mod.one/src/module-info.java", 
				srcMod);
			createFolder("mod.one/src/q");
			String srcX =
				"package q;\n" +
				"public class X {\n" +
				"	p.a.X f;\n" +
				"}";
			createFile("/mod.one/src/q/X.java", srcX);
			auto.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);

			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod.one/module-info.java", srcMod, true);
			assertProblems("module-info should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcX.toCharArray());
			getWorkingCopy("/mod.one/src/q/X.java", srcX, true);
			assertProblems("X should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
			if (auto != null)
				deleteProject(auto);
		}
	}
	// like testAutoModule5, warning configured as ERROR
	public void testAutoModule6() throws Exception {
		IJavaProject javaProject = null, auto = null;
		try {
			auto = createJava9Project("auto", new String[] {"src"});
			createFolder("auto/src/p/a");
			createFile("auto/src/p/a/X.java",
				"package p.a;\n" +
				"public class X {}\n;");

			javaProject = createJava9Project("mod.one", new String[] {"src"});
			IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			addClasspathEntry(javaProject, JavaCore.newProjectEntry(auto.getPath(), null, false, attributes, false));
			javaProject.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.ERROR);

			String srcMod =
				"module mod.one { \n" +
				"	requires auto;\n" +
				"}";
			createFile("/mod.one/src/module-info.java", 
				srcMod);
			auto.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);

			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod.one/module-info.java", srcMod, true);
			assertProblems("module-info should have only one error",
					"----------\n" + 
					"1. ERROR in /mod.one/module-info.java (at line 2)\n" + 
					"	requires auto;\n" + 
					"	         ^^^^\n" + 
					"Name of automatic module \'auto\' is unstable, it is derived from the module\'s file name.\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
			if (auto != null)
				deleteProject(auto);
		}
	}

	// patch can see unexported type from host (and package accessible method), but not vice versa
	public void testPatch1() throws CoreException, IOException {
		try {
			IJavaProject mainProject = createJava9Project("org.astro");
			String[] sources = { 
				"src/module-info.java",
				"module org.astro {\n" + // no exports
				"}",
				"src/org/astro/World.java",
				"package org.astro;\n" +
				"public class World {\n" +
				"	public String name() { return \"world\"; }\n" +
				"	void internalTest() { }\n" +
				"	public org.astro.test.WorldTest test;\n" +
				"}",
			};
			createSourceFiles(mainProject, sources);

			IJavaProject patchProject = createJava9Project("org.astro.patch");
			IClasspathAttribute[] attributes = {
						JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
						JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "org.astro")
					};
			addClasspathEntry(patchProject, JavaCore.newProjectEntry(new Path("/org.astro"), null, false, attributes, false));
			String[] patchSources = {
				"src/org/astro/test/WorldTest.java",
				"package org.astro.test;\n" +
				"import org.astro.*;\n" +
				"public class WorldTest {\n" +
				"	void testWorld(World w) {\n" +
				"		w.name();\n" +
				"	}\n" +
				"}\n",
				"src/org/astro/Test2.java",
				"package org.astro;\n" +
				"class Test2 {\n" +
				"	void test(World w) {\n" +
				"		w.internalTest();\n" + // package access
				"	}\n" +
				"}\n"
			};
			createSourceFiles(patchProject, patchSources);
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = mainProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"org.astro.test cannot be resolved to a type", // missing reverse dependency
					markers);

			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/org.astro.patch/src/org/astro/test/WorldTest.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

			this.problemRequestor.reset();
			cu = getCompilationUnit("/org.astro/src/org/astro/World.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" + 
				"1. ERROR in /org.astro/src/org/astro/World.java\n" + 
				"org.astro.test cannot be resolved to a type\n" +
				"----------\n",
				this.problemRequestor);

		} finally {
			this.deleteProject("org.astro");
			this.deleteProject("org.astro.patch");
		}
	}

	// patch can see unexported type from host - JRE patched from two source folders
	public void testPatch2() throws CoreException, IOException {
		try {
			IClasspathAttribute[] attributes = {
					JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
					JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.desktop=/missing.path::java.base=/org.astro.patch/src:/org.astro.patch/src2")
			};
			IJavaProject patchProject = createJava9ProjectWithJREAttributes("org.astro.patch", new String[]{"src", "src2"}, attributes);

			String[] patchSources = {
				"src/org/astro/Test2.java",
				"package org.astro;\n" +
				"class Test2 {\n" +
				"	int test(jdk.internal.misc.Unsafe unsafe) {\n" +
				"		return unsafe.addressSize();\n" +
				"	}\n" +
				"}\n",
				"src2/jdk/internal/misc/Test3.java",
				"package jdk.internal.misc;\n" +
				"class Test3 {\n" +
				"	Signal.NativeHandler handler;\n" + // package access
				"}\n"
			};
			createSourceFiles(patchProject, patchSources);
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/org.astro.patch/src/org/astro/Test2.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

		} finally {
			this.deleteProject("org.astro.patch");
		}
	}

	// patch can share a package with its host - jar
	public void testPatch3() throws CoreException, IOException {
		try {
			String[] sources = {
				"p/a/X.java",
				"package p.a;\n" +
				"class X {}\n;", // package access
				"module-info.java",
				"module mod.one {\n" + // no exports
				"}\n"
			};
			String outputDirectory = Util.getOutputDirectory();

			String jarPath = outputDirectory + File.separator + "mod-one.jar";
			Util.createJar(sources, jarPath, "9");

			IJavaProject patchProject = createJava9Project("mod.one.patch");			
			IClasspathAttribute[] attributes = {
					JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
					JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "mod.one=/mod.one.patch")
			};
			addClasspathEntry(patchProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false));

			String[] patchSources = {
				"src/p/a/Test2.java",
				"package p.a;\n" +
				"class Test2 extends X {\n" +
				"}\n"
			};
			createSourceFiles(patchProject, patchSources);
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/mod.one.patch/src/p/a/Test2.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

		} finally {
			this.deleteProject("mod.one.patch");
		}
	}
	public void testLimitModules1() throws CoreException, IOException {
		try {
			IClasspathAttribute[] attributes = {
					JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
					JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.base,java.desktop")
			};
			IJavaProject project = createJava9ProjectWithJREAttributes("org.astro", new String[]{"src", "src2"}, attributes);

			String[] sources = {
				"src/module-info.java",
				"module org.astro {\n" +
				"	requires java.base;\n" +
				"	requires java.desktop;\n" +
				"	requires java.datatransfer;\n" + // within the closure of java.desktop
				"	requires java.sql;\n" + // not included
				"}\n",
				"src/org/astro/Test2.java",
				"package org.astro;\n" +
				"class Test2 {\n" +
				"	java.awt.Window window;\n" +
				"}\n",
				"src2/org/astro/Test3.java",
				"package org.astro;\n" +
				"class Test3 {\n" +
				"	java.awt.datatransfer.Clipboard clippy;\n" +
				"}\n"
			};
			createSourceFiles(project, sources);
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"java.sql cannot be resolved to a module", // outside limited scope
					markers);

			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/org.astro/src/module-info.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"1. ERROR in /org.astro/src/module-info.java\n" + 
				"java.sql cannot be resolved to a module\n" +
				"----------\n",
				this.problemRequestor);

			this.problemRequestor.reset();
			cu = getCompilationUnit("/org.astro/src/org/astro/Test2.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

			this.problemRequestor.reset();
			cu = getCompilationUnit("/org.astro/src/org/astro/Test3.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

		} finally {
			this.deleteProject("org.astro");
		}
	}
	public void testLimitModules2() throws CoreException, IOException {
		try {
			IClasspathAttribute[] attributes = {
					JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
					JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.se") // test transitive closure
			};
			IJavaProject project = createJava9ProjectWithJREAttributes("org.astro", new String[]{"src", "src2"}, attributes);

			String[] sources = {
				"src/module-info.java",
				"module org.astro {\n" +
				"	requires java.base;\n" +
				"	requires java.desktop;\n" +
				"	requires java.datatransfer;\n" +
				"	requires java.sql;\n" +
				"}\n",
				"src/org/astro/Test2.java",
				"package org.astro;\n" +
				"class Test2 {\n" +
				"	java.awt.Window window;\n" +
				"}\n",
				"src2/org/astro/Test3.java",
				"package org.astro;\n" +
				"class Test3 {\n" +
				"	java.awt.datatransfer.Clipboard clippy;\n" +
				"}\n"
			};
			createSourceFiles(project, sources);
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"",
					markers);

			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/org.astro/src/module-info.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

			this.problemRequestor.reset();
			cu = getCompilationUnit("/org.astro/src/org/astro/Test2.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

			this.problemRequestor.reset();
			cu = getCompilationUnit("/org.astro/src/org/astro/Test3.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" +
				"----------\n",
				this.problemRequestor);

		} finally {
			this.deleteProject("org.astro");
		}
	}
	public void testDefaultRootModules() throws CoreException, IOException {
		try {

			IJavaProject project = createJava9Project("org.astro", new String[]{"src"});

			String[] sources = {
				"src/org/astro/ProblemWithPostConstruct.java",
				"package org.astro;\n" +
				"import javax.annotation.PostConstruct;\n" + 
				"\n" + 
				"public class ProblemWithPostConstruct {\n" +
				"	@PostConstruct void init() {}\n" + 
				"}\n"
			};
			createSourceFiles(project, sources);
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"The import javax.annotation.PostConstruct cannot be resolved\n" + 
					"PostConstruct cannot be resolved to a type", // not in default root modules: java.xml.ws.annotation
					markers);
			
			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/org.astro/src/org/astro/ProblemWithPostConstruct.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" + 
				"1. ERROR in /org.astro/src/org/astro/ProblemWithPostConstruct.java\n" + 
				"The import javax.annotation.PostConstruct cannot be resolved\n" + 
				"----------\n" + 
				"2. ERROR in /org.astro/src/org/astro/ProblemWithPostConstruct.java\n" + 
				"PostConstruct cannot be resolved to a type\n" + 
				"----------\n",
				this.problemRequestor);
		} finally {
			this.deleteProject("org.astro");
		}
	}
	public void testBug522398() throws CoreException {
		try {

			String[] sources = new String[] {
				"src/javax/xml/mysubpackage/MyClass.java",
				"package javax.xml.mysubpackage;\n" +
				"\n" +
				"public class MyClass {\n" +
				"}\n" +
				"\n" +
				"",
				"src/nonmodular/UsesMySubPackage.java",
				"package nonmodular;\n" +
				"\n" +
				"import javax.xml.mysubpackage.MyClass;\n" +
				"\n" +
				"public class UsesMySubPackage {\n" +
				"	public MyClass field;\n" +
				"}\n" +
				"",
			};
			IJavaProject p1 = setupModuleProject("nonmodular1", sources);
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {},
				false/*not exported*/);
			String[] src = new String[] {
				"src/nonmodular2/Problem.java",
				"package nonmodular2;\n" +
				"\n" +
				"import javax.xml.XMLConstants;\n" +
				"\n" +
				"import nonmodular.UsesMySubPackage;\n" +
				"\n" +
				"public class Problem extends nonmodular.UsesMySubPackage {\n" +
				"	String s = XMLConstants.NULL_NS_URI;\n" +
				"}\n" +
				"",
			};
			IJavaProject p2 = setupModuleProject("nonmodular2", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			deleteProject("nonmodular1");
			deleteProject("nonmodular2");
		}
	}
	public void testBug522330() throws CoreException, IOException {
		try {
			String[] sources = new String[] {
				"src/javax/net/ServerSocketFactory1.java",
				"package javax.net;\n" +
				"\n" +
				"public class ServerSocketFactory1 {\n" +
				"}\n" +
				"\n" +
				"",
			};
			IJavaProject p1 = setupModuleProject("nonmodular1", sources);
			p1.setOption(JavaCore.COMPILER_COMPLIANCE, "1.8"); // compile with 1.8 compliance to avoid error about package conflict
			
			IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false,
				new IClasspathAttribute[] {},
				false/*not exported*/);
			String[] src = new String[] {
				"src/nonmodular2/Problem.java",
				"package nonmodular2;\n" +
				"\n" +
				"import javax.net.ServerSocketFactory;\n" +
				"\n" +
				"public class Problem  {\n" +
				"	Object o = ServerSocketFactory.getDefault();\n" +
				"} \n" +
				"",
			};
			IJavaProject p2 = setupModuleProject("nonmodular2", src, new IClasspathEntry[] { dep });
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("unexpected markers",
					"The package javax.net is accessible from more than one module: <unnamed>, java.base\n" +
					"ServerSocketFactory cannot be resolved",
					markers);
		} finally {
			deleteProject("nonmodular1");
			deleteProject("nonmodular2");
		}
	}

	public void testBug522503() throws Exception {
		try {
			IJavaProject p1 = setupModuleProject("mod.one",
				new String[] {
					"src/module-info.java",
					"module mod.one {\n" +
					"	exports p1;\n" +
					"}\n",
					"src/p1/API.java",
					"package p1;\n" +
					"public class API {}\n"
				});
			IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			IClasspathEntry[] deps = { JavaCore.newLibraryEntry(p1.getOutputLocation(), null, null, null, attr, false) };
			String[] sources2 = new String[] {
				"src/module-info.java",
				"module mod.two {\n" +
				"	requires mod.one;\n" +
				"}\n",
				"src/client/Client.java",
				"package client;\n" +
				"import p1.API;\n" +
				"public class Client {\n" +
				"	API api;\n" +
				"}\n"
			};
			IJavaProject p2 = setupModuleProject("mod.two", sources2, deps);
			p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
	
			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/mod.two/src/client/Client.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" + 
				"----------\n",
				this.problemRequestor);
		} finally {
			deleteProject("mod.one");			
			deleteProject("mod.two");			
		}
	}
	public void testBug522671() throws Exception {
		try {
		IJavaProject p1 = setupModuleProject("util",
			new String[] {
				"src/module-info.java",
				"module util {\n" +
				"	exports my.util;\n" +
				"}\n" +
				"",
				"src/my/util/Data.java",
				"package my.util;\n" +
				"public class Data {\n" +
				"}\n" +
				"",
				"src/my/util/AnnotatedInModule.java",
				"package my.util;\n" +
				"public abstract class AnnotatedInModule {\n" +
				"	abstract public Data getTime();\n" +
				"}\n" +
				"",
			});
		IJavaProject p2 = setupModuleProject("util2",
			new String[] {
				"src/module-info.java",
				"module util2 {\n" +
				"	exports my.util.nested;\n" +
				"}\n" +
				"",
				"src/my/util/nested/Unrelated.java",
				"package my.util.nested;\n" +
				"class Unrelated {\n" +
				"}\n" +
				"",
			});
		String[] sources3 = {
			"src/a/other/AnnotatedInOtherNonModule.java",
			"package a.other;\n" +
			"import my.util.Data;\n" +
			"public class AnnotatedInOtherNonModule {\n" +
			"	Data generationDate;\n" +
			"}\n" +
			"",
		};
		IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
		// modulepath
		IClasspathEntry[] deps3 = { JavaCore.newProjectEntry(p1.getPath(), null, false, attr, false) };
		IJavaProject p3 = setupModuleProject("other", sources3, deps3);

		String[] sources4 = {
			"src/test/Test.java",
			"package test;\n" +
			"\n" +
			"import a.other.AnnotatedInOtherNonModule;\n" +
			"import my.util.AnnotatedInModule;\n" +
			"import my.util.Data;\n" +
			"\n" +
			"public class Test extends AnnotatedInOtherNonModule {\n" +
			"	public Data f(AnnotatedInModule calendar) {\n" +
			"		return calendar.getTime();\n" +
			"	}\n" +
			"}\n" +
			"",
		};
		IClasspathEntry[] deps4 = { //
				// modulepath (with split package my.util)
				JavaCore.newProjectEntry(p1.getPath(), null, false, attr, false), //
				JavaCore.newProjectEntry(p2.getPath(), null, false, attr, false), //
				// classpath
				JavaCore.newProjectEntry(p3.getPath()) //
		};
		IJavaProject p4 = setupModuleProject("test", sources4, deps4);
		p4.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);

		assertNoErrors();

		this.problemRequestor.reset();
		ICompilationUnit cu = getCompilationUnit("/test/src/test/Test.java");
		cu.getWorkingCopy(this.wcOwner, null);
		assertProblems(
			"Unexpected problems",
			"----------\n" + 
			"----------\n",
			this.problemRequestor);
		} finally {
			deleteProject("util");
			deleteProject("util2");
			deleteProject("other");
			deleteProject("test");
		}
	}
	public void testBug522671b() throws CoreException {
		try {
			String[] sources = new String[] {
				"src/nonmodular1/HasConstructorWithProperties.java",
				"package nonmodular1;\n" +
				"\n" +
				"import java.util.Properties;\n" +
				"\n" +
				"public class HasConstructorWithProperties {\n" +
				"\n" +
				"	public HasConstructorWithProperties(Properties loadedProperties) {\n" +
				"	}\n" +
				"\n" +
				"	protected Properties method() {\n" +
				"		return null;\n" +
				"	}\n" +
				"\n" +
				"}\n" +
				"",
				"src/nonmodular1/HasPropertiesField.java",
				"package nonmodular1;\n" +
				"\n" +
				"import java.util.Properties;\n" +
				"\n" +
				"public class HasPropertiesField {\n" +
				"	Properties properties;\n" +
				"}\n" +
				"",
			};
			IJavaProject p1 = setupModuleProject("nonmodular1", sources);

			String[] sources2 = new String[] {
					"src/java/util/dummy/Dummy.java",
					"package java.util.dummy;\n" +
					"\n" +
					"public class Dummy {\n" +
					"}\n" +
					"\n" +
					"",
				};
			IJavaProject p2 = setupModuleProject("nonmodular2", sources2);
			p2.setOption(JavaCore.COMPILER_COMPLIANCE, "1.8"); // compile with 1.8 compliance to avoid error about package conflict

			IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false,
					new IClasspathAttribute[] {},
					false/*not exported*/);
			IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false,
					new IClasspathAttribute[] {},
					false/*not exported*/);
			String[] src = new String[] {
				"src/test/a/UsesHasPropertiesField.java",
				"package test.a;\n" +
				"\n" +
				"import nonmodular1.HasPropertiesField;\n" +
				"\n" +
				"public class UsesHasPropertiesField extends HasPropertiesField {\n" +
				"}\n" +
				"",
				"src/test/b/Test.java",
				"package test.b;\n" +
				"\n" +
				"import java.util.Properties;\n" +
				"\n" +
				"import nonmodular1.HasConstructorWithProperties;\n" +
				"\n" +
				"public final class Test {\n" +
				"	public static Object test(Properties cassandraConf) {\n" +
				"		return new HasConstructorWithProperties(cassandraConf);\n" +
				"	}\n" +
				"}\n" +
				"",
			};
			IJavaProject p3 = setupModuleProject("nonmodular3", src, new IClasspathEntry[] { dep1, dep2 });
			p3.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			deleteProject("nonmodular1");
			deleteProject("nonmodular2");
			deleteProject("nonmodular3");
		}
	}

	public void testBug525522() throws Exception {
		try {
			// non-modular substitute for java.jnlp:
			IClasspathAttribute[] jreAttribs = { JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.base,java.desktop,java.rmi,java.sql") };
			IJavaProject jnlp = createJava9ProjectWithJREAttributes("jnlp", new String[] {"src"}, jreAttribs);
			createFolder("jnlp/src/javax/jnlp");
			createFile("jnlp/src/javax/jnlp/UnavailableServiceException.java",
						"package javax.jnlp;\n" +
						"@SuppressWarnings(\"serial\")\n" +
						"public class UnavailableServiceException extends Exception {\n" +
						"}\n");
			createFile("jnlp/src/javax/jnlp/ServiceManager.java",
						"package javax.jnlp;\n" +
						"public class ServiceManager {\n" +
						"	public static void lookup(String s) throws UnavailableServiceException {}\n" +
						"}\n");

			// non-modular project consuming the non-modular jnlp, instead of the module from the JRE: 
			IJavaProject p1 = createJava9ProjectWithJREAttributes("nonmod1", new String[] {"src"}, jreAttribs);
			addClasspathEntry(p1, JavaCore.newProjectEntry(jnlp.getPath()));

			createFolder("nonmod1/src/test");
			createFile("nonmod1/src/test/Test.java",
						"package test;\n" + 
						"import javax.jnlp.ServiceManager;\n" + 
						"import javax.jnlp.UnavailableServiceException;\n" + 
						"\n" + 
						"public class Test {\n" + 
						"\n" + 
						"    void init() {\n" + 
						"        try {\n" + 
						"            ServiceManager.lookup(\"\");\n" + 
						"        } catch (final UnavailableServiceException e) {\n" + 
						"            e.printStackTrace();\n" + 
						"        }\n" + 
						"\n" + 
						"    }\n" + 
						"}\n");
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.reset();
			ICompilationUnit cu = getCompilationUnit("/nonmod1/src/test/Test.java");
			cu.getWorkingCopy(this.wcOwner, null);
			assertProblems(
				"Unexpected problems",
				"----------\n" + 
				"----------\n",
				this.problemRequestor);

		} finally {
			deleteProject("jnlp");
			deleteProject("nonmod1");
		}
	}

	public void testBug525603() throws Exception {
		IJavaProject javaProject = null;
		try {
			String[] sources = {
				"com/automod1/pack/DummyA.java",
				"package com.automod1.pack;\n" +
				"public class DummyA {}\n;"
			};
			String outputDirectory = Util.getOutputDirectory();
	
			String jarPath = outputDirectory + File.separator + "automod.jar";
			Util.createJar(sources, jarPath, "1.8");
			
			javaProject = createJava9Project("mod1", new String[] {"src"});
			IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			addClasspathEntry(javaProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false));

			String srcMod =
				"module mod1 {\n" + 
				"	exports com.mod1.pack1;\n" + 
				"	requires automod;\n" + 
				"}";
			createFile("/mod1/src/module-info.java", 
				srcMod);
			createFolder("/mod1/src/com/mod1/pack1");
			String srcX =
				"package com.mod1.pack1;\n" +
				"public class Dummy {\n" +
				"}";
			createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX);
			
			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod1/src/module-info.java", srcMod, true);
			assertProblems("module-info should have exactly one warning",
					"----------\n" + 
					"1. WARNING in /mod1/src/module-info.java (at line 3)\n" + 
					"	requires automod;\n" + 
					"	         ^^^^^^^\n" + 
					"Name of automatic module \'automod\' is unstable, it is derived from the module\'s file name.\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcX.toCharArray());
			getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX, true);
			assertProblems("X should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
		}
	}

	public void testBug522670() throws Exception {
		Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
		try {
			Hashtable<String, String> newOptions=new Hashtable<>(javaCoreOptions);
			newOptions.put(CompilerOptions.OPTION_Store_Annotations, JavaCore.ENABLED);
			JavaCore.setOptions(newOptions);
			IJavaProject p1 = setupModuleProject("util",
				new String[] {
					"src/module-info.java",
					"module util {\n" +
					"	exports my.util;\n" +
					"}\n" +
					"",
					"src/my/util/Data.java",
					"package my.util;\n" +
					"public class Data {\n" +
					"}\n" +
					"",
					"src/my/util/AnnotatedInModule.java",
					"package my.util;\n" +
					"import static java.lang.annotation.ElementType.TYPE_USE;\n" +
					"import java.lang.annotation.Target;\n" +
					"@Target(TYPE_USE)\n" +
					"@interface Y {\n" +
					"}\n" +
					"public abstract class AnnotatedInModule {\n" +
					"	abstract public @Y Data getTime();\n" +
					"}\n" +
					"",
				});
			IJavaProject p2 = setupModuleProject("util2",
				new String[] {
					"src/module-info.java",
					"module util2 {\n" +
					"	exports my.util.nested;\n" +
					"}\n" +
					"",
					"src/my/util/nested/Unrelated.java",
					"package my.util.nested;\n" +
					"class Unrelated {\n" +
					"}\n" +
					"",
				});
			String[] sources3 = {
				"src/a/other/AnnotatedInOtherNonModule.java",
				"package a.other;\n" +
				"import static java.lang.annotation.ElementType.TYPE_USE;\n" +
				"import java.lang.annotation.Target;\n" +
				"import my.util.Data;\n" +
				"@Target(TYPE_USE)\n" +
				"@interface X {\n" +
				"}\n" +
				"public class AnnotatedInOtherNonModule {\n" +
				"	@X\n" +
				"	Data generationDate;\n" +
				"}\n" +
				"",
			};
			IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
			// modulepath
			IClasspathEntry[] deps3 = { JavaCore.newProjectEntry(p1.getPath(), null, false, attr, false) };
			IJavaProject p3 = setupModuleProject("other", sources3, deps3);
	
			String[] sources4 = {
				"src/test/Test.java",
				"package test;\n" +
				"\n" +
				"import a.other.AnnotatedInOtherNonModule;\n" +
				"import my.util.AnnotatedInModule;\n" +
				"import my.util.Data;\n" +
				"\n" +
				"public class Test extends AnnotatedInOtherNonModule {\n" +
				"	public Data f(AnnotatedInModule calendar) {\n" +
				"		return calendar.getTime();\n" +
				"	}\n" +
				"}\n" +
				"",
			};
			IClasspathEntry[] deps4 = { //
					// modulepath (with split package my.util)
					JavaCore.newProjectEntry(p1.getPath(), null, false, attr, false), //
					JavaCore.newProjectEntry(p2.getPath(), null, false, attr, false), //
					// classpath
					JavaCore.newProjectEntry(p3.getPath()) //
			};
			IJavaProject p4 = setupModuleProject("test", sources4, deps4);
			p4.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
	
			assertNoErrors();
		} finally {
			JavaCore.setOptions(javaCoreOptions);
			deleteProject("util");
			deleteProject("util2");
			deleteProject("other");
			deleteProject("test");
		}
	}

	public void testBug526054() throws Exception {
		if (!isJRE9) return;
		ClasspathJrt.resetCaches();
		try {
			// jdk.rmic is not be visible to code in an unnamed module, but using requires we can see the module.
			// only, there's nothing exported from it (which is why JEP 261 hides it from unnamed), so we --add-reads:
			IClasspathAttribute[] attrs = new IClasspathAttribute[] {
				JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=mod1")
			};
			IJavaProject javaProject = createJava9ProjectWithJREAttributes("mod1", new String[] {"src"}, attrs);

			String srcMod =
				"module mod1 {\n" + 
				"	exports com.mod1.pack1;\n" + 
				"	requires jdk.rmic;\n" + 
				"}";
			createFile("/mod1/src/module-info.java", 
				srcMod);
			createFolder("/mod1/src/com/mod1/pack1");
			String srcX =
				"package com.mod1.pack1;\n" +
				"import sun.rmi.rmic.Main;\n" +
				"public class Dummy {\n" +
				"	String test() {\n" +
				"		return Main.getString(\"in\");\n" +
				"	}\n" +
				"}";
			createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX);

			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod1/src/module-info.java", srcMod, true);
			assertProblems("module-info should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcX.toCharArray());
			getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX, true);
			assertProblems("Dummy should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
		} finally {
			deleteProject("mod1");
		}
	}

	public void testBug526054b() throws Exception {
		ClasspathJrt.resetCaches();
		try {
			// one project can see jdk.rmic/sun.rmi.rmic
			IClasspathAttribute[] attrs = new IClasspathAttribute[] {
				JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=mod1")
			};
			createJava9ProjectWithJREAttributes("mod1", new String[] {"src"}, attrs);

			String srcMod1 =
				"module mod1 {\n" + 
				"	exports com.mod1.pack1;\n" + 
				"	requires jdk.rmic;\n" + 
				"}";
			createFile("/mod1/src/module-info.java", 
				srcMod1);
			createFolder("/mod1/src/com/mod1/pack1");
			String srcX1 =
				"package com.mod1.pack1;\n" +
				"import sun.rmi.rmic.Constants;\n" + // this should never be complained against due to above add-exports.
				"public class Dummy implements Constants {\n" +
				"}";
			createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX1);
			
			// second project cannot see jdk.rmic/sun.rmi.rmic:
			createJava9Project("mod2", new String[] {"src"});

			String srcMod2 =
				"module mod2 {\n" + 
				"	exports com.mod2.pack1;\n" + 
				"	requires jdk.rmic;\n" + 
				"}";
			createFile("/mod2/src/module-info.java", 
				srcMod2);
			createFolder("/mod2/src/com/mod2/pack1");
			String srcX2 =
				"package com.mod2.pack1;\n" +
				"import sun.rmi.rmic.Main;\n" +
				"public class Dummy {\n" +
				"	String test() {\n" +
				"		return Main.getString(\"in\");\n" +
				"	}\n" +
				"}";
			createFile("/mod2/src/com/mod2/pack1/Dummy.java", srcX2);

			// check first:
			this.problemRequestor.initialize(srcX1.toCharArray());
			getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX1, true);
			assertProblems("Dummy in mod1 should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			// check second:
			this.problemRequestor.initialize(srcX2.toCharArray());
			getWorkingCopy("/mod2/src/com/mod2/pack1/Dummy.java", srcX2, true);
			assertProblems("Dummy in mod2 should have problems",
					"----------\n" + 
					"1. ERROR in /mod2/src/com/mod2/pack1/Dummy.java (at line 2)\n" + 
					"	import sun.rmi.rmic.Main;\n" + 
					"	       ^^^^^^^^^^^^^^^^^\n" + 
					"The type sun.rmi.rmic.Main is not accessible\n" + 
					"----------\n" + 
					"2. ERROR in /mod2/src/com/mod2/pack1/Dummy.java (at line 5)\n" + 
					"	return Main.getString(\"in\");\n" + 
					"	       ^^^^\n" + 
					"Main cannot be resolved\n" + 
					"----------\n",
					this.problemRequestor);

			// check both in a combined build
			getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = getWorkspace().getRoot().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"The type sun.rmi.rmic.Main is not accessible\n" + 
					"Main cannot be resolved",
					markers);
		} finally {
			deleteProject("mod1");
			deleteProject("mod2");
		}
	}

	public void testBug525918() throws CoreException {
		try {
			String[] sources = new String[] { 
				"src/module-info.java",
				"import p.MyAbstractDriver;\n" + 
				"import p.MyAbstractDriverWithProvider;\n" + 
				"import p.MyDriverInf;\n" + 
				"import p.MyInfWithProvider;\n" + 
				"module test {\n" +
				"	requires java.sql;\n" +
				"	provides java.sql.Driver with MyDriverInf, MyAbstractDriver, MyInfWithProvider, MyAbstractDriverWithProvider;" +
				"}",
				"src/p/MyDriverInf.java",
				"package p;\n" +
				"public interface MyDriverInf extends java.sql.Driver { }",
				"src/p/MyAbstractDriver.java",
				"package p;\n" +
				"public abstract class MyAbstractDriver {\n" + 
				"	public MyAbstractDriver() { }\n" + 
				"}",
				"src/p/MyInfWithProvider.java",
				"package p;\n" +
				"public interface MyInfWithProvider {\n" + 
				"	public static java.sql.Driver provider() {\n" + 
				"		return null;\n" + 
				"	}\n" + 
				"}\n",
				"src/p/MyAbstractDriverWithProvider.java",
				"package p;\n" +
				"public abstract class MyAbstractDriverWithProvider {\n" + 
				"	public static java.sql.Driver provider() {\n" + 
				"		return null;\n" + 
				"	}\n" + 
				"}"
			};
			IJavaProject p1 = setupModuleProject("test", sources);
			p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			super.sortMarkers(markers);
			assertMarkers("Unexpected markers",
				"Invalid service implementation, the type p.MyAbstractDriver is abstract\n" +
				"Invalid service implementation, the type p.MyDriverInf is abstract\n" +
				"Type mismatch: cannot convert from MyAbstractDriver to Driver"
				, markers);
		} finally {
			deleteProject("test");
		}
	}

	public void testBug527576() throws Exception {
		IJavaProject javaProject = null;
		try {
			
			javaProject = createJava9Project("mod1", new String[] {"src"});
			String[] sources = {
					"org/junit/Assert.java",
					"package org.junit;\n" +
					"public class Assert {}\n;"
				};
		
			Path jarPath = new Path('/' + javaProject.getProject().getName() + '/' + "localjunit.jar");
			Util.createJar(sources, javaProject.getProject().getWorkspace().getRoot().getFile(jarPath).getRawLocation().toOSString(), "1.8");
			javaProject.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);

			addClasspathEntry(javaProject, JavaCore.newLibraryEntry(jarPath, null, null, null, null, false));

			String srcMod =
				"module mod1 {\n" +
				"}";
			createFile("/mod1/src/module-info.java", 
				srcMod);
			createFolder("/mod1/src/com/mod1/pack1");
			String srcX =
				"package com.mod1.pack1;\n" +
				"import org.junit.Assert;\n" +
				"public class Dummy extends Assert {\n" +
				"}";
			createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX);
			
			this.problemRequestor.initialize(srcMod.toCharArray());
			getWorkingCopy("/mod1/src/module-info.java", srcMod, true);
			assertProblems("module-info should have no problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);

			this.problemRequestor.initialize(srcX.toCharArray());
			getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX, true);
			assertProblems("X should have errors because Assert should not be visible",
					"----------\n" + 
					"1. ERROR in /mod1/src/com/mod1/pack1/Dummy.java (at line 2)\n" + 
					"	import org.junit.Assert;\n" + 
					"	       ^^^^^^^^^^^^^^^^\n" + 
					"The type org.junit.Assert is not accessible\n" + 
					"----------\n" + 
					"2. ERROR in /mod1/src/com/mod1/pack1/Dummy.java (at line 3)\n" + 
					"	public class Dummy extends Assert {\n" + 
					"	                           ^^^^^^\n" + 
					"Assert cannot be resolved to a type\n" + 
					"----------\n",
					this.problemRequestor);

			javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = javaProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The type org.junit.Assert is not accessible\n" + 
					"Assert cannot be resolved to a type", 
					markers);
		} finally {
			if (javaProject != null)
				deleteProject(javaProject);
		}
	}
	public void testBug528467a() throws CoreException {
		IJavaProject p1 = createJava9Project("mod.one");
		try {
			IClasspathEntry[] rawClasspath = p1.getRawClasspath();
			String jrtPath = null;
			for (int i = 0; i < rawClasspath.length; i++) {
				IClasspathEntry iClasspathEntry = rawClasspath[i];
				if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY &&
						iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) {
					jrtPath = iClasspathEntry.getPath().toOSString();
					IAccessRule[] pathRules = new IAccessRule[1];
					pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/**"), IAccessRule.K_NON_ACCESSIBLE);
					IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), 
							iClasspathEntry.getSourceAttachmentPath(), 
							iClasspathEntry.getSourceAttachmentRootPath(), 
								pathRules, 
								iClasspathEntry.getExtraAttributes(), 
								iClasspathEntry.isExported());
					rawClasspath[i] = newEntry;
					break;
				}
			}
			p1.setRawClasspath(rawClasspath, null);
			createFolder("/mod.one/src/p1");
			createFile("/mod.one/src/module-info.java",
					"module mod.one {\n" +
					"	exports p1;\n" +
					"	requires java.desktop;\n" +
					"}\n");
			createFile("/mod.one/src/p1/X.java",
					"package p1;\n" +
							"public class X {\n"
							+ "    java.awt.Image im = null;\n"
							+ "}\n");

			waitForManualRefresh();
			waitForAutoBuild();
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			
			assertMarkers("Unexpected markers", "Access restriction: The type 'Image' is not API (restriction on required library '"+ 
																							jrtPath + "')", markers);
		} finally {
			deleteProject(p1);
		}
	}
	public void testBug528467b() throws CoreException {
		IJavaProject p1 = createJava9Project("mod.one");
		try {
			IClasspathEntry[] rawClasspath = p1.getRawClasspath();
			String jrtPath = null;
			for (int i = 0; i < rawClasspath.length; i++) {
				IClasspathEntry iClasspathEntry = rawClasspath[i];
				if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY &&
						iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) {
					jrtPath = iClasspathEntry.getPath().toOSString();
					IAccessRule[] pathRules = new IAccessRule[1];
					pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/Image"), IAccessRule.K_NON_ACCESSIBLE);
					IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), 
							iClasspathEntry.getSourceAttachmentPath(), 
							iClasspathEntry.getSourceAttachmentRootPath(), 
								pathRules, 
								iClasspathEntry.getExtraAttributes(), 
								iClasspathEntry.isExported());
					rawClasspath[i] = newEntry;
					break;
				}
			}
			p1.setRawClasspath(rawClasspath, null);
			createFolder("/mod.one/src/p1");
			createFile("/mod.one/src/module-info.java",
					"module mod.one {\n" +
					"	exports p1;\n" +
					"	requires java.desktop;\n" +
					"}\n");
			createFile("/mod.one/src/p1/X.java",
					"package p1;\n" +
					"import java.awt.*;\n" +
					"public abstract class X extends Image {\n" +
					"	public Graphics foo() {\n" +
					"		return getGraphics();\n" +
					"	}\n"
					+ "}\n");

			waitForManualRefresh();
			waitForAutoBuild();
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);

			assertMarkers("Unexpected markers", 
					"Access restriction: The type \'Image\' is not API (restriction on required library '"+ jrtPath + "')\n" + 
					"The type Graphics from module java.desktop may not be accessible to clients due to missing \'requires transitive\'\n" + 
					"Access restriction: The method \'Image.getGraphics()\' is not API (restriction on required library '"+ jrtPath + "')", markers);
		} finally {
			deleteProject(p1);
		}
	}
	public void testBug528467c() throws CoreException {
		IJavaProject p1 = createJava9Project("unnamed");
		try {
			IClasspathEntry[] rawClasspath = p1.getRawClasspath();
			String jrtPath = null;
			for (int i = 0; i < rawClasspath.length; i++) {
				IClasspathEntry iClasspathEntry = rawClasspath[i];
				if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY &&
						iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) {
					jrtPath = iClasspathEntry.getPath().toOSString();
					IAccessRule[] pathRules = new IAccessRule[1];
					pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/**"), IAccessRule.K_NON_ACCESSIBLE);
					IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), 
							iClasspathEntry.getSourceAttachmentPath(), 
							iClasspathEntry.getSourceAttachmentRootPath(), 
								pathRules, 
								iClasspathEntry.getExtraAttributes(), 
								iClasspathEntry.isExported());
					rawClasspath[i] = newEntry;
					break;
				}
			}
			p1.setRawClasspath(rawClasspath, null);
			createFolder("/unnamed/src/p1");
			createFile("/unnamed/src/p1/X.java",
					"package p1;\n" +
							"public class X {\n"
							+ "    java.awt.Image im = null;\n"
							+ "}\n");

			waitForManualRefresh();
			waitForAutoBuild();
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);

			assertMarkers("Unexpected markers", "Access restriction: The type 'Image' is not API (restriction on required library '"+ 
																							jrtPath + "')", markers);
		} finally {
			deleteProject(p1);
		}
	}
	// Bug 520713: allow test code to access code on the classpath
	public void testWithTestAttributeAndTestDependencyOnClassPath() throws CoreException, IOException {
		String outputDirectory = Util.getOutputDirectory();
		
		String jarPath = outputDirectory + File.separator + "mytestlib.jar";
		IJavaProject project1 = null;
		IJavaProject project2 = null;
		try {
			String[] sources = {
				"my/test/Test.java",
				"package my.test;\n" +
				"public class Test {}\n;"
			};
			Util.createJar(sources, jarPath, "1.8");
			
			project1 = createJava9Project("Project1", new String[] {"src"});
			addClasspathEntry(project1, JavaCore.newSourceEntry(new Path("/Project1/src-tests"), null, null, new Path("/Project1/bin-tests"), new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") }));
			addClasspathEntry(project1, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") }, false));

			createFolder("/Project1/src/p1");
			createFolder("/Project1/src-tests/p1");
			createFile("/Project1/src/module-info.java",
					"module m1 {\n" +
					"	exports p1;\n" +
					"}");
			createFile("/Project1/src/p1/P1Class.java", 
					"package p1;\n" + 
					"\n" + 
					"public class P1Class {\n"+ 
					"}\n" 
					);
			createFile("/Project1/src/p1/Production1.java",
					"package p1;\n" + 
					"\n" + 
					"public class Production1 {\n" + 
					"	void p1() {\n" + 
					"		new P1Class(); // ok\n" + 
					"		new T1Class(); // forbidden\n" + 
					"	}\n" + 
					"}\n" + 
					""
					);
			createFile("/Project1/src-tests/p1/T1Class.java", 
					"package p1;\n" + 
					"\n" + 
					"public class T1Class {\n"+ 
					"}\n" 
					);
			createFile("/Project1/src-tests/p1/Test1.java", 
					"package p1;\n" + 
					"\n" + 
					"public class Test1 extends my.test.Test {\n" + 
					"	void test1() {\n" + 
					"		new P1Class(); // ok\n" + 
					"		new T1Class(); // ok\n" + 
					"	}\n" + 
					"}\n" + 
					"" 
					);
			project1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
	
			IMarker[] markers = project1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"T1Class cannot be resolved to a type" + 
					"", 
					markers);
			
			project2 = createJava9Project("Project2", new String[] {"src"});
			addClasspathEntry(project2, JavaCore.newProjectEntry(new Path("/Project1"), null, false, new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }, false));
			addClasspathEntry(project2, JavaCore.newSourceEntry(new Path("/Project2/src-tests"), null, null, new Path("/Project2/bin-tests"), new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") }));
			addClasspathEntry(project2, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") }, false));
			createFolder("/Project2/src/p2");
			createFolder("/Project2/src-tests/p2");
			createFile("/Project2/src/module-info.java",
					"module m2 {\n" +
					"	requires m1;\n" +
					"}");
			createFile("/Project2/src/p2/P2Class.java", 
					"package p2;\n" + 
					"\n" + 
					"public class P2Class {\n"+ 
					"}\n" 
					);
			createFile("/Project2/src/p2/Production2.java",
					"package p2;\n" + 
					"\n" + 
					"import p1.P1Class;\n" + 
					"import p1.T1Class;\n" + 
					"\n" + 
					"public class Production2 {\n" + 
					"	void p2() {\n" + 
					"		new P1Class(); // ok\n" + 
					"		new P2Class(); // ok\n" + 
					"		new T1Class(); // forbidden\n" + 
					"		new T2Class(); // forbidden\n" + 
					"	}\n" + 
					"}\n" + 
					""
					);
			createFile("/Project2/src-tests/p2/T2Class.java", 
					"package p2;\n" + 
					"\n" + 
					"public class T2Class {\n"+ 
					"}\n" 
					);
			createFile("/Project2/src-tests/p2/Test2.java", 
					"package p2;\n" + 
					"\n" + 
					"import p1.P1Class;\n" + 
					"import p1.T1Class;\n" + 
					"\n" + 
					"public class Test2 extends p1.Test1 {\n" + 
					"	void test2() {\n" + 
					"		new P1Class(); // ok\n" + 
					"		new P2Class(); // ok\n" + 
					"		new T1Class(); // ok\n" + 
					"		new T2Class(); // ok\n" + 
					"	}\n" + 
					"}\n" + 
					"" 
					);
			project1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
	
			IMarker[] markers2 = project2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers2);
			assertMarkers("Unexpected markers", 
					"The import p1.T1Class cannot be resolved\n" + 
					"T1Class cannot be resolved to a type\n" + 
					"T2Class cannot be resolved to a type", 
					markers2);
		} finally {
			if (project1 != null)
				deleteProject(project1);
			if (project2 != null)
				deleteProject(project2);
			new File(jarPath).delete();
		}
	}

	public void testBug531579() throws Exception {
		String outputDirectory = Util.getOutputDirectory();

		String jarPath = outputDirectory + File.separator + "jaxb-api.jar";
		IJavaProject project1 = null;
		try {
			// these types replace inaccessible types from JRE/javax.xml.bind:
			// (not a problem during IDE builds)
			String[] sources = {
				"javax/xml/bind/JAXBContext.java",
				"package javax.xml.bind;\n" +
				"public abstract class JAXBContext {\n" + 
				"	public static JAXBContext newInstance( String contextPath )\n" + 
				"		throws JAXBException {\n" +
				"		return null;\n" +
				"	}\n" +
				"}\n",
				"javax/xml/bind/JAXBException.java",
				"package javax.xml.bind;\n" +
				"public class JAXBException extends Exception {}\n"
			};
			Util.createJar(sources, jarPath, "1.8");

			project1 = createJava9Project("Project1", new String[] {"src"});
			addClasspathEntry(project1, JavaCore.newLibraryEntry(new Path(jarPath), null, null));

			createFolder("/Project1/src/p1");
			createFile("/Project1/src/p1/ImportJAXBType.java", 
					"package p1;\n" + 
					"\n" + 
					"import javax.xml.bind.JAXBContext;\n" + 
					"\n" + 
					"public class ImportJAXBType {\n" + 
					"\n" + 
					"	public static void main(String[] args) throws Exception {\n" + 
					"		JAXBContext context = JAXBContext.newInstance(\"\");\n" + 
					"	}\n" + 
					"\n" + 
					"}\n" 
					);

			project1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);

			IMarker[] markers = project1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"The value of the local variable context is not used", 
					markers);
		} finally {
			if (project1 != null)
				deleteProject(project1);
			new File(jarPath).delete();
		}
	}
	public void testBug527569a() throws CoreException {
		IJavaProject p1 = createJava9Project("Bug527569", "9");
		try {
			createFolder("/Bug527569/src/p1");
			createFile("/Bug527569/src/p1/X.java",
					"package p1;\n" +
					"public class X {\n" +
					"	public java.util.stream.Stream<String> emptyStream() {\n" +
					"		return null;\n" +
					"	}\n" +
					"}");

			waitForManualRefresh();
			waitForAutoBuild();
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject(p1);
		}
	}
	public void testBug527569b() throws CoreException {
		IJavaProject p1 = createJava9Project("Bug527569", "1.7");
		try {
			createFolder("/Bug527569/src/p1");
			createFile("/Bug527569/src/p1/X.java",
					"package p1;\n" +
					"public class X {\n" +
					"	public java.util.stream.Stream<String> emptyStream() {\n" +
					"		return null;\n" +
					"	}\n" +
					"}");

			waitForManualRefresh();
			waitForAutoBuild();
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject(p1);
		}
	}
	public void testBug527569c() throws CoreException {
		if (!isJRE9) return;
		IJavaProject p1 = createJava9Project("Bug527569", "1.7");
		Map<String, String> options = new HashMap<>();
		// Make sure the new options map doesn't reset.
		options.put(CompilerOptions.OPTION_Compliance, "1.7");
		options.put(CompilerOptions.OPTION_Source, "1.7");
		options.put(CompilerOptions.OPTION_TargetPlatform, "1.7");
		options.put(CompilerOptions.OPTION_Release, "enabled");
		p1.setOptions(options);
		try {
			createFolder("/Bug527569/src/p1");
			createFile("/Bug527569/src/p1/X.java",
					"package p1;\n" +
					"public class X {\n" +
					"	public java.util.stream.Stream<String> emptyStream() {\n" +
					"		return null;\n" +
					"	}\n" +
					"}");

			waitForManualRefresh();
			waitForAutoBuild();
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "java.util.stream.Stream cannot be resolved to a type", markers);
		} finally {
			deleteProject(p1);
		}
	}
	public void testBug527569d() throws CoreException {
		IJavaProject p1 = createJava9Project("Bug527569", "9");
		try {
			createFolder("/Bug527569/src/p1");
			createFile("/Bug527569/src/p1/X.java",
					"package p1;\n" +
					"public class X {\n" +
					"	public java.lang.Compiler getCompiler() {\n" +
					"		return null;\n" +
					"	}\n" +
					"}");

			waitForManualRefresh();
			waitForAutoBuild();
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "The type Compiler has been deprecated since version 9 and marked for removal", markers);
		} finally {
			deleteProject(p1);
		}
	}
	public void testBug527569e() throws CoreException {
		if (!isJRE9 || isJRE12) return;
		IJavaProject p1 = createJava9Project("Bug527569", "1.8");
		Map<String, String> options = new HashMap<>();
		// Make sure the new options map doesn't reset.
		options.put(CompilerOptions.OPTION_Compliance, "1.7");
		options.put(CompilerOptions.OPTION_Source, "1.7");
		options.put(CompilerOptions.OPTION_TargetPlatform, "1.7");
		options.put(CompilerOptions.OPTION_Release, "enabled");
		p1.setOptions(options);
		try {
			createFolder("/Bug527569/src/p1");
			createFile("/Bug527569/src/p1/X.java",
					"package p1;\n" +
					"public class X {\n" +
					"	public java.lang.Compiler getCompiler() {\n" +
					"		return null;\n" +
					"	}\n" +
					"}");

			waitForManualRefresh();
			waitForAutoBuild();
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject(p1);
		}
	}
	public void testBug522601() throws CoreException {
		IJavaProject p1 = createJava9Project("Bug522601", "9");
		try {
			IFile file = createFile("/Bug522601/test.txt", "not a jar");
			IClasspathAttribute modAttr = JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true");
			addLibraryEntry(p1, file.getFullPath(), null, null, null, null, new IClasspathAttribute[] { modAttr }, false);
			p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers", 
					"Archive for required library: \'test.txt\' in project \'Bug522601\' cannot be read or is not a valid ZIP file\n" + 
					"The project cannot be built until build path errors are resolved", markers);
		} finally {
			deleteProject(p1);
		}
	}
	// automatic modules export all their packages
	public void testBug532724() throws CoreException, IOException {
		try {
			String libPath = "externalLib/test.jar";
			Util.createJar(
					new String[] {
						"test/src/org/astro/World.java", //$NON-NLS-1$
						"package org.astro;\n" +
						"public interface World {\n" +
						"	public String name();\n" +
						"}",
					},
					null,
					new HashMap<>(),
					null,
					getExternalResourcePath(libPath));
			String[] src = new String[] { 
					"src/module-info.java",
					"module com.greetings {\n" +
					"	requires transitive test;\n" +
					"	exports com.greetings;\n" +
					"}",
					"src/com/greetings/MyWorld.java",
					"package com.greetings;\n" +
					"import org.astro.World;\n"	+
					"public class MyWorld {\n" +
					"	public World name() {\n" +
					"		return null;\n" +
					"	}\n" +
					"}"
			};
			IClasspathAttribute modAttr = new ClasspathAttribute("module", "true");
			IClasspathEntry dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, ClasspathEntry.NO_ACCESS_RULES,
					new IClasspathAttribute[] {modAttr},
					false/*not exported*/);
			IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
			p2.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE);
			p2.setOption(JavaCore.COMPILER_PB_API_LEAKS, JavaCore.ERROR);

			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteExternalResource("externalLib");
			this.deleteProject("com.greetings");
		}
	}
	public void testBug534624a() throws CoreException, IOException {
		IJavaProject project = null;
		Hashtable<String, String> options = JavaCore.getOptions();
		try {
			project = setUpJavaProject("bug.test.b534624");
			IClasspathEntry[] rawClasspath = project.getRawClasspath();
			IClasspathEntry jrtEntry = getJRTLibraryEntry();
			for(int i = 0; i < rawClasspath.length; i++) {
				if (rawClasspath[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
					rawClasspath[i] = jrtEntry;
			}
			project.setRawClasspath(rawClasspath, null);
			project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_10);
			project.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_10);
			project.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_10);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "Version9 cannot be resolved to a module", markers);
		} finally {
			if (project != null)
				deleteProject(project);
			JavaCore.setOptions(options);
		}
	}
	public void testBug534624b() throws CoreException, IOException {
		IJavaProject project = null;
		Hashtable<String, String> options = JavaCore.getOptions();
		try {
			project = setUpJavaProject("bug.test.b534624");
			IClasspathEntry[] rawClasspath = project.getRawClasspath();
			IClasspathEntry jrtEntry = getJRTLibraryEntry();
			for(int i = 0; i < rawClasspath.length; i++) {
				if (rawClasspath[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
					rawClasspath[i] = jrtEntry;
			}
			project.setRawClasspath(rawClasspath, null);
			project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_9);
			project.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_9);
			project.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_9);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "Version10 cannot be resolved to a module", markers);
			
			project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_10);
			project.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_10);
			project.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_10);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "Version9 cannot be resolved to a module", markers);
		} finally {
			if (project != null)
				deleteProject(project);
			JavaCore.setOptions(options);
		}
	}
	// missing linked jar must not cause NPE
	public void testBug540904() throws CoreException, IOException {
		try {
			String[] src = new String[] { 
					"src/test/Test.java",
					"package test;\n" +
					"public class Test {\n" +
					"}"
			};
			IJavaProject p2 = setupModuleProject("Bug540904", src, new IClasspathEntry[] {  });
			IFile file = getFile("/Bug540904/link.jar");
			file.createLink(new Path("MISSING/missing.jar"), IResource.ALLOW_MISSING_LOCAL, null);
			addLibraryEntry(p2, file.getFullPath(), false);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			this.deleteProject("Bug540904");
		}
	}
	public void testBug540788() throws Exception {
		try {
			// project common:
			IJavaProject common = createJava9Project("Bug540788.common", new String[] { "src/main/java" });
			createSourceFiles(common,
					new String[] {
						"src/main/java/module-info.java",
						"module org.sheepy.common {\n" + 
						"	requires transitive org.eclipse.emf.common;\n" + 
						"	requires transitive org.eclipse.emf.ecore;\n" + 
						"}\n"
					});
			IFolder libs = createFolder("/Bug540788.common/libs");
			String emfCommonLocation = libs.getLocation()+"/org.eclipse.emf.common.jar";
			Path emfCommonPath = new Path(emfCommonLocation);
			Util.createJar(
					new String[] {
							"src/org/eclipse/emf/common/Foo.java",
							"package org.eclipse.emf.common;\n" +
							"public interface Foo {\n" +
							"}",
					},
					null,
					new HashMap<>(),
					null,
					emfCommonLocation);
			addModularLibraryEntry(common, emfCommonPath, null);

			String ecoreLocation = libs.getLocation()+"/org.eclipse.emf.ecore.jar";
			Path ecorePath = new Path(ecoreLocation);
			Util.createJar(
					new String[] {
						"src/org/eclipse/emf/ecore/EObject.java",
						"package org.eclipse.emf.ecore;\n" +
						"public interface EObject {\n" +
						"}",
					},
					null,
					new HashMap<>(),
					null,
					ecoreLocation);
			addModularLibraryEntry(common, ecorePath, null);
			// project vulkan:
			IJavaProject vulkan = createJava9Project("Bug540788.vulkan", new String[] { "src/main/java" });
			createSourceFiles(vulkan,
					new String[] {
						"src/main/java/module-info.java",
						"module org.sheepy.vulkan {\n" + 
						"	requires transitive org.sheepy.common;\n" + 
						"	exports org.sheepy.vulkan.model.resource;\n" + 
						"}\n",
						"src/main/java/org/sheepy/vulkan/model/resource/Resource.java",
						"package org.sheepy.vulkan.model.resource;\n" + 
						"import org.eclipse.emf.ecore.EObject;\n" + 
						"public interface Resource extends EObject {\n" + 
						"}\n",
						"src/main/java/org/sheepy/vulkan/model/resource/VulkanBuffer.java",
						"package org.sheepy.vulkan.model.resource;\n" + 
						"public interface VulkanBuffer extends Resource {\n" + 
						"}\n",
					});
			addModularProjectEntry(vulkan, common);
			addModularLibraryEntry(vulkan, emfCommonPath, null);
			addModularLibraryEntry(vulkan, ecorePath, null);
			// project vulkan.demo
			IJavaProject vulkan_demo = createJava9Project("Bug540788.vulkan.demo", new String[] { "src/main/java" });
			createSourceFiles(vulkan_demo,
					new String[] {
						"src/main/java/module-info.java",
						"module org.sheepy.vulkan.demo {\n" + 
						"	exports org.sheepy.vulkan.demo.model;\n" + 
						"	requires org.sheepy.vulkan;\n" + 
						"}\n",
						"src/main/java/org/sheepy/vulkan/demo/model/UniformBuffer.java",
						"package org.sheepy.vulkan.demo.model;\n" + 
						"import org.sheepy.vulkan.model.resource.VulkanBuffer;\n" + 
						"public interface UniformBuffer extends VulkanBuffer {\n" + 
						"}\n",
					});
			addModularProjectEntry(vulkan_demo, vulkan);
			addModularProjectEntry(vulkan_demo, common);
			addModularLibraryEntry(vulkan_demo, emfCommonPath, null);
			addModularLibraryEntry(vulkan_demo, ecorePath, null);
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = vulkan_demo.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "", markers);
		} finally {
			deleteProject("Bug540788.common");
			deleteProject("Bug540788.vulkan");
			deleteProject("Bug540788.vulkan.demo");
		}
	}
	public void testBug541015() throws Exception {
		try {
			IJavaProject m1 = createJava9Project("m1", new String[] { "src" });
			createSourceFiles(m1,
					new String[] {
						"src/module-info.java",
						"module m1 { exports org.p1; }\n",
						"src/org/p1/T1.java",
						"package org.p1;\n" +
						"public class T1 {}\n"
					});
			IJavaProject m2 = createJava9Project("m2", new String[] { "src" });
			createSourceFiles(m2,
					new String[] {
						"src/module-info.java",
						"module m2 { exports org.p1; }\n",
						"src/org/p1/T1.java",
						"package org.p1;\n" +
						"public class T1 {}\n"
					});
			IJavaProject m3 = createJava9Project("m3", new String[] { "src" });
			createSourceFiles(m3,
					new String[] {
						"src/module-info.java",
						"module m3 { exports org.p1; }\n",
						"src/org/p1/T1.java",
						"package org.p1;\n" +
						"public class T1 {}\n"
					});
			IJavaProject unnamed = createJava9Project("unnamed", new String[] { "src" });
			String testSource = "package test;\n" +
			"import org.p1.T1;\n" +
			"public class Test {\n" +
			"	T1 t1;\n" +
			"}\n";
			createSourceFiles(unnamed,
					new String[] {
						"src/test/Test.java",
						testSource
					});
			addModularProjectEntry(unnamed, m1);
			addModularProjectEntry(unnamed, m2);
			addModularProjectEntry(unnamed, m3);
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = unnamed.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"The package org.p1 is accessible from more than one module: m1, m2, m3\n" + 
					"T1 cannot be resolved to a type",
					markers);
			
			char[] sourceChars = testSource.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit("/unnamed/src/test/Test.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"1. ERROR in /unnamed/src/test/Test.java (at line 2)\n" + 
					"	import org.p1.T1;\n" + 
					"	       ^^^^^^\n" + 
					"The package org.p1 is accessible from more than one module: m1, m2, m3\n" + 
					"----------\n" + 
					"2. ERROR in /unnamed/src/test/Test.java (at line 4)\n" + 
					"	T1 t1;\n" + 
					"	^^\n" + 
					"T1 cannot be resolved to a type\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject("m1");
			deleteProject("m2");
			deleteProject("m3");
			deleteProject("unnamed");
		}
	}
	public void testBug536928_comment22() throws CoreException, IOException {
		try {
			IJavaProject project = createJava9Project("ztest", new String[] { "src" });
			createFolder("/ztest/lib");
			Util.createJar(new String[] {
					"javax/xml/transform/Transformer.java",
					"package javax.xml.transform;\n" +
					"public class Transformer {}\n",
					"javax/xml/transform/Result.java",
					"package javax.xml.transform;\n" +
					"public class Result {}\n"
				},
				project.getProject().getLocation().toString() + "/lib/xml-apis.jar",
				"1.8");
			project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
			IClasspathEntry libraryEntry = JavaCore.newLibraryEntry(new Path("/ztest/lib/xml-apis.jar"), null, null);
			addClasspathEntry(project, libraryEntry, 1); // right after src and before jrt-fs.jar
			
			String testSource =
					"package com.ztest;\n" + 
					"import javax.xml.transform.Transformer;\n" + 
					"\n" + 
					"public class TestApp {\n" +
					"	Transformer ts;\n" +
					"	javax.xml.transform.Result result;\n" + 
					"}\n";
			createFolder("/ztest/src/com/ztest");
			createFile("/ztest/src/com/ztest/TestApp.java", testSource);
			String test2Source =
					"package com.ztest;\n" +
					"import javax.xml.transform.*;\n" +
					"public class Test2 {\n" +
					"	Transformer ts;\n" +
					"}\n";
			createFile("/ztest/src/com/ztest/Test2.java", test2Source);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected Markers",
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" +
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" +
					"Transformer cannot be resolved to a type\n" +
					"Transformer cannot be resolved to a type\n" +
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml",
					markers);
			
			char[] sourceChars = testSource.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit("/ztest/src/com/ztest/TestApp.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"1. ERROR in /ztest/src/com/ztest/TestApp.java (at line 2)\n" + 
					"	import javax.xml.transform.Transformer;\n" + 
					"	       ^^^^^^^^^^^^^^^^^^^\n" + 
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + 
					"----------\n" + 
					"2. ERROR in /ztest/src/com/ztest/TestApp.java (at line 5)\n" + 
					"	Transformer ts;\n" + 
					"	^^^^^^^^^^^\n" + 
					"Transformer cannot be resolved to a type\n" + 
					"----------\n" + 
					"3. ERROR in /ztest/src/com/ztest/TestApp.java (at line 6)\n" + 
					"	javax.xml.transform.Result result;\n" + 
					"	^^^^^^^^^^^^^^^^^^^\n" + 
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + 
					"----------\n",
					this.problemRequestor);

			sourceChars = test2Source.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit("/ztest/src/com/ztest/Test2.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"1. ERROR in /ztest/src/com/ztest/Test2.java (at line 2)\n" + 
					"	import javax.xml.transform.*;\n" + 
					"	       ^^^^^^^^^^^^^^^^^^^\n" + 
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + 
					"----------\n" + 
					"2. ERROR in /ztest/src/com/ztest/Test2.java (at line 4)\n" + 
					"	Transformer ts;\n" + 
					"	^^^^^^^^^^^\n" + 
					"Transformer cannot be resolved to a type\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject("ztest");
		}
	}
	public void testBug536928_comment22b() throws CoreException, IOException {
		try {
			IJavaProject project = createJava9Project("ztest", new String[] { "src" });
			createFolder("/ztest/lib");
			Util.createJar(new String[] {
					"javax/xml/transform/Transformer.java",
					"package javax.xml.transform;\n" +
					"public class Transformer {}\n",
					"javax/xml/transform/Result.java",
					"package javax.xml.transform;\n" +
					"public class Result {}\n"
				},
				project.getProject().getLocation().toString() + "/lib/xml-apis.jar",
				"1.8");
			project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
			IClasspathEntry libraryEntry = JavaCore.newLibraryEntry(new Path("/ztest/lib/xml-apis.jar"), null, null);
			addClasspathEntry(project, libraryEntry, 2); // DIFFERENCE HERE: place xml-apis.jar AFTER jrt-fs.jar
			
			String testSource =
					"package com.ztest;\n" + 
					"import javax.xml.transform.Transformer;\n" + 
					"\n" + 
					"public class TestApp {\n" +
					"	Transformer ts;\n" +
					"	javax.xml.transform.Result result;\n" + 
					"}\n";
			createFolder("/ztest/src/com/ztest");
			createFile("/ztest/src/com/ztest/TestApp.java", testSource);
			String test2Source =
					"package com.ztest;\n" +
					"import javax.xml.transform.*;\n" +
					"public class Test2 {\n" +
					"	Transformer ts;\n" +
					"}\n";
			createFile("/ztest/src/com/ztest/Test2.java", test2Source);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected Markers",
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" +
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" +
					"Transformer cannot be resolved to a type\n" +
					"Transformer cannot be resolved to a type\n" +
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml",
					markers);
			
			char[] sourceChars = testSource.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit("/ztest/src/com/ztest/TestApp.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"1. ERROR in /ztest/src/com/ztest/TestApp.java (at line 2)\n" + 
					"	import javax.xml.transform.Transformer;\n" + 
					"	       ^^^^^^^^^^^^^^^^^^^\n" + 
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + 
					"----------\n" + 
					"2. ERROR in /ztest/src/com/ztest/TestApp.java (at line 5)\n" + 
					"	Transformer ts;\n" + 
					"	^^^^^^^^^^^\n" + 
					"Transformer cannot be resolved to a type\n" + 
					"----------\n" + 
					"3. ERROR in /ztest/src/com/ztest/TestApp.java (at line 6)\n" + 
					"	javax.xml.transform.Result result;\n" + 
					"	^^^^^^^^^^^^^^^^^^^\n" + 
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + 
					"----------\n",
					this.problemRequestor);

			sourceChars = test2Source.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit("/ztest/src/com/ztest/Test2.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"1. ERROR in /ztest/src/com/ztest/Test2.java (at line 2)\n" + 
					"	import javax.xml.transform.*;\n" + 
					"	       ^^^^^^^^^^^^^^^^^^^\n" + 
					"The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + 
					"----------\n" + 
					"2. ERROR in /ztest/src/com/ztest/Test2.java (at line 4)\n" + 
					"	Transformer ts;\n" + 
					"	^^^^^^^^^^^\n" + 
					"Transformer cannot be resolved to a type\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject("ztest");
		}
	}
	public void testBug536928_comment22_limited() throws CoreException, IOException {
		try {
			IClasspathAttribute[] limitModules = {
				JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.base")	
			};
			IJavaProject project = createJava9ProjectWithJREAttributes("ztest", new String[] { "src" }, limitModules);
			createFolder("/ztest/lib");
			Util.createJar(new String[] {
					"javax/xml/transform/Transformer.java",
					"package javax.xml.transform;\n" +
					"public class Transformer {}\n",
					"javax/xml/transform/Result.java",
					"package javax.xml.transform;\n" +
					"public class Result {}\n"
				},
				project.getProject().getLocation().toString() + "/lib/xml-apis.jar",
				"1.8");
			project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
			IClasspathEntry libraryEntry = JavaCore.newLibraryEntry(new Path("/ztest/lib/xml-apis.jar"), null, null);
			addClasspathEntry(project, libraryEntry, 1); // right after src and before jrt-fs.jar
			
			String testSource =
					"package com.ztest;\n" + 
					"import javax.xml.transform.Transformer;\n" + 
					"\n" + 
					"public class TestApp {\n" +
					"	Transformer ts;\n" + 
					"	javax.xml.transform.Result result;\n" + 
					"}\n";
			createFolder("/ztest/src/com/ztest");
			createFile("/ztest/src/com/ztest/TestApp.java", testSource);
			String test2Source =
					"package com.ztest;\n" +
					"import javax.xml.transform.*;\n" +
					"public class Test2 {\n" +
					"	Transformer ts;\n" +
					"}\n";
			createFile("/ztest/src/com/ztest/Test2.java", test2Source);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
			
			char[] sourceChars = testSource.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit("/ztest/src/com/ztest/TestApp.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
			sourceChars = test2Source.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit("/ztest/src/com/ztest/Test2.java").getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject("ztest");
		}
	}
	public void testBug542896() throws CoreException {
		IJavaProject java10Project = createJava10Project("bug", new String[] { "src" });
		try {
			createFolder("/bug/src/test/platform");
			createFile("/bug/src/test/platform/Context.java",
					"package test.platform;\n" + 
					"\n" + 
					"import java.net.URI;\n" + 
					"\n" + 
					"public interface Context {\n" + 
					"	public URI getURI();\n" + 
					"}\n");
			createFile("/bug/src/test/platform/AbstractContext.java",
					"package test.platform;\n" + 
					"\n" + 
					"import java.net.URI;\n" + 
					"import java.util.*;\n" + 
					"import test.*;\n" + 
					"\n" + 
					"public abstract class AbstractContext implements Context {\n" + 
					"	Iterable<URI> uris = new ArrayList<URI>();\n" + 
					"	Application application;\n" + 
					"}\n");
			String testSource =
					"package test;\n" + 
					"\n" + 
					"import java.io.*;\n" + 
					"import java.net.*;\n" + 
					"import java.util.*;\n" + 
					"\n" + 
					"import test.platform.*;\n" + 
					"\n" + 
					"public interface Application // extends Foo\n" + 
					"{\n" + 
					"}\n";
			String testPath = "/bug/src/test/Application.java";
			createFile(testPath, testSource);
			// first compile: no error:
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
			char[] sourceChars = testSource.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit(testPath).getWorkingCopy(this.wcOwner, null);
			assertProblems(
					"Unexpected problems",
					"----------\n" + 
					"1. WARNING in /bug/src/test/Application.java (at line 3)\n" + 
					"	import java.io.*;\n" + 
					"	       ^^^^^^^\n" + 
					"The import java.io is never used\n" + 
					"----------\n" + 
					"2. WARNING in /bug/src/test/Application.java (at line 4)\n" + 
					"	import java.net.*;\n" + 
					"	       ^^^^^^^^\n" + 
					"The import java.net is never used\n" + 
					"----------\n" + 
					"3. WARNING in /bug/src/test/Application.java (at line 5)\n" + 
					"	import java.util.*;\n" + 
					"	       ^^^^^^^^^\n" + 
					"The import java.util is never used\n" + 
					"----------\n" + 
					"4. WARNING in /bug/src/test/Application.java (at line 7)\n" + 
					"	import test.platform.*;\n" + 
					"	       ^^^^^^^^^^^^^\n" + 
					"The import test.platform is never used\n" + 
					"----------\n",
					this.problemRequestor);
			// introduce error:
			String testSourceEdited =
					"package test;\n" + 
					"\n" + 
					"import java.io.*;\n" + 
					"import java.net.*;\n" + 
					"import java.util.*;\n" + 
					"\n" + 
					"import test.platform.*;\n" + 
					"\n" + 
					"public interface Application extends Foo\n" + 
					"{\n" + 
					"}\n";
			editFile(testPath, testSourceEdited);
			java10Project.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			IMarker[] markers = java10Project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers", "Foo cannot be resolved to a type", markers);
		} finally {
			if (java10Project != null)
				deleteProject(java10Project);
		}
	}
	public void testBug543392a() throws Exception {
		bug543392(null);
	}
	public void testBug543392b() throws Exception {
		// put other on the *modulepath*:
		IClasspathAttribute[] attrs = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
		bug543392(attrs);
	}
	void bug543392(IClasspathAttribute[] dependencyAttrs) throws Exception {
		IJavaProject other = createJava9Project("other");
		IJavaProject current = createJava9Project("current");
		try {
			createFile("other/src/module-info.java",
					"module other {\n" +
					"	exports other.p;\n" +
					"}\n");
			createFolder("other/src/other/p");
			createFile("other/src/other/p/C.java",
					"package other.p;\n" +
					"public class C {}\n");

			addClasspathEntry(current,
					JavaCore.newProjectEntry(other.getProject().getFullPath(), null, false, dependencyAttrs, false)); // dependency, but ..
			createFile("current/src/module-info.java", "module current {}\n"); // ... no 'requires'!
			createFolder("current/src/current");

			String test1path = "current/src/current/Test1.java";
			String test1source =
					"package current;\n" +
					"import other.p.C;\n" +
					"public class Test1 {\n" +
					"}\n";
			createFile(test1path, test1source);
			String test2path = "current/src/current/Test2.java";
			String test2source =
					"package current;\n" +
					"public class Test2 {\n" +
					"	other.p.C c;\n" +
					"}\n";
			createFile(test2path, test2source);

			getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			IMarker[] markers = current.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
					"The type other.p.C is not accessible\n" +
					"The type other.p.C is not accessible",
					markers);

			char[] sourceChars = test1source.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit(test1path).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"1. ERROR in /current/src/current/Test1.java (at line 2)\n" + 
					"	import other.p.C;\n" + 
					"	       ^^^^^^^^^\n" + 
					"The type other.p.C is not accessible\n" + 
					"----------\n",
					this.problemRequestor);
			sourceChars = test2source.toCharArray();
			this.problemRequestor.initialize(sourceChars);
			getCompilationUnit(test2path).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"1. ERROR in /current/src/current/Test2.java (at line 3)\n" + 
					"	other.p.C c;\n" + 
					"	^^^^^^^^^\n" + 
					"The type other.p.C is not accessible\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject(other);
			deleteProject(current);
		}
	}
	public void testBug541328() throws Exception {
		IJavaProject pa = createJava9Project("m.a");
		IJavaProject pb = createJava9Project("m.b");
		IJavaProject test = createJava9Project("test");
		try {
			createFolder("m.a/src/a/foo");
			createFile("m.a/src/a/foo/Bar.java", "package a.foo;\n public class Bar {}\n");
			createFile("m.a/src/module-info.java",
					"module m.a {\n" +
					"	exports a.foo to m.b;\n" +
					"}\n");
			createFile("m.b/src/module-info.java",
					"module m.b {\n" +
					"	requires m.a;\n" +
					"	exports b;\n" +
					"}\n");
			createFolder("m.b/src/b");
			createFile("m.b/src/b/Boo.java",
					"package b;\n" +
					"import a.foo.Bar;\n" +
					"public class Boo extends Bar {}\n");
			addModularProjectEntry(pb, pa);

			IClasspathAttribute[] forceExport = { 
						JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
						JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "m.a/a.foo=ALL-UNNAMED")
					};
			addClasspathEntry(test, JavaCore.newProjectEntry(pa.getPath(), null, false, forceExport, false));
			addModularProjectEntry(test, pb);

			String testSource =
					"import a.foo.Bar;\n" +
					"import b.Boo;\n" +
					"public class Test {\n" +
					"	Bar b = new Boo();\n" +
					"}\n";
			String testPath = "test/src/Test.java";
			createFile(testPath, testSource);
			getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.initialize(testSource.toCharArray());
			getCompilationUnit(testPath).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject(pa);
			deleteProject(pb);
			deleteProject(test);
		}
	}
	public void testBug543195() throws CoreException {
		IJavaProject pj1 = createJava9Project("pj1");
		IJavaProject pj2 = createJava9Project("pj2");
		IJavaProject ptest = createJava9Project("ptest");
		try {
			addModularProjectEntry(pj2, pj1);
			addModularProjectEntry(ptest, pj2);

			createFolder("pj1/src/p");
			createFile("pj1/src/p/Missing.java",
					"package p;\n" +
					"public class Missing {\n" +
					"	public void miss() {}\n" +
					"}\n");
			createFile("pj1/src/module-info.java",
					"module pj1 {\n" +
					"	exports p;\n" +
					"}\n");

			createFolder("pj2/src/q");
			createFile("pj2/src/q/API.java",
					"package q;\n" +
					"public class API extends p.Missing {}\n");
			createFile("pj2/src/q/API2.java",
					"package q;\n" +
					"public class API2 extends API {}\n");
			createFile("pj2/src/module-info.java",
					"module pj2 {\n" +
					"	requires pj1;\n" +
					"	exports q;\n" +
					"}\n");
			getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);

			deleteFile("pj1/bin/p/Missing.class");
			pj1.getProject().close(null);

			createFolder("ptest/src/p/r");
			createFile("ptest/src/p/r/P.java", "package p.r;\n public class P {}\n");
			createFolder("ptest/src/t");
			createFile("ptest/src/t/Test1.java",
					"package t;\n" +
					"import q.API2;\n" +
					"public class Test1 {\n" +
					"	void m(API2 a) {\n" +
					"		a.miss();\n" +
					"	}\n" +
					"}\n");
			String test2Path = "ptest/src/t/Test2.java";
			String test2Content =
					"package t;\n" +
					"import p.Missing;\n" +
					"public class Test2 {}\n";
			createFile(test2Path, test2Content);
			ptest.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			IMarker[] markers = ptest.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("unexpected markers",
					"The import p.Missing cannot be resolved\n" + 
					"The method miss() is undefined for the type API2",
					markers);

			this.problemRequestor.initialize(test2Content.toCharArray());
			getCompilationUnit(test2Path).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"1. ERROR in /ptest/src/t/Test2.java (at line 2)\n" + 
					"	import p.Missing;\n" + 
					"	       ^^^^^^^^^\n" + 
					"The import p.Missing cannot be resolved\n" +
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject(pj1);
			deleteProject(pj2);
			deleteProject(ptest);
		}
	}

	public void testBug543701() throws Exception {
		IJavaProject p = createJava9Project("p");
		String outputDirectory = Util.getOutputDirectory();
		try {
			String jar1Path = outputDirectory + File.separator + "lib1.jar";
			Util.createJar(new String[] {
						"javax/xml/transform/Result.java",
						"package javax.xml.transform;\n" +
						"public class Result {}\n"
					}, new HashMap<>(), jar1Path);

			String jar2Path = outputDirectory + File.separator + "lib2.jar";
			Util.createJar(new String[] {
						"p2/C2.java",
						"package p2;\n" +
						"import javax.xml.transform.Result;\n" +
						"public class C2 {\n" +
						"	public void m(Number n) {}\n" +
						"	public void m(Result r) {}\n" + // Result will be ambiguous looking from project 'p', but should not break compilation 
						"}\n"
					}, new HashMap<>(), jar2Path);

			addLibraryEntry(p, jar1Path, false);
			addLibraryEntry(p, jar2Path, false);

			createFolder("p/src/pp");
			String testPath = "p/src/pp/Test.java";
			String testSource =
					"package pp;\n" +
					"import p2.C2;\n" +
					"public class Test {\n" +
					"	void test(C2 c2) {\n" +
					"		c2.m(Integer.valueOf(1));\n" +
					"	}\n" +
					"}\n";
			createFile(testPath, testSource);

			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.initialize(testSource.toCharArray());
			getCompilationUnit(testPath).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject(p);
			// clean up output dir
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}

	public void testBug543441() throws Exception {
		// unsuccessful attempt at triggering NPE on null required module
		IJavaProject p = createJava9Project("p");
		String outputDirectory = Util.getOutputDirectory();
		try {
			String jar1Path = outputDirectory + File.separator + "lib1.jar";
			Util.createJar(new String[] {
						"module-info.java",
						"module lib1 {}\n"
					}, jar1Path, "9");

			String jar2Path = outputDirectory + File.separator + "lib2.jar";
			Util.createJar(new String[] {
						"module-info.java",
						"module lib2 {\n" +
						"	requires lib1;\n" + // will be messing when seen from project 'p'
						"	exports p2;\n" +
						"}\n",
						"p2/C2.java",
						"package p2;\n" +
						"public class C2 {}\n"
					},
					null, jar2Path, new String[] { jar1Path }, "9");

			File jar1File = new File(jar1Path);
			jar1File.delete();

			addModularLibraryEntry(p, new Path(jar2Path), null);
			createFile("p/src/module-info.java",
					"module p {\n" +
					"	requires transitive lib2;\n" + // not lib1
					"}\n");
			createFolder("p/src/pkg");
			createFile("p/src/pkg/Test.java",
					"package pkg;\n" +
					"import p2.C2;\n" +
					"public class Test {\n" +
					"	void test(C2 c) {}\n" +
					"}\n");

			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			assertNoErrors();

		} finally {
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	
	public void testBug543765() throws CoreException, IOException {
		// failure never seen in this test
		IJavaProject m = createJava9Project("M");
		IJavaProject n = createJava9Project("N");
		IJavaProject x = createJava9Project("X");
		IJavaProject y = createJava9Project("Y");
		String outputDirectory = Util.getOutputDirectory();
		try {
			// ------ W ------
			String wJarLocation = outputDirectory + File.separator + "w-0.0.1-SNAPSHOT.jar";
			IPath wJarPath = new Path(wJarLocation);
			Util.createJar(new String[] {
						"external/W.java",
						"public class W {\n" +
						"	public static void main(String... args) {}\n" +
						"}\n"
					}, wJarLocation, "9");
			
			// ------ X ------
			addModularLibraryEntry(x, wJarPath, null);
			createFolder("X/src/com/example/x");
			createFile("X/src/com/example/x/X.java",
					"package com.example.x;\n" + 
					"public class X {\n" + 
					"    public static void main(String[] args) { \n" + 
					"        System.out.println(\"X\");\n" + 
					"    }\n" + 
					"}\n");
			createFile("X/src/module-info.java",
					"open module com.example.x {\n" + 
					"    exports com.example.x;\n" + 
					"    requires w;\n" + 
					"}\n");
			
			// ------ Y ------
			addModularLibraryEntry(y, wJarPath, null);
			addModularProjectEntry(y, x);
			createFolder("Y/src/com/example/y");
			createFile("Y/src/com/example/y/Y.java",
					"package com.example.y;\n" + 
					"public class Y {\n" + 
					"    public static void main(String[] args) { \n" + 
					"        System.out.println(\"Y\");\n" + 
					"    }\n" + 
					"}\n");
			createFile("Y/src/module-info.java",
					"open module com.example.y {\n" + 
					"    exports com.example.y;\n" + 
					"    requires com.example.x;\n" + 
					"}\n");

			// ------ N ------
			createFolder("N/src/com/example/n");
			createFile("N/src/com/example/n/N.java",
					"package com.example.n;\n" + 
					"public class N {\n" + 
					"    public static void main(String[] args) { \n" + 
					"        System.out.println(\"N\");\n" + 
					"    } \n" + 
					"}\n");
			createFile("N/src/module-info.java",
					"open module n {\n" + 
					"    exports com.example.n;\n" + 
					"}\n");

			// ------ M ------
			// insert new entries before JRE:
			IClasspathEntry[] entries = m.getRawClasspath();
			int length = entries.length;
			System.arraycopy(entries, 0, entries = new IClasspathEntry[length + 4], 4, length);
			entries[0] = entries[4];
			entries[1] = newModularLibraryEntry(wJarPath, null, null);
			entries[2] = newModularProjectEntry(n);
			entries[3] = newModularProjectEntry(x);
			entries[4] = newModularProjectEntry(y);
			m.setRawClasspath(entries, null);

			createFolder("M/src/m");
			String mSource =
					"package m;\n" + 
					"import com.example.n.N;\n" + 
					"public class M {\n" + 
					"    public static void main(String[] args) {\n" + 
					"        System.out.println(\"M\");\n" + 
					"        N.main(null);\n" + 
					"    }\n" + 
					"}\n";
			String mPath = "M/src/m/M.java";
			createFile(mPath, mSource);
			createFile("M/src/module-info.java",
					"open module m {\n" + 
					"    requires n;\n" + 
					"    requires w;\n" + 
					"}\n");
			
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();
			
			m.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.initialize(mSource.toCharArray());
			getCompilationUnit(mPath).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject(m);
			deleteProject(n);
			deleteProject(x);
			deleteProject(y);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}

	public void testBug544126() throws CoreException, IOException {
		String outputDirectory = Util.getOutputDirectory();
		IJavaProject p = createJava9Project("p");
		try {
			String jar1Path = outputDirectory + File.separator + "auto1Lib.jar";
			createJar(
					new String[] {
						"org/test/Root.java",
						"package org.test;\n" +
						"public class Root {}\n"
					},
					jar1Path);
			String jar2Path = outputDirectory + File.separator + "auto2Lib.jar";
			createJar(
					new String[] {
						"org/test/ext/Ext.java",
						"package org.test.ext;\n" +
						"public class Ext {}\n"
					},
					jar2Path);
			addModularLibraryEntry(p, new Path(jar1Path), null);
			addModularLibraryEntry(p, new Path(jar2Path), null);
			createFolder("p/src/test");
			String testPath = "p/src/test/Test.java";
			String testSource =
					"package test;\n" +
					"import org.test.Root;\n" + 
					"public class Test {\n" + 
					"    public static void main(String[] args) { \n" + 
					"        System.out.println(new Root());\n" + 
					"    }\n" + 
					"}\n";
			createFile(testPath, testSource);
			createFile("p/src/module-info.java",
					"module test {\n" + 
					"    requires auto1Lib;\n" + 
					"    requires auto2Lib;\n" + 
					"}\n");
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.initialize(testSource.toCharArray());
			getCompilationUnit(testPath).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	
	public void testBug544432() throws CoreException {
		IJavaProject prjA = createJava9Project("A");
		IJavaProject prjB = createJava9Project("B");
		try {
			createFolder("A/src/com/a");
			createFile("A/src/com/a/A.java",
				"package com.a;\n" + 
				"\n" + 
				"public class A {}\n");
			createFile("A/src/module-info.java",
				"open module com.a {\n" + 
				"	exports com.a;\n" + 
				"}\n");

			addModularProjectEntry(prjB, prjA);
			createFolder("B/src/com/a/b");
			String bPath = "B/src/com/a/b/B.java";
			String bSource =
				"package com.a.b;\n" + 
				"import com.a.A;\n" + 
				"public class B {\n" + 
				"	\n" + 
				"	public static void main(String[] args) {\n" + 
				"		A a = new A();\n" + 
				"		System.out.println(a);\n" + 
				"	}\n" + 
				"}\n";
			createFile(bPath, bSource);
			createFile("B/src/module-info.java",
				"open module com.a.b {\n" + 
				"	requires com.a;\n" + 
				"}\n");
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.initialize(bSource.toCharArray());
			getCompilationUnit(bPath).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			deleteProject(prjA);
			deleteProject(prjB);
		}
	}

	public void testReleaseOption1() throws Exception {
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "public class X {\n" +
								"}";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption2() throws Exception {
		if (!isJRE12)
			return;
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "public class X {\n" +
								"	public java.util.stream.Stream<String> emptyStream() {\n" +
								"		return null;\n" +
								"	}\n" +
								"}";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"The project was not built due to \"release 6 is not found in the system\". "
					+ "Fix the problem, then try refreshing this project and building it since it may be inconsistent",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption3() throws Exception {
		if (isJRE12)
			return;
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "public class X {\n" +
								"	public java.util.stream.Stream<String> emptyStream() {\n" +
								"		return null;\n" +
								"	}\n" +
								"}";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"java.util.stream.Stream cannot be resolved to a type",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption4() throws Exception {
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "public class X {\n" +
								"	public java.util.stream.Stream<String> emptyStream() {\n" +
								"		return null;\n" +
								"	}\n" +
								"}";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption5() throws Exception {
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "public class X {\n" +
								"	public java.util.stream.Stream<String> emptyStream() {\n" +
								"		return null;\n" +
								"	}\n" +
								"}";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"java.util.stream.Stream cannot be resolved to a type",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption6() throws Exception {
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "interface I {\n" +
								"  int add(int x, int y);\n" +
								"}\n" +
								"public class X {\n" +
								"  public static void main(String[] args) {\n" +
								"    I i = (x, y) -> {\n" +
								"      return x + y;\n" +
								"    };\n" +
								"  }\n" +
								"}\n";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"Lambda expressions are allowed only at source level 1.8 or above",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption7() throws Exception {
		if (isJRE12)
			return;
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "import java.io.*;\n" +
								"public class X {\n" + 
								"	public static void main(String[] args) {\n" + 
								"		try {\n" + 
								"			System.out.println();\n" + 
								"			Reader r = new FileReader(args[0]);\n" + 
								"			r.read();\n" + 
								"		} catch(IOException | FileNotFoundException e) {\n" +
								"			e.printStackTrace();\n" + 
								"		}\n" + 
								"	}\n" + 
								"}";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			assertMarkers("Unexpected markers",
							"Multi-catch parameters are not allowed for source level below 1.7\n" + 
							"The exception FileNotFoundException is already caught by the alternative IOException",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption8() throws Exception {
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_9);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_9);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_9);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "module mod.one { \n" +
								"	requires java.base;\n" +
								"}";
			String mPath = "p/src/module-info.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption9() throws Exception {
		if (!isJRE10) return;
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_10);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_10);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_10);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "module mod.one { \n" +
								"	requires java.base;\n" +
								"}";
			String mPath = "p/src/module-info.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption10() throws Exception {
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "module mod.one { \n" +
					"	requires java.base;\n" +
					"}";
			String mPath = "p/src/module-info.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			sortMarkers(markers);
			String expected =
					"Syntax error on token \"module\", package expected\n" + 
					"Syntax error on token(s), misplaced construct(s)\n" + 
					"Syntax error on token \".\", , expected\n" + 
					"Syntax error on token \"}\", delete this token";
			assertMarkers("Unexpected markers",
							expected,  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption11() throws Exception {
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			createFolder("p/src/foo");
			createFile(
					"p/src/foo/Module.java",
					"package foo;\n" +
					"public class Module {}\n");
			createFile(
					"p/src/foo/X.java",
					"package foo;\n" +
					"public class X { \n" +
					"	public Module getModule(String name) {\n" + 
					"		return null;\n" +
					"	}\n" + 
					"}");
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption12() throws Exception {
		if (!isJRE12)
			return;
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "import java.io.*;\n" + 
								"\n" + 
								"public class X {\n" + 
								"	public static void main(String[] args) {\n" + 
								"		String str = Integer.toUnsignedString(1, 1);\n" + 
								"	}\n" + 
								"}";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"The method toUnsignedString(int, int) is undefined for the type Integer",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testReleaseOption13() throws Exception {
		if (!isJRE12)
			return;
		Hashtable<String, String> options = JavaCore.getOptions();
		IJavaProject p = createJava9Project("p");
		p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
		p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
		String outputDirectory = Util.getOutputDirectory();
		try {
			String testSource = "\n" + 
								"public class X {\n" + 
								"	public static void main(String[] args) {\n" + 
								"		Integer.toUnsignedString(1, 1);\n" + 
								"	}\n" + 
								"}";
			String mPath = "p/src/X.java";
			createFile(mPath,
					testSource);
			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			assertMarkers("Unexpected markers",
					"",  markers);

		} finally {
			JavaCore.setOptions(options);
			deleteProject(p);
			File outputDir = new File(outputDirectory);
			if (outputDir.exists())
				Util.flushDirectoryContent(outputDir);
		}
	}
	public void testBug547114a() throws CoreException, IOException {
		String outputDirectory = Util.getOutputDirectory();
		String jarPath = outputDirectory + File.separator + "lib.jar";
		try {
			// focus project has no module-info, to trigger path where LE#knownPackages is not empty when processing add-reads
			String[] sources = new String[] {
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"import p.C;\n" +
					"public class World {\n" +
					"	C f;\n" +
					"}\n"
			};
			IJavaProject p = setupModuleProject("org.astro", sources);

			Util.createJar(new String[] {
					"/lib/src/module-info.java",
					"module lib {\n" +
					"	exports p;\n" +
					"}\n",
					"/lib/src/p/C.java",
					"package p;\n" +
					"public class C {}\n",
				},
				jarPath,
				"9");
			addClasspathEntry(p, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null,
					new IClasspathAttribute[] {
						JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
						JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_READS, "lib=missing.module") // problematic directive on jar-dependency
					},
					false));

			p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
			waitForAutoBuild();
			
			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			// 1. marker is on the project, second on the "current" CU: World.java.
			assertMarkers("Unexpected markers",
					"The project was not built since its build path has a problem: missing.module cannot be resolved to a module, it is referenced from an add-reads directive. Fix the build path then try building this project\n" + 
					"missing.module cannot be resolved to a module, it is referenced from an add-reads directive",
					markers);
		} finally {
			deleteProject("org.astro");
			deleteFile(jarPath);
		}
	}
	public void testBug547114b() throws CoreException, IOException {
		try {
			IJavaProject p = setupModuleProject("org.astro", new String[] {
					"src/module-info.java",
					"module org.astro {\n" +
					"	requires lib;\n" +
					"}\n",
					"src/org/astro/World.java",
					"package org.astro;\n" +
					"import p.C;\n" +
					"public class World {\n" +
					"	C f;\n" +
					"}\n"
			});
			
			IJavaProject lib = setupModuleProject("lib", new String[] {
					"src/module-info.java",
					"module lib {\n" +
					"	exports p;\n" +
					"}\n",
					"src/p/C.java",
					"package p;\n" +
					"public class C {}\n",
			});
			addClasspathEntry(p, JavaCore.newProjectEntry(lib.getPath(), null, false,
					new IClasspathAttribute[] {
						JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
						JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_READS, "lib=missing.module") // problematic directive on project dependency
					},
					false));

			ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			waitForAutoBuild();

			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
			// 1. marker is on the project, second on the "current" CU: World.java.
			assertMarkers("Unexpected markers",
					"The project was not built since its build path has a problem: missing.module cannot be resolved to a module, it is referenced from an add-reads directive. Fix the build path then try building this project\n" + 
					"missing.module cannot be resolved to a module, it is referenced from an add-reads directive",
					markers);
		} finally {
			deleteProject("org.astro");
			deleteProject("lib");
		}
	}
	public void testBug547479() throws CoreException {
		int max = org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE;

		IJavaProject prjA = createJava9Project("A");
		IJavaProject prjB = createJava9Project("B");
		try {
			createFile("A/src/module-info.java",
				"module A {\n" + 
				"}\n");

			addModularProjectEntry(prjB, prjA);
			// prepare files to be compiled in two batches à 2 files:
			org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 2;
			// ---1---
			createFolder("B/src/b");
			createFile("B/src/b/Class1.java",
				"package b;\n" + 
				"import java.sql.Connection;\n" + 
				"public class Class1 {\n" + 
				"	Connection connection;\n" + 
				"}\n");
			createFile("B/src/b/Class2.java",
				"package b;\n" + 
				"import java.sql.Connection;\n" + 
				"public class Class2 {\n" + 
				"	Connection connection;\n" + 
				"}\n");
			// ---2---
			createFile("B/src/module-info.java",
				"module B {\n" + 
				"	requires java.sql;\n" + 
				"	requires A;\n" + 
				"}\n");
			String bPath = "B/src/b/Class3.java";
			String bSource =
				"package b;\n" + // <= this triggered createPackage in an inconsistent state
				"import java.sql.Connection;\n" + 
				"public class Class3 {\n" + 
				"	Connection connection;\n" + 
				"}\n";
			createFile(bPath, bSource);
			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
			assertNoErrors();

			this.problemRequestor.initialize(bSource.toCharArray());
			getCompilationUnit(bPath).getWorkingCopy(this.wcOwner, null);
			assertProblems("unexpected problems",
					"----------\n" + 
					"----------\n",
					this.problemRequestor);
		} finally {
			org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = max;
			deleteProject(prjA);
			deleteProject(prjB);
		}
	}
	protected void assertNoErrors() throws CoreException {
		for (IProject p : getWorkspace().getRoot().getProjects()) {
			int maxSeverity = p.findMaxProblemSeverity(null, true, IResource.DEPTH_INFINITE);
			if (maxSeverity == IMarker.SEVERITY_ERROR) {
				for (IMarker marker : p.findMarkers(null, true, IResource.DEPTH_INFINITE))
					System.err.println("Marker "+ marker.toString());
			}
			assertFalse("Unexpected errors in project " + p.getName(), maxSeverity == IMarker.SEVERITY_ERROR);
		}
	}
	// sort by CHAR_START then MESSAGE
	protected void sortMarkers(IMarker[] markers) {
		Arrays.sort(markers, Comparator.comparingInt((IMarker a) -> a.getAttribute(IMarker.CHAR_START, 0))
									   .thenComparing((IMarker a) -> a.getAttribute(IMarker.MESSAGE, ""))); 
	}
}
