@Test
public void updatesShapeNamesAndReferences() {

    Model model = Model.assembler()
            .addImport(IntegTest.class.getResource("rename-shape-test-model.json"))
            .assemble()
            .unwrap();
    Map<ShapeId, ShapeId> renamed = new HashMap<>();
    // Service
    ShapeId fromService = ShapeId.from("ns.foo#MyService");
    ShapeId toService = ShapeId.from("ns.bar#MyNewService");
    renamed.put(fromService, toService);
    // Operation
    ShapeId fromOperation = ShapeId.from("ns.foo#MyOperation");
    ShapeId toOperation = ShapeId.from("ns.baz#MyNewOperation");
    renamed.put(fromOperation, toOperation);
    ShapeId fromOtherOperation = ShapeId.from("ns.foo#MyOtherOperation");
    ShapeId toOtherOperation = ShapeId.from("ns.fred#MyOtherNewOperation");
    renamed.put(fromOtherOperation, toOtherOperation);
    // Resource
    ShapeId fromResource = ShapeId.from("ns.foo#MyResource");
    ShapeId toResource = ShapeId.from("ns.qux#MyNewResource");
    renamed.put(fromResource, toResource);
    // Structure
    ShapeId fromStructure = ShapeId.from("ns.foo#MyStructure");
    ShapeId toStructure = ShapeId.from("ns.quux#MyNewStructure");
    renamed.put(fromStructure, toStructure);
    // List
    ShapeId fromList = ShapeId.from("ns.foo#MyList");
    ShapeId toList = ShapeId.from("ns.quuz#MyNewList");
    renamed.put(fromList, toList);
    // Map
    ShapeId fromMap = ShapeId.from("ns.foo#MyMap");
    ShapeId toMap = ShapeId.from("ns.corge#MyNewMap");
    renamed.put(fromMap, toMap);
    // Set
    ShapeId fromSet = ShapeId.from("ns.foo#MySet");
    ShapeId toSet = ShapeId.from("ns.grault#MyNewSet");
    renamed.put(fromSet, toSet);
    // Union
    ShapeId fromUnion = ShapeId.from("ns.foo#MyUnion");
    ShapeId toUnion = ShapeId.from("ns.garply#MyNewUnion");
    renamed.put(fromUnion, toUnion);
    // ID
    ShapeId fromId = ShapeId.from("ns.foo#MyId");
    ShapeId toId = ShapeId.from("ns.waldo#MyNewId");
    renamed.put(fromId, toId);
    ModelTransformer transformer = ModelTransformer.create();
    Model result = transformer.renameShapes(model, renamed);
    // All new names are present.
    assertTrue(result.getShape(toService).isPresent());
    assertTrue(result.getShape(toOperation).isPresent());
    assertTrue(result.getShape(toResource).isPresent());
    assertTrue(result.getShape(toStructure).isPresent());
    assertTrue(result.getShape(toList).isPresent());
    assertTrue(result.getShape(toMap).isPresent());
    assertTrue(result.getShape(toSet).isPresent());
    assertTrue(result.getShape(toUnion).isPresent());
    assertTrue(result.getShape(toId).isPresent());
    // All new shapes are updated as references.
    ServiceShape service = result.getShape(toService).get().asServiceShape().get();
    assertTrue(service.getOperations().contains(toOperation));
    assertTrue(service.getResources().contains(toResource));
    ResourceShape resource = result.getShape(toResource).get().asResourceShape().get();
    assertEquals(resource.getIdentifiers().get("myId"), toId);
    assertTrue(resource.getAllOperations().contains(toOtherOperation));
    StructureShape operationInput = result.getShape(ShapeId.from("ns.foo#MyOperationInput")).get()
            .asStructureShape().get();
    MemberShape struct = operationInput.getMember("struct").get();
    MemberShape list = operationInput.getMember("list").get();
    MemberShape map = operationInput.getMember("map").get();
    MemberShape set = operationInput.getMember("set").get();
    MemberShape union = operationInput.getMember("union").get();
    assertEquals(struct.getTarget(), toStructure);
    assertEquals(list.getTarget(), toList);
    assertEquals(map.getTarget(), toMap);
    assertEquals(set.getTarget(), toSet);
    assertEquals(union.getTarget(), toUnion);
    // All old names have been removed.
    assertFalse(result.getShape(fromService).isPresent());
    assertFalse(result.getShape(fromOperation).isPresent());
    assertFalse(result.getShape(fromResource).isPresent());
    assertFalse(result.getShape(fromStructure).isPresent());
    assertFalse(result.getShape(fromList).isPresent());
    assertFalse(result.getShape(fromMap).isPresent());
    assertFalse(result.getShape(fromSet).isPresent());
    assertFalse(result.getShape(fromUnion).isPresent());
    assertFalse(result.getShape(fromId).isPresent());
}