/**
   * Parse start of element from document. Ignores character data to next start or end tag, but
   * throws exception if an end tag is seen before a start tag, or if the start tag seen does not
   * match the expected name.
   *
   * @param tag element name expected
   * @throws IOException if error reading document
   * @throws XmlPullParserException if expected element not found, or if other parse error
   */
  protected void parseStartTag(String tag) throws IOException, XmlPullParserException {
    while (true) {
      switch (m_parser.next()) {
        case XmlPullParser.START_TAG:
          m_parser.readStartTag(m_startTag);
          if (m_startTag.getLocalName().equals(tag)) {
            return;
          }
          // fall through for error handling

        case XmlPullParser.END_TAG:
        case XmlPullParser.END_DOCUMENT:
          throw new XmlPullParserException("Missing expected start tag " + tag);
      }
    }
  }
  /**
   * Parse end of element from document. Collects character data to the end tag and returns it with
   * whitespace stripped. Throws an exception if a start tag is seen before an end tag, or if the
   * end tag seen does not match the expected name.
   *
   * @param tag element name expected
   * @return content text with whitespace stripped
   * @throws IOException if error reading document
   * @throws XmlPullParserException if expected element not found, or if other parse error
   */
  protected String parseEndTag(String tag) throws IOException, XmlPullParserException {
    m_buffer.setLength(0);
    while (true) {
      switch (m_parser.next()) {
        case XmlPullParser.CONTENT:
          m_buffer.append(m_parser.readContent());
          break;

        case XmlPullParser.END_TAG:
          m_parser.readEndTag(m_endTag);
          if (m_endTag.getLocalName().equals(tag)) {
            return m_buffer.toString().trim();
          }
          // fall through for error handling

        case XmlPullParser.START_TAG:
        case XmlPullParser.END_DOCUMENT:
          throw new XmlPullParserException("Missing expected end tag " + tag);
      }
    }
  }
  /**
   * Parse and process trade history information stream.
   *
   * @param in XML document reader
   * @throws IOException if error reading document
   * @throws XmlPullParserException on document parse error
   */
  public void parse(Reader in) throws IOException, XmlPullParserException {

    // set document source for parse
    m_parser.reset();
    m_parser.setInput(in);

    // main pull parsing loop
    byte type;
    while ((type = m_parser.next()) != XmlPullParser.END_DOCUMENT) {

      // ignore everything other than a start tag
      if (type == XmlPullParser.START_TAG) {

        // process the start tags we're interested in
        m_parser.readStartTag(m_startTag);
        String lname = m_startTag.getLocalName();
        if (lname.equals(STOCK_ELEMENT_NAME)) {
          parseStockTrade();
        } else if (lname.equals(OPTION_ELEMENT_NAME)) {
          parseOptionTrade();
        }
      }
    }
  }