protected void checkNodeIntegrity(NR n) {
		// Check parent has exactly the minimum bounds of its children
		NS expectedBounds = unionStream(getChildrenOf(n).stream().map(DBTreeRecord::getBounds));
		if (expectedBounds == null && n != root) {
			throw new AssertionError("Non-root node cannot be empty");
		}
		if (expectedBounds != null && !expectedBounds.equals(n.getBounds())) {
			throw new AssertionError("Parent bounds do not match expected");
		}

		// Check parent type wrt. child types
		switch (n.getType()) {
			case DIRECTORY: {
				Collection<DR> dataChildren = getDataChildrenOf(n.getKey());
				// NOTE: isEmpty() uses size(), which uses getChildCount
				// Has no regard for which table. Use iterator instead.
				if (dataChildren.iterator().hasNext()) {
					throw new AssertionError(
						"Directory node " + n + " cannot contain data " + dataChildren);
				}
				Collection<NR> nodeChildren = getNodeChildrenOf(n);
				if (!nodeChildren.iterator().hasNext()) {
					throw new AssertionError("Directory node " + n + " cannot be empty");
				}
				NodeType childType = nodeChildren.iterator().next().getType();
				if (childType == NodeType.LEAF) {
					throw new AssertionError(
						"Only leaf-parent directory node can have leaf children: n=" + n +
							",children=" + nodeChildren);
				}
				for (NR nr : nodeChildren) {
					if (nr.getType() != childType) {
						throw new AssertionError(
							"All sibling must have the same type: " + nodeChildren);
					}
				}
				break;
			}
			case LEAF_PARENT: {
				Collection<DR> dataChildren = getDataChildrenOf(n);
				if (dataChildren.iterator().hasNext()) {
					throw new AssertionError(
						"Directory node " + n + " cannot contain data " + dataChildren);
				}
				Collection<NR> nodeChildren = getNodeChildrenOf(n);
				if (!nodeChildren.iterator().hasNext()) {
					throw new AssertionError("Leaf-parent " + n + " cannot be empty");
				}
				for (NR nr : nodeChildren) {
					if (nr.getType() != NodeType.LEAF) {
						throw new AssertionError("Leaf-parent node " + n +
							" must have all leaf children: " + nodeChildren);
					}
				}
				break;
			}
			case LEAF:
				Collection<NR> nodeChildren = getNodeChildrenOf(n);
				if (nodeChildren.iterator().hasNext()) {
					throw new AssertionError(
						"Leaf node " + n + " cannot contain nodes " + nodeChildren);
				}
				break;
		}

		// Check that child count matches by counting over iterator
		long actualChildCount = 0;
		for (@SuppressWarnings("unused")
		Object obj : getChildrenOf(n)) {
			actualChildCount++;
		}
		if (actualChildCount != n.getChildCount()) {
			throw new AssertionError("Parent's child count " + n.getChildCount() +
				" does not match actual count " + actualChildCount);
		}

		// Check that data count matches by summing over iterator
		long actualDataCount = 0;
		for (DBTreeRecord<?, ?> r : getChildrenOf(n)) {
			actualDataCount += r.getDataCount();
		}
		if (actualDataCount != n.getDataCount()) {
			throw new AssertionError("Parent's data count " + n.getDataCount() +
				" does not match actual sum " + actualDataCount);
		}
	}
Check the integrity of a single node entry.

This method is for tree developers and testers. Override this method if you have additional
integrity checks.

@param n the entry to check
Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/database/spatial/AbstractConstraintsTree.java