@Override
	public boolean merge(TaskMonitor taskMonitor) throws CancelledException {
		isCancelled = false;
		mergeMonitor = taskMonitor;
		mergeMonitor.initialize(mergeResolvers.length);
		if (mergeMonitor instanceof TaskDialog) {
			((TaskDialog) taskMonitor).setCancelEnabled(false);
		}
		mergeStatus = true;
		try {
			SwingUtilities.invokeAndWait(new Runnable() {
				@Override
				public void run() {
					runManager.showProgressIcon(false);

					// For now just get the phases in order and assume the displayed phase info
					// is nested correctly.
					mergeProgressPanel = new MergeProgressPanel();
					for (MergeResolver mergeResolver : mergeResolvers) {
						String[][] phaseArray = mergeResolver.getPhases();
						for (String[] element : phaseArray) {
							mergeProgressPanel.addInfo(element);
						}
					}
					mergeTool = ModalPluginTool.createTool(getMergeTitle());
					mergePlugin =
						createMergeManagerPlugin(mergeTool, MergeManager.this, resultDomainObject);

					Dimension d = getPreferredMergeToolSize();
					mergeTool.setSize(d.width, d.height);
					Point centerLoc = WindowUtilities.centerOnScreen(mergeTool.getSize());
					mergeTool.setLocation(centerLoc.x, centerLoc.y);

					initializeMerge();

					try {
						mergeTool.addPlugin(mergePlugin);
						// Adjust the size of the monitor component at the bottom of the merge tool.
						final JComponent monitorComp = runManager.getMonitorComponent();
						Dimension monitorDim = monitorComp.getPreferredSize();
						monitorDim.width = 500;
						monitorComp.setPreferredSize(monitorDim);
						mergeTool.addStatusComponent(monitorComp, true, false);
					}
					catch (PluginException e) {
						Msg.error(this, e);
					}

					SwingUtilities.invokeLater(() -> scheduleMerge());

					// Show the tool while the merge is occurring and block until merge completes.
					mergeTool.setVisible(true);

					conflictsResolveCompleted(); // make sure we cleanup tool

					cleanupMerge();
				}

				private String getMergeTitle() {
					DomainFile domainFile = resultDomainObject.getDomainFile();
					return "Merge Tool: " + domainFile.toString();
				}
			});
		}
		catch (InterruptedException e) {
		}
		catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new CancelledException();
		}
		finally {
			mergeCompleted = true;
			if (mergeMonitor instanceof TaskDialog) {
				((TaskDialog) taskMonitor).setCancelEnabled(true);
			}
		}

		MergeManagerProvider provider = mergePlugin.getProvider();
		if (taskMonitor.isCancelled() || provider.mergeWasCanceled()) {
			throw new CancelledException();
		}
		return mergeStatus;
	}
Returns one of the four programs involved in the merge as indicated by the version.
@param version the program version to return. (LATEST, MY, ORIGINAL, or RESULT).
@return the indicated program version or null if a valid version isn't specified.
@see MergeConstants
Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManager.java