Bug 410207 - Compiler incorrectly reports error message "X cannot be
resolved. It is indirectly referenced from required .class files"

Signed-off-by: Szymon Ptaszkiewicz <szymon.ptaszkiewicz@pl.ibm.com>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java
index a067924..dbb16d6 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -25,6 +25,7 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -5591,4 +5592,226 @@
 		deleteProject(project);
 	}
 }
+/**
+ * Project's compliance: source: 1.5, compiler: 1.5
+ * Jar's compliance: source: 1.3, compiler: 1.3
+ * Jar contains a class with "enum" package and is located inside the project.
+ * The test verifies that class from the "enum" package is not proposed.
+ */
+public void testBug410207a() throws Exception {
+	try {
+		IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5");
+		Util.createJar(new String[] {
+				"a/enum/b/NonCompliant.java",
+				"package a.enum.b;\n" +
+				"public class NonCompliant {\n" +
+				"}",
+				"lib/External.java",
+				"package lib;\n" +
+				"import a.enum.b.NonCompliant;\n" +
+				"public class External {\n" +
+				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
+				"      return null;\n" +
+				"	}\n" +
+				"}"
+			},
+			p.getProject().getLocation().append("lib.jar").toOSString(),
+			"1.3");
+		refresh(p);
+		createFolder("/P/src/p/");
+		createFile(
+				"/P/src/p/Main.java",
+				"package p;\n" +
+				"import lib.External;\n" +
+				"public class Main {\n" +
+				"   public void m() {\n" +
+				"      External external = new External();\n" +
+				"      external.setNonCompliant(new );\n" +
+				"   };\n" +
+				"}"
+		);
+		waitUntilIndexesReady();
+		ICompilationUnit cu = getCompilationUnit("P", "src", "p", "Main.java");
+		String source = cu.getSource();
+		String completeBehind = "external.setNonCompliant(new ";
+		int cursorLocation = source.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true);
+		cu.codeComplete(cursorLocation, requestor);
+		assertResults(
+				"Main[TYPE_REF]{Main, p, Lp.Main;, null, null, 27}",
+				requestor.getResults());
+	} finally {
+		deleteProject("P");
+	}
+}
+/**
+ * Project's compliance: source: 1.5, compiler: 1.5
+ * Jar's compliance: source: 1.4, compiler: 1.6
+ * Jar contains a class with "enum" package and is located inside the project.
+ * The test verifies that class from the "enum" package is not proposed. It verifies also that
+ * compiler compliance of the jar is not used as source compliance.
+ */
+public void testBug410207b() throws Exception {
+	try {
+		IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5");
+		Map options = new HashMap();
+		options.put(CompilerOptions.OPTION_Source, "1.4");
+		Util.createJar(new String[] {
+				"a/enum/b/NonCompliant.java",
+				"package a.enum.b;\n" +
+				"public class NonCompliant {\n" +
+				"}",
+				"lib/External.java",
+				"package lib;\n" +
+				"import a.enum.b.NonCompliant;\n" +
+				"public class External {\n" +
+				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
+				"      return null;\n" +
+				"	}\n" +
+				"}"
+			},
+			null,/*extraPathsAndContents*/
+			p.getProject().getLocation().append("lib.jar").toOSString(),
+			null,/*classpath*/
+			"1.6",
+			options);
+		refresh(p);
+		createFolder("/P/src/p/");
+		createFile(
+				"/P/src/p/Main.java",
+				"package p;\n" +
+				"import lib.External;\n" +
+				"public class Main {\n" +
+				"   public void m() {\n" +
+				"      External external = new External();\n" +
+				"      external.setNonCompliant(new );\n" +
+				"   };\n" +
+				"}"
+		);
+		waitUntilIndexesReady();
+		ICompilationUnit cu = getCompilationUnit("P", "src", "p", "Main.java");
+		String source = cu.getSource();
+		String completeBehind = "external.setNonCompliant(new ";
+		int cursorLocation = source.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true);
+		cu.codeComplete(cursorLocation, requestor);
+		assertResults(
+				"Main[TYPE_REF]{Main, p, Lp.Main;, null, null, 27}",
+				requestor.getResults());
+	} finally {
+		deleteProject("P");
+	}
+}
+/**
+ * Two projects:
+ * 		Lib: source: 1.4, compiler: 1.4
+ * 		P: source: 1.5, compiler: 1.5
+ * Lib contains a class with "enum" package and is required by P (dependency on the bin folder).
+ * The test verifies that class from the "enum" package is not proposed for P.
+ */
+public void testBug410207c() throws Exception {
+	try {
+		createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4");
+		createFolder("/Lib/src/a/enum/b");
+		createFile(
+				"/Lib/src/a/enum/b/NonCompliant.java",
+				"package a.enum.b;\n" +
+				"public class NonCompliant {\n" +
+				"}"
+		);
+		createFolder("/Lib/src/lib");
+		createFile(
+				"/Lib/src/lib/External.java",
+				"package lib;\n" +
+				"import a.enum.b.NonCompliant;\n" +
+				"public class External {\n" +
+				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
+				"      return null;\n" +
+				"	}\n" +
+				"}"
+		);
+		getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null);
+		createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/Lib/bin"}, "bin", "1.5");
+		createFolder("/P/src/p");
+		createFile(
+				"/P/src/p/Main.java",
+				"package p;\n" +
+				"import lib.External;\n" +
+				"public class Main {\n" +
+				"   public void m() {\n" +
+				"      External external = new External();\n" +
+				"      external.setNonCompliant(new );\n" +
+				"   };\n" +
+				"}"
+		);
+		waitUntilIndexesReady();
+		ICompilationUnit cu = getCompilationUnit("P", "src", "p", "Main.java");
+		String source = cu.getSource();
+		String completeBehind = "external.setNonCompliant(new ";
+		int cursorLocation = source.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true);
+		cu.codeComplete(cursorLocation, requestor);
+		assertResults(
+				"Main[TYPE_REF]{Main, p, Lp.Main;, null, null, 27}",
+				requestor.getResults());
+	} finally {
+		deleteProjects(new String[] { "Lib", "P" });
+	}
+}
+/**
+ * Two projects:
+ * 		Lib: source: 1.4, compiler: 1.4
+ * 		P: source: 1.5, compiler: 1.5
+ * Lib contains a class with "enum" package and is required by P (dependency on the whole project).
+ * The test verifies that class from the "enum" package is not proposed for P.
+ */
+public void testBug410207d() throws Exception {
+	try {
+		createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4");
+		createFolder("/Lib/src/a/enum/b");
+		createFile(
+				"/Lib/src/a/enum/b/NonCompliant.java",
+				"package a.enum.b;\n" +
+				"public class NonCompliant {\n" +
+				"}"
+		);
+		createFolder("/Lib/src/lib");
+		createFile(
+				"/Lib/src/lib/External.java",
+				"package lib;\n" +
+				"import a.enum.b.NonCompliant;\n" +
+				"public class External {\n" +
+				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
+				"      return null;\n" +
+				"	}\n" +
+				"}"
+		);
+		getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null);
+		createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, new String[] {"/Lib"}, "bin", "1.5");
+		createFolder("/P/src/p");
+		createFile(
+				"/P/src/p/Main.java",
+				"package p;\n" +
+				"import lib.External;\n" +
+				"public class Main {\n" +
+				"   public void m() {\n" +
+				"      External external = new External();\n" +
+				"      external.setNonCompliant(new );\n" +
+				"   };\n" +
+				"}"
+		);
+		waitUntilIndexesReady();
+		ICompilationUnit cu = getCompilationUnit("P", "src", "p", "Main.java");
+		String source = cu.getSource();
+		String completeBehind = "external.setNonCompliant(new ";
+		int cursorLocation = source.lastIndexOf(completeBehind) + completeBehind.length();
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true);
+		cu.codeComplete(cursorLocation, requestor);
+		assertResults(
+				"Main[TYPE_REF]{Main, p, Lp.Main;, null, null, 27}",
+				requestor.getResults());
+	} finally {
+		deleteProjects(new String[] { "Lib", "P" });
+	}
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
index cc36657..3ed2718 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -13,7 +13,9 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.Map;
 
 import junit.framework.Test;
 
