public E set(D lower, D upper, V value) {
		// Go one out to find abutting ranges, too.
		D prev = getPreviousOrSame(lower);
		D next = getNextOrSame(upper);
		Set<E> toRemove = new LinkedHashSet<>();
		Map<R, V> toPut = new HashMap<>();
		for (E entry : getIntersecting(prev, next)) {
			R r = getRange(entry);
			int cmpMin = compare(getLower(r), lower);
			int cmpMax = compare(getUpper(r), upper);
			boolean sameVal = valuesEqual(getValue(entry), value);
			if (cmpMin <= 0 && cmpMax >= 0 && sameVal) {
				return entry; // The value in this range is already set as specified
			}
			toRemove.add(entry);
			if (cmpMin < 0) {
				if (sameVal) {
					// Expand the new entry to cover the one we just removed
					lower = getLower(r);
				}
				else {
					// Create a truncated entry to replace the one we just removed
					toPut.put(toSpan(getLower(r), prev), getValue(entry));
				}
			}
			if (cmpMax > 0) {
				if (sameVal) {
					// Expand the new entry to cover the one we just removed
					upper = getUpper(r);
				}
				else {
					// Create a truncated entry to replace the one we just removed
					toPut.put(toSpan(next, getUpper(r)), getValue(entry));
				}
			}
		}
		for (E entry : toRemove) {
			remove(entry);
		}
		E result = put(toSpan(lower, upper), value);
		assert toPut.size() <= 2;
		for (Entry<R, V> ent : toPut.entrySet()) {
			put(ent.getKey(), ent.getValue());
		}
		return result;
	}
Entry point: Set the given range to the given value, coalescing where possible

@param lower the lower bound
@param upper the upper bound
@param value the value
@return the entry containing the value
Ghidra/Framework/Emulation/src/main/java/generic/RangeMapSetter.java