/**
   * Register the transformers for transforming from 1.4.0 to 1.3.0 management api versions, in
   * which: - attributes INDEXING_PROPERTIES, SEGMENTS were added in 1.4 - attribute VIRTUAL_NODES
   * was deprecated in 1.4 - expression support was added to most attributes in 1.4, except for
   * CLUSTER, DEFAULT_CACHE and MODE for which it was already enabled in 1.3
   *
   * <p>Chaining of transformers is used in cases where two transformers are required for the same
   * operation.
   *
   * @param subsystem the subsystems registration
   */
  private static void registerTransformers(final SubsystemRegistration subsystem) {

    // define the resource and operation transformers
    final InfinispanOperationTransformer_1_3 removeSelectedCacheAttributes =
        new InfinispanOperationTransformer_1_3();

    final RejectExpressionValuesTransformer cacheContainerReject =
        new RejectExpressionValuesTransformer(
            InfinispanRejectedExpressions_1_3.REJECT_CONTAINER_ATTRIBUTES);
    final RejectExpressionValuesTransformer transportReject =
        new RejectExpressionValuesTransformer(
            InfinispanRejectedExpressions_1_3.REJECT_TRANSPORT_ATTRIBUTES);
    final RejectExpressionValuesTransformer cacheReject =
        new RejectExpressionValuesTransformer(
            InfinispanRejectedExpressions_1_3.REJECT_CACHE_ATTRIBUTES);
    final ChainedOperationTransformer chained =
        new ChainedOperationTransformer(removeSelectedCacheAttributes, cacheReject);

    // Register the model transformers
    TransformersSubRegistration registration =
        subsystem.registerModelTransformers(
            ModelVersion.create(1, 3), new InfinispanSubsystemTransformer_1_3());
    TransformersSubRegistration containerRegistration =
        registration.registerSubResource(
            CacheContainerResource.CONTAINER_PATH, (OperationTransformer) cacheContainerReject);
    containerRegistration.registerSubResource(
        TransportResource.TRANSPORT_PATH, (OperationTransformer) transportReject);

    PathElement[] cachePaths = {
      LocalCacheResource.LOCAL_CACHE_PATH,
      InvalidationCacheResource.INVALIDATION_CACHE_PATH,
      ReplicatedCacheResource.REPLICATED_CACHE_PATH,
      DistributedCacheResource.DISTRIBUTED_CACHE_PATH
    };
    for (int i = 0; i < cachePaths.length; i++) {
      // register chained operation transformers for cache ADD operations where we need to remove
      // and reject
      TransformersSubRegistration cacheRegistration =
          containerRegistration.registerSubResource(cachePaths[i], (OperationTransformer) chained);
      registerCacheChildrenTransformers(cacheRegistration);
    }
  }