@@ -34,6 +36,7 @@
 import org.eclipse.jdt.core.compiler.ReconcileContext;
 import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.core.CompilationUnit;
 import org.eclipse.jdt.internal.core.JavaModelManager;
 import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
@@ -5298,4 +5301,209 @@
 			deleteProject(project15);
 	}
 }
+/**
+ * Project's compliance: source: 1.5, compiler: 1.5
+ * Jar's compliance: source: 1.3, compiler: 1.3
+ * Jar contains a class with "enum" package and is located inside the project.
+ * The test verifies that class from the "enum" package is correctly reconciled.
+ */
+public void testBug410207a() throws Exception {
+	try {
+		IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5");
+		Util.createJar(new String[] {
+				"a/enum/b/NonCompliant.java",
+				"package a.enum.b;\n" +
+				"public class NonCompliant {\n" +
+				"}",
+				"lib/External.java",
+				"package lib;\n" +
+				"import a.enum.b.NonCompliant;\n" +
+				"public class External {\n" +
+				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
+				"      return null;\n" +
+				"	}\n" +
+				"}"
+			},
+			p.getProject().getLocation().append("lib.jar").toOSString(),
+			"1.3");
+		refresh(p);
+		setUpWorkingCopy(
+				"/P/src/p/Main.java",
+				"package p;\n" +
+				"import lib.External;\n" +
+				"public class Main {\n" +
+				"   public void m() {\n" +
+				"      External external = new External();\n" +
+				"      external.setNonCompliant(null);\n" +
+				"   };\n" +
+				"}"
+		);
+		this.problemRequestor.reset();
+		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
+		assertProblems(
+				"Unexpected problems",
+				"----------\n" +
+				"----------\n"
+		);
+	} finally {
+		deleteProject("P");
+	}
+}
+/**
+ * Project's compliance: source: 1.5, compiler: 1.5
+ * Jar's compliance: source: 1.4, compiler: 1.6
+ * Jar contains a class with "enum" package and is located inside the project.
+ * The test verifies that class from the "enum" package is correctly reconciled.
+ */
+public void testBug410207b() throws Exception {
+	try {
+		IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5");
+		Map options = new HashMap();
+		options.put(CompilerOptions.OPTION_Source, "1.4");
+		Util.createJar(new String[] {
+				"a/enum/b/NonCompliant.java",
+				"package a.enum.b;\n" +
+				"public class NonCompliant {\n" +
+				"}",
+				"lib/External.java",
+				"package lib;\n" +
+				"import a.enum.b.NonCompliant;\n" +
+				"public class External {\n" +
+				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
+				"      return null;\n" +
+				"	}\n" +
+				"}"
+			},
+			null,/*extraPathsAndContents*/
+			p.getProject().getLocation().append("lib.jar").toOSString(),
+			null,/*classpath*/
+			"1.6",
+			options);
+		refresh(p);
+		setUpWorkingCopy(
+				"/P/src/p/Main.java",
+				"package p;\n" +
+				"import lib.External;\n" +
+				"public class Main {\n" +
+				"   public void m() {\n" +
+				"      External external = new External();\n" +
+				"      external.setNonCompliant(null);\n" +
+				"   };\n" +
+				"}"
+		);
+		this.problemRequestor.reset();
+		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
+		assertProblems(
+				"Unexpected problems",
+				"----------\n" +
+				"----------\n"
+		);
+	} finally {
+		deleteProject("P");
+	}
+}
+/**
+ * Two projects:
+ * 		Lib: source: 1.4, compiler: 1.4
+ * 		P: source: 1.5, compiler: 1.5
+ * Lib contains a class with "enum" package and is required by P (dependency on the bin folder).
+ * The test verifies that class from the "enum" package is correctly reconciled for P.
+ */
+public void testBug410207c() throws Exception {
+	try {
+		createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4");
+		createFolder("/Lib/src/a/enum/b");
+		createFile(
+				"/Lib/src/a/enum/b/NonCompliant.java",
+				"package a.enum.b;\n" +
+				"public class NonCompliant {\n" +
+				"}"
+		);
+		createFolder("/Lib/src/lib");
+		createFile(
+				"/Lib/src/lib/External.java",
+				"package lib;\n" +
+				"import a.enum.b.NonCompliant;\n" +
+				"public class External {\n" +
+				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
+				"      return null;\n" +
+				"	}\n" +
+				"}"
+		);
+		getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null);
+		createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/Lib/bin"}, "bin", "1.5");
+		setUpWorkingCopy(
+				"/P/src/p/Main.java",
+				"package p;\n" +
+				"import lib.External;\n" +
+				"public class Main {\n" +
+				"   public void m() {\n" +
+				"      External external = new External();\n" +
+				"      external.setNonCompliant(null);\n" +
+				"   };\n" +
+				"}"
+		);
+		this.problemRequestor.reset();
+		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
+		assertProblems(
+				"Unexpected problems",
+				"----------\n" +
+				"----------\n"
+		);
+	} finally {
+		deleteProjects(new String[] { "Lib", "P" });
+	}
+}
+/**
+ * Two projects:
+ * 		Lib: source: 1.4, compiler: 1.4
+ * 		P: source: 1.5, compiler: 1.5
+ * Lib contains a class with "enum" package and is required by P (dependency on the whole project).
+ * The test verifies that class from the "enum" package is correctly reconciled for P.
+ */
+public void testBug410207d() throws Exception {
+	try {
+		createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4");
+		createFolder("/Lib/src/a/enum/b");
+		createFile(
+				"/Lib/src/a/enum/b/NonCompliant.java",
+				"package a.enum.b;\n" +
+				"public class NonCompliant {\n" +
+				"}"
+		);
+		createFolder("/Lib/src/lib");
+		createFile(
+				"/Lib/src/lib/External.java",
+				"package lib;\n" +
+				"import a.enum.b.NonCompliant;\n" +
+				"public class External {\n" +
+				"   public NonCompliant setNonCompliant(NonCompliant x) {\n" +
+				"      return null;\n" +
+				"	}\n" +
+				"}"
+		);
+		getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null);
+		createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, new String[] {"/Lib"}, "bin", "1.5");
+		setUpWorkingCopy(
+				"/P/src/p/Main.java",
+				"package p;\n" +
+				"import lib.External;\n" +
+				"public class Main {\n" +
+				"   public void m() {\n" +
+				"      External external = new External();\n" +
+				"      external.setNonCompliant(null);\n" +
+				"   };\n" +
+				"}"
+		);
+		this.problemRequestor.reset();
+		this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null);
+		assertProblems(
+				"Unexpected problems",
+				"----------\n" +
+				"----------\n"
+		);
+	} finally {
+		deleteProjects(new String[] { "Lib", "P" });
+	}
+}
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index 8b7c565..61c6fbf 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -26,6 +26,7 @@
 import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.WorkingCopyOwner;
