update jdt.core to 2e651fafefe7eb36baab915076f5230cc977a033
(right before the Java20 merge)
diff --git a/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF
index 7fb1034..553499f 100644
--- a/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Eclipse Compiler for Java(TM)
 Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch
-Bundle-Version: 3.33.0.OTDT_r282_qualifier
+Bundle-Version: 3.33.100.OTDT_r282_qualifier
 Bundle-ClassPath: .
 Bundle-Vendor: Eclipse.org
 Automatic-Module-Name: org.eclipse.jdt.core.compiler.batch
diff --git a/org.eclipse.jdt.core.compiler.batch/pom.xml b/org.eclipse.jdt.core.compiler.batch/pom.xml
index b9fa6f2..c19acde7 100644
--- a/org.eclipse.jdt.core.compiler.batch/pom.xml
+++ b/org.eclipse.jdt.core.compiler.batch/pom.xml
@@ -14,10 +14,10 @@
   <parent>
     <artifactId>eclipse.jdt.core</artifactId>
     <groupId>org.eclipse.jdt</groupId>
-    <version>4.27.0-SNAPSHOT</version>
+    <version>4.28.0-SNAPSHOT</version>
   </parent>
   <artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
-  <version>3.33.0-SNAPSHOT</version>
+  <version>3.33.100-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 2346f40..68e6b2d 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2023 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -17,6 +17,7 @@
  *							  Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
  *     Frits Jalvingh    - contributions for bug 533830.
  *     Red Hat Inc.	     - add module-info Javadoc support
