diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/566943/RecCompConst.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/566943/RecCompConst.java
new file mode 100644
index 0000000..7c368ac
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/566943/RecCompConst.java
@@ -0,0 +1,10 @@
+package p;
+
+import java.util.List;
+
+public record RecCompConst(int a, char c, String b) {
+
+	public /*[*/RecCompConst/*]*/ {
+    }
+
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/566943/RecCompConst_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/566943/RecCompConst_out.java
new file mode 100644
index 0000000..e889e93
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/566943/RecCompConst_out.java
@@ -0,0 +1,14 @@
+package p;
+
+import java.util.List;
+
+public record RecCompConst(int a, char c, String b) {
+
+	public static RecCompConst createRecCompConst(int a, char c, String b) {
+		return new RecCompConst(a, c, b);
+	}
+
+	public /*[*/RecCompConst/*]*/ {
+    }
+
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/568987/RecCanConst.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/568987/RecCanConst.java
new file mode 100644
index 0000000..2c388d4
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/568987/RecCanConst.java
@@ -0,0 +1,10 @@
+package p;
+
+import java.util.List;
+
+public record RecCanConst(int a, char c, String b) {
+
+	public /*[*/RecCanConst/*]*/(int a, char c, String b) {
+    }
+
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/568987/RecCanConst_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/568987/RecCanConst_out.java
new file mode 100644
index 0000000..1615a81
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceFactory/Bugzilla/568987/RecCanConst_out.java
@@ -0,0 +1,14 @@
+package p;
+
+import java.util.List;
+
+public record RecCanConst(int a, char c, String b) {
+
+	public static RecCanConst createRecCanConst(int a, char c, String b) {
+		return new RecCanConst(a, c, b);
+	}
+
+	public /*[*/RecCanConst/*]*/(int a, char c, String b) {
+    }
+
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
index 0a227c8..5147eed 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
@@ -47,6 +47,7 @@
 	IntroduceParameterTests.class,
 	IntroduceParameterTests1d7.class,
 	IntroduceFactoryTests.class,
+	IntroduceFactoryTests15.class,
 
 	//-- structure
 	ChangeSignatureTests.class,
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTests.java
index d7208db..c0e51f3 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTests.java
@@ -14,42 +14,16 @@
  *******************************************************************************/
 package org.eclipse.jdt.ui.tests.refactoring;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
 import org.junit.Test;
 
-import org.eclipse.jdt.testplugin.JavaProjectHelper;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-
 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
 
-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.ISourceRange;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.SourceRange;
-
-import org.eclipse.jdt.internal.corext.refactoring.code.IntroduceFactoryRefactoring;
-
 import org.eclipse.jdt.ui.tests.refactoring.rules.Java1d6Setup;
 
 /**
  * @author rfuhrer@watson.ibm.com
  */
-public class IntroduceFactoryTests extends GenericRefactoringTest {
+public class IntroduceFactoryTests extends IntroduceFactoryTestsBase{
 	private static final String REFACTORING_PATH= "IntroduceFactory/";
 
 	public IntroduceFactoryTests() {
@@ -61,467 +35,6 @@
 		return REFACTORING_PATH;
 	}
 
-	/**
-	 * Produces a test file name based on the name of this JUnit testcase.
-	 * For input files, trims off the trailing part of the test name that
-	 * begins with a '_', to get rid of the options part, so that we can
-	 * have a single (suite of) input file(s) but several outputs dependent
-	 * on the option settings.
-	 * @param input true iff the requested file is an input file.
-	 * @return the name of the test file, with a trailing "_in.java" if an input
-	 * file and a trailing "_XXX.java" if an output file and the test name/options
-	 * are "_XXX".
-	 */
-	private String getSimpleTestFileName(boolean input) {
-		String	testName = getName();
-		int		usIdx=  testName.indexOf('_');
-		int		endIdx= (usIdx >= 0) ? usIdx : testName.length();
-		String	fileName = (input ? (testName.substring(4, endIdx) + "_in") : testName.substring(4));
-
-		return fileName + ".java";
-	}
-
-	/**
-	 * Produces a test file name based on the name of this JUnit testcase,
-	 * like getSimpleTestFileName(), but also prepends the appropriate version
-	 * of the resource path (depending on the value of <code>positive</code>).
-	 * Test files are assumed to be located in the resources directory.
-	 * @param positive true iff the requested file is for a positive unit test
-	 * @param input true iff the requested file is an input file
-	 * @return the test file name
-	 */
-	private String getTestFileName(boolean positive, boolean input) {
-		String path= TEST_PATH_PREFIX + getRefactoringPath();
-
-		path += (positive ? "positive/": "negative/");
-		return path + getSimpleTestFileName(input);
-	}
-
-	/**
-	 * Produces a compilation unit from an input source file whose name
-	 * is based on the testcase name.
-	 * Test files are assumed to be located in the resources directory.
-	 * @param pack
-	 * @param positive
-	 * @param input
-	 * @return the ICompilationUnit created from the specified test file
-	 * @throws Exception
-	 */
-	private ICompilationUnit createCUForSimpleTest(IPackageFragment pack,
-												  boolean positive, boolean input)
-		throws Exception
-	{
-		String	fileName= getTestFileName(positive, input);
-		String	cuName= getSimpleTestFileName(input);
-
-		return createCU(pack, cuName, getFileContents(fileName));
-	}
-
-	/**
-	 * Produces a test file name based on the name of this JUnit testcase,
-	 * like getSimpleTestFileName(), but also prepends the appropriate version
-	 * of the resource path (depending on the value of <code>positive</code>).
-	 * Test files are assumed to be located in the resources directory.
-	 * @param project the project
-	 * @param pack the package fragment
-	 * @param fileName the file name
-	 * @param input true iff the requested file is an input file
-	 * @return the test file name
-	 */
-	private String getBugTestFileName(IJavaProject project, IPackageFragment pack, String fileName, boolean input) {
-		String testName= getName();
-		String testNumber= testName.substring("test".length());//$NON-NLS-1$
-		String path= TEST_PATH_PREFIX + getRefactoringPath() + "Bugzilla/" + testNumber + "/" +
-									(project == null ? "" : project.getElementName() + "/") +
-									(pack == getPackageP() ? "" : pack.getElementName() + "/");
-
-		return path + fileName + (input ? "" : "_out") + ".java";//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-	}
-
-	/**
-	 * Produces a compilation unit from an input source file whose path
-	 * is based on the testcase name, but whose basename is supplied by
-	 * the caller.
-	 * Test files are assumed to be located in the resources directory.
-	 * @param project can be null if only 1 project exists in the test workspace
-	 * @param pack
-	 * @param baseName
-	 * @param input
-	 * @return the ICompilationUnit created from the specified test file
-	 * @throws Exception
-	 */
-	private ICompilationUnit createCUForBugTestCase(IJavaProject project,
-													IPackageFragment pack, String baseName, boolean input)
-		throws Exception
-	{
-		String	fileName= getBugTestFileName(project, pack, baseName, input);
-		String	cuName= baseName + (input ? "" : "_out") + ".java";
-
-		return createCU(pack, cuName, getFileContents(fileName));
-	}
-
-	static final String SELECTION_START_HERALD= "/*[*/";
-	static final String SELECTION_END_HERALD= "/*]*/";
-
-	/**
-	 * Finds and returns the selection markers in the given source string,
-	 * i.e. the first occurrences of <code>SELECTION_START_HERALD</code> and
-	 * <code>SELECTION_END_HERALD</code>. Fails an assertion if either of these
-	 * markers is not present in the source string.
-	 * @param source
-	 * @return an ISourceRange representing the marked selection
-	 * @throws Exception
-	 */
-	private ISourceRange findSelectionInSource(String source) throws Exception {
-		int		begin= source.indexOf(SELECTION_START_HERALD) + SELECTION_START_HERALD.length();
-		int		end= source.indexOf(SELECTION_END_HERALD);
-
-		if (begin < SELECTION_START_HERALD.length())
-			fail("No selection start comment in input source file!");
-		if (end < 0)
-			fail("No selection end comment in input source file!");
-
-		return new SourceRange(begin, end-begin);
-	}
-
-	private void doSingleUnitTest(boolean protectConstructor, ICompilationUnit cu, String outputFileName) throws Exception, JavaModelException, IOException {
-		ISourceRange		selection= findSelectionInSource(cu.getSource());
-		IntroduceFactoryRefactoring	ref= new IntroduceFactoryRefactoring(cu, selection.getOffset(), selection.getLength());
-
-		ref.setProtectConstructor(protectConstructor);
-
-		RefactoringStatus	activationResult= ref.checkInitialConditions(new NullProgressMonitor());
-
-		assertTrue("activation was supposed to be successful", activationResult.isOK());
-
-		RefactoringStatus	checkInputResult= ref.checkFinalConditions(new NullProgressMonitor());
-
-		if (!checkInputResult.isOK()) {
-			performChange(ref, false);
-
-			String newSource = cu.getSource();
-
-			System.err.println("!!!Precondition failed for " + getName() + "!!!");
-			System.err.println("Compile-time error: " + checkInputResult.toString());
-			System.err.println("Offending source:");
-			System.err.print(newSource);
-			fail("precondition was supposed to pass but was " + checkInputResult.toString());
-		}
-
-		performChange(ref, false);
-
-		String newSource = cu.getSource();
-
-		assertEqualLines(getName() + ": ", getFileContents(outputFileName), newSource);
-	}
-
-	private void doSingleUnitTestWithWarning(boolean protectConstructor, ICompilationUnit cu, String outputFileName) throws Exception, JavaModelException, IOException {
-		ISourceRange selection= findSelectionInSource(cu.getSource());
-		IntroduceFactoryRefactoring ref= new IntroduceFactoryRefactoring(cu, selection.getOffset(), selection.getLength());
-
-		ref.setProtectConstructor(protectConstructor);
-
-		RefactoringStatus activationResult= ref.checkInitialConditions(new NullProgressMonitor());
-
-		assertTrue("activation was supposed to be successful", activationResult.isOK());
-
-		RefactoringStatus checkInputResult= ref.checkFinalConditions(new NullProgressMonitor());
-
-		assertEquals(RefactoringStatus.WARNING, checkInputResult.getSeverity());
-		performChange(ref, false);
-
-		String newSource= cu.getSource();
-
-		assertEqualLines(getName() + ": ", getFileContents(outputFileName), newSource);
-	}
-
-	/**
-	 * Tests the IntroduceFactoryRefactoring refactoring on a single input source file
-	 * whose name is the test name (minus the "test" prefix and any trailing
-	 * options indicator such as "_FFF"), and compares the transformed code
-	 * to a source file whose name is the test name (minus the "test" prefix).
-	 * Test files are assumed to be located in the resources directory.
-	 * @param protectConstructor true iff IntroduceFactoryRefactoring should make the constructor private
-	 * @throws Exception
-	 */
-	void singleUnitHelper(boolean protectConstructor)
-		throws Exception
-	{
-		ICompilationUnit	cu= createCUForSimpleTest(getPackageP(), true, true);
-
-		doSingleUnitTest(protectConstructor, cu, getTestFileName(true, false));
-	}
-
-	/**
-	 * Tests the IntroduceFactoryRefactoring refactoring on a single input source file
-	 * whose name is the test name (minus the "test" prefix and any trailing
-	 * options indicator such as "_FFF"), and compares the transformed code
-	 * to a source file whose name is the test name (minus the "test" prefix).
-	 * Test files are assumed to be located in the resources directory.
-	 * @param baseFileName the base file name
-	 * @param protectConstructor true iff IntroduceFactoryRefactoring should make the constructor private
-	 * @throws Exception
-	 */
-	protected void singleUnitBugHelper(String baseFileName, boolean protectConstructor)
-		throws Exception
-	{
-		ICompilationUnit	cu= createCUForBugTestCase(null, getPackageP(), baseFileName, true);
-
-		doSingleUnitTest(protectConstructor, cu, getBugTestFileName(null, getPackageP(), baseFileName, false));
-	}
-
-	protected void singleUnitBugHelperWithWarning(String baseFileName, boolean protectConstructor)
-			throws Exception
-	{
-		ICompilationUnit cu= createCUForBugTestCase(null, getPackageP(), baseFileName, true);
-
-		doSingleUnitTestWithWarning(protectConstructor, cu, getBugTestFileName(null, getPackageP(), baseFileName, false));
-	}
-
-	/**
-	 * Like singleUnitHelper(), but allows for the specification of the names of
-	 * the generated factory method, class, and interface, as appropriate.
-	 * @param factoryMethodName the name to use for the generated factory method
-	 * @param factoryClassName the name of the factory class
-	 * @throws Exception
-	 */
-	void namesHelper(String factoryMethodName, String factoryClassName)
-		throws Exception
-	{
-		ICompilationUnit	cu= createCUForSimpleTest(getPackageP(), true, true);
-		ISourceRange		selection= findSelectionInSource(cu.getSource());
-		IntroduceFactoryRefactoring	ref= new IntroduceFactoryRefactoring(cu, selection.getOffset(), selection.getLength());
-
-		RefactoringStatus	activationResult= ref.checkInitialConditions(new NullProgressMonitor());
-
-		assertTrue("activation was supposed to be successful", activationResult.isOK());
-
-		if (factoryMethodName != null)
-			ref.setNewMethodName(factoryMethodName);
-		if (factoryClassName != null)
-			ref.setFactoryClass(factoryClassName);
-
-		RefactoringStatus	checkInputResult= ref.checkFinalConditions(new NullProgressMonitor());
-
-		assertTrue("precondition was supposed to pass but was " + checkInputResult.toString(), checkInputResult.isOK());
-
-		performChange(ref, false);
-
-		String newSource = cu.getSource();
-
-		assertEqualLines(getName() + ": ", getFileContents(getTestFileName(true, false)), newSource);
-	}
-
-	/**
-	 * Creates a compilation unit for a source file with a given base name (plus
-	 * "_in" suffix) in the given package. The source file is assumed to be
-	 * located in the test resources directory.<br>
-	 * Currently only handles positive tests.
-	 * @param fileName the base name of the source file (minus the "_in" suffix)
-	 * @param pack an IPackageFragment for the containing package
-	 * @return the ICompilationUnit for the newly-created unit
-	 * @throws Exception
-	 */
-	private ICompilationUnit createCUFromFileName(String fileName, IPackageFragment pack) throws Exception {
-		String fullName = TEST_PATH_PREFIX + getRefactoringPath() + "positive/" + fileName + "_in.java";
-
-		return createCU(pack, fileName + "_in.java", getFileContents(fullName));
-	}
-
-	private void doMultiUnitTest(ICompilationUnit[] CUs, String testPath, String[] outputFileBaseNames, String factoryClassName) throws Exception, JavaModelException, IOException {
-		ISourceRange selection= findSelectionInSource(CUs[0].getSource());
-		IntroduceFactoryRefactoring	ref= new IntroduceFactoryRefactoring(CUs[0], selection.getOffset(), selection.getLength());
-
-		RefactoringStatus activationResult= ref.checkInitialConditions(new NullProgressMonitor());
-
-		assertTrue("activation was supposed to be successful", activationResult.isOK());
-
-		if (factoryClassName != null)
-			ref.setFactoryClass(factoryClassName);
-
-		RefactoringStatus	checkInputResult= ref.checkFinalConditions(new NullProgressMonitor());
-
-		assertTrue("precondition was supposed to pass but was " + checkInputResult.toString(), checkInputResult.isOK());
-
-		performChange(ref, false);
-
-		String	testName= getName();
-
-		for (int i = 0; i < CUs.length; i++) {
-			int optIdx= testName.indexOf("_");
-			String testOptions= (optIdx >= 0) ? testName.substring(optIdx) : "";
-			String outFileName= testPath + outputFileBaseNames[i] + testOptions + "_out.java";
-			String xformedSrc= CUs[i].getSource();
-			String expectedSrc= getFileContents(outFileName);
-
-			assertEqualLines(getName() + ": ", expectedSrc, xformedSrc);
-		}
-	}
-
-	/**
-	 * Tests the IntroduceFactoryRefactoring refactoring on a set of input source files
-	 * whose names are supplied in the <code>fileBaseNames</code> argument,
-	 * and compares the transformed code to source files whose names are
-	 * the input base names plus the options suffix (e.g. "_FFF").
-	 * Test files are assumed to be located in the resources directory.
-	 * @param staticFactoryMethod true iff IntroduceFactoryRefactoring should make the factory method static
-	 * @param inputFileBaseNames an array of input source file base names
-	 * @throws Exception
-	 */
-	void multiUnitHelper(boolean staticFactoryMethod, String[] inputFileBaseNames)
-		throws Exception
-	{
-		IPackageFragment	pkg= getPackageP();
-		ICompilationUnit	CUs[]= new ICompilationUnit[inputFileBaseNames.length];
-
-		for (int i = 0; i < inputFileBaseNames.length; i++)
-			CUs[i] = createCUFromFileName(inputFileBaseNames[i], pkg);
-
-		String	testPath= TEST_PATH_PREFIX + getRefactoringPath() + "positive/";
-
-		doMultiUnitTest(CUs, testPath, inputFileBaseNames, null);
-	}
-
-	/**
-	 * Tests the IntroduceFactoryRefactoring refactoring on a set of input source files
-	 * whose names are supplied in the <code>fileBaseNames</code> argument,
-	 * and compares the transformed code to source files whose names are
-	 * the input base names plus the options suffix (e.g. "_FFF").
-	 * Test files are assumed to be located in the resources directory.
-	 * @param staticFactoryMethod true iff IntroduceFactoryRefactoring should make the factory method static
-	 * @param inputFileBaseNames an array of input source file base names
-	 * @param factoryClassName the fully-qualified name of the class to receive the factory method, or null
-	 * if the factory method is to be placed on the class defining the given constructor
-	 * @throws Exception
-	 */
-	void multiUnitBugHelper(boolean staticFactoryMethod, String[] inputFileBaseNames, String factoryClassName)
-		throws Exception
-	{
-		ICompilationUnit CUs[]= new ICompilationUnit[inputFileBaseNames.length];
-
-		for(int i= 0; i < inputFileBaseNames.length; i++) {
-			int pkgEnd= inputFileBaseNames[i].lastIndexOf('/')+1;
-			boolean explicitPkg= (pkgEnd > 0);
-			IPackageFragment pkg= explicitPkg ? getRoot().createPackageFragment(inputFileBaseNames[i].substring(0, pkgEnd-1), true, new NullProgressMonitor()) : getPackageP();
-
-			CUs[i]= createCUForBugTestCase(null, pkg, inputFileBaseNames[i].substring(pkgEnd), true);
-		}
-
-		String	testName= getName();
-		String	testNumber= testName.substring("test".length());
-		String	testPath= TEST_PATH_PREFIX + getRefactoringPath() + "Bugzilla/" + testNumber + "/";
-
-		doMultiUnitTest(CUs, testPath, inputFileBaseNames, factoryClassName);
-	}
-
-	void multiProjectBugHelper(String[] inputFileBaseNames, String[] dependencies) throws Exception {
-		Map<String, Set<String>> projName2PkgNames= collectProjectPackages(inputFileBaseNames);
-		Map<String, IJavaProject> projName2Project= new HashMap<>();
-		Map<IJavaProject, IPackageFragmentRoot> proj2PkgRoot= new HashMap<>();
-
-		try {
-			createProjectPackageStructure(projName2PkgNames, projName2Project, proj2PkgRoot);
-
-			ICompilationUnit[] CUs= createCUs(inputFileBaseNames, projName2Project, proj2PkgRoot);
-
-			addProjectDependencies(dependencies, projName2Project);
-
-			String testName= getName();
-			String testNumber= testName.substring("test".length());
-			String testPath= TEST_PATH_PREFIX + getRefactoringPath() + "Bugzilla/" + testNumber + "/";
-
-			doMultiUnitTest(CUs, testPath, inputFileBaseNames, null);
-
-		} finally {
-			for (IJavaProject project : proj2PkgRoot.keySet()) {
-				if (project.exists()) {
-					try {
-						project.getProject().delete(true, null);
-					} catch (CoreException e) {
-						// swallow exception to avoid destroying the original one
-						e.printStackTrace();
-					}
-				}
-			}
-		}
-	}
-
-	private ICompilationUnit[] createCUs(String[] inputFileBaseNames, Map<String, IJavaProject> projName2Project, Map<IJavaProject, IPackageFragmentRoot> proj2PkgRoot) throws Exception {
-		ICompilationUnit CUs[]= new ICompilationUnit[inputFileBaseNames.length];
-
-		for(int i= 0; i < inputFileBaseNames.length; i++) {
-			String filePath= inputFileBaseNames[i];
-
-			int projEnd= filePath.indexOf('/');
-			int pkgEnd= filePath.lastIndexOf('/');
-			int fileBegin= pkgEnd+1;
-
-			String projName= filePath.substring(0, projEnd);
-			String pkgName= filePath.substring(projEnd+1, pkgEnd).replace('/', '.');
-
-			IJavaProject project= projName2Project.get(projName);
-			IPackageFragmentRoot root= proj2PkgRoot.get(project);
-			IPackageFragment pkg= root.getPackageFragment(pkgName);
-
-			CUs[i]= createCUForBugTestCase(project, pkg, filePath.substring(fileBegin), true);
-		}
-		return CUs;
-	}
-
-	private void addProjectDependencies(String[] dependencies, Map<String, IJavaProject> projName2Project) throws JavaModelException {
-		for (String dependency : dependencies) {
-			// dependent:provider
-			int colonIdx= dependency.indexOf(':');
-			String depName= dependency.substring(0, colonIdx);
-			String provName= dependency.substring(colonIdx+1);
-			IJavaProject depProj= projName2Project.get(depName);
-			IJavaProject provProj= projName2Project.get(provName);
-			JavaProjectHelper.addRequiredProject(depProj, provProj);
-		}
-	}
-
-	private void createProjectPackageStructure(Map<String, Set<String>> projName2PkgNames, Map<String, IJavaProject> projName2Project, Map<IJavaProject, IPackageFragmentRoot> proj2PkgRoot) throws CoreException, JavaModelException {
-		for (Map.Entry<String, Set<String>> entry : projName2PkgNames.entrySet()) {
-			String projName = entry.getKey();
-			IJavaProject project= JavaProjectHelper.createJavaProject(projName, "bin");
-			IPackageFragmentRoot root= JavaProjectHelper.addSourceContainer(project, CONTAINER);
-			JavaProjectHelper.addRTJar(project);
-			Set<IPackageFragment> pkgs= new HashSet<>();
-			projName2Project.put(projName, project);
-			proj2PkgRoot.put(project, root);
-			for (String pkgName : entry.getValue()) {
-				pkgs.add(root.createPackageFragment(pkgName, true, null));
-			}
-		}
-	}
-
-	private Map<String, Set<String>> collectProjectPackages(String[] inputFileBaseNames) {
-		Map<String, Set<String>> proj2Pkgs= new HashMap<>();
-
-		for (String filePath : inputFileBaseNames) {
-			int projEnd= filePath.indexOf('/');
-			String projName= filePath.substring(0, projEnd);
-			String pkgName= filePath.substring(projEnd+1, filePath.lastIndexOf('/'));
-
-			Set<String> projPkgs= proj2Pkgs.get(projName);
-
-			if (projPkgs == null)
-				proj2Pkgs.put(projName, projPkgs= new HashSet<>());
-			projPkgs.add(pkgName);
-		}
-		return proj2Pkgs;
-	}
-
-	private void failHelper(int expectedStatus) throws Exception {
-		ICompilationUnit	cu= createCUForSimpleTest(getPackageP(), false, true);
-		ISourceRange		selection= findSelectionInSource(cu.getSource());
-		IntroduceFactoryRefactoring	ref= new IntroduceFactoryRefactoring(cu, selection.getOffset(), selection.getLength());
-		RefactoringStatus	result= performRefactoring(ref);
-
-		assertNotNull("precondition was supposed to fail", result);
-		assertEquals("status", expectedStatus, result.getSeverity());
-	}
-
 	//--- TESTS
 	@Test
 	public void testStaticContext_FFF() throws Exception {
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTests15.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTests15.java
new file mode 100644
index 0000000..95c4c2d
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTests15.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.refactoring;
+
+import org.junit.Test;
+
+import org.eclipse.jdt.ui.tests.refactoring.rules.JavaPreviewSetup;
+
+public class IntroduceFactoryTests15 extends IntroduceFactoryTestsBase {
+	private static final String REFACTORING_PATH= "IntroduceFactory/";
+
+	public IntroduceFactoryTests15() {
+		rts= new JavaPreviewSetup();
+	}
+
+	@Override
+	protected String getRefactoringPath() {
+		return REFACTORING_PATH;
+	}
+
+	//--- TESTS
+	@Test
+	public void test568987() throws Exception {
+		singleUnitBugHelper("RecCanConst", false);
+	}
+
+	@Test
+	public void test566943() throws Exception {
+		singleUnitBugHelper("RecCompConst", false);
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTestsBase.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTestsBase.java
new file mode 100644
index 0000000..c29c13c
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceFactoryTestsBase.java
@@ -0,0 +1,531 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * 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
+ *     Samrat Dhillon <samrat.dhillon@gmail.com> - [introduce factory] Introduce Factory on an abstract class adds a statement to create an instance of that class - https://bugs.eclipse.org/bugs/show_bug.cgi?id=395016
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+
+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.ISourceRange;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.SourceRange;
+
+import org.eclipse.jdt.internal.corext.refactoring.code.IntroduceFactoryRefactoring;
+
+import org.eclipse.jdt.ui.tests.refactoring.rules.Java1d6Setup;
+
+/**
+ * @author rfuhrer@watson.ibm.com
+ */
+public class IntroduceFactoryTestsBase extends GenericRefactoringTest {
+	private static final String REFACTORING_PATH= "IntroduceFactory/";
+
+	public IntroduceFactoryTestsBase() {
+		rts= new Java1d6Setup();
+	}
+
+	@Override
+	protected String getRefactoringPath() {
+		return REFACTORING_PATH;
+	}
+
+	/**
+	 * Produces a test file name based on the name of this JUnit testcase.
+	 * For input files, trims off the trailing part of the test name that
+	 * begins with a '_', to get rid of the options part, so that we can
+	 * have a single (suite of) input file(s) but several outputs dependent
+	 * on the option settings.
+	 * @param input true iff the requested file is an input file.
+	 * @return the name of the test file, with a trailing "_in.java" if an input
+	 * file and a trailing "_XXX.java" if an output file and the test name/options
+	 * are "_XXX".
+	 */
+	private String getSimpleTestFileName(boolean input) {
+		String	testName = getName();
+		int		usIdx=  testName.indexOf('_');
+		int		endIdx= (usIdx >= 0) ? usIdx : testName.length();
+		String	fileName = (input ? (testName.substring(4, endIdx) + "_in") : testName.substring(4));
+
+		return fileName + ".java";
+	}
+
+	/**
+	 * Produces a test file name based on the name of this JUnit testcase,
+	 * like getSimpleTestFileName(), but also prepends the appropriate version
+	 * of the resource path (depending on the value of <code>positive</code>).
+	 * Test files are assumed to be located in the resources directory.
+	 * @param positive true iff the requested file is for a positive unit test
+	 * @param input true iff the requested file is an input file
+	 * @return the test file name
+	 */
+	private String getTestFileName(boolean positive, boolean input) {
+		String path= TEST_PATH_PREFIX + getRefactoringPath();
+
+		path += (positive ? "positive/": "negative/");
+		return path + getSimpleTestFileName(input);
+	}
+
+	/**
+	 * Produces a compilation unit from an input source file whose name
+	 * is based on the testcase name.
+	 * Test files are assumed to be located in the resources directory.
+	 * @param pack
+	 * @param positive
+	 * @param input
+	 * @return the ICompilationUnit created from the specified test file
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	private ICompilationUnit createCUForSimpleTest(IPackageFragment pack,
+												  boolean positive, boolean input)
+		throws Exception
+	{
+		String	fileName= getTestFileName(positive, input);
+		String	cuName= getSimpleTestFileName(input);
+
+		return createCU(pack, cuName, getFileContents(fileName));
+	}
+
+	/**
+	 * Produces a test file name based on the name of this JUnit testcase,
+	 * like getSimpleTestFileName(), but also prepends the appropriate version
+	 * of the resource path (depending on the value of <code>positive</code>).
+	 * Test files are assumed to be located in the resources directory.
+	 * @param project the project
+	 * @param pack the package fragment
+	 * @param fileName the file name
+	 * @param input true iff the requested file is an input file
+	 * @return the test file name
+	 */
+	private String getBugTestFileName(IJavaProject project, IPackageFragment pack, String fileName, boolean input) {
+		String testName= getName();
+		String testNumber= testName.substring("test".length());//$NON-NLS-1$
+		String path= TEST_PATH_PREFIX + getRefactoringPath() + "Bugzilla/" + testNumber + "/" +
+									(project == null ? "" : project.getElementName() + "/") +
+									(pack == getPackageP() ? "" : pack.getElementName() + "/");
+
+		return path + fileName + (input ? "" : "_out") + ".java";//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	}
+
+	/**
+	 * Produces a compilation unit from an input source file whose path
+	 * is based on the testcase name, but whose basename is supplied by
+	 * the caller.
+	 * Test files are assumed to be located in the resources directory.
+	 * @param project can be null if only 1 project exists in the test workspace
+	 * @param pack
+	 * @param baseName
+	 * @param input
+	 * @return the ICompilationUnit created from the specified test file
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	private ICompilationUnit createCUForBugTestCase(IJavaProject project,
+													IPackageFragment pack, String baseName, boolean input)
+		throws Exception
+	{
+		String	fileName= getBugTestFileName(project, pack, baseName, input);
+		String	cuName= baseName + (input ? "" : "_out") + ".java";
+
+		return createCU(pack, cuName, getFileContents(fileName));
+	}
+
+	static final String SELECTION_START_HERALD= "/*[*/";
+	static final String SELECTION_END_HERALD= "/*]*/";
+
+	/**
+	 * Finds and returns the selection markers in the given source string,
+	 * i.e. the first occurrences of <code>SELECTION_START_HERALD</code> and
+	 * <code>SELECTION_END_HERALD</code>. Fails an assertion if either of these
+	 * markers is not present in the source string.
+	 * @param source
+	 * @return an ISourceRange representing the marked selection
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	private ISourceRange findSelectionInSource(String source) throws Exception {
+		int		begin= source.indexOf(SELECTION_START_HERALD) + SELECTION_START_HERALD.length();
+		int		end= source.indexOf(SELECTION_END_HERALD);
+
+		if (begin < SELECTION_START_HERALD.length())
+			fail("No selection start comment in input source file!");
+		if (end < 0)
+			fail("No selection end comment in input source file!");
+
+		return new SourceRange(begin, end-begin);
+	}
+
+	private void doSingleUnitTest(boolean protectConstructor, ICompilationUnit cu, String outputFileName) throws Exception, JavaModelException, IOException {
+		ISourceRange		selection= findSelectionInSource(cu.getSource());
+		IntroduceFactoryRefactoring	ref= new IntroduceFactoryRefactoring(cu, selection.getOffset(), selection.getLength());
+
+		ref.setProtectConstructor(protectConstructor);
+
+		RefactoringStatus	activationResult= ref.checkInitialConditions(new NullProgressMonitor());
+
+		assertTrue("activation was supposed to be successful", activationResult.isOK());
+
+		RefactoringStatus	checkInputResult= ref.checkFinalConditions(new NullProgressMonitor());
+
+		if (!checkInputResult.isOK()) {
+			performChange(ref, false);
+
+			String newSource = cu.getSource();
+
+			System.err.println("!!!Precondition failed for " + getName() + "!!!");
+			System.err.println("Compile-time error: " + checkInputResult.toString());
+			System.err.println("Offending source:");
+			System.err.print(newSource);
+			fail("precondition was supposed to pass but was " + checkInputResult.toString());
+		}
+
+		performChange(ref, false);
+
+		String newSource = cu.getSource();
+
+		assertEqualLines(getName() + ": ", getFileContents(outputFileName), newSource);
+	}
+
+	private void doSingleUnitTestWithWarning(boolean protectConstructor, ICompilationUnit cu, String outputFileName) throws Exception, JavaModelException, IOException {
+		ISourceRange selection= findSelectionInSource(cu.getSource());
+		IntroduceFactoryRefactoring ref= new IntroduceFactoryRefactoring(cu, selection.getOffset(), selection.getLength());
+
+		ref.setProtectConstructor(protectConstructor);
+
+		RefactoringStatus activationResult= ref.checkInitialConditions(new NullProgressMonitor());
+
+		assertTrue("activation was supposed to be successful", activationResult.isOK());
+
+		RefactoringStatus checkInputResult= ref.checkFinalConditions(new NullProgressMonitor());
+
+		assertEquals(RefactoringStatus.WARNING, checkInputResult.getSeverity());
+		performChange(ref, false);
+
+		String newSource= cu.getSource();
+
+		assertEqualLines(getName() + ": ", getFileContents(outputFileName), newSource);
+	}
+
+	/**
+	 * Tests the IntroduceFactoryRefactoring refactoring on a single input source file
+	 * whose name is the test name (minus the "test" prefix and any trailing
+	 * options indicator such as "_FFF"), and compares the transformed code
+	 * to a source file whose name is the test name (minus the "test" prefix).
+	 * Test files are assumed to be located in the resources directory.
+	 * @param protectConstructor true iff IntroduceFactoryRefactoring should make the constructor private
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	void singleUnitHelper(boolean protectConstructor)
+		throws Exception
+	{
+		ICompilationUnit	cu= createCUForSimpleTest(getPackageP(), true, true);
+
+		doSingleUnitTest(protectConstructor, cu, getTestFileName(true, false));
+	}
+
+	/**
+	 * Tests the IntroduceFactoryRefactoring refactoring on a single input source file
+	 * whose name is the test name (minus the "test" prefix and any trailing
+	 * options indicator such as "_FFF"), and compares the transformed code
+	 * to a source file whose name is the test name (minus the "test" prefix).
+	 * Test files are assumed to be located in the resources directory.
+	 * @param baseFileName the base file name
+	 * @param protectConstructor true iff IntroduceFactoryRefactoring should make the constructor private
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	protected void singleUnitBugHelper(String baseFileName, boolean protectConstructor)
+		throws Exception
+	{
+		ICompilationUnit	cu= createCUForBugTestCase(null, getPackageP(), baseFileName, true);
+
+		doSingleUnitTest(protectConstructor, cu, getBugTestFileName(null, getPackageP(), baseFileName, false));
+	}
+
+	protected void singleUnitBugHelperWithWarning(String baseFileName, boolean protectConstructor)
+			throws Exception
+	{
+		ICompilationUnit cu= createCUForBugTestCase(null, getPackageP(), baseFileName, true);
+
+		doSingleUnitTestWithWarning(protectConstructor, cu, getBugTestFileName(null, getPackageP(), baseFileName, false));
+	}
+
+	/**
+	 * Like singleUnitHelper(), but allows for the specification of the names of
+	 * the generated factory method, class, and interface, as appropriate.
+	 * @param factoryMethodName the name to use for the generated factory method
+	 * @param factoryClassName the name of the factory class
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	void namesHelper(String factoryMethodName, String factoryClassName)
+		throws Exception
+	{
+		ICompilationUnit	cu= createCUForSimpleTest(getPackageP(), true, true);
+		ISourceRange		selection= findSelectionInSource(cu.getSource());
+		IntroduceFactoryRefactoring	ref= new IntroduceFactoryRefactoring(cu, selection.getOffset(), selection.getLength());
+
+		RefactoringStatus	activationResult= ref.checkInitialConditions(new NullProgressMonitor());
+
+		assertTrue("activation was supposed to be successful", activationResult.isOK());
+
+		if (factoryMethodName != null)
+			ref.setNewMethodName(factoryMethodName);
+		if (factoryClassName != null)
+			ref.setFactoryClass(factoryClassName);
+
+		RefactoringStatus	checkInputResult= ref.checkFinalConditions(new NullProgressMonitor());
+
+		assertTrue("precondition was supposed to pass but was " + checkInputResult.toString(), checkInputResult.isOK());
+
+		performChange(ref, false);
+
+		String newSource = cu.getSource();
+
+		assertEqualLines(getName() + ": ", getFileContents(getTestFileName(true, false)), newSource);
+	}
+
+	/**
+	 * Creates a compilation unit for a source file with a given base name (plus
+	 * "_in" suffix) in the given package. The source file is assumed to be
+	 * located in the test resources directory.<br>
+	 * Currently only handles positive tests.
+	 * @param fileName the base name of the source file (minus the "_in" suffix)
+	 * @param pack an IPackageFragment for the containing package
+	 * @return the ICompilationUnit for the newly-created unit
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	private ICompilationUnit createCUFromFileName(String fileName, IPackageFragment pack) throws Exception {
+		String fullName = TEST_PATH_PREFIX + getRefactoringPath() + "positive/" + fileName + "_in.java";
+
+		return createCU(pack, fileName + "_in.java", getFileContents(fullName));
+	}
+
+	private void doMultiUnitTest(ICompilationUnit[] CUs, String testPath, String[] outputFileBaseNames, String factoryClassName) throws Exception, JavaModelException, IOException {
+		ISourceRange selection= findSelectionInSource(CUs[0].getSource());
+		IntroduceFactoryRefactoring	ref= new IntroduceFactoryRefactoring(CUs[0], selection.getOffset(), selection.getLength());
+
+		RefactoringStatus activationResult= ref.checkInitialConditions(new NullProgressMonitor());
+
+		assertTrue("activation was supposed to be successful", activationResult.isOK());
+
+		if (factoryClassName != null)
+			ref.setFactoryClass(factoryClassName);
+
+		RefactoringStatus	checkInputResult= ref.checkFinalConditions(new NullProgressMonitor());
+
+		assertTrue("precondition was supposed to pass but was " + checkInputResult.toString(), checkInputResult.isOK());
+
+		performChange(ref, false);
+
+		String	testName= getName();
+
+		for (int i = 0; i < CUs.length; i++) {
+			int optIdx= testName.indexOf("_");
+			String testOptions= (optIdx >= 0) ? testName.substring(optIdx) : "";
+			String outFileName= testPath + outputFileBaseNames[i] + testOptions + "_out.java";
+			String xformedSrc= CUs[i].getSource();
+			String expectedSrc= getFileContents(outFileName);
+
+			assertEqualLines(getName() + ": ", expectedSrc, xformedSrc);
+		}
+	}
+
+	/**
+	 * Tests the IntroduceFactoryRefactoring refactoring on a set of input source files
+	 * whose names are supplied in the <code>fileBaseNames</code> argument,
+	 * and compares the transformed code to source files whose names are
+	 * the input base names plus the options suffix (e.g. "_FFF").
+	 * Test files are assumed to be located in the resources directory.
+	 * @param staticFactoryMethod true iff IntroduceFactoryRefactoring should make the factory method static
+	 * @param inputFileBaseNames an array of input source file base names
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	void multiUnitHelper(boolean staticFactoryMethod, String[] inputFileBaseNames)
+		throws Exception
+	{
+		IPackageFragment	pkg= getPackageP();
+		ICompilationUnit	CUs[]= new ICompilationUnit[inputFileBaseNames.length];
+
+		for (int i = 0; i < inputFileBaseNames.length; i++)
+			CUs[i] = createCUFromFileName(inputFileBaseNames[i], pkg);
+
+		String	testPath= TEST_PATH_PREFIX + getRefactoringPath() + "positive/";
+
+		doMultiUnitTest(CUs, testPath, inputFileBaseNames, null);
+	}
+
+	/**
+	 * Tests the IntroduceFactoryRefactoring refactoring on a set of input source files
+	 * whose names are supplied in the <code>fileBaseNames</code> argument,
+	 * and compares the transformed code to source files whose names are
+	 * the input base names plus the options suffix (e.g. "_FFF").
+	 * Test files are assumed to be located in the resources directory.
+	 * @param staticFactoryMethod true iff IntroduceFactoryRefactoring should make the factory method static
+	 * @param inputFileBaseNames an array of input source file base names
+	 * @param factoryClassName the fully-qualified name of the class to receive the factory method, or null
+	 * if the factory method is to be placed on the class defining the given constructor
+	 * @throws Exception
+	 */
+	@SuppressWarnings("javadoc")
+	void multiUnitBugHelper(boolean staticFactoryMethod, String[] inputFileBaseNames, String factoryClassName)
+		throws Exception
+	{
+		ICompilationUnit CUs[]= new ICompilationUnit[inputFileBaseNames.length];
+
+		for(int i= 0; i < inputFileBaseNames.length; i++) {
+			int pkgEnd= inputFileBaseNames[i].lastIndexOf('/')+1;
+			boolean explicitPkg= (pkgEnd > 0);
+			IPackageFragment pkg= explicitPkg ? getRoot().createPackageFragment(inputFileBaseNames[i].substring(0, pkgEnd-1), true, new NullProgressMonitor()) : getPackageP();
+
+			CUs[i]= createCUForBugTestCase(null, pkg, inputFileBaseNames[i].substring(pkgEnd), true);
+		}
+
+		String	testName= getName();
+		String	testNumber= testName.substring("test".length());
+		String	testPath= TEST_PATH_PREFIX + getRefactoringPath() + "Bugzilla/" + testNumber + "/";
+
+		doMultiUnitTest(CUs, testPath, inputFileBaseNames, factoryClassName);
+	}
+
+	void multiProjectBugHelper(String[] inputFileBaseNames, String[] dependencies) throws Exception {
+		Map<String, Set<String>> projName2PkgNames= collectProjectPackages(inputFileBaseNames);
+		Map<String, IJavaProject> projName2Project= new HashMap<>();
+		Map<IJavaProject, IPackageFragmentRoot> proj2PkgRoot= new HashMap<>();
+
+		try {
+			createProjectPackageStructure(projName2PkgNames, projName2Project, proj2PkgRoot);
+
+			ICompilationUnit[] CUs= createCUs(inputFileBaseNames, projName2Project, proj2PkgRoot);
+
+			addProjectDependencies(dependencies, projName2Project);
+
+			String testName= getName();
+			String testNumber= testName.substring("test".length());
+			String testPath= TEST_PATH_PREFIX + getRefactoringPath() + "Bugzilla/" + testNumber + "/";
+
+			doMultiUnitTest(CUs, testPath, inputFileBaseNames, null);
+
+		} finally {
+			for (IJavaProject project : proj2PkgRoot.keySet()) {
+				if (project.exists()) {
+					try {
+						project.getProject().delete(true, null);
+					} catch (CoreException e) {
+						// swallow exception to avoid destroying the original one
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+	}
+
+	private ICompilationUnit[] createCUs(String[] inputFileBaseNames, Map<String, IJavaProject> projName2Project, Map<IJavaProject, IPackageFragmentRoot> proj2PkgRoot) throws Exception {
+		ICompilationUnit CUs[]= new ICompilationUnit[inputFileBaseNames.length];
+
+		for(int i= 0; i < inputFileBaseNames.length; i++) {
+			String filePath= inputFileBaseNames[i];
+
+			int projEnd= filePath.indexOf('/');
+			int pkgEnd= filePath.lastIndexOf('/');
+			int fileBegin= pkgEnd+1;
+
+			String projName= filePath.substring(0, projEnd);
+			String pkgName= filePath.substring(projEnd+1, pkgEnd).replace('/', '.');
+
+			IJavaProject project= projName2Project.get(projName);
+			IPackageFragmentRoot root= proj2PkgRoot.get(project);
+			IPackageFragment pkg= root.getPackageFragment(pkgName);
+
+			CUs[i]= createCUForBugTestCase(project, pkg, filePath.substring(fileBegin), true);
+		}
+		return CUs;
+	}
+
+	private void addProjectDependencies(String[] dependencies, Map<String, IJavaProject> projName2Project) throws JavaModelException {
+		for (String dependency : dependencies) {
+			// dependent:provider
+			int colonIdx= dependency.indexOf(':');
+			String depName= dependency.substring(0, colonIdx);
+			String provName= dependency.substring(colonIdx+1);
+			IJavaProject depProj= projName2Project.get(depName);
+			IJavaProject provProj= projName2Project.get(provName);
+			JavaProjectHelper.addRequiredProject(depProj, provProj);
+		}
+	}
+
+	private void createProjectPackageStructure(Map<String, Set<String>> projName2PkgNames, Map<String, IJavaProject> projName2Project, Map<IJavaProject, IPackageFragmentRoot> proj2PkgRoot) throws CoreException, JavaModelException {
+		for (Map.Entry<String, Set<String>> entry : projName2PkgNames.entrySet()) {
+			String projName = entry.getKey();
+			IJavaProject project= JavaProjectHelper.createJavaProject(projName, "bin");
+			IPackageFragmentRoot root= JavaProjectHelper.addSourceContainer(project, CONTAINER);
+			JavaProjectHelper.addRTJar(project);
+			Set<IPackageFragment> pkgs= new HashSet<>();
+			projName2Project.put(projName, project);
+			proj2PkgRoot.put(project, root);
+			for (String pkgName : entry.getValue()) {
+				pkgs.add(root.createPackageFragment(pkgName, true, null));
+			}
+		}
+	}
+
+	private Map<String, Set<String>> collectProjectPackages(String[] inputFileBaseNames) {
+		Map<String, Set<String>> proj2Pkgs= new HashMap<>();
+
+		for (String filePath : inputFileBaseNames) {
+			int projEnd= filePath.indexOf('/');
+			String projName= filePath.substring(0, projEnd);
+			String pkgName= filePath.substring(projEnd+1, filePath.lastIndexOf('/'));
+
+			Set<String> projPkgs= proj2Pkgs.get(projName);
+
+			if (projPkgs == null)
+				proj2Pkgs.put(projName, projPkgs= new HashSet<>());
+			projPkgs.add(pkgName);
+		}
+		return proj2Pkgs;
+	}
+
+	protected void failHelper(int expectedStatus) throws Exception {
+		ICompilationUnit	cu= createCUForSimpleTest(getPackageP(), false, true);
+		ISourceRange		selection= findSelectionInSource(cu.getSource());
+		IntroduceFactoryRefactoring	ref= new IntroduceFactoryRefactoring(cu, selection.getOffset(), selection.getLength());
+		RefactoringStatus	result= performRefactoring(ref);
+
+		assertNotNull("precondition was supposed to fail", result);
+		assertEquals("status", expectedStatus, result.getSeverity());
+	}
+}
diff --git a/org.eclipse.jdt.ui/.settings/.api_filters b/org.eclipse.jdt.ui/.settings/.api_filters
index 90c76a9..01b5436 100644
--- a/org.eclipse.jdt.ui/.settings/.api_filters
+++ b/org.eclipse.jdt.ui/.settings/.api_filters
@@ -63,6 +63,20 @@
                 <message_argument value="isCanonicalConstructor()"/>
             </message_arguments>
         </filter>
+        <filter comment="This is a Java 15 preview feature" id="640712815">
+            <message_arguments>
+                <message_argument value="IMethodBinding"/>
+                <message_argument value="IntroduceFactoryRefactoring"/>
+                <message_argument value="isCompactConstructor()"/>
+            </message_arguments>
+        </filter>
+        <filter comment="This is a Java 15 preview feature" id="640712815">
+            <message_arguments>
+                <message_argument value="RecordDeclaration"/>
+                <message_argument value="IntroduceFactoryRefactoring"/>
+                <message_argument value="recordComponents()"/>
+            </message_arguments>
+        </filter>
     </resource>
     <resource path="core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ReplaceInvocationsRefactoring.java" type="org.eclipse.jdt.internal.corext.refactoring.code.ReplaceInvocationsRefactoring">
         <filter id="571519004">
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceFactoryRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceFactoryRefactoring.java
index 979ee68..97c3575 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceFactoryRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceFactoryRefactoring.java
@@ -66,6 +66,7 @@
 import org.eclipse.jdt.core.dom.Name;
 import org.eclipse.jdt.core.dom.NodeFinder;
 import org.eclipse.jdt.core.dom.ParameterizedType;
+import org.eclipse.jdt.core.dom.RecordDeclaration;
 import org.eclipse.jdt.core.dom.ReturnStatement;
 import org.eclipse.jdt.core.dom.SimpleName;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
@@ -579,7 +580,13 @@
 		if (ctorDecl != null) {
 			List<SingleVariableDeclaration>	formalArgs= ctorDecl.parameters();
 			int i= 0;
-
+			if (formalArgs.size() == 0 && numArgs > 0 && fCtorBinding.isCompactConstructor()) {
+				ASTNode parent= ctorDecl.getParent();
+				if (parent instanceof RecordDeclaration) {
+					RecordDeclaration recDecl= (RecordDeclaration) parent;
+					formalArgs= recDecl.recordComponents();
+				}
+			}
 			for(Iterator<SingleVariableDeclaration> iter= formalArgs.iterator(); iter.hasNext(); i++) {
 				SingleVariableDeclaration svd= iter.next();
 
