/**
   * Fires the appropriate SAX events on the content handler to build the XML elements for the
   * property.
   *
   * @param property the property to be exported
   * @param contentHandler the SAX content handler for which SAX events will be invoked as the XML
   *     document is created.
   * @param skipBinary if <code>true</code>, indicates that binary properties should not be exported
   * @throws SAXException if an exception occurs during generation of the XML document
   * @throws RepositoryException if an exception occurs accessing the content repository
   */
  private void emitProperty(Property property, ContentHandler contentHandler, boolean skipBinary)
      throws RepositoryException, SAXException {
    assert property instanceof AbstractJcrProperty
        : "Illegal attempt to use " + getClass().getName() + " on non-ModeShape property";

    AbstractJcrProperty prop = (AbstractJcrProperty) property;

    // first set the property sv:name attribute
    AttributesImpl propAtts = new AttributesImpl();
    propAtts.addAttribute(
        JcrSvLexicon.NAME.getNamespaceUri(),
        JcrSvLexicon.NAME.getLocalName(),
        getPrefixedName(JcrSvLexicon.NAME),
        PropertyType.nameFromValue(PropertyType.STRING),
        prop.getName());

    // and it's sv:type attribute
    propAtts.addAttribute(
        JcrSvLexicon.TYPE.getNamespaceUri(),
        JcrSvLexicon.TYPE.getLocalName(),
        getPrefixedName(JcrSvLexicon.TYPE),
        PropertyType.nameFromValue(PropertyType.STRING),
        PropertyType.nameFromValue(prop.getType()));

    // and it's sv:multiple attribute
    if (prop.isMultiple()) {
      propAtts.addAttribute(
          JcrSvLexicon.TYPE.getNamespaceUri(),
          JcrSvLexicon.TYPE.getLocalName(),
          getPrefixedName(JcrSvLexicon.MULTIPLE),
          PropertyType.nameFromValue(PropertyType.BOOLEAN),
          Boolean.TRUE.toString());
    }

    // output the sv:property element
    startElement(contentHandler, JcrSvLexicon.PROPERTY, propAtts);

    boolean modified = property.isModified();

    // then output a sv:value element for each of its values
    if (prop instanceof JcrMultiValueProperty) {
      Value[] values = prop.getValues();
      for (int i = 0; i < values.length; i++) {

        emitValue(values[i], contentHandler, property.getType(), skipBinary, modified);
      }
    } else {
      emitValue(property.getValue(), contentHandler, property.getType(), skipBinary, modified);
    }

    // end the sv:property element
    endElement(contentHandler, JcrSvLexicon.PROPERTY);
  }
  /**
   * Fires the appropriate SAX events on the content handler to build the XML elements for the
   * property.
   *
   * @param propertyName the name of the property to be exported
   * @param propertyType the type of the property to be exported
   * @param value the value of the single-valued property to be exported
   * @param contentHandler the SAX content handler for which SAX events will be invoked as the XML
   *     document is created.
   * @param skipBinary if <code>true</code>, indicates that binary properties should not be exported
   * @throws SAXException if an exception occurs during generation of the XML document
   * @throws RepositoryException if an exception occurs accessing the content repository
   */
  private void emitProperty(
      Name propertyName,
      int propertyType,
      Object value,
      ContentHandler contentHandler,
      boolean skipBinary)
      throws RepositoryException, SAXException {
    ValueFactory<String> strings =
        session.getExecutionContext().getValueFactories().getStringFactory();

    // first set the property sv:name attribute
    AttributesImpl propAtts = new AttributesImpl();
    propAtts.addAttribute(
        JcrSvLexicon.NAME.getNamespaceUri(),
        JcrSvLexicon.NAME.getLocalName(),
        getPrefixedName(JcrSvLexicon.NAME),
        PropertyType.nameFromValue(PropertyType.STRING),
        strings.create(propertyName));

    // and it's sv:type attribute
    propAtts.addAttribute(
        JcrSvLexicon.TYPE.getNamespaceUri(),
        JcrSvLexicon.TYPE.getLocalName(),
        getPrefixedName(JcrSvLexicon.TYPE),
        PropertyType.nameFromValue(PropertyType.STRING),
        PropertyType.nameFromValue(propertyType));

    // output the sv:property element
    startElement(contentHandler, JcrSvLexicon.PROPERTY, propAtts);

    // then output a sv:value element for each of its values
    emitValue(strings.create(value), contentHandler);

    // end the sv:property element
    endElement(contentHandler, JcrSvLexicon.PROPERTY);
  }