private Shape mapTraits(Shape shape) {
        Collection<Trait> traits = new ArrayList<>();
        boolean changed = false;

        // Map over the traits and see if any of them changed. If none
        // changed, then there is no need to create a new copy of the shape.
        for (Trait trait : shape.getAllTraits().values()) {
            Trait mapped = Objects.requireNonNull(mapper.apply(shape, trait), "Trait mapper must not return null");
            traits.add(mapped);
            if (!mapped.equals(trait)) {
                changed = true;
            }
        }

        if (!changed) {
            return shape;
        }

        return Shape.shapeToBuilder(shape).clearTraits().addTraits(traits).build();
    }
Maps over traits in a model using a mapping function.

<p>Shapes are only transformed and replaced in the model if one
of its traits are modified.

@see ModelTransformer#mapTraits
smithy-model/src/main/java/software/amazon/smithy/model/transform/MapTraits.java