@Test
	public void testClear() throws CodeUnitInsertionException, CancelledException, IOException {
		TraceData d4000;
		TraceData d4004;
		TraceInstruction i4008;
		try (Transaction tx = b.startTransaction()) {
			d4000 = b.addData(0, b.addr(0x4000), IntegerDataType.dataType, b.buf(1, 2, 3, 4));
			d4000.setEndSnap(9);
			d4004 = b.addData(0, b.addr(0x4004), IntegerDataType.dataType, b.buf(5, 6, 7, 8));
			d4004.setEndSnap(5);
			i4008 = b.addInstruction(0, b.addr(0x4008), b.host, b.buf(0xf4, 0));
			i4008.setEndSnap(9);
		}

		assertEquals(d4000, manager.definedUnits().getAt(0, b.addr(0x4000)));
		try (Transaction tx = b.startTransaction()) {
			manager.definedUnits()
					.clear(Lifespan.ALL, b.range(0x0000, -0x0001), false,
						TaskMonitor.DUMMY);
		}
		assertNull(manager.definedUnits().getAt(0, b.addr(0x4000)));
		assertNull(manager.definedUnits().getAt(0, b.addr(0x4004)));
		assertNull(manager.definedUnits().getAt(0, b.addr(0x4008)));
		assertUndefinedWithAddr(b.addr(0x4000), manager.codeUnits().getAt(0, b.addr(0x4000)));

		b.trace.undo();
		d4000 = manager.definedData().getAt(0, b.addr(0x4000));
		d4004 = manager.definedData().getAt(0, b.addr(0x4004));
		i4008 = manager.instructions().getAt(0, b.addr(0x4008));

		assertEquals(d4000, manager.definedUnits().getAt(7, b.addr(0x4000)));
		try (Transaction tx = b.startTransaction()) {
			manager.definedUnits()
					.clear(Lifespan.span(7, 8), b.range(0x0000, -0x0001), false,
						TaskMonitor.DUMMY);
		}
		assertNull(manager.definedUnits().getAt(7, b.addr(0x4000)));
		assertNull(manager.definedUnits().getAt(7, b.addr(0x4004)));
		assertNull(manager.definedUnits().getAt(7, b.addr(0x4008)));
		assertEquals(Lifespan.span(0, 6), d4000.getLifespan());
		assertEquals(Lifespan.span(0, 5), d4004.getLifespan());
		assertEquals(Lifespan.span(0, 6), i4008.getLifespan());

		b.trace.undo();
		d4000 = manager.definedData().getAt(0, b.addr(0x4000));
		d4004 = manager.definedData().getAt(0, b.addr(0x4004));
		i4008 = manager.instructions().getAt(0, b.addr(0x4008));

		assertEquals(d4000, manager.definedUnits().getAt(7, b.addr(0x4000)));
		try (Transaction tx = b.startTransaction()) {
			manager.definedUnits()
					.clear(Lifespan.span(7, 8), b.range(0x4000, 0x4000), false,
						TaskMonitor.DUMMY);
		}
		assertNull(manager.definedUnits().getAt(7, b.addr(0x4000)));
		assertEquals(d4004, manager.definedUnits().getAt(5, b.addr(0x4004)));
		assertEquals(i4008, manager.definedUnits().getAt(7, b.addr(0x4008)));
		assertEquals(Lifespan.span(0, 6), d4000.getLifespan());
		assertEquals(Lifespan.span(0, 5), d4004.getLifespan());
		assertEquals(Lifespan.span(0, 9), i4008.getLifespan());

		b.trace.undo();
		d4000 = manager.definedData().getAt(0, b.addr(0x4000));
		d4004 = manager.definedData().getAt(0, b.addr(0x4004));
		i4008 = manager.instructions().getAt(0, b.addr(0x4008));

		assertEquals(d4000, manager.definedUnits().getAt(0, b.addr(0x4000)));
		try (Transaction tx = b.startTransaction()) {
			manager.instructions()
					.clear(Lifespan.ALL, b.range(0x0000, -0x0001), false,
						TaskMonitor.DUMMY);
		}
		assertEquals(d4000, manager.definedUnits().getAt(0, b.addr(0x4000)));
		assertEquals(d4004, manager.definedUnits().getAt(0, b.addr(0x4004)));
		assertNull(manager.definedUnits().getAt(0, b.addr(0x4008)));

		b.trace.undo();
		d4000 = manager.definedData().getAt(0, b.addr(0x4000));
		d4004 = manager.definedData().getAt(0, b.addr(0x4004));
		i4008 = manager.instructions().getAt(0, b.addr(0x4008));

		assertEquals(d4000, manager.definedUnits().getAt(0, b.addr(0x4000)));
		try (Transaction tx = b.startTransaction()) {
			manager.definedData()
					.clear(Lifespan.ALL, b.range(0x0000, -0x0001), false,
						TaskMonitor.DUMMY);
		}
		assertNull(manager.definedUnits().getAt(0, b.addr(0x4000)));
		assertNull(manager.definedUnits().getAt(0, b.addr(0x4004)));
		assertEquals(i4008, manager.definedUnits().getAt(0, b.addr(0x4008)));

		// TODO: Verify events fire
	}
This test is interesting because the pointer type def causes an update to the data type
settings <em>while the unit is still being created</em>. This will invalidate the trace's
caches. All of them, including the defined data units, which can become the cause of many
timing issues.
Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeManagerTest.java