Bug 574073: [17] Merge master to BETA_JAVA17 branch periodically during
4.21

Post M1 - Merge remote-tracking branch 'origin/master' into BETA_JAVA17

Change-Id: I741bbf3982dbf89d0f63e7dfbc1a165b15444947
diff --git a/org.eclipse.jdt.core.manipulation/.settings/.api_filters b/org.eclipse.jdt.core.manipulation/.settings/.api_filters
index 4a3be0c..bae7ae8 100644
--- a/org.eclipse.jdt.core.manipulation/.settings/.api_filters
+++ b/org.eclipse.jdt.core.manipulation/.settings/.api_filters
@@ -8,20 +8,4 @@
             </message_arguments>
         </filter>
     </resource>
-    <resource path="core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java" type="org.eclipse.jdt.internal.corext.dom.ASTFlattener">
-        <filter comment="This is a Java 16 preview feature" id="640712815">
-            <message_arguments>
-                <message_argument value="PatternInstanceofExpression"/>
-                <message_argument value="ASTFlattener"/>
-                <message_argument value="getLeftOperand()"/>
-            </message_arguments>
-        </filter>
-        <filter comment="This is a Java 16 preview feature" id="640712815">
-            <message_arguments>
-                <message_argument value="PatternInstanceofExpression"/>
-                <message_argument value="ASTFlattener"/>
-                <message_argument value="getRightOperand()"/>
-            </message_arguments>
-        </filter>
-    </resource>
 </component>
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
index 6beec87..b8a8f6b 100644
--- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
@@ -462,7 +462,8 @@
 	public static String LocalCorrectionsSubProcessor_replace_with_unqualified_enum_constant;
 	public static String LocalCorrectionsSubProcessor_throw_allocated_description;
 	public static String LocalCorrectionsSubProcessor_add_provider_method_description;
-	public static String localCorrectionsSubProcessor_declareSealedAsDirectSuperInterface_description;
+	public static String LocalCorrectionsSubProcessor_declareSealedAsDirectSuperInterface_description;
+	public static String LocalCorrectionsSubProcessor_declareSubClassAsPermitsSealedClass_description;
 	public static String SuppressWarningsSubProcessor_fix_suppress_token_label;
 	public static String SuppressWarningsSubProcessor_remove_annotation_label;
 	public static String VarargsWarningsSubProcessor_add_safevarargs_label;
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
index cf66f64..95174df 100644
--- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
@@ -136,7 +136,8 @@
 LocalCorrectionsSubProcessor_throw_allocated_description=Throw the allocated object
 LocalCorrectionsSubProcessor_replace_with_unqualified_enum_constant=Replace with unqualified enum constant ''{0}''
 LocalCorrectionsSubProcessor_add_provider_method_description=Create ''{0}'' provider method
