public Set<Shape> compute(Model model) {
        NeighborProvider baseProvider = NeighborProviderIndex.of(model).getProvider();
        NeighborProvider providerWithIdRefRelationships = NeighborProvider.withIdRefRelationships(model, baseProvider);
        Walker shapeWalker = new Walker(providerWithIdRefRelationships);

        // Find all shapes connected to any service shape.
        Set<ShapeId> connected = new HashSet<>();

        // Stop traversing into trees that are already traversed.
        Predicate<Relationship> traversed = rel -> !connected.contains(rel.getNeighborShapeId());

        Set<Shape> rootShapes = rootShapeSelector.select(model);
        for (Shape root : rootShapes) {
            shapeWalker.iterateShapes(root, traversed).forEachRemaining(shape -> connected.add(shape.getId()));
        }

        // Don't remove shapes that are traits or connected to traits.
        for (Shape trait : model.getShapesWithTrait(TraitDefinition.class)) {
            shapeWalker.iterateShapes(trait, traversed).forEachRemaining(shape -> connected.add(shape.getId()));
        }

        // Any shape that wasn't identified as connected to a root is considered unreferenced.
        Set<Shape> result = new HashSet<>();
        for (Shape shape : model.toSet()) {
            if (!shape.isMemberShape()
                    && !connected.contains(shape.getId())
                    && !Prelude.isPreludeShape(shape)
                    && keepFilter.test(shape)) {
                result.add(shape);
            }
        }

        return result;
    }
Gets the set of shapes that are unreferenced.

@param model Model to compute from.
@return Returns the unreferenced shapes.
smithy-model/src/main/java/software/amazon/smithy/model/neighbor/UnreferencedShapes.java