protected void checkInstructionSet(long startSnap, InstructionSet instructionSet,
			Set<Address> skipDelaySlots) {
		// NOTE: Partly derived from CodeManager#checkInstructionSet()
		// Attempted to factor more fluently
		DBTraceMemoryManager mm = space.trace.getMemoryManager();
		for (InstructionBlock block : instructionSet) {
			// If block contains a known error, record its address, and do not proceed beyond it
			Address errorAddress = null;
			// See if this block has already been pruned due to errors in upstream blocks
			InstructionError conflict = block.getInstructionConflict();
			if (conflict != null) {
				errorAddress = conflict.getInstructionAddress();
				if (errorAddress == null) {
					// Assume the whole block is messed up, and skip it.
					continue;
				}
			}
			if (block.isEmpty()) {
				continue; // nothing to iterate over anyway, so skip it.
			}

			// Flow into first instruction is flow into block
			// After this, each time the protoInstr is stepped,
			// we update flow to preceding instruction address
			Address flowFromAddress = block.getFlowFromAddress();
			Instruction lastProtoInstr = null;
			Iterator<Pair<Instruction, CodeUnit>> overlapIt = startCheckingBlock(startSnap, block);
			while (overlapIt.hasNext()) {
				Pair<Instruction, CodeUnit> overlap = overlapIt.next();
				Instruction protoInstr = overlap.getLeft();
				if (errorAddress != null && protoInstr.getAddress().compareTo(errorAddress) >= 0) {
					break; // do not proceed beyond disassembly errors
				}
				if (lastProtoInstr != protoInstr) {
					flowFromAddress = protoInstr.getAddress();
					lastProtoInstr = protoInstr;
				}
				CodeUnit existsCu = overlap.getRight();
				DBTraceMemorySpace ms =
					mm.getMemorySpace(existsCu.getAddress().getAddressSpace(), false);
				if (!isKnown(ms, startSnap, existsCu) && existsCu instanceof TraceCodeUnit tcu) {
					tcu.delete();
					continue;
				}
				int cmp = existsCu.getMinAddress().compareTo(protoInstr.getMinAddress());
				boolean existsIsInstruction = (existsCu instanceof TraceInstruction);
				if (cmp == 0 && existsIsInstruction) {
					TraceInstruction existsInstr = (TraceInstruction) existsCu;
					if (protoInstr.isInDelaySlot() != existsInstr.isInDelaySlot() &&
						protoInstr.getLength() == existsInstr.getLength()) {
						if (protoInstr.isInDelaySlot()) {
							// allow the delay-slot protoInstr to overwrite the existsInstr
							existsInstr.delete();
						}
						else {
							// Likely caused by odd flow into delay slot - assume OK
							// Do not allow the non delay-slot protoInstr to overwrite!
							skipDelaySlots.add(existsInstr.getAddress());
						}
						continue;
					}
					if (!protoInstr.getPrototype().equals(existsInstr.getPrototype())) {
						InstructionError.dumpInstructionDifference(protoInstr, existsInstr);
						block.setInconsistentPrototypeConflict(existsInstr.getAddress(),
							flowFromAddress);
					}
					else {
						// Mark block as overlapping existing code
						// NOTE: This seems to include when protoInstr and existsInstr match
						block.setInstructionError(InstructionErrorType.DUPLICATE,
							protoInstr.getAddress(), existsInstr.getAddress(), flowFromAddress,
							null);
					}
					break; // next block (skip remainder of this one)
				}
				// NOTE: existsIsInstruction implies cmp != 0, so record as off-cut conflict
				block.setCodeUnitConflict(existsCu.getAddress(), protoInstr.getAddress(),
					flowFromAddress, existsIsInstruction, true);
			}
		}
	}
Checks the intended locations for conflicts with existing units.

<p>
This also clears locations where delay slots will be replacing non-delay slots.
{@code skipDelaySlots} will be populated with any existing delay slot locations which should
not be overwritten

@param instructionSet the instruction set to examine
@param skipDelaySlots an empty mutable set to be populated
Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceInstructionsView.java