protected void parseElement(
      final ElementParser parser,
      ModelElement parentElement,
      final ModelNode parentNode,
      final XMLExtendedStreamReader reader,
      final List<ModelNode> addOperations)
      throws XMLStreamException {
    while (reader.hasNext() && reader.nextTag() != END_DOCUMENT) {
      if (!reader.isStartElement()) {
        if (reader.isEndElement() && reader.getLocalName().equals(parentElement.getName())) {
          break;
        }
        continue;
      }

      if (reader.getLocalName().equals(parentElement.getName())) {
        continue;
      }

      ModelElement element = ModelElement.forName(reader.getLocalName());

      if (element == null) {
        if (XMLElement.forName(reader.getLocalName()) != null) {
          continue;
        }

        throw unexpectedElement(reader);
      }

      parser.parse(reader, element, parentNode, addOperations);
    }
  }
  /**
   * Reads a element from the stream considering the parameters.
   *
   * @param reader XMLExtendedStreamReader instance from which the elements are read.
   * @param xmlElement Name of the Model Element to be parsed.
   * @param key Name of the attribute to be used to as the key for the model.
   * @param addOperations List of operations.
   * @param lastNode Parent ModelNode instance.
   * @param attributes AttributeDefinition instances to be used to extract the attributes and
   *     populate the resulting model.
   * @return A ModelNode instance populated.
   * @throws javax.xml.stream.XMLStreamException
   */
  protected ModelNode parseConfig(
      XMLExtendedStreamReader reader,
      ModelElement xmlElement,
      String key,
      ModelNode lastNode,
      List<SimpleAttributeDefinition> attributes,
      List<ModelNode> addOperations)
      throws XMLStreamException {
    if (!reader.getLocalName().equals(xmlElement.getName())) {
      return null;
    }

    ModelNode modelNode = Util.getEmptyOperation(ADD, null);

    int attributeCount = reader.getAttributeCount();

    for (int i = 0; i < attributeCount; i++) {
      String attributeLocalName = reader.getAttributeLocalName(i);

      if (ModelElement.forName(attributeLocalName) == null) {
        throw unexpectedAttribute(reader, i);
      }
    }

    for (SimpleAttributeDefinition simpleAttributeDefinition : attributes) {
      simpleAttributeDefinition.parseAndSetParameter(
          reader.getAttributeValue("", simpleAttributeDefinition.getXmlName()), modelNode, reader);
    }

    String name = xmlElement.getName();

    if (key != null) {
      name = key;

      if (modelNode.hasDefined(key)) {
        name = modelNode.get(key).asString();
      } else {
        String attributeValue = reader.getAttributeValue("", key);

        if (attributeValue != null) {
          name = attributeValue;
        }
      }
    }

    modelNode
        .get(ModelDescriptionConstants.OP_ADDR)
        .set(lastNode.clone().get(OP_ADDR).add(xmlElement.getName(), name));

    addOperations.add(modelNode);

    return modelNode;
  }
  private void readElement(
      XMLExtendedStreamReader reader, ModelNode subsystemNode, List<ModelNode> addOperations)
      throws XMLStreamException {
    while (reader.hasNext() && reader.nextTag() != END_DOCUMENT) {
      if (!reader.isStartElement()) {
        continue;
      }

      // if the current element is supported but is not a model element
      if (XMLElement.forName(reader.getLocalName()) != null) {
        continue;
      }

      ModelElement modelKey = ModelElement.forName(reader.getLocalName());

      if (modelKey == null) {
        throw unexpectedElement(reader);
      }

      switch (modelKey) {
        case PARTITION_MANAGER:
          parseIdentityManagementConfig(reader, subsystemNode, addOperations);
          break;
        default:
          throw unexpectedElement(reader);
      }
    }
  }