Update jdt.core to S4_15_0_M3
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 376e4b3..7390e53 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, 2019 GK Software AG, and others.
+ * Copyright (c) 2013, 2020 GK Software AG, and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -10060,4 +10060,108 @@
 			};
 		runner.runConformTest();
 	}
+	public void testBug559677() {
+		Runner runner = new Runner();
+		runner.testFiles = new String[] {
+			"MyClass.java",
+			"public class MyClass {\n" + 
+			"	private void myRun() {\n" + 
+			"	}\n" + 
+			"	private void myMethod(final Runnable r) {\n" + 
+			"	}\n" + 
+			"	public void test() {\n" + 
+			"		// second opening brace causes endless loop while saving\n" + 
+			"		myMethod((this::myRun);\n" + 
+			"	}\n" + 
+			"}\n"
+		};
+		runner.performStatementsRecovery = true;
+		runner.expectedCompilerLog =
+			"----------\n" + 
+			"1. ERROR in MyClass.java (at line 8)\n" + 
+			"	myMethod((this::myRun);\n" + 
+			"	                     ^\n" + 
+			"Syntax error, insert \")\" to complete Expression\n" + 
+			"----------\n";
+		runner.runNegativeTest();
+	}
+	public void testBug559951() {
+		if (this.complianceLevel < ClassFileConstants.JDK10) return; // uses 'var'
+		runConformTest(
+			new String[] {
+				"no/Demo.java",
+				"package no;\n" +
+				"public class Demo {\n" +
+				"	static void broken_method_dispatch_on_bounded_type_in_lambda_argument_with_Eclipse_compiler() {\n" + 
+				"		WithMessageRecipients withRecipients = new Message(new EmailRecipient(\"Jane\", \"jane@example.com\"), new EmailRecipient(\"Joe\", \"joe@example.com\"));\n" + 
+				"\n" + 
+				"		withRecipients.getMessageRecipients()\n" + 
+				"			.stream()\n" + 
+				"			.forEach(recipient -> System.out.println(recipient.getName() + \" <\" + recipient.getEmailAddress() + \">\"));\n" + 
+				"	}\n" + 
+				"	static void works_fine_in_for_loop() {\n" + 
+				"		WithMessageRecipients withRecipients = new Message(new EmailRecipient(\"Jane\", \"jane@example.com\"), new EmailRecipient(\"Joe\", \"joe@example.com\"));\n" + 
+				"\n" + 
+				"		for (var recipient : withRecipients.getMessageRecipients()) {\n" + 
+				"			System.out.println(recipient.getName() + \" <\" + recipient.getEmailAddress() + \">\");\n" + 
+				"		}\n" + 
+				"	}\n" +
+				"	public static void main(String... args) {\n" +
+				"		works_fine_in_for_loop();\n" +
+				"		broken_method_dispatch_on_bounded_type_in_lambda_argument_with_Eclipse_compiler();\n" +
+				"	}\n" +
+				"}\n",
+				"no/WithName.java",
+				"package no;\n" + 
+				"public interface WithName {\n" + 
+				"	String getName();\n" + 
+				"}",
+				"no/WithEmailAddress.java",
+				"package no;\n" + 
+				"public interface WithEmailAddress {\n" + 
+				"	String getEmailAddress();\n" + 
+				"}\n",
+				"no/WithMessageRecipients.java",
+				"package no;\n" + 
+				"import java.util.List;\n" + 
+				"public interface WithMessageRecipients {\n" + 
+				"	<CONTACT extends WithName & WithEmailAddress> List<? extends CONTACT> getMessageRecipients();\n" + 
+				"}",
+				"no/EmailRecipient.java",
+				"package no;\n" + 
+				"public class EmailRecipient implements WithName, WithEmailAddress {\n" + 
+				"	private final String name;\n" + 
+				"	private final String emailAddress;\n" + 
+				"	public EmailRecipient(String name, String emailAddress) {\n" + 
+				"		this.name = name;\n" + 
+				"		this.emailAddress = emailAddress;\n" + 
+				"	}\n" + 
+				"	@Override\n" + 
+				"	public String getEmailAddress() {\n" + 
+				"		return emailAddress;\n" + 
+				"	}\n" + 
+				"	@Override\n" + 
+				"	public String getName() {\n" + 
+				"		return name;\n" + 
+				"	}\n" + 
+				"}",
+				"no/Message.java",
+				"package no;\n" + 
+				"import java.util.List;\n" + 
+				"public class Message implements WithMessageRecipients {\n" + 
+				"	private final List<EmailRecipient> recipients;\n" + 
+				"	public Message(EmailRecipient ... recipients) {\n" + 
+				"		this.recipients = List.of(recipients);\n" + 
+				"	}\n" + 
+				"	@Override\n" + 
+				"	public List<EmailRecipient> getMessageRecipients() {\n" + 
+				"		return recipients;\n" + 
+				"	}\n" + 
+				"}"
+			},
+			"Jane <jane@example.com>\n" + 
+			"Joe <joe@example.com>\n" + 
+			"Jane <jane@example.com>\n" + 
+			"Joe <joe@example.com>");
+	}
 }
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 a2d4457..e51e26f 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
@@ -16,6 +16,8 @@
  *								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
+ *     Pierre-Yves B. <pyvesdev@gmail.com> - Contribution for
+ *                              Bug 559618 - No compiler warning for import from same package
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -1343,7 +1345,6 @@
 					"p/X1.java",
 					"package p;\n" +
 					"import java.util.Map;\n" +
-					"import p.List;\n" +
 					"import org.eclipse.jdt.annotation.*;\n" +
 					"import static java.lang.annotation.ElementType.*;\n" +
 					"import java.lang.annotation.*;\n" +
