Bug 547181 - [9][impl] Reconsider representation and lookup of packages
(SplitPackageBinding)

More simplifications:
- MB.getTopLevelPackage already handles the LE package cache, so
directly forward to it from LE.getToplevelPackage
- Reduce places where LE.TheNotFoundPackage is returned and handled
- More usages of PlainPackageBinding
- MB.getVisiblePackage already does addPackage, remove in MB.getPackage

Also adds a fix to make sure that ReconcilerTests9.testBug547113 doesn't
fail pre java 9

Change-Id: Ie28c61b531bc0992f047a634bbd856f9a79c9f62
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests9.java
index 25fff83..4f85147 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests9.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests9.java
@@ -852,6 +852,8 @@
 	}
 }
 public void testBug547113() throws CoreException {
+	if (!isJRE9)
+		return;
 	IJavaProject unnamed = createJava9Project("unnamed");
 	IJavaProject a = createJava9Project("a");
 	IJavaProject b = createJava9Project("b");
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index 18a9dd0..97e45e5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -40,7 +40,7 @@
 	public LookupEnvironment environment;
 	public CompilationUnitDeclaration referenceContext;
 	public char[][] currentPackageName;
-	public PackageBinding fPackage;
+	public PlainPackageBinding fPackage;
 	public ImportBinding[] imports;
 	public int importPtr;
 	public HashtableOfObject typeOrPackageCache; // used in Scope.getTypeOrPackage()
@@ -132,7 +132,7 @@
 			problemReporter().unnamedPackageInNamedModule(module());
 		}
 	} else {
-		if ((this.fPackage = this.environment.createPackage(this.currentPackageName)) == null) {
+		if ((this.fPackage = this.environment.createPlainPackage(this.currentPackageName)) == null) {
 			if (this.referenceContext.currentPackage != null) {
 				problemReporter().packageCollidesWithType(this.referenceContext); // only report when the unit has a package statement
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 7082388..0f3f6d2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -83,7 +83,7 @@
 	public ModuleBinding UnNamedModule;
 	public ModuleBinding JavaBaseModule;
 	public ModuleBinding module;
-	public PackageBinding defaultPackage;
+	public PlainPackageBinding defaultPackage;
 	/** All visible toplevel packages, i.e. observable packages associated with modules read by the current module. */
 	HashtableOfPackage knownPackages;
 	private int lastCompletedUnitIndex = -1; 	// ROOT_ONLY
@@ -1086,6 +1086,9 @@
  * 3. Create the method bindings
  */
 public PackageBinding createPackage(char[][] compoundName) {
+	return createPlainPackage(compoundName);	
+}
+public PlainPackageBinding createPlainPackage(char[][] compoundName) {
 	PackageBinding packageBinding = this.module.getDeclaredPackage(CharOperation.concatWith(compoundName, '.'));
 	if (packageBinding != null && packageBinding.isValidBinding()) {
 		// restart from the toplevel package to proceed with clash analysis below
@@ -1637,22 +1640,17 @@
 * Answer null if the package cannot be found.
 */
 PackageBinding getTopLevelPackage(char[] name) {
+	if (this.useModuleSystem) {
+		return this.module.getTopLevelPackage(name);
+	}
 	PackageBinding packageBinding = getPackage0(name);
 	if (packageBinding != null) {
 		if (packageBinding == TheNotFoundPackage)
 			return null;
 		return packageBinding;
 	}
-	if (this.useModuleSystem) {
-		packageBinding = this.module.getTopLevelPackage(name);
-	} else {
-		if (this.nameEnvironment.isPackage(null, name)) {
-			this.knownPackages.put(name, packageBinding = new PlainPackageBinding(name, this, this.module));
-		}
-	}
-	if (packageBinding != null) {
-		if (packageBinding == TheNotFoundPackage)
-			return null;
+	if (this.nameEnvironment.isPackage(null, name)) {
+		this.knownPackages.put(name, packageBinding = new PlainPackageBinding(name, this, this.module));
 		return packageBinding;
 	}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
index 3fd3111..5b48102 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
@@ -541,7 +541,7 @@
 		// check cache:
 		PackageBinding binding = this.environment.getPackage0(name);
 		if (binding != null)
-			return binding;
+			return binding == LookupEnvironment.TheNotFoundPackage ? null : binding;
 		binding = getVisiblePackage(null, name);
 		// remember:
 		if (binding != null) {
@@ -658,13 +658,13 @@
 		}
 
 		PackageBinding parent = getTopLevelPackage(qualifiedPackageName[0]);
-		if (parent == null || parent == LookupEnvironment.TheNotFoundPackage)
+		if (parent == null)
 			return null;
 
 		// check each sub package
 		for (int i = 1; i < qualifiedPackageName.length; i++) {
 			PackageBinding binding = getVisiblePackage(parent, qualifiedPackageName[i]); 
-			if (binding == null || binding == LookupEnvironment.TheNotFoundPackage) {
+			if (binding == null) {
 				return null;
 			}
 			parent = binding;
@@ -688,12 +688,10 @@
 		}
 		PackageBinding binding = null;
 		PackageBinding parent = getVisiblePackage(parentPackageName);
-		if (parent != null && parent != LookupEnvironment.TheNotFoundPackage) {
+		if (parent != null) {
 			binding = getVisiblePackage(parent, packageName);
 		}
-		if (binding != null)
-			return addPackage(binding, false);
-		return null;
+		return binding;
 	}
 	
 	/**