@Test
	public void testMergeFunctionReplacingForcedIndirectOnReturnWithAutoParam() throws Exception {

		mtf.initialize("NotepadMergeListingTest_X86", new ProgramModifierListener() {

			// should apply diff on return type and jim vs. bob parameter name, with return ptr auto-param

			@Override
			public void modifyLatest(ProgramDB program) {
				try {
					Structure struct = new StructureDataType("struct", 20);
					Function func = getFunction(program, "0x1002249");
					func.getParameter(1).setName("bob", SourceType.USER_DEFINED);
					// trigger injection of auto-param return pointer as parameter-1 (bob is now parameter-2)
					func.setReturn(struct, VariableStorage.UNASSIGNED_STORAGE,
						SourceType.USER_DEFINED);
					func.setCallingConvention(CompilerSpec.CALLING_CONVENTION_stdcall);
				}
				catch (Exception e) {
					e.printStackTrace();
					Assert.fail(e.getMessage());
				}
				Function func = getFunction(program, "0x1002249");
				assertEquals("struct * FUN_01002249(struct * __return_storage_ptr__, int bob)",
					func.getPrototypeString(false, false));
				assertEquals(2, func.getParameterCount());
				Parameter parameter = func.getParameter(0);
				assertEquals("[struct * __return_storage_ptr__@Stack[0x4]:4 (auto)]",
					parameter.toString());
				parameter = func.getParameter(1);
				assertEquals("[int bob@Stack[0x8]:4]", parameter.toString());
			}

			@Override
			public void modifyPrivate(ProgramDB program) {
				// Forced indirect for the return.
				try {
					Function func = getFunction(program, "0x1002249");
					func.getParameter(1).setName("jim", SourceType.USER_DEFINED);
					func.setReturn(Undefined4DataType.dataType, VariableStorage.UNASSIGNED_STORAGE,
						SourceType.USER_DEFINED);
				}
				catch (Exception e) {
					e.printStackTrace();
					Assert.fail(e.getMessage());
				}
				Function func = getFunction(program, "0x1002249");
				assertEquals("undefined4 FUN_01002249(MyClass * this, int jim)",
					func.getPrototypeString(false, false));
				assertEquals(2, func.getParameterCount());
				Parameter parameter = func.getParameter(0);
				assertEquals("[MyClass * this@ECX:4 (auto)]", parameter.toString());
				parameter = func.getParameter(1);
				assertEquals("[int jim@Stack[0x4]:4]", parameter.toString());
			}
		});

		p1 = mtf.getResultProgram();
		p2 = mtf.getPrivateProgram();

		int txId = p1.startTransaction("Merge into Program 1");
		boolean commit = false;
		try {
			AddressSet setToDiff = new AddressSet();
			setToDiff.addRange(addr(p1, "0x1002249"), addr(p1, "0x1002249"));
			programMerge = new ProgramMergeManager(p1, p2, setToDiff);

			programMerge.setDiffFilter(new ProgramDiffFilter(ProgramDiffFilter.FUNCTION_DIFFS));
			programMerge.setMergeFilter(
				new ProgramMergeFilter(ProgramMergeFilter.FUNCTIONS, ProgramMergeFilter.MERGE));
			AddressSet expectedDiffsBefore = new AddressSet();
			expectedDiffsBefore.addRange(addr(p1, "0x1002249"), addr(p1, "0x1002249"));
			assertEquals(expectedDiffsBefore, programMerge.getFilteredDifferences());

			AddressSet mergeSet = new AddressSet();
			mergeSet.addRange(addr(p1, "0x1002249"), addr(p1, "0x1002249"));
			programMerge.merge(mergeSet, TaskMonitor.DUMMY);

			AddressSet expectedDiffsAfter = new AddressSet();
			assertEquals(expectedDiffsAfter, programMerge.getFilteredDifferences());

			Function func = getFunction(p1, "0x1002249");
			assertEquals("undefined4 FUN_01002249(MyClass * this, int jim)",
				func.getPrototypeString(false, false));
			assertEquals(2, func.getParameterCount());
			Parameter parameter = func.getParameter(0);
			assertEquals("[MyClass * this@ECX:4 (auto)]", parameter.toString());
			parameter = func.getParameter(1);
			assertEquals("[int jim@Stack[0x4]:4]", parameter.toString());
			commit = true;
		}
		finally {
			p1.endTransaction(txId, commit);
		}
	}
<CODE>ProgramMerge2Test</CODE> tests the <CODE>ProgramMerge</CODE> class
to verify it correctly merges various types of program differences.
The tests modify copies of the same program to cause differences
between these two programs, which can then be merged.
Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramMerge2Test.java