@Override
	public void merge(TaskMonitor monitor) {
		mergeManager.setInProgress(PROGRAM_CONTEXT_PHASE);
		mergeManager.updateProgress(0, "Initializing merge of program context registers...");
		initMergeInfo();
		if (mergeManager != null) {
			mergePanel = mergeManager.getListingMergePanel();
			if (conflictInfoPanel == null) {
				conflictInfoPanel = new ConflictInfoPanel();
			}
			mergePanel.setTopComponent(conflictInfoPanel);
		}
		try {
			List<String> latestNames = latestContext.getRegisterNames();
			List<String> myNames = myContext.getRegisterNames();
			if (!latestNames.equals(myNames)) {
				mergeManager.setStatusText("Program Context Registers don't match between the programs.");
				cancel();
				return;
			}

			ArrayList<Register> regs = new ArrayList<>(latestContext.getRegisters());
			// Sort the registers by size so that largest come first.
			// This prevents the remove call below from incorrectly clearing 
			// smaller registers that are part of a larger register.
			Collections.sort(regs, new Comparator<Register>() {
				@Override
				public int compare(Register r1, Register r2) {
					return r2.getBitLength() - r1.getBitLength();
				}
			});

			int transactionID = resultPgm.startTransaction(getDescription());
			boolean commit = false;
			try {
				int numRegs = regs.size();
				monitor.initialize(numRegs);

				// Get the conflicts for each register
				for (int i = 0; i < numRegs; i++) {
					Register reg = regs.get(i);
					if (reg.isProcessorContext()) {
						continue; // context register handle by code unit merge
					}
					String regName = reg.getName();
					int currentProgressPercentage = (int) (((float) 100 / numRegs) * i);
					mergeManager.updateProgress(currentProgressPercentage,
						"Merging register values for " + regName);
					monitor.setProgress(i);
					monitor.checkCancelled();
					rmm =
						new RegisterMergeManager(regName, mergeManager, resultPgm, originalPgm,
							latestPgm, myPgm, latestChanges, myChanges);
					rmm.merge(monitor);
				}
				mergeManager.updateProgress(100, "Done merging program context registers...");

				commit = true;
			}
			catch (CancelledException e) {
				mergeManager.setStatusText("User cancelled merge.");
				cancel();
			}
			finally {
				resultPgm.endTransaction(transactionID, commit);
			}
		}
		finally {
			monitor = null;
		}
		mergeManager.setCompleted(PROGRAM_CONTEXT_PHASE);
	}
Sets up the change address sets, Diffs between the various program versions,
and Merges from various versions to the resulting program.
Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/ProgramContextMergeManager.java