-localCorrectionsSubProcessor_declareSealedAsDirectSuperInterface_description=Declare ''{0}'' as direct super interface of ''{1}''
+LocalCorrectionsSubProcessor_declareSealedAsDirectSuperInterface_description=Declare ''{0}'' as direct super interface of ''{1}''
+LocalCorrectionsSubProcessor_declareSubClassAsPermitsSealedClass_description=Declare ''{0}'' as permitted subtype of ''{1}''
 TypeMismatchSubProcessor_addcast_description=Add cast to ''{0}''
 TypeMismatchSubProcessor_changecast_description=Change cast to ''{0}''
 TypeMismatchSubProcessor_changereturntype_description=Change method return type to ''{0}''
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringBufferToStringBuilderFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringBufferToStringBuilderFixCore.java
index 9d65bca..ba6128a 100644
--- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringBufferToStringBuilderFixCore.java
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringBufferToStringBuilderFixCore.java
@@ -131,13 +131,14 @@
 
 		@Override
 		public boolean visit(final MethodDeclaration visited) {
-			Type returnType= visited.getReturnType2();
-			ITypeBinding returnTypeBinding= returnType.resolveBinding();
 			IMethodBinding methodBinding= visited.resolveBinding();
-			if (methodBinding == null || returnTypeBinding == null) {
+			if (methodBinding == null) {
 				return true;
 			}
-			checkType(returnType);
+			Type returnType= visited.getReturnType2();
+			if (returnType != null) {
+				checkType(returnType);
+			}
 			for (Object obj : visited.parameters()) {
 				SingleVariableDeclaration parm= (SingleVariableDeclaration)obj;
 				Type type= parm.getType();
diff --git a/org.eclipse.jdt.junit.runtime/META-INF/MANIFEST.MF b/org.eclipse.jdt.junit.runtime/META-INF/MANIFEST.MF
index 86c2f9c..c1c05ed 100644
--- a/org.eclipse.jdt.junit.runtime/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.junit.runtime/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.junit.runtime;singleton:=true
-Bundle-Version: 3.6.0.qualifier
+Bundle-Version: 3.6.100.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.internal.junit.runner;
diff --git a/org.eclipse.jdt.junit.runtime/pom.xml b/org.eclipse.jdt.junit.runtime/pom.xml
index 822e260..c1f055a 100644
--- a/org.eclipse.jdt.junit.runtime/pom.xml
+++ b/org.eclipse.jdt.junit.runtime/pom.xml
@@ -18,6 +18,6 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.junit.runtime</artifactId>
-  <version>3.6.0-SNAPSHOT</version>
+  <version>3.6.100-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/org.eclipse.jdt.text.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.text.tests/META-INF/MANIFEST.MF
index ac37ace..8e05ff2 100644
--- a/org.eclipse.jdt.text.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.text.tests/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Plugin.name
 Bundle-SymbolicName: org.eclipse.jdt.text.tests;singleton:=true
-Bundle-Version: 3.13.1300.qualifier
+Bundle-Version: 3.13.1400.qualifier
 Bundle-Activator: org.eclipse.jdt.text.tests.JdtTextTestPlugin
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: %Plugin.providerName
diff --git a/org.eclipse.jdt.text.tests/pom.xml b/org.eclipse.jdt.text.tests/pom.xml
index b1f2277..32ab640 100644
--- a/org.eclipse.jdt.text.tests/pom.xml
+++ b/org.eclipse.jdt.text.tests/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (c) 2012, 2019 Eclipse Foundation and others.
+  Copyright (c) 2012, 2021 Eclipse Foundation and others.
   All rights reserved. This program and the accompanying materials
   are made available under the terms of the Eclipse Distribution License v1.0
   which accompanies this distribution, and is available at
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.text.tests</artifactId>
-  <version>3.13.1300-SNAPSHOT</version>
+  <version>3.13.1400-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/PostFixCompletionTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/PostFixCompletionTest.java
index a740492..559ad3d 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/PostFixCompletionTest.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/PostFixCompletionTest.java
@@ -57,12 +57,15 @@
 
 	private IPackageFragment pkg;
 
+	private Hashtable<String, String> savedOptions;
+
 	@Rule
 	public ProjectTestSetup cts= new ProjectTestSetup();
 
 	@Before
 	public void setUp() throws Exception {
 		Hashtable<String, String> options= JavaCore.getDefaultOptions();
+		savedOptions= new Hashtable<>(options);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "2");
 		JavaCore.setOptions(options);
@@ -76,6 +79,7 @@
 	@After
 	public void tearDown() throws Exception {
 		JavaProjectHelper.delete(fJProject);
+		JavaCore.setOptions(savedOptions);
 	}
 
 	@Test
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplateCompletionTests.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplateCompletionTests.java
index 47a1ab6..08a3f70 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplateCompletionTests.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplateCompletionTests.java
@@ -12,16 +12,16 @@
  *******************************************************************************/
 package org.eclipse.jdt.text.tests.templates;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.util.Arrays;
 import java.util.List;
 
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 import org.eclipse.jdt.testplugin.JavaProjectHelper;
 
@@ -54,7 +54,7 @@
 
 	private IPackageFragment pkg;
 
-	@BeforeEach
+	@Before
 	public void setUp() throws Exception {
 		fJProject= JavaProjectHelper.createJavaProject("TestProject", "bin");
 		JavaProjectHelper.addRTJar18(fJProject);
@@ -62,7 +62,7 @@
 		pkg= javaSrc.createPackageFragment("test", false, null);
 	}
 
-	@AfterEach
+	@After
 	public void tearDown() throws Exception {
 		JavaProjectHelper.delete(fJProject);
 	}
@@ -107,6 +107,41 @@
 		}
 	}
 
+	@Test
+	public void testRegressionBug574267() throws Exception {
+		String propDisplay= "sysout - print to standard out";
+		StringBuffer buf= new StringBuffer();
+		buf.append("class Sample {\n" +
+				"	void sample(String foo) {\n" +
+				"		if (foo != null) {\n" +
+				"			sys$ // content assist here\n" +
+				"			System.out.println();\n" +
+				"		}\n" +
+				"	}\n" +
+				"}");
+
+		int completionIndex= getCompletionIndex(buf);
+		ICompilationUnit cu= getCompilationUnit(pkg, buf, "Sample.java");
+		List<ICompletionProposal> proposals= computeCompletionProposals(cu, completionIndex);
+
+		assertProposalsExist(Arrays.asList(propDisplay), proposals);
+
+		ITextViewer viewer= initializeViewer(cu);
+		applyProposal(viewer, proposals, "sysout", completionIndex);
+
+		StringBuffer expected= new StringBuffer();
+		expected.append("class Sample {\n" +
+				"	void sample(String foo) {\n" +
+				"		if (foo != null) {\n" +
+				"			System.out.println(); // content assist here\n" +
+				"			System.out.println();\n" +
+				"		}\n" +
+				"	}\n" +
+				"}");
+
+		assertEquals(expected.toString(), viewer.getDocument().get());
+	}
+
 	private ITextViewer initializeViewer(ICompilationUnit cu) throws Exception {
 		IEditorPart editor= EditorUtility.openInEditor(cu);
 		ITextViewer viewer= new TextViewer(editor.getSite().getShell(), SWT.NONE);
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplateContributionTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplateContributionTest.java
index a005d4d..499ecca 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplateContributionTest.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplateContributionTest.java
@@ -17,7 +17,7 @@
 
 import java.util.Iterator;
 
-import org.junit.jupiter.api.Test;
+import org.junit.Test;
 
 import org.eclipse.jface.text.templates.ContextTypeRegistry;
 import org.eclipse.jface.text.templates.Template;
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplatesTestSuite.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplatesTestSuite.java
index 59cbf68..24f39c0 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplatesTestSuite.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/templates/TemplatesTestSuite.java
@@ -12,15 +12,20 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.text.tests.templates;
-import org.junit.platform.runner.JUnitPlatform;
-import org.junit.platform.suite.api.SelectClasses;
 import org.junit.runner.RunWith;
 /**
  * Template test suite.
  *
  * @since 3.4
  */
-@RunWith(JUnitPlatform.class)
-@SelectClasses( TemplateContributionTest.class )
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	//$JUnit-BEGIN$
+	TemplateContributionTest.class,
+	TemplateCompletionTests.class
+	//$JUnit-END$
+})
 public class TemplatesTestSuite {
 }
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeSignature/canModify/A_testAll59_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeSignature/canModify/A_testAll59_in.java
index 9747b21..8afc4aa 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeSignature/canModify/A_testAll59_in.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeSignature/canModify/A_testAll59_in.java
@@ -28,7 +28,7 @@
 	 * @see #getList(..)
 	 * @see p.A#getList(int, int, boolean)
 	 * @see <a href="spec.html#section">Java Spec</a>
