private String pullNextXmlChunkFromTopElementOnStack(XMLChunkerState data)
      throws KettleException {
    Stack<String> elementStack = data.getElementStack();
    XMLStreamReader xmlStreamReader = data.getXmlStreamReader();

    int elementStackDepthOnEntry = elementStack.size();
    StringWriter stringWriter = new StringWriter();

    try {
      XMLStreamWriter xmlStreamWriter =
          data.getXmlOutputFactory().createXMLStreamWriter(stringWriter);

      xmlStreamWriter.writeStartDocument(CharEncoding.UTF_8, "1.0");

      // put the current element on because presumably it's the open element for the one
      // that is being looked for.

      XmlReaderToWriter.write(xmlStreamReader, xmlStreamWriter);

      while (xmlStreamReader.hasNext() & elementStack.size() >= elementStackDepthOnEntry) {

        switch (xmlStreamReader.next()) {
          case XMLStreamConstants.END_DOCUMENT:
            break; // handled below explicitly.

          case XMLStreamConstants.END_ELEMENT:
            elementStack.pop();
            XmlReaderToWriter.write(xmlStreamReader, xmlStreamWriter);
            break;

          case XMLStreamConstants.START_ELEMENT:
            elementStack.push(xmlStreamReader.getLocalName());
            XmlReaderToWriter.write(xmlStreamReader, xmlStreamWriter);
            break;

          default:
            XmlReaderToWriter.write(xmlStreamReader, xmlStreamWriter);
            break;
        }
      }

      xmlStreamWriter.writeEndDocument();
      xmlStreamWriter.close();
    } catch (Exception e) {
      throw new KettleException("unable to process a chunk of the xero xml stream", e);
    }

    return stringWriter.toString();
  }
  @Override
  public int writeData(OutputStream out, DbData data) throws Exception {
    XMLStreamWriter sw = _staxOutFactory.createXMLStreamWriter(out, "UTF-8");
    sw.writeStartDocument();
    sw.writeStartElement(FIELD_TABLE);
    Iterator<DbRow> it = data.rows();
    while (it.hasNext()) {
      DbRow row = it.next();
      sw.writeStartElement(FIELD_ROW); // <row>

      sw.writeStartElement(DbRow.Field.id.name());
      sw.writeCharacters(String.valueOf(row.getId()));
      sw.writeEndElement();

      sw.writeStartElement(DbRow.Field.firstname.name());
      sw.writeCharacters(row.getFirstname());
      sw.writeEndElement();

      sw.writeStartElement(DbRow.Field.lastname.name());
      sw.writeCharacters(row.getLastname());
      sw.writeEndElement();

      sw.writeStartElement(DbRow.Field.zip.name());
      sw.writeCharacters(String.valueOf(row.getZip()));
      sw.writeEndElement();

      sw.writeStartElement(DbRow.Field.street.name());
      sw.writeCharacters(row.getStreet());
      sw.writeEndElement();

      sw.writeStartElement(DbRow.Field.city.name());
      sw.writeCharacters(row.getCity());
      sw.writeEndElement();

      sw.writeStartElement(DbRow.Field.state.name());
      sw.writeCharacters(row.getState());
      sw.writeEndElement();

      sw.writeEndElement(); // </row>
    }
    sw.writeEndElement();
    sw.writeEndDocument();
    sw.close();
    return -1;
  }