@@ -3236,7 +3237,8 @@
 	}
 
 	public void testBug416180() {
-		runConformTestWithLibs(
+		runWarningTestWithLibs(
+			true,
 			new String[] {
 				"X.java",
 				"import org.eclipse.jdt.annotation.NonNull;\n" + 
@@ -4984,6 +4986,7 @@
 		"	       ^^^^^\n" + 
 		"The @NonNull field field may not have been initialized\n" + 
 		"----------\n";
+	runner.javacTestOptions = JavacTestOptions.Excuse.EclipseWarningConfiguredAsError;
 	runner.runNegativeTest();
 }
 
@@ -5029,6 +5032,7 @@
 		"	       ^^^^^\n" + 
 		"The @NonNull field field may not have been initialized\n" + 
 		"----------\n";
+	runner.javacTestOptions = JavacTestOptions.Excuse.EclipseWarningConfiguredAsError;
 	runner.runNegativeTest();
 }
 
@@ -5305,6 +5309,7 @@
 		"	          ^^^^\n" + 
 		"Null type mismatch: required \'@NonNull Number\' but the provided value is null\n" + 
 		"----------\n";
+	runner.javacTestOptions = JavacTestOptions.Excuse.EclipseWarningConfiguredAsError;
 	runner.runNegativeTest();
 }
 
@@ -6620,7 +6625,8 @@
 		"");
 }
 public void testBug439298_comment3() {
-	runConformTestWithLibs(
+	runWarningTestWithLibs(
+		true,
 		new String[] {
 			"Extract.java",
 			"import org.eclipse.jdt.annotation.*;\n" + 
@@ -17764,7 +17770,8 @@
 	runner.runWarningTest();
 }
 public void testBug540264() {
-	runNegativeTestWithLibs(
+	runNegativeTest(
+		true,
 		new String[] {
 			"example/Example.java",
 			"package example;\n" +
@@ -17776,7 +17783,8 @@
 			"    }\n" +
 			"}\n" +
 			"",
-		}, 
+		},
+		this.LIBS,
 		getCompilerOptions(),
 		"----------\n" + 
 		"1. ERROR in example\\Example.java (at line 5)\n" + 
@@ -17793,7 +17801,8 @@
 		"	for (X.Y<Z> entry : x) {\n" + 
 		"	                    ^\n" + 
 		"x cannot be resolved to a variable\n" + 
-		"----------\n"
+		"----------\n",
+		JavacTestOptions.DEFAULT
 	);
 }
 public void testBug542707_1() {
@@ -18008,4 +18017,71 @@
 		"Null type safety (type annotations): The expression of type \'String\' needs unchecked conversion to conform to \'capture#of ? super @Nullable String\'\n" + 
 		"----------\n");
 }
+public void testBug560213source() {
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.classLibraries = this.LIBS;
+	runner.testFiles = new String[] {
+		"nullEnumSort/MyEnum.java",
+		"package nullEnumSort;\n" + 
+		"\n" + 
+		"import org.eclipse.jdt.annotation.NonNullByDefault;\n" + 
+		"\n" + 
+		"@NonNullByDefault\n" + 
+		"enum MyEnum {\n" + 
+		"    x\n" + 
+		"}\n",
+		"nullEnumSort/EnumProblem.java",
+		"package nullEnumSort;\n" + 
+		"\n" + 
+		"import java.util.Collections;\n" + 
+		"import java.util.List;\n" + 
+		"\n" + 
+		"import org.eclipse.jdt.annotation.NonNullByDefault;\n" + 
+		"\n" + 
+		"@NonNullByDefault\n" + 
+		"public class EnumProblem {\n" + 
+		"    void f(List<MyEnum> list) {\n" + 
+		"        Collections.sort(list);\n" + 
+		"    }\n" + 
+		"\n}"
+	};
+	runner.runConformTest();
+}
+public void testBug560213binary() {
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.testFiles = new String[] {
+		"nullEnumSort/MyEnum.java",
+		"package nullEnumSort;\n" + 
+		"\n" + 
+		"import org.eclipse.jdt.annotation.NonNullByDefault;\n" + 
+		"\n" + 
+		"@NonNullByDefault\n" + 
+		"enum MyEnum {\n" + 
+		"    x\n" + 
+		"}\n"
+	};
+	runner.classLibraries = this.LIBS;
+	runner.runConformTest();
+
+	runner.shouldFlushOutputDirectory = false;
+	runner.testFiles = new String[] {
+		"nullEnumSort/EnumProblem.java",
+		"package nullEnumSort;\n" + 
+		"\n" + 
+		"import java.util.Collections;\n" + 
+		"import java.util.List;\n" + 
+		"\n" + 
+		"import org.eclipse.jdt.annotation.NonNullByDefault;\n" + 
+		"\n" + 
+		"@NonNullByDefault\n" + 
+		"public class EnumProblem {\n" + 
+		"    void f(List<MyEnum> list) {\n" + 
+		"        Collections.sort(list);\n" + 
+		"    }\n" + 
+		"\n}"
+	};
+	runner.runConformTest();
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelCompletionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelCompletionTests.java
index 6c177f0..3371230 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelCompletionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelCompletionTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -164,6 +164,7 @@
 	this.oldOptions = JavaCore.getOptions();
 	Hashtable<String, String> options = new Hashtable<>(this.oldOptions);
 	options.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.DISABLED);
+	options.put(JavaCore.CODEASSIST_SUBWORD_MATCH, JavaCore.DISABLED);
 	JavaCore.setOptions(options);
 	waitUntilIndexesReady();
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java
index 296eb4f..8b3d8c7 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompilationUnitTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -11,6 +11,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - contribution for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
+ *     Pierre-Yves B. <pyvesdev@gmail.com> - Contribution for bug 559618 - No compiler warning for import from same package
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.model;
 
@@ -2699,4 +2700,92 @@
 		deleteFolder("/P/src/test1");
 	}
 }
+public void testBug559618_1() throws CoreException {
+	try {
+			createFile("/P/src/p/C.java",
+					"package p;\n" +
+					"public class C{};\n");
+
+			createFile("/P/src/p/D.java",
+					"package p;\n" +
+					"import p.C;\n" +
+					"public class D {\n" +
+					"  C getC() {\n" +
+					"    return null;\n" +
+					"  }\n" +
+					"}\n");
+			ICompilationUnit cuD = getCompilationUnit("/P/src/p/D.java");
+
+			ASTParser parser = ASTParser.newParser(AST_INTERNAL_LATEST);
+			parser.setProject(this.testProject);
+			parser.setSource(cuD);
+			parser.setResolveBindings(true);
+			org.eclipse.jdt.core.dom.CompilationUnit cuAST = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null);
+			IProblem[] problems = cuAST.getProblems();
+			assertEquals("Should have 1 problem", 1, problems.length);
+			assertEquals("Should have only an unused warning", "The import p.C is never used", problems[0].getMessage());
+	} finally {
+			deleteFile("/P/src/p/C.java");
+			deleteFile("/P/src/p/D.java");
+	}
+}
+public void testBug559618_2() throws CoreException { // Same as testBug559618_1, but with wildcard import.
+	try {
+			createFile("/P/src/p/C.java",
+					"package p;\n" +
+					"public class C{};\n");
+			
+			createFile("/P/src/p/D.java",
+					"package p;\n" +
+					"import p.*;\n" +
+					"public class D {\n" +
+					"  C getC() {\n" +
+					"    return null;\n" +
+					"  }\n" +
+					"}\n");
+			ICompilationUnit cuD = getCompilationUnit("/P/src/p/D.java");
+			
+			ASTParser parser = ASTParser.newParser(AST_INTERNAL_LATEST);
+			parser.setProject(this.testProject);
+			parser.setSource(cuD);
+			parser.setResolveBindings(true);
+			org.eclipse.jdt.core.dom.CompilationUnit cuAST = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null);
+			IProblem[] problems = cuAST.getProblems();
+			assertEquals("Should have 1 problem", 1, problems.length);
+			assertEquals("Should have only an unused warning", "The import p is never used", problems[0].getMessage());
+	} finally {
+			deleteFile("/P/src/p/C.java");
+			deleteFile("/P/src/p/D.java");
+	}
+}
+public void testBug559618_3() throws CoreException { // Nested class imports must not be flagged as unused.
+	try {
+		createFile("/P/src/p/C.java",
+				"package p;\n" +
+				"public class C{\n" +
+				"  public class C1{};\n" +
+				"};\n");
+		
+		createFile("/P/src/p/D.java",
+				"package p;\n" +
+				"import p.C.C1;\n" +
+				"public class D {\n" +
+				"  C1 getC1() {\n" +
+				"    return null;\n" +
+				"  }\n" +
+				"}\n");
+		ICompilationUnit cuD = getCompilationUnit("/P/src/p/D.java");
+		
+		ASTParser parser = ASTParser.newParser(AST_INTERNAL_LATEST);
+		parser.setProject(this.testProject);
+		parser.setSource(cuD);
+		parser.setResolveBindings(true);
+		org.eclipse.jdt.core.dom.CompilationUnit cuAST = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null);
+		IProblem[] problems = cuAST.getProblems();
+		assertEquals("Should have no problems", 0, problems.length);
+	} finally {
+		deleteFile("/P/src/p/C.java");
+		deleteFile("/P/src/p/D.java");
+	}
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionContextTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionContextTests.java
index a1431bf..dadb6be 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionContextTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionContextTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * Copyright (c) 2005, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -2249,7 +2249,7 @@
 		"completion token kind=TOKEN_KIND_NAME\n" +
 		"expectedTypesSignatures=null\n" +
 		"expectedTypesKeys=null\n"+
