default KeyPath searchForCanonicalContainer(Class<? extends TraceObjectInterface> type) {
		if (type == TraceObjectInterface.class) {
			throw new IllegalArgumentException("Must provide a specific interface");
		}
		SchemaContext ctx = getContext();
		Set<TraceObjectSchema> visited = new HashSet<>();
		Set<TraceObjectSchema> visitedAsElement = new HashSet<>();
		Set<Private.CanonicalSearchEntry> allOnLevel = new HashSet<>();
		allOnLevel.add(new Private.CanonicalSearchEntry(KeyPath.ROOT, false, this));
		while (!allOnLevel.isEmpty()) {
			KeyPath found = null;
			for (Private.CanonicalSearchEntry ent : allOnLevel) {
				if (ent.schema.getInterfaces().contains(type) && ent.parentIsCanonical) {
					// Check for final being index is in parentIsCanonical.
					if (found != null) {
						return null; // Non-unique answer
					}
					found = ent.path.parent();
				}
			}
			if (found != null) {
				return found; // Unique shortest answer
			}

			Set<Private.CanonicalSearchEntry> nextLevel = new HashSet<>();
			for (Private.CanonicalSearchEntry ent : allOnLevel) {
				if (PathPattern.isWildcard(ent.path.key())) {
					continue;
				}
				for (Map.Entry<String, AttributeSchema> attrEnt : ent.schema.getAttributeSchemas()
						.entrySet()) {
					TraceObjectSchema attrSchema = ctx.getSchema(attrEnt.getValue().getSchema());
					if ((TraceObjectInterface.class.isAssignableFrom(attrSchema.getType()) ||
						TraceObject.class.isAssignableFrom(attrSchema.getType())) &&
						visited.add(attrSchema)) {
						nextLevel.add(new Private.CanonicalSearchEntry(
							ent.path.key(attrEnt.getKey()),
							// If child is not element, this is not its canonical container
							false, attrSchema));
					}
				}
				for (Map.Entry<String, SchemaName> elemEnt : ent.schema.getElementSchemas()
						.entrySet()) {
					TraceObjectSchema elemSchema = ctx.getSchema(elemEnt.getValue());
					visited.add(elemSchema); // Add but do not condition
					if (visitedAsElement.add(elemSchema)) {
						nextLevel.add(new Private.CanonicalSearchEntry(
							ent.path.index(elemEnt.getKey()),
							ent.schema.isCanonicalContainer(), elemSchema));
					}
				}
				TraceObjectSchema deSchema = ctx.getSchema(ent.schema.getDefaultElementSchema());
				visited.add(deSchema);
				if (visitedAsElement.add(deSchema)) {
					nextLevel.add(new Private.CanonicalSearchEntry(ent.path.index(""),
						ent.schema.isCanonicalContainer(), deSchema));
				}
			}
			allOnLevel = nextLevel;
		}
		// We exhausted the reachable schemas
		return null;
	}
Find the (sub) path to the canonical container for objects implementing a given interface

<p>
If more than one container is found having the shortest path, then {@code null} is returned.

@param type the sub-type of {@link TraceObjectInterface} to search for
@return the single path to that container
Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/target/schema/TraceObjectSchema.java