private void parseIndexing(XMLExtendedStreamReader reader, ModelNode node)
      throws XMLStreamException {
    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      if (attribute == Attribute.INDEX) {
        CacheResource.INDEXING.parseAndSetParameter(value, node, reader);
      } else {
        throw ParseUtils.unexpectedAttribute(reader, i);
      }
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case PROPERTY:
          {
            int attributes = reader.getAttributeCount();
            String property = null;
            for (int i = 0; i < attributes; i++) {
              String value = reader.getAttributeValue(i);
              Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
              switch (attribute) {
                case NAME:
                  {
                    property = value;
                    break;
                  }
                default:
                  {
                    throw ParseUtils.unexpectedAttribute(reader, i);
                  }
              }
            }
            if (property == null) {
              throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.NAME));
            }
            String value = reader.getElementText();
            CacheResource.INDEXING_PROPERTIES.parseAndAddParameterElement(
                property, value, node, reader);
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedElement(reader);
          }
      }
    }
    // ParseUtils.requireNoContent(reader);
  }
  private void parseCustomStore(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {
    // ModelNode for the store add operation
    ModelNode storeAddress = cache.get(ModelDescriptionConstants.OP_ADDR).clone();
    storeAddress.add(ModelKeys.STORE, ModelKeys.STORE_NAME);
    storeAddress.protect();
    ModelNode store = Util.getEmptyOperation(ModelDescriptionConstants.ADD, storeAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case CLASS:
          {
            CommonAttributes.CLASS.parseAndSetParameter(value, store, reader);
            break;
          }
        default:
          {
            this.parseStoreAttribute(reader, i, attribute, value, store);
          }
      }
    }

    if (!store.hasDefined(ModelKeys.CLASS)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.CLASS));
    }

    this.parseStoreProperties(reader, store);
    operations.add(store);
  }
  private void parseCustomStore(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {

    PathAddress storeAddress =
        PathAddress.pathAddress(cache.get(OP_ADDR)).append(ModelKeys.STORE, ModelKeys.STORE_NAME);
    ModelNode store = Util.createAddOperation(storeAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case CLASS:
          {
            StoreResource.CLASS.parseAndSetParameter(value, store, reader);
            break;
          }
        default:
          {
            this.parseStoreAttribute(reader, i, attribute, value, store);
          }
      }
    }

    if (!store.hasDefined(ModelKeys.CLASS)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.CLASS));
    }

    List<ModelNode> additionalConfigurationOperations = new ArrayList<ModelNode>();
    this.parseStoreElements(reader, store, additionalConfigurationOperations);
    operations.add(store);
    operations.addAll(additionalConfigurationOperations);
  }
  private void parseRehashing(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {

    // ModelNode for the rehashing add operation
    ModelNode rehashingAddress = cache.get(ModelDescriptionConstants.OP_ADDR).clone();
    rehashingAddress.add(ModelKeys.STATE_TRANSFER, ModelKeys.STATE_TRANSFER_NAME);
    rehashingAddress.protect();
    ModelNode rehashing = Util.getEmptyOperation(ModelDescriptionConstants.ADD, rehashingAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case ENABLED:
          {
            CommonAttributes.ENABLED.parseAndSetParameter(value, rehashing, reader);
            break;
          }
        case TIMEOUT:
          {
            CommonAttributes.TIMEOUT.parseAndSetParameter(value, rehashing, reader);
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }
    ParseUtils.requireNoContent(reader);
    operations.add(rehashing);
  }
 private void parseStateTransfer(XMLExtendedStreamReader reader, ModelNode stateTransfer)
     throws XMLStreamException {
   for (int i = 0; i < reader.getAttributeCount(); i++) {
     String value = reader.getAttributeValue(i);
     Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
     switch (attribute) {
       case ENABLED:
         {
           stateTransfer.get(ModelKeys.ENABLED).set(Boolean.parseBoolean(value));
           break;
         }
       case TIMEOUT:
         {
           stateTransfer.get(ModelKeys.TIMEOUT).set(Long.parseLong(value));
           break;
         }
       case FLUSH_TIMEOUT:
         {
           stateTransfer.get(ModelKeys.FLUSH_TIMEOUT).set(Long.parseLong(value));
           break;
         }
       default:
         {
           throw ParseUtils.unexpectedAttribute(reader, i);
         }
     }
   }
   ParseUtils.requireNoContent(reader);
 }
  private void parseLocalCache(
      XMLExtendedStreamReader reader, ModelNode containerAddress, List<ModelNode> operations)
      throws XMLStreamException {

    // ModelNode for the cache add operation
    ModelNode cache = Util.getEmptyOperation(ModelDescriptionConstants.ADD, null);
    List<ModelNode> additionalConfigurationOperations = new ArrayList<ModelNode>();

    // set the cache mode to local
    // cache.get(ModelKeys.MODE).set(Configuration.CacheMode.LOCAL.name());

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      this.parseCacheAttribute(reader, i, attribute, value, cache);
    }

    if (!cache.hasDefined(ModelKeys.NAME)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.NAME));
    }

    // update the cache address with the cache name
    addCacheNameToAddress(cache, containerAddress, ModelKeys.LOCAL_CACHE);

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      this.parseCacheElement(reader, element, cache, additionalConfigurationOperations);
    }

    operations.add(cache);
    // add operations to create configuration resources
    for (ModelNode additionalOperation : additionalConfigurationOperations) {
      operations.add(additionalOperation);
    }
  }
 private void parseEviction(XMLExtendedStreamReader reader, ModelNode eviction)
     throws XMLStreamException {
   for (int i = 0; i < reader.getAttributeCount(); i++) {
     String value = reader.getAttributeValue(i);
     Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
     switch (attribute) {
       case STRATEGY:
         {
           try {
             EvictionStrategy strategy = EvictionStrategy.valueOf(value);
             eviction.get(ModelKeys.STRATEGY).set(strategy.name());
           } catch (IllegalArgumentException e) {
             throw ParseUtils.invalidAttributeValue(reader, i);
           }
           break;
         }
       case MAX_ENTRIES:
         {
           eviction.get(ModelKeys.MAX_ENTRIES).set(Integer.parseInt(value));
           break;
         }
       case INTERVAL:
         {
           ROOT_LOGGER.deprecatedAttribute(
               attribute.getLocalName(), Element.EVICTION.getLocalName(), "ISPN-1268");
           break;
         }
       default:
         {
           throw ParseUtils.unexpectedAttribute(reader, i);
         }
     }
   }
   ParseUtils.requireNoContent(reader);
 }
  private void parseReplicatedCache(XMLExtendedStreamReader reader, ModelNode cache)
      throws XMLStreamException {
    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      this.parseClusteredCacheAttribute(
          reader, i, attribute, value, cache, Configuration.CacheMode.REPL_SYNC);
    }

    if (!cache.hasDefined(ModelKeys.NAME)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.NAME));
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case STATE_TRANSFER:
          {
            this.parseStateTransfer(reader, cache.get(ModelKeys.STATE_TRANSFER).setEmptyObject());
            break;
          }
        default:
          {
            this.parseCacheElement(reader, element, cache);
          }
      }
    }
  }
 private void parseExpiration(XMLExtendedStreamReader reader, ModelNode expiration)
     throws XMLStreamException {
   for (int i = 0; i < reader.getAttributeCount(); i++) {
     String value = reader.getAttributeValue(i);
     Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
     switch (attribute) {
       case MAX_IDLE:
         {
           expiration.get(ModelKeys.MAX_IDLE).set(Long.parseLong(value));
           break;
         }
       case LIFESPAN:
         {
           expiration.get(ModelKeys.LIFESPAN).set(Long.parseLong(value));
           break;
         }
       case INTERVAL:
         {
           expiration.get(ModelKeys.INTERVAL).set(Long.parseLong(value));
           break;
         }
       default:
         {
           throw ParseUtils.unexpectedAttribute(reader, i);
         }
     }
   }
   ParseUtils.requireNoContent(reader);
 }
  private void parseFileStore(XMLExtendedStreamReader reader, ModelNode store)
      throws XMLStreamException {
    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case RELATIVE_TO:
          {
            store.get(ModelKeys.RELATIVE_TO).set(value);
            break;
          }
        case PATH:
          {
            store.get(ModelKeys.PATH).set(value);
            break;
          }
        default:
          {
            this.parseStoreAttribute(reader, i, attribute, value, store);
          }
      }
    }

    this.parseStoreProperties(reader, store);
  }
  private void parseFileStore(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {
    // ModelNode for the store add operation
    ModelNode storeAddress = cache.get(ModelDescriptionConstants.OP_ADDR).clone();
    storeAddress.add(ModelKeys.FILE_STORE, ModelKeys.FILE_STORE_NAME);
    storeAddress.protect();
    ModelNode store = Util.getEmptyOperation(ModelDescriptionConstants.ADD, storeAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case RELATIVE_TO:
          {
            CommonAttributes.RELATIVE_TO.parseAndSetParameter(value, store, reader);
            break;
          }
        case PATH:
          {
            CommonAttributes.PATH.parseAndSetParameter(value, store, reader);
            break;
          }
        default:
          {
            this.parseStoreAttribute(reader, i, attribute, value, store);
          }
      }
    }

    this.parseStoreProperties(reader, store);
    operations.add(store);
  }
  private void parseEviction(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {

    PathAddress evictionAddress =
        PathAddress.pathAddress(cache.get(OP_ADDR))
            .append(ModelKeys.EVICTION, ModelKeys.EVICTION_NAME);
    ModelNode eviction = Util.createAddOperation(evictionAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case STRATEGY:
          {
            EvictionResource.EVICTION_STRATEGY.parseAndSetParameter(value, eviction, reader);
            break;
          }
        case MAX_ENTRIES:
          {
            EvictionResource.MAX_ENTRIES.parseAndSetParameter(value, eviction, reader);
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }
    ParseUtils.requireNoContent(reader);
    operations.add(eviction);
  }
  /**
   * {@inheritDoc}
   *
   * @see
   *     org.jboss.staxmapper.XMLElementReader#readElement(org.jboss.staxmapper.XMLExtendedStreamReader,
   *     java.lang.Object)
   */
  @Override
  public void readElement(XMLExtendedStreamReader reader, List<ModelNode> operations)
      throws XMLStreamException {

    ModelNode subsystemAddress = new ModelNode();
    subsystemAddress.add(ModelDescriptionConstants.SUBSYSTEM, InfinispanExtension.SUBSYSTEM_NAME);
    subsystemAddress.protect();

    ModelNode subsystem = Util.getEmptyOperation(ModelDescriptionConstants.ADD, subsystemAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      ParseUtils.requireNoNamespaceAttribute(reader, i);
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case DEFAULT_CACHE_CONTAINER:
          {
            subsystem.get(ModelKeys.DEFAULT_CACHE_CONTAINER).set(value);
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }

    if (!subsystem.hasDefined(ModelKeys.DEFAULT_CACHE_CONTAINER)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.DEFAULT_CACHE_CONTAINER));
    }

    // command to add the subsystem
    operations.add(subsystem);

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      switch (Namespace.forUri(reader.getNamespaceURI())) {
        case INFINISPAN_1_0:
        case INFINISPAN_1_1:
          {
            Element element = Element.forName(reader.getLocalName());
            switch (element) {
              case CACHE_CONTAINER:
                {
                  parseContainer(reader, subsystemAddress, operations);
                  break;
                }
              default:
                {
                  throw ParseUtils.unexpectedElement(reader);
                }
            }
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedElement(reader);
          }
      }
    }
  }
  private void parseFileStore(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {

    PathAddress storeAddress =
        PathAddress.pathAddress(cache.get(OP_ADDR))
            .append(ModelKeys.FILE_STORE, ModelKeys.FILE_STORE_NAME);
    ModelNode store = Util.createAddOperation(storeAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case RELATIVE_TO:
          {
            FileStoreResource.RELATIVE_TO.parseAndSetParameter(value, store, reader);
            break;
          }
        case PATH:
          {
            FileStoreResource.PATH.parseAndSetParameter(value, store, reader);
            break;
          }
        default:
          {
            this.parseStoreAttribute(reader, i, attribute, value, store);
          }
      }
    }

    List<ModelNode> additionalConfigurationOperations = new ArrayList<ModelNode>();
    this.parseStoreElements(reader, store, additionalConfigurationOperations);
    operations.add(store);
    operations.addAll(additionalConfigurationOperations);
  }
  private void parseStoreProperty(
      XMLExtendedStreamReader reader, ModelNode node, final List<ModelNode> operations)
      throws XMLStreamException {

    int attributes = reader.getAttributeCount();
    String propertyName = null;
    for (int i = 0; i < attributes; i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case NAME:
          {
            propertyName = value;
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }
    if (propertyName == null) {
      throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.NAME));
    }
    String propertyValue = reader.getElementText();

    PathAddress propertyAddress =
        PathAddress.pathAddress(node.get(OP_ADDR)).append(ModelKeys.PROPERTY, propertyName);
    ModelNode property = Util.createAddOperation(propertyAddress);

    // represent the value as a ModelNode to cater for expressions
    StorePropertyResource.VALUE.parseAndSetParameter(propertyValue, property, reader);

    operations.add(property);
  }
 private void parseStoreProperty(XMLExtendedStreamReader reader, ModelNode node)
     throws XMLStreamException {
   int attributes = reader.getAttributeCount();
   String property = null;
   for (int i = 0; i < attributes; i++) {
     String value = reader.getAttributeValue(i);
     Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
     switch (attribute) {
       case NAME:
         {
           property = value;
           break;
         }
       default:
         {
           throw ParseUtils.unexpectedAttribute(reader, i);
         }
     }
   }
   if (property == null) {
     throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.NAME));
   }
   String value = reader.getElementText();
   node.get(ModelKeys.PROPERTIES).add(property, value);
 }
  private void parseTransport(
      XMLExtendedStreamReader reader, ModelNode containerAddress, List<ModelNode> operations)
      throws XMLStreamException {

    // ModelNode for the transport add operation
    ModelNode transport = Util.getEmptyOperation(ModelDescriptionConstants.ADD, null);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case STACK:
          {
            transport.get(ModelKeys.STACK).set(value);
            break;
          }
        case EXECUTOR:
          {
            transport.get(ModelKeys.EXECUTOR).set(value);
            break;
          }
        case LOCK_TIMEOUT:
          {
            transport.get(ModelKeys.LOCK_TIMEOUT).set(Long.parseLong(value));
            break;
          }
        case SITE:
          {
            transport.get(ModelKeys.SITE).set(value);
            break;
          }
        case RACK:
          {
            transport.get(ModelKeys.RACK).set(value);
            break;
          }
        case MACHINE:
          {
            transport.get(ModelKeys.MACHINE).set(value);
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }
    ParseUtils.requireNoContent(reader);

    // setup the transport address
    ModelNode transportAddress = containerAddress.clone();
    transportAddress.add(ModelKeys.SINGLETON, ModelKeys.TRANSPORT);
    transportAddress.protect();
    transport.get(ModelDescriptionConstants.OP_ADDR).set(transportAddress);

    operations.add(transport);
  }
  private void parseRemoteStore(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {
    // ModelNode for the store add operation
    ModelNode storeAddress = cache.get(ModelDescriptionConstants.OP_ADDR).clone();
    storeAddress.add(ModelKeys.REMOTE_STORE, ModelKeys.REMOTE_STORE_NAME);
    storeAddress.protect();
    ModelNode store = Util.getEmptyOperation(ModelDescriptionConstants.ADD, storeAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case CACHE:
          {
            CommonAttributes.CACHE.parseAndSetParameter(value, store, reader);
            break;
          }
        case SOCKET_TIMEOUT:
          {
            CommonAttributes.SOCKET_TIMEOUT.parseAndSetParameter(value, store, reader);
            break;
          }
        case TCP_NO_DELAY:
          {
            CommonAttributes.TCP_NO_DELAY.parseAndSetParameter(value, store, reader);
            break;
          }
        default:
          {
            this.parseStoreAttribute(reader, i, attribute, value, store);
          }
      }
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case REMOTE_SERVER:
          {
            this.parseRemoteServer(reader, store.get(ModelKeys.REMOTE_SERVERS).add());
            break;
          }
        default:
          {
            this.parseStoreProperty(reader, store);
          }
      }
    }

    if (!store.hasDefined(ModelKeys.REMOTE_SERVERS)) {
      throw ParseUtils.missingRequired(reader, Collections.singleton(Element.REMOTE_SERVER));
    }
    operations.add(store);
  }
  private void parseJDBCStoreTable(XMLExtendedStreamReader reader, ModelNode table)
      throws XMLStreamException {
    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case PREFIX:
          {
            table.get(ModelKeys.PREFIX).set(value);
            break;
          }
        case FETCH_SIZE:
          {
            table.get(ModelKeys.FETCH_SIZE).set(Integer.parseInt(value));
            break;
          }
        case BATCH_SIZE:
          {
            table.get(ModelKeys.BATCH_SIZE).set(Integer.parseInt(value));
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case ID_COLUMN:
          {
            this.parseJDBCStoreColumn(reader, table.get(ModelKeys.ID_COLUMN).setEmptyObject());
            break;
          }
        case DATA_COLUMN:
          {
            this.parseJDBCStoreColumn(reader, table.get(ModelKeys.DATA_COLUMN).setEmptyObject());
            break;
          }
        case TIMESTAMP_COLUMN:
          {
            this.parseJDBCStoreColumn(
                reader, table.get(ModelKeys.TIMESTAMP_COLUMN).setEmptyObject());
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedElement(reader);
          }
      }
    }
  }
  private void parseBinaryKeyedJDBCStore(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {

    PathAddress storeAddress =
        PathAddress.pathAddress(cache.get(OP_ADDR))
            .append(ModelKeys.BINARY_KEYED_JDBC_STORE, ModelKeys.BINARY_KEYED_JDBC_STORE_NAME);
    ModelNode store = Util.createAddOperation(storeAddress);

    List<ModelNode> additionalConfigurationOperations = new ArrayList<ModelNode>();

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case DATASOURCE:
          {
            BaseJDBCStoreResource.DATA_SOURCE.parseAndSetParameter(value, store, reader);
            break;
          }
        default:
          {
            this.parseStoreAttribute(reader, i, attribute, value, store);
          }
      }
    }

    if (!store.hasDefined(ModelKeys.DATASOURCE)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.DATASOURCE));
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case BINARY_KEYED_TABLE:
          {
            this.parseJDBCStoreTable(
                reader, store.get(ModelKeys.BINARY_KEYED_TABLE).setEmptyObject());
            break;
          }
        case WRITE_BEHIND:
          {
            parseStoreWriteBehind(reader, store, additionalConfigurationOperations);
            break;
          }
        default:
          {
            this.parseStoreProperty(reader, store, additionalConfigurationOperations);
          }
      }
    }
    operations.add(store);
    operations.addAll(additionalConfigurationOperations);
  }
  private void parseDistributedCache(XMLExtendedStreamReader reader, ModelNode cache)
      throws XMLStreamException {
    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case OWNERS:
          {
            cache.get(ModelKeys.OWNERS).set(Integer.parseInt(value));
            break;
          }
        case VIRTUAL_NODES:
          {
            cache.get(ModelKeys.VIRTUAL_NODES).set(Integer.parseInt(value));
            break;
          }
        case L1_LIFESPAN:
          {
            cache.get(ModelKeys.L1_LIFESPAN).set(Long.parseLong(value));
            break;
          }
        default:
          {
            this.parseClusteredCacheAttribute(
                reader, i, attribute, value, cache, Configuration.CacheMode.DIST_SYNC);
          }
      }
    }

    if (!cache.hasDefined(ModelKeys.NAME)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.NAME));
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case REHASHING:
          {
            this.parseRehashing(reader, cache.get(ModelKeys.REHASHING).setEmptyObject());
            break;
          }
        default:
          {
            this.parseCacheElement(reader, element, cache);
          }
      }
    }
  }
  private void parseRemoteStore(XMLExtendedStreamReader reader, ModelNode store)
      throws XMLStreamException {
    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case CACHE:
          {
            store.get(ModelKeys.CACHE).set(value);
            break;
          }
        case SOCKET_TIMEOUT:
          {
            store.get(ModelKeys.SOCKET_TIMEOUT).set(Long.parseLong(value));
            break;
          }
        case TCP_NO_DELAY:
          {
            store.get(ModelKeys.TCP_NO_DELAY).set(Boolean.valueOf(value));
            break;
          }
        default:
          {
            this.parseStoreAttribute(reader, i, attribute, value, store);
          }
      }
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case REMOTE_SERVER:
          {
            this.parseRemoteServer(reader, store.get(ModelKeys.REMOTE_SERVER).add());
            break;
          }
        default:
          {
            this.parseStoreProperty(reader, store);
          }
      }
    }

    if (!store.hasDefined(ModelKeys.REMOTE_SERVER)) {
      throw ParseUtils.missingRequired(reader, Collections.singleton(Element.REMOTE_SERVER));
    }
  }
  private void parseTransport(
      XMLExtendedStreamReader reader, ModelNode containerAddress, List<ModelNode> operations)
      throws XMLStreamException {

    // ModelNode for the transport add operation
    ModelNode transport = Util.getEmptyOperation(ModelDescriptionConstants.ADD, null);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case STACK:
          {
            TransportResource.STACK.parseAndSetParameter(value, transport, reader);
            break;
          }
        case CLUSTER:
          {
            TransportResource.CLUSTER.parseAndSetParameter(value, transport, reader);
            break;
          }
        case EXECUTOR:
          {
            TransportResource.EXECUTOR.parseAndSetParameter(value, transport, reader);
            break;
          }
        case LOCK_TIMEOUT:
          {
            TransportResource.LOCK_TIMEOUT.parseAndSetParameter(value, transport, reader);
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }
    ParseUtils.requireNoContent(reader);

    // setup the transport address
    ModelNode transportAddress = containerAddress.clone();
    transportAddress.add(ModelKeys.TRANSPORT, ModelKeys.TRANSPORT_NAME);
    transportAddress.protect();
    transport.get(ModelDescriptionConstants.OP_ADDR).set(transportAddress);

    operations.add(transport);
  }
  private void parseInvalidationCache(
      XMLExtendedStreamReader reader, ModelNode containerAddress, List<ModelNode> operations)
      throws XMLStreamException {

    // ModelNode for the cache add operation
    ModelNode cache = Util.getEmptyOperation(ModelDescriptionConstants.ADD, null);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      this.parseClusteredCacheAttribute(reader, i, attribute, value, cache);
    }

    if (!cache.hasDefined(ModelKeys.NAME)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.NAME));
    }
    if (!cache.hasDefined(ModelKeys.MODE)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.MODE));
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case STATE_TRANSFER:
          {
            this.parseStateTransfer(reader, cache.get(ModelKeys.STATE_TRANSFER).setEmptyObject());
            break;
          }
        default:
          {
            this.parseCacheElement(reader, element, cache);
          }
      }
    }
    String name = cache.get(ModelKeys.NAME).asString();
    // setup the cache address
    ModelNode cacheAddress = containerAddress.clone();
    cacheAddress.add(ModelKeys.INVALIDATION_CACHE, name);
    cacheAddress.protect();
    cache.get(ModelDescriptionConstants.OP_ADDR).set(cacheAddress);

    // get rid of NAME now that we are finished with it
    cache.remove(ModelKeys.NAME);

    operations.add(cache);
  }
  private void parseStoreWriteBehind(
      XMLExtendedStreamReader reader, ModelNode store, List<ModelNode> operations)
      throws XMLStreamException {
    // ModelNode for the write-behind add operation
    ModelNode writeBehindAddress = store.get(ModelDescriptionConstants.OP_ADDR).clone();
    writeBehindAddress.add(ModelKeys.WRITE_BEHIND, ModelKeys.WRITE_BEHIND_NAME);
    writeBehindAddress.protect();
    ModelNode writeBehind =
        Util.getEmptyOperation(ModelDescriptionConstants.ADD, writeBehindAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case FLUSH_LOCK_TIMEOUT:
          {
            StoreWriteBehindResource.FLUSH_LOCK_TIMEOUT.parseAndSetParameter(
                value, writeBehind, reader);
            break;
          }
        case MODIFICATION_QUEUE_SIZE:
          {
            StoreWriteBehindResource.MODIFICATION_QUEUE_SIZE.parseAndSetParameter(
                value, writeBehind, reader);
            break;
          }
        case SHUTDOWN_TIMEOUT:
          {
            StoreWriteBehindResource.SHUTDOWN_TIMEOUT.parseAndSetParameter(
                value, writeBehind, reader);
            break;
          }
        case THREAD_POOL_SIZE:
          {
            StoreWriteBehindResource.THREAD_POOL_SIZE.parseAndSetParameter(
                value, writeBehind, reader);
            break;
          }
        default:
          throw ParseUtils.unexpectedAttribute(reader, i);
      }
    }
    ParseUtils.requireNoContent(reader);
    operations.add(writeBehind);
  }
  /**
   * {@inheritDoc}
   *
   * @see
   *     org.jboss.staxmapper.XMLElementReader#readElement(org.jboss.staxmapper.XMLExtendedStreamReader,
   *     java.lang.Object)
   */
  @SuppressWarnings("deprecation")
  @Override
  public void readElement(XMLExtendedStreamReader reader, List<ModelNode> operations)
      throws XMLStreamException {

    ModelNode subsystemAddress = new ModelNode();
    subsystemAddress.add(ModelDescriptionConstants.SUBSYSTEM, InfinispanExtension.SUBSYSTEM_NAME);
    subsystemAddress.protect();

    ModelNode subsystem = Util.getEmptyOperation(ModelDescriptionConstants.ADD, subsystemAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      ParseUtils.requireNoNamespaceAttribute(reader, i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case DEFAULT_CACHE_CONTAINER:
          {
            // Ignore
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }

    // command to add the subsystem
    operations.add(subsystem);

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case CACHE_CONTAINER:
          {
            parseContainer(reader, subsystemAddress, operations);
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedElement(reader);
          }
      }
    }
  }
  @SuppressWarnings("deprecation")
  private void parseTransaction(
      XMLExtendedStreamReader reader, ModelNode cache, List<ModelNode> operations)
      throws XMLStreamException {

    // ModelNode for the transaction add operation
    ModelNode transactionAddress = cache.get(ModelDescriptionConstants.OP_ADDR).clone();
    transactionAddress.add(ModelKeys.TRANSACTION, ModelKeys.TRANSACTION_NAME);
    transactionAddress.protect();
    ModelNode transaction =
        Util.getEmptyOperation(ModelDescriptionConstants.ADD, transactionAddress);

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      switch (attribute) {
        case STOP_TIMEOUT:
          {
            CommonAttributes.STOP_TIMEOUT.parseAndSetParameter(value, transaction, reader);
            break;
          }
        case MODE:
          {
            CommonAttributes.MODE.parseAndSetParameter(value, transaction, reader);
            break;
          }
        case LOCKING:
          {
            CommonAttributes.LOCKING.parseAndSetParameter(value, transaction, reader);
            break;
          }
        case EAGER_LOCKING:
          {
            ROOT_LOGGER.eagerAttributeDeprecated();
            break;
          }
        default:
          {
            throw ParseUtils.unexpectedAttribute(reader, i);
          }
      }
    }
    ParseUtils.requireNoContent(reader);
    operations.add(transaction);
  }
  private void parseReplicatedCache(
      XMLExtendedStreamReader reader, PathAddress containerAddress, List<ModelNode> operations)
      throws XMLStreamException {

    // ModelNode for the cache add operation
    ModelNode cache = Util.getEmptyOperation(ModelDescriptionConstants.ADD, null);
    List<ModelNode> additionalConfigurationOperations = new ArrayList<ModelNode>();

    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      this.parseClusteredCacheAttribute(reader, i, attribute, value, cache);
    }

    if (!cache.hasDefined(ModelKeys.NAME)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.NAME));
    }
    if (!cache.hasDefined(ModelKeys.MODE)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.MODE));
    }

    // update the cache address with the cache name
    addCacheNameToAddress(cache, containerAddress, ModelKeys.REPLICATED_CACHE);

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      switch (element) {
        case STATE_TRANSFER:
          {
            this.parseStateTransfer(reader, cache, additionalConfigurationOperations);
            break;
          }
        default:
          {
            this.parseCacheElement(reader, element, cache, additionalConfigurationOperations);
          }
      }
    }

    operations.add(cache);
    // add operations to create configuration resources
    for (ModelNode additionalOperation : additionalConfigurationOperations) {
      operations.add(additionalOperation);
    }
  }
  private void parseInvalidationCache(XMLExtendedStreamReader reader, ModelNode cache)
      throws XMLStreamException {
    for (int i = 0; i < reader.getAttributeCount(); i++) {
      String value = reader.getAttributeValue(i);
      Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
      this.parseClusteredCacheAttribute(
          reader, i, attribute, value, cache, Configuration.CacheMode.INVALIDATION_SYNC);
    }

    if (!cache.hasDefined(ModelKeys.NAME)) {
      throw ParseUtils.missingRequired(reader, EnumSet.of(Attribute.NAME));
    }

    while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
      Element element = Element.forName(reader.getLocalName());
      this.parseCacheElement(reader, element, cache);
    }
  }
 private void parseTransport(XMLExtendedStreamReader reader, ModelNode transport)
     throws XMLStreamException {
   for (int i = 0; i < reader.getAttributeCount(); i++) {
     String value = reader.getAttributeValue(i);
     Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i));
     switch (attribute) {
       case STACK:
         {
           transport.get(ModelKeys.STACK).set(value);
           break;
         }
       case EXECUTOR:
         {
           transport.get(ModelKeys.EXECUTOR).set(value);
           break;
         }
       case LOCK_TIMEOUT:
         {
           transport.get(ModelKeys.LOCK_TIMEOUT).set(Long.parseLong(value));
           break;
         }
       case SITE:
         {
           transport.get(ModelKeys.SITE).set(value);
           break;
         }
       case RACK:
         {
           transport.get(ModelKeys.RACK).set(value);
           break;
         }
       case MACHINE:
         {
           transport.get(ModelKeys.MACHINE).set(value);
           break;
         }
       default:
         {
           throw ParseUtils.unexpectedAttribute(reader, i);
         }
     }
   }
   ParseUtils.requireNoContent(reader);
 }