+ *     Red Hat Inc.      - add NLS support for Text Blocks
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -847,7 +848,7 @@
 			int i = 0;
 			stringLiteralsLoop: for (; i < stringLiteralsLength; i++) {
 				literal = this.stringLiterals[i];
-				final int literalLineNumber = literal.lineNumber;
+				final int literalLineNumber = literal instanceof TextBlock ? ((TextBlock)literal).endLineNumber : literal.lineNumber;
 				if (lastLineNumber != literalLineNumber) {
 					indexInLine = 1;
 					lastLineNumber = literalLineNumber;
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java
index a4e8a57..e092b6d 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TextBlock.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2019 IBM Corporation and others.
+ * Copyright (c) 2019, 2023 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -14,7 +14,11 @@
 
 public class TextBlock extends StringLiteral {
 
-	public TextBlock(char[] token, int start, int end, int lineNumber) {
+	public int endLineNumber;
+
+	public TextBlock(char[] token, int start, int end, int lineNumber, int endLineNumber) {
 		super(token, start,end, lineNumber);
+		this.endLineNumber= endLineNumber - 1; // line number is 1 based
 	}
+
 }
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
index 5ad8ee8..9947ef6 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java
@@ -39,6 +39,8 @@
  */
 public class IntersectionTypeBinding18 extends ReferenceBinding {
 
+	private static final char[] INTERSECTION_PACKAGE_NAME = "<package intersection>".toCharArray(); //$NON-NLS-1$
+
 	public ReferenceBinding [] intersectingTypes;
 	private ReferenceBinding javaLangObject;
 	int length;
@@ -256,6 +258,11 @@
 	}
 
 	@Override
+	public char[] qualifiedPackageName() {
+		return INTERSECTION_PACKAGE_NAME;
+	}
+
+	@Override
 	public char[] qualifiedSourceName() {
 		StringBuilder qualifiedSourceName = new StringBuilder(16);
 		for (int i = 0; i < this.length; i++) {
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 7637348..d63ca0d 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -2881,7 +2881,7 @@
 			computeRecordComponents();
 			MethodBinding recordExplicitCanon = checkAndGetExplicitCanonicalConstructors();
 			if (recordExplicitCanon != null) {
-				if (recordCanonIndex != -1 ) {
+				if (recordCanonIndex != -1 && resolvedMethods[recordCanonIndex] instanceof SyntheticMethodBinding) {
 					removeSyntheticRecordCanonicalConstructor((SyntheticMethodBinding) resolvedMethods[recordCanonIndex]);
 					resolvedMethods[recordCanonIndex] = null;
 					failed++;
@@ -3098,6 +3098,15 @@
 		// handle forward references to potential default abstract methods
 		addDefaultAbstractMethods();
 		this.tagBits |= TagBits.AreMethodsComplete;
+		if (this.isRecordDeclaration) {
+			/* https://github.com/eclipse-jdt/eclipse.jdt.core/issues/365 */
+			for (int i = 0; i < this.methods.length; i++) {
+				MethodBinding method = this.methods[i];
+				if ((method.tagBits & TagBits.AnnotationSafeVarargs) == 0 && method.sourceMethod() != null) {
+					checkAndFlagHeapPollution(method, method.sourceMethod());
+				}
+			}
+		}
 	}
 	return this.methods;
 }
@@ -3586,7 +3595,10 @@
 				methodDecl.scope.problemReporter().safeVarargsOnNonFinalInstanceMethod(method);
 			}
 		} else {
-			checkAndFlagHeapPollution(method, methodDecl);
+			/* https://github.com/eclipse-jdt/eclipse.jdt.core/issues/365 */
+			if (!this.isRecordDeclaration) {
+				checkAndFlagHeapPollution(method, methodDecl);
+			}
 		}
 	}
 
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
index 2daab75..bb71d4d 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -1841,7 +1841,9 @@
 			}
 			consumeToken();
 			token = readTokenSafely();
-			if (token==TerminalTokens.TokenNameERROR||token==TerminalTokens.TokenNameStringLiteral){
+			if (token==TerminalTokens.TokenNameERROR
+					|| token==TerminalTokens.TokenNameStringLiteral
+					|| token==TerminalTokens.TokenNameIdentifier){
 				regionName = this.scanner.getCurrentTokenString();
 				consumeToken();
 				lastIndex = regionName.length() - 1;
@@ -2007,8 +2009,9 @@
 						indexOfLastComment = indexOfLastSingleComment(commentLine.substring(2),noSingleLineComm);
 						commentStr = commentLine.substring(indexOfLastComment+2);
 					}
-					Scanner commentScanner = new Scanner(false, false, false, this.scanner.sourceLevel, this.scanner.complianceLevel,
-							null, null, false, false);
+					Scanner commentScanner = new JavadocScanner(false, false, false/* nls */, this.scanner.sourceLevel, this.scanner.complianceLevel,
+							null/* taskTags */, null/* taskPriorities */, false/* taskCaseSensitive */, false, true, true);
+
 					if (commentStr.startsWith("//")) { //$NON-NLS-1$
 						commentStr = commentStr.substring(2);
 					}
@@ -2064,6 +2067,25 @@
 											isRegion = true;
 											break;
 										default:
+											if (getRegionValue) {
+												String regionStr = commentScanner.getCurrentTokenString();
+												regionStr = stripQuotes(regionStr);
+												if (START.equals(attribute) &&  regionStr.equals(region)) {
+													insideRegion = true;
+													regionStarted = true;
+												}
+												if (END.equals(attribute)) {
+													if (regionStr.equals(region)) {
+														insideRegion = false;
+													}
+													stack.removeFirst();
+												}
+												if (!END.equals(attribute) && insideRegion) {
+													stack.addFirst(attribute);
+												}
+												attribute = null;
+												getRegionValue = false;
+											}
 											isRegion = false;
 											break;
 									}
@@ -2402,7 +2424,9 @@
 													case TerminalTokens.TokenNameIdentifier:
 														if (processValue) {
 															value = slScanner.getCurrentTokenString();
-															if (map.get(attribute) == null) {
+															if (REGION.equals(attribute)) {
+																regionName = value;
+															} else if (map.get(attribute) == null) {
 																map.put(attribute, value);
 																if ((attribute.equals(SUBSTRING) && (map.get(REGEX) != null))
 																		|| (attribute.equals(REGEX) && (map.get(SUBSTRING) != null))) {
diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 749d4ec..dd012b5 100644
--- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2022 IBM Corporation and others.
+ * Copyright (c) 2000, 2023 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -40,6 +40,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -12325,12 +12326,15 @@
 						textBlock2,
 						this.scanner.startPosition,
 						this.scanner.currentPosition - 1,
-						Util.getLineNumber(this.scanner.startPosition, this.scanner.lineEnds, 0, this.scanner.linePtr));
+						Util.getLineNumber(this.scanner.startPosition, this.scanner.lineEnds, 0, this.scanner.linePtr),
+						Util.getLineNumber(this.scanner.currentPosition - 1, this.scanner.lineEnds, 0, this.scanner.linePtr));
+		this.compilationUnit.recordStringLiteral(textBlock, this.currentElement != null);
 	} else {
 		textBlock = new TextBlock(
 				textBlock2,
 			this.scanner.startPosition,
 			this.scanner.currentPosition - 1,
+			0,
 			0);
 	}
 	pushOnExpressionStack(textBlock);
@@ -13854,19 +13858,16 @@
 	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
 	this.recordNestedMethodLevels.remove(typeDecl);
 	problemReporter().validateJavaFeatureSupport(JavaFeature.RECORDS, typeDecl.sourceStart, typeDecl.sourceEnd);
+	/* create canonical constructor - check for the clash later at binding time */
+	/* https://github.com/eclipse-jdt/eclipse.jdt.core/issues/365 */
+	typeDecl.createDefaultConstructor(!(this.diet && this.dietInt == 0), true);
 	//convert constructor that do not have the type's name into methods
 	ConstructorDeclaration cd = typeDecl.getConstructor(this);
-	if (cd == null) {
-		/* create canonical constructor - check for the clash later at binding time */
-		cd = typeDecl.createDefaultConstructor(!(this.diet && this.dietInt == 0), true);
-	} else {
-		if (cd instanceof CompactConstructorDeclaration
-			|| ((typeDecl.recordComponents == null || typeDecl.recordComponents.length == 0)
-			&& (cd.arguments == null || cd.arguments.length == 0))) {
-			cd.bits |= ASTNode.IsCanonicalConstructor;
-		}
+	if (cd instanceof CompactConstructorDeclaration
+		|| ((typeDecl.recordComponents == null || typeDecl.recordComponents.length == 0)
+		&& (cd.arguments == null || cd.arguments.length == 0))) {
+		cd.bits |= ASTNode.IsCanonicalConstructor;
 	}
-
 	if (this.scanner.containsAssertKeyword) {
 		typeDecl.bits |= ASTNode.ContainsAssertion;
 	}
@@ -13875,7 +13876,10 @@
 	if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
 		typeDecl.bits |= ASTNode.UndocumentedEmptyBlock;
 	}
-	TypeReference superClass = new QualifiedTypeReference(TypeConstants.JAVA_LANG_RECORD, new long[] {0});
+	char[][] sources = TypeConstants.JAVA_LANG_RECORD;
+	long[] poss = new long[sources.length];
+	Arrays.fill(poss, 0);
+	TypeReference superClass = new QualifiedTypeReference(sources, poss);
 	superClass.bits |= ASTNode.IsSuperType;
 	typeDecl.superclass = superClass;
 	typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
index b444b15..e637566 100644
--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core.tests.compiler;singleton:=true
-Bundle-Version: 3.12.2100.qualifier
+Bundle-Version: 3.12.2200.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.core.tests.compiler,
diff --git a/org.eclipse.jdt.core.tests.compiler/pom.xml b/org.eclipse.jdt.core.tests.compiler/pom.xml
index f090fab..ebb0d5f 100644
--- a/org.eclipse.jdt.core.tests.compiler/pom.xml
+++ b/org.eclipse.jdt.core.tests.compiler/pom.xml
@@ -15,11 +15,11 @@
   <parent>
     <artifactId>tests-pom</artifactId>
     <groupId>org.eclipse.jdt</groupId>
-    <version>4.27.0-SNAPSHOT</version>
+    <version>4.28.0-SNAPSHOT</version>
     <relativePath>../tests-pom/</relativePath>
   </parent>
   <artifactId>org.eclipse.jdt.core.tests.compiler</artifactId>
-  <version>3.12.2100-SNAPSHOT</version>
+  <version>3.12.2200-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
@@ -31,7 +31,6 @@
   		<plugin>
   			<groupId>org.eclipse.tycho</groupId>
 	  		<artifactId>tycho-surefire-plugin</artifactId>
-	  		<version>${tycho.version}</version>
 	  		<configuration>
 	  			<includes>
 	  				<include>org/eclipse/jdt/core/tests/compiler/parser/TestAll.class</include>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_15.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_15.java
new file mode 100644
index 0000000..4674cee
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_15.java
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2014 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import java.util.Map;
+
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+import junit.framework.Test;
+
+@SuppressWarnings({ "unchecked", "rawtypes" })
+public class ExternalizeStringLiteralsTest_15 extends AbstractRegressionTest {
+
+private static final JavacTestOptions JAVAC_OPTIONS = new JavacTestOptions("-source 15");
+
+static {
+//	TESTS_NAMES = new String[] { "test000" };
+//	TESTS_NUMBERS = new int[] { 6 };
+//	TESTS_RANGE = new int[] { 11, -1 };
+}
+public ExternalizeStringLiteralsTest_15(String name) {
+	super(name);
+}
+public static Test suite() {
+	return buildMinimalComplianceTestSuite(testClass(), F_15);
+}
+
+public void test001() {
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+	customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+
+	this.runNegativeTest(
+		true,
+		new String[] {
+			"X.java",
+			"public class X\n" +
+			"{\n" +
+			"    String x = \"\"\"\n" +
+			"        abcdefg\n" +
+			"        hijklmn\n" +
+			"        \"\"\";\n" +
+			"}"
+		},
+		null,
+		customOptions,
+		"----------\n" +
+		"1. ERROR in X.java (at line 3)\n" +
+		"	String x = \"\"\"\n" +
+		"        abcdefg\n" +
+		"        hijklmn\n" +
+		"        \"\"\";\n" +
+		"	           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+		"Non-externalized string literal; it should be followed by //$NON-NLS-<n>$\n" +
+		"----------\n",
+		JAVAC_OPTIONS);
+}
+public void test002() {
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+	customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+
+	this.runNegativeTest(
+		true,
+		new String[] {
+			"X.java",
+			"public class X\n" +
+			"{\n" +
+			"    String x = \"\"\"\n" +
+			"        abcdefg\n" +
+			"        hijklmn\n" +
+			"        \"\"\"; //$NON-NLS-1$ //$NON-NLS-2$\n" +
+			"}"
+		},
+		null,
+		customOptions,
+		"----------\n" +
+		"1. ERROR in X.java (at line 6)\n" +
+		"	\"\"\"; //$NON-NLS-1$ //$NON-NLS-2$\n" +
+		"	                   ^^^^^^^^^^^^^\n" +
+		"Unnecessary $NON-NLS$ tag\n" +
+		"----------\n",
+		JAVAC_OPTIONS);
+}
+public void test003() {
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.WARNING);
+	customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+
+	this.runNegativeTest(
+		true,
+		new String[] {
+			"X.java",
+			"public class X\n" +
+			"{\n" +
+			"    String x = \"\"\"\n" +
+			"        abcdefg\n" +
+			"        hijklmn\n" +
+			"        \"\"\";\n" +
+			"    @SuppressWarnings(\"nls\")\n" +
+			"    void foo() {\n" +
+			"        String x2 = \"\"\"\n" +
+			"            abcdefg\n" +
+			"            hijklmn\n" +
+			"            \"\"\";\n" +
+			"    }\n" +
+			"}"
+		},
+		null,
+		customOptions,
+		"----------\n" +
+		"1. WARNING in X.java (at line 3)\n" +
+		"	String x = \"\"\"\n" +
+		"        abcdefg\n" +
+		"        hijklmn\n" +
+		"        \"\"\";\n" +
+		"	           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+		"Non-externalized string literal; it should be followed by //$NON-NLS-<n>$\n" +
+		"----------\n",
+		JAVAC_OPTIONS);
+}
+public void test004() {
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+	customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+	this.runNegativeTest(
+		true,
+		new String[] {
+			"X.java",
+			"class X {\n" +
+			"\n" +
+			"	void foo() {\n" +
+			"		String s6 = \"\"\"\n" +
+			"			SUCCESS\n" +
+			"			\"\"\";\n" +
+			"		System.out.println(s6);\n" +
+			"	}\n" +
+			"}",
+		},
+		null, customOptions,
+		"----------\n" +
+		"1. ERROR in X.java (at line 4)\n" +
+		"	String s6 = \"\"\"\n" +
+		"			SUCCESS\n" +
+		"			\"\"\";\n" +
+		"	            ^^^^^^^^^^^^^^^^^^^^^\n" +
+		"Non-externalized string literal; it should be followed by //$NON-NLS-<n>$\n" +
+		"----------\n",
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+}
+public void test005() {
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.WARNING);
+	customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+	this.runConformTest(
+		new String[] {
+			"X.java",
+			"public class X {\n" +
+			"\n" +
+			"	public static void main(String[] args) {\n" +
+			"		String s6 = \"\"\"\n" +
+			"			SUCCESS\n" +
+			"			\"\"\"; //$NON-NLS-1$\n" +
+			"		System.out.println(s6);\n" +
+			"	}\n" +
+			"}",
+		},
+		"SUCCESS",
+		null,
+		true,
+		null,
+		customOptions,
+		null);
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=237245
+public void test006() {
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.ERROR);
+	customOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+	customOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+	this.runNegativeTest(
+		new String[] {
+			"X.java",
+			"public class X {\n" +
+			"	@Annot({\n" +
+			"		@A(name = \"\"\"\n" +
+			"           name\n" +
+			"           \"\"\", //$NON-NLS-1$\n" +
+			" 		value = \"\"\"\n" +
+			"           Test\n" +
+			"           \"\"\") //$NON-NLS-1$\n" +
+			"	})\n" +
+			"	@X2(\"\"\"\n" +
+			"   \"\"\") //$NON-NLS-1$\n" +
+			"	void foo() {\n" +
+			"	}\n" +
+			"}\n" +
+			"@interface Annot {\n" +
+			"	A[] value();\n" +
+			"}\n" +
+			"@interface A {\n" +
+			"	String name();\n" +
+			"	String value();\n" +
+			"}\n" +
+			"@interface X2 {\n" +
+			"	String value();\n" +
+			"}",
+		},
+		"----------\n" +
+		"1. ERROR in X.java (at line 5)\n" +
+		"	\"\"\", //$NON-NLS-1$\n" +
+		"	     ^^^^^^^^^^^^^\n" +
+		"Unnecessary $NON-NLS$ tag\n" +
+		"----------\n" +
+		"2. ERROR in X.java (at line 8)\n" +
+		"	\"\"\") //$NON-NLS-1$\n" +
+		"	     ^^^^^^^^^^^^^\n" +
+		"Unnecessary $NON-NLS$ tag\n" +
+		"----------\n" +
+		"3. ERROR in X.java (at line 11)\n" +
+		"	\"\"\") //$NON-NLS-1$\n" +
+		"	     ^^^^^^^^^^^^^\n" +
+		"Unnecessary $NON-NLS$ tag\n" +
+		"----------\n",
+		null,
+		true,
+		customOptions);
+}
+public static Class testClass() {
+	return ExternalizeStringLiteralsTest_15.class;
+}
+}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiterals15Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_1_5.java
similarity index 97%
rename from org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiterals15Test.java
rename to org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_1_5.java
index bc8501f..31cc9e4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiterals15Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ExternalizeStringLiteralsTest_1_5.java
@@ -21,14 +21,14 @@
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 
 @SuppressWarnings({ "unchecked", "rawtypes" })
-public class ExternalizeStringLiterals15Test extends AbstractRegressionTest {
+public class ExternalizeStringLiteralsTest_1_5 extends AbstractRegressionTest {
 
 static {
 //	TESTS_NAMES = new String[] { "test000" };
 //	TESTS_NUMBERS = new int[] { 7 };
 //	TESTS_RANGE = new int[] { 11, -1 };
 }
-public ExternalizeStringLiterals15Test(String name) {
+public ExternalizeStringLiteralsTest_1_5(String name) {
 	super(name);
 }
 public static Test suite() {
@@ -274,6 +274,6 @@
 		customOptions);
 }
 public static Class testClass() {
-	return ExternalizeStringLiterals15Test.class;
+	return ExternalizeStringLiteralsTest_1_5.class;
 }
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
index 9932347..e0a02bc 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
@@ -576,6 +576,7 @@
 			"----------\n");
 	}
 	public void testBug550750_025() {
+		getPossibleComplianceLevels();
 		this.runNegativeTest(
 				new String[] {
 						"X.java",
@@ -602,9 +603,15 @@
 			"	record Point(int myInt, int myZ, int myZ) implements I {\n" +
 			"	                                     ^^^\n" +
 			"Duplicate component myZ in record\n" +
+			"----------\n" +
+			"3. ERROR in X.java (at line 6)\n" +
+			"	record Point(int myInt, int myZ, int myZ) implements I {\n" +
+			"	                                     ^^^\n" +
+			"Duplicate parameter myZ\n" +
 			"----------\n");
 	}
 	public void testBug550750_026() {
+		getPossibleComplianceLevels();
 		this.runNegativeTest(
 				new String[] {
 						"X.java",
@@ -634,8 +641,18 @@
 			"----------\n" +
 			"3. ERROR in X.java (at line 6)\n" +
 			"	record Point(int myInt, int myInt, int myInt, int myZ) implements I {\n" +
+			"	                            ^^^^^\n" +
+			"Duplicate parameter myInt\n" +
+			"----------\n" +
+			"4. ERROR in X.java (at line 6)\n" +
+			"	record Point(int myInt, int myInt, int myInt, int myZ) implements I {\n" +
 			"	                                       ^^^^^\n" +
 			"Duplicate component myInt in record\n" +
+			"----------\n" +
+			"5. ERROR in X.java (at line 6)\n" +
+			"	record Point(int myInt, int myInt, int myInt, int myZ) implements I {\n" +
+			"	                                       ^^^^^\n" +
+			"Duplicate parameter myInt\n" +
 			"----------\n");
 	}
 	public void testBug550750_027() {
@@ -1112,6 +1129,7 @@
 			"----------\n");
 	}
 	public void testBug553152_008() {
+		getPossibleComplianceLevels();
 		this.runNegativeTest(
 				new String[] {
 						"X.java",
@@ -1133,22 +1151,17 @@
 						"interface I {}\n"
 				},
 			"----------\n" +
-			"1. ERROR in X.java (at line 7)\n" +
-			"	public Point {\n" +
-			"	       ^^^^^\n" +
-			"Duplicate method Point(Integer, int) in type Point\n" +
-			"----------\n" +
-			"2. ERROR in X.java (at line 8)\n" +
+			"1. ERROR in X.java (at line 8)\n" +
 			"	this.myInt = 0;\n" +
 			"	^^^^^^^^^^\n" +
 			"Illegal explicit assignment of a final field myInt in compact constructor\n" +
 			"----------\n" +
-			"3. ERROR in X.java (at line 9)\n" +
+			"2. ERROR in X.java (at line 9)\n" +
 			"	this.myZ = 0;\n" +
 			"	^^^^^^^^\n" +
 			"Illegal explicit assignment of a final field myZ in compact constructor\n" +
 			"----------\n" +
-			"4. ERROR in X.java (at line 11)\n" +
+			"3. ERROR in X.java (at line 11)\n" +
 			"	public Point(Integer myInt, int myZ) {\n" +
 			"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
 			"Duplicate method Point(Integer, int) in type Point\n" +
@@ -7361,6 +7374,7 @@
 //Test that in presence of an explicit canonical constructor that is NOT annotated with @SafeVarargs,
 // we don't report the warning on the record type but report on the explicit canonical constructor
 public void testBug563182_02() {
+	getPossibleComplianceLevels();
 	Map<String, String> customOptions = getCompilerOptions();
 	this.runNegativeTest(
 		new String[] {
@@ -7388,6 +7402,7 @@
 //Test that in presence of an explicit canonical constructor that IS annotated with @SafeVarargs,
 //we don't report the warning on neither the record type nor the explicit canonical constructor
 public void testBug563182_03() {
+	getPossibleComplianceLevels();
 	Map<String, String> customOptions = getCompilerOptions();
 	this.runNegativeTest(
 		new String[] {
@@ -7437,6 +7452,7 @@
 //Test that in presence of a compact canonical constructor that IS annotated with @SafeVarargs,
 //we don't report the warning on neither the record type nor the compact canonical constructor
 public void testBug563182_05() {
+	getPossibleComplianceLevels();
 	Map<String, String> customOptions = getCompilerOptions();
 	this.runNegativeTest(
 		new String[] {
@@ -8992,6 +9008,7 @@
 	options.put(CompilerOptions.OPTION_ReportSpecialParameterHidingField, CompilerOptions.DISABLED);
 }
 public void testBug573195_001() throws Exception {
+	getPossibleComplianceLevels();
 	runConformTest(
 			new String[] {
 					"X.java",
@@ -9009,19 +9026,20 @@
 				},
 				"1");
 	String expectedOutput = // constructor
-			"  // Method descriptor #12 (I)V\n" +
+			"  // Method descriptor #8 (I)V\n" +
 			"  // Stack: 2, Locals: 2\n" +
-			"  protected X$R(int arg0);\n" +
+			"  protected X$R(int i);\n" +
 			"     0  aload_0 [this]\n" +
-			"     1  invokespecial java.lang.Record() [36]\n" +
+			"     1  invokespecial java.lang.Record() [10]\n" +
 			"     4  aload_0 [this]\n" +
-			"     5  iload_1 [arg0]\n" +
-			"     6  putfield X$R.i : int [20]\n" +
+			"     5  iload_1 [i]\n" +
+			"     6  putfield X$R.i : int [13]\n" +
 			"     9  return\n";
 	RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X$R.class", ClassFileBytesDisassembler.SYSTEM);
 }
 
 public void testBug574284_001() throws Exception {
+	getPossibleComplianceLevels();
 	runConformTest(
 			new String[] {
 					"X.java",
@@ -9042,17 +9060,17 @@
 			},
 		"0");
 	String expectedOutput = // constructor
-			"  // Method descriptor #14 (Z[I)V\n" +
+			"  // Method descriptor #10 (Z[I)V\n" +
 			"  // Stack: 2, Locals: 3\n" +
-			"  X$Rec(boolean arg0, int... arg1);\n" +
+			"  X$Rec(boolean isHidden, int... indexes);\n" +
 			"     0  aload_0 [this]\n" +
-			"     1  invokespecial java.lang.Record() [41]\n" +
+			"     1  invokespecial java.lang.Record() [12]\n" +
 			"     4  aload_0 [this]\n" +
-			"     5  iload_1 [arg0]\n" +
-			"     6  putfield X$Rec.isHidden : boolean [21]\n" +
+			"     5  iload_1 [isHidden]\n" +
+			"     6  putfield X$Rec.isHidden : boolean [15]\n" +
 			"     9  aload_0 [this]\n" +
-			"    10  aload_2 [arg1]\n" +
-			"    11  putfield X$Rec.indexes : int[] [24]\n" +
+			"    10  aload_2 [indexes]\n" +
+			"    11  putfield X$Rec.indexes : int[] [17]\n" +
 			"    14  return\n";
 	RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "X$Rec.class", ClassFileBytesDisassembler.SYSTEM);
 
@@ -9173,4 +9191,36 @@
 		false,
 		options);
 }
+
+public void testIssue365_001() throws Exception {
+	getPossibleComplianceLevels();
+	runConformTest(
+			new String[] {
+					"A.java",
+					"import java.util.Collections;\n" +
+					"import java.util.List;\n" +
+					"public record A(List<String> names) {\n" +
+					"    public A(String name) {\n" +
+					"        this(Collections.singletonList(name));\n" +
+					"    }\n" +
+					"    public static void main(String[] args) {\n" +
+					"        System.out.println(0);\n" +
+					"    }" +
+					"}\n"
+			},
+		"0");
+	String expectedOutput = // constructor
+			"  // Method descriptor #10 (Ljava/util/List;)V\n" +
+			"  // Signature: (Ljava/util/List<Ljava/lang/String;>;)V\n" +
+			"  // Stack: 2, Locals: 2\n" +
+			"  public A(java.util.List names);\n" +
+			"     0  aload_0 [this]\n" +
+			"     1  invokespecial java.lang.Record() [13]\n" +
+			"     4  aload_0 [this]\n" +
+			"     5  aload_1 [names]\n" +
+			"     6  putfield A.names : java.util.List [16]\n" +
+			"     9  return\n";
+	RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "A.class", ClassFileBytesDisassembler.SYSTEM);
+
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
index 4445a98..40b0186 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
@@ -118,7 +118,7 @@
 	since_1_5.add(BatchCompilerTest.class);
 	since_1_5.add(NullAnnotationBatchCompilerTest.class);
 	since_1_5.add(ConcurrentBatchCompilerTest.class);
-	since_1_5.add(ExternalizeStringLiterals15Test.class);
+	since_1_5.add(ExternalizeStringLiteralsTest_1_5.class);
 	since_1_5.add(Deprecated15Test.class);
 	since_1_5.add(InnerEmulationTest_1_5.class);
 	since_1_5.add(AssignmentTest_1_5.class);
@@ -210,6 +210,7 @@
 	 since_15.add(Unicode13Test.class);
 	 since_15.add(BatchCompilerTest_15.class);
 	 since_15.add(TextBlockTest.class);
+	 since_15.add(ExternalizeStringLiteralsTest_15.class);
 
 	 // add 16 specific test here (check duplicates)
 	 ArrayList since_16 = new ArrayList();
diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
index dbb452b..e3402e3 100644
--- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core.tests.model;singleton:=true
-Bundle-Version: 3.11.400.qualifier
+Bundle-Version: 3.11.600.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.core.tests,
diff --git a/org.eclipse.jdt.core.tests.model/pom.xml b/org.eclipse.jdt.core.tests.model/pom.xml
index a0c04d4..ac0fc3b 100644
--- a/org.eclipse.jdt.core.tests.model/pom.xml
+++ b/org.eclipse.jdt.core.tests.model/pom.xml
@@ -15,11 +15,11 @@
   <parent>
     <artifactId>tests-pom</artifactId>
     <groupId>org.eclipse.jdt</groupId>
-    <version>4.27.0-SNAPSHOT</version>
+    <version>4.28.0-SNAPSHOT</version>
     <relativePath>../tests-pom/</relativePath>
   </parent>
   <artifactId>org.eclipse.jdt.core.tests.model</artifactId>
-  <version>3.11.400-SNAPSHOT</version>
+  <version>3.11.600-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
index 33bc581..2ca29d1 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
@@ -693,6 +693,9 @@
 	protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance) throws CoreException, IOException {
 		addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, null);
 	}
+	protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance, boolean exported) throws CoreException, IOException {
+		addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, null, exported);
+	}
 	protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String compliance) throws CoreException, IOException {
 		addLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, null, null, compliance, null);
 	}
@@ -720,6 +723,19 @@
 			String[] librariesExclusionPatterns,
 			String compliance,
 			Map options) throws CoreException, IOException {
+		addLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, librariesInclusionPatterns, librariesExclusionPatterns, compliance, options, true);
+	}
+	private void addLibrary(
+			IJavaProject javaProject,
+			String jarName,
+			String sourceZipName,
+			String[] pathAndContents,
+			String[] nonJavaResources,
+			String[] librariesInclusionPatterns,
+			String[] librariesExclusionPatterns,
+			String compliance,
+			Map options,
+			boolean exported) throws CoreException, IOException {
 		IProject project = createLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, compliance, options);
 		String projectPath = '/' + project.getName() + '/';
 		addLibraryEntry(
@@ -729,7 +745,7 @@
 			null,
 			toIPathArray(librariesInclusionPatterns),
 			toIPathArray(librariesExclusionPatterns),
-			true
+			exported
 		);
 	}
 	protected IProject createLibrary(
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java
index b34ad05..b2b70d1 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests11.java
@@ -17,6 +17,9 @@
 import junit.framework.Test;
 
 public class CompletionTests11 extends AbstractJavaModelCompletionTests {
+	static {
+		// TESTS_NAMES = new String[] {};
+	}
 
 public CompletionTests11(String name) {
 	super(name);
@@ -58,4 +61,190 @@
 		requestor.getResults());
 }
 
+public void test_members_matching_paramater_name_on_getter() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Smart.java",
+			"package test;\n" +
+					"public class Smart {\n" +
+					"	public static void persist(Task task) {	\n" +
+					"		create(task.);\n" +
+					"	}\n" +
+					"	public static void create(String name, boolean completed, int details) {}\n" +
+					"	public static class Task {\n" +
+					"		public String getName() {return null;}\n" +
+					"		public boolean isCompleted() {return false;}\n" +
+					"		public String details() {return null;}\n" +
+					"	}\n" +
+					"}\n");
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "task.";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertTrue(requestor.getResults(), requestor.getResults()
+			.contains("getName[METHOD_REF]{getName(), Ltest.Smart$Task;, ()Ljava.lang.String;, getName, null, " +
+					(R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_CASE + R_EXACT_EXPECTED_TYPE
+							+ R_NON_STATIC + R_NON_RESTRICTED + R_RESOLVED)
+					+ "}"));
+}
+
+public void test_members_matching_paramater_name_on_non_getter() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Smart.java",
+			"package test;\n" +
+					"public class Smart {\n" +
+					"	public static void persist(Task task) {	\n" +
+					"		create(task.getName(), false, task.);\n" +
+					"	}\n" +
+					"	public static void create(String name, boolean completed, String details, String assignee) {}\n"
+					+
+					"	public static class Task {\n" +
+					"		public String getName() {return null;}\n" +
+					"		public boolean isCompleted() {return false;}\n" +
+					"		public String details() {return null;}\n" +
+					"		public int getAssignee() {return null;}\n" +
+					"	}\n" +
+					"}\n");
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "task.";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertTrue(requestor.getResults(), requestor.getResults()
+			.contains("details[METHOD_REF]{details(), Ltest.Smart$Task;, ()Ljava.lang.String;, details, null, " +
+					(R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_CASE + R_EXACT_EXPECTED_TYPE
+							+ R_NON_STATIC + R_NON_RESTRICTED + R_RESOLVED)
+					+ "}"));
+}
+
+public void test_members_matching_paramater_name_on_boolean_getter() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Smart.java",
+			"package test;\n" +
+					"public class Smart {\n" +
+					"	public static void persist(Task task) {	\n" +
+					"		create(task.getName(), task.);\n" +
+					"	}\n" +
+					"	public static void create(String name, boolean completed, String details, String assignee) {}\n"
+					+
+					"	public static class Task {\n" +
+					"		public String getName() {return null;}\n" +
+					"		public boolean isCompleted() {return false;}\n" +
+					"		public String details() {return null;}\n" +
+					"		public int getAssignee() {return null;}\n" +
+					"	}\n" +
+					"}\n");
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "task.";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertTrue(requestor.getResults(), requestor.getResults()
+			.contains(
+					"isCompleted[METHOD_REF]{isCompleted(), Ltest.Smart$Task;, ()Z, isCompleted, null, "
+							+
+							(R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_CASE + R_EXACT_EXPECTED_TYPE
+									+ R_NON_STATIC + R_NON_RESTRICTED + R_RESOLVED)
+							+ "}"));
+}
+
+public void test_members_matching_paramater_name_on_wrong_type() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Smart.java",
+			"package test;\n" +
+					"public class Smart {\n" +
+					"	public static void persist(Task task) {	\n" +
+					"		create(task.getName(), false, \"\", task.);\n" +
+					"	}\n" +
+					"	public static void create(String name, boolean completed, String details, String assignee) {}\n"
+					+
+					"	public static class Task {\n" +
+					"		public String getName() {return null;}\n" +
+					"		public boolean isCompleted() {return false;}\n" +
+					"		public String details() {return null;}\n" +
+					"		public int getAssignee() {return null;}\n" +
+					"	}\n" +
+					"}\n");
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "task.";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertFalse(requestor.getResults(), requestor.getResults()
+			.contains(
+					"getAssignee[METHOD_REF]{getAssignee(), Ltest.Smart$Task;, ()Ljava.lang.String;, getAssignee, null, "
+							+
+							(R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_EXACT_EXPECTED_TYPE + R_NON_STATIC
+									+ R_NON_RESTRICTED + R_RESOLVED)
+							+ "}"));
+}
+
+public void test_members_matching_paramater_name_on_field() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Smart.java",
+			"package test;\n" +
+					"public class Smart {\n" +
+					"	public static void persist(Task task) {	\n" +
+					"		create(task.getName(), false, \"\", task.);\n" +
+					"	}\n" +
+					"	public static void create(String name, boolean completed, String details, String assignee) {}\n"
+					+
+					"	public static class Task {\n" +
+					"		public String getName() {return null;}\n" +
+					"		public boolean isCompleted() {return false;}\n" +
+					"		public String details() {return null;}\n" +
+					"		public int getAssignee() {return null;}\n" +
+					"		public String assignee;}\n" +
+					"	}\n" +
+					"}\n");
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "task.";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertTrue(requestor.getResults(), requestor.getResults()
+			.contains(
+					"assignee[FIELD_REF]{assignee, Ltest.Smart$Task;, Ljava.lang.String;, assignee, null, "
+							+
+							(R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_CASE + R_EXACT_EXPECTED_TYPE
+									+ R_NON_STATIC + R_NON_RESTRICTED + R_RESOLVED)
+							+ "}"));
+}
+
+public void test_members_matching_paramater_name_on_local_variable() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/test/Smart.java",
+			"package test;\n" +
+					"public class Smart {\n" +
+					"	public static void persist(String name, String shortName) {	\n" +
+					"		create(null, false, null, null);\n" +
+					"	}\n" +
+					"	public static void create(String name, boolean completed, String details, String assignee) {}\n"
+					+
+					"}\n");
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "create(";
+	int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertTrue(requestor.getResults(), requestor.getResults()
+			.contains(
+					"name[LOCAL_VARIABLE_REF]{name, null, Ljava.lang.String;, name, null, "
+							+
+							(R_DEFAULT + R_INTERESTING + R_EXACT_NAME + R_CASE + R_NON_STATIC + R_NON_RESTRICTED
+									+ R_UNQUALIFIED)
+							+ "}"));
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
index 5ab2d77..864669c 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
@@ -6753,4 +6753,50 @@
 	assertTrue(String.format("Result doesn't contain expected methods (%s)", result),
 			result.contains("new[KEYWORD]{new, null, null, new, null, 49}"));
 }
+// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/767
+public void testGH767() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/Foo.java",
+					"public class Foo {\n"
+					+ "    public void foo() {\n"
+					+ "			\"abc\".substring(i)."
+					+ "    }\n"
+					+ "}");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "substring(i).";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, new NullProgressMonitor());
+
+	String result = requestor.getResults();
+	assertTrue(String.format("Result doesn't contain expected method (%s)", result),
+			result.contains("length[METHOD_REF]{length(), Ljava.lang.String;, ()I, length, null, 60}\n"));
+}
+// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/831
+public void testIntersection18GH831() throws Exception {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/Foo.java",
+			"public class Foo {\n"
+			+ "    public void foo() {\n"
+			+ "			java.util.Optional.of(true ? 0 : \"\")."
+			+ "    }\n"
+			+ "}");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "of(true ? 0 : \"\").";
+	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, new NullProgressMonitor());
+
+	String result = requestor.getResults();
+	assertTrue(String.format("Result doesn't contain expected method (%s)", result),
+	result.contains("get[METHOD_REF]{get(), Ljava.util.Optional<Ljava.io.Serializable;>;, ()Ljava.io.Serializable;, get, null, 60}\n"));
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java
index 8123f78..ba6ade1 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs16Tests.java
@@ -16,9 +16,11 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.WorkingCopyOwner;
 import org.eclipse.jdt.core.search.IJavaSearchScope;
