update jdt.core from I20160128-2000 for 4.6M5
diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
index a1fb1eb..f13a31b2 100644
--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core.tests.compiler;singleton:=true
-Bundle-Version: 3.12.0.qualifier
+Bundle-Version: 3.12.100.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.core.tests.compiler,
diff --git a/org.eclipse.jdt.core.tests.compiler/pom.xml b/org.eclipse.jdt.core.tests.compiler/pom.xml
index 5d9201c..1bfc96a 100644
--- a/org.eclipse.jdt.core.tests.compiler/pom.xml
+++ b/org.eclipse.jdt.core.tests.compiler/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.core.tests.compiler</artifactId>
-  <version>3.12.0-SNAPSHOT</version>
+  <version>3.12.100-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java
index fc702c2..86c44f1 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java
@@ -114,6 +114,15 @@
 				this.LIBS,
 				false /*shouldFlush*/);
 	}
+	void runNegativeTestWithLibs(boolean skipJavac, String[] testFiles, String expectedErrorLog) {
+		runNegativeTest(
+				skipJavac,
+				null,
+				testFiles,
+				expectedErrorLog,
+				this.LIBS,
+				false /*shouldFlush*/);
+	}
 	void runNegativeTestWithExtraLibs(String[] testFiles, String expectedErrorLog, String [] extraLibs) {
 		String [] libraries = new String [(this.LIBS == null ? 0 : this.LIBS.length) + (extraLibs == null ? 0 : extraLibs.length)];
 		if (this.LIBS != null)
@@ -127,6 +136,16 @@
 				false /*shouldFlush*/);
 	}
 	void runNegativeTestWithLibs(boolean shouldFlushOutputDirectory, String[] testFiles, Map customOptions, String expectedErrorLog) {
+		runNegativeTestWithLibs(
+				shouldFlushOutputDirectory,
+				testFiles,
+				customOptions,
+				expectedErrorLog,
+				// runtime options
+			    false);
+	}
+	void runNegativeTestWithLibs(boolean shouldFlushOutputDirectory, String[] testFiles, Map customOptions, 
+			String expectedErrorLog, boolean skipJavaC) {
 		runNegativeTest(
 				shouldFlushOutputDirectory,
 				testFiles,
@@ -134,6 +153,7 @@
 				customOptions,
 				expectedErrorLog,
 				// runtime options
+				skipJavaC ? JavacTestOptions.SKIP :
 			    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
 	}
 //{ObjectTeams: make visible to downstream:
@@ -145,6 +165,9 @@
 //{ObjectTeams: make visible to downstream:
 	protected
 // SH}
+	void runNegativeTestWithLibs(String[] testFiles, Map customOptions, String expectedErrorLog, boolean skipJavac) {
+		runNegativeTestWithLibs(false /* flush output directory */,	testFiles, customOptions, expectedErrorLog, skipJavac);
+	}
 	void runConformTestWithLibs(String[] testFiles, Map customOptions, String expectedCompilerLog) {
 		runConformTestWithLibs(false /* flush output directory */, testFiles, customOptions, expectedCompilerLog);
 	}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 3e9fe2f..45a8889 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -197,6 +197,9 @@
 			if ("1.8.0_40".equals(rawVersion)) {
 				return 1000; // corresponds to JLS maintenance release 2015-02-13
 			}
+			if ("1.8.0_45".equals(rawVersion)) {
+				return 1100; // corresponds to JLS maintenance release 2015-02-13
+			}
 			if ("1.8.0_60".equals(rawVersion)) {
 				return 1500;
 			}
@@ -358,7 +361,7 @@
 			EclipseWarningConfiguredAsError = RUN_JAVAC ?
 				new Excuse(MismatchType.EclipseErrorsJavacWarnings | MismatchType.EclipseErrorsJavacNone) : null,
 			JavacCompilesBogusReferencedFileAgain = RUN_JAVAC ?
-				new Excuse(MismatchType.JavacErrorsEclipseNone) : null,
+				new Excuse(MismatchType.EclipseErrorsJavacNone) : null,
 				// bugs not found on javac bug site, but points to a javac bug.
 			JavacDoesNotCompileCorrectSource = RUN_JAVAC ?
 				new JavacHasABug(MismatchType.JavacErrorsEclipseNone) : null,
@@ -370,7 +373,11 @@
 			JavacGeneratesIncorrectCode = RUN_JAVAC ?
 					new JavacHasABug(MismatchType.StandardOutputMismatch) : null,
 			JavacHasWarningsEclipseNotConfigured = RUN_JAVAC ?
-					new JavacHasABug(MismatchType.JavacWarningsEclipseNone) : null;
+					new JavacHasABug(MismatchType.JavacWarningsEclipseNone) : null,
+			JavacHasErrorsEclipseHasWarnings = RUN_JAVAC ?
+					new JavacHasABug(MismatchType.JavacErrorsEclipseWarnings) : null,
+			JavacHasErrorsEclipseHasNone = RUN_JAVAC ?
+					new JavacHasABug(MismatchType.JavacErrorsEclipseNone) : null;
 	}
 	Excuse excuseFor(JavacCompiler compiler) {
 		return null;
@@ -420,12 +427,6 @@
 						return compiler.compliance > ClassFileConstants.JDK1_6 ? this : null;
 					}
 				}: null,
-			EclipseBug236370 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=236370
-				new EclipseHasABug(MismatchType.EclipseErrorsJavacNone) {
-					Excuse excuseFor(JavacCompiler compiler) {
-						return compiler.compliance > ClassFileConstants.JDK1_6 ? this : null;
-					}
-				}: null,
 			EclipseBug236379 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=236379
 				new EclipseHasABug(MismatchType.EclipseWarningsJavacNone) {
 					Excuse excuseFor(JavacCompiler compiler) {
@@ -436,8 +437,6 @@
 				new EclipseHasABug(MismatchType.JavacErrorsEclipseNone) : null,
 			EclipseBug427719 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=427719
 				new EclipseHasABug(MismatchType.JavacErrorsEclipseWarnings) : null,
-			EclipseBug427745 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=427745
-				new EclipseHasABug(MismatchType.StandardOutputMismatch) : null,
 			EclipseBug421922 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=421922
 						new EclipseHasABug(MismatchType.EclipseErrorsJavacNone) : null,
 			EclipseBug428061 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428061
@@ -456,8 +455,6 @@
 			super(mismatchType);
 		}
 		public static final EclipseJustification
-			EclipseBug40839 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=40839
-				new EclipseJustification(MismatchType.JavacWarningsEclipseNone) : null,
 			EclipseBug72704 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=72704
 				new EclipseJustification(MismatchType.EclipseErrorsJavacNone) : null,
 			EclipseBug83902 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=83902
@@ -508,16 +505,6 @@
 				} : null,
 			EclipseBug180789 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789
 				new EclipseJustification(MismatchType.EclipseErrorsJavacWarnings) : null,
-			EclipseBug183211 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=183211
-				new EclipseJustification(MismatchType.JavacErrorsEclipseNone | MismatchType.EclipseErrorsJavacNone) : null,
-			EclipseBug183211b = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=183211
-				new EclipseJustification(MismatchType.EclipseErrorsJavacNone) {
-					Excuse excuseFor(JavacCompiler compiler) {
-						return compiler.compliance > ClassFileConstants.JDK1_5 ? this : null;
-					}
-				} : null,
-			EclipseBug185422 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=185422
-				new EclipseJustification(MismatchType.JavacErrorsEclipseNone) : null,
 			EclipseBug218677 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=218677
 				new EclipseJustification(MismatchType.EclipseErrorsJavacNone) {
 					Excuse excuseFor(JavacCompiler compiler) {
@@ -1451,24 +1438,46 @@
 		Map customOptions,
 		ICompilerRequestor clientRequestor,
 		boolean skipJavac) {
-		runTest(
-			shouldFlushOutputDirectory,
-			testFiles,
-			classLib,
-			customOptions,
-			false /* do not perform statements recovery */,
-			clientRequestor,
-			false,
-			null,
-			false,
-			vmArguments,
-			expectedSuccessOutputString,
-			null,
-			(skipJavac ?
-					JavacTestOptions.SKIP :
-					JavacTestOptions.DEFAULT));
+		runConformTest(
+				testFiles, 
+				expectedSuccessOutputString, 
+				classLib, 
+				shouldFlushOutputDirectory, 
+				vmArguments, 
+				customOptions, 
+				clientRequestor, 
+				skipJavac, 
+				(skipJavac ?
+						JavacTestOptions.SKIP :
+						JavacTestOptions.DEFAULT));
 	}
 
+	protected void runConformTest(
+			String[] testFiles,
+			String expectedSuccessOutputString,
+			String[] classLib,
+			boolean shouldFlushOutputDirectory,
+			String[] vmArguments,
+			Map customOptions,
+			ICompilerRequestor clientRequestor,
+			boolean skipJavac,
+			JavacTestOptions javacTestOptions) {
+			runTest(
+				shouldFlushOutputDirectory,
+				testFiles,
+				classLib,
+				customOptions,
+				false /* do not perform statements recovery */,
+				clientRequestor,
+				false,
+				null,
+				false,
+				vmArguments,
+				expectedSuccessOutputString,
+				null,
+				javacTestOptions);
+		}
+
 	/*
 	 * Run Sun compilation using javac.
 	 * Launch compilation in a thread and verify that it does not take more than 5s
@@ -2150,6 +2159,18 @@
 			boolean shouldFlushOutputDirectory,
 			Map customOptions,
 			String expectedErrorString) {
+			runNegativeTest(testFiles, expectedCompilerLog, classLibraries, 
+					shouldFlushOutputDirectory, customOptions, expectedErrorString, 
+					JavacTestOptions.DEFAULT);
+		}
+	protected void runNegativeTest(
+			String[] testFiles,
+			String expectedCompilerLog,
+			String[] classLibraries,
+			boolean shouldFlushOutputDirectory,
+			Map customOptions,
+			String expectedErrorString,
+			JavacTestOptions javacTestOptions) {
 			runTest(
 		 		// test directory preparation
 				shouldFlushOutputDirectory /* should flush output directory */,
@@ -2174,7 +2195,7 @@
 				null /* do not check output string */,
 				expectedErrorString /* do not check error string */,
 				// javac options
-				JavacTestOptions.DEFAULT /* default javac test options */);
+				javacTestOptions /* default javac test options */);
 		}
 	protected void runNegativeTest(
 		String[] testFiles,
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java
index fe3d00e..be896d9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2014 IBM Corporation and others.
+ * Copyright (c) 2005, 2016 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
@@ -241,6 +241,38 @@
 		"	                   ^\n" +
 		"The blank final field o may not have been initialized\n" +
 		"----------\n" +
+		(this.complianceLevel >= ClassFileConstants.JDK1_7 ?
+		"4. ERROR in X.java (at line 35)\n" +
+		"	System.out.println(this.o); // legal\n" +
+		"	                        ^\n" +
+		"The blank final field o may not have been initialized\n" +
+		"----------\n" +
+		"5. WARNING in X.java (at line 42)\n" +
+		"	private final Object o;\n" +
+		"	                     ^\n" +
+		"The value of the field X.Test5.o is not used\n" +
+		"----------\n" +
+		"6. ERROR in X.java (at line 44)\n" +
+		"	Test5() {\n" +
+		"	^^^^^^^\n" +
+		"The blank final field o may not have been initialized\n" +
+		"----------\n" +
+		"7. ERROR in X.java (at line 46)\n" +
+		"	other.o = new Object(); // illegal!  other.o is not assignable\n" +
+		"	      ^\n" +
+		"The final field X.Test5.o cannot be assigned\n" +
+		"----------\n" +
+		"8. WARNING in X.java (at line 52)\n" +
+		"	private final Object o;\n" +
+		"	                     ^\n" +
+		"The value of the field X.Test6.o is not used\n" +
+		"----------\n" +
+		"9. ERROR in X.java (at line 59)\n" +
+		"	other.o = new Object(); // illegal!  other.o is not assignable\n" +
+		"	      ^\n" +
+		"The final field X.Test6.o cannot be assigned\n" +
+		"----------\n"
+		:
 		"4. WARNING in X.java (at line 42)\n" +
 		"	private final Object o;\n" +
 		"	                     ^\n" +
@@ -265,7 +297,7 @@
 		"	other.o = new Object(); // illegal!  other.o is not assignable\n" +
 		"	      ^\n" +
 		"The final field X.Test6.o cannot be assigned\n" +
-		"----------\n");
+		"----------\n"));
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=190391
 public void test005() {
@@ -2027,6 +2059,45 @@
 			"Type mismatch: cannot convert from char to Integer\n" + 
 			"----------\n");
 }
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=480989
+public void testbug480989() {
+	String src = 
+			"public abstract class Unassigned {\n" + 
+			"    public Unassigned() {}\n" + 
+			"    static class SubClass extends Unassigned {\n" + 
+			"        private final String test;\n" + 
+			"        public SubClass(String atest) { // rename\n" + 
+			"            System.out.println(this.test);\n" + 
+			"            this.test = atest;\n" + 
+			"            System.out.println(this.test);\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"    public static void main(String[] args) {\n" + 
+			"        new SubClass(\"Hello World!\");\n" + 
+			"    }\n" + 
+			"}\n";
+	if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
+		this.runNegativeTest(
+			new String[] {
+				"Unassigned.java",
+				src
+			},
+			"----------\n" + 
+			"1. ERROR in Unassigned.java (at line 6)\n" + 
+			"	System.out.println(this.test);\n" + 
+			"	                        ^^^^\n" + 
+			"The blank final field test may not have been initialized\n" + 
+			"----------\n");
+	} else {
+		this.runConformTest(
+			new String[] {
+				"Unassigned.java",
+				src 
+			},
+			"null\n" +
+			"Hello World!");
+	}
+}
 public static Class testClass() {
 	return AssignmentTest.class;
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AutoBoxingTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AutoBoxingTest.java
index 2ebb3a3..62bb53e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AutoBoxingTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AutoBoxingTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2014 IBM Corporation and others.
+ * Copyright (c) 2005, 2016 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
@@ -3148,6 +3148,8 @@
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=95868
 	public void test104() {
 		this.runConformTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.JavacGeneratesIncorrectCode,
 			new String[] {
 				"X.java",
 				"import java.util.HashMap;\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated18Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated18Test.java
index feb68fe..b34ecd5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated18Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated18Test.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014 IBM Corporation and others.
+ * Copyright (c) 2014, 2016 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
@@ -28,6 +28,8 @@
 	Map options = getCompilerOptions();
 	options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.ERROR);
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
 		new String[] {
 			"X.java",
 			"public class X {\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DeprecatedTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DeprecatedTest.java
index 93699b8..f59d3c3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DeprecatedTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DeprecatedTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -244,7 +244,7 @@
 			"0" /* expected output string */,
 			"" /* expected error string */,
 			// javac options
-			JavacTestOptions.EclipseJustification.EclipseBug40839 /* javac test options */);
+			JavacTestOptions.DEFAULT /* javac test options */);
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=88124
 public void test007() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java
index 28ccc49..4ef1ac4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java
@@ -5253,7 +5253,7 @@
 		"null" /* expected output string */,
 		"" /* expected error string */,
 		// javac options
-		JavacTestOptions.Excuse.JavacCompilesBogusReferencedFileAgain /* javac test options */);
+		JavacTestOptions.Excuse.JavacHasErrorsEclipseHasNone /* javac test options */); // note that Eclipse has errors for X while javac alsore reports for X - no conflict
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=227502 - variation
 public void test148() {
@@ -5302,7 +5302,7 @@
 		"null" /* expected output string */,
 		"" /* expected error string */,
 		// javac options
-		JavacTestOptions.Excuse.JavacCompilesBogusReferencedFileAgain /* javac test options */);
+		JavacTestOptions.Excuse.JavacHasErrorsEclipseHasNone /* javac test options */);// see prev note
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=227502 - variation
 public void test149() throws Exception {
@@ -6636,7 +6636,7 @@
 		"",
 		"class test180.Test",
 		"",
-		null);
+		JavacTestOptions.Excuse.JavacHasErrorsEclipseHasNone);
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=289892
 // in interaction with null annotations
@@ -6696,7 +6696,7 @@
 		"",
 		"class test180.Test",
 		"",
-		null);
+		JavacTestOptions.Excuse.JavacHasErrorsEclipseHasNone);
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=300133
 public void test181() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java
index 5907976..c0763a3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExpressionContextTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2014 IBM Corporation and others.
+ * Copyright (c) 2013, 2016 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
@@ -263,6 +263,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399773, [1.8][compiler] Cast expression should allow for additional bounds to form intersection types
 public void test009() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 				"X.java",
 				"import java.util.List;\n" +
@@ -503,6 +505,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399778, [1.8][compiler] Conditional operator expressions should propagate target types
 public void test018() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 				"X.java",
 				"interface I {\n" +
@@ -525,6 +529,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=399778, [1.8][compiler] Conditional operator expressions should propagate target types
 public void test019() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 				"X.java",
 				"interface I {\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest8.java
index 1961639..a26c85a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest8.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2014 GK Software AG and others.
+ * Copyright (c) 2013, 2016 GK Software AG 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
@@ -67,7 +67,8 @@
 		"	ISAM printer = (p,o) -> p.concat(o.toString());\n" + 
 		"	                                 ^\n" + 
 		"Potential null pointer access: this expression has a '@Nullable' type\n" + 
