public void writePayloadTo(XMLStreamWriter writer) throws XMLStreamException {
    if (payloadLocalName == null) {
      return;
    } // no body
    assert unconsumed();
    XMLStreamReaderToXMLStreamWriter conv = new XMLStreamReaderToXMLStreamWriter();
    while (reader.getEventType() != XMLStreamConstants.END_DOCUMENT) {
      String name = reader.getLocalName();
      String nsUri = reader.getNamespaceURI();

      // after previous conv.bridge() call the cursor will be at
      // END_ELEMENT. Check if its not soapenv:Body then move to next
      // ELEMENT
      if (reader.getEventType() == XMLStreamConstants.END_ELEMENT) {
        if (!name.equals("Body") || !nsUri.equals(soapVersion.nsUri)) {
          XMLStreamReaderUtil.nextElementContent(reader);
          if (reader.getEventType() == XMLStreamConstants.END_DOCUMENT) {
            break;
          }
          name = reader.getLocalName();
          nsUri = reader.getNamespaceURI();
        }
      }
      if (name.equals("Body") && nsUri.equals(soapVersion.nsUri)
          || (reader.getEventType() == XMLStreamConstants.END_DOCUMENT)) {
        break;
      }
      conv.bridge(reader, writer);
    }
    reader.close();
    XMLStreamReaderFactory.recycle(reader);
  }
  public void writePayloadTo(
      ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment)
      throws SAXException {
    assert unconsumed();
    try {
      if (payloadLocalName == null) {
        return;
      } // no body

      XMLStreamReaderToContentHandler conv =
          new XMLStreamReaderToContentHandler(reader, contentHandler, true, fragment);

      while (reader.getEventType() != XMLStreamConstants.END_DOCUMENT) {
        String name = reader.getLocalName();
        String nsUri = reader.getNamespaceURI();

        // after previous conv.bridge() call the cursor will be at
        // END_ELEMENT. Check if its not soapenv:Body then move to next
        // ELEMENT
        if (reader.getEventType() == XMLStreamConstants.END_ELEMENT) {
          if (!name.equals("Body") || !nsUri.equals(soapVersion.nsUri)) {
            XMLStreamReaderUtil.nextElementContent(reader);
            if (reader.getEventType() == XMLStreamConstants.END_DOCUMENT) {
              break;
            }
            name = reader.getLocalName();
            nsUri = reader.getNamespaceURI();
          }
        }
        if (name.equals("Body") && nsUri.equals(soapVersion.nsUri)
            || (reader.getEventType() == XMLStreamConstants.END_DOCUMENT)) {
          break;
        }

        conv.bridge();
      }
      reader.close();
      XMLStreamReaderFactory.recycle(reader);
    } catch (XMLStreamException e) {
      Location loc = e.getLocation();
      if (loc == null) {
        loc = DummyLocation.INSTANCE;
      }

      SAXParseException x =
          new SAXParseException(
              e.getMessage(),
              loc.getPublicId(),
              loc.getSystemId(),
              loc.getLineNumber(),
              loc.getColumnNumber(),
              e);
      errorHandler.error(x);
    }
  }
 public <T> T readPayloadAsJAXB(Bridge<T> bridge) throws JAXBException {
   cacheMessage();
   if (!hasPayload()) {
     return null;
   }
   assert unconsumed();
   T r =
       bridge.unmarshal(
           reader, hasAttachments() ? new AttachmentUnmarshallerImpl(getAttachments()) : null);
   XMLStreamReaderUtil.close(reader);
   XMLStreamReaderFactory.recycle(reader);
   return r;
 }
  /**
   * Creates a {@link StreamMessage} from a {@link XMLStreamReader} that points at the start element
   * of the payload, and headers.
   *
   * <p>This method creaets a {@link Message} from a payload.
   *
   * @param headers if null, it means no headers. if non-null, it will be owned by this message.
   * @param reader points at the start element/document of the payload (or the end element of the
   *     &lt;s:Body> if there's no payload)
   */
  public VerifiedStreamMessage(
      @Nullable HeaderList headers,
      @NotNull AttachmentSet attachmentSet,
      @NotNull XMLStreamReader reader,
      @NotNull SOAPVersion soapVersion,
      Map<String, String> bodyEnvNs) {
    super(soapVersion);
    this.headers = headers;
    this.attachmentSet = attachmentSet;
    this.reader = reader;
    this.bodyEnvNs = bodyEnvNs;

    if (reader.getEventType() == START_DOCUMENT) {
      XMLStreamReaderUtil.nextElementContent(reader);
    }

    // if the reader is pointing to the end element </soapenv:Body> then its empty message
    // or no payload
    if (reader.getEventType() == XMLStreamConstants.END_ELEMENT) {
      String body = reader.getLocalName();
      String nsUri = reader.getNamespaceURI();
      assert body != null;
      assert nsUri != null;
      // if its not soapenv:Body then throw exception, we received malformed stream
      if (body.equals("Body") && nsUri.equals(soapVersion.nsUri)) {
        this.payloadLocalName = null;
        this.payloadNamespaceURI = null;
      } else { // TODO: i18n and also we should be throwing better message that this
        throw new WebServiceException("Malformed stream: {" + nsUri + "}" + body);
      }
    } else {
      this.payloadLocalName = reader.getLocalName();
      this.payloadNamespaceURI = reader.getNamespaceURI();
    }

    // use the default infoset representation for headers
    int base = soapVersion.ordinal() * 3;
    this.envelopeTag = DEFAULT_TAGS[base];
    this.headerTag = DEFAULT_TAGS[base + 1];
    this.bodyTag = DEFAULT_TAGS[base + 2];
  }