-		"completion token location=UNKNOWN",
+		"completion token location={IN_IMPORT}",
 		result.context);
 }
 public void test0082() throws JavaModelException {
@@ -2275,7 +2275,7 @@
 		"completion token kind=TOKEN_KIND_NAME\n" +
 		"expectedTypesSignatures=null\n" +
 		"expectedTypesKeys=null\n"+
-		"completion token location=UNKNOWN",
+		"completion token location={IN_IMPORT}",
 		result.context);
 }
 public void test0083() throws JavaModelException {
@@ -2301,7 +2301,7 @@
 		"completion token kind=TOKEN_KIND_NAME\n" +
 		"expectedTypesSignatures=null\n" +
 		"expectedTypesKeys=null\n"+
-		"completion token location=UNKNOWN",
+		"completion token location={IN_IMPORT}",
 		result.context);
 }
 public void test0084() throws JavaModelException {
@@ -2327,7 +2327,7 @@
 		"completion token kind=TOKEN_KIND_NAME\n" +
 		"expectedTypesSignatures=null\n" +
 		"expectedTypesKeys=null\n"+
-		"completion token location=UNKNOWN",
+		"completion token location={IN_IMPORT}",
 		result.context);
 }
 public void test0085() throws JavaModelException {
@@ -2353,7 +2353,7 @@
 		"completion token kind=TOKEN_KIND_NAME\n" +
 		"expectedTypesSignatures=null\n" +
 		"expectedTypesKeys=null\n"+
-		"completion token location=UNKNOWN",
+		"completion token location={IN_IMPORT}",
 		result.context);
 }
 public void test0086() throws JavaModelException {
@@ -2379,7 +2379,7 @@
 		"completion token kind=TOKEN_KIND_NAME\n" +
 		"expectedTypesSignatures=null\n" +
 		"expectedTypesKeys=null\n"+
-		"completion token location=UNKNOWN",
+		"completion token location={IN_IMPORT}",
 		result.context);
 }
 public void test0087() throws JavaModelException {
@@ -2405,7 +2405,7 @@
 		"completion token kind=TOKEN_KIND_NAME\n" +
 		"expectedTypesSignatures=null\n" +
 		"expectedTypesKeys=null\n"+
-		"completion token location=UNKNOWN",
+		"completion token location={IN_IMPORT}",
 		result.context);
 }
 public void test0088() throws JavaModelException {
@@ -2431,7 +2431,7 @@
 		"completion token kind=TOKEN_KIND_NAME\n" +
 		"expectedTypesSignatures=null\n" +
 		"expectedTypesKeys=null\n"+
-		"completion token location=UNKNOWN",
+		"completion token location={IN_IMPORT}",
 		result.context);
 }
 public void test0089() throws JavaModelException {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
index 01641b6..3f8a2cc 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
@@ -6336,7 +6336,7 @@
 	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
 
 	assertResults(
-			"AClass2[TYPE_REF]{test.p.AClass2;, test.p, Ltest.p.AClass2;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_NON_RESTRICTED) + "}",
+			"AClass2[TYPE_REF]{test.p.AClass2, test.p, Ltest.p.AClass2;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_NON_RESTRICTED) + "}",
 			requestor.getResults());
 }
 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
index c95e87e..3f91659 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2018 IBM Corporation and others.
+ * Copyright (c) 2004, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -206,6 +206,11 @@
 					buffer.append("CONSTRUCTOR_START"); //$NON-NLS-1$
 					first = false;
 				}
+				if ((locationType & CompletionContext.TL_IN_IMPORT) != 0) {
+					if (!first) buffer.append(',');
+					buffer.append("IN_IMPORT"); //$NON-NLS-1$
+					first = false;
+				}
 				buffer.append('}');
 			}
 		}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java
index 18d695a..af87bd5 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java
@@ -14621,5 +14621,17 @@
 	assertTrue(!requestor.getResults().equals(""));
 	assertTrue(requestor.getResults().contains("toString("));
 }
+public void testBug15589() throws JavaModelException {
+	CompletionResult result = complete(
+            "/Completion/src3/bug15589/Test.java",
+            "package bug15589;\n" +
+            "import java.util.Coll;\n" +
+            "public class Test {\n" +
+            "}\n",
+            "import java.util.Coll");
 
+    assertResults(
+            "Collection[TYPE_REF]{Collection, java.util, Ljava.util.Collection;, null, null, "+(R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_NON_RESTRICTED)+"}",
+            result.proposals);
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
index 11e5b2e..a4f0234 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
@@ -10,6 +10,7 @@
  *
  * Contributors:
  *     Stephan Herrmann - initial API and implementation
+ *     Pierre-Yves B. <pyvesdev@gmail.com> - Contributions for bug 559618 - No compiler warning for import from same package
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.model;
 
@@ -2101,7 +2102,6 @@
 				"\n" + 
 				"import libs.Lib1;\n" + 
 				"import libs.Lib2;\n" + 
-				"import tests.Lib3;\n" + 
 				"\n" + 
 				"public class Test1 {\n" + 
 				"	@NonNull String test1(Lib1<@NonNull String> lib) {\n" + 
@@ -2119,7 +2119,7 @@
 		assertProblems(reconciled.getProblems(), new String[] {
 				"Pb(980) Unsafe interpretation of method return type as '@NonNull' based on the receiver type 'Lib1<@NonNull String>'. Type 'Lib1<T>' doesn't seem to be designed with null type annotations in mind",
 				"Pb(980) Unsafe interpretation of method return type as '@NonNull' based on the receiver type 'Lib2<@NonNull String>'. Type 'Lib2<T>' doesn't seem to be designed with null type annotations in mind",
-		}, new int[] { 10, 13 }, new int[] { ProblemSeverities.Warning, ProblemSeverities.Info } );
+		}, new int[] { 9, 12 }, new int[] { ProblemSeverities.Warning, ProblemSeverities.Info } );
 	}
 
 	public void testBug490343() throws Exception {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/MatchingRegionsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/MatchingRegionsTest.java
index 0ce124c..c045fbf 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/MatchingRegionsTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/MatchingRegionsTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -1542,5 +1542,16 @@
 	assertEquals("Unexpected regions length", 2, regions.length);
 	assertEquals("Unexpected matching regions", "chec[k]Background", printRegions(name, regions));
 }
-
+public void testSubword1() {
+	String name = "LinkedHashMap";
+	int[] regions = SearchPattern.getMatchingRegions("linkedmap",  name, SearchPattern.R_SUBWORD_MATCH);
+	assertEquals("Unexpected regions length", 4, regions.length);
+	assertEquals("Unexpected matching regions", "[Linked]Hash[Map]", printRegions(name, regions));
+}
+public void testSubword2() {
+	String name = "addEnlistListener";
+	int[] regions = SearchPattern.getMatchingRegions("addlist",  name, SearchPattern.R_SUBWORD_MATCH);
+	assertEquals("Unexpected regions length", 4, regions.length);
+	assertEquals("Unexpected matching regions", "[add]Enlist[List]ener", printRegions(name, regions));
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java
index 992ad6f..2ce6c98 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -48,6 +48,7 @@
 			COMPLETION_SUITES.add(CompletionWithMissingTypesTests_1_5.class);
 			COMPLETION_SUITES.add(SnippetCompletionContextTests.class);
 			COMPLETION_SUITES.add(SubstringCompletionTests.class);
+			COMPLETION_SUITES.add(SubwordCompletionTests.class);
 		}
 		COMPLETION_SUITES.add(JavadocTypeCompletionModelTest.class);
 		COMPLETION_SUITES.add(JavadocFieldCompletionModelTest.class);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SubwordCompletionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SubwordCompletionTests.java