-		"----------\n");
+		"----------\n",
+		true /* skipJavac */);
 }
 
 // Lambda with declared args violates null contract of super
@@ -100,7 +101,8 @@
 		"	ISAM printer = (@NonNull  Object o1, @NonNull 	Object o2, @NonNull	 Object o3) -> System.out.println(2);\n" + 
 		"	                                              	           ^^^^^^^^^^^^^^^^\n" + 
 		"Illegal redefinition of parameter o3, inherited method from ISAM does not constrain this parameter\n" + 
-		"----------\n");
+		"----------\n",
+		true /* skipJavac */);
 }
 
 // Lambda with declared args inherits / modifies contract of super
@@ -147,7 +149,8 @@
 		"	-> System.out.println(o1.toString()+o2.toString()+o3.toString());\n" + 
 		"	                                                  ^^\n" + 
 		"Potential null pointer access: this expression has a '@Nullable' type\n" + 
-		"----------\n");
+		"----------\n",
+		true /* skipJavac */);
 }
 
 // Lambda with declared args has illegal @NonNull an primitive argument
@@ -174,7 +177,8 @@
 		"	ISAM printer1 = (@NonNull int i) \n" + 
 		"	                 ^^^^^^^^\n" + 
 		"The nullness annotation @NonNull is not applicable for the primitive type int\n" + 
-		"----------\n");
+		"----------\n", 
+		true /* skipJavac */);
 }
 
 // Lambda inherits null contract and has block with return statement 
@@ -203,7 +207,8 @@
 		"	return null; // error\n" + 
 		"	       ^^^^\n" + 
 		"Null type mismatch: required \'@NonNull String\' but the provided value is null\n" + 
-		"----------\n");
+		"----------\n",
+		true /* skipJavac */);
 }
 // Lambda has no descriptor (overriding method from Object), don't bail out with NPE during analysis
 public void testLambda_05a() {
@@ -231,7 +236,8 @@
 		"	ISAM printer = () -> {\n" +
 		"	               ^^^^^\n" +
 		"The target type of this expression must be a functional interface\n" +
-		"----------\n");
+		"----------\n",
+		true /* skipJavac */);
 }
 // Test flows with ReferenceExpression regarding: 
 // - definite assignment
