@Test
	public void testMergeSymbolSource() throws Exception {
		mtf.initialize("NotepadMergeListingTest", new ProgramModifierListener() {
			@Override
			public void modifyLatest(ProgramDB program) {
				// P1 program
				SymbolTable st = program.getSymbolTable();
				Namespace namespace = program.getGlobalNamespace();
				try {
					// 0100248f is default function
					program.getFunctionManager()
							.getFunctionAt(addr(program, "0x0100248f"))
							.getSymbol()
							.setName("Bud", SourceType.IMPORTED);
					createDataReference(program, addr(program, "0x01001e81"),
						addr(program, "0x01001ea0"));
					Symbol[] symbols = st.getSymbols(addr(program, "0x01001ea0"));
					symbols[0].setName("Zero", SourceType.IMPORTED);
					st.createLabel(addr(program, "0x01001ea9"), "One", namespace,
						SourceType.USER_DEFINED);
					st.createLabel(addr(program, "0x01001eb5"), "Two", namespace,
						SourceType.IMPORTED);
					st.createLabel(addr(program, "0x01001ebc"), "Three", namespace,
						SourceType.ANALYSIS);
				}
				catch (Exception e) {
					Assert.fail(e.getMessage());
				}
			}

			@Override
			public void modifyPrivate(ProgramDB program) {
				// P2 program
				SymbolTable st = program.getSymbolTable();
				Namespace namespace = program.getGlobalNamespace();
				try {
					// 0100248f is default function
					program.getFunctionManager()
							.getFunctionAt(addr(program, "0x0100248f"))
							.getSymbol()
							.setName("Bud", SourceType.ANALYSIS);
					createDataReference(program, addr(program, "0x01001e81"),
						addr(program, "0x01001ea0"));// Leave this as default.
					Symbol[] symbols = st.getSymbols(addr(program, "0x01001ea0"));
					symbols[0].setName("Zero", SourceType.ANALYSIS);
					st.createLabel(addr(program, "0x01001ea9"), "One", namespace,
						SourceType.IMPORTED);
					st.createLabel(addr(program, "0x01001eb5"), "Two", namespace,
						SourceType.ANALYSIS);
					st.createLabel(addr(program, "0x01001ebc"), "Three", namespace,
						SourceType.USER_DEFINED);
				}
				catch (Exception e) {
					Assert.fail(e.getMessage());
				}
			}
		});

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

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

			programMerge.setDiffFilter(new ProgramDiffFilter(ProgramDiffFilter.SYMBOL_DIFFS));
			programMerge.setMergeFilter(
				new ProgramMergeFilter(ProgramMergeFilter.SYMBOLS, ProgramMergeFilter.MERGE));
			AddressSet expectedDiffs = new AddressSet();
			expectedDiffs.addRange(addr(p1, "0x01001ea0"), addr(p1, "0x01001ea0"));
			expectedDiffs.addRange(addr(p1, "0x01001ea9"), addr(p1, "0x01001ea9"));
			expectedDiffs.addRange(addr(p1, "0x01001eb5"), addr(p1, "0x01001eb5"));
			expectedDiffs.addRange(addr(p1, "0x01001ebc"), addr(p1, "0x01001ebc"));
			expectedDiffs.addRange(addr(p1, "0x0100248f"), addr(p1, "0x0100248f"));
			expectedDiffs.addRange(addr(p1, "0x1002691"), addr(p1, "0x1002691"));// Label in the 100248f namespace.
			assertEquals(expectedDiffs, programMerge.getFilteredDifferences());

			AddressSet mergeSet = new AddressSet();
			mergeSet.add(expectedDiffs);
			programMerge.merge(mergeSet, TaskMonitor.DUMMY);

			assertEquals(mergeSet, programMerge.getFilteredDifferences());

			SymbolTable st = p1.getSymbolTable();

			Symbol[] syms = st.getSymbols(addr(p1, "0x0100248f"));
			assertEquals(1, syms.length);
			assertEquals("Bud", syms[0].getName());
			assertEquals(SourceType.IMPORTED, syms[0].getSource());

			syms = st.getSymbols(addr(p1, "0x01001ea0"));
			assertEquals(1, syms.length);
			assertEquals("Zero", syms[0].getName());
			assertEquals(SourceType.IMPORTED, syms[0].getSource());

			syms = st.getSymbols(addr(p1, "0x01001ea9"));
			assertEquals(1, syms.length);
			assertEquals("One", syms[0].getName());
			assertEquals(SourceType.USER_DEFINED, syms[0].getSource());

			syms = st.getSymbols(addr(p1, "0x01001eb5"));
			assertEquals(1, syms.length);
			assertEquals("Two", syms[0].getName());
			assertEquals(SourceType.IMPORTED, syms[0].getSource());

			syms = st.getSymbols(addr(p1, "0x01001ebc"));
			assertEquals(1, syms.length);
			assertEquals("Three", syms[0].getName());
			assertEquals(SourceType.ANALYSIS, syms[0].getSource());
			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