/** Writes the whole envelope as SAX events. */
  @Override
  public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler)
      throws SAXException {
    String soapNsUri = soapVersion.nsUri;

    contentHandler.setDocumentLocator(NULL_LOCATOR);
    contentHandler.startDocument();
    contentHandler.startPrefixMapping("S", soapNsUri);
    contentHandler.startElement(soapNsUri, "Envelope", "S:Envelope", EMPTY_ATTS);
    if (hasHeaders()) {
      contentHandler.startElement(soapNsUri, "Header", "S:Header", EMPTY_ATTS);
      MessageHeaders headers = getHeaders();
      for (Header h : headers.asList()) {
        h.writeTo(contentHandler, errorHandler);
      }
      contentHandler.endElement(soapNsUri, "Header", "S:Header");
    }
    // write the body
    contentHandler.startElement(soapNsUri, "Body", "S:Body", EMPTY_ATTS);
    writePayloadTo(contentHandler, errorHandler, true);
    contentHandler.endElement(soapNsUri, "Body", "S:Body");
    contentHandler.endElement(soapNsUri, "Envelope", "S:Envelope");
  }
  /** Default implementation that relies on {@link #writePayloadTo(XMLStreamWriter)} */
  @Override
  public void writeTo(XMLStreamWriter w) throws XMLStreamException {
    String soapNsUri = soapVersion.nsUri;
    w.writeStartDocument();
    w.writeStartElement("S", "Envelope", soapNsUri);
    w.writeNamespace("S", soapNsUri);
    if (hasHeaders()) {
      w.writeStartElement("S", "Header", soapNsUri);
      MessageHeaders headers = getHeaders();
      for (Header h : headers.asList()) {
        h.writeTo(w);
      }
      w.writeEndElement();
    }
    // write the body
    w.writeStartElement("S", "Body", soapNsUri);

    writePayloadTo(w);

    w.writeEndElement();
    w.writeEndElement();
    w.writeEndDocument();
  }