Model transform(ModelTransformer transformer, Model model) {
        Collection<Shape> shouldReplace = determineShapesToReplace(model);
        if (shouldReplace.isEmpty()) {
            return model;
        }

        assertShapeTypeChangesSound(model, shouldReplace);
        Model.Builder builder = createReplacedModelBuilder(model, shouldReplace);

        // Update shapes that relied on mixins that were updated.
        updateMixins(model, builder, shouldReplace);

        // If a member shape changes, then ensure that the containing shape
        // is also updated to reference the updated member. Note that the updated container
        // shapes will be a modified version of shapes present in the shouldReplace Set
        // over shapes in the provided model.
        builder.addShapes(getUpdatedContainers(model, shouldReplace));

        // Builds the model, then returns a model that removes any shapes that
        // need to be removed after mapping over the shapes.
        return transformer.removeShapes(builder.build(), getRemovedMembers(model, shouldReplace));
    }
Replaces shapes while ensuring that the transformed model is in a
consistent state.

<p>This transformer accounts for the following scenarios:

<ul>
    <li>When a member is modified, ensures that its containing shape
    references the new member.</li>
    <li>When an aggregate shape is modified, ensures that all members are
    updated in the model.</li>
    <li>When a member is removed from a structure or union,
    ensures that the member is removed from the model.</li>
    <li>When a mixin is updated, ensures that all shapes that use the
    mixin are updated.</li>
</ul>

<p>Only shapes that are not currently in a model or shapes that are
different than the existing shape in a model are inserted into a
transformed model.

<p>When updates are made both to a container shape and to a member owned
by the container shape, the member updates takes precedent over any
updated made to the old member referenced by the container (e.g., if you
update a structure and change one of the members of the structure without
also updating the member in the model *and* you update a member in
the model, the member in the model will overwrite the member referenced
by the structure).

<p>This transformer only supports replacing shapes if the previous shape
and new shape are of the same type. Any replacements encountered that
attempt to change the type of a shape will throw an exception.
smithy-model/src/main/java/software/amazon/smithy/model/transform/ReplaceShapes.java