@@ -621,6 +623,44 @@
 
 			}
 		}
+
+	/*
+	 * A record defined in a JRE class causes an AIOOBE during a call hierarchy computation.
+	 * The record is encountered while indexing a Java project with a snippet,
+	 * when computing the call hierarchy of a field in the snippet.
+	 * The same AIOOBE can be reproduced with a reference search in the same snippet.
+	 * https://github.com/eclipse-jdt/eclipse.jdt.core/issues/790
+	 */
+	public void testAIOOBEForRecordClassGh790() throws Exception {
+		String testProjectName = "gh790AIOOBEForRecordClass";
+		try {
+			IJavaProject project = createJava16Project(testProjectName, new String[] {"src"});
+			String packageFolder = "/" + testProjectName + "/src/test";
+			createFolder(packageFolder);
+			String testSource =
+				"package test;\n" +
+				"public class Test {\n" +
+				"protected final java.util.HashMap<?, ?> internal;\n" +
+				"protected final java.util.HashMap<?, ?> map;\n" +
+				"    public Test() {\n" +
+				"	    internal = new java.util.HashMap<>();\n" +
+				"	    map = internal;\n" +
+				"    }\n" +
+			    "}\n";
+			createFile(packageFolder + "/Test.java", testSource);
+			buildAndExpectNoProblems(project);
+
+			IType type = project.findType("test.Test");
+			IField field = type.getField("internal");
+			search(field, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+			assertSearchResults(
+					"src/test/Test.java test.Test() [internal] EXACT_MATCH\n" +
+					"src/test/Test.java test.Test() [internal] EXACT_MATCH");
+		} finally {
+			deleteProject(testProjectName);
+		}
+	}
+
 }
 
 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
