/**
   * Parse and record tracking information. Uses known structure of tracking information fragment to
   * get the information, recording the agent information directly and returning the tracking
   * information as a whole.
   *
   * @return tracking information
   * @throws IOException if error reading document
   * @throws XmlPullParserException if parse error
   */
  protected TrackingData parseTracking() throws IOException, XmlPullParserException {

    // read id attribute from root element start tag
    TrackingData data = new TrackingData();
    parseStartTag(TRACKING_ELEMENT_NAME);
    data.m_id = attributeValue(ID_ATTRIBUTE_NAME);

    // read time as content of its own element
    data.m_time = parseElementContent(TIME_ELEMENT_NAME);

    // read seller agent information
    parseStartTag(SELLER_ELEMENT_NAME);
    data.m_seller = attributeValue(IDENT_ATTRIBUTE_NAME);
    data.m_isDirectSeller = "direct".equals(attributeValue(TYPE_ATTRIBUTE_NAME));
    parseEndTag(SELLER_ELEMENT_NAME);

    // read buyer agent information
    parseStartTag(BUYER_ELEMENT_NAME);
    data.m_buyer = attributeValue(IDENT_ATTRIBUTE_NAME);
    data.m_isDirectBuyer = "direct".equals(attributeValue(TYPE_ATTRIBUTE_NAME));
    parseEndTag(BUYER_ELEMENT_NAME);

    // read exchange identifier as content of its own element
    data.m_exchange = parseElementContent(EXCHANGE_ELEMENT_NAME);

    // finish with closing tag for root element
    parseEndTag(TRACKING_ELEMENT_NAME);

    // record agent information before returning
    AgentTrack.recordAgent(data.m_buyer, !data.m_isDirectBuyer, false);
    AgentTrack.recordAgent(data.m_seller, !data.m_isDirectSeller, true);
    return data;
  }