protected Set<TraceAddressSnapRange> subtractFrom(Lifespan span, AddressRange range,
			Set<TraceAddressSnapRange> cur, Set<TraceAddressSnapRange> set1,
			Set<TraceAddressSnapRange> set2) {
		Set<TraceAddressSnapRange> prevLeftOver = cur;
		Set<TraceAddressSnapRange> nextLeftOver = cur == set1 ? set2 : set1;
		for (TraceAddressSnapRange tasr : mapSpace.reduce(
			TraceAddressSnapRangeQuery.intersecting(range, span)).keys()) {
			for (TraceAddressSnapRange lo : prevLeftOver) {
				if (tasr.encloses(lo)) {
					continue;
				}
				if (!lo.intersects(tasr)) {
					nextLeftOver.add(lo);
					continue;
				}
				TraceAddressSnapRange intersection = lo.intersection(tasr);
				// TODO: See how this performs in practice.
				// This could cause an explosion before a reduction....
				if (lo.getX1().compareTo(intersection.getX1()) < 0) {
					nextLeftOver.add(new ImmutableTraceAddressSnapRange(lo.getX1(),
						intersection.getX1().previous(), lo.getLifespan()));
				}
				if (lo.getX2().compareTo(intersection.getX2()) > 0) {
					nextLeftOver.add(new ImmutableTraceAddressSnapRange(intersection.getX2().next(),
						lo.getX2(), lo.getLifespan()));
				}
				if (lo.getY1().compareTo(intersection.getY1()) < 0) {
					nextLeftOver.add(new ImmutableTraceAddressSnapRange(intersection.getRange(),
						Lifespan.span(lo.getY1(), intersection.getY1() - 1)));
				}
				if (lo.getY2().compareTo(intersection.getY2()) > 0) {
					nextLeftOver.add(new ImmutableTraceAddressSnapRange(intersection.getRange(),
						Lifespan.span(intersection.getY2() + 1, lo.getY2())));
				}
			}
			if (nextLeftOver.isEmpty()) {
				return nextLeftOver;
			}

			Set<TraceAddressSnapRange> clear = prevLeftOver;
			clear.clear();
			prevLeftOver = nextLeftOver;
			nextLeftOver = clear;
		}
		return prevLeftOver;
	}
Subtract from cur, the boxes covered by the entries intersecting the given query box

<p>
Compute C = A - B, where A B and C are sets of (possibly overlapping) boxes. A is given by
{@code} cur, and B is the set of bounding boxes for entries intersecting the query box. Two
temporary sets must be provided, and {@code cur} must be identical to one of them. This
routine will mutate them. The returned result will be identical to one of them.

<p>
If repeated subtraction is needed, the temporary sets need only be constructed once. For each
subsequent round of subtraction, {@code cur} should be the returned result of the previous
round. The final result is the return value of the final round.

<p>
This is used in the implementation of {@link #coversRange(TraceAddressSnapRange)}.

@param span the lifespan of the query box
@param range the address range of the query box
@param cur the set of boxes, identical to one of the temporary working sets.
@param set1 a temporary set for working
@param set2 a temporary set for working
@return the result of subtraction, identical to one of the temporary working sets
Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/AbstractBaseDBTraceDefinedUnitsView.java