private ModelNode parseDatabaseBinaryStorage(
      final XMLExtendedStreamReader reader, final String repositoryName) throws XMLStreamException {
    final ModelNode storageType = new ModelNode();
    storageType.get(OP).set(ADD);
    storageType
        .get(OP_ADDR)
        .add(SUBSYSTEM, ModeShapeExtension.SUBSYSTEM_NAME)
        .add(ModelKeys.REPOSITORY, repositoryName)
        .add(ModelKeys.CONFIGURATION, ModelKeys.BINARY_STORAGE)
        .add(ModelKeys.STORAGE_TYPE, ModelKeys.DB_BINARY_STORAGE);

    if (reader.getAttributeCount() > 0) {
      for (int i = 0; i < reader.getAttributeCount(); i++) {
        String attrName = reader.getAttributeLocalName(i);
        String attrValue = reader.getAttributeValue(i);
        Attribute attribute = Attribute.forName(attrName);
        switch (attribute) {
            // The rest go on the ModelNode for the type ...
          case DATA_SOURCE_JNDI_NAME:
            ModelAttributes.DATA_SOURCE_JNDI_NAME.parseAndSetParameter(
                attrValue, storageType, reader);
            break;
          case MIN_VALUE_SIZE:
            ModelAttributes.MINIMUM_BINARY_SIZE.parseAndSetParameter(
                attrValue, storageType, reader);
            break;
          default:
            throw ParseUtils.unexpectedAttribute(reader, i);
        }
      }
    }
    requireNoElements(reader);

    return storageType;
  }
  private ModelNode parseCustomBinaryStorage(
      final XMLExtendedStreamReader reader, final String repositoryName) throws XMLStreamException {
    final ModelNode storageType = new ModelNode();
    storageType.get(OP).set(ADD);
    storageType
        .get(OP_ADDR)
        .add(SUBSYSTEM, ModeShapeExtension.SUBSYSTEM_NAME)
        .add(ModelKeys.REPOSITORY, repositoryName)
        .add(ModelKeys.CONFIGURATION, ModelKeys.BINARY_STORAGE)
        .add(ModelKeys.STORAGE_TYPE, ModelKeys.CUSTOM_BINARY_STORAGE);

    if (reader.getAttributeCount() > 0) {
      for (int i = 0; i < reader.getAttributeCount(); i++) {
        String attrName = reader.getAttributeLocalName(i);
        String attrValue = reader.getAttributeValue(i);
        Attribute attribute = Attribute.forName(attrName);
        switch (attribute) {
          case CLASSNAME:
            ModelAttributes.CLASSNAME.parseAndSetParameter(attrValue, storageType, reader);
            break;
          case MODULE:
            ModelAttributes.MODULE.parseAndSetParameter(attrValue, storageType, reader);
            break;
          case MIN_VALUE_SIZE:
            ModelAttributes.MINIMUM_BINARY_SIZE.parseAndSetParameter(
                attrValue, storageType, reader);
            break;
          default:
            storageType.get(attrName).set(attrValue);
            break;
        }
      }
    }
    requireNoElements(reader);

    return storageType;
  }
  private void writeBinaryStorageModel(
      XMLExtendedStreamWriter writer, String storageType, ModelNode storage)
      throws XMLStreamException {
    if (ModelKeys.FILE_BINARY_STORAGE.equals(storageType)) {
      // This is the default, but there is no default value for the ModelAttributes.PATH (which is
      // required),
      // which means we always have to write this out. If it is the default binary storage, then
      // there
      // won't even be a 'binary-storage=BINARIES' model node.
      writer.writeStartElement(Element.FILE_BINARY_STORAGE.getLocalName());
      ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.PATH.marshallAsAttribute(storage, false, writer);
      ModelAttributes.RELATIVE_TO.marshallAsAttribute(storage, false, writer);
      ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
      writer.writeEndElement();
    } else if (ModelKeys.CACHE_BINARY_STORAGE.equals(storageType)) {
      writer.writeStartElement(Element.CACHE_BINARY_STORAGE.getLocalName());
      ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.DATA_CACHE_NAME.marshallAsAttribute(storage, false, writer);
      ModelAttributes.METADATA_CACHE_NAME.marshallAsAttribute(storage, false, writer);
      ModelAttributes.CHUNK_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.CACHE_CONFIG.marshallAsAttribute(storage, false, writer);
      ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
      writer.writeEndElement();
    } else if (ModelKeys.DB_BINARY_STORAGE.equals(storageType)) {
      writer.writeStartElement(Element.DB_BINARY_STORAGE.getLocalName());
      ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.DATA_SOURCE_JNDI_NAME.marshallAsAttribute(storage, false, writer);
      ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
      writer.writeEndElement();
    } else if (ModelKeys.COMPOSITE_BINARY_STORAGE.equals(storageType)) {
      writer.writeStartElement(Element.COMPOSITE_BINARY_STORAGE.getLocalName());
      ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);

      writeNestedStoresOfType(
          storage, ModelKeys.NESTED_STORAGE_TYPE_FILE, ModelKeys.FILE_BINARY_STORAGE, writer);
      writeNestedStoresOfType(
          storage, ModelKeys.NESTED_STORAGE_TYPE_CACHE, ModelKeys.CACHE_BINARY_STORAGE, writer);
      writeNestedStoresOfType(
          storage, ModelKeys.NESTED_STORAGE_TYPE_DB, ModelKeys.DB_BINARY_STORAGE, writer);
      writeNestedStoresOfType(
          storage, ModelKeys.NESTED_STORAGE_TYPE_CUSTOM, ModelKeys.CUSTOM_BINARY_STORAGE, writer);

      writer.writeEndElement();
    } else if (ModelKeys.CUSTOM_BINARY_STORAGE.equals(storageType)) {
      writer.writeStartElement(Element.CUSTOM_BINARY_STORAGE.getLocalName());
      ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
      ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
      ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
      for (String key : storage.keys()) {
        if (key.equals(ModelKeys.CLASSNAME)) {
          ModelAttributes.CLASSNAME.marshallAsAttribute(storage, false, writer);
        } else if (key.equals(ModelKeys.MODULE)) {
          ModelAttributes.MODULE.marshallAsAttribute(storage, false, writer);
        } else {
          writer.writeAttribute(key, storage.get(key).asString());
        }
      }
      writer.writeEndElement();
    }
  }