protected void assertServiceAgreesWithOpenProgramsAndTraces() {
		Map<Trace, Set<LogicalBreakpoint>> breaksByTraceViaPer = new HashMap<>();
		for (Trace trace : traceManager.getOpenTraces()) {
			Set<LogicalBreakpoint> breaks = new HashSet<>();
			for (Entry<Address, Set<LogicalBreakpoint>> ent : breakpointService
					.getBreakpoints(trace)
					.entrySet()) {
				for (LogicalBreakpoint lb : ent.getValue()) {
					Address traceAddress = lb.getTraceAddress(trace);
					assertEquals(ent.getKey(), traceAddress);
					assertTrue(breaks.add(lb)); // All are unique within a trace
				}
			}
			if (!breaks.isEmpty()) {
				assertNull(breaksByTraceViaPer.put(trace, breaks));
			}
		}

		Map<Program, Set<LogicalBreakpoint>> breaksByProgramViaPer = new HashMap<>();
		for (Program prog : programManager.getAllOpenPrograms()) {
			Set<LogicalBreakpoint> breaks = new HashSet<>();
			for (Entry<Address, Set<LogicalBreakpoint>> ent : breakpointService.getBreakpoints(prog)
					.entrySet()) {
				for (LogicalBreakpoint lb : ent.getValue()) {
					ProgramLocation loc = lb.getProgramLocation();
					assertEquals(prog, loc.getProgram());
					assertEquals(ent.getKey(), loc.getAddress());
					assertTrue(breaks.add(lb)); // All are unique within a program
				}
			}
			if (!breaks.isEmpty()) {
				assertNull(breaksByProgramViaPer.put(prog, breaks));
			}
		}

		Map<Trace, Set<LogicalBreakpoint>> breaksByTraceViaAll = new HashMap<>();
		Map<Program, Set<LogicalBreakpoint>> breaksByProgramViaAll = new HashMap<>();
		for (LogicalBreakpoint lb : breakpointService.getAllBreakpoints()) {
			ProgramLocation loc = lb.getProgramLocation();
			if (loc != null) {
				Set<LogicalBreakpoint> breaks =
					breaksByProgramViaAll.computeIfAbsent(loc.getProgram(), __ -> new HashSet<>());
				assertTrue(breaks.add(lb));
			}
			for (Trace t : lb.getMappedTraces()) {
				Set<LogicalBreakpoint> breaks =
					breaksByTraceViaAll.computeIfAbsent(t, __ -> new HashSet<>());
				assertTrue(breaks.add(lb));
			}
		}

		assertEquals(breaksByProgramViaPer, breaksByProgramViaAll);
		assertEquals(breaksByTraceViaPer, breaksByTraceViaAll);
	}
Tracks the current set of logical breakpoints.

<p>
Its assertions require perfection in the sequence of events: 1) No double-adds. 2) No
double-removes. 3) No extraneous updates. At the end of each test, the current set of
breakpoints in this listener should be verified against those reported by the service.
Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/AbstractDebuggerLogicalBreakpointServiceTest.java