@@ -288,6 +294,8 @@
 	Map options = getCompilerOptions();
 	options.put(JavaCore.COMPILER_PB_NULL_REFERENCE, JavaCore.ERROR);
 	runNegativeTest(
+		false /*skipJavac */,
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
 		new String[] {
 			 "I.java",
 			 "public interface I {\n" +
@@ -343,6 +351,7 @@
 }
 public void testReferenceExpression_nullAnnotation_2() {
 	runNegativeTestWithLibs(
+		true, /* skipJavac */
 		new String[] {
 			 "I.java",
 			 "import org.eclipse.jdt.annotation.*;\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index c54b7fb..acc8216 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -25920,6 +25920,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=101831
 public void test0803() {
 	this.runNegativeTest(
+		false /* skipJavac */,
+		this.complianceLevel < ClassFileConstants.JDK1_8 ? null : JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 		new String[] {
 			"X.java",
 			"import java.util.*;\n" +
@@ -30492,7 +30494,9 @@
 			"}\n",
 		},
 	// javac options
-	JavacTestOptions.JavacHasABug.JavacBugFixed_6_10 /* javac test options */);
+	this.complianceLevel < ClassFileConstants.JDK1_8 ? 
+			(JavacTestOptions) JavacTestOptions.JavacHasABug.JavacBugFixed_6_10 :
+			JavacTestOptions.DEFAULT/* javac test options */);
 }
 // Test case which comes from JDT/UI tests TypeEnvironmentTest.testWildcardAssignements
 public void test0922() {
@@ -34965,7 +34969,7 @@
 			"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
 			"Type mismatch: cannot convert from Closure<capture#10-of ? super J & capture#11-of ? super J> to Closure<String>\n" + 
 			"----------\n",
-		JavacTestOptions.EclipseHasABug.EclipseBug236370);
+		JavacTestOptions.DEFAULT);
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=158531
 public void test1035() {
@@ -43346,6 +43350,8 @@
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=215843 - variation
 public void test1234() {
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.EclipseHasABug.EclipseBug427719,
 		new String[] {
 			"X.java",
 			"public class X { \n" +
@@ -49833,6 +49839,9 @@
 // FIXME javac8 doesn't find the error
 public void test1421() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			this.complianceLevel < ClassFileConstants.JDK1_8 ? 
+			null : JavacTestOptions.Excuse.JavacCompilesIncorrectSource,
 			new String[] {
 				"X.java", //-----------------------------------------------------------------------
 				"public class X {\n" + 
@@ -51312,6 +51321,9 @@
 // FIXME: javac rejects (correctly? how?), see http://mail.openjdk.java.net/pipermail/lambda-spec-experts/2013-December/000443.html
 public void test277643() {
 	this.runNegativeTest(
+		false /* skipJavac */,
+		this.complianceLevel < ClassFileConstants.JDK1_8 ? null :
+		JavacTestOptions.EclipseHasABug.EclipseBug428061,
 		new String[] {
 	    "Test.java",
 	    "public class Test {\n" +
@@ -51408,6 +51420,9 @@
 // FIXME: javac rejects (correctly? how?), see http://mail.openjdk.java.net/pipermail/lambda-spec-experts/2013-December/000443.html
 public void test283306() {
 	this.runNegativeTest(
+		false /* skipJavac */,
+		this.complianceLevel < ClassFileConstants.JDK1_8 ? null :
+		JavacTestOptions.EclipseHasABug.EclipseBug428061,
 		new String[] {
 	    "Test.java",
 	    "public class Test {\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
index 3f85381..588c3a5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -1508,7 +1508,8 @@
 		null,
 		false,
 		compilerOptions15,
-		null);
+		null,
+		JavacTestOptions.Excuse.JavacHasWarningsEclipseNotConfigured);
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962 
 public void test337962() {
@@ -2647,6 +2648,8 @@
 			CompilerOptions.OPTION_ReportUnusedTypeParameter,
 			CompilerOptions.ERROR);
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
 		new String[] {
 			"X.java",
 			"public class X<T> {\n"+
@@ -2798,6 +2801,8 @@
 	          CompilerOptions.ENABLED);
 
 	this.runNegativeTest(
+		false /*skipJavac */,
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
 		 new String[] {
  		"X.java",
          "/***\n" +
@@ -2829,6 +2834,8 @@
         CompilerOptions.DISABLED);
 
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
         new String[] {
      		   "X.java",
                 "/***\n" +
@@ -3148,6 +3155,8 @@
 			"}\n";
 	if (this.complianceLevel < ClassFileConstants.JDK1_8) {
 		runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.EclipseHasABug.EclipseBug428061,
 			new String[] {
 				"Compile.java",
 				compileSrc
@@ -3640,6 +3649,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=427282,  Internal compiler error: java.lang.ArrayIndexOutOfBoundsException: -1 at org.eclipse.jdt.internal.compiler.ClassFile.traverse
 public void test427282() {
 	runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 		new String[] {
 			"X.java",
 			"import java.util.Collection;\n" +
@@ -4445,7 +4456,8 @@
 		"	Optional.fromNullable(entry.getValue()).or(NO_VALUE);\n" + 
 		"	                                        ^^\n" + 
 		"The method or(Optional<? extends capture#2-of ?>) in the type Optional<capture#2-of ?> is not applicable for the arguments (Object)\n" + 
-		"----------\n");
+		"----------\n",
+		JavacTestOptions.Excuse.JavacCompilesIncorrectSource);
 }
 public void testBug432603a() {
 	runConformTest(
@@ -4478,6 +4490,8 @@
 }
 public void testBug399527() {
 	runNegativeTest(
+		false /*skipJavac */,
+		JavacTestOptions.Excuse.JavacCompilesIncorrectSource,
 		new String[] {
 			"TypeInferenceProblem.java",
 			"\n" + 
@@ -5198,6 +5212,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=446223, [1.8][compiler] Java8 generics eclipse doesn't compile  
 public void test446223() {
 		this.runNegativeTest(
+		   false /* skipJavac */,
+		   JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 		   new String[] {
 			   "X.java",
 			   "public class X {\n" +
@@ -5604,6 +5620,8 @@
 // original test case, documenting existing compiler behavior
 public void testBug456459a() {
 	runNegativeTest(
+		false /*skipJavac */,
+		JavacTestOptions.Excuse.JavacHasErrorsEclipseHasWarnings,
 		new String[] {
 			"EnumTest.java",
 			"import java.util.EnumSet;\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index 4269018..c62cebf 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2015 GK Software AG, and others.
+ * Copyright (c) 2013, 2016 GK Software AG, 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
@@ -14,6 +14,7 @@
 import java.util.Map;
 
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 
 import junit.framework.Test;
@@ -456,6 +457,9 @@
 }
 public void testBug401850a() {
 	runNegativeTest(
+		false /* skipJavac */,
+		this.complianceLevel < ClassFileConstants.JDK1_8 ?
+		null : JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 		new String[] {
 			"X.java",
 			"import java.util.List;\n" + 
@@ -2884,6 +2888,8 @@
 	Map customOptions = getCompilerOptions();
 	customOptions.put(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, CompilerOptions.ERROR);
 	runNegativeTest(
+		false /*skipJavac */,
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
 		new String[] {
 			"DTest.java",
 			"import java.util.function.Function;\n" + 
@@ -3368,6 +3374,8 @@
 }
 public void testBug435187() {
 	runNegativeTest(
+		false /*skipJavac */,
+		JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 		new String[] {
 			"ExtractLocalLambda.java",
 			"\n" + 
@@ -5753,6 +5761,8 @@
 }
 public void testBug483019a() {
 	runConformTest(
+		false /*skipJavac */,
+		JavacTestOptions.Excuse.JavacHasErrorsEclipseHasNone,
 		new String[] {
 			"Test.java",
 			"import sub.J;\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index a0b79c7..b426473 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -1591,6 +1591,8 @@
 }
 public void test056() {
 	  this.runConformTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.JavacGeneratesIncorrectCode,
 	    new String[] {
 	      "X.java",
 	      "interface I {\n" +
@@ -1899,6 +1901,8 @@
 
 public void testReferenceExpressionInference3a() {
 	runConformTest(
+		false /* skipJavac*/,
+		JavacTestOptions.Excuse.JavacDoesNotCompileCorrectSource,
 		new String[] {
 			"X.java",
 			"interface I<E,F> {\n" +
@@ -1912,7 +1916,7 @@
 			"	<Z> Z i2s (Integer i) { return null; }\n" +
 			"	<V,W extends Number> W bar(V v) { return null; }\n" +
 			"}\n"
-		});
+		}, null);
 }
 
 // previous test demonstrates that a solution exists, just inference doesn't find it.
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
index cdc3815..ccddc7b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -7224,6 +7224,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=146383
 public void test094() {
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.JavacCompilesIncorrectSource,
 		new String[] {
 			"X.java",//===================
 			"import java.util.ArrayList;\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
index b30d692..85c739b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
@@ -25,6 +25,7 @@
 import java.io.IOException;
 import java.util.Map;
 
+import org.eclipse.jdt.core.tests.compiler.regression.AbstractRegressionTest.JavacTestOptions.Excuse;
 import org.eclipse.jdt.core.tests.junit.extension.TestCase;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
@@ -2349,6 +2350,8 @@
 public void test069() {
 	// Lambda argument hides a field.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -2446,6 +2449,8 @@
 public void test073() {
 	// Lambda local hides a field
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -2574,6 +2579,8 @@
 public void test078() {
 	// Nested Lambda argument redeclares a field.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -2900,6 +2907,8 @@
 public void test088() {
 	// class inside lambda (!) redeclares a field.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -2926,6 +2935,8 @@
 public void test089() {
 	// class inside lambda redeclares outer method's argument.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -2957,6 +2968,8 @@
 public void test090() {
 	// class inside lambda redeclares outer method's local.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -2988,6 +3001,8 @@
 public void test091() {
 	// class inside lambda redeclares outer lambda's argument.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -3019,6 +3034,8 @@
 public void test092() {
 	// class inside lambda redeclares outer lambda's local.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -3051,6 +3068,8 @@
 public void test093() {
 	// local of class inside lambda redeclares a field.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -3088,6 +3107,8 @@
 public void test094() {
 	// local of class under lambda redeclares outer methods local.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -3125,6 +3146,8 @@
 public void test095() {
 	// local of class under lambda redeclares outer lambda's argument & local
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -3329,6 +3352,8 @@
 public void test400745a() {
 	// local type hiding scenario 
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -4177,6 +4202,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=384750, [1.8] Compiler should reject invalid method reference expressions
 public void test384750j() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -4223,6 +4250,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=384750, [1.8] Compiler should reject invalid method reference expressions
 public void test384750l() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -4720,6 +4749,8 @@
 	Map customOptions = getCompilerOptions();
 	customOptions.put(CompilerOptions.OPTION_ReportIndirectStaticAccess, CompilerOptions.WARNING);
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java",
 					"interface I {\n" +
@@ -4868,6 +4899,8 @@
 //  https://bugs.eclipse.org/bugs/show_bug.cgi?id=384750, [1.8] Compiler should reject invalid method reference expressions
 public void test384750z6() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.DEFAULT,
 			new String[] {
 					"X.java",
 					"import java.util.List;\n" +
@@ -4885,6 +4918,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=384750, [1.8] Compiler should reject invalid method reference expressions
 public void test384750z7() {
 this.runNegativeTest(
+		false /* skipJavac */,
+		new JavacTestOptions("-Xlint:rawtypes"),
 		new String[] {
 				"X.java",
 				"import java.util.List;\n" +
@@ -5163,6 +5198,8 @@
 // demonstrate that the bound problem is the only real issue in test401610e()
 public void test401610ee() {
 this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 		new String[] {
 				"X.java",
 				"interface I<T extends String> {\n" +
@@ -5632,6 +5669,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=401847, [1.8][compiler] Polyconditionals not accepted in method invocation contexts.
 public void test401847() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 				"X.java",
 				"interface I {\n" +
@@ -5705,6 +5744,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=401939, [1.8][compiler] Incorrect shape analysis leads to method resolution failure .
 public void test401939() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 				"X.java",
 				"interface I {\n" +
@@ -5954,6 +5995,8 @@
 	Map options = getCompilerOptions();
 	options.put(CompilerOptions.OPTION_ReportUndocumentedEmptyBlock, CompilerOptions.ERROR);
 	this.runNegativeTest(
+			false /* skipJavac */,
+			new JavacTestOptions("Xlint:empty"),
 			new String[] {
 				"X.java",
 				"interface I {\n" +
@@ -6501,6 +6544,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=406588, [1.8][compiler][codegen] java.lang.invoke.LambdaConversionException: Incorrect number of parameters for static method newinvokespecial 
 public void test406588() {
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.JavacCompilesIncorrectSource,
 			new String[] {
 				"X.java",
 				"interface I {\n" +
@@ -6558,6 +6603,8 @@
 		compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR);
 		compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.ERROR);
 		this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
 			new String[] {
 				"X.java", 
 				"interface I {\n" +
@@ -6744,6 +6791,8 @@
 	compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR);
 	compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.WARNING);
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 		new String[] {
 				"Y.java",
 				"public class Y {\n" +
@@ -6795,6 +6844,8 @@
 					"    }\n" +
 					"}\n";
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[]{"Y.java",
 						source},
 						"----------\n" + 
@@ -7261,6 +7312,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=420598, [1.8][compiler] Incorrect error about intersection cast type not being a functional interface. 
 public void testIntersectionCast() {
 		this.runNegativeTest(
+			true /* skipJavac */,
+			JavacTestOptions.EclipseHasABug.EclipseBug424410,
 			new String[] {
 					"X.java", 
 					"import java.io.Serializable;\n" +
@@ -7479,6 +7532,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=422489, [1.8][compiler] NPE in CompoundAssignment.analyseCode when creating AST for java.util.stream.Collectors
 public void test422489b() { // interfaces and methods order changed, triggers NPE.
 	this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.JavacHasWarningsEclipseNotConfigured,
 			new String[] {
 					"X.java", 
 					"interface I {\n" +
@@ -7672,6 +7727,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=421927, [1.8][compiler] Bad diagnostic: Unnecessary cast from I to I for lambdas.
 public void test421927a() {
 	this.runNegativeTest(
+			false,
+			Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 					"X.java", 
 					"interface I { \n" +
@@ -8332,6 +8389,8 @@
 // NOTE: javac 8b127 incorrectly accepts this program due to https://bugs.openjdk.java.net/browse/JDK-8033810
 public void test425278() {
 	runNegativeTest(
+		false /*skipJavac */,
+		JavacTestOptions.JavacHasABug.JavacBug8033810,
 		new String[] {
 			"X.java",
 			"interface I<T, S extends X<T>> { \n" +
@@ -9126,6 +9185,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=438945, [1.8] NullPointerException InferenceContext18.checkExpression in java 8 with generics, primitives, and overloading
 public void test438945() {
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.JavacHasWarningsEclipseNotConfigured,
 		new String[] {
 			"X.java",
 			"import java.util.function.ToIntFunction;\n" +
@@ -9150,6 +9211,8 @@
 	options.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
 		new String[] {
 			"X.java",
 			"@FunctionalInterface\n" +
@@ -9660,6 +9723,8 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=432759,  [1.8][compiler] Some differences between Javac and ECJ regarding wildcards and static methods
 public void test432759() {
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.JavacDoesNotCompileCorrectSource,
 		new String[] {
 			"X.java", 
 			"import java.util.function.BinaryOperator;\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
index 9dbfe49..792f9e2 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2015 GK Software AG and others.
+ * Copyright (c) 2010, 2016 GK Software AG 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
@@ -171,7 +171,11 @@
 	    "",
 	    this.LIBS,
 	    false/*shouldFlush*/,
-	    null/*vmArgs*/);
+	    null/*vmArgs*/,
+	    null /*customOptions*/,
+	    null /*clientRequester*/,
+	    false/*skipJavac*/,
+	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
 }
 
 // a non-null argument is checked for null
@@ -212,7 +216,11 @@
 	    "OK",
 	    this.LIBS,
 	    false/*shouldFlush*/,
-	    null/*vmArgs*/);
+	    null/*vmArgs*/,
+	    null /*customOptions*/,
+	    null /*clientRequester*/,
+	    false/*skipJavac*/,
+	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
 }
 // passing null to nonnull parameter - many fields in enclosing class
 public void test_nonnull_parameter_003() {
@@ -847,7 +855,11 @@
 		"",
 	    this.LIBS,
 	    false/*shouldFlush*/,
-	    null/*vmArgs*/);
+	    null/*vmArgs*/,
+	    null /*customOtions*/,
+	    null /*clientRequester*/,
+	    false/*skipJavac*/,
+	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
 	runNegativeTestWithLibs(
 		false, // don't flush
 		new String[] {
@@ -887,7 +899,11 @@
 		"",
 	    this.LIBS,
 	    false/*shouldFlush*/,
-	    null/*vmArgs*/);
+	    null/*vmArgs*/,
+	    null /*customOptions*/,
+	    null /*clientRequester*/,
+	    false/*skipJavac*/,
+	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
 }
 // a method adds a @NonNull annotation, super interface has no null annotation
 // changing other from unconstrained to @Nullable is OK
@@ -1362,7 +1378,11 @@
 		"",
 	    this.LIBS,
 	    false/*shouldFlush*/,
-	    null/*vmArgs*/);
+	    null/*vmArgs*/,
+	    null /*customOptions*/,
+	    null /*clientRequester*/,
+	    false/*skipJavac*/,
+	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
 }
 
 // a method relaxes the parameter null specification from @NonNull to un-annotated
@@ -8696,6 +8716,7 @@
 	options2.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo2.NonNull2");
 	options2.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo2.Nullable2");
 	options2.put(JavaCore.COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME, "org.foo2.NoNulls2");
+	options2.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION, JavaCore.WARNING);
 	runConformTest(
 		false, // flush
 		new String[] {
@@ -8727,7 +8748,7 @@
 			"	}\n" +
 			"	@NoNulls2\n" + 
 			"	public String strong(String theValue) {\n" + 
-			"		return theValue;\n" + 
+			"		return weaken(theValue);\n" + 
 			"	}\n" + 
 			"\n" + 
 			"}",
@@ -8744,8 +8765,13 @@
 			"}"
 		},
 		null, //libs
-		options1,
-		"",
+		options2,
+		"----------\n" + 
+		"1. WARNING in p2\\TestNulls2.java (at line 10)\n" + 
+		"	return weaken(theValue);\n" + 
+		"	       ^^^^^^^^^^^^^^^^\n" + 
+		"Null type mismatch: required \'@NonNull2 String\' but the provided value is specified as @Nullable2\n" + 
+		"----------\n",
 		"",
 		"",
 		JavacTestOptions.DEFAULT);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index 8fe4419..f92be0a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2015 GK Software AG and others.
+ * Copyright (c) 2012, 2016 GK Software AG 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
@@ -12,6 +12,7 @@
  *								Bug 467032 - TYPE_USE Null Annotations: IllegalStateException with annotated arrays of Enum when accessed via BinaryTypeBinding
  *								Bug 467482 - TYPE_USE null annotations: Incorrect "Redundant null check"-warning
  *								Bug 473713 - [1.8][null] Type mismatch: cannot convert from @NonNull A1 to @NonNull A1
+ *								Bug 467430 - TYPE_USE Null Annotations: Confusing error message with known null value
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -83,6 +84,8 @@
 		customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable");
 		customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull");
 		runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
 			new String[] {
 				CUSTOM_NULLABLE_NAME,
 				CUSTOM_NULLABLE_CONTENT_JSR308,
@@ -8158,6 +8161,77 @@
 				"}\n"
 			}, getCompilerOptions(), "");
 }
+public void testBug467430() {
+	runConformTestWithLibs(
+		new String[] {
+				"A.java",
+				"public class A {\n" +
+				"	@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+				"	void m(java.util.@org.eclipse.jdt.annotation.Nullable Map<String, Integer> map) {\n" +
+				"	}\n" +
+				"	void m2(A a) {\n" +
+				"		final java.util.Map<String, Integer> v = null;\n" +
+				"		a.m(v);\n" +
+				"	}\n" +
+				"}"
+			}, 
+			getCompilerOptions(),
+			"");
+}
+public void testBug467430mismatch() {
+	runConformTestWithLibs(
+		new String[] {
+				"A.java",
+				"public class A {\n" +
+				"	@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+				"	void m(java.util.@org.eclipse.jdt.annotation.Nullable Map<String, Integer> map) {\n" +
+				"	}\n" +
+				"	void m2(A a) {\n" +
+				"		final java.util.Map<String, @org.eclipse.jdt.annotation.Nullable Integer> v = null;\n" +
+				"		a.m(v);\n" +
+				"	}\n" +
+				"}"
+			}, 
+			getCompilerOptions(),
+			"");
+}
+public void testBug467430array() {
+	runConformTestWithLibs(
+		new String[] {
+				"A.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"public class A {\n" +
+				"	@NonNullByDefault\n" +
+				"	void m(@NonNull String @Nullable [] array) {\n" +
+				"	}\n" +
+				"	void m2(A a) {\n" +
+				"		final String[] v = null;\n" +
+				"		a.m(v);\n" +
+				"	}\n" +
+				"}"
+			}, 
+			getCompilerOptions(),
+			"");
+}
+public void testBug467430arrayMismatch() {
+	runConformTestWithLibs(
+		new String[] {
+				"A.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"public class A {\n" +
+				"	@NonNullByDefault\n" +
+				"	void m(@NonNull String @Nullable [] array) {\n" +
+				"	}\n" +
+				"	void m2(A a) {\n" +
+				"		final @Nullable String @Nullable [] v = null;\n" +
+				"		a.m(v);\n" +
+				"	}\n" +
+				"}"
+			}, 
+			getCompilerOptions(),
+			"");
+}
+
 public void testBug446217() {
 	runConformTestWithLibs(
 		new String[] {
@@ -8746,7 +8820,7 @@
 			"		checkNotNull(map); // OK\n" + 
 			"\n" + 
 			"		@NonNull\n" + 
-			"		Object @Nullable [] objects = null;\n" + 
+			"		Object @Nullable [] objects = new @NonNull Object[0];\n" + 
 			"		// Error: Null type mismatch (type annotations): required '@NonNull Object @NonNull[]' but this expression ...\n" + 
 			"		checkNotNull(objects);\n" + 
 			"	}\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java
index 63e6ecf..dd28486 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2014 IBM Corporation and others.
+ * Copyright (c) 2013, 2016 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
@@ -768,6 +768,8 @@
 }
 public void test027() { // javac bug: 8b115 complains of ambiguity here.
 	this.runConformTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.JavacDoesNotCompileCorrectSource,
 			new String[] {
 				"X.java",
 				"interface I {\n" +
@@ -1325,6 +1327,8 @@
 }
 public void test4008712i() { // javac bug: 8b115 complains of ambiguity here.
 	this.runConformTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.JavacDoesNotCompileCorrectSource,
 			new String[] {
 				"X.java",
 				"interface I {\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RepeatableAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RepeatableAnnotationTest.java
index ae5f98b..28475ca 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RepeatableAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RepeatableAnnotationTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2014 Jesper S Moller and others.
+ * Copyright (c) 2013, 2016 Jesper S Moller 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
@@ -1456,6 +1456,8 @@
 	// 419209: [1.8] Repeating container annotations should be rejected in the presence of annotation it contains
 	public void testRepeatableWithContaining1() {
 		this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 				"A.java",
 				"@interface FooContainerContainer {\n" +
@@ -1481,6 +1483,8 @@
 	// 419209: [1.8] Repeating container annotations should be rejected in the presence of annotation it contains
 	public void testRepeatableWithContaining2() {
 		this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 				"A.java",
 				"@interface FooContainerContainer {\n" +
@@ -1506,6 +1510,8 @@
 	// 419209: [1.8] Repeating container annotations should be rejected in the presence of annotation it contains
 	public void testRepeatableWithContaining3() {
 		this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.EclipseHasSomeMoreWarnings,
 			new String[] {
 				"A.java",
 				"@interface FooContainerContainer {\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
index 9f6865c..e10053f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -2212,7 +2212,7 @@
 			"" /* expected output string */,
 			null /* do not check error string */,
 			// javac options
-			JavacTestOptions.EclipseJustification.EclipseBug183211 /* javac test options */);
+			JavacTestOptions.DEFAULT /* javac test options */);
 	}
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=183211 - variation
 	public void test062() {
@@ -2283,7 +2283,7 @@
 			"	                   ^\n" +
 			"The field b is ambiguous\n" +
 			"----------\n",
-			JavacTestOptions.EclipseJustification.EclipseBug183211b
+			JavacTestOptions.DEFAULT
 		);
 	}
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=183211 - variation
@@ -2308,7 +2308,7 @@
 			"	^\n" +
 			"The type M is ambiguous\n" +
 			"----------\n",
-			JavacTestOptions.EclipseJustification.EclipseBug183211
+			JavacTestOptions.DEFAULT
 		);
 	}
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=230026
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
index 8d16cb5..323c5f8 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
@@ -6242,6 +6242,8 @@
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=419331, [1.8][compiler] Weird error on forward reference to type annotations from type parameter declarations
 	public void testForwardReference() {
 		this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.Excuse.JavacHasWarningsEclipseNotConfigured,
 			new String[] {
 				"T.java",
 				"import java.lang.annotation.Annotation;\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode18Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode18Test.java
index ae5e6d5..4090e8b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode18Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode18Test.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014 IBM Corporation and others.
+ * Copyright (c) 2014, 2016 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
@@ -43,6 +43,8 @@
 	Map options = getCompilerOptions();
 	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.JavacCompilesIncorrectSource,
 		new String[] {
 			"X.java",
 			"public class X {\n" + 
@@ -70,6 +72,8 @@
 	Map options = getCompilerOptions();
 	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
 	this.runNegativeTest(
+		false /* skipJavac */,
+		JavacTestOptions.Excuse.JavacCompilesIncorrectSource,
 		new String[] {
 			"X.java",
 			"public class X {\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
index 55860a0..70fb49e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
@@ -1290,6 +1290,8 @@
  	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102631
 	public void test033() {
 		this.runNegativeTest(
+			false /* skipJavac */,
+			JavacTestOptions.EclipseHasABug.EclipseBug421922,
 			new String[] {
 				"X.java",
 				"public class X {\n" +
@@ -1362,7 +1364,9 @@
 			System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
 			if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
 				this.runNegativeTest(
-					new String[] {
+				false /* skipJavac */,
+				JavacTestOptions.EclipseHasABug.EclipseBug421922,
+				new String[] {
 						"X.java",
 						"public class X {\n" +
 						"	void a(boolean b, Object... o) {System.out.print(1);}\n" +
@@ -2996,6 +3000,8 @@
 			System.setProperty("tolerateIllegalAmbiguousVarargsInvocation", "true");
 			if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
 				this.runNegativeTest(
+					false /* skipJavac */,
+					JavacTestOptions.EclipseHasABug.EclipseBug421922,
 					new String[] {
 						"X.java",
 						"import java.util.Arrays;\n" +
@@ -3381,6 +3387,8 @@
 					"2");
 			} else {
 				this.runNegativeTest(
+						false /* skipJavac */,
+						JavacTestOptions.EclipseHasABug.EclipseBug421922,
 						src,
 						"----------\n" + 
 						"1. WARNING in X.java (at line 5)\n" + 
@@ -3425,6 +3433,8 @@
 					"1");
 			} else {
 				this.runNegativeTest(
+						false /* skipJavac */,
+						JavacTestOptions.EclipseHasABug.EclipseBug421922,
 						src,
 						"----------\n" + 
 						"1. ERROR in X.java (at line 9)\n" + 
diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
index 100e1d5..c463de4 100644
--- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core.tests.model;singleton:=true
-Bundle-Version: 3.10.0.qualifier
+Bundle-Version: 3.10.100.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.core.tests,
diff --git a/org.eclipse.jdt.core.tests.model/pom.xml b/org.eclipse.jdt.core.tests.model/pom.xml
index 20f1fb3..66b2fb2 100644
--- a/org.eclipse.jdt.core.tests.model/pom.xml
+++ b/org.eclipse.jdt.core.tests.model/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.core.tests.model</artifactId>
-  <version>3.10.0-SNAPSHOT</version>
+  <version>3.10.100-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
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 4bc8775..da461e4 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, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -8559,9 +8559,8 @@
 		if(choices == null || choices.length == 0) return;
 		int length = keyword.length;
 		for (int i = 0; i < choices.length; i++)
-			if (length <= choices[i].length
-			&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
-					)){
+			if (length <= choices[i].length && (CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */)
+					|| (this.options.substringMatch && CharOperation.substringMatch(keyword, choices[i])))) {
 				if (ignorePackageKeyword && CharOperation.equals(choices[i], Keywords.PACKAGE))
 					continue;
 				int relevance = computeBaseRelevance();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index 25b8742..680c44b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -193,6 +193,15 @@
 	if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
 		manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
 	}
+	if (currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_7) {
+		FieldBinding fieldBinding = this.binding;
+		if (fieldBinding.isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
+			FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
+			if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
+				currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+			}
+		}
+	}
 	return flowInfo;
 }
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
index 50ad57f..748dcd3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
@@ -235,6 +235,8 @@
 							long providedBits = validNullTagBits(providedDimsTagBits[i]);
 							if (i == 0 && requiredBits == TagBits.AnnotationNullable && nullStatus != -1 && mode.requiredNullableMatchesAll()) {
 								// toplevel nullable array: no need to check 
+								if (nullStatus == FlowInfo.NULL)
+									break; // null value has no details
 							} else {
 								if (i > 0)
 									currentNullStatus = -1; // don't use beyond the outermost dimension
@@ -261,7 +263,7 @@
 					if (severity == 0 && (providedBits & TagBits.AnnotationNonNull) != 0)
 						okStatus = NullAnnotationMatching.NULL_ANNOTATIONS_OK_NONNULL;
 				}
-				if (severity < 2) {
+				if (severity < 2 && nullStatus != FlowInfo.NULL) {  // null value has no details
 					TypeBinding providedSuper = providedType.findSuperTypeOriginatingFrom(requiredType);
 					TypeBinding providedSubstituteSuper = providedSubstitute != null ? providedSubstitute.findSuperTypeOriginatingFrom(requiredType) : null;
 					if(severity == 1 && requiredType.isTypeVariable() && providedType.isTypeVariable() && (providedSuper == requiredType || providedSubstituteSuper == requiredType)) { //$IDENTITY-COMPARISON$
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java
index 673f34e..68cd771 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java
@@ -1189,72 +1189,78 @@
 	 */
 	public final TextEdit rewriteImports(IProgressMonitor monitor) throws CoreException {
 
-		SubMonitor subMonitor = SubMonitor.convert(monitor,
-				Messages.bind(Messages.importRewrite_processDescription), 2);
-		if (!hasRecordedChanges()) {
-			this.createdImports= CharOperation.NO_STRINGS;
-			this.createdStaticImports= CharOperation.NO_STRINGS;
+		try {
+			SubMonitor subMonitor = SubMonitor.convert(monitor,
+					Messages.bind(Messages.importRewrite_processDescription), 2);
+			if (!hasRecordedChanges()) {
+				this.createdImports= CharOperation.NO_STRINGS;
+				this.createdStaticImports= CharOperation.NO_STRINGS;
 //{ObjectTeams: base
-			this.createdBaseImports= CharOperation.NO_STRINGS;
+				this.createdBaseImports= CharOperation.NO_STRINGS;
 //SH}
-			return new MultiTextEdit();
-		}
-
-		CompilationUnit usedAstRoot= this.astRoot;
-		if (usedAstRoot == null) {
-			ASTParser parser= ASTParser.newParser(AST.JLS8);
-			parser.setSource(this.compilationUnit);
-			parser.setFocalPosition(0); // reduced AST
-			parser.setResolveBindings(false);
-			usedAstRoot= (CompilationUnit) parser.createAST(subMonitor.split(1));
-		}
-
-		ImportRewriteConfiguration config= buildImportRewriteConfiguration();
-
-		ImportRewriteAnalyzer computer=
-			new ImportRewriteAnalyzer(this.compilationUnit, usedAstRoot, config);
-
-		for (String addedImport : this.addedImports) {
-			boolean isStatic = STATIC_PREFIX == addedImport.charAt(0);
-			String qualifiedName = addedImport.substring(1);
+				return new MultiTextEdit();
+			}
+	
+			CompilationUnit usedAstRoot= this.astRoot;
+			if (usedAstRoot == null) {
+				ASTParser parser= ASTParser.newParser(AST.JLS8);
+				parser.setSource(this.compilationUnit);
+				parser.setFocalPosition(0); // reduced AST
+				parser.setResolveBindings(false);
+				usedAstRoot= (CompilationUnit) parser.createAST(subMonitor.split(1));
+			}
+	
+			ImportRewriteConfiguration config= buildImportRewriteConfiguration();
+	
+			ImportRewriteAnalyzer computer=
+				new ImportRewriteAnalyzer(this.compilationUnit, usedAstRoot, config);
+	
+			for (String addedImport : this.addedImports) {
+				boolean isStatic = STATIC_PREFIX == addedImport.charAt(0);
+				String qualifiedName = addedImport.substring(1);
 //{ObjectTeams: base
 /* orig:
-			computer.addImport(isStatic, qualifiedName);
+				computer.addImport(isStatic, qualifiedName);
   :giro */
-			boolean isBase = BASE_PREFIX == addedImport.charAt(0);
-			computer.addImport(isStatic, isBase, qualifiedName);
+				boolean isBase = BASE_PREFIX == addedImport.charAt(0);
+				computer.addImport(isStatic, isBase, qualifiedName);
 // SH}
-		}
-
-		for (String removedImport : this.removedImports) {
-			boolean isStatic = STATIC_PREFIX == removedImport.charAt(0);
-			String qualifiedName = removedImport.substring(1);
+			}
+	
+			for (String removedImport : this.removedImports) {
+				boolean isStatic = STATIC_PREFIX == removedImport.charAt(0);
+				String qualifiedName = removedImport.substring(1);
 //{ObjectTeams: base
 /* orig:
-			computer.removeImport(isStatic, qualifiedName);
+				computer.removeImport(isStatic, qualifiedName);
   :giro */
-			boolean isBase = BASE_PREFIX == removedImport.charAt(0);
-			computer.removeImport(isStatic, isBase, qualifiedName);
+				boolean isBase = BASE_PREFIX == removedImport.charAt(0);
+				computer.removeImport(isStatic, isBase, qualifiedName);
 // SH}
-		}
-
-		for (String typeExplicitSimpleName : this.typeExplicitSimpleNames) {
-			computer.requireExplicitImport(false, typeExplicitSimpleName);
-		}
-
-		for (String staticExplicitSimpleName : this.staticExplicitSimpleNames) {
-			computer.requireExplicitImport(true, staticExplicitSimpleName);
-		}
-
-		ImportRewriteAnalyzer.RewriteResult result= computer.analyzeRewrite(subMonitor.split(1));
-
-		this.createdImports= result.getCreatedImports();
-		this.createdStaticImports= result.getCreatedStaticImports();
+			}
+	
+			for (String typeExplicitSimpleName : this.typeExplicitSimpleNames) {
+				computer.requireExplicitImport(false, typeExplicitSimpleName);
+			}
+	
+			for (String staticExplicitSimpleName : this.staticExplicitSimpleNames) {
+				computer.requireExplicitImport(true, staticExplicitSimpleName);
+			}
+	
+			ImportRewriteAnalyzer.RewriteResult result= computer.analyzeRewrite(subMonitor.split(1));
+	
+			this.createdImports= result.getCreatedImports();
+			this.createdStaticImports= result.getCreatedStaticImports();
 //{ObjectTeams: base
-		this.createdBaseImports= result.getCreatedBaseImports();
+			this.createdBaseImports= result.getCreatedBaseImports();
 //SH}
-
-		return result.getTextEdit();
+	
+			return result.getTextEdit();
+		} finally {
+			if (monitor != null) {
+				monitor.done();
+			}
+		}
 	}
 
 	private ImportRewriteConfiguration buildImportRewriteConfiguration() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 21dfe53..dcf048a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -4179,170 +4179,176 @@
 	 * @since 3.1
 	 */
 	public static void initializeAfterLoad(IProgressMonitor monitor) throws CoreException {
-		SubMonitor mainMonitor = SubMonitor.convert(monitor, Messages.javamodel_initialization, 100);
-		mainMonitor.subTask(Messages.javamodel_configuring_classpath_containers);
-
-		// initialize all containers and variables
-		JavaModelManager manager = JavaModelManager.getJavaModelManager();
 		try {
-			SubMonitor subMonitor = mainMonitor.split(50).setWorkRemaining(100); // 50% of the time is spent in initializing containers and variables
-			subMonitor.worked(5); // give feedback to the user that something is happening
-			manager.batchContainerInitializationsProgress.initializeAfterLoadMonitor.set(subMonitor);
-			if (manager.forceBatchInitializations(true/*initAfterLoad*/)) { // if no other thread has started the batch container initializations
-				manager.getClasspathContainer(Path.EMPTY, null); // force the batch initialization
-			} else { // else wait for the batch initialization to finish
-				while (manager.batchContainerInitializations == JavaModelManager.BATCH_INITIALIZATION_IN_PROGRESS) {
-					subMonitor.subTask(manager.batchContainerInitializationsProgress.subTaskName);
-					subMonitor.worked(manager.batchContainerInitializationsProgress.getWorked());
-					synchronized(manager) {
-						try {
-							manager.wait(100);
-						} catch (InterruptedException e) {
-							// continue
+			SubMonitor mainMonitor = SubMonitor.convert(monitor, Messages.javamodel_initialization, 100);
+			mainMonitor.subTask(Messages.javamodel_configuring_classpath_containers);
+	
+			// initialize all containers and variables
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			try {
+				SubMonitor subMonitor = mainMonitor.split(50).setWorkRemaining(100); // 50% of the time is spent in initializing containers and variables
+				subMonitor.worked(5); // give feedback to the user that something is happening
+				manager.batchContainerInitializationsProgress.initializeAfterLoadMonitor.set(subMonitor);
+				if (manager.forceBatchInitializations(true/*initAfterLoad*/)) { // if no other thread has started the batch container initializations
+					manager.getClasspathContainer(Path.EMPTY, null); // force the batch initialization
+				} else { // else wait for the batch initialization to finish
+					while (manager.batchContainerInitializations == JavaModelManager.BATCH_INITIALIZATION_IN_PROGRESS) {
+						subMonitor.subTask(manager.batchContainerInitializationsProgress.subTaskName);
+						subMonitor.worked(manager.batchContainerInitializationsProgress.getWorked());
+						synchronized(manager) {
+							try {
+								manager.wait(100);
+							} catch (InterruptedException e) {
+								// continue
+							}
 						}
 					}
 				}
+			} finally {
+				manager.batchContainerInitializationsProgress.initializeAfterLoadMonitor.set(null);
+			}
+	
+			// avoid leaking source attachment properties (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=183413 )
+			// and recreate links for external folders if needed
+			mainMonitor.subTask(Messages.javamodel_resetting_source_attachment_properties);
+			final IJavaProject[] projects = manager.getJavaModel().getJavaProjects();
+			HashSet visitedPaths = new HashSet();
+			ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
+			for (int i = 0, length = projects.length; i < length; i++) {
+				JavaProject javaProject = (JavaProject) projects[i];
+				IClasspathEntry[] classpath;
+				try {
+					classpath = javaProject.getResolvedClasspath();
+				} catch (JavaModelException e) {
+					// project no longer exist: ignore
+					continue;
+				}
+				if (classpath != null) {
+					for (int j = 0, length2 = classpath.length; j < length2; j++) {
+						IClasspathEntry entry = classpath[j];
+						if (entry.getSourceAttachmentPath() != null) {
+							IPath entryPath = entry.getPath();
+							if (visitedPaths.add(entryPath)) {
+								Util.setSourceAttachmentProperty(entryPath, null);
+							}
+						}
+						// else source might have been attached by IPackageFragmentRoot#attachSource(...), we keep it
+						if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+							IPath entryPath = entry.getPath();
+							if (ExternalFoldersManager.isExternalFolderPath(entryPath) && externalFoldersManager.getFolder(entryPath) == null) {
+								externalFoldersManager.addFolder(entryPath, true);
+							}
+						}
+					}
+				}
+			}
+			try {
+				externalFoldersManager.createPendingFolders(mainMonitor.split(1));
+			}
+			catch(JavaModelException jme) {
+				// Creation of external folder project failed. Log it and continue;
+				Util.log(jme, "Error while processing external folders"); //$NON-NLS-1$
+			}
+	
+			// ensure external jars are refreshed (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=93668)
+			// before search is initialized (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=405051)
+			final JavaModel model = manager.getJavaModel();
+			try {
+				mainMonitor.subTask(Messages.javamodel_refreshing_external_jars);
+				model.refreshExternalArchives(
+					null/*refresh all projects*/,
+					mainMonitor.split(1) // 1% of the time is spent in jar refresh
+				);
+			} catch (JavaModelException e) {
+				// refreshing failed: ignore
+			}
+	
+			// initialize delta state
+			mainMonitor.subTask(Messages.javamodel_initializing_delta_state);
+			manager.deltaState.rootsAreStale = true; // in case it was already initialized before we cleaned up the source attachment properties
+			manager.deltaState.initializeRoots(true/*initAfteLoad*/);
+	
+			// dummy query for waiting until the indexes are ready
+			mainMonitor.subTask(Messages.javamodel_configuring_searchengine);
+			SearchEngine engine = new SearchEngine();
+			IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
+			try {
+				engine.searchAllTypeNames(
+					null,
+					SearchPattern.R_EXACT_MATCH,
+					"!@$#!@".toCharArray(), //$NON-NLS-1$
+					SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
+					IJavaSearchConstants.CLASS,
+					scope,
+					new TypeNameRequestor() {
+						public void acceptType(
+							int modifiers,
+							char[] packageName,
+							char[] simpleTypeName,
+							char[][] enclosingTypeNames,
+							String path) {
+							// no type to accept
+						}
+					},
+					// will not activate index query caches if indexes are not ready, since it would take to long
+					// to wait until indexes are fully rebuild
+					IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH,
+					mainMonitor.split(47) // 47% of the time is spent in the dummy search
+				);
+			} catch (JavaModelException e) {
+				// /search failed: ignore
+			} catch (OperationCanceledException e) {
+				if (mainMonitor.isCanceled())
+					throw e;
+				// else indexes were not ready: catch the exception so that jars are still refreshed
+			}
+	
+			// check if the build state version number has changed since last session
+			// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98969)
+			mainMonitor.subTask(Messages.javamodel_getting_build_state_number);
+			QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "stateVersionNumber"); //$NON-NLS-1$
+			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+			String versionNumber = null;
+			try {
+				versionNumber = root.getPersistentProperty(qName);
+			} catch (CoreException e) {
+				// could not read version number: consider it is new
+			}
+			String newVersionNumber = Byte.toString(State.VERSION);
+			if (!newVersionNumber.equals(versionNumber)) {
+				// build state version number has changed: touch every projects to force a rebuild
+				if (JavaBuilder.DEBUG)
+					System.out.println("Build state version number has changed"); //$NON-NLS-1$
+				IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+					public void run(IProgressMonitor progressMonitor2) throws CoreException {
+						for (int i = 0, length = projects.length; i < length; i++) {
+							IJavaProject project = projects[i];
+							try {
+								if (JavaBuilder.DEBUG)
+									System.out.println("Touching " + project.getElementName()); //$NON-NLS-1$
+								new ClasspathValidation((JavaProject) project).validate(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164
+								project.getProject().touch(progressMonitor2);
+							} catch (CoreException e) {
+								// could not touch this project: ignore
+							}
+						}
+					}
+				};
+				mainMonitor.subTask(Messages.javamodel_building_after_upgrade);
+				try {
+					ResourcesPlugin.getWorkspace().run(runnable, mainMonitor.split(1));
+				} catch (CoreException e) {
+					// could not touch all projects
+				}
+				try {
+					root.setPersistentProperty(qName, newVersionNumber);
+				} catch (CoreException e) {
+					Util.log(e, "Could not persist build state version number"); //$NON-NLS-1$
+				}
 			}
 		} finally {
-			manager.batchContainerInitializationsProgress.initializeAfterLoadMonitor.set(null);
-		}
-
-		// avoid leaking source attachment properties (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=183413 )
-		// and recreate links for external folders if needed
-		mainMonitor.subTask(Messages.javamodel_resetting_source_attachment_properties);
-		final IJavaProject[] projects = manager.getJavaModel().getJavaProjects();
-		HashSet visitedPaths = new HashSet();
-		ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
-		for (int i = 0, length = projects.length; i < length; i++) {
-			JavaProject javaProject = (JavaProject) projects[i];
-			IClasspathEntry[] classpath;
-			try {
-				classpath = javaProject.getResolvedClasspath();
-			} catch (JavaModelException e) {
-				// project no longer exist: ignore
-				continue;
-			}
-			if (classpath != null) {
-				for (int j = 0, length2 = classpath.length; j < length2; j++) {
-					IClasspathEntry entry = classpath[j];
-					if (entry.getSourceAttachmentPath() != null) {
-						IPath entryPath = entry.getPath();
-						if (visitedPaths.add(entryPath)) {
-							Util.setSourceAttachmentProperty(entryPath, null);
-						}
-					}
-					// else source might have been attached by IPackageFragmentRoot#attachSource(...), we keep it
-					if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
-						IPath entryPath = entry.getPath();
-						if (ExternalFoldersManager.isExternalFolderPath(entryPath) && externalFoldersManager.getFolder(entryPath) == null) {
-							externalFoldersManager.addFolder(entryPath, true);
-						}
-					}
-				}
-			}
-		}
-		try {
-			externalFoldersManager.createPendingFolders(mainMonitor.split(1));
-		}
-		catch(JavaModelException jme) {
-			// Creation of external folder project failed. Log it and continue;
-			Util.log(jme, "Error while processing external folders"); //$NON-NLS-1$
-		}
-
-		// ensure external jars are refreshed (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=93668)
-		// before search is initialized (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=405051)
-		final JavaModel model = manager.getJavaModel();
-		try {
-			mainMonitor.subTask(Messages.javamodel_refreshing_external_jars);
-			model.refreshExternalArchives(
-				null/*refresh all projects*/,
-				mainMonitor.split(1) // 1% of the time is spent in jar refresh
-			);
-		} catch (JavaModelException e) {
-			// refreshing failed: ignore
-		}
-
-		// initialize delta state
-		mainMonitor.subTask(Messages.javamodel_initializing_delta_state);
-		manager.deltaState.rootsAreStale = true; // in case it was already initialized before we cleaned up the source attachment properties
-		manager.deltaState.initializeRoots(true/*initAfteLoad*/);
-
-		// dummy query for waiting until the indexes are ready
-		mainMonitor.subTask(Messages.javamodel_configuring_searchengine);
-		SearchEngine engine = new SearchEngine();
-		IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
-		try {
-			engine.searchAllTypeNames(
-				null,
-				SearchPattern.R_EXACT_MATCH,
-				"!@$#!@".toCharArray(), //$NON-NLS-1$
-				SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
-				IJavaSearchConstants.CLASS,
-				scope,
-				new TypeNameRequestor() {
-					public void acceptType(
-						int modifiers,
-						char[] packageName,
-						char[] simpleTypeName,
-						char[][] enclosingTypeNames,
-						String path) {
-						// no type to accept
-					}
-				},
-				// will not activate index query caches if indexes are not ready, since it would take to long
-				// to wait until indexes are fully rebuild
-				IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH,
-				mainMonitor.split(47) // 47% of the time is spent in the dummy search
-			);
-		} catch (JavaModelException e) {
-			// /search failed: ignore
-		} catch (OperationCanceledException e) {
-			if (mainMonitor.isCanceled())
-				throw e;
-			// else indexes were not ready: catch the exception so that jars are still refreshed
-		}
-
-		// check if the build state version number has changed since last session
-		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98969)
-		mainMonitor.subTask(Messages.javamodel_getting_build_state_number);
-		QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "stateVersionNumber"); //$NON-NLS-1$
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		String versionNumber = null;
-		try {
-			versionNumber = root.getPersistentProperty(qName);
-		} catch (CoreException e) {
-			// could not read version number: consider it is new
-		}
-		String newVersionNumber = Byte.toString(State.VERSION);
-		if (!newVersionNumber.equals(versionNumber)) {
-			// build state version number has changed: touch every projects to force a rebuild
-			if (JavaBuilder.DEBUG)
-				System.out.println("Build state version number has changed"); //$NON-NLS-1$
-			IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
-				public void run(IProgressMonitor progressMonitor2) throws CoreException {
-					for (int i = 0, length = projects.length; i < length; i++) {
-						IJavaProject project = projects[i];
-						try {
-							if (JavaBuilder.DEBUG)
-								System.out.println("Touching " + project.getElementName()); //$NON-NLS-1$
-							new ClasspathValidation((JavaProject) project).validate(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164
-							project.getProject().touch(progressMonitor2);
-						} catch (CoreException e) {
-							// could not touch this project: ignore
-						}
-					}
-				}
-			};
-			mainMonitor.subTask(Messages.javamodel_building_after_upgrade);
-			try {
-				ResourcesPlugin.getWorkspace().run(runnable, mainMonitor.split(1));
-			} catch (CoreException e) {
-				// could not touch all projects
-			}
-			try {
-				root.setPersistentProperty(qName, newVersionNumber);
-			} catch (CoreException e) {
-				Util.log(e, "Could not persist build state version number"); //$NON-NLS-1$
+			if (monitor != null) {
+				monitor.done();
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
index 66ccb75..74f2b35 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
@@ -706,66 +706,74 @@
 	 * @exception CoreException if the operation fails
 	 */
 	public void run(IProgressMonitor monitor) throws CoreException {
-		JavaModelManager manager = JavaModelManager.getJavaModelManager();
-		DeltaProcessor deltaProcessor = manager.getDeltaProcessor();
-		int previousDeltaCount = deltaProcessor.javaModelDeltas.size();
+		SubMonitor oldMonitor = this.progressMonitor;
 		try {
-			this.progressMonitor = SubMonitor.convert(monitor);
-			pushOperation(this);
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			DeltaProcessor deltaProcessor = manager.getDeltaProcessor();
+			int previousDeltaCount = deltaProcessor.javaModelDeltas.size();
 			try {
-				if (canModifyRoots()) {
-					// computes the root infos before executing the operation
-					// noop if aready initialized
-					JavaModelManager.getDeltaState().initializeRoots(false/*not initiAfterLoad*/);
+				this.progressMonitor = SubMonitor.convert(monitor);
+				pushOperation(this);
+				try {
+					if (canModifyRoots()) {
+						// computes the root infos before executing the operation
+						// noop if aready initialized
+						JavaModelManager.getDeltaState().initializeRoots(false/*not initiAfterLoad*/);
+					}
+	
+					executeOperation();
+				} finally {
+					if (isTopLevelOperation()) {
+						runPostActions();
+					}
 				}
-
-				executeOperation();
 			} finally {
-				if (isTopLevelOperation()) {
-					runPostActions();
+				try {
+					// reacquire delta processor as it can have been reset during executeOperation()
+					deltaProcessor = manager.getDeltaProcessor();
+	
+					// update JavaModel using deltas that were recorded during this operation
+					for (int i = previousDeltaCount, size = deltaProcessor.javaModelDeltas.size(); i < size; i++) {
+						deltaProcessor.updateJavaModel((IJavaElementDelta)deltaProcessor.javaModelDeltas.get(i));
+					}
+	
+					// close the parents of the created elements and reset their project's cache (in case we are in an
+					// IWorkspaceRunnable and the clients wants to use the created element's parent)
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=83646
+					for (int i = 0, length = this.resultElements.length; i < length; i++) {
+						IJavaElement element = this.resultElements[i];
+						Openable openable = (Openable) element.getOpenable();
+						if (!(openable instanceof CompilationUnit) || !((CompilationUnit) openable).isWorkingCopy()) { // a working copy must remain a child of its parent even after a move
+							((JavaElement) openable.getParent()).close();
+						}
+						switch (element.getElementType()) {
+							case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+							case IJavaElement.PACKAGE_FRAGMENT:
+								deltaProcessor.projectCachesToReset.add(element.getJavaProject());
+								break;
+						}
+					}
+					deltaProcessor.resetProjectCaches();
+	
+					// fire only iff:
+					// - the operation is a top level operation
+					// - the operation did produce some delta(s)
+					// - but the operation has not modified any resource
+					if (isTopLevelOperation()) {
+						if ((deltaProcessor.javaModelDeltas.size() > previousDeltaCount || !deltaProcessor.reconcileDeltas.isEmpty())
+								&& !hasModifiedResource()) {
+							deltaProcessor.fire(null, DeltaProcessor.DEFAULT_CHANGE_EVENT);
+						} // else deltas are fired while processing the resource delta
+					}
+				} finally {
+					popOperation();
 				}
 			}
 		} finally {
-			try {
-				// reacquire delta processor as it can have been reset during executeOperation()
-				deltaProcessor = manager.getDeltaProcessor();
-
-				// update JavaModel using deltas that were recorded during this operation
-				for (int i = previousDeltaCount, size = deltaProcessor.javaModelDeltas.size(); i < size; i++) {
-					deltaProcessor.updateJavaModel((IJavaElementDelta)deltaProcessor.javaModelDeltas.get(i));
-				}
-
-				// close the parents of the created elements and reset their project's cache (in case we are in an
-				// IWorkspaceRunnable and the clients wants to use the created element's parent)
-				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=83646
-				for (int i = 0, length = this.resultElements.length; i < length; i++) {
-					IJavaElement element = this.resultElements[i];
-					Openable openable = (Openable) element.getOpenable();
-					if (!(openable instanceof CompilationUnit) || !((CompilationUnit) openable).isWorkingCopy()) { // a working copy must remain a child of its parent even after a move
-						((JavaElement) openable.getParent()).close();
-					}
-					switch (element.getElementType()) {
-						case IJavaElement.PACKAGE_FRAGMENT_ROOT:
-						case IJavaElement.PACKAGE_FRAGMENT:
-							deltaProcessor.projectCachesToReset.add(element.getJavaProject());
-							break;
-					}
-				}
-				deltaProcessor.resetProjectCaches();
-
-				// fire only iff:
-				// - the operation is a top level operation
-				// - the operation did produce some delta(s)
-				// - but the operation has not modified any resource
-				if (isTopLevelOperation()) {
-					if ((deltaProcessor.javaModelDeltas.size() > previousDeltaCount || !deltaProcessor.reconcileDeltas.isEmpty())
-							&& !hasModifiedResource()) {
-						deltaProcessor.fire(null, DeltaProcessor.DEFAULT_CHANGE_EVENT);
-					} // else deltas are fired while processing the resource delta
-				}
-			} finally {
-				popOperation();
+			if (monitor != null) {
+				monitor.done();
 			}
+			this.progressMonitor = oldMonitor;
 		}
 	}
 	/**
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
index a0d0e40..c425a0e 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
@@ -244,6 +244,9 @@
 			}
 		} finally {
 			requestor.endReporting();
+			if (monitor != null) {
+				monitor.done();
+			}
 		}
 	}
 	/**
@@ -505,7 +508,7 @@
 
 	}
 
-boolean match(char[] patternName, int matchRule, char[] name) {
+	boolean match(char[] patternName, int matchRule, char[] name) {
 		boolean isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0;
 		if (patternName != null) {
 			boolean isCamelCase = (matchRule & (SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH)) != 0;
@@ -591,174 +594,191 @@
 		int waitingPolicy,
 		IProgressMonitor progressMonitor)  throws JavaModelException {
 
-		// Validate match rule first
-		final int validatedTypeMatchRule = SearchPattern.validateMatchRule(typeName == null ? null : new String (typeName), typeMatchRule);
-		
-		final int pkgMatchRule = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE;
-		final char NoSuffix = IIndexConstants.TYPE_SUFFIX; // Used as TYPE_SUFFIX has no effect in method #match(char, char[] , int, char[], int , int, char[], char[])
-
-		// Debug
-		if (VERBOSE) {
-			Util.verbose("BasicSearchEngine.searchAllConstructorDeclarations(char[], char[], int, IJavaSearchScope, IRestrictedAccessConstructorRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
-			Util.verbose("	- package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
-			Util.verbose("	- type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
-			Util.verbose("	- type match rule: "+getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
-			if (validatedTypeMatchRule != typeMatchRule) {
-				Util.verbose("	- validated type match rule: "+getMatchRuleString(validatedTypeMatchRule)); //$NON-NLS-1$
+		try {
+			// Validate match rule first
+			final int validatedTypeMatchRule = SearchPattern.validateMatchRule(typeName == null ? null : new String (typeName), typeMatchRule);
+			
+			final int pkgMatchRule = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE;
+			final char NoSuffix = IIndexConstants.TYPE_SUFFIX; // Used as TYPE_SUFFIX has no effect in method #match(char, char[] , int, char[], int , int, char[], char[])
+	
+			// Debug
+			if (VERBOSE) {
+				Util.verbose("BasicSearchEngine.searchAllConstructorDeclarations(char[], char[], int, IJavaSearchScope, IRestrictedAccessConstructorRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+				Util.verbose("	- package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
+				Util.verbose("	- type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
+				Util.verbose("	- type match rule: "+getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
+				if (validatedTypeMatchRule != typeMatchRule) {
+					Util.verbose("	- validated type match rule: "+getMatchRuleString(validatedTypeMatchRule)); //$NON-NLS-1$
+				}
+				Util.verbose("	- scope: "+scope); //$NON-NLS-1$
 			}
-			Util.verbose("	- scope: "+scope); //$NON-NLS-1$
-		}
-		if (validatedTypeMatchRule == -1) return; // invalid match rule => return no results
-
-		// Create pattern
-		IndexManager indexManager = JavaModelManager.getIndexManager();
-		final ConstructorDeclarationPattern pattern = new ConstructorDeclarationPattern(
-				packageName,
-				typeName,
-				validatedTypeMatchRule);
-
-		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
-		final HashSet workingCopyPaths = new HashSet();
-		String workingCopyPath = null;
-		ICompilationUnit[] copies = getWorkingCopies();
-		final int copiesLength = copies == null ? 0 : copies.length;
-		if (copies != null) {
-			if (copiesLength == 1) {
-				workingCopyPath = copies[0].getPath().toString();
-			} else {
-				for (int i = 0; i < copiesLength; i++) {
-					ICompilationUnit workingCopy = copies[i];
-					workingCopyPaths.add(workingCopy.getPath().toString());
-				}
-			}
-		}
-		final String singleWkcpPath = workingCopyPath;
-
-		// Index requestor
-		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
-			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
-				// Filter unexpected types
-				ConstructorDeclarationPattern record = (ConstructorDeclarationPattern)indexRecord;
-				
-				if ((record.extraFlags & ExtraFlags.IsMemberType) != 0) {
-					return true; // filter out member classes
-				}
-				if ((record.extraFlags & ExtraFlags.IsLocalType) != 0) {
-					return true; // filter out local and anonymous classes
-				}
-				switch (copiesLength) {
-					case 0:
-						break;
-					case 1:
-						if (singleWkcpPath.equals(documentPath)) {
-							return true; // filter out *the* working copy
-						}
-						break;
-					default:
-						if (workingCopyPaths.contains(documentPath)) {
-							return true; // filter out working copies
-						}
-						break;
-				}
-
-				// Accept document path
-				AccessRestriction accessRestriction = null;
-				if (access != null) {
-					// Compute document relative path
-					int pkgLength = (record.declaringPackageName==null || record.declaringPackageName.length==0) ? 0 : record.declaringPackageName.length+1;
-					int nameLength = record.declaringSimpleName==null ? 0 : record.declaringSimpleName.length;
-					char[] path = new char[pkgLength+nameLength];
-					int pos = 0;
-					if (pkgLength > 0) {
-						System.arraycopy(record.declaringPackageName, 0, path, pos, pkgLength-1);
-						CharOperation.replace(path, '.', '/');
-						path[pkgLength-1] = '/';
-						pos += pkgLength;
-					}
-					if (nameLength > 0) {
-						System.arraycopy(record.declaringSimpleName, 0, path, pos, nameLength);
-						pos += nameLength;
-					}
-					// Update access restriction if path is not empty
-					if (pos > 0) {
-						accessRestriction = access.getViolatedRestriction(path);
-					}
-				}
-				nameRequestor.acceptConstructor(
-						record.modifiers,
-						record.declaringSimpleName,
-						record.parameterCount,
-						record.signature,
-						record.parameterTypes,
-						record.parameterNames,
-						record.declaringTypeModifiers,
-						record.declaringPackageName,
-						record.extraFlags,
-						documentPath,
-						accessRestriction);
-				return true;
-			}
-		};
-
-		SubMonitor subMonitor = SubMonitor.convert(progressMonitor, Messages.engine_searching, 1000);
-		// add type names from indexes
-		indexManager.performConcurrentJob(
-			new PatternSearchJob(
-				pattern,
-				getDefaultSearchParticipant(), // Java search only
-				scope,
-				searchRequestor),
-			waitingPolicy,
-			subMonitor.split(Math.max(1000-copiesLength, 0)));
-
-		// add type names from working copies
-		if (copies != null) {
-			for (int i = 0; i < copiesLength; i++) {
-				SubMonitor iterationMonitor = subMonitor.split(1);
-				final ICompilationUnit workingCopy = copies[i];
-				if (scope instanceof HierarchyScope) {
-					if (!((HierarchyScope)scope).encloses(workingCopy, iterationMonitor)) continue;
+			if (validatedTypeMatchRule == -1) return; // invalid match rule => return no results
+	
+			// Create pattern
+			IndexManager indexManager = JavaModelManager.getIndexManager();
+			final ConstructorDeclarationPattern pattern = new ConstructorDeclarationPattern(
+					packageName,
+					typeName,
+					validatedTypeMatchRule);
+	
+			// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+			final HashSet workingCopyPaths = new HashSet();
+			String workingCopyPath = null;
+			ICompilationUnit[] copies = getWorkingCopies();
+			final int copiesLength = copies == null ? 0 : copies.length;
+			if (copies != null) {
+				if (copiesLength == 1) {
+					workingCopyPath = copies[0].getPath().toString();
 				} else {
-					if (!scope.encloses(workingCopy)) continue;
+					for (int i = 0; i < copiesLength; i++) {
+						ICompilationUnit workingCopy = copies[i];
+						workingCopyPaths.add(workingCopy.getPath().toString());
+					}
 				}
-				
-				final String path = workingCopy.getPath().toString();
-				if (workingCopy.isConsistent()) {
-					IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
-					char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
-					IType[] allTypes = workingCopy.getAllTypes();
-					for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
-						IType type = allTypes[j];
-						char[] simpleName = type.getElementName().toCharArray();
-						if (match(NoSuffix, packageName, pkgMatchRule, typeName, validatedTypeMatchRule, 0/*no kind*/, packageDeclaration, simpleName) && !type.isMember()) {
-							
-							int extraFlags = ExtraFlags.getExtraFlags(type);
-							
-							boolean hasConstructor = false;
-							
-							IMethod[] methods = type.getMethods();
-							for (int k = 0; k < methods.length; k++) {
-								IMethod method = methods[k];
-								if (method.isConstructor()) {
-									hasConstructor = true;
-									
-									String[] stringParameterNames = method.getParameterNames();
-									String[] stringParameterTypes = method.getParameterTypes();
-									int length = stringParameterNames.length;
-									char[][] parameterNames = new char[length][];
-									char[][] parameterTypes = new char[length][];
-									for (int l = 0; l < length; l++) {
-										parameterNames[l] = stringParameterNames[l].toCharArray();
-										parameterTypes[l] = Signature.toCharArray(Signature.getTypeErasure(stringParameterTypes[l]).toCharArray());
+			}
+			final String singleWkcpPath = workingCopyPath;
+	
+			// Index requestor
+			IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+				public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+					// Filter unexpected types
+					ConstructorDeclarationPattern record = (ConstructorDeclarationPattern)indexRecord;
+					
+					if ((record.extraFlags & ExtraFlags.IsMemberType) != 0) {
+						return true; // filter out member classes
+					}
+					if ((record.extraFlags & ExtraFlags.IsLocalType) != 0) {
+						return true; // filter out local and anonymous classes
+					}
+					switch (copiesLength) {
+						case 0:
+							break;
+						case 1:
+							if (singleWkcpPath.equals(documentPath)) {
+								return true; // filter out *the* working copy
+							}
+							break;
+						default:
+							if (workingCopyPaths.contains(documentPath)) {
+								return true; // filter out working copies
+							}
+							break;
+					}
+	
+					// Accept document path
+					AccessRestriction accessRestriction = null;
+					if (access != null) {
+						// Compute document relative path
+						int pkgLength = (record.declaringPackageName==null || record.declaringPackageName.length==0) ? 0 : record.declaringPackageName.length+1;
+						int nameLength = record.declaringSimpleName==null ? 0 : record.declaringSimpleName.length;
+						char[] path = new char[pkgLength+nameLength];
+						int pos = 0;
+						if (pkgLength > 0) {
+							System.arraycopy(record.declaringPackageName, 0, path, pos, pkgLength-1);
+							CharOperation.replace(path, '.', '/');
+							path[pkgLength-1] = '/';
+							pos += pkgLength;
+						}
+						if (nameLength > 0) {
+							System.arraycopy(record.declaringSimpleName, 0, path, pos, nameLength);
+							pos += nameLength;
+						}
+						// Update access restriction if path is not empty
+						if (pos > 0) {
+							accessRestriction = access.getViolatedRestriction(path);
+						}
+					}
+					nameRequestor.acceptConstructor(
+							record.modifiers,
+							record.declaringSimpleName,
+							record.parameterCount,
+							record.signature,
+							record.parameterTypes,
+							record.parameterNames,
+							record.declaringTypeModifiers,
+							record.declaringPackageName,
+							record.extraFlags,
+							documentPath,
+							accessRestriction);
+					return true;
+				}
+			};
+	
+			SubMonitor subMonitor = SubMonitor.convert(progressMonitor, Messages.engine_searching, 1000);
+			// add type names from indexes
+			indexManager.performConcurrentJob(
+				new PatternSearchJob(
+					pattern,
+					getDefaultSearchParticipant(), // Java search only
+					scope,
+					searchRequestor),
+				waitingPolicy,
+				subMonitor.split(Math.max(1000-copiesLength, 0)));
+	
+			// add type names from working copies
+			if (copies != null) {
+				for (int i = 0; i < copiesLength; i++) {
+					SubMonitor iterationMonitor = subMonitor.split(1);
+					final ICompilationUnit workingCopy = copies[i];
+					if (scope instanceof HierarchyScope) {
+						if (!((HierarchyScope)scope).encloses(workingCopy, iterationMonitor)) continue;
+					} else {
+						if (!scope.encloses(workingCopy)) continue;
+					}
+					
+					final String path = workingCopy.getPath().toString();
+					if (workingCopy.isConsistent()) {
+						IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
+						char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
+						IType[] allTypes = workingCopy.getAllTypes();
+						for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
+							IType type = allTypes[j];
+							char[] simpleName = type.getElementName().toCharArray();
+							if (match(NoSuffix, packageName, pkgMatchRule, typeName, validatedTypeMatchRule, 0/*no kind*/, packageDeclaration, simpleName) && !type.isMember()) {
+								
+								int extraFlags = ExtraFlags.getExtraFlags(type);
+								
+								boolean hasConstructor = false;
+								
+								IMethod[] methods = type.getMethods();
+								for (int k = 0; k < methods.length; k++) {
+									IMethod method = methods[k];
+									if (method.isConstructor()) {
+										hasConstructor = true;
+										
+										String[] stringParameterNames = method.getParameterNames();
+										String[] stringParameterTypes = method.getParameterTypes();
+										int length = stringParameterNames.length;
+										char[][] parameterNames = new char[length][];
+										char[][] parameterTypes = new char[length][];
+										for (int l = 0; l < length; l++) {
+											parameterNames[l] = stringParameterNames[l].toCharArray();
+											parameterTypes[l] = Signature.toCharArray(Signature.getTypeErasure(stringParameterTypes[l]).toCharArray());
+										}
+										
+										nameRequestor.acceptConstructor(
+												method.getFlags(),
+												simpleName,
+												parameterNames.length,
+												null,// signature is not used for source type
+												parameterTypes, 
+												parameterNames,
+												type.getFlags(),
+												packageDeclaration,
+												extraFlags,
+												path,
+												null);
 									}
-									
+								}
+								
+								if (!hasConstructor) {
 									nameRequestor.acceptConstructor(
-											method.getFlags(),
+											Flags.AccPublic,
 											simpleName,
-											parameterNames.length,
-											null,// signature is not used for source type
-											parameterTypes, 
-											parameterNames,
+											-1,
+											null, // signature is not used for source type
+											CharOperation.NO_CHAR_CHAR,
+											CharOperation.NO_CHAR_CHAR,
 											type.getFlags(),
 											packageDeclaration,
 											extraFlags,
@@ -766,148 +786,137 @@
 											null);
 								}
 							}
-							
-							if (!hasConstructor) {
-								nameRequestor.acceptConstructor(
-										Flags.AccPublic,
-										simpleName,
-										-1,
-										null, // signature is not used for source type
-										CharOperation.NO_CHAR_CHAR,
-										CharOperation.NO_CHAR_CHAR,
-										type.getFlags(),
-										packageDeclaration,
-										extraFlags,
-										path,
-										null);
-							}
 						}
-					}
-				} else {
-					Parser basicParser = getParser();
-					org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
-					CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
-					CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
-					if (parsedUnit != null) {
-						final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
-						class AllConstructorDeclarationsVisitor extends ASTVisitor {
-							private TypeDeclaration[] declaringTypes = new TypeDeclaration[0];
-							private int declaringTypesPtr = -1;
-							
-							private void endVisit(TypeDeclaration typeDeclaration) {
-								if (!hasConstructor(typeDeclaration) && typeDeclaration.enclosingType == null) {
+					} else {
+						Parser basicParser = getParser();
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
+						CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
+						CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
+						if (parsedUnit != null) {
+							final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
+							class AllConstructorDeclarationsVisitor extends ASTVisitor {
+								private TypeDeclaration[] declaringTypes = new TypeDeclaration[0];
+								private int declaringTypesPtr = -1;
 								
+								private void endVisit(TypeDeclaration typeDeclaration) {
+									if (!hasConstructor(typeDeclaration) && typeDeclaration.enclosingType == null) {
+									
+										if (match(NoSuffix, packageName, pkgMatchRule, typeName, validatedTypeMatchRule, 0/*no kind*/, packageDeclaration, typeDeclaration.name)) {
+											nameRequestor.acceptConstructor(
+													Flags.AccPublic,
+													typeName,
+													-1,
+													null, // signature is not used for source type
+													CharOperation.NO_CHAR_CHAR,
+													CharOperation.NO_CHAR_CHAR,
+													typeDeclaration.modifiers,
+													packageDeclaration,
+													ExtraFlags.getExtraFlags(typeDeclaration),
+													path,
+													null);
+										}
+									}
+									
+									this.declaringTypes[this.declaringTypesPtr] = null;
+									this.declaringTypesPtr--;
+								}
+								
+								public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope s) {
+									endVisit(typeDeclaration);
+								}
+								
+								public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope s) {
+									endVisit(memberTypeDeclaration);
+								}
+								
+								private boolean hasConstructor(TypeDeclaration typeDeclaration) {
+									AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+									int length = methods == null ? 0 : methods.length;
+									for (int j = 0; j < length; j++) {
+										if (methods[j].isConstructor()) {
+											return true;
+										}
+									}
+									
+									return false;
+								}
+								public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope classScope) {
+									TypeDeclaration typeDeclaration = this.declaringTypes[this.declaringTypesPtr];
 									if (match(NoSuffix, packageName, pkgMatchRule, typeName, validatedTypeMatchRule, 0/*no kind*/, packageDeclaration, typeDeclaration.name)) {
+										Argument[] arguments = constructorDeclaration.arguments;
+										int length = arguments == null ? 0 : arguments.length;
+										char[][] parameterNames = new char[length][];
+										char[][] parameterTypes = new char[length][];
+										for (int l = 0; l < length; l++) {
+											Argument argument = arguments[l];
+											parameterNames[l] = argument.name;
+											if (argument.type instanceof SingleTypeReference) {
+												parameterTypes[l] = ((SingleTypeReference)argument.type).token;
+//{ObjectTeams: one more kind of type reference: (note that TypeAnchorReference cannot occur as an argument type)
+											} else if (argument.type instanceof LiftingTypeReference) {
+												parameterTypes[l] = CharOperation.concatWith(((LiftingTypeReference)argument.type).baseTokens, '.');
+//SH}
+											} else {
+												parameterTypes[l] = CharOperation.concatWith(((QualifiedTypeReference)argument.type).tokens, '.');
+											}
+										}
+										
+										TypeDeclaration enclosing = typeDeclaration.enclosingType;
+										char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+										while (enclosing != null) {
+											enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
+											if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
+												enclosing = enclosing.enclosingType;
+											} else {
+												enclosing = null;
+											}
+										}
+										
 										nameRequestor.acceptConstructor(
-												Flags.AccPublic,
+												constructorDeclaration.modifiers,
 												typeName,
-												-1,
+												parameterNames.length,
 												null, // signature is not used for source type
-												CharOperation.NO_CHAR_CHAR,
-												CharOperation.NO_CHAR_CHAR,
+												parameterTypes,
+												parameterNames,
 												typeDeclaration.modifiers,
 												packageDeclaration,
 												ExtraFlags.getExtraFlags(typeDeclaration),
 												path,
 												null);
 									}
+									return false; // no need to find constructors from local/anonymous type
+								}
+								public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+									return false; 
 								}
 								
-								this.declaringTypes[this.declaringTypesPtr] = null;
-								this.declaringTypesPtr--;
-							}
-							
-							public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope s) {
-								endVisit(typeDeclaration);
-							}
-							
-							public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope s) {
-								endVisit(memberTypeDeclaration);
-							}
-							
-							private boolean hasConstructor(TypeDeclaration typeDeclaration) {
-								AbstractMethodDeclaration[] methods = typeDeclaration.methods;
-								int length = methods == null ? 0 : methods.length;
-								for (int j = 0; j < length; j++) {
-									if (methods[j].isConstructor()) {
-										return true;
+								private boolean visit(TypeDeclaration typeDeclaration) {
+									if(this.declaringTypes.length <= ++this.declaringTypesPtr) {
+										int length = this.declaringTypesPtr;
+										System.arraycopy(this.declaringTypes, 0, this.declaringTypes = new TypeDeclaration[length * 2 + 1], 0, length);
 									}
+									this.declaringTypes[this.declaringTypesPtr] = typeDeclaration;
+									return true;
 								}
 								
-								return false;
-							}
-							public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope classScope) {
-								TypeDeclaration typeDeclaration = this.declaringTypes[this.declaringTypesPtr];
-								if (match(NoSuffix, packageName, pkgMatchRule, typeName, validatedTypeMatchRule, 0/*no kind*/, packageDeclaration, typeDeclaration.name)) {
-									Argument[] arguments = constructorDeclaration.arguments;
-									int length = arguments == null ? 0 : arguments.length;
-									char[][] parameterNames = new char[length][];
-									char[][] parameterTypes = new char[length][];
-									for (int l = 0; l < length; l++) {
-										Argument argument = arguments[l];
-										parameterNames[l] = argument.name;
-										if (argument.type instanceof SingleTypeReference) {
-											parameterTypes[l] = ((SingleTypeReference)argument.type).token;
-//{ObjectTeams: one more kind of type reference: (note that TypeAnchorReference cannot occur as an argument type)
-										} else if (argument.type instanceof LiftingTypeReference) {
-											parameterTypes[l] = CharOperation.concatWith(((LiftingTypeReference)argument.type).baseTokens, '.');
-//SH}
-										} else {
-											parameterTypes[l] = CharOperation.concatWith(((QualifiedTypeReference)argument.type).tokens, '.');
-										}
-									}
-									
-									TypeDeclaration enclosing = typeDeclaration.enclosingType;
-									char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
-									while (enclosing != null) {
-										enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
-										if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
-											enclosing = enclosing.enclosingType;
-										} else {
-											enclosing = null;
-										}
-									}
-									
-									nameRequestor.acceptConstructor(
-											constructorDeclaration.modifiers,
-											typeName,
-											parameterNames.length,
-											null, // signature is not used for source type
-											parameterTypes,
-											parameterNames,
-											typeDeclaration.modifiers,
-											packageDeclaration,
-											ExtraFlags.getExtraFlags(typeDeclaration),
-											path,
-											null);
+								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope s) {
+									return visit(typeDeclaration);
 								}
-								return false; // no need to find constructors from local/anonymous type
-							}
-							public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
-								return false; 
-							}
-							
-							private boolean visit(TypeDeclaration typeDeclaration) {
-								if(this.declaringTypes.length <= ++this.declaringTypesPtr) {
-									int length = this.declaringTypesPtr;
-									System.arraycopy(this.declaringTypes, 0, this.declaringTypes = new TypeDeclaration[length * 2 + 1], 0, length);
+								
+								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope s) {
+									return visit(memberTypeDeclaration);
 								}
-								this.declaringTypes[this.declaringTypesPtr] = typeDeclaration;
-								return true;
 							}
-							
-							public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope s) {
-								return visit(typeDeclaration);
-							}
-							
-							public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope s) {
-								return visit(memberTypeDeclaration);
-							}
+							parsedUnit.traverse(new AllConstructorDeclarationsVisitor(), parsedUnit.scope);
 						}
-						parsedUnit.traverse(new AllConstructorDeclarationsVisitor(), parsedUnit.scope);
 					}
 				}
 			}
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
 		}
 	}
 
@@ -1542,112 +1551,118 @@
 			boolean waitForIndexes,
 			IProgressMonitor progressMonitor)  throws JavaModelException {
 
-		if (VERBOSE) {
-			Util.verbose("BasicSearchEngine.searchAllSecondaryTypeNames(IPackageFragmentRoot[], IRestrictedAccessTypeRequestor, boolean, IProgressMonitor)"); //$NON-NLS-1$
-			StringBuffer buffer = new StringBuffer("	- source folders: "); //$NON-NLS-1$
-			int length = sourceFolders.length;
-			for (int i=0; i<length; i++) {
-				if (i==0) {
-					buffer.append('[');
-				} else {
-					buffer.append(',');
-				}
-				buffer.append(sourceFolders[i].getElementName());
-			}
-			buffer.append("]\n	- waitForIndexes: "); //$NON-NLS-1$
-			buffer.append(waitForIndexes);
-			Util.verbose(buffer.toString());
-		}
-
-		IndexManager indexManager = JavaModelManager.getIndexManager();
-		final TypeDeclarationPattern pattern = new SecondaryTypeDeclarationPattern();
-
-		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
-		final HashSet workingCopyPaths = new HashSet();
-		String workingCopyPath = null;
-		ICompilationUnit[] copies = getWorkingCopies();
-		final int copiesLength = copies == null ? 0 : copies.length;
-		if (copies != null) {
-			if (copiesLength == 1) {
-				workingCopyPath = copies[0].getPath().toString();
-			} else {
-				for (int i = 0; i < copiesLength; i++) {
-					ICompilationUnit workingCopy = copies[i];
-					workingCopyPaths.add(workingCopy.getPath().toString());
-				}
-			}
-		}
-		final String singleWkcpPath = workingCopyPath;
-
-		// Index requestor
-		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
-			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
-				// Filter unexpected types
-				TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
-				if (!record.secondary) {
-					return true; // filter maint types
-				}
-				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
-					return true; // filter out local and anonymous classes
-				}
-				switch (copiesLength) {
-					case 0:
-						break;
-					case 1:
-						if (singleWkcpPath.equals(documentPath)) {
-							return true; // fliter out *the* working copy
-						}
-						break;
-					default:
-						if (workingCopyPaths.contains(documentPath)) {
-							return true; // filter out working copies
-						}
-						break;
-				}
-
-				// Accept document path
-				AccessRestriction accessRestriction = null;
-				if (access != null) {
-					// Compute document relative path
-					int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
-					int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
-					char[] path = new char[pkgLength+nameLength];
-					int pos = 0;
-					if (pkgLength > 0) {
-						System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
-						CharOperation.replace(path, '.', '/');
-						path[pkgLength-1] = '/';
-						pos += pkgLength;
-					}
-					if (nameLength > 0) {
-						System.arraycopy(record.simpleName, 0, path, pos, nameLength);
-						pos += nameLength;
-					}
-					// Update access restriction if path is not empty
-					if (pos > 0) {
-						accessRestriction = access.getViolatedRestriction(path);
-					}
-				}
-				nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
-				return true;
-			}
-		};
-
-		// add type names from indexes
 		try {
-			SubMonitor subMonitor = SubMonitor.convert(progressMonitor, Messages.engine_searching, 100);
-			indexManager.performConcurrentJob(
-				new PatternSearchJob(
-					pattern,
-					getDefaultSearchParticipant(), // Java search only
-					createJavaSearchScope(sourceFolders),
-					searchRequestor),
-				waitForIndexes
-					? IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH
-					: IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH,
-				subMonitor.split(100));
-		} catch (OperationCanceledException oce) {
-			// do nothing
+			if (VERBOSE) {
+				Util.verbose("BasicSearchEngine.searchAllSecondaryTypeNames(IPackageFragmentRoot[], IRestrictedAccessTypeRequestor, boolean, IProgressMonitor)"); //$NON-NLS-1$
+				StringBuffer buffer = new StringBuffer("	- source folders: "); //$NON-NLS-1$
+				int length = sourceFolders.length;
+				for (int i=0; i<length; i++) {
+					if (i==0) {
+						buffer.append('[');
+					} else {
+						buffer.append(',');
+					}
+					buffer.append(sourceFolders[i].getElementName());
+				}
+				buffer.append("]\n	- waitForIndexes: "); //$NON-NLS-1$
+				buffer.append(waitForIndexes);
+				Util.verbose(buffer.toString());
+			}
+	
+			IndexManager indexManager = JavaModelManager.getIndexManager();
+			final TypeDeclarationPattern pattern = new SecondaryTypeDeclarationPattern();
+	
+			// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+			final HashSet workingCopyPaths = new HashSet();
+			String workingCopyPath = null;
+			ICompilationUnit[] copies = getWorkingCopies();
+			final int copiesLength = copies == null ? 0 : copies.length;
+			if (copies != null) {
+				if (copiesLength == 1) {
+					workingCopyPath = copies[0].getPath().toString();
+				} else {
+					for (int i = 0; i < copiesLength; i++) {
+						ICompilationUnit workingCopy = copies[i];
+						workingCopyPaths.add(workingCopy.getPath().toString());
+					}
+				}
+			}
+			final String singleWkcpPath = workingCopyPath;
+	
+			// Index requestor
+			IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+				public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+					// Filter unexpected types
+					TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
+					if (!record.secondary) {
+						return true; // filter maint types
+					}
+					if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
+						return true; // filter out local and anonymous classes
+					}
+					switch (copiesLength) {
+						case 0:
+							break;
+						case 1:
+							if (singleWkcpPath.equals(documentPath)) {
+								return true; // fliter out *the* working copy
+							}
+							break;
+						default:
+							if (workingCopyPaths.contains(documentPath)) {
+								return true; // filter out working copies
+							}
+							break;
+					}
+	
+					// Accept document path
+					AccessRestriction accessRestriction = null;
+					if (access != null) {
+						// Compute document relative path
+						int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
+						int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
+						char[] path = new char[pkgLength+nameLength];
+						int pos = 0;
+						if (pkgLength > 0) {
+							System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
+							CharOperation.replace(path, '.', '/');
+							path[pkgLength-1] = '/';
+							pos += pkgLength;
+						}
+						if (nameLength > 0) {
+							System.arraycopy(record.simpleName, 0, path, pos, nameLength);
+							pos += nameLength;
+						}
+						// Update access restriction if path is not empty
+						if (pos > 0) {
+							accessRestriction = access.getViolatedRestriction(path);
+						}
+					}
+					nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
+					return true;
+				}
+			};
+	
+			// add type names from indexes
+			try {
+				SubMonitor subMonitor = SubMonitor.convert(progressMonitor, Messages.engine_searching, 100);
+				indexManager.performConcurrentJob(
+					new PatternSearchJob(
+						pattern,
+						getDefaultSearchParticipant(), // Java search only
+						createJavaSearchScope(sourceFolders),
+						searchRequestor),
+					waitForIndexes
+						? IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH
+						: IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH,
+					subMonitor.split(100));
+			} catch (OperationCanceledException oce) {
+				// do nothing
+			}
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
 		}
 	}
 
@@ -1670,245 +1685,251 @@
 		int waitingPolicy,
 		IProgressMonitor progressMonitor)  throws JavaModelException {
 
-		// Validate match rule first
-		final int validatedTypeMatchRule = SearchPattern.validateMatchRule(typeName == null ? null : new String (typeName), typeMatchRule);
-
-		// Debug
-		if (VERBOSE) {
-			Util.verbose("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
-			Util.verbose("	- package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
-			Util.verbose("	- package match rule: "+getMatchRuleString(packageMatchRule)); //$NON-NLS-1$
-			Util.verbose("	- type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
-			Util.verbose("	- type match rule: "+getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
-			if (validatedTypeMatchRule != typeMatchRule) {
-				Util.verbose("	- validated type match rule: "+getMatchRuleString(validatedTypeMatchRule)); //$NON-NLS-1$
+		try {
+			// Validate match rule first
+			final int validatedTypeMatchRule = SearchPattern.validateMatchRule(typeName == null ? null : new String (typeName), typeMatchRule);
+	
+			// Debug
+			if (VERBOSE) {
+				Util.verbose("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+				Util.verbose("	- package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
+				Util.verbose("	- package match rule: "+getMatchRuleString(packageMatchRule)); //$NON-NLS-1$
+				Util.verbose("	- type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
+				Util.verbose("	- type match rule: "+getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
+				if (validatedTypeMatchRule != typeMatchRule) {
+					Util.verbose("	- validated type match rule: "+getMatchRuleString(validatedTypeMatchRule)); //$NON-NLS-1$
+				}
+				Util.verbose("	- search for: "+searchFor); //$NON-NLS-1$
+				Util.verbose("	- scope: "+scope); //$NON-NLS-1$
 			}
-			Util.verbose("	- search for: "+searchFor); //$NON-NLS-1$
-			Util.verbose("	- scope: "+scope); //$NON-NLS-1$
-		}
-		if (validatedTypeMatchRule == -1) return; // invalid match rule => return no results
-
-		// Create pattern
-		IndexManager indexManager = JavaModelManager.getIndexManager();
-		final char typeSuffix;
-		switch(searchFor){
-			case IJavaSearchConstants.CLASS :
-				typeSuffix = IIndexConstants.CLASS_SUFFIX;
-				break;
-			case IJavaSearchConstants.CLASS_AND_INTERFACE :
-				typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
-				break;
-			case IJavaSearchConstants.CLASS_AND_ENUM :
-				typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
-				break;
-			case IJavaSearchConstants.INTERFACE :
-				typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
-				break;
-			case IJavaSearchConstants.INTERFACE_AND_ANNOTATION :
-				typeSuffix = IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX;
-				break;
-			case IJavaSearchConstants.ENUM :
-				typeSuffix = IIndexConstants.ENUM_SUFFIX;
-				break;
-			case IJavaSearchConstants.ANNOTATION_TYPE :
-				typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
-				break;
-			default :
-				typeSuffix = IIndexConstants.TYPE_SUFFIX;
-				break;
-		}
-		final TypeDeclarationPattern pattern = packageMatchRule == SearchPattern.R_EXACT_MATCH
-			? new TypeDeclarationPattern(
-				packageName,
-				null,
-				typeName,
-				typeSuffix,
-				validatedTypeMatchRule)
-			: new QualifiedTypeDeclarationPattern(
-				packageName,
-				packageMatchRule,
-				typeName,
-				typeSuffix,
-				validatedTypeMatchRule);
-
-		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
-		final HashSet workingCopyPaths = new HashSet();
-		String workingCopyPath = null;
-		ICompilationUnit[] copies = getWorkingCopies();
-		final int copiesLength = copies == null ? 0 : copies.length;
-		if (copies != null) {
-			if (copiesLength == 1) {
-				workingCopyPath = copies[0].getPath().toString();
-			} else {
+			if (validatedTypeMatchRule == -1) return; // invalid match rule => return no results
+	
+			// Create pattern
+			IndexManager indexManager = JavaModelManager.getIndexManager();
+			final char typeSuffix;
+			switch(searchFor){
+				case IJavaSearchConstants.CLASS :
+					typeSuffix = IIndexConstants.CLASS_SUFFIX;
+					break;
+				case IJavaSearchConstants.CLASS_AND_INTERFACE :
+					typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
+					break;
+				case IJavaSearchConstants.CLASS_AND_ENUM :
+					typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
+					break;
+				case IJavaSearchConstants.INTERFACE :
+					typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
+					break;
+				case IJavaSearchConstants.INTERFACE_AND_ANNOTATION :
+					typeSuffix = IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX;
+					break;
+				case IJavaSearchConstants.ENUM :
+					typeSuffix = IIndexConstants.ENUM_SUFFIX;
+					break;
+				case IJavaSearchConstants.ANNOTATION_TYPE :
+					typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+					break;
+				default :
+					typeSuffix = IIndexConstants.TYPE_SUFFIX;
+					break;
+			}
+			final TypeDeclarationPattern pattern = packageMatchRule == SearchPattern.R_EXACT_MATCH
+				? new TypeDeclarationPattern(
+					packageName,
+					null,
+					typeName,
+					typeSuffix,
+					validatedTypeMatchRule)
+				: new QualifiedTypeDeclarationPattern(
+					packageName,
+					packageMatchRule,
+					typeName,
+					typeSuffix,
+					validatedTypeMatchRule);
+	
+			// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+			final HashSet workingCopyPaths = new HashSet();
+			String workingCopyPath = null;
+			ICompilationUnit[] copies = getWorkingCopies();
+			final int copiesLength = copies == null ? 0 : copies.length;
+			if (copies != null) {
+				if (copiesLength == 1) {
+					workingCopyPath = copies[0].getPath().toString();
+				} else {
+					for (int i = 0; i < copiesLength; i++) {
+						ICompilationUnit workingCopy = copies[i];
+						workingCopyPaths.add(workingCopy.getPath().toString());
+					}
+				}
+			}
+			final String singleWkcpPath = workingCopyPath;
+	
+			// Index requestor
+			IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+				public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+					// Filter unexpected types
+					TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
+					if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
+						return true; // filter out local and anonymous classes
+					}
+					switch (copiesLength) {
+						case 0:
+							break;
+						case 1:
+							if (singleWkcpPath.equals(documentPath)) {
+								return true; // filter out *the* working copy
+							}
+							break;
+						default:
+							if (workingCopyPaths.contains(documentPath)) {
+								return true; // filter out working copies
+							}
+							break;
+					}
+	
+					// Accept document path
+					AccessRestriction accessRestriction = null;
+					if (access != null) {
+						// Compute document relative path
+						int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
+						int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
+						char[] path = new char[pkgLength+nameLength];
+						int pos = 0;
+						if (pkgLength > 0) {
+							System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
+							CharOperation.replace(path, '.', '/');
+							path[pkgLength-1] = '/';
+							pos += pkgLength;
+						}
+						if (nameLength > 0) {
+							System.arraycopy(record.simpleName, 0, path, pos, nameLength);
+							pos += nameLength;
+						}
+						// Update access restriction if path is not empty
+						if (pos > 0) {
+							accessRestriction = access.getViolatedRestriction(path);
+						}
+					}
+					if (match(record.typeSuffix, record.modifiers)) {
+						nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
+					}
+					return true;
+				}
+			};
+	
+			SubMonitor subMonitor = SubMonitor.convert(progressMonitor, Messages.engine_searching, 1000);
+			// add type names from indexes
+			indexManager.performConcurrentJob(
+				new PatternSearchJob(
+					pattern,
+					getDefaultSearchParticipant(), // Java search only
+					scope,
+					searchRequestor),
+				waitingPolicy,
+				subMonitor.split(Math.max(1000-copiesLength, 0)));
+	
+			// add type names from working copies
+			if (copies != null) {
 				for (int i = 0; i < copiesLength; i++) {
-					ICompilationUnit workingCopy = copies[i];
-					workingCopyPaths.add(workingCopy.getPath().toString());
-				}
-			}
-		}
-		final String singleWkcpPath = workingCopyPath;
-
-		// Index requestor
-		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
-			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
-				// Filter unexpected types
-				TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
-				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
-					return true; // filter out local and anonymous classes
-				}
-				switch (copiesLength) {
-					case 0:
-						break;
-					case 1:
-						if (singleWkcpPath.equals(documentPath)) {
-							return true; // filter out *the* working copy
-						}
-						break;
-					default:
-						if (workingCopyPaths.contains(documentPath)) {
-							return true; // filter out working copies
-						}
-						break;
-				}
-
-				// Accept document path
-				AccessRestriction accessRestriction = null;
-				if (access != null) {
-					// Compute document relative path
-					int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
-					int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
-					char[] path = new char[pkgLength+nameLength];
-					int pos = 0;
-					if (pkgLength > 0) {
-						System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
-						CharOperation.replace(path, '.', '/');
-						path[pkgLength-1] = '/';
-						pos += pkgLength;
+					SubMonitor iterationMonitor = subMonitor.split(i);
+					final ICompilationUnit workingCopy = copies[i];
+					if (scope instanceof HierarchyScope) {
+						if (!((HierarchyScope)scope).encloses(workingCopy, iterationMonitor)) continue;
+					} else {
+						if (!scope.encloses(workingCopy)) continue;
 					}
-					if (nameLength > 0) {
-						System.arraycopy(record.simpleName, 0, path, pos, nameLength);
-						pos += nameLength;
-					}
-					// Update access restriction if path is not empty
-					if (pos > 0) {
-						accessRestriction = access.getViolatedRestriction(path);
-					}
-				}
-				if (match(record.typeSuffix, record.modifiers)) {
-					nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
-				}
-				return true;
-			}
-		};
-
-		SubMonitor subMonitor = SubMonitor.convert(progressMonitor, Messages.engine_searching, 1000);
-		// add type names from indexes
-		indexManager.performConcurrentJob(
-			new PatternSearchJob(
-				pattern,
-				getDefaultSearchParticipant(), // Java search only
-				scope,
-				searchRequestor),
-			waitingPolicy,
-			subMonitor.split(Math.max(1000-copiesLength, 0)));
-
-		// add type names from working copies
-		if (copies != null) {
-			for (int i = 0; i < copiesLength; i++) {
-				SubMonitor iterationMonitor = subMonitor.split(i);
-				final ICompilationUnit workingCopy = copies[i];
-				if (scope instanceof HierarchyScope) {
-					if (!((HierarchyScope)scope).encloses(workingCopy, iterationMonitor)) continue;
-				} else {
-					if (!scope.encloses(workingCopy)) continue;
-				}
-				final String path = workingCopy.getPath().toString();
-				if (workingCopy.isConsistent()) {
-					IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
-					char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
-					IType[] allTypes = workingCopy.getAllTypes();
-					for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
-						IType type = allTypes[j];
-						IJavaElement parent = type.getParent();
-						char[][] enclosingTypeNames;
-						if (parent instanceof IType) {
-							char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray();
-							enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName);
-						} else {
-							enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
-						}
-						char[] simpleName = type.getElementName().toCharArray();
-						int kind;
-						if (type.isEnum()) {
-							kind = TypeDeclaration.ENUM_DECL;
-						} else if (type.isAnnotation()) {
-							kind = TypeDeclaration.ANNOTATION_TYPE_DECL;
-						}	else if (type.isClass()) {
-							kind = TypeDeclaration.CLASS_DECL;
-						} else /*if (type.isInterface())*/ {
-							kind = TypeDeclaration.INTERFACE_DECL;
-						}
-						if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, kind, packageDeclaration, simpleName)) {
-							if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
-								((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, type.getFlags()));
+					final String path = workingCopy.getPath().toString();
+					if (workingCopy.isConsistent()) {
+						IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
+						char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
+						IType[] allTypes = workingCopy.getAllTypes();
+						for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
+							IType type = allTypes[j];
+							IJavaElement parent = type.getParent();
+							char[][] enclosingTypeNames;
+							if (parent instanceof IType) {
+								char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray();
+								enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName);
 							} else {
-								nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
+								enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+							}
+							char[] simpleName = type.getElementName().toCharArray();
+							int kind;
+							if (type.isEnum()) {
+								kind = TypeDeclaration.ENUM_DECL;
+							} else if (type.isAnnotation()) {
+								kind = TypeDeclaration.ANNOTATION_TYPE_DECL;
+							}	else if (type.isClass()) {
+								kind = TypeDeclaration.CLASS_DECL;
+							} else /*if (type.isInterface())*/ {
+								kind = TypeDeclaration.INTERFACE_DECL;
+							}
+							if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, kind, packageDeclaration, simpleName)) {
+								if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
+									((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, type.getFlags()));
+								} else {
+									nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
+								}
 							}
 						}
-					}
-				} else {
-					Parser basicParser = getParser();
-					org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
-					CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
-					CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
-					if (parsedUnit != null) {
-						final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
-						class AllTypeDeclarationsVisitor extends ASTVisitor {
-							public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
-								return false; // no local/anonymous type
-							}
-							public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
-								if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, TypeDeclaration.kind(typeDeclaration.modifiers), packageDeclaration, typeDeclaration.name)) {
-									if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
-										IType type = workingCopy.getType(new String(typeName));
-										((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, typeDeclaration.modifiers));
-									} else {
-										nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
-									}
+					} else {
+						Parser basicParser = getParser();
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
+						CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
+						CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
+						if (parsedUnit != null) {
+							final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
+							class AllTypeDeclarationsVisitor extends ASTVisitor {
+								public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+									return false; // no local/anonymous type
 								}
-								return true;
-							}
-							public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
-								if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, TypeDeclaration.kind(memberTypeDeclaration.modifiers), packageDeclaration, memberTypeDeclaration.name)) {
-									// compute enclosing type names
-									TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
-									char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
-									while (enclosing != null) {
-										enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
-										if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
-											enclosing = enclosing.enclosingType;
+								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
+									if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, TypeDeclaration.kind(typeDeclaration.modifiers), packageDeclaration, typeDeclaration.name)) {
+										if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
+											IType type = workingCopy.getType(new String(typeName));
+											((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, typeDeclaration.modifiers));
 										} else {
-											enclosing = null;
+											nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
 										}
 									}
-									// report
-									if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
-										IType type = workingCopy.getType(new String(enclosingTypeNames[0]));
-										for (int j=1, l=enclosingTypeNames.length; j<l; j++) {
-											type = type.getType(new String(enclosingTypeNames[j]));
-										}
-										((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, 0));
-									} else {
-										nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
-									}
+									return true;
 								}
-								return true;
+								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
+									if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, TypeDeclaration.kind(memberTypeDeclaration.modifiers), packageDeclaration, memberTypeDeclaration.name)) {
+										// compute enclosing type names
+										TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
+										char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+										while (enclosing != null) {
+											enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
+											if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
+												enclosing = enclosing.enclosingType;
+											} else {
+												enclosing = null;
+											}
+										}
+										// report
+										if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
+											IType type = workingCopy.getType(new String(enclosingTypeNames[0]));
+											for (int j=1, l=enclosingTypeNames.length; j<l; j++) {
+												type = type.getType(new String(enclosingTypeNames[j]));
+											}
+											((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, 0));
+										} else {
+											nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
+										}
+									}
+									return true;
+								}
 							}
+							parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope);
 						}
-						parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope);
 					}
 				}
 			}
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
 		}
 	}
 
@@ -1929,266 +1950,278 @@
 		int waitingPolicy,
 		IProgressMonitor progressMonitor)  throws JavaModelException {
 
-		// Debug
-		if (VERBOSE) {
-			Util.verbose("BasicSearchEngine.searchAllTypeNames(char[][], char[][], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
-			Util.verbose("	- package name: "+(qualifications==null?"null":new String(CharOperation.concatWith(qualifications, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
-			Util.verbose("	- type name: "+(typeNames==null?"null":new String(CharOperation.concatWith(typeNames, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
-			Util.verbose("	- match rule: "+getMatchRuleString(matchRule)); //$NON-NLS-1$
-			Util.verbose("	- search for: "+searchFor); //$NON-NLS-1$
-			Util.verbose("	- scope: "+scope); //$NON-NLS-1$
-		}
-		IndexManager indexManager = JavaModelManager.getIndexManager();
-
-		// Create pattern
-		final char typeSuffix;
-		switch(searchFor){
-			case IJavaSearchConstants.CLASS :
-				typeSuffix = IIndexConstants.CLASS_SUFFIX;
-				break;
-			case IJavaSearchConstants.CLASS_AND_INTERFACE :
-				typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
-				break;
-			case IJavaSearchConstants.CLASS_AND_ENUM :
-				typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
-				break;
-			case IJavaSearchConstants.INTERFACE :
-				typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
-				break;
-			case IJavaSearchConstants.INTERFACE_AND_ANNOTATION :
-				typeSuffix = IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX;
-				break;
-			case IJavaSearchConstants.ENUM :
-				typeSuffix = IIndexConstants.ENUM_SUFFIX;
-				break;
-			case IJavaSearchConstants.ANNOTATION_TYPE :
-				typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
-				break;
-			default :
-				typeSuffix = IIndexConstants.TYPE_SUFFIX;
-				break;
-		}
-		final MultiTypeDeclarationPattern pattern = new MultiTypeDeclarationPattern(qualifications, typeNames, typeSuffix, matchRule);
-
-		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
-		final HashSet workingCopyPaths = new HashSet();
-		String workingCopyPath = null;
-		ICompilationUnit[] copies = getWorkingCopies();
-		final int copiesLength = copies == null ? 0 : copies.length;
-		if (copies != null) {
-			if (copiesLength == 1) {
-				workingCopyPath = copies[0].getPath().toString();
-			} else {
-				for (int i = 0; i < copiesLength; i++) {
-					ICompilationUnit workingCopy = copies[i];
-					workingCopyPaths.add(workingCopy.getPath().toString());
-				}
+		try {
+			// Debug
+			if (VERBOSE) {
+				Util.verbose("BasicSearchEngine.searchAllTypeNames(char[][], char[][], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+				Util.verbose("	- package name: "+(qualifications==null?"null":new String(CharOperation.concatWith(qualifications, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
+				Util.verbose("	- type name: "+(typeNames==null?"null":new String(CharOperation.concatWith(typeNames, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
+				Util.verbose("	- match rule: "+getMatchRuleString(matchRule)); //$NON-NLS-1$
+				Util.verbose("	- search for: "+searchFor); //$NON-NLS-1$
+				Util.verbose("	- scope: "+scope); //$NON-NLS-1$
 			}
-		}
-		final String singleWkcpPath = workingCopyPath;
-
-		// Index requestor
-		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
-			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
-				// Filter unexpected types
-				QualifiedTypeDeclarationPattern record = (QualifiedTypeDeclarationPattern) indexRecord;
-				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
-					return true; // filter out local and anonymous classes
-				}
-				switch (copiesLength) {
-					case 0:
-						break;
-					case 1:
-						if (singleWkcpPath.equals(documentPath)) {
-							return true; // filter out *the* working copy
-						}
-						break;
-					default:
-						if (workingCopyPaths.contains(documentPath)) {
-							return true; // filter out working copies
-						}
-						break;
-				}
-
-				// Accept document path
-				AccessRestriction accessRestriction = null;
-				if (access != null) {
-					// Compute document relative path
-					int qualificationLength = (record.qualification == null || record.qualification.length == 0) ? 0 : record.qualification.length + 1;
-					int nameLength = record.simpleName == null ? 0 : record.simpleName.length;
-					char[] path = new char[qualificationLength + nameLength];
-					int pos = 0;
-					if (qualificationLength > 0) {
-						System.arraycopy(record.qualification, 0, path, pos, qualificationLength - 1);
-						CharOperation.replace(path, '.', '/');
-
-						// Access rules work on package level and should not discriminate on enclosing types.
-						boolean isNestedType = record.enclosingTypeNames != null && record.enclosingTypeNames.length > 0;
-						path[qualificationLength-1] = isNestedType ? '$' : '/';
-						pos += qualificationLength;
-					}
-					if (nameLength > 0) {
-						System.arraycopy(record.simpleName, 0, path, pos, nameLength);
-						pos += nameLength;
-					}
-					// Update access restriction if path is not empty
-					if (pos > 0) {
-						accessRestriction = access.getViolatedRestriction(path);
-					}
-				}
-				nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
-				return true;
+			IndexManager indexManager = JavaModelManager.getIndexManager();
+	
+			// Create pattern
+			final char typeSuffix;
+			switch(searchFor){
+				case IJavaSearchConstants.CLASS :
+					typeSuffix = IIndexConstants.CLASS_SUFFIX;
+					break;
+				case IJavaSearchConstants.CLASS_AND_INTERFACE :
+					typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
+					break;
+				case IJavaSearchConstants.CLASS_AND_ENUM :
+					typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
+					break;
+				case IJavaSearchConstants.INTERFACE :
+					typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
+					break;
+				case IJavaSearchConstants.INTERFACE_AND_ANNOTATION :
+					typeSuffix = IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX;
+					break;
+				case IJavaSearchConstants.ENUM :
+					typeSuffix = IIndexConstants.ENUM_SUFFIX;
+					break;
+				case IJavaSearchConstants.ANNOTATION_TYPE :
+					typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+					break;
+				default :
+					typeSuffix = IIndexConstants.TYPE_SUFFIX;
+					break;
 			}
-		};
-
-		SubMonitor subMonitor = SubMonitor.convert(progressMonitor, Messages.engine_searching, 100);
-		// add type names from indexes
-		indexManager.performConcurrentJob(
-			new PatternSearchJob(
-				pattern,
-				getDefaultSearchParticipant(), // Java search only
-				scope,
-				searchRequestor),
-			waitingPolicy,
-			subMonitor.split(100));
-
-		// add type names from working copies
-		if (copies != null) {
-			for (int i = 0, length = copies.length; i < length; i++) {
-				ICompilationUnit workingCopy = copies[i];
-				final String path = workingCopy.getPath().toString();
-				if (workingCopy.isConsistent()) {
-					IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
-					char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
-					IType[] allTypes = workingCopy.getAllTypes();
-					for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
-						IType type = allTypes[j];
-						IJavaElement parent = type.getParent();
-						char[][] enclosingTypeNames;
-						char[] qualification = packageDeclaration;
-						if (parent instanceof IType) {
-							char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray();
-							enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName);
-							qualification = CharOperation.concat(qualification, parentQualifiedName);
-						} else {
-							enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
-						}
-						char[] simpleName = type.getElementName().toCharArray();
-						char suffix = IIndexConstants.TYPE_SUFFIX;
-						if (type.isClass()) {
-							suffix = IIndexConstants.CLASS_SUFFIX;
-						} else if (type.isInterface()) {
-							suffix = IIndexConstants.INTERFACE_SUFFIX;
-						} else if (type.isEnum()) {
-							suffix = IIndexConstants.ENUM_SUFFIX;
-						} else if (type.isAnnotation()) {
-							suffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
-						}
-						if (pattern.matchesDecodedKey(new QualifiedTypeDeclarationPattern(qualification, simpleName, suffix, matchRule))) {
-							nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
-						}
-					}
+			final MultiTypeDeclarationPattern pattern = new MultiTypeDeclarationPattern(qualifications, typeNames, typeSuffix, matchRule);
+	
+			// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+			final HashSet workingCopyPaths = new HashSet();
+			String workingCopyPath = null;
+			ICompilationUnit[] copies = getWorkingCopies();
+			final int copiesLength = copies == null ? 0 : copies.length;
+			if (copies != null) {
+				if (copiesLength == 1) {
+					workingCopyPath = copies[0].getPath().toString();
 				} else {
-					Parser basicParser = getParser();
-					org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
-					CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
-					CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
-					if (parsedUnit != null) {
-						final char[] packageDeclaration = parsedUnit.currentPackage == null
-							? CharOperation.NO_CHAR
-							: CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
-						class AllTypeDeclarationsVisitor extends ASTVisitor {
-							public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
-								return false; // no local/anonymous type
-							}
-							public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
-								SearchPattern decodedPattern =
-									new QualifiedTypeDeclarationPattern(packageDeclaration, typeDeclaration.name, convertTypeKind(TypeDeclaration.kind(typeDeclaration.modifiers)), matchRule);
-								if (pattern.matchesDecodedKey(decodedPattern)) {
-									nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
-								}
-								return true;
-							}
-							public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
-								// compute enclosing type names
-								char[] qualification = packageDeclaration;
-								TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
-								char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
-								while (enclosing != null) {
-									qualification = CharOperation.concat(qualification, enclosing.name, '.');
-									enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
-									if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
-										enclosing = enclosing.enclosingType;
-									} else {
-										enclosing = null;
-									}
-								}
-								SearchPattern decodedPattern =
-									new QualifiedTypeDeclarationPattern(qualification, memberTypeDeclaration.name, convertTypeKind(TypeDeclaration.kind(memberTypeDeclaration.modifiers)), matchRule);
-								if (pattern.matchesDecodedKey(decodedPattern)) {
-									nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
-								}
-								return true;
-							}
-						}
-						parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope);
+					for (int i = 0; i < copiesLength; i++) {
+						ICompilationUnit workingCopy = copies[i];
+						workingCopyPaths.add(workingCopy.getPath().toString());
 					}
 				}
 			}
+			final String singleWkcpPath = workingCopyPath;
+	
+			// Index requestor
+			IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+				public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+					// Filter unexpected types
+					QualifiedTypeDeclarationPattern record = (QualifiedTypeDeclarationPattern) indexRecord;
+					if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
+						return true; // filter out local and anonymous classes
+					}
+					switch (copiesLength) {
+						case 0:
+							break;
+						case 1:
+							if (singleWkcpPath.equals(documentPath)) {
+								return true; // filter out *the* working copy
+							}
+							break;
+						default:
+							if (workingCopyPaths.contains(documentPath)) {
+								return true; // filter out working copies
+							}
+							break;
+					}
+	
+					// Accept document path
+					AccessRestriction accessRestriction = null;
+					if (access != null) {
+						// Compute document relative path
+						int qualificationLength = (record.qualification == null || record.qualification.length == 0) ? 0 : record.qualification.length + 1;
+						int nameLength = record.simpleName == null ? 0 : record.simpleName.length;
+						char[] path = new char[qualificationLength + nameLength];
+						int pos = 0;
+						if (qualificationLength > 0) {
+							System.arraycopy(record.qualification, 0, path, pos, qualificationLength - 1);
+							CharOperation.replace(path, '.', '/');
+	
+							// Access rules work on package level and should not discriminate on enclosing types.
+							boolean isNestedType = record.enclosingTypeNames != null && record.enclosingTypeNames.length > 0;
+							path[qualificationLength-1] = isNestedType ? '$' : '/';
+							pos += qualificationLength;
+						}
+						if (nameLength > 0) {
+							System.arraycopy(record.simpleName, 0, path, pos, nameLength);
+							pos += nameLength;
+						}
+						// Update access restriction if path is not empty
+						if (pos > 0) {
+							accessRestriction = access.getViolatedRestriction(path);
+						}
+					}
+					nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
+					return true;
+				}
+			};
+	
+			SubMonitor subMonitor = SubMonitor.convert(progressMonitor, Messages.engine_searching, 100);
+			// add type names from indexes
+			indexManager.performConcurrentJob(
+				new PatternSearchJob(
+					pattern,
+					getDefaultSearchParticipant(), // Java search only
+					scope,
+					searchRequestor),
+				waitingPolicy,
+				subMonitor.split(100));
+	
+			// add type names from working copies
+			if (copies != null) {
+				for (int i = 0, length = copies.length; i < length; i++) {
+					ICompilationUnit workingCopy = copies[i];
+					final String path = workingCopy.getPath().toString();
+					if (workingCopy.isConsistent()) {
+						IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
+						char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
+						IType[] allTypes = workingCopy.getAllTypes();
+						for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
+							IType type = allTypes[j];
+							IJavaElement parent = type.getParent();
+							char[][] enclosingTypeNames;
+							char[] qualification = packageDeclaration;
+							if (parent instanceof IType) {
+								char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray();
+								enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName);
+								qualification = CharOperation.concat(qualification, parentQualifiedName);
+							} else {
+								enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+							}
+							char[] simpleName = type.getElementName().toCharArray();
+							char suffix = IIndexConstants.TYPE_SUFFIX;
+							if (type.isClass()) {
+								suffix = IIndexConstants.CLASS_SUFFIX;
+							} else if (type.isInterface()) {
+								suffix = IIndexConstants.INTERFACE_SUFFIX;
+							} else if (type.isEnum()) {
+								suffix = IIndexConstants.ENUM_SUFFIX;
+							} else if (type.isAnnotation()) {
+								suffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+							}
+							if (pattern.matchesDecodedKey(new QualifiedTypeDeclarationPattern(qualification, simpleName, suffix, matchRule))) {
+								nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
+							}
+						}
+					} else {
+						Parser basicParser = getParser();
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
+						CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
+						CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
+						if (parsedUnit != null) {
+							final char[] packageDeclaration = parsedUnit.currentPackage == null
+								? CharOperation.NO_CHAR
+								: CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
+							class AllTypeDeclarationsVisitor extends ASTVisitor {
+								public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+									return false; // no local/anonymous type
+								}
+								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
+									SearchPattern decodedPattern =
+										new QualifiedTypeDeclarationPattern(packageDeclaration, typeDeclaration.name, convertTypeKind(TypeDeclaration.kind(typeDeclaration.modifiers)), matchRule);
+									if (pattern.matchesDecodedKey(decodedPattern)) {
+										nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
+									}
+									return true;
+								}
+								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
+									// compute enclosing type names
+									char[] qualification = packageDeclaration;
+									TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
+									char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+									while (enclosing != null) {
+										qualification = CharOperation.concat(qualification, enclosing.name, '.');
+										enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
+										if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
+											enclosing = enclosing.enclosingType;
+										} else {
+											enclosing = null;
+										}
+									}
+									SearchPattern decodedPattern =
+										new QualifiedTypeDeclarationPattern(qualification, memberTypeDeclaration.name, convertTypeKind(TypeDeclaration.kind(memberTypeDeclaration.modifiers)), matchRule);
+									if (pattern.matchesDecodedKey(decodedPattern)) {
+										nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
+									}
+									return true;
+								}
+							}
+							parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope);
+						}
+					}
+				}
+			}
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
 		}
 	}
 
 	public void searchDeclarations(IJavaElement enclosingElement, SearchRequestor requestor, SearchPattern pattern, IProgressMonitor monitor) throws JavaModelException {
-		if (VERBOSE) {
-			Util.verbose("	- java element: "+enclosingElement); //$NON-NLS-1$
-		}
-		IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[] {enclosingElement});
-		IResource resource = ((JavaElement) enclosingElement).resource();
-		if (enclosingElement instanceof IMember) {
-			IMember member = (IMember) enclosingElement;
-			ICompilationUnit cu = member.getCompilationUnit();
-			if (cu != null) {
-				resource = cu.getResource();
-			} else if (member.isBinary()) {
-				// binary member resource cannot be used as this
-				// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=148215
-				resource = null;
-			}
-		}
 		try {
-			if (resource instanceof IFile) {
-				try {
-					requestor.beginReporting();
-					if (VERBOSE) {
-						Util.verbose("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
+			if (VERBOSE) {
+				Util.verbose("	- java element: "+enclosingElement); //$NON-NLS-1$
+			}
+			IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[] {enclosingElement});
+			IResource resource = ((JavaElement) enclosingElement).resource();
+			if (enclosingElement instanceof IMember) {
+				IMember member = (IMember) enclosingElement;
+				ICompilationUnit cu = member.getCompilationUnit();
+				if (cu != null) {
+					resource = cu.getResource();
+				} else if (member.isBinary()) {
+					// binary member resource cannot be used as this
+					// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=148215
+					resource = null;
+				}
+			}
+			try {
+				if (resource instanceof IFile) {
+					try {
+						requestor.beginReporting();
+						if (VERBOSE) {
+							Util.verbose("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
+						}
+						SearchParticipant participant = getDefaultSearchParticipant();
+						SearchDocument[] documents = MatchLocator.addWorkingCopies(
+							pattern,
+							new SearchDocument[] {new JavaSearchDocument(enclosingElement.getPath().toString(), participant)},
+							getWorkingCopies(enclosingElement),
+							participant);
+						participant.locateMatches(
+							documents,
+							pattern,
+							scope,
+							requestor,
+							monitor);
+					} finally {
+						requestor.endReporting();
 					}
-					SearchParticipant participant = getDefaultSearchParticipant();
-					SearchDocument[] documents = MatchLocator.addWorkingCopies(
+				} else {
+					search(
 						pattern,
-						new SearchDocument[] {new JavaSearchDocument(enclosingElement.getPath().toString(), participant)},
-						getWorkingCopies(enclosingElement),
-						participant);
-					participant.locateMatches(
-						documents,
-						pattern,
+						new SearchParticipant[] {getDefaultSearchParticipant()},
 						scope,
 						requestor,
 						monitor);
-				} finally {
-					requestor.endReporting();
 				}
-			} else {
-				search(
-					pattern,
-					new SearchParticipant[] {getDefaultSearchParticipant()},
-					scope,
-					requestor,
-					monitor);
+			} catch (CoreException e) {
+				if (e instanceof JavaModelException)
+					throw (JavaModelException) e;
+				throw new JavaModelException(e);
 			}
-		} catch (CoreException e) {
-			if (e instanceof JavaModelException)
-				throw (JavaModelException) e;
-			throw new JavaModelException(e);
+		} finally {
+			if (monitor != null) {
+				monitor.done();
+			}
 		}
 	}
 
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
index 4626c37..4771e86 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
@@ -264,6 +264,9 @@
 			}
 			status = searchJob.execute(subMonitor);
 		} finally {
+			if (progress != null) {
+				progress.done();
+			}
 			if (VERBOSE)
 				Util.verbose("FINISHED  concurrent job - " + searchJob); //$NON-NLS-1$
 		}