@Test
	public void testAddDiffExternalFunctionKeepBoth() throws Exception {
		final String libname = "user32.dll";
		final String parentNamespace = "MyNamespace";
		final String label1 = "oranges";
		final String label2 = "apples";
		final String address = null;
		final String param1 = "P1";
		final String param2 = "Length";
		final String comment1 = "Test Parameter Comment";
		final String comment2 = "My Parameter Comment";

		mtf.initialize("NotepadMergeListingTest", new MergeProgramModifier() {

			@Override
			public void initializeProgram(MergeProgram program) throws Exception {
				program.addMemory("memory", "0x0", 0x200);
			}

			@Override
			public void modifyLatest(MergeProgram mergeProgram) throws Exception {
				Library library =
					mergeProgram.createExternalLibrary(libname, SourceType.USER_DEFINED);
				Namespace namespace =
					mergeProgram.createNamespace(library, parentNamespace, SourceType.USER_DEFINED);
				mergeProgram.addExternalFunction(namespace, label1, "0x120",
					SourceType.USER_DEFINED);
				ExternalLocation externalLocation = mergeProgram.addExternalFunction(namespace,
					label2, address, SourceType.USER_DEFINED);

				Function function = externalLocation.getFunction();
				assertNotNull(function);

				Program program = mergeProgram.getProgram();
				Parameter parameter1 = new ParameterImpl(param1, new DWordDataType(), 4, program);
				parameter1.setComment(comment1);

				mergeProgram.updateFunction(function, true, new ByteDataType(), parameter1);
			}

			@Override
			public void modifyPrivate(MergeProgram mergeProgram) throws Exception {
				Library library =
					mergeProgram.createExternalLibrary(libname, SourceType.USER_DEFINED);
				Namespace namespace =
					mergeProgram.createNamespace(library, parentNamespace, SourceType.USER_DEFINED);
				ExternalLocation externalLocation = mergeProgram.addExternalFunction(namespace,
					label2, address, SourceType.USER_DEFINED);

				Function function = externalLocation.getFunction();
				assertNotNull(function);

				Program program = mergeProgram.getProgram();
				Register register = program.getRegister("r0l");
				Parameter parameter1 =
					new ParameterImpl(param2, new CharDataType(), register, program);
				parameter1.setComment(comment2);

				mergeProgram.updateFunction(function, true, new FloatDataType(), parameter1);
			}
		});

		executeMerge(ASK_USER);
		chooseButtonAndApply("Resolve External Add Conflict", KEEP_BOTH_BUTTON);
		waitForMergeCompletion();

		SymbolTable symbolTable = resultProgram.getSymbolTable();
		Namespace externalLibrary = (Namespace) symbolTable.getLibrarySymbol(libname).getObject();
		assertNotNull(externalLibrary);
		Namespace myNamespace = symbolTable.getNamespace(parentNamespace, externalLibrary);
		assertNotNull(myNamespace);

		Symbol oranges = getUniqueSymbol(resultProgram, label1, myNamespace);
		assertNotNull(oranges);

		List<Symbol> symbols = symbolTable.getSymbols(label2, myNamespace);
		assertEquals(2, symbols.size());
		Object obj1 = symbols.get(0).getObject();
		Object obj2 = symbols.get(1).getObject();
		assertTrue(obj1 instanceof Function);
		assertTrue(obj2 instanceof Function);
		Function fun1 = (Function) obj1;
		Function fun2 = (Function) obj2;

		if (!fun1.getReturnType().isEquivalent(new ByteDataType())) {
			Function tmp = fun1;
			fun1 = fun2;
			fun2 = tmp;
		}

		assertTrue(new ByteDataType().isEquivalent(fun1.getReturnType()));
		assertEquals(1, fun1.getParameterCount());
		Parameter parameter = fun1.getParameter(0);
		assertEquals(param1, parameter.getName());
		assertTrue(new DWordDataType().isEquivalent(parameter.getDataType()));
		assertTrue(parameter.isStackVariable());
		assertEquals(4, parameter.getStackOffset());
		assertEquals(comment1, parameter.getComment());

		assertTrue(new FloatDataType().isEquivalent(fun2.getReturnType()));
		assertEquals(1, fun2.getParameterCount());
		Parameter f2parameter = fun2.getParameter(0);
		assertEquals(param2, f2parameter.getName());
		assertTrue(new CharDataType().isEquivalent(f2parameter.getDataType()));
		assertTrue(f2parameter.isRegisterVariable());
		assertEquals(resultProgram.getRegister("r0l"), f2parameter.getRegister());
		assertEquals(comment2, f2parameter.getComment());
	}
The external function merger only detects and merges source differences when a name
difference is being merged.
Ghidra/Features/Base/src/test.slow/java/ghidra/app/merge/listing/ExternalMergerAddTest.java