@@ -54,6 +55,7 @@
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 import org.eclipse.jdt.internal.compiler.util.ObjectVector;
@@ -69,6 +71,7 @@
 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
 import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
 import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
 
 /**
  * This class is the entry point for source completions.
@@ -498,8 +501,6 @@
 	private final static int SUPERTYPE = 1;
 	private final static int SUBTYPE = 2;
 	
-	private final static char[] DOT_ENUM = ".enum".toCharArray(); //$NON-NLS-1$
-	
 	int expectedTypesPtr = -1;
 	TypeBinding[] expectedTypes = new TypeBinding[1];
 	int expectedTypesFilter;
@@ -551,6 +552,10 @@
 	int startPosition, actualCompletionPosition, endPosition, offset;
 	int tokenStart, tokenEnd;
 	int javadocTagPosition; // Position of previous tag while completing in javadoc
+	String sourceLevel;
+	String complianceLevel;
+	SimpleSetOfCharArray validPackageNames = new SimpleSetOfCharArray(10);
+	SimpleSetOfCharArray invalidPackageNames = new SimpleSetOfCharArray(1);
 	HashtableOfObject knownPkgs = new HashtableOfObject(10);
 	HashtableOfObject knownTypes = new HashtableOfObject(10);
 	
@@ -657,6 +662,8 @@
 		this.nameEnvironment = nameEnvironment;
 		this.typeCache = new HashtableOfObject(5);
 		this.openedBinaryTypes = 0;
+		this.sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
+		this.complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
 
 		this.problemFactory = new CompletionProblemFactory(Locale.getDefault());
 		this.problemReporter = new ProblemReporter(
@@ -1085,6 +1092,8 @@
 
 		if (this.knownPkgs.containsKey(packageName)) return;
 
+		if (!isValidPackageName(packageName)) return;
+
 		this.knownPkgs.put(packageName, this);
 
 		char[] completion;
@@ -1172,7 +1181,7 @@
 			}
 		}
 		
-		if (isForbiddenType(packageName, simpleTypeName, enclosingTypeNames)) {
+		if (isForbidden(packageName, simpleTypeName, enclosingTypeNames)) {
 			return;
 		}
 
@@ -11959,16 +11968,19 @@
 	private boolean isAllowingLongComputationProposals() {
 		return this.monitor != null;
 	}
-	private boolean isForbidden(Binding binding) {
+	private boolean isForbidden(ReferenceBinding binding) {
 		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
 			if(this.forbbidenBindings[i] == binding) {
 				return true;
 			}
 		}
+		if (!isValidPackageName(binding.qualifiedPackageName())) {
+			return true;
+		}
 		return false;
 	}
 
-	private boolean isForbiddenType(char[] givenPkgName, char[] givenTypeName, char[][] enclosingTypeNames) {
+	private boolean isForbidden(char[] givenPkgName, char[] givenTypeName, char[][] enclosingTypeNames) {
 		// CharOperation.concatWith() handles the cases where input args are null/empty
 		char[] fullTypeName = CharOperation.concatWith(enclosingTypeNames, givenTypeName, '.');
 		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
@@ -11984,11 +11996,8 @@
 			}
 		}
 		
-		// filter packages ending with enum for projects above 1.5 
-		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=317264
-		if (this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5 &&
-				CharOperation.endsWith(givenPkgName, DOT_ENUM)) { //note: it should be .enum and not just enum
-				return true;
+		if (!isValidPackageName(givenPkgName)) {
+			return true;
 		}
 		
 		return false;
@@ -12006,6 +12015,28 @@
 		return this.requestor.isIgnored(kind) ||
 			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
 	}
+
+	private boolean isValidPackageName(char[] packageName) {
+		if (this.validPackageNames.includes(packageName)) {
+			return true;
+		}
+
+		if (this.invalidPackageNames.includes(packageName)) {
+			return false;
+		}
+
+		char[][] names = CharOperation.splitOn('.', packageName);
+		for (int i = 0, length = names.length; i < length; i++) {
+			if (!Util.isValidFolderNameForPackage(new String(names[i]), this.sourceLevel, this.complianceLevel)) {
+				this.invalidPackageNames.add(packageName);
+				return false;
+			}
+		}
+
+		this.validPackageNames.add(packageName);
+		return true;
+	}
+
 	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
 
 		if(parent instanceof ParameterizedSingleTypeReference) {
@@ -12672,6 +12703,8 @@
 	protected void reset() {
 
 		super.reset(false);
+		this.validPackageNames = new SimpleSetOfCharArray(10);
+		this.invalidPackageNames = new SimpleSetOfCharArray(1);
 		this.knownPkgs = new HashtableOfObject(10);
 		this.knownTypes = new HashtableOfObject(10);
 		if (this.noCacheNameEnvironment != null) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
index ca43b54..8fd2f55 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -196,6 +196,9 @@
 		return storedNonJavaResources();
 	}
 }
+protected boolean internalIsValidPackageName() {
+	return true;
+}
 /**
  * Jars and jar entries are all read only
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
index 5b18c19..1127e5c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -21,6 +21,7 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
 import org.eclipse.jdt.internal.core.util.Util;
 
@@ -39,6 +40,11 @@
 	private final static ArrayList EMPTY_LIST = new ArrayList();
 
 	/**
+	 * Compiler compliance level that was used to produce the jar.
+	 */
+	protected final String complianceLevel;
+
+	/**
 	 * The path to the jar file
 	 * (a workspace relative path if the jar is internal,
 	 * or an OS path if the jar is external)
@@ -53,6 +59,9 @@
 	protected JarPackageFragmentRoot(IPath externalJarPath, JavaProject project) {
 		super(null, project);
 		this.jarPath = externalJarPath;
+		Object file = JavaModel.getTarget(getPath(), true);
+		long level = Util.getJdkLevel(file);
+		this.complianceLevel = CompilerOptions.versionFromJdkLevel(level);
 	}
 	/**
 	 * Constructs a package fragment root which is the root of the Java package directory hierarchy
@@ -61,6 +70,9 @@
 	protected JarPackageFragmentRoot(IResource resource, JavaProject project) {
 		super(resource, project);
 		this.jarPath = resource.getFullPath();
+		Object file = JavaModel.getTarget(getPath(), true);
+		long level = Util.getJdkLevel(file);
+		this.complianceLevel = CompilerOptions.versionFromJdkLevel(level);
 	}
 
 	/**
@@ -73,9 +85,6 @@
 		IJavaElement[] children;
 		ZipFile jar = null;
 		try {
-			IJavaProject project = getJavaProject();
-			String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
-			String compliance = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
 			jar = getJar();
 
 			// always create the default package
@@ -83,7 +92,7 @@
 
 			for (Enumeration e= jar.entries(); e.hasMoreElements();) {
 				ZipEntry member= (ZipEntry) e.nextElement();
-				initRawPackageInfo(rawPackageInfo, member.getName(), member.isDirectory(), sourceLevel, compliance);
+				initRawPackageInfo(rawPackageInfo, member.getName(), member.isDirectory());
 			}
 
 			// loop through all of referenced packages, creating package fragments if necessary
@@ -210,7 +219,7 @@
 	public int hashCode() {
 		return this.jarPath.hashCode();
 	}
-	private void initRawPackageInfo(HashtableOfArrayToObject rawPackageInfo, String entryName, boolean isDirectory, String sourceLevel, String compliance) {
+	private void initRawPackageInfo(HashtableOfArrayToObject rawPackageInfo, String entryName, boolean isDirectory) {
 		int lastSeparator = isDirectory ? entryName.length()-1 : entryName.lastIndexOf('/');
 		String[] pkgName = Util.splitOn('/', entryName, 0, lastSeparator);
 		String[] existing = null;
@@ -223,7 +232,9 @@
 		}
 		JavaModelManager manager = JavaModelManager.getJavaModelManager();
 		for (int i = existingLength; i < length; i++) {
-			if (Util.isValidFolderNameForPackage(pkgName[i], sourceLevel, compliance)) {
+			// sourceLevel must be null because we know nothing about it based on a jar file
+			// complianceLevel can be retrieved from a jar file
+			if (Util.isValidFolderNameForPackage(pkgName[i], null, this.complianceLevel)) {
 				System.arraycopy(existing, 0, existing = new String[i+1], 0, i);
 				existing[i] = manager.intern(pkgName[i]);
 				rawPackageInfo.put(existing, new ArrayList[] { EMPTY_LIST, EMPTY_LIST });
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
index 35fb34b..02b6f7a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -57,9 +57,12 @@
 
 	public String[] names;
 
+	private boolean isValidPackageName;
+
 protected PackageFragment(PackageFragmentRoot root, String[] names) {
 	super(root);
 	this.names = names;
+	this.isValidPackageName = internalIsValidPackageName();
 }
 /**
  * @see Openable
@@ -384,14 +387,11 @@
 	}
 	return false;
 }
-/**
- * @see IPackageFragment#isDefaultPackage()
- */
-public boolean isDefaultPackage() {
-	return this.names.length == 0;
-}
-private boolean isValidPackageName() {
-	JavaProject javaProject = (JavaProject) getJavaProject();
+protected boolean internalIsValidPackageName() {
+	// if package fragment refers to folder in another IProject, then
+	// resource().getProject() is different than getJavaProject().getProject()
+	// use the other java project's options to verify the name
+	IJavaProject javaProject = JavaCore.create(resource().getProject());
 	String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
 	String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
 	for (int i = 0, length = this.names.length; i < length; i++) {
@@ -401,6 +401,15 @@
 	return true;
 }
 /**
+ * @see IPackageFragment#isDefaultPackage()
+ */
+public boolean isDefaultPackage() {
+	return this.names.length == 0;
+}
+protected final boolean isValidPackageName() {
+	return this.isValidPackageName;
+}
+/**
  * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
  */
 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index b9f4ce4..d74fe42 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -216,14 +216,18 @@
 		vChildren.add(pkg);
 	}
 	try {
-		JavaProject javaProject = (JavaProject)getJavaProject();
-		JavaModelManager manager = JavaModelManager.getJavaModelManager();
 		IResource[] members = folder.members();
 		boolean hasIncluded = isIncluded;
 		int length = members.length;
-		if (length >0) {
-			String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
-			String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+		if (length > 0) {
+			// if package fragment root refers to folder in another IProject, then
+			// folder.getProject() is different than getJavaProject().getProject()
+			// use the other java project's options to verify the name
+			IJavaProject otherJavaProject = JavaCore.create(folder.getProject());
+			String sourceLevel = otherJavaProject.getOption(JavaCore.COMPILER_SOURCE, true);
+			String complianceLevel = otherJavaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+			JavaProject javaProject = (JavaProject) getJavaProject();
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
 			for (int i = 0; i < length; i++) {
 				IResource member = members[i];
 				String memberName = member.getName();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java
index 22333a8..fc2f3f9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -56,14 +56,18 @@
 static Object[] computeFolderNonJavaResources(IPackageFragmentRoot root, IContainer folder, char[][] inclusionPatterns, char[][] exclusionPatterns) throws JavaModelException {
 	IResource[] nonJavaResources = new IResource[5];
 	int nonJavaResourcesCounter = 0;
-	JavaProject project = (JavaProject) root.getJavaProject();
 	try {
-		IClasspathEntry[] classpath = project.getResolvedClasspath();
 		IResource[] members = folder.members();
 		int length = members.length;
 		if (length > 0) {
-			String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
-			String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+			// if package fragment root refers to folder in another IProject, then
+			// folder.getProject() is different than root.getJavaProject().getProject()
+			// use the other java project's options to verify the name
+			IJavaProject otherJavaProject = JavaCore.create(folder.getProject());
+			String sourceLevel = otherJavaProject.getOption(JavaCore.COMPILER_SOURCE, true);
+			String complianceLevel = otherJavaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+			JavaProject javaProject = (JavaProject) root.getJavaProject();
+			IClasspathEntry[] classpath = javaProject.getResolvedClasspath();
 			nextResource: for (int i = 0; i < length; i++) {
 				IResource member = members[i];
 				switch (member.getType()) {