private void replaceFunctions(AddressSetView addrSet2, TaskMonitor monitor)
			throws CancelledException, UnsupportedOperationException {
		if (!originToResultTranslator.isOneForOneTranslator()) {
			String message = originToResultTranslator.getClass().getName() +
				" is not a one for one translator and can't replace functions.";
			throw new UnsupportedOperationException(message);
		}
		monitor.setMessage("Replacing Functions...");
		AddressSet addrSet = originToResultTranslator.getAddressSet(addrSet2);

		FunctionManager resultFM = resultProgram.getFunctionManager();
		FunctionManager originFM = originProgram.getFunctionManager();
		FunctionIterator funcIter1 = resultFM.getFunctions(addrSet, true);
		FunctionIterator funcIter2 = originFM.getFunctions(addrSet2, true);
		FunctionAddressIterator iter1 = new FunctionAddressIterator(funcIter1);
		FunctionAddressIterator iter2 = new FunctionAddressIterator(funcIter2);
		AddressIteratorConverter convertedIter2 =
			new AddressIteratorConverter(originProgram, iter2, resultProgram);
		// Get the addresses in the set.
		MultiAddressIterator functionIter =
			new MultiAddressIterator(new AddressIterator[] { iter1, convertedIter2 });
		AddressSet resultEntrySet = new AddressSet();
		while (functionIter.hasNext()) {
			monitor.checkCancelled();
			Address address = functionIter.next();
			resultEntrySet.addRange(address, address);
		}
		// Get each address in the address set and change the function.
		long totalAddresses = resultEntrySet.getNumAddresses();
		long granularity = (totalAddresses / PROGRESS_COUNTER_GRANULARITY) + 1;
		monitor.initialize(totalAddresses);
		AddressSet thunkSet = new AddressSet();
		AddressIterator it = resultEntrySet.getAddresses(true);
		for (int count = 0; it.hasNext(); count++) {
			monitor.checkCancelled();
			Address address = it.next();
			if (count % granularity == 0) {
				monitor.setProgress(count);
				monitor.setMessage("Replacing Function " + (count + 1) + " of " + totalAddresses +
					"." + " Address = " + address.toString(true));
			}
			if (isThunkFunction(address)) {
				// Skip the thunk, but save it for processing during a second pass.
				thunkSet.addRange(address, address);
				continue;
			}
			replaceFunction(address, monitor);
		}
		monitor.setProgress(totalAddresses);

		replaceThunks(thunkSet, monitor);
	}
<CODE>mergeFunctions</CODE> merges function differences within the specified
 address set.

@param addrSet the addresses to be merged.
The addresses in this set should be derived from program1.
@param monitor the task monitor for notifying the user of this merge's
progress.
@throws CancelledException if user cancels via the monitor.
Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java