static NeighborProvider reverse(Model model, NeighborProvider forwardProvider) {
        // Note: this method previously needed lots of intermediate representations
        // stored in memory to create a Map<ShapeId, List<RelationShip>> that contains
        // only unique relationships. It was done using Stream, distinct, and groupingBy.
        // However, when trying to load ridiculously large models, that approach consumes
        // tons of heap. This approach allocates as little as possible (I think), but
        // does require creating an ArrayList copy of a Set each time neighbors are returned.
        Map<ShapeId, Set<Relationship>> targetedFrom = new HashMap<>();

        for (Shape shape : model.toSet()) {
            for (Relationship rel : forwardProvider.getNeighbors(shape)) {
                targetedFrom.computeIfAbsent(rel.getNeighborShapeId(), id -> new HashSet<>()).add(rel);
            }
        }

        return shape -> {
            Set<Relationship> shapes = targetedFrom.get(shape.getId());
            return shapes == null ? Collections.emptyList() : ListUtils.copyOf(shapes);
        };
    }
Returns a NeighborProvider that returns relationships that point at a
given shape rather than relationships that the given shape points at.

@param model Model to build reverse relationships from.
@param forwardProvider The forward directed neighbor provider to grab relationships from.
@return Returns the reverse neighbor provider.
smithy-model/src/main/java/software/amazon/smithy/model/neighbor/NeighborProvider.java