-	 * @see A# getList(int, long)
+	 * @see A#getList (int, long)
 	 */
 	public ArrayList getList(int from, long to, Object[] arr[]) {
 		return new ArrayList(Arrays.asList(arr).subList(from, (int)to));
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeSignature/canModify/A_testAll59_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeSignature/canModify/A_testAll59_out.java
index 5201b8a..b99cca1 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeSignature/canModify/A_testAll59_out.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeSignature/canModify/A_testAll59_out.java
@@ -29,7 +29,7 @@
 	 * @see #getList(..)
 	 * @see p.A#getList(int, int, boolean)
 	 * @see <a href="spec.html#section">Java Spec</a>
-	 * @see A# getList(boolean, int, char)
+	 * @see A#getList (boolean, int, char)
 	 */
 	public ArrayList getList(int from, long to, Object[] arr[]) {
 		return new ArrayList(Arrays.asList(arr).subList(from, (int)to));
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/RenamePrivateField/testUnicode01/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/RenamePrivateField/testUnicode01/in/A.java
index 6f9058f..f764cf6 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/resources/RenamePrivateField/testUnicode01/in/A.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/RenamePrivateField/testUnicode01/in/A.java
@@ -4,8 +4,8 @@
 	A fi\u0065ld;
 	
 	/**
-	 * @see A # field
-	 * @see A # fiel\u0064
+	 * @see A#field
+	 * @see A#fiel\u0064
 	 * @see #fiel\u0064
 	 */
 	A(A a) {
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/RenamePrivateField/testUnicode01/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/RenamePrivateField/testUnicode01/out/A.java
index 07ba6f5..9772ac9 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/resources/RenamePrivateField/testUnicode01/out/A.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/RenamePrivateField/testUnicode01/out/A.java
@@ -4,8 +4,8 @@
 	A feel;
 	
 	/**
-	 * @see A # feel
-	 * @see A # feel
+	 * @see A#feel
+	 * @see A#feel
 	 * @see #feel
 	 */
 	A(A a) {
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java
index 2e9f06a..6f64edb 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java
@@ -449,6 +449,8 @@
 				+ "package test1;\n" //
 				+ "\n" //
 				+ "public class TestStringBuilderCleanup extends SuperClass {\n" //
+				+ "    private TestStringBuilderCleanup(){\n" //
+				+ "    }\n" //
 				+ "    public record K(StringBuffer comp1) {\n" //
 				+ "        public static StringBuffer field1;\n" //
 				+ "        public static StringBuffer field2;\n" //
@@ -469,6 +471,8 @@
 				+ "package test1;\n" //
 				+ "\n" //
 				+ "public class TestStringBuilderCleanup extends SuperClass {\n" //
+				+ "    private TestStringBuilderCleanup(){\n" //
+				+ "    }\n" //
 				+ "    public record K(StringBuffer comp1) {\n" //
 				+ "        public static StringBuffer field1;\n" //
 				+ "        public static StringBuffer field2;\n" //
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java
index a90358c..f944e5b 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java
@@ -3887,6 +3887,25 @@
 	}
 
 	@Test
+	public void testDoNotConvertStringBufferToStringBuilder() throws Exception {
+		// test bug 574588 NPE on private constructor
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+
+		String sample= "" //
+				+ "package test1;\n" //
+				+ "\n" //
+				+ "public class TestStringBuilderCleanup {\n" //
+				+ "    private TestStringBuilderCleanup(){\n" //
+				+ "    }\n" //
+				+ "}\n";
+		ICompilationUnit cu1= pack1.createCompilationUnit("TestStringBuilderCleanup.java", sample, false, null);
+
+		enable(CleanUpConstants.STRINGBUFFER_TO_STRINGBUILDER);
+
+		assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+	}
+
+	@Test
 	public void testConvertStringBufferToStringBuilderAll() throws Exception {
 		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
 		String sample0= "" //
@@ -3894,6 +3913,9 @@
 				+ "\n" //
 				+ "public class SuperClass {\n" //
 				+ "    public StringBuffer field0;\n" //
+				+ "    private SuperClass(StringBuffer a) {\n" //
+				+ "        this.field0 = a;\n" //
+				+ "    }\n" //
 				+ "    public void method0(StringBuffer parm) {\n" //
 				+ "        System.out.println(parm.toString());\n" //
 				+ "    }\n" //
@@ -3977,6 +3999,9 @@
 				+ "\n" //
 				+ "public class SuperClass {\n" //
 				+ "    public StringBuilder field0;\n" //
+				+ "    private SuperClass(StringBuilder a) {\n" //
+				+ "        this.field0 = a;\n" //
+				+ "    }\n" //
 				+ "    public void method0(StringBuilder parm) {\n" //
 				+ "        System.out.println(parm.toString());\n" //
 				+ "    }\n" //
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestPreview.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestPreview.java
new file mode 100644
index 0000000..9ae15b7
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestPreview.java
@@ -0,0 +1,500 @@
+/*******************************************************************************
+ * Copyright (c) 2019, 2021 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.ui.tests.quickfix;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+import org.eclipse.jdt.ui.tests.core.rules.Java16ProjectTestSetup;
+import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
+import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
+import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal;
+
+public class QuickFixTestPreview extends QuickFixTest {
+
+    @Rule
+    public ProjectTestSetup projectsetup = new Java16ProjectTestSetup(true);
+
+    private IJavaProject fJProject1;
+
+    private IPackageFragmentRoot fSourceFolder;
+
+	@After
+	public void tearDown() throws Exception {
+		if (fJProject1 != null) {
+			JavaProjectHelper.delete(fJProject1);
+		}
+	}
+
+	@Test
+	public void testAddSealedMissingClassModifierProposal() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test= "" +
+					"package test;\n" +
+					"\n" +
+					"public sealed class Shape permits Square {}\n" +
+					"\n" +
+					"class Square extends Shape {}\n";
+		ICompilationUnit cu= pack1.createCompilationUnit("Shape.java",test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 1);
+		assertNumberOfProposals(proposals, 3);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		String expected1= "" +
+						"package test;\n" +
+						"\n" +
+						"public sealed class Shape permits Square {}\n" +
+						"\n" +
+						"final class Square extends Shape {}\n";
+
+		proposal= (CUCorrectionProposal) proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		String expected2= "" +
+						"package test;\n" +
+						"\n" +
+						"public sealed class Shape permits Square {}\n" +
+						"\n" +
+						"non-sealed class Square extends Shape {}\n";
+
+		proposal= (CUCorrectionProposal) proposals.get(2);
+		String preview3= getPreviewContent(proposal);
+
+		String expected3= "" +
+						"package test;\n" +
+						"\n" +
+						"public sealed class Shape permits Square {}\n" +
+						"\n" +
+						"sealed class Square extends Shape {}\n";
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2, preview3 }, new String[] { expected1, expected2, expected3 });
+
+	}
+
+	@Test
+	public void testAddSealedMissingInterfaceModifierProposal() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test = "" +
+					"package test;\n" +
+					"\n" +
+					"public sealed interface Shape permits Square {}\n" +
+					"\n" +
+					"interface Square extends Shape {}\n";
+		ICompilationUnit cu= pack1.createCompilationUnit("Shape.java", test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 1);
+		assertNumberOfProposals(proposals, 2);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		String expected1= "" +
+						"package test;\n" +
+						"\n" +
+						"public sealed interface Shape permits Square {}\n" +
+						"\n" +
+						"sealed interface Square extends Shape {}\n";
+
+		proposal= (CUCorrectionProposal) proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		String expected2= "" +
+						"package test;\n" +
+						"\n" +
+						"public sealed interface Shape permits Square {}\n" +
+						"\n" +
+						"non-sealed interface Square extends Shape {}\n";
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+
+	}
+
+	@Test
+	public void testAddSealedAsDirectSuperTypeProposal1() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed class Shape permits Square {\n" +
+				"}\n";
+		pack1.createCompilationUnit("Shape.java", test, false, null);
+
+		test= "" +
+				"package test;\n" +
+				"\n" +
+				"public non-sealed class Square extends Shape {\n" +
+				"}\n";
+		pack1.createCompilationUnit("Square.java", test, false, null);
+
+		test= "" +
+				"package test;\n" +
+				"\n" +
+				"public non-sealed class Circle extends Shape {\n" +
+				"}\n";
+		ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu2);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu2, astRoot, 1);
+		assertNumberOfProposals(proposals, 1);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview= getPreviewContent(proposal);
+
+		String expected= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed class Shape permits Square, Circle {\n" +
+				"}\n";
+
+		assertEqualString(preview, expected);
+	}
+
+	@Test
+	public void testAddSealedAsDirectSuperTypeProposal2() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface Shape permits Square {\n" +
+				"}\n";
+		pack1.createCompilationUnit("Shape.java", test, false, null);
+
+		test= "" +
+				"package test;\n" +
+				"\n" +
+				"public non-sealed class Square implements Shape {\n" +
+				"}\n";
+		pack1.createCompilationUnit("Square.java", test, false, null);
+
+		test= "" +
+				"package test;\n" +
+				"\n" +
+				"public non-sealed class Circle implements Shape {\n" +
+				"}\n";
+		ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu2);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu2, astRoot, 1);
+		assertNumberOfProposals(proposals, 1);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview= getPreviewContent(proposal);
+
+		String expected= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface Shape permits Square, Circle {\n" +
+				"}\n";
+
+		assertEqualString(preview, expected);
+	}
+
+	@Test
+	public void testAddSealedAsDirectSuperTypeProposal3() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface Shape permits Square {\n" +
+				"}\n";
+		pack1.createCompilationUnit("Shape.java", test, false, null);
+
+		test= "" +
+				"package test;\n" +
+				"\n" +
+				"public non-sealed class Square implements Shape {\n" +
+				"}\n";
+		pack1.createCompilationUnit("Square.java", test, false, null);
+
+		test= "" +
+				"package test;\n" +
+				"\n" +
+				"public non-sealed interface Circle extends Shape {\n" +
+				"}\n";
+		ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu2);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu2, astRoot, 1);
+		assertNumberOfProposals(proposals, 1);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview= getPreviewContent(proposal);
+
+		String expected= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface Shape permits Square, Circle {\n" +
+				"}\n";
+
+		assertEqualString(preview, expected);
+	}
+
+	@Test
+	public void testAddSealedAsDirectSuperTypeProposal4() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+		IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+		def.createCompilationUnit("module-info.java", MODULE_INFO_FILE_CONTENT, false, null);
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface Shape permits Square {\n" +
+				"}\n";
+		pack1.createCompilationUnit("Shape.java", test, false, null);
+
+		test= "" +
+				"package test;\n" +
+				"\n" +
+				"public non-sealed class Square implements Shape {\n" +
+				"}\n";
+		pack1.createCompilationUnit("Square.java", test, false, null);
+
+
+		IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null);
+
+		test= "" +
+				"package test2;\n" +
+				"\n" +
+				"import test.Shape;\n" +
+				"\n" +
+				"public non-sealed interface Circle extends Shape {\n" +
+				"}\n";
+		ICompilationUnit cu2= pack2.createCompilationUnit("Circle.java", test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu2);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu2, astRoot, 1);
+		assertNumberOfProposals(proposals, 1);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview= getPreviewContent(proposal);
+
+		String expected= "" +
+				"package test;\n" +
+				"\n" +
+				"import test2.Circle;\n" +
+				"\n" +
+				"public sealed interface Shape permits Square, Circle {\n" +
+				"}\n";
+
+		assertEqualString(preview, expected);
+	}
+
+	@Test
+	public void testAddSealedAsDirectSuperInterface1() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface IShape permits Circle {\\n" +
+				"\n" +
+				"}\n" +
+				"\n" +
+				"class Circle {\n" +
+				"    \n" +
+				"}\n";
+		ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 2);
+		assertNumberOfProposals(proposals, 1);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		String expected1= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface IShape permits Circle {\\n" +
+				"\n" +
+				"}\n" +
+				"\n" +
+				"class Circle implements IShape {\n" +
+				"    \n" +
+				"}\n";
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 });
+	}
+
+	@Test
+	public void testAddSealedAsDirectSuperInterface2() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface IShape permits IRectangle {\\n" +
+				"\n" +
+				"}\n" +
+				"\n" +
+				"interface IRectangle {\n" +
+				"    \n" +
+				"}\n";
+		ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 2);
+		assertNumberOfProposals(proposals, 1);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		String expected1= "" +
+				"package test;\n" +
+				"\n" +
+				"public sealed interface IShape permits IRectangle {\\n" +
+				"\n" +
+				"}\n" +
+				"\n" +
+				"interface IRectangle extends IShape {\n" +
+				"    \n" +
+				"}\n";
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 });
+	}
+
+	@Test
+	public void testAddSealedAsDirectSuperInterface3() throws Exception {
+		fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+		fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
+		JavaProjectHelper.set16CompilerOptions(fJProject1, true);
+
+		Map<String, String> options= fJProject1.getOptions(false);
+		options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		fJProject1.setOptions(options);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
+
+		String test= "" +
+				"package test;\n" +
+				"\n" +
+				"import java.lang.annotation.IncompleteAnnotationException;\n" +
+				"\n" +
+				"public sealed interface IShape permits IncompleteAnnotationException {\\n" +
+				"\n" +
+				"}\n";
+		ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 3);
+		assertNumberOfProposals(proposals, 0);
+	}
+
+}
diff --git a/org.eclipse.jdt.ui/.settings/.api_filters b/org.eclipse.jdt.ui/.settings/.api_filters
index c056158..6a6c033 100644
--- a/org.eclipse.jdt.ui/.settings/.api_filters
+++ b/org.eclipse.jdt.ui/.settings/.api_filters
@@ -129,6 +129,15 @@
             </message_arguments>
         </filter>
     </resource>
+    <resource path="ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java" type="org.eclipse.jdt.internal.ui.text.correction.LocalCorrectionsSubProcessor">
+        <filter comment="Sealed types preview feature" id="640712815">
+            <message_arguments>
+                <message_argument value="IType"/>
+                <message_argument value="LocalCorrectionsSubProcessor"/>
+                <message_argument value="isSealed()"/>
+            </message_arguments>
+        </filter>
+    </resource>
     <resource path="ui/org/eclipse/jdt/internal/ui/util/ViewerPane.java" type="org.eclipse.jdt.internal.ui.util.ViewerPane">
         <filter id="571473929">
             <message_arguments>
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java
index 7e67a9f..0f5998b 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java
@@ -778,7 +778,7 @@
 
 	@SuppressWarnings("unchecked")
 	private static HashMap<String, CollectionElementVariable2> getIndexedCollectionElements(ConstraintVariable2 constraintVariable) {
-		return (HashMap<String, CollectionElementVariable2>) constraintVariable.getData(INDEXED_COLLECTION_ELEMENTS);
+		return constraintVariable == null ? null : (HashMap<String, CollectionElementVariable2>) constraintVariable.getData(INDEXED_COLLECTION_ELEMENTS);
 	}
 
 	private static void setElementVariable(ConstraintVariable2 typeConstraintVariable, CollectionElementVariable2 elementVariable, TypeVariable typeVariable) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java
index c02cea7..23cd185 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java
@@ -1305,6 +1305,66 @@
 		}
 	}
 
+	public static void addTypeAsPermittedSubTypeProposal(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) throws JavaModelException {
+		ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
+		if (selectedNode == null) {
+			return;
+		}
+		if (!ASTHelper.isSealedTypeSupportedInAST(selectedNode.getAST())) {
+			return;
+		}
+
+		while (selectedNode.getParent() instanceof Type) {
+			selectedNode= selectedNode.getParent();
+		}
+		if (selectedNode.getLocationInParent() != TypeDeclaration.SUPERCLASS_TYPE_PROPERTY
+				&& selectedNode.getLocationInParent() != TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY) {
+			return;
+		}
+		TypeDeclaration subType= (TypeDeclaration) selectedNode.getParent();
+		ITypeBinding subTypeBinding= subType.resolveBinding();
+		IJavaElement sealedTypeElement= null;
+		if (selectedNode instanceof SimpleType) {
+			ITypeBinding typeBinding= ((SimpleType) selectedNode).resolveBinding();
+			if (typeBinding != null) {
+				sealedTypeElement= typeBinding.getJavaElement();
+			}
+		}
+		if (!(sealedTypeElement instanceof IType)) {
+			return;
+		}
+		IType sealedType= (IType) sealedTypeElement;
+		if (sealedType.isBinary() || !sealedType.isSealed()) {
+			return;
+		}
+		ICompilationUnit compilationUnit= sealedType.getCompilationUnit();
+		CompilationUnitRewrite cuRewrite= new CompilationUnitRewrite(compilationUnit);
+		TypeDeclaration declaration= ASTNodeSearchUtil.getTypeDeclarationNode(sealedType, cuRewrite.getRoot());
+		if (declaration == null) {
+			return;
+		}
+
+		AST ast= declaration.getAST();
+		String subTypeName= subType.getName().getIdentifier();
+		Type type= ast.newSimpleType(ast.newSimpleName(subTypeName));
+
+		ASTRewrite astRewrite= cuRewrite.getASTRewrite();
+		astRewrite.getListRewrite(declaration, TypeDeclaration.PERMITS_TYPES_PROPERTY).insertLast(type, null);
+
+		String sealedTypeName= problem.getProblemArguments()[1];
+		String label= Messages.format(CorrectionMessages.LocalCorrectionsSubProcessor_declareSubClassAsPermitsSealedClass_description, new String[] { subTypeName, sealedTypeName });
+		Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_ADD);
+		ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, compilationUnit, astRewrite, IProposalRelevance.DECLARE_SEALED_AS_DIRECT_SUPER_TYPE, image);
+		ImportRewrite importRewrite= proposal.getImportRewrite();
+		if (importRewrite == null) {
+			importRewrite= StubUtility.createImportRewrite(compilationUnit, true);
+		}
+
+		ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(declaration.getRoot(), importRewrite);
+		importRewrite.addImport(subTypeBinding, astRewrite.getAST(), importRewriteContext);
+		proposal.setImportRewrite(importRewrite);	proposals.add(proposal);
+	}
+
 	public static void addSealedAsDirectSuperTypeProposal(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) throws JavaModelException {
 		ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
 		if (selectedNode == null) {
@@ -1352,7 +1412,7 @@
 		astRewrite.getListRewrite(declaration, TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY).insertLast(type, null);
 
 		String permittedTypeName= problem.getProblemArguments()[0];
-		String label= Messages.format(CorrectionMessages.localCorrectionsSubProcessor_declareSealedAsDirectSuperInterface_description, new String[] { sealedTypeName, permittedTypeName });
+		String label= Messages.format(CorrectionMessages.LocalCorrectionsSubProcessor_declareSealedAsDirectSuperInterface_description, new String[] { sealedTypeName, permittedTypeName });
 		Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_ADD);
 		ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, compilationUnit, astRewrite, IProposalRelevance.DECLARE_SEALED_AS_DIRECT_SUPER_TYPE, image);
 		proposals.add(proposal);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ModifierCorrectionSubProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ModifierCorrectionSubProcessor.java
index 7d621d6..9480c15 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ModifierCorrectionSubProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ModifierCorrectionSubProcessor.java
@@ -915,7 +915,7 @@
 			ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, IProposalRelevance.REMOVE_OVERRIDE, image);
 			proposals.add(proposal);
 
-			QuickAssistProcessor.getCreateInSuperClassProposals(context, methodDecl.getName(), proposals);
+			QuickAssistProcessor.getCreateInSuperClassProposals(context, methodDecl.getName(), proposals, false);
 		}
 	}
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
index d9eb1f6..0347d55 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
@@ -3985,6 +3985,10 @@
 
 
 	public static boolean getCreateInSuperClassProposals(IInvocationContext context, ASTNode node, Collection<ICommandAccess> resultingCollections) throws CoreException {
+		return getCreateInSuperClassProposals(context, node, resultingCollections, true);
+	}
+
+	public static boolean getCreateInSuperClassProposals(IInvocationContext context, ASTNode node, Collection<ICommandAccess> resultingCollections, boolean addOverride) throws CoreException {
 		if (!(node instanceof SimpleName) || !(node.getParent() instanceof MethodDeclaration)) {
 			return false;
 		}
@@ -4024,7 +4028,7 @@
 					if (targetCU != null) {
 						String label= Messages.format(CorrectionMessages.QuickAssistProcessor_createmethodinsuper_description,
 								new String[] { BasicElementLabels.getJavaElementName(curr.getName()), BasicElementLabels.getJavaElementName(binding.getName()) });
-						resultingCollections.add(new NewDefiningMethodProposal(label, targetCU, astRoot, typeDecl, binding, paramNames, IProposalRelevance.CREATE_METHOD_IN_SUPER));
+						resultingCollections.add(new NewDefiningMethodProposal(label, targetCU, astRoot, typeDecl, binding, paramNames, addOverride, IProposalRelevance.CREATE_METHOD_IN_SUPER));
 					}
 				}
 			}
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java
index 75cb271..6d34e41 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java
@@ -131,6 +131,8 @@
 			case IProblem.SealedMissingClassModifier:
 			case IProblem.SealedMissingInterfaceModifier:
 			case IProblem.SealedNotDirectSuperInterface:
+			case IProblem.SealedSuperClassDoesNotPermit:
+			case IProblem.SealedSuperInterfaceDoesNotPermit:
 			case IProblem.Task:
 			case IProblem.UnusedMethodDeclaredThrownException:
 			case IProblem.UnusedConstructorDeclaredThrownException:
@@ -473,6 +475,10 @@
 			case IProblem.SealedNotDirectSuperInterface:
 				LocalCorrectionsSubProcessor.addSealedAsDirectSuperTypeProposal(context, problem, proposals);
 				break;
+			case IProblem.SealedSuperClassDoesNotPermit:
+			case IProblem.SealedSuperInterfaceDoesNotPermit:
+				LocalCorrectionsSubProcessor.addTypeAsPermittedSubTypeProposal(context, problem, proposals);
+				break;
 			case IProblem.StaticMethodRequested:
 			case IProblem.NonStaticFieldFromStaticInvocation:
 				LocalCorrectionsSubProcessor.addObjectReferenceProposal(context, problem, proposals);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/NewDefiningMethodProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/NewDefiningMethodProposal.java
index 0d51989..38df0d9 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/NewDefiningMethodProposal.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/NewDefiningMethodProposal.java
@@ -66,10 +66,13 @@
 
 	private final String[] fParamNames;
 
-	public NewDefiningMethodProposal(String label, ICompilationUnit targetCU, ASTNode invocationNode, ITypeBinding binding, IMethodBinding method, String[] paramNames, int relevance) {
+	private boolean fAddOverrideAnnotation;
+
+	public NewDefiningMethodProposal(String label, ICompilationUnit targetCU, ASTNode invocationNode, ITypeBinding binding, IMethodBinding method, String[] paramNames, boolean addOverride, int relevance) {
 		super(label, targetCU, invocationNode, binding, relevance, null);
 		fMethod= method;
 		fParamNames= paramNames;
+		fAddOverrideAnnotation= addOverride;
 
 		ImageDescriptor desc= JavaElementImageProvider.getMethodImageDescriptor(binding.isInterface() || binding.isAnnotation(), method.getModifiers());
 		setImage(JavaPlugin.getImageDescriptorRegistry().get(desc));
@@ -82,7 +85,9 @@
 
 	@Override
 	protected void performChange(IEditorPart part, IDocument document) throws CoreException {
-		addOverrideAnnotation(document);
+		if (fAddOverrideAnnotation) {
+			addOverrideAnnotation(document);
+		}
 		super.performChange(part, document);
 	}