public void bytesChanged(Set<TraceAddressSnapRange> changed, long snap, Address start,
			byte[] oldBytes, byte[] newBytes) {
		AddressSet diffs = ByteArrayUtils.computeDiffsAddressSet(start, oldBytes, newBytes);
		Set<AbstractDBTraceCodeUnit<?>> affectedUnits = new HashSet<>();
		for (TraceAddressSnapRange box : changed) {
			if (!diffs.intersects(box.getX1(), box.getX2())) {
				continue;
			}
			for (AbstractDBTraceCodeUnit<?> unit : definedUnits.getIntersecting(box)) {
				if (diffs.intersects(unit.getMinAddress(), unit.getMaxAddress())) {
					affectedUnits.add(unit);
				}
			}
		}

		MemBuffer newBuf =
			new ByteMemBufferImpl(start, newBytes, trace.getBaseLanguage().isBigEndian());
		for (AbstractDBTraceCodeUnit<?> unit : affectedUnits) {
			// Rule:
			//     Break unit down into time portions before affected range, and at/within range
			//     For Data in affected range:
			//         For dynamic types, only accept if the length is unaffected
			//         For simple types, just re-apply
			//     For Instruction in affected range:
			//         Probably just delete it.
			long unitStartSnap;
			long unitEndSnap = unit.getEndSnap();
			if (unit.getStartSnap() < snap) {
				unit.setEndSnap(snap - 1);
				unitStartSnap = snap;
			}
			else {
				unitStartSnap = unit.getStartSnap();
				unit.delete();
			}
			if (unit instanceof DBTraceData) {
				DBTraceData dataUnit = (DBTraceData) unit;
				boolean reApply = false;
				DataType dataType = dataUnit.getDataType();
				if (dataType instanceof Dynamic) {
					Dynamic ddt = (Dynamic) dataType;
					WrappedMemBuffer newWrapped =
						new WrappedMemBuffer(newBuf, (int) dataUnit.getAddress().subtract(start));
					int newLength = ddt.getLength(newWrapped, dataUnit.getLength());
					reApply = newLength == unit.getLength();
				}
				else {
					reApply = true;
				}
				if (reApply) {
					try {
						definedData.create(Lifespan.span(unitStartSnap, unitEndSnap),
							unit.getAddress(), unit.getPlatform(), dataType, unit.getLength());
					}
					catch (CodeUnitInsertionException e) {
						throw new AssertionError(e);
					}
				}
			}
		}
	}
Notify this space that some bytes have changed

<p>
If any unit(s) contained the changed bytes, they may need to be truncated, deleted, and/or
replaced. Instructions are generally truncated or deleted without replacement. A data unit
may be replaced if its length would match that of the original.

@param changed the boxes whose bytes changed
@param snap the snap where the client requested the change
@param start the starting address where the client requested the change
@param oldBytes the old bytes
@param newBytes the new bytes
Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceCodeSpace.java