void mergeCodeUnits(AddressSetView p1MergeSet, ProgramMergeFilter filter, TaskMonitor monitor)
			throws MemoryAccessException, CancelledException {
		boolean mergeInstructions =
			(filter.getFilter(ProgramMergeFilter.INSTRUCTIONS) == ProgramMergeFilter.REPLACE);
		boolean mergeData =
			(filter.getFilter(ProgramMergeFilter.DATA) == ProgramMergeFilter.REPLACE);
		if (!mergeInstructions && !mergeData) {
			return;
		}

		AddressSet byteDiffs2 = null;
		ProgramDiffFilter byteDiffFilter = new ProgramDiffFilter(ProgramDiffFilter.BYTE_DIFFS);
		if (filter.getFilter(ProgramMergeFilter.BYTES) == ProgramMergeFilter.IGNORE) {
			byteDiffs2 = DiffUtility.getCompatibleAddressSet(
				programDiff.getDifferences(byteDiffFilter, monitor), program2);
		}

		// ** Equates **
		ProgramDiffFilter equateDiffFilter = new ProgramDiffFilter(ProgramDiffFilter.EQUATE_DIFFS);
		AddressSetView equateDiffs1 = programDiff.getDifferences(equateDiffFilter, monitor);
		AddressSet equateDiffSet1 = equateDiffs1.intersect(p1MergeSet);
		AddressSet equateDiffSet2 = DiffUtility.getCompatibleAddressSet(equateDiffSet1, program2);

		// ** Code Units (Instructions/Data) **
		ProgramDiffFilter cuDiffFilter = new ProgramDiffFilter(ProgramDiffFilter.CODE_UNIT_DIFFS);
		AddressSetView codeUnitDiffs1 = programDiff.getDifferences(cuDiffFilter, monitor);
		AddressSet codeUnitDiffSet1 = codeUnitDiffs1.intersect(p1MergeSet);
		AddressSet codeUnitDiffSet2 =
			DiffUtility.getCompatibleAddressSet(codeUnitDiffSet1, program2);
		// MergeCodeUnits won't clear any code units where instruction prototypes match.
		merger.mergeCodeUnits(codeUnitDiffSet2, byteDiffs2, false, monitor);

		// Merge the references anywhere we replaced code units. 
		// Do a merge of references rather than replace so that we don't lose any non-default 
		// references where the instruction prototypes matched.
		// Use only the source's default references if we are ignoring reference diffs.
		boolean ignoreReferenceDiffs =
			filter.getFilter(ProgramMergeFilter.REFERENCES) == ProgramMergeFilter.IGNORE;
		boolean onlyKeepDefaults = ignoreReferenceDiffs;
		merger.mergeReferences(codeUnitDiffSet2, onlyKeepDefaults, monitor);

		merger.mergeEquates(equateDiffSet2, monitor);
	}
<CODE>mergeCodeUnits</CODE> merges all instructions and/or data
(as indicated) in the specified address set from the second program. 
It merges them into the merge program. When merging
instructions, the bytes are also moved if they differ.

@param p1MergeSet the addresses to be merged.
The addresses in this set should be derived from program1.
@param filter the current merge filter settings indicating what types
of differences should be merged.
@param monitor the task monitor for notifying the user of this merge's
progress.

@throws MemoryAccessException if bytes can't be copied.
Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMergeManager.java