static void buildTransformation(
      ModelVersion version, ResourceTransformationDescriptionBuilder parent) {
    ResourceTransformationDescriptionBuilder builder = parent.addChildResource(PATH);

    RemoteSiteResourceDefinition.buildTransformation(version, builder);
    PropertyResourceDefinition.buildTransformation(version, builder);
  }
  private void parseRemoteSite(
      XMLExtendedStreamReader reader,
      PathAddress relayAddress,
      Map<PathAddress, ModelNode> operations)
      throws XMLStreamException {
    String site = require(reader, XMLAttribute.NAME);
    PathAddress address = relayAddress.append(RemoteSiteResourceDefinition.pathElement(site));
    ModelNode operation = Util.createAddOperation(address);
    operations.put(address, operation);

    String cluster = null;

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      XMLAttribute attribute = XMLAttribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case NAME:
          {
            // Already parsed
            break;
          }
        case STACK:
          {
            if (this.schema.since(JGroupsSchema.VERSION_3_0)) {
              throw ParseUtils.unexpectedAttribute(reader, i);
            }
            readAttribute(
                reader, i, operation, RemoteSiteResourceDefinition.DeprecatedAttribute.STACK);
            break;
          }
        case CLUSTER:
          {
            if (this.schema.since(JGroupsSchema.VERSION_3_0)) {
              throw ParseUtils.unexpectedAttribute(reader, i);
            }
            cluster = value;
            break;
          }
        case CHANNEL:
          {
            if (this.schema.since(JGroupsSchema.VERSION_3_0)) {
              readAttribute(reader, i, operation, RemoteSiteResourceDefinition.Attribute.CHANNEL);

              // We need to populate the deprecated STACK attribute so that we have enough context
              // for transforming the add operation
              PathAddress subsystemAddress =
                  PathAddress.pathAddress(JGroupsSubsystemResourceDefinition.PATH);
              PathAddress channelAddress =
                  subsystemAddress.append(ChannelResourceDefinition.pathElement(value));
              ModelNode channelOperation = operations.get(channelAddress);
              if (channelOperation != null) {
                String stack;
                if (channelOperation.hasDefined(
                    ChannelResourceDefinition.Attribute.STACK.getDefinition().getName())) {
                  stack =
                      channelOperation
                          .get(ChannelResourceDefinition.Attribute.STACK.getDefinition().getName())
                          .asString();
                } else {
                  stack =
                      operations
                          .get(subsystemAddress)
                          .get(
                              JGroupsSubsystemResourceDefinition.Attribute.DEFAULT_STACK
                                  .getDefinition()
                                  .getName())
                          .asString();
                }
                setAttribute(
                    reader,
                    stack,
                    operation,
                    RemoteSiteResourceDefinition.DeprecatedAttribute.STACK);
              }
              break;
            }
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }

    if (this.schema.since(JGroupsSchema.VERSION_3_0)) {
      if (!operation.hasDefined(
          RemoteSiteResourceDefinition.Attribute.CHANNEL.getDefinition().getName())) {
        throw ParseUtils.missingRequired(reader, EnumSet.of(XMLAttribute.CHANNEL));
      }
    } else {
      if (!operation.hasDefined(
          RemoteSiteResourceDefinition.DeprecatedAttribute.STACK.getDefinition().getName())) {
        throw ParseUtils.missingRequired(reader, EnumSet.of(XMLAttribute.STACK));
      }
      String channel = (cluster != null) ? cluster : site;
      setAttribute(reader, channel, operation, RemoteSiteResourceDefinition.Attribute.CHANNEL);

      // We need to create a corresponding channel add operation
      PathAddress subsystemAddress =
          PathAddress.pathAddress(JGroupsSubsystemResourceDefinition.PATH);
      PathAddress channelAddress =
          subsystemAddress.append(ChannelResourceDefinition.pathElement(channel));
      ModelNode channelOperation = Util.createAddOperation(channelAddress);
      String stack =
          operation
              .get(RemoteSiteResourceDefinition.DeprecatedAttribute.STACK.getDefinition().getName())
              .asString();
      setAttribute(reader, stack, channelOperation, ChannelResourceDefinition.Attribute.STACK);
      operations.put(channelAddress, channelOperation);
    }

    ParseUtils.requireNoContent(reader);
  }