@Test
	public void testReplaceOverlayOrderWithConflict() throws Exception {
		mtf.initialize("overlayCalc", new ProgramModifierListener() {
			@Override
			public void modifyLatest(ProgramDB program) {
				// P1 program
				SymbolTable st = program.getSymbolTable();
				try {
					// SomeOverlay 0x01001630 - 0x0100182f
					program.getMemory()
							.createInitializedBlock("SomeOverlay", addr(program, "0x01001630"),
								0x200, (byte) 0, TaskMonitor.DUMMY, true);
					// OtherOverlay 0x01001630 - 0x0100192f
					program.getMemory()
							.createInitializedBlock("OtherOverlay", addr(program, "0x01001630"),
								0x300, (byte) 0, TaskMonitor.DUMMY, true);

					st.createLabel(addr(program, "SomeOverlay::01001630"), "OVL1630_Latest",
						SourceType.USER_DEFINED);
					st.createLabel(addr(program, "OtherOverlay::01001646"), "OVL1646_Latest",
						SourceType.USER_DEFINED);
				}
				catch (Exception e) {
					Assert.fail(e.getMessage());
				}
			}

			@Override
			public void modifyPrivate(ProgramDB program) {
				// P2 program
				SymbolTable st = program.getSymbolTable();
				try {
					program.getMemory()
							.createInitializedBlock("OtherOverlay", addr(program, "0x01001630"),
								0x200, (byte) 0, TaskMonitor.DUMMY, true);
					program.getMemory()
							.createInitializedBlock("SomeOverlay", addr(program, "0x01001630"),
								0x300, (byte) 0, TaskMonitor.DUMMY, true);

					st.createLabel(addr(program, "SomeOverlay::01001630"), "OVL1630_Private",
						SourceType.USER_DEFINED);
					st.createLabel(addr(program, "OtherOverlay::01001646"), "OVL1646_Private",
						SourceType.USER_DEFINED);
				}
				catch (Exception e) {
					Assert.fail(e.getMessage());
				}
			}
		});

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

		int txId = p1.startTransaction("Replace in Program 1");
		boolean commit = false;
		try {
			AddressSet setToDiff = new AddressSet();
			setToDiff.addRange(addr(p1, "SomeOverlay::01001630"),
				addr(p1, "SomeOverlay::0100182f"));
			setToDiff.addRange(addr(p2, "SomeOverlay::01001830"),
				addr(p2, "SomeOverlay::0100192f"));
			setToDiff.addRange(addr(p1, "OtherOverlay::01001630"),
				addr(p1, "OtherOverlay::0100192f"));
			programMerge = new ProgramMergeManager(p1, p2, setToDiff);

			programMerge.setDiffFilter(new ProgramDiffFilter(ProgramDiffFilter.SYMBOL_DIFFS));
			AddressSet expectedDiffs = new AddressSet();
			expectedDiffs.addRange(addr(p1, "SomeOverlay::01001630"),
				addr(p1, "SomeOverlay::01001630"));
			expectedDiffs.addRange(addr(p1, "OtherOverlay::01001646"),
				addr(p1, "OtherOverlay::01001646"));
			assertEquals(expectedDiffs, programMerge.getFilteredDifferences());

			SymbolTable st1 = p1.getSymbolTable();
			Address a1 = addr(p1, "SomeOverlay::01001630");
			Address a2 = addr(p1, "OtherOverlay::01001646");
			System.out.println("Before:");
			for (Symbol s : st1.getSymbols(a1)) {
				System.out.println(a1 + " " + s.getName());
			}
			for (Symbol s : st1.getSymbols(a2)) {
				System.out.println(a2 + " " + s.getName());
			}

			programMerge.setMergeFilter(
				new ProgramMergeFilter(ProgramMergeFilter.SYMBOLS, ProgramMergeFilter.REPLACE));
			programMerge.merge(expectedDiffs, TaskMonitor.DUMMY);

			System.out.println("After:");
			for (Symbol s : st1.getSymbols(a1)) {
				System.out.println(a1 + " " + s.getName());
			}
			for (Symbol s : st1.getSymbols(a2)) {
				System.out.println(a2 + " " + s.getName());
			}

			AddressSet expectedPostMergeDiffs = new AddressSet();
			assertEquals(expectedPostMergeDiffs, programMerge.getFilteredDifferences());
			commit = true;
		}
		finally {
			p1.endTransaction(txId, commit);
		}

		SymbolTable resultSymTab = p1.getSymbolTable();

		Symbol[] symbols = resultSymTab.getSymbols(addr(p1, "SomeOverlay::01001630"));
		assertEquals(1, symbols.length);
		assertEquals("OVL1630_Private", symbols[0].getName());

		symbols = resultSymTab.getSymbols(addr(p1, "OtherOverlay::01001646"));
		assertEquals(1, symbols.length);
		assertEquals("OVL1646_Private", symbols[0].getName());
	}
<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