index e7c98ee..7ecabda 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
@@ -15422,7 +15422,7 @@
 }
 
 /*
- * Test that having a module conflict in projects that are on the compile classpath
+ * Test that having a module conflict in libraries that are on the compile classpath
  * (and not the compile module path) doesn't affect searching for types in those projects.
  * https://github.com/eclipse-jdt/eclipse.jdt.core/issues/675
  */
@@ -15482,6 +15482,82 @@
 	}
 }
 
+/**
+ * A modular project refers to a modular library defining a type {@code TestClass},
+ * this project also references a non-modular project on its classpath.
+ * The non-modular project uses a non-modular library that defines the same type {@code TestClass}.
+ * Since neither project exports the library, there is no compile error and no module conflict for the type.
+ * This test ensures the search doesn't run into a module conflict due to not considering whether the libraries are exported.
+ *
+ * Originally the problem was observed by using a Java 8 project and a Java 11 project,
+ * with {@code java.util.Locale} as the type that causes the search to run into a module conflict.
+ *
+ * https://github.com/eclipse-jdt/eclipse.jdt.core/issues/723
+ */
+public void testModuleConflictGh723() throws Exception {
+	String projectName = "gh723Project";
+	String modularProjectName = "gh723ProjectModular";
+	try {
+		IJavaProject project = createJavaProject(projectName, new String[] {"src"}, new String[] {"JCL11_LIB"}, "bin", "11");
+		IJavaProject modularProject = createJavaProject(modularProjectName, new String[] {"src"}, new String[] {"JCL11_LIB"}, "bin", "11");
+
+		createFolder("/" + projectName + "/src/test/");
+		createFile("/" + projectName + "/src/test/Test.java",
+				"package test;\n" +
+				"public class Test {\n" +
+				"  public static void test(testpackage.TestClass t) {\n" +
+				"  }\n" +
+				"}");
+
+		createFolder("/" + modularProjectName + "/src/testmodular/");
+		createFile("/" + modularProjectName + "/src/testmodular/TestModular.java",
+				"package testmodular;\n" +
+				"public class TestModular {\n" +
+				"  public void testModular() {\n" +
+				"      test.Test.test(null);\n" +
+				"  }\n" +
+				"}");
+
+		String ambiguousTypeDefinition =
+				"package testpackage;\n" +
+				"public class TestClass {\n" +
+				"}";
+
+		addLibrary(project,
+				"libGh723.jar",
+				"libGh723.src.zip",
+				new String[] {
+						"testpackage/TestClass.java",
+						ambiguousTypeDefinition },
+				JavaCore.VERSION_1_8,
+				false);
+
+		addModularLibrary(modularProject,
+				"libGh723_modular.jar",
+				"libGh723_modular.src.zip",
+				new String[] {
+						"module-info.java",
+						"module testmodule {\n" +
+						"  exports testpackage;\n" +
+						"}",
+						"testpackage/TestClass.java",
+						ambiguousTypeDefinition },
+				JavaCore.VERSION_11);
+
+		addClasspathEntry(modularProject, JavaCore.newProjectEntry(project.getPath()));
+		buildAndExpectNoProblems(project, modularProject);
+
+		IType type = project.findType("test.Test");
+		IMethod method = type.getMethod("test", new String [] {"Qtestpackage.TestClass;"});
+		search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
+		assertSearchResults(
+				"src/testmodular/TestModular.java void testmodular.TestModular.testModular() [test(null)] EXACT_MATCH");
+	} finally {
+		deleteProject(projectName);
+		deleteProject(modularProjectName);
+	}
+}
+
 private static String toString(char[][] modules) {
 	StringBuilder sb = new StringBuilder();
 	for (char[] m : modules) {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
index 470c020..2b81638 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
index c7811cb..3e3f73d 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
@@ -5604,7 +5604,7 @@
 		try {
 			IClasspathAttribute[] attributes = {
 					JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"),
-					JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.desktop=/missing.path::java.base=/org.astro.patch/src:/org.astro.patch/src2")
+					JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.desktop=/missing.path::java.base=/org.astro.patch/src"+File.pathSeparator+"/org.astro.patch/src2")
 			};
 			IJavaProject patchProject = createJava9ProjectWithJREAttributes("org.astro.patch", new String[]{"src", "src2"}, attributes);
 
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index b6d7e88..2d8c4b2 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
-Bundle-Version: 3.33.0.OTDT_r282_qualifier
+Bundle-Version: 3.33.100.OTDT_r282_qualifier
 Bundle-Activator: org.eclipse.jdt.core.JavaCore
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -52,7 +52,7 @@
  org.eclipse.core.filesystem;bundle-version="[1.7.0,2.0.0)",
  org.eclipse.text;bundle-version="[3.6.0,4.0.0)",
  org.eclipse.team.core;bundle-version="[3.1.0,4.0.0)";resolution:=optional,
- org.eclipse.jdt.core.compiler.batch;bundle-version="3.33.0.OTDT_r282";visibility:=reexport
+ org.eclipse.jdt.core.compiler.batch;bundle-version="3.33.100.OTDT_r282";visibility:=reexport
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Eclipse-ExtensibleAPI: true
 Bundle-ActivationPolicy: lazy
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 d54d617..5cde377 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
@@ -25,13 +25,15 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.StreamSupport;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -261,7 +263,7 @@
 import org.eclipse.jdt.internal.core.SourceType;
 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
 import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
-import org.eclipse.jdt.internal.core.search.matching.IndexBasedJavaSearchEnvironment;
+import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
 import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 import org.eclipse.objectteams.otdt.core.IOTType;
@@ -501,8 +503,7 @@
 
 //{ObjectTeams: prefixes for callout-to-field:
 	private static final char[] SET = "set".toCharArray(); //$NON-NLS-1$
-
-	private static final char[] GET = "get".toCharArray(); //$NON-NLS-1$
+	// GET is declared below (regular JDT)
 // SH}
 
 	public static char[] createBindingKey(char[] packageName, char[] typeName) {
@@ -722,6 +723,8 @@
 		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
 	private final static char[] JAVA_LANG_NAME =
 		CharOperation.concatWith(JAVA_LANG, '.');
+	private final static char[] GET = "get".toCharArray(); //$NON-NLS-1$
+	private final static char[] IS = "is".toCharArray(); //$NON-NLS-1$
 
 	private final static int NONE = 0;
 	private final static int SUPERTYPE = 1;
@@ -5022,16 +5025,28 @@
 		}
 		return 0;
 	}
-	int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
-		if(CharOperation.equals(token, proposalName, true)) {
+
+	int computeRelevanceForCaseMatching(char[][] tokens, char[] proposalName) {
+		int finalRelevance = 0;
+		for (int i = 0; i < tokens.length; i++) {
+			int relevance = computeRelevanceForCaseMatching(tokens[i], proposalName);
+			if (relevance > finalRelevance) {
+				finalRelevance = relevance;
+			}
+		}
+		return finalRelevance;
+	}
+
+	int computeRelevanceForCaseMatching(char[] token, char[] proposalName) {
+		if (CharOperation.equals(token, proposalName, true)) {
 			return R_EXACT_NAME + R_CASE;
-		} else if(CharOperation.equals(token, proposalName, false)) {
+		} else if (CharOperation.equals(token, proposalName, false)) {
 			return R_EXACT_NAME;
 		} else if (CharOperation.prefixEquals(token, proposalName, false)) {
 			if (CharOperation.prefixEquals(token, proposalName, true))
 				return R_CASE;
-		} else if (this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, proposalName)){
-				return R_CAMEL_CASE;
+		} else if (this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, proposalName)) {
+			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)) {
@@ -7303,6 +7318,9 @@
 				}
 			}
 		}
