static void buildTransformation(
      ModelVersion version, ResourceTransformationDescriptionBuilder builder) {

    if (InfinispanModel.VERSION_4_0_0.requiresTransformation(version)) {
      // Converts pool name to its JNDI name
      Converter converter =
          new Converter() {
            @Override
            public void convert(
                PathAddress address,
                String name,
                ModelNode value,
                ModelNode model,
                TransformationContext context) {
              if (value.isDefined()) {
                PathAddress rootAddress = address.subAddress(0, address.size() - 4);
                PathAddress subsystemAddress =
                    rootAddress.append(
                        PathElement.pathElement(
                            ModelDescriptionConstants.SUBSYSTEM, "datasources"));
                Resource subsystem = context.readResourceFromRoot(subsystemAddress);
                String poolName = value.asString();
                for (String type : Arrays.asList("data-source", "xa-data-source")) {
                  if (subsystem.hasChildren(type)) {
                    for (Resource.ResourceEntry entry : subsystem.getChildren(type)) {
                      if (entry.getName().equals(poolName)) {
                        value.set(entry.getModel().get("jndi-name"));
                        return;
                      }
                    }
                  }
                }
              }
            }
          };
      builder
          .getAttributeBuilder()
          .addRename(Attribute.DATA_SOURCE.getName(), DeprecatedAttribute.DATASOURCE.getName())
          .setValueConverter(
              new SimpleAttributeConverter(converter), Attribute.DATA_SOURCE.getDefinition());
    }

    if (InfinispanModel.VERSION_3_0_0.requiresTransformation(version)) {
      builder
          .addOperationTransformationOverride(ModelDescriptionConstants.ADD)
          .setCustomOperationTransformer(
              new SimpleOperationTransformer(new LegacyPropertyAddOperationTransformer()))
          .inheritResourceAttributeDefinitions();
    }

    if (InfinispanModel.VERSION_2_0_0.requiresTransformation(version)) {
      builder
          .getAttributeBuilder()
          .setDiscard(DiscardAttributeChecker.UNDEFINED, Attribute.DIALECT.getDefinition())
          .addRejectCheck(RejectAttributeChecker.DEFINED, Attribute.DIALECT.getDefinition())
          .end();
    }

    StoreResourceDefinition.buildTransformation(version, builder);
  }
  static void buildTransformation(
      ModelVersion version, ResourceTransformationDescriptionBuilder builder) {

    StateTransferResourceDefinition.buildTransformation(version, builder);

    if (InfinispanModel.VERSION_4_0_0.requiresTransformation(version)) {
      builder.addChildResource(
          PartitionHandlingResourceDefinition.PATH, new RequiredChildResourceDiscardPolicy());
    } else {
      PartitionHandlingResourceDefinition.buildTransformation(version, builder);
    }

    if (InfinispanModel.VERSION_2_0_0.requiresTransformation(version)) {
      final ResourceTransformationDescriptionBuilder backupsBuilder =
          builder.addChildResource(
              BackupsResourceDefinition.PATH, new RequiredChildResourceDiscardPolicy());
      backupsBuilder.rejectChildResource(BackupResourceDefinition.WILDCARD_PATH);

      builder.addChildResource(
          BackupForResourceDefinition.PATH, new RequiredChildResourceDiscardPolicy());
    } else {
      BackupsResourceDefinition.buildTransformation(version, builder);
      BackupForResourceDefinition.buildTransformation(version, builder);
    }

    ClusteredCacheResourceDefinition.buildTransformation(version, builder);
  }
  private static FailedOperationTransformationConfig createFailedOperationConfig(
      ModelVersion version) {

    FailedOperationTransformationConfig config = new FailedOperationTransformationConfig();
    PathAddress subsystemAddress =
        PathAddress.pathAddress(InfinispanSubsystemResourceDefinition.PATH);
    PathAddress containerAddress =
        subsystemAddress.append(CacheContainerResourceDefinition.WILDCARD_PATH);

    if (InfinispanModel.VERSION_2_0_0.requiresTransformation(version)) {
      for (PathElement path :
          Arrays.asList(
              DistributedCacheResourceDefinition.WILDCARD_PATH,
              ReplicatedCacheResourceDefinition.WILDCARD_PATH)) {
        PathAddress cacheAddress = containerAddress.append(path);
        config.addFailedAttribute(
            cacheAddress
                .append(BackupsResourceDefinition.PATH)
                .append(BackupResourceDefinition.WILDCARD_PATH),
            FailedOperationTransformationConfig.REJECTED_RESOURCE);
        config.addFailedAttribute(
            cacheAddress.append(BackupForResourceDefinition.PATH),
            FailedOperationTransformationConfig.REJECTED_RESOURCE);
      }
    }

    if (InfinispanModel.VERSION_1_5_0.requiresTransformation(version)) {
      config.addFailedAttribute(
          containerAddress,
          new ChangeToTrueConfig(
              CacheContainerResourceDefinition.Attribute.STATISTICS_ENABLED.getName()));
      config.addFailedAttribute(
          containerAddress.append(LocalCacheResourceDefinition.WILDCARD_PATH),
          new ChangeToTrueConfig(CacheResourceDefinition.Attribute.STATISTICS_ENABLED.getName()));
      config.addFailedAttribute(
          containerAddress.append(DistributedCacheResourceDefinition.WILDCARD_PATH),
          new ChangeToTrueConfig(CacheResourceDefinition.Attribute.STATISTICS_ENABLED.getName()));
      config.addFailedAttribute(
          containerAddress.append(ReplicatedCacheResourceDefinition.WILDCARD_PATH),
          new ChangeToTrueConfig(CacheResourceDefinition.Attribute.STATISTICS_ENABLED.getName()));
      config.addFailedAttribute(
          containerAddress.append(InvalidationCacheResourceDefinition.WILDCARD_PATH),
          new ChangeToTrueConfig(CacheResourceDefinition.Attribute.STATISTICS_ENABLED.getName()));
    }

    return config;
  }