@Override
	protected Pair<L, R> seekNext() {
		if (nextL != null) {
			assert nextR != null;
			int cmp = leftRanger.getMaxAddress(nextL).compareTo(rightRanger.getMaxAddress(nextR));
			if (cmp <= 0) {
				nextL = null; // Cause left to advance
			}
			if (cmp >= 0) { // Yes, both should advance if max's are equal
				nextR = null; // Cause right to advance
			}
		}
		else {
			assert nextR == null;
		}

		if (nextL == null) {
			if (!left.hasNext()) {
				return null;
			}
			nextL = left.next();
		}
		if (nextR == null) {
			if (!right.hasNext()) {
				return null;
			}
			nextR = right.next();
		}
		while (true) {
			if (leftRanger.getMaxAddress(nextL).compareTo(rightRanger.getMinAddress(nextR)) < 0) {
				if (!left.hasNext()) {
					nextL = null;
					return null;
				}
				nextL = left.next();
				continue;
			}
			if (rightRanger.getMaxAddress(nextR).compareTo(leftRanger.getMinAddress(nextL)) < 0) {
				if (!right.hasNext()) {
					nextR = null;
					return null;
				}
				nextR = right.next();
				continue;
			}
			// Left and right overlap!
			return pair;
		}
	}
A means of obtaining the range attribute from each object

@param <T> the type of objects returned by an iterator
Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/util/OverlappingObjectIterator.java