@Test
	public void testRecordThenAddTwoKindsOfBreakpointsDisable1Mixed() throws Throwable {
		createTarget1();
		Trace trace = getTrace(target1);
		traceManager.openTrace(trace);

		createProgramFromTrace(trace);
		intoProject(program);
		programManager.openProgram(program);

		addProgramTextBlock(program);
		MR text = addTargetTextRegion(target1);

		addTextMapping(target1, text, program);

		addProgramBreakpoints(program);
		addTargetSoftwareBreakpoint(target1, text);
		addTargetAccessBreakpoint(target1, text);
		waitOn(mappingService.changesSettled());
		waitOn(breakpointService.changesSettled());

		assertEquals(3, breakpointService.getAllBreakpoints().size());

		Set<LogicalBreakpoint> lbs =
			breakpointService.getBreakpointsAt(program, addr(program, 0x00400123));
		assertEquals(2, lbs.size());
		lbs.stream()
				.filter(l -> l.getKinds().contains(TraceBreakpointKind.SW_EXECUTE))
				.findAny()
				.orElseThrow();
		lbs.stream()
				.filter(l -> l.getKinds().contains(TraceBreakpointKind.READ))
				.findAny()
				.orElseThrow();
		LogicalBreakpoint lbEx = lbs.stream()
				.filter(l -> l.getKinds().contains(TraceBreakpointKind.SW_EXECUTE))
				.findAny()
				.orElseThrow();
		LogicalBreakpoint lbRw = lbs.stream()
				.filter(l -> l.getKinds().contains(TraceBreakpointKind.READ))
				.findAny()
				.orElseThrow();
		CompletableFuture<Void> disable = lbEx.disable();
		handleToggleBreakpointInvocation(target1, Unique.assertOne(lbEx.getTraceBreakpoints(trace)),
			false);
		waitOn(disable);
		waitForDomainObject(trace);
		waitOn(breakpointService.changesSettled());

		// TODO: This is more a test for the marker plugin, no?
		assertEquals(State.MIXED, lbEx.computeState().sameAdddress(lbRw.computeState()));
	}
NB. The target could still be mid transaction. If we open this transaction too soon, then
the breakpoint gets aborted as well.
Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/AbstractDebuggerLogicalBreakpointServiceTest.java