public Set<Shape> compute(Model model) {
        Walker walker = new Walker(NeighborProviderIndex.of(model).getProvider());

        // Begin with a mutable set of all trait definitions contained in the model
        Set<Shape> unused = model.getShapesWithTrait(TraitDefinition.class)
                .stream()
                // Exclude prelude traits -- these are defined by Smithy, not by the model itself
                .filter(FunctionalUtils.not(Prelude::isPreludeShape))
                .collect(Collectors.toSet());

        // Find all traits used directly or indirectly by a service shape and remove
        // their definitions from the unused set.
        model.shapes(ServiceShape.class)
                .flatMap(service -> walker.walkShapes(service).stream())
                .distinct()
                .map(Shape::getAllTraits)
                .flatMap(traits -> traits.keySet().stream())
                .distinct()
                .flatMap(traitId -> getTraitShapes(model, traitId).stream())
                .filter(keepFilter)
                .forEach(unused::remove);

        return unused;
    }
@param keepFilter Predicate that if matched keeps a trait definition from being unreferenced.
smithy-model/src/main/java/software/amazon/smithy/model/neighbor/UnreferencedTraitDefinitions.java