new file mode 100644
index 0000000..e115698
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SubwordCompletionTests.java
@@ -0,0 +1,875 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Julian Honnen.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ * Contributors:
+ *     Julian Honnen - initial version
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.model;
+
+import java.util.Hashtable;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+
+import junit.framework.Test;
+
+public class SubwordCompletionTests extends AbstractJavaModelCompletionTests {
+
+public static Test suite() {
+	return buildModelTestSuite(SubwordCompletionTests.class, BYTECODE_DECLARATION_ORDER);
+}
+public SubwordCompletionTests(String name) {
+	super(name);
+}
+public void setUpSuite() throws Exception {
+	if (COMPLETION_PROJECT == null)  {
+		COMPLETION_PROJECT = setUpJavaProject("Completion", "1.8", true);
+	} else {
+		setUpProjectCompliance(COMPLETION_PROJECT, "1.8", true);
+	}
+	super.setUpSuite();
+	Hashtable<String, String> options = new Hashtable<>(this.oldOptions);
+	options.put(JavaCore.CODEASSIST_SUBWORD_MATCH, JavaCore.ENABLED);
+	JavaCore.setOptions(options);
+}
+public void tearDownSuite() throws Exception {
+	if (COMPLETION_SUITES == null) {
+		deleteProject("Completion");
+	} else {
+		COMPLETION_SUITES.remove(getClass());
+		if (COMPLETION_SUITES.size() == 0) {
+			deleteProject("Completion");
+			COMPLETION_SUITES = null;
+		}
+	}
+	if (COMPLETION_SUITES == null) {
+		COMPLETION_PROJECT = null;
+	}
+	super.tearDownSuite();
+}
+
+public void testQualifiedNonStaticMethod() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+		"/Completion/src/test/Test.java",
+		"package test;"+
+		"public class Test {\n" +
+		"  public void addListener() {}\n" +
+		"  public void addXListener() {}\n" +
+		"  public void addYListener() {}\n" +
+		"  void foo() {\n" +
+		"    this.addlistener\n" +
+		"  }\n" +
+		"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "this.addlistener";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"addXListener[METHOD_REF]{addXListener(), Ltest.Test;, ()V, addXListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_STATIC + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"addYListener[METHOD_REF]{addYListener(), Ltest.Test;, ()V, addYListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_STATIC + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"addListener[METHOD_REF]{addListener(), Ltest.Test;, ()V, addListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_STATIC + R_NON_RESTRICTED + R_EXACT_NAME) + "}",
+			requestor.getResults());
+}
+
+public void testUnqualifiedNonStaticMethod() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+		"/Completion/src/test/Test.java",
+		"package test;"+
+		"public class Test {\n" +
+		"  public void addListener() {}\n" +
+		"  public void addXListener() {}\n" +
+		"  public void addYListener() {}\n" +
+		"  void foo() {\n" +
+		"    addlistener\n" +
+		"  }\n" +
+		"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "addlistener";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"addXListener[METHOD_REF]{addXListener(), Ltest.Test;, ()V, addXListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"addYListener[METHOD_REF]{addYListener(), Ltest.Test;, ()V, addYListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"addListener[METHOD_REF]{addListener(), Ltest.Test;, ()V, addListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_EXACT_NAME) + "}",
+			requestor.getResults());
+}
+public void testQualifiedStaticMethod() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+		"/Completion/src/test/Test.java",
+		"package test;"+
+		"public class Test {\n" +
+		"  public static void addListener() {}\n" +
+		"  public void addXListener() {}\n" +
+		"  public static void addYListener() {}\n" +
+		"  void foo() {\n" +
+		"    Test.addlistener\n" +
+		"  }\n" +
+		"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "Test.addlistener";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"addYListener[METHOD_REF]{addYListener(), Ltest.Test;, ()V, addYListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING +  R_NON_RESTRICTED +  R_NON_INHERITED +R_SUBWORD) + "}\n" +
+			"addListener[METHOD_REF]{addListener(), Ltest.Test;, ()V, addListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING +  R_NON_RESTRICTED +  R_NON_INHERITED +R_EXACT_NAME) + "}",
+			requestor.getResults());
+}
+public void testUnqualifiedStaticMethod() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+		"/Completion/src/test/Test.java",
+		"package test;"+
+		"public class Test {\n" +
+		"  public static void addListener() {}\n" +
+		"  public void addXListener() {}\n" +
+		"  public static void addYListener() {}\n" +
+		"  void foo() {\n" +
+		"    addlistener\n" +
+		"  }\n" +
+		"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "addlistener";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"addXListener[METHOD_REF]{addXListener(), Ltest.Test;, ()V, addXListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"addYListener[METHOD_REF]{addYListener(), Ltest.Test;, ()V, addYListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED +  R_NON_RESTRICTED +  R_SUBWORD) + "}\n" +
+			"addListener[METHOD_REF]{addListener(), Ltest.Test;, ()V, addListener, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED +  R_NON_RESTRICTED +  R_EXACT_NAME) + "}",
+			requestor.getResults());
+}
+public void testQualifiedNonStaticField() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+		"/Completion/src/test/Test.java",
+		"package test;"+
+		"public class Test {\n" +
+		"  int fItems;\n" +
+		"  int fOtherItems;\n" +
+		"  long fItemsCount;\n" +
+		"  void foo() {\n" +
+		"    this.fitem\n" +
+		"  }\n" +
+		"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "this.fitem";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"fOtherItems[FIELD_REF]{fOtherItems, Ltest.Test;, I, fOtherItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_STATIC + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"fItems[FIELD_REF]{fItems, Ltest.Test;, I, fItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_STATIC + R_NON_RESTRICTED) + "}\n" +
+			"fItemsCount[FIELD_REF]{fItemsCount, Ltest.Test;, J, fItemsCount, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_STATIC + R_NON_RESTRICTED) + "}",
+			requestor.getResults());
+}
+
+public void testUnqualifiedNonStaticField() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  int fItems;\n" +
+			"  int fOtherItems;\n" +
+			"  long fItemsCount;\n" +
+			"  void foo() {\n" +
+			"    fitem\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "fitem";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"fOtherItems[FIELD_REF]{fOtherItems, Ltest.Test;, I, fOtherItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"fItems[FIELD_REF]{fItems, Ltest.Test;, I, fItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + + R_UNQUALIFIED + R_NON_RESTRICTED) + "}\n" +
+			"fItemsCount[FIELD_REF]{fItemsCount, Ltest.Test;, J, fItemsCount, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
+			requestor.getResults());
+}
+public void testQualifiedStaticField() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static int sItems;\n" +
+			"  static int sOtherItems;\n" +
+			"  long fSomeItemsCount;\n" +
+			"  void foo() {\n" +
+			"    Test.sitem\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "Test.sitem";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"sOtherItems[FIELD_REF]{sOtherItems, Ltest.Test;, I, sOtherItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_NON_INHERITED + R_SUBWORD) + "}\n" +
+			"sItems[FIELD_REF]{sItems, Ltest.Test;, I, sItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_NON_INHERITED) + "}",
+			requestor.getResults());
+}
+public void testUnqualifiedStaticField() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static int sItems;\n" +
+			"  static int sOtherItems;\n" +
+			"  long fSomeItemsCount;\n" +
+			"  void foo() {\n" +
+			"    sitem\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "sitem";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"fSomeItemsCount[FIELD_REF]{fSomeItemsCount, Ltest.Test;, J, fSomeItemsCount, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"sOtherItems[FIELD_REF]{sOtherItems, Ltest.Test;, I, sOtherItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"sItems[FIELD_REF]{sItems, Ltest.Test;, I, sItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
+			requestor.getResults());
+}
+public void testLocalVariable() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static int items;\n" +
+			"  int otherTemporaryItems;\n" +
+			"  static long itemsCount;\n" +
+			"  void foo() {\n" +
+			"    int temporaryItem = 0;\n" +
+			"    tempitem\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "tempitem";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"otherTemporaryItems[FIELD_REF]{otherTemporaryItems, Ltest.Test;, I, otherTemporaryItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"temporaryItem[LOCAL_VARIABLE_REF]{temporaryItem, null, I, temporaryItem, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testMethodParamVariable() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static int items;\n" +
+			"  int otherTemporaryItems;\n" +
+			"  static long itemsCount;\n" +
+			"  void foo(int temporaryItems) {\n" +
+			"    tempitems\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "item";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"otherTemporaryItems[FIELD_REF]{otherTemporaryItems, Ltest.Test;, I, otherTemporaryItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"temporaryItems[LOCAL_VARIABLE_REF]{temporaryItems, null, I, temporaryItems, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testClassTypeInstantiation() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"interface Map {}\n" +
+			"class LinkedHashMap implements Map {}\n" +
+			"class SpecificLinkedHashMap extends LinkedHashMap {}\n" +
+			"interface Foobaz {}\n" +
+			"class SpecificFooBaz implements Foobaz {}\n" +
+			"public class Test {\n" +
+			"  {\n" +
+			"    Map f = new linkedmap\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "new linkedmap";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"LinkedHashMap[TYPE_REF]{LinkedHashMap, test, Ltest.LinkedHashMap;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"SpecificLinkedHashMap[TYPE_REF]{SpecificLinkedHashMap, test, Ltest.SpecificLinkedHashMap;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testClassTypeFieldDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"interface Map {}\n" +
+			"class LinkedHashMap implements Map {}\n" +
+			"class SpecificLinkedHashMap extends LinkedHashMap {}\n" +
+			"interface Foobaz {}\n" +
+			"class SpecificFooBaz implements Foobaz {}\n" +
+			"public class Test {\n" +
+			"  public linkedmap\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "public linkedmap";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"LinkedHashMap[TYPE_REF]{LinkedHashMap, test, Ltest.LinkedHashMap;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"SpecificLinkedHashMap[TYPE_REF]{SpecificLinkedHashMap, test, Ltest.SpecificLinkedHashMap;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testClassTypeParamDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"interface Map {}\n" +
+			"class LinkedHashMap implements Map {}\n" +
+			"class SpecificLinkedHashMap extends LinkedHashMap {}\n" +
+			"interface Foobaz {}\n" +
+			"class SpecificFooBaz implements Foobaz {}\n" +
+			"public class Test {\n" +
+			"  void setFoo(linkedmap\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "void setFoo(linkedmap";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"LinkedHashMap[TYPE_REF]{LinkedHashMap, test, Ltest.LinkedHashMap;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"SpecificLinkedHashMap[TYPE_REF]{SpecificLinkedHashMap, test, Ltest.SpecificLinkedHashMap;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testClassTypeLocalVarDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"interface Map {}\n" +
+			"class LinkedHashMap implements Map {}\n" +
+			"class SpecificLinkedHashMap extends LinkedHashMap {}\n" +
+			"interface Foobaz {}\n" +
+			"class SpecificFooBaz implements Foobaz {}\n" +
+			"public class Test {\n" +
+			"  void foo() {\n" +
+			"    final linkedmap" +
+			"  }" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "final linkedmap";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"LinkedHashMap[TYPE_REF]{LinkedHashMap, test, Ltest.LinkedHashMap;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"SpecificLinkedHashMap[TYPE_REF]{SpecificLinkedHashMap, test, Ltest.SpecificLinkedHashMap;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testClassTypeThrowsDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"interface Foobar {}\n" +
+			"class SpecificFooBar implements Foobar extends Exception {}\n" +
+			"class EvenMoreSpecificFooBar extends SpecificFooBar {}\n" +
+			"interface Foobaz {}\n" +
+			"class SpecificFooBaz implements Foobaz extends Exception {}\n" +
+			"public class Test {\n" +
+			"  void foo() throws fbar {\n" +
+			"  }" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "void foo() throws fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"EvenMoreSpecificFooBar[TYPE_REF]{EvenMoreSpecificFooBar, test, Ltest.EvenMoreSpecificFooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}\n" +
+			"SpecificFooBar[TYPE_REF]{SpecificFooBar, test, Ltest.SpecificFooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testClassTypeExtends() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"interface Foobar {}\n" +
+			"class SpecificFooBar implements Foobar {}\n" +
+			"class EvenMoreSpecificFooBar extends SpecificFooBar {}\n" +
+			"interface Foobaz {}\n" +
+			"class SpecificFooBaz implements Foobaz {}\n" +
+			"public class Test extends fbar {\n" +
+			"  }" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "public class Test extends fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"EvenMoreSpecificFooBar[TYPE_REF]{EvenMoreSpecificFooBar, test, Ltest.EvenMoreSpecificFooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_CLASS + R_SUBWORD) + "}\n" +
+			"SpecificFooBar[TYPE_REF]{SpecificFooBar, test, Ltest.SpecificFooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_CLASS + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testClassTypeImplements() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"interface FooBar {}\n" +
+			"interface FooBarExtension extends FooBar {}\n" +
+			"class SpecificFooBar implements FooBar {}\n" +
+			"class EvenMoreSpecificFooBar extends SpecificFooBar {}\n" +
+			"interface Foobaz {}\n" +
+			"class SpecificFooBaz implements Foobaz {}\n" +
+			"public class Test implements fbar {\n" +
+			"  }" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "public class Test implements fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"FooBar[TYPE_REF]{FooBar, test, Ltest.FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_INTERFACE + R_SUBWORD) + "}\n" +
+			"FooBarExtension[TYPE_REF]{FooBarExtension, test, Ltest.FooBarExtension;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_UNQUALIFIED + R_NON_RESTRICTED + R_INTERFACE + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testInnerClassTypeInstantiation() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  class FooBar {}\n" +
+			"  {\n" +
+			"    Test t = new Test();\n" +
+			"    Object f = t.new fbar\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "t.new fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testInnerClassTypeFieldDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  class FooBar {}\n" +
+			"  public fbar\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "public fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testInnerClassTypeParamDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  class FooBar {}\n" +
+			"  void foo(fbar\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "void foo(fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testInnerClassTypeLocalVarDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  class FooBar {}\n" +
+			"  {\n" +
+			"    final fbar\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "final fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testInnerClassTypeThrowsDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  class FooBar extends Exception {}\n" +
+			"  void foo() throws fbar" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "void foo() throws fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testInnerClassTypeExtends() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  class FooBar {}\n" +
+			"  class SpecificFooBar extends fbar\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "SpecificFooBar extends fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testInnerClassTypeImplements() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  interface FooBar {}\n" +
+			"  class SpecificFooBar implements fbar\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "class SpecificFooBar implements fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testStaticNestedClassTypeInstantiation() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static class FooBar {}\n" +
+			"  {\n" +
+			"    Object f = new fbar\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "new fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testStaticNestedClassTypeFieldDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static class FooBar {}\n" +
+			"  public fbar\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "public fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testStaticNestedClassTypeParamDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static class FooBar {}\n" +
+			"  void foo(fbar\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "void foo(fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testStaticNestedClassTypeLocalVarDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static class FooBar {}\n" +
+			"  {\n" +
+			"    final fbar\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "final fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testStaticNestedClassTypeThrowsDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static class FooBar extends Exception {}\n" +
+			"  void foo() throws fbar" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "void foo() throws fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testStaticNestedClassTypeExtends() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static class FooBar {}\n" +
+			"  class SpecificFooBar extends fbar\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "SpecificFooBar extends fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testStaticNestedClassTypeImplements() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  static interface FooBar {}\n" +
+			"  class SpecificFooBar implements fbar\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "class SpecificFooBar implements fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"Test.FooBar[TYPE_REF]{FooBar, test, Ltest.Test$FooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testLocalClassTypeInstantiation() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  void foo() {\n" +
+			"    class FooBar {}\n" +
+			"    Object f = new fbar\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "new fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"FooBar[TYPE_REF]{FooBar, test, LFooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testLocalClassTypeLocalVarDeclaration() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  void foo() {\n" +
+			"    class FooBar {}\n" +
+			"    final fbar\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "final fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"FooBar[TYPE_REF]{FooBar, test, LFooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testLocalClassTypeExtends() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  void foo() {\n" +
+			"    class FooBar {}\n" +
+			"    class SpecificFooBar extends fbar\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "class SpecificFooBar extends fbar";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"FooBar[TYPE_REF]{FooBar, test, LFooBar;, null, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXPECTED_TYPE + R_NON_RESTRICTED + R_UNQUALIFIED + R_SUBWORD) + "}",
+			requestor.getResults());
+}
+public void testDontPreventInsertionOfExactMatch() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Test.java",
+			"package test;"+
+			"public class Test {\n" +
+			"  void foo(java.util.Map<String, String> map) {\n" +
+			"    map.put(\n" +
+			"  }\n" +
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "map.put(";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+	assertResults(
+			"put[METHOD_REF]{, Ljava.util.Map<Ljava.lang.String;Ljava.lang.String;>;, (Ljava.lang.String;Ljava.lang.String;)Ljava.lang.String;, put, (key, value), " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_EXACT_NAME + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED ) + "}",
+			requestor.getResults());
+}
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter/src/test0554/B.java b/org.eclipse.jdt.core.tests.model/workspace/Converter/src/test0554/B.java
index 9326194..9a27da2 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/Converter/src/test0554/B.java
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter/src/test0554/B.java
@@ -1,7 +1,5 @@
 package test0554;
 
-import test0554.A;
-
 public class B {
 	public static String foo() {
 		return A.getString("xx");
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter/src/test0555/B.java b/org.eclipse.jdt.core.tests.model/workspace/Converter/src/test0555/B.java
index 7f90455..0441e1c 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/Converter/src/test0555/B.java
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter/src/test0555/B.java
@@ -1,7 +1,5 @@
 package test0555;
 
-import test0555.A;
-
 public class B {
 	public static String foo() {
 		return A.BUNDLE_NAME;
diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
new file mode 100644
index 0000000..6b595ce
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/.api_filters
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jdt.core" version="2">
+    <resource path="model/org/eclipse/jdt/core/CompletionContext.java" type="org.eclipse.jdt.core.CompletionContext">
+        <filter comment="Contract of getTokenLocation() announces future additions" id="336658481">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.CompletionContext"/>
+                <message_argument value="TL_IN_IMPORT"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="search/org/eclipse/jdt/core/search/SearchPattern.java" type="org.eclipse.jdt.core.search.SearchPattern">
+        <filter id="336658481">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.search.SearchPattern"/>
+                <message_argument value="R_SUBWORD_MATCH"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
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 f8884c6..422e9ca 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
@@ -54,6 +54,7 @@
 import org.eclipse.jdt.core.compiler.CategorizedProblem;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
 import org.eclipse.jdt.core.search.IJavaSearchConstants;
 import org.eclipse.jdt.core.search.IJavaSearchScope;
@@ -1540,10 +1541,10 @@
 						} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
 							continue next;
 						} else {
-							completionName = CharOperation.concat(completionName, new char[] { ';' });
+							completionName = appendUnlessNextToken(completionName, new char[] { ';' }, TerminalTokens.TokenNameSEMICOLON);
 						}
 					} else {
-						completionName = CharOperation.concat(completionName, new char[] { ';' });
+						completionName = appendUnlessNextToken(completionName, new char[] {';'}, TerminalTokens.TokenNameSEMICOLON);
 					}
 	
 					int relevance = computeBaseRelevance();
@@ -1702,6 +1703,18 @@
 		}
 	}
 	
+	private char[] appendUnlessNextToken(char[] completionName, char[] suffix, int nextToken) {
+		this.parser.scanner.resetTo(this.endPosition, Integer.MAX_VALUE);
+		try {
+			if (this.parser.scanner.getNextToken() != nextToken) {
+				return CharOperation.concat(completionName, suffix);
+			}
+		} catch (InvalidInputException e) {
+			// ignore
+		}
+		return completionName;
+	}
+
 	public void acceptUnresolvedName(char[] name) {
 		int relevance = computeBaseRelevance();
 		relevance += computeRelevanceForResolution(false);
@@ -1916,6 +1929,8 @@
 			}
 		} else if (astNode instanceof CompletionOnKeyword3 && ((CompletionOnKeyword3) astNode).afterTryOrCatch()) {
 				context.setTokenLocation(CompletionContext.TL_STATEMENT_START);
+		} else if (astNode instanceof CompletionOnImportReference) {
+			context.setTokenLocation(CompletionContext.TL_IN_IMPORT);
 		} else {
 			ReferenceContext referenceContext = scope.referenceContext();
 			if (referenceContext instanceof AbstractMethodDeclaration) {
@@ -2247,7 +2262,7 @@
 							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
 							if ((this.unitScope = parsedUnit.scope) != null) {
 								contextAccepted = true;
-								buildContext(importReference, null, parsedUnit, null, null);
+								buildContext(importReference, null, parsedUnit, null, this.unitScope);
 
 								long positions = importReference.sourcePositions[importReference.tokens.length - 1];
 								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
@@ -4734,6 +4749,8 @@
 				return R_CAMEL_CASE;
 		} else if (this.options.substringMatch && CharOperation.substringMatch(token, proposalName)) {
 			return R_SUBSTRING;
+		} else if (this.options.subwordMatch && CharOperation.subWordMatch(token, proposalName)) {
+			return R_SUBWORD;
 		}
 		return 0;
 	}
@@ -13722,7 +13739,8 @@
 	private boolean isFailedMatch(char[] token, char[] name) {
 		if ((this.options.substringMatch && CharOperation.substringMatch(token, name))
 				|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, name))
-				|| CharOperation.prefixEquals(token, name, false)) {
+				|| CharOperation.prefixEquals(token, name, false)
+				|| (this.options.subwordMatch && CharOperation.subWordMatch(token, name))) {
 			return false;
 		}
 
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
index c968294..383acb7 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -48,6 +48,7 @@
 	int R_NAME_SUFFIX = 3;
 	int R_NAME_LESS_NEW_CHARACTERS = 15;
 	int R_SUBSTRING = -21;
+	int R_SUBWORD = -22;
 	int R_METHOD_OVERIDE = 3;
 	int R_NON_RESTRICTED = 3;
 	int R_TRUE_OR_FALSE = 1;
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
index 53bc140..92a40a3 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -57,6 +57,8 @@
 		"org.eclipse.jdt.core.codeComplete.camelCaseMatch"; 	//$NON-NLS-1$
 	public static final String OPTION_SubstringMatch =
 			"org.eclipse.jdt.core.codeComplete.substringMatch"; 	//$NON-NLS-1$
+	public static final String OPTION_SubwordMatch =
+			"org.eclipse.jdt.core.codeComplete.subwordMatch"; 	//$NON-NLS-1$
 	public static final String OPTION_SuggestStaticImports =
 		"org.eclipse.jdt.core.codeComplete.suggestStaticImports"; 	//$NON-NLS-1$
 
@@ -70,6 +72,7 @@
 	public boolean forceImplicitQualification = false;
 	public boolean camelCaseMatch = true;
 	public boolean substringMatch = true;
+	public boolean subwordMatch = true;
 	public boolean suggestStaticImport = true;
 	public char[][] fieldPrefixes = null;
 	public char[][] staticFieldPrefixes = null;
@@ -243,6 +246,13 @@
 				this.substringMatch = false;
 			}
 		}
+		if ((optionValue = optionsMap.get(OPTION_SubwordMatch)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.subwordMatch = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.subwordMatch = false;
+			}
+		}
 		if ((optionValue = optionsMap.get(OPTION_PerformDeprecationCheck)) != null) {
 			if (ENABLED.equals(optionValue)) {
 				this.checkDeprecation = true;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
index 5dc15d6..6ef0dc6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -57,6 +57,8 @@
 	 */
 	public static final char[] COMMA_SEPARATOR = new char[] {','};
 
+	private static final int[] EMPTY_REGIONS = new int[0];
+
 /**
  * Answers a new array with appending the suffix character at the end of the array.
  * <br>
@@ -745,6 +747,146 @@
 
 /**
  * Answers true if the characters of the pattern are contained in the
+ * name as a subword, in a case-insensitive way.
+ *
+ * @param pattern the given pattern
+ * @param name the given name
+ * @return true if the pattern matches the given name, false otherwise
+ * @since 3.21
+ */
+public static final boolean subWordMatch(char[] pattern, char[] name) {
+	if (name == null)
+		return false; // null name cannot match
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+
+	int[] matchingRegions = getSubWordMatchingRegions(new String(pattern), new String(name));
+	return matchingRegions != null;
+}
+
+/**
+ * Answers all the regions in a given name matching a subword pattern.
+ * <p>
+ * Each of these regions is made of its starting index and its length in the given
+ * name. They are all concatenated in a single array of <code>int</code>
+ * which therefore always has an even length.
+ * <p>
+ * Note that each region is disjointed from the following one.<br>
+ * E.g. if the regions are <code>{ start1, length1, start2, length2 }</code>,
+ * then <code>start1+length1</code> will always be smaller than
+ * <code>start2</code>.
+ * <p>
+ * Examples:
+ * <ol>
+ * <li><pre>
+ *    pattern = "linkedmap"
+ *    name = LinkedHashMap
+ *    result:  { 0, 6, 10, 3 }
+ * </pre></li>
+ * </ol>
+ *
+ * @see CharOperation#subWordMatch(char[], char[])
+ * 	for more details on the subword behavior
+ *
+ * @param pattern the given pattern
+ * @param name the given name
+ * @return an array of <code>int</code> having two slots per returned
+ * 	regions (first one is the starting index of the region and the second
+ * 	one the length of the region).<br>
+ * 	Note that it may be <code>null</code> if the given name does not match
+ * 	the pattern
+ * @since 3.21
+ */
+public static final int[] getSubWordMatchingRegions(String pattern, String name) {
+
+	if (name == null)
+		return null; // null name cannot match
+	if (pattern == null) {
+		// null pattern cannot match any region
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=264816
+		return EMPTY_REGIONS;
+	}
+
+	int segmentStart = 0;
+	int[] segments = EMPTY_REGIONS;
+	char[] nameChars = name.toCharArray();
+
+	// Main loop is on pattern characters
+	int iName = -1;
+	for (int iPattern = 0; iPattern < pattern.length(); iPattern++) {
+		iName++;
+		if (iName == nameChars.length){
+			// We have exhausted the name (and not the pattern), so it's not a match
+			return null;
+		}
+
+		char patternChar = pattern.charAt(iPattern);
+		char nameChar = nameChars[iName];
+
+		// For as long as we're exactly matching, bring it on
+		if (patternChar == nameChar) {
+			continue;
+		}
+
+		// lower case pattern also matches upper case name
+		if (ScannerHelper.toLowerCase(nameChar) == patternChar) {
+			continue;
+		}
+
+		// not matching, record previous segment and find next word match in name
+		if (iName > segmentStart) {
+			segments = Arrays.copyOf(segments, segments.length + 2);
+			segments[segments.length - 2] = segmentStart;
+			segments[segments.length - 1] = iName - segmentStart;
+		}
+
+		int wordStart = indexOfWordStart(nameChars, iName, patternChar);
+		if (wordStart < 0) {
+			//	We have exhausted name (and not pattern), so it's not a match
+			return null;
+		}
+
+		segmentStart = wordStart;
+		iName = wordStart;
+	}
+
+	 // we have exhausted pattern, record final segment
+	segments = Arrays.copyOf(segments, segments.length + 2);
+	segments[segments.length - 2] = segmentStart;
+	segments[segments.length - 1] = iName - segmentStart + 1;
+
+	return segments;
+}
+
+/**
+ * Returns the index of the first word after nameStart, beginning with patternChar.
+ * Returns -1 if no matching word is found.
+ */
+private static int indexOfWordStart(char[] name, int nameStart, char patternChar) {
+
+	char target = ScannerHelper.toUpperCase(patternChar);
+	boolean lastWasSeparator = false;
+
+	for (int iName = nameStart; iName < name.length; iName++) {
+		char nameChar = name[iName];
+		if (nameChar == target || (lastWasSeparator && nameChar == patternChar)) {
+			return iName;
+		}
+
+		// don't match across identifiers (e.g. "index" should not match "substring(int beginIndex)")
+		if (!ScannerHelper.isJavaIdentifierPart(nameChar)) {
+			return -1;
+		}
+
+		lastWasSeparator = nameChar == '_';
+	}
+
+	// We have exhausted name
+	return -1;
+}
+
+/**
+ * Answers true if the characters of the pattern are contained in the
  * name as a substring, in a case-insensitive way.
  *
  * @param pattern the given pattern
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index dc687c5..bec3ac7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -66,6 +66,7 @@
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
 import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
@@ -946,13 +947,25 @@
 		return this.descriptor.parameters;
 	}
 
+	private boolean contextHasSyntaxError() {
+		ReferenceContext referenceContext = this.enclosingScope.referenceContext();
+		if (referenceContext instanceof AbstractMethodDeclaration) {
+			if ((((AbstractMethodDeclaration) referenceContext).bits & ASTNode.HasSyntaxErrors) != 0)
+				return true;
+		}
+		return false;
+	}
+
 	// Cache resolved copies against various target types, so repeat overload resolution and possibly type inference could be avoided.
 	private ReferenceExpression cachedResolvedCopy(TypeBinding targetType) {
 
 		ReferenceExpression copy = this.copiesPerTargetType != null ? this.copiesPerTargetType.get(targetType) : null;
 		if (copy != null)
 			return copy;
-		
+
+		if (contextHasSyntaxError())
+			return null;
+
 		IErrorHandlingPolicy oldPolicy = this.enclosingScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
 		try {
 			copy = copy();
@@ -1239,7 +1252,11 @@
 	@Override
 	public boolean isCompatibleWith(TypeBinding targetType, Scope scope) {
 		ReferenceExpression copy = cachedResolvedCopy(targetType);
-		return copy != null && copy.resolvedType != null && copy.resolvedType.isValidBinding() && copy.binding != null && copy.binding.isValidBinding();
+		if (copy == null) {
+			return contextHasSyntaxError(); // in case of syntax error avoid secondary errors
+		} else {
+			return copy.resolvedType != null && copy.resolvedType.isValidBinding() && copy.binding != null && copy.binding.isValidBinding();
+		}
 	}
 	
 	@Override
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 56afed0..0afaf5e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -3544,6 +3544,10 @@
 						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic()))
 						&& codegenBinding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object methods
 					|| !codegenBinding.declaringClass.canBeSeenBy(currentScope)) {
+				TypeBinding erasedReceiverType = actualReceiverType.erasure();
+				if (erasedReceiverType.isIntersectionType18()) {
+					actualReceiverType = erasedReceiverType; // need to peel the intersecting types below
+				}
 				if (actualReceiverType.isIntersectionType18()) {
 					TypeBinding[] intersectingTypes = ((IntersectionTypeBinding18)actualReceiverType).getIntersectingTypes();
 					for(int i = 0; i < intersectingTypes.length; i++) {
@@ -3553,7 +3557,7 @@
 						}
 					}
 				} else {
-					constantPoolDeclaringClass = actualReceiverType.erasure();
+					constantPoolDeclaringClass = erasedReceiverType;
 				}
 			}
 		}				
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
index ea66be2..a7f49f0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
@@ -17,8 +17,6 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-
 public class BaseTypeBinding extends TypeBinding {
 
 	public static final int[] CONVERSIONS;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index f80d48c..014f2cb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -60,6 +60,8 @@
  *  							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
  *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          	Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
+ *     Pierre-Yves B. <pyvesdev@gmail.com> - Contributions for
+ *                              Bug 559618 - No compiler warning for import from same package
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -3707,14 +3709,15 @@
 			Binding cachedBinding = (Binding) typeOrPackageCache.get(name);
 			if (cachedBinding != null) { // can also include NotFound ProblemReferenceBindings if we already know this name is not found
 				if (cachedBinding instanceof ImportBinding) { // single type import cached in faultInImports(), replace it in the cache with the type
-					ImportReference importReference = ((ImportBinding) cachedBinding).reference;
-					if (importReference != null) {
+					ImportBinding importBinding = (ImportBinding) cachedBinding;
+					ImportReference importReference = importBinding.reference;
+					if (importReference != null && !isUnnecessarySamePackageImport(importBinding.resolvedImport, unitScope)) {
 						importReference.bits |= ASTNode.Used;
 					}
 					if (cachedBinding instanceof ImportConflictBinding)
 						typeOrPackageCache.put(name, cachedBinding = ((ImportConflictBinding) cachedBinding).conflictingTypeBinding); // already know its visible
 					else
-						typeOrPackageCache.put(name, cachedBinding = ((ImportBinding) cachedBinding).resolvedImport); // already know its visible
+						typeOrPackageCache.put(name, cachedBinding = importBinding.resolvedImport); // already know its visible
 				}
 				if ((mask & Binding.TYPE) != 0) {
 					if (foundType != null && foundType.problemId() != ProblemReasons.NotVisible && cachedBinding.problemId() != ProblemReasons.Ambiguous)
@@ -3859,6 +3862,17 @@
 		return foundType;
 	}
 
+	private boolean isUnnecessarySamePackageImport(Binding resolvedImport, Scope unitScope) {
+		if (resolvedImport instanceof ReferenceBinding) {
+			if (unitScope.getCurrentPackage() == ((ReferenceBinding) resolvedImport).getPackage()) {
+				if ((resolvedImport.getAnnotationTagBits() & TagBits.IsNestedType) != 0)
+					return false; // importing nested types is still necessary
+				return true;
+			}
+		}
+		return false;
+	}
+
 	// Added for code assist... NOT Public API
 	// DO NOT USE to resolve import references since this method assumes 'A.B' is relative to a single type import of 'p1.A'
 	// when it may actually mean the type B in the package A
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
index 184b9a4..1ac0753 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -355,7 +355,8 @@
 	}
 
 	private BoundCheckStatus nullBoundCheck(Scope scope, TypeBinding argumentType, TypeBinding substitutedSuperType, Substitution substitution, ASTNode location, BoundCheckStatus previousStatus) {
-		if (NullAnnotationMatching.analyse(this, argumentType, substitutedSuperType, substitution, -1, null, CheckMode.BOUND_CHECK).isAnyMismatch()) {
+		NullAnnotationMatching status = NullAnnotationMatching.analyse(this, argumentType, substitutedSuperType, substitution, -1, null, CheckMode.BOUND_CHECK);
+		if (status.isAnyMismatch() && !status.isAnnotatedToUnannotated()) {
 			if (location != null)
 				scope.problemReporter().nullityMismatchTypeArgument(this, argumentType, location);
 			return BoundCheckStatus.NULL_PROBLEM;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultValuePairBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultValuePairBinding.java
index 8ef3e6f..5a5ea0c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultValuePairBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultValuePairBinding.java
@@ -16,9 +16,6 @@
  *******************************************************************************/
 package org.eclipse.jdt.core.dom;
 
-import org.eclipse.jdt.core.dom.BindingResolver;
-import org.eclipse.jdt.core.dom.IMethodBinding;
-
 /**
  * Member value pair which compose of default values.
  */
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
index 7c8adc0..a1cde5f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
@@ -23,8 +23,6 @@
 import org.eclipse.jface.text.TextUtilities;
 
 import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.dom.SimplePropertyDescriptor;
-import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
 import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
 import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
 import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/IndentManipulation.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/IndentManipulation.java
index 004f627..791bc44 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/IndentManipulation.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/IndentManipulation.java
@@ -17,7 +17,6 @@
 import java.util.Arrays;
 import java.util.Map;
 
-import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
 import org.eclipse.jdt.internal.compiler.util.Util;
 import org.eclipse.jface.text.BadLocationException;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java
index 89f1264..53ee512 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * Copyright (c) 2005, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -75,6 +75,19 @@
 	public static final int TL_CONSTRUCTOR_START = 4;
 
 	/**
+	 * The completed token is part of an import statement<br>
+	 * e.g.
+	 * <pre>
+	 * import java.util| // completion occurs at |
+	 * </pre>
+	 *
+	 * @see #getTokenLocation()
+	 *
+	 * @since 3.21
+	 */
+	public static final int TL_IN_IMPORT = 8;
+
+	/**
 	 * The completion token is unknown.
 	 * @since 3.2
 	 */
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 d9dfa9b..c8697c3 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -2802,6 +2802,19 @@
 	 */
 	public static final String CODEASSIST_SUBSTRING_MATCH = PLUGIN_ID + ".codeComplete.substringMatch"; //$NON-NLS-1$
 	/**
+	 * Code assist option ID: Activate Subword Code Completion.
+	 * <p>When enabled, completion shows proposals in which the pattern can
+	 *    be found as a subword in a case-insensitive way.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.subwordMatch"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.21
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_SUBWORD_MATCH = PLUGIN_ID + ".codeComplete.subwordMatch"; //$NON-NLS-1$
+	/**
 	 * Code assist option ID: Automatic Qualification of Implicit Members.
 	 * <p>When active, completion automatically qualifies completion on implicit
 	 *    field references and message expressions.</p>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
index cb679cc..04276ab 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -115,6 +115,7 @@
 		defaultOptionsMap.put(JavaCore.CODEASSIST_DISCOURAGED_REFERENCE_CHECK, JavaCore.DISABLED);
 		defaultOptionsMap.put(JavaCore.CODEASSIST_CAMEL_CASE_MATCH, JavaCore.ENABLED);
 		defaultOptionsMap.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_SUBWORD_MATCH, JavaCore.DISABLED);
 		defaultOptionsMap.put(JavaCore.CODEASSIST_SUGGEST_STATIC_IMPORTS, JavaCore.ENABLED);
 		defaultOptionsMap.put(ChunkCache.CHUNK_CACHE_SIZE_MB, Double.toString(ChunkCache.CHUNK_CACHE_SIZE_MB_DEFAULT));
 		defaultOptionsMap.put(ChunkCache.CHUNK_CACHE_SIZE_PERCENT,
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index 9c3baec..297faa2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -2500,6 +2500,7 @@
 		defaultOptionsMap.put(JavaCore.CODEASSIST_DISCOURAGED_REFERENCE_CHECK, JavaCore.DISABLED);
 		defaultOptionsMap.put(JavaCore.CODEASSIST_CAMEL_CASE_MATCH, JavaCore.ENABLED);
 		defaultOptionsMap.put(JavaCore.CODEASSIST_SUBSTRING_MATCH, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_SUBWORD_MATCH, JavaCore.DISABLED);
 		defaultOptionsMap.put(JavaCore.CODEASSIST_SUGGEST_STATIC_IMPORTS, JavaCore.ENABLED);
 
 		// Time out for parameter names
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
index 012a927..1b78beb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -97,6 +97,7 @@
 	}
 	return null;
 }
+/** Lists all java-like files and also sub-directories (for recursive tests). */
 String[] directoryList(String qualifiedPackageName) {
 	String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
 	if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
@@ -111,7 +112,8 @@
 			for (int i = 0, l = members.length; i < l; i++) {
 				IResource m = members[i];
 				String name = m.getName();
-				if (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
+				if (m.getType() == IResource.FOLDER || // include folders so we recognize empty parent packages
+						(m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name))) {
 					// add exclusion pattern check here if we want to hide .class files
 					dirList[index++] = name;
 				}
@@ -215,7 +217,23 @@
 		if (this.module == null || !moduleName.equals(String.valueOf(this.module.name())))
 			return false;
 	}
-	return directoryList(qualifiedPackageName) != null;
+	String[] list = directoryList(qualifiedPackageName);
+	if (list != null) {
+		// 1. search files here:
+		for (String entry : list) {
+			String entryLC = entry.toLowerCase();
+			if (entryLC.endsWith(SuffixConstants.SUFFIX_STRING_class) || entryLC.endsWith(SuffixConstants.SUFFIX_STRING_java))
+				return true;
+		}
+		// 2. recurse into sub directories
+		for (String entry : list) {
+			if (entry.indexOf('.') == -1) { // no plain files without '.' are returned by directoryList()
+				if (isPackage(qualifiedPackageName+'/'+entry, null/*already checked*/))
+					return true;
+			}
+		}
+	}
+	return false;
 }
 @Override
 public boolean hasCompilationUnit(String qualifiedPackageName, String moduleName) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
index fd384f2..b72832d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -86,7 +86,8 @@
 				for (int i = 0, l = members.length; i < l; i++) {
 					IResource m = members[i];
 					String name = m.getName();
-					if (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
+					if (m.getType() == IResource.FOLDER
+							|| (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name))) {
 						// add exclusion pattern check here if we want to hide .class files
 						dirList[index++] = name;
 					}
@@ -102,7 +103,8 @@
 						for (int i = 0, l = members.length; i < l; i++) {
 							IResource m = members[i];
 							String name = m.getName();
-							if (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isJavaFileName(name)) {
+							if (m.getType() == IResource.FOLDER
+									|| (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isJavaFileName(name))) {
 								// FIXME: check if .java file has any declarations?
 								dirList[index++] = name;
 							}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java
index a1e9071..5fffe47 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java
@@ -148,6 +148,9 @@
 
 			this.notifier.subTask(Messages.build_analyzingSources);
 			addAffectedSourceFiles();
+			if (this.testImageBuilder != null) {
+				this.testImageBuilder.addAffectedSourceFiles();
+			}
 			this.notifier.updateProgressDelta(0.05f);
 		}
 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
index 51cfb8e..0874ed6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
@@ -45,7 +45,6 @@
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.search.AbstractJavaSearchScope;
-import org.eclipse.jdt.internal.core.util.Util;
 
 /**
  * Creates java element handles.
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
index 31df465..d99c43b 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -230,6 +230,27 @@
 	 */
 	public static final int R_SUBSTRING_MATCH = 0x0200;
 
+	/**
+	 * Match rule: The search pattern contains a subword expression in a case-insensitive way.
+	 * <p>
+	 * Examples:
+	 * <ul>
+	 * 	<li>'addlist' string pattern will match
+	 * 		'addListener' and 'addChangeListener'</li>
+	 * </ul>
+	 *
+	 * This rule is not intended to be combined with any other match rule. In case
+	 * of other match rule flags are combined with this one, then match rule validation
+	 * will return a modified rule in order to perform a better appropriate search request
+	 * (see {@link #validateMatchRule(String, int)} for more details).
+	 * 
+	 * <p>
+	 * This is implemented only for code assist and not available for normal search.
+	 *
+	 * @since 3.21
+	 */
+	public static final int R_SUBWORD_MATCH = 0x0400;
+
 	private static final int MODE_MASK = R_EXACT_MATCH
 		| R_PREFIX_MATCH
 		| R_PATTERN_MATCH
@@ -876,6 +897,8 @@
 				return next >= 0 ? new int[] {next, patternLength} : null;
 			}
 			break;
+		case SearchPattern.R_SUBWORD_MATCH:
+			return CharOperation.getSubWordMatchingRegions(pattern, name);
 	}
 	return null;
 }