+
+		char[] boostMatches = findParameterNameAtLocationFromAssistParent(new ObjectVector());
+
 		// Inherited fields which are hidden by subclasses are filtered out
 		// No visibility checks can be performed without the scope & invocationSite
 
@@ -7481,6 +7499,9 @@
 			relevance += computeRelevanceForResolution();
 			relevance += computeRelevanceForInterestingProposal(field);
 			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
+			if(boostMatches.length > 0) {
+				relevance += computeRelevanceForCaseMatching(boostMatches, field.name);
+			}
 			int computeRelevanceForExpectingType = computeRelevanceForExpectingType(field.type);
 			if(this.strictMatchForExtepectedType && computeRelevanceForExpectingType <= 0) {
 				continue;
@@ -9875,6 +9896,14 @@
 		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
 		int minArgLength = argTypes == null ? 0 : argTypes.length;
 
+		char[][] boostMatches = new char[0][];
+		char[] parameterName = findParameterNameAtLocationFromAssistParent(new ObjectVector());
+		if(parameterName.length > 0) {
+			char[] nameForMethods = capitalize(parameterName);
+			boostMatches = new char[][] { parameterName, CharOperation.concat(GET, nameForMethods),
+					CharOperation.concat(IS, nameForMethods) };
+		}
+
 		next : for (int f = methods.length; --f >= 0;) {
 			MethodBinding method = methods[f];
 
@@ -10128,6 +10157,9 @@
 			relevance += computeRelevanceForResolution();
 			relevance += computeRelevanceForInterestingProposal();
 			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+			if(boostMatches.length > 0) {
+				relevance += computeRelevanceForCaseMatching(boostMatches, method.selector);
+			}
 			int computeRelevanceForExpectingType = computeRelevanceForExpectingType(method.returnType);
 			if(this.strictMatchForExtepectedType && computeRelevanceForExpectingType <= 0) {
 				continue;
@@ -10292,6 +10324,55 @@
 
 		methodsFound.addAll(newMethodsFound);
 	}
+
+	private char[] capitalize(char[] name) {
+		char[] result = new char[name.length];
+		for (int i = 0; i < name.length; i++) {
+			if (i == 0) {
+				result[i] = Character.toUpperCase(name[i]);
+			} else {
+				result[i] = name[i];
+			}
+		}
+		return result;
+	}
+
+	private char[] findParameterNameAtLocationFromAssistParent(ObjectVector methodsFound) {
+		char[] parameterName = new char[0];
+		MethodBinding[] candidates;
+		final MessageSend parent;
+		if (this.parser.assistNodeParent instanceof MessageSend) {
+			parent = (MessageSend) this.parser.assistNodeParent;
+			candidates = Optional.ofNullable(parent.actualReceiverType)
+					.or(() -> Optional.ofNullable(parent.receiver).map(r -> r.resolvedType))
+					.map(t -> t.getMethods(parent.selector)).orElse(new MethodBinding[0]);
+		} else if (this.parser.assistNode instanceof MessageSend) {
+			parent = (MessageSend) this.parser.assistNode;
+			candidates = StreamSupport.stream(methodsFound.spliterator(), false)
+					.filter(Objects::nonNull)
+					.filter(o -> o instanceof Object[]).map(o -> (Object[]) o)
+					.map(o -> o[0]).filter(o -> o instanceof MethodBinding).map(b -> (MethodBinding) b)
+					.filter(b -> CharOperation.equals(parent.selector, b.selector)).findFirst()
+					.map(m -> new MethodBinding[] { m }).orElse(new MethodBinding[0]);
+		} else {
+			return parameterName;
+		}
+
+		final int argumentLength = (parent.arguments != null) ? parent.arguments.length : 1;
+		for (MethodBinding binding : candidates) {
+			if (binding.parameterNames.length >= argumentLength) {
+				for (int i = 0; i < argumentLength; i++) {
+					if (parent.arguments == null || parent.arguments[i] == this.parser.assistNode) {
+						parameterName = binding.parameterNames[i];
+					}
+				}
+			}
+			if (parameterName.length > 0) {
+				break;
+			}
+		}
+		return parameterName;
+	}
 	private void findLocalMethodsFromFavorites(
 			char[] methodName,
 			MethodBinding[] methods,
@@ -13896,6 +13977,8 @@
 
 		Scope currentScope = scope;
 
+		char[]	boostMatches = findParameterNameAtLocationFromAssistParent(methodsFound);
+
 		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
 			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
 
@@ -13975,6 +14058,9 @@
 							relevance += computeRelevanceForResolution();
 							relevance += computeRelevanceForInterestingProposal(local);
 							relevance += computeRelevanceForCaseMatching(token, local.name);
+							if(boostMatches.length > 0) {
+								relevance += computeRelevanceForCaseMatching(boostMatches, local.name);
+							}
 							int computeRelevanceForExpectingType = computeRelevanceForExpectingType(local.type);
 							if(this.strictMatchForExtepectedType && computeRelevanceForExpectingType <= 0) {
 								continue;
@@ -14274,7 +14360,7 @@
 	private INameEnvironment getNoCacheNameEnvironment() {
 		if (this.noCacheNameEnvironment == null) {
 			JavaModelManager.getJavaModelManager().cacheZipFiles(this);
-			this.noCacheNameEnvironment = IndexBasedJavaSearchEnvironment.create(Collections.singletonList(this.javaProject), this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/));
+			this.noCacheNameEnvironment = new JavaSearchNameEnvironment(this.javaProject, this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/));
 		}
 		return this.noCacheNameEnvironment;
 	}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
index dbb7888..a4d3cb4 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
@@ -82,6 +82,9 @@
 				ProblemMethodBinding problemMethodBinding = new ProblemMethodBinding(messageSend.selector, argBindings, ProblemReasons.NotFound);
 				throw new CompletionNodeFound(this, problemMethodBinding, scope);
 			}
+			if (messageSend.binding != null) {
+				throw new CompletionNodeFound(this, messageSend.binding.declaringClass, scope);
+			}
 		}
 
 		if (this.actualReceiverType == null || !this.actualReceiverType.isValidBinding())
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java
index a569256..3b07cf1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java
@@ -602,9 +602,12 @@
 			/* rebuild identifiers and dimensions */
 			if (identCount == 1) { // simple type reference
 				if (dim == 0) {
+					int n = typeName.length;
+					boolean hasDiamond = n > 2 && typeName[n - 2] == '<' && typeName[n - 1] == '>';
 					char[] nameFragment;
-					if (nameFragmentStart != 0 || nameFragmentEnd >= 0) {
-						int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1;
+					int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1;
+					boolean hasEmptyFragment = nameFragmentLength == 0 && hasDiamond;
+					if ((nameFragmentStart != 0 || nameFragmentEnd >= 0) && !hasEmptyFragment) {
 						System.arraycopy(typeName, nameFragmentStart, nameFragment = new char[nameFragmentLength], 0, nameFragmentLength);
 					} else {
 						nameFragment = typeName;
@@ -618,7 +621,11 @@
 						return new TypeAnchorReference(name, start);
 					}
 // SH}
-					return new SingleTypeReference(nameFragment, ((long) start << 32) + end);
+					SingleTypeReference singleTypeReference = new SingleTypeReference(nameFragment, ((long) start << 32) + end);
+					if (hasDiamond) {
+						singleTypeReference.bits |= ASTNode.IsDiamond;
+					}
+					return singleTypeReference;
 				} else {
 					int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1;
 					char[] nameFragment = new char[nameFragmentLength];
diff --git a/org.eclipse.jdt.core/pom.xml b/org.eclipse.jdt.core/pom.xml
index fa2d20b..323ec73 100644
--- a/org.eclipse.jdt.core/pom.xml
+++ b/org.eclipse.jdt.core/pom.xml
@@ -14,10 +14,10 @@
   <parent>
     <artifactId>eclipse.jdt.core</artifactId>
     <groupId>org.eclipse.jdt</groupId>
-    <version>4.27.0-SNAPSHOT</version>
+    <version>4.28.0-SNAPSHOT</version>
   </parent>
   <artifactId>org.eclipse.jdt.core</artifactId>
-  <version>3.33.0-SNAPSHOT</version>
+  <version>3.33.100-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
index 0a80f8a..19415b9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
@@ -13,13 +13,11 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.search.indexing;
 
-import java.util.Collections;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.compiler.CharOperation;
@@ -55,7 +53,7 @@
 import org.eclipse.jdt.internal.core.JavaProject;
 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
 import org.eclipse.jdt.internal.core.jdom.CompilationUnit;
-import org.eclipse.jdt.internal.core.search.matching.IndexBasedJavaSearchEnvironment;
+import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
 import org.eclipse.jdt.internal.core.search.matching.MethodPattern;
 import org.eclipse.jdt.internal.core.search.processing.JobManager;
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
@@ -176,7 +174,7 @@
 			this.cud = this.basicParser.parse(this.compilationUnit, new CompilationResult(this.compilationUnit, 0, 0, this.options.maxProblemsPerUnit));
 			JavaModelManager.getJavaModelManager().cacheZipFiles(this); // use model only for caching
 			// Use a non model name environment to avoid locks, monitors and such.
-			INameEnvironment nameEnvironment = IndexBasedJavaSearchEnvironment.create(Collections.singletonList((IJavaProject)javaProject), JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, true/*add primary WCs*/));
+			INameEnvironment nameEnvironment = new JavaSearchNameEnvironment(javaProject, JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, true/*add primary WCs*/));
 			this.lookupEnvironment = new LookupEnvironment(this, this.options, problemReporter, nameEnvironment);
 			reduceParseTree(this.cud);
 //{ObjectTeams: need Dependencies configured:
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java
deleted file mode 100644
index 65c2e14..0000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015, 2018 Google, Inc and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *   Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.search.matching;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
-import org.eclipse.jdt.internal.core.JavaProject;
-
-public class IndexBasedJavaSearchEnvironment {
-
-	public static INameEnvironment create(List<IJavaProject> javaProjects, org.eclipse.jdt.core.ICompilationUnit[] copies) {
-		Iterator<IJavaProject> next = javaProjects.iterator();
-		JavaSearchNameEnvironment result = new JavaSearchNameEnvironment(next.next(), copies);
-
-		while (next.hasNext()) {
-			result.addProjectClassPath((JavaProject)next.next());
-		}
-		return result;
-	}
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
index 7c21e98..3fcb71f 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
@@ -17,7 +17,9 @@
 
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -40,6 +42,7 @@
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
 import org.eclipse.jdt.internal.compiler.env.IModule;
 import org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
@@ -159,6 +162,10 @@
 }
 
 protected /* visible for testing only */ void addProjectClassPath(JavaProject javaProject) {
+	addProjectClassPath(javaProject, false);
+}
+
+void addProjectClassPath(JavaProject javaProject, boolean onlyExported) {
 	long start = 0;
 	if (NameLookup.VERBOSE) {
 		Util.verbose(" EXTENDING JavaSearchNameEnvironment");  //$NON-NLS-1$
@@ -166,7 +173,7 @@
 		start = System.currentTimeMillis();
 	}
 
-	LinkedHashSet<ClasspathLocation> locations = computeClasspathLocations(javaProject);
+	LinkedHashSet<ClasspathLocation> locations = computeClasspathLocations(javaProject, onlyExported);
 	if (locations != null) this.locationSet.addAll(locations);
 
     if (NameLookup.VERBOSE) {
@@ -177,6 +184,10 @@
 }
 
 private LinkedHashSet<ClasspathLocation> computeClasspathLocations(JavaProject javaProject) {
+	return computeClasspathLocations(javaProject, false);
+}
+
+private LinkedHashSet<ClasspathLocation> computeClasspathLocations(JavaProject javaProject, boolean onlyExported) {
 
 	IPackageFragmentRoot[] roots = null;
 	try {
@@ -195,7 +206,11 @@
 	int length = roots.length;
 	JavaModelManager manager = JavaModelManager.getJavaModelManager();
 	for (int i = 0; i < length; i++) {
-		ClasspathLocation cp = mapToClassPathLocation(manager, (PackageFragmentRoot) roots[i], imd);
+		PackageFragmentRoot root = (PackageFragmentRoot) roots[i];
+		if (onlyExported && !isSourceOrExported(root)) {
+			continue;
+		}
+		ClasspathLocation cp = mapToClassPathLocation(manager, root, imd);
 		if (cp != null) {
 			try {
 				indexPackageNames(cp, roots[i]);
@@ -561,6 +576,16 @@
 	return set.toArray(new char[set.size()][]);
 }
 
+public static INameEnvironment createWithReferencedProjects(IJavaProject javaProject, List<IJavaProject> referencedProjects, org.eclipse.jdt.core.ICompilationUnit[] copies) {
+	JavaSearchNameEnvironment result = new JavaSearchNameEnvironment(javaProject, copies);
+
+	Iterator<IJavaProject> next = referencedProjects.iterator();
+	while (next.hasNext()) {
+		result.addProjectClassPath((JavaProject)next.next(), true);
+	}
+	return result;
+}
+
 private static boolean isComplianceJava9OrHigher(IJavaProject javaProject) {
 	if (javaProject == null) {
 		return false;
@@ -607,4 +632,15 @@
 	}
 	return false;
 }
+
+private static boolean isSourceOrExported(PackageFragmentRoot root) {
+	boolean isExported = true; // if we run into exceptions, assume exported
+	try {
+		IClasspathEntry entry = root.getRawClasspathEntry();
+		isExported = entry.getEntryKind() == IClasspathEntry.CPE_SOURCE || entry.isExported();
+	} catch (JavaModelException e) {
+		Util.log(e, "Error checking whether package fragment root is exported!"); //$NON-NLS-1$
+	}
+	return isExported;
+}
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index fad008d..64a7e90 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -1329,14 +1329,13 @@
 	SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(this.workingCopies);
 
 	List<IJavaProject> projects = new ArrayList<>();
-	projects.add(project);
 	if (this.pattern.focus != null) {
 		IJavaProject focusProject = this.pattern.focus.getJavaProject();
 		if (!project.equals(focusProject)) {
 			projects.add(focusProject);
 		}
 	}
-	this.nameEnvironment = IndexBasedJavaSearchEnvironment.create(projects, this.workingCopies);
+	this.nameEnvironment = JavaSearchNameEnvironment.createWithReferencedProjects(project, projects, this.workingCopies);
 
 	// create lookup environment
 	Map map = project.getOptions(true);