private Address forwardToCommon(Listing[] listings, Address start) {
		CodeUnit realCU = listings[0].getCodeUnitContaining(start);
		if (realCU == null) {
			return null;
		}
		Address realStart = realCU.getMinAddress();
		CodeUnitIterator iter = listings[0].getCodeUnits(realStart, true);
		while (iter.hasNext()) {
			boolean matches = true;
			CodeUnit cu = iter.next();
			Address addr = cu.getMaxAddress();
			if (cu instanceof Instruction) {
				Instruction checkInstr = (Instruction) cu;
				int delaySlotDepth;
				if (checkInstr.isInDelaySlot()) {
					// unexpected - but lets handle it anyway
					delaySlotDepth = computeRemainingDelaySlots(checkInstr);
				}
				else {
					delaySlotDepth = checkInstr.getDelaySlotDepth();
				}
				while (delaySlotDepth != 0 && iter.hasNext()) {
					cu = iter.next();
					addr = cu.getMaxAddress();
					--delaySlotDepth;
				}
			}
			for (int i = 1; i < listings.length; i++) {
				CodeUnit checkCU = listings[i].getCodeUnitContaining(addr);
				if (checkCU == null) {
					break;
				}
				if (checkCU instanceof Instruction) {
					// make sure we consume delay-slotted instruction group
					Instruction checkInstr = (Instruction) checkCU;
					if (checkInstr.isInDelaySlot() || checkInstr.getDelaySlotDepth() != 0) {
						checkCU = findLastDelaySlot(checkInstr);
					}
				}
				if (!checkCU.getMaxAddress().equals(addr)) {
					matches = false;
					break;
				}
			}
			if (matches) {
				return addr;
			}
		}
		return null;
	}
Code units are compared between the indicated listings starting at the
indicated address. The listings are searched in forward address order
until the address is found where all the listings have a code unit
with the same maximum address.
@param listings the program listings in the order LATEST, MY, ORIGINAL.
@param start the address to start at.
@return the common address where code units end for all listings or null.
Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/CodeUnitMerger.java