private void breakTieWithCtrlFlow(ArrayList<DataNGram> matchList, boolean useOrder,
			TaskMonitor monitor) throws CancelledException {
		DataNGram current = matchList.get(0);
		if (current.weight <= 1) {
			return;					// Don't try to break ties on low weight n-grams
		}
		ArrayList<DataCtrl> cfragsList = new ArrayList<>();

		// Create the list of control-flow n-grams, and set up a way to get back to the original DataVertex
		for (int j = 0; j < matchList.size(); j++) {
			monitor.checkCancelled();
			DataVertex tiedVertex = matchList.get(j).root;

			// Mark the vertex as having been analyzed this pass.  This prevents additional
			// rounds of tie breaking on the same set of nodes for lower depth n-grams.  I.e.,
			// if vertices are indistinguishable at this depth, they will continue to be
			// indistinguishable at lower depths.
			tiedVertex.passComplete = pass;

			// The vertex is guaranteed to have at least 1 source, as the weight > 1
			DataVertex opVertex = (current.root.isOp() ? tiedVertex : tiedVertex.sources.get(0));
			CtrlVertex ctiedVertex = dataToCtrl(opVertex);
			for (int d = 0; d < ctiedVertex.ngrams.size(); d++) {
				CtrlNGram nGram = ctiedVertex.ngrams.get(d);
				DataCtrl temp = new DataCtrl(tiedVertex, nGram);		// Tie CtrlNGram to tiedVertex
				cfragsList.add(temp);
			}
		}

		cfragsList.sort(compareHashes);		// Sort list so that identical n-grams are adjacent
		int j = 0;
		while (j < cfragsList.size()) {
			if (monitor.isCancelled()) {
				return;
			}
			DataCtrl ccurrent = cfragsList.get(j);
			if (ccurrent.dataVertex.paired) {		// If we've already paired DataVertex
				j++;
				continue;							// Don't look at it again
			}

			int jbar = j + 1;
			while (jbar < cfragsList.size()) {	// Iterate to the first n-gram whose hash doesn't match
				DataCtrl cfuture = cfragsList.get(jbar);
				if (!ccurrent.ctrlNGram.equalHash(cfuture.ctrlNGram)) {
					break;
				}
				jbar++;
			}

			if (jbar - j == 2) {					// Exactly 2 matching n-gram hashes. Possible pair.
				DataCtrl cnext = cfragsList.get(j + 1);
				if (ccurrent.ctrlNGram.graphsDiffer(cnext.ctrlNGram)) {
					DataVertex temp0 = ccurrent.dataVertex;
					DataVertex temp1 = cnext.dataVertex;
					ngramPinner(temp0, temp1, current.depth);
				}
			}
			else if (useOrder && jbar - j > 2) {
				breakTieUsingOrder(cfragsList, j, jbar, current);
			}
			j = jbar;

		}
	}
Given a list of more than 2 DataNGrams with matching hash, try to distinguish the underlying
DataVertex objects by comparing CtrlNGrams associated with each DataVertex through its
containing CtrlVertex.  If DataVertex pairs can be distinguished, they are added to pinMap.
@param matchList is the list of matching DataNGrams
@param useOrder is true if block order should be used to break ties
@param monitor is the TaskMonitor
@throws CancelledException if the user cancels the task
Ghidra/Features/CodeCompare/src/main/java/ghidra/features/codecompare/graphanalysis/Pinning.java