/* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  //------100-columns-wide------>|*/
// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)

package org.xmlpull.v1;

import java.io.InputStream;
import java.io.IOException;
import java.io.Reader;

/**
 * XML Pull Parser is an interface that defines parsing functionality provided
 * in <a href="http://www.xmlpull.org/">XMLPULL V1 API</a> (visit this website to
 * learn more about API and its implementations).
 *
 * <p>There are following different
 * kinds of parser depending on which features are set:<ul>
 * <li><b>non-validating</b> parser as defined in XML 1.0 spec when
 *   FEATURE_PROCESS_DOCDECL is set to true
 * <li><b>validating parser</b> as defined in XML 1.0 spec when
 *   FEATURE_VALIDATION is true (and that implies that FEATURE_PROCESS_DOCDECL is true)
 * <li>when FEATURE_PROCESS_DOCDECL is false (this is default and
 *   if different value is required necessary must be changed before parsing is started)
 *   then parser behaves like XML 1.0 compliant non-validating parser under condition that
 *  <em>no DOCDECL is present</em> in XML documents
 *   (internal entites can still be defined with defineEntityReplacementText()).
 *   This mode of operation is intended <b>for operation in constrained environments</b> such as J2ME.
 * </ul>
 *
 *
 * <p>There are two key methods: next() and nextToken(). While next() provides
 * access to high level parsing events, nextToken() allows access to lower
 * level tokens.
 *
 * <p>The current event state of the parser
 * can be determined by calling the
 * <a href="#getEventType()">getEventType()</a> method.
 * Initially, the parser is in the <a href="#START_DOCUMENT">START_DOCUMENT</a>
 * state.
 *
 * <p>The method <a href="#next()">next()</a> advances the parser to the
 * next event. The int value returned from next determines the current parser
 * state and is identical to the value returned from following calls to
 * getEventType ().
 *
 * <p>Th following event types are seen by next()<dl>
 * <dt><a href="#START_TAG">START_TAG</a><dd> An XML start tag was read.
 * <dt><a href="#TEXT">TEXT</a><dd> Text content was read;
 * the text content can be retrieved using the getText() method.
 *  (when in validating mode next() will not report ignorable whitespace, use nextToken() instead)
 * <dt><a href="#END_TAG">END_TAG</a><dd> An end tag was read
 * <dt><a href="#END_DOCUMENT">END_DOCUMENT</a><dd> No more events are available
 * </dl>
 *
 * <p>after first next() or nextToken() (or any other next*() method)
 * is called user application can obtain
 * XML version, standalone and encoding from XML declaration
 * in following ways:<ul>
 * <li><b>version</b>:
 *  getProperty(&quot;<a href="http://xmlpull.org/v1/doc/properties.html#xmldecl-version">http://xmlpull.org/v1/doc/properties.html#xmldecl-version</a>&quot;)
 *       returns String ("1.0") or null if XMLDecl was not read or if property is not supported
 * <li><b>standalone</b>:
 *  getProperty(&quot;<a href="http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone">http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone</a>&quot;)
 *       returns Boolean: null if there was no standalone declaration
 *  or if property is not supported
 *         otherwise returns Boolean(true) if standalone="yes" and Boolean(false) when standalone="no"
 * <li><b>encoding</b>: obtained from getInputEncoding()
 *       null if stream had unknown encoding (not set in setInputStream)
 *           and it was not declared in XMLDecl
 * </ul>
 *
 * A minimal example for using this API may look as follows:
 * <pre>
 * import java.io.IOException;
 * import java.io.StringReader;
 *
 * import org.xmlpull.v1.XmlPullParser;
 * import org.xmlpull.v1.<a href="XmlPullParserException.html">XmlPullParserException</a>;
 * import org.xmlpull.v1.<a href="XmlPullParserFactory.html">XmlPullParserFactory</a>;
 *
 * public class SimpleXmlPullApp
 * {
 *
 *     public static void main (String args[])
 *         throws XmlPullParserException, IOException
 *     {
 *         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
 *         factory.setNamespaceAware(true);
 *         XmlPullParser xpp = factory.newPullParser();
 *
 *         xpp.<a href="#setInput">setInput</a>( new StringReader ( "&lt;foo>Hello World!&lt;/foo>" ) );
 *         int eventType = xpp.getEventType();
 *         while (eventType != XmlPullParser.END_DOCUMENT) {
 *          if(eventType == XmlPullParser.START_DOCUMENT) {
 *              System.out.println("Start document");
 *          } else if(eventType == XmlPullParser.START_TAG) {
 *              System.out.println("Start tag "+xpp.<a href="#getName()">getName()</a>);
 *          } else if(eventType == XmlPullParser.END_TAG) {
 *              System.out.println("End tag "+xpp.getName());
 *          } else if(eventType == XmlPullParser.TEXT) {
 *              System.out.println("Text "+xpp.<a href="#getText()">getText()</a>);
 *          }
 *          eventType = xpp.next();
 *         }
 *         System.out.println("End document");
 *     }
 * }
 * </pre>
 *
 * <p>The above example will generate the following output:
 * <pre>
 * Start document
 * Start tag foo
 * Text Hello World!
 * End tag foo
 * End document
 * </pre>
 *
 * <p>For more details on API usage, please refer to the
 * quick Introduction available at <a href="http://www.xmlpull.org">http://www.xmlpull.org</a>
 *
 * @see XmlPullParserFactory
 * @see #defineEntityReplacementText
 * @see #getName
 * @see #getNamespace
 * @see #getText
 * @see #next
 * @see #nextToken
 * @see #setInput
 * @see #FEATURE_PROCESS_DOCDECL
 * @see #FEATURE_VALIDATION
 * @see #START_DOCUMENT
 * @see #START_TAG
 * @see #TEXT
 * @see #END_TAG
 * @see #END_DOCUMENT
 *
 * @author <a href="http://www-ai.cs.uni-dortmund.de/PERSONAL/haustein.html">Stefan Haustein</a>
 * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
 */

public interface XmlPullParser {

    /** This constant represents the default namespace (empty string "") */
    String NO_NAMESPACE = "";

    // ----------------------------------------------------------------------------
    // EVENT TYPES as reported by next()

    /**
     * Signalize that parser is at the very beginning of the document
     * and nothing was read yet.
     * This event type can only be observed by calling getEvent()
     * before the first call to next(), nextToken, or nextTag()</a>).
     *
     * @see #next
     * @see #nextToken
     */
    int START_DOCUMENT = 0;

    /**
     * Logical end of the xml document. Returned from getEventType, next()
     * and nextToken()
     * when the end of the input document has been reached.
     * <p><strong>NOTE:</strong> subsequent calls to
     * <a href="#next()">next()</a> or <a href="#nextToken()">nextToken()</a>
     * may result in exception being thrown.
     *
     * @see #next
     * @see #nextToken
     */
    int END_DOCUMENT = 1;

    /**
     * Returned from getEventType(),
     * <a href="#next()">next()</a>, <a href="#nextToken()">nextToken()</a> when
     * a start tag was read.
     * The name of start tag is available from getName(), its namespace and prefix are
     * available from getNamespace() and getPrefix()
     * if <a href='#FEATURE_PROCESS_NAMESPACES'>namespaces are enabled</a>.
     * See getAttribute* methods to retrieve element attributes.
     * See getNamespace* methods to retrieve newly declared namespaces.
     *
     * @see #next
     * @see #nextToken
     * @see #getName
     * @see #getPrefix
     * @see #getNamespace
     * @see #getAttributeCount
     * @see #getDepth
     * @see #getNamespaceCount
     * @see #getNamespace
     * @see #FEATURE_PROCESS_NAMESPACES
     */
    int START_TAG = 2;

    /**
     * Returned from getEventType(), <a href="#next()">next()</a>, or
     * <a href="#nextToken()">nextToken()</a> when an end tag was read.
     * The name of start tag is available from getName(), its
     * namespace and prefix are
     * available from getNamespace() and getPrefix().
     *
     * @see #next
     * @see #nextToken
     * @see #getName
     * @see #getPrefix
     * @see #getNamespace
     * @see #FEATURE_PROCESS_NAMESPACES
     */
    int END_TAG = 3;


    /**
     * Character data was read and will is available by calling getText().
     * <p><strong>Please note:</strong> <a href="#next()">next()</a> will
     * accumulate multiple
     * events into one TEXT event, skipping IGNORABLE_WHITESPACE,
     * PROCESSING_INSTRUCTION and COMMENT events,
     * In contrast, <a href="#nextToken()">nextToken()</a> will stop reading
     * text when any other event is observed.
     * Also, when the state was reached by calling next(), the text value will
     * be normalized, whereas getText() will
     * return unnormalized content in the case of nextToken(). This allows
     * an exact roundtrip without changing line ends when examining low
     * level events, whereas for high level applications the text is
     * normalized appropriately.
     *
     * @see #next
     * @see #nextToken
     * @see #getText
     */
    int TEXT = 4;

    // ----------------------------------------------------------------------------
    // additional events exposed by lower level nextToken()

    /**
     * A CDATA sections was just read;
     * this token is available only from calls to <a href="#nextToken()">nextToken()</a>.
     * A call to next() will accumulate various text events into a single event
     * of type TEXT. The text contained in the CDATA section is available
     * by calling getText().
     *
     * @see #nextToken
     * @see #getText
     */
    int CDSECT = 5;

    /**
     * An entity reference was just read;
     * this token is available from <a href="#nextToken()">nextToken()</a>
     * only. The entity name is available by calling getName(). If available,
     * the replacement text can be obtained by calling getText(); otherwise,
     * the user is responsible for resolving the entity reference.
     * This event type is never returned from next(); next() will
     * accumulate the replacement text and other text
     * events to a single TEXT event.
     *
     * @see #nextToken
     * @see #getText
     */
    int ENTITY_REF = 6;

    /**
     * Ignorable whitespace was just read.
     * This token is available only from <a href="#nextToken()">nextToken()</a>).
     * For non-validating
     * parsers, this event is only reported by nextToken() when outside
     * the root element.
     * Validating parsers may be able to detect ignorable whitespace at
     * other locations.
     * The ignorable whitespace string is available by calling getText()
     *
     * <p><strong>NOTE:</strong> this is different from calling the
     *  isWhitespace() method, since text content
     *  may be whitespace but not ignorable.
     *
     * Ignorable whitespace is skipped by next() automatically; this event
     * type is never returned from next().
     *
     * @see #nextToken
     * @see #getText
     */
    int IGNORABLE_WHITESPACE = 7;

    /**
     * An XML processing instruction declaration was just read. This
     * event type is available only via <a href="#nextToken()">nextToken()</a>.
     * getText() will return text that is inside the processing instruction.
     * Calls to next() will skip processing instructions automatically.
     * @see #nextToken
     * @see #getText
     */
    int PROCESSING_INSTRUCTION = 8;

    /**
     * An XML comment was just read. This event type is this token is
     * available via <a href="#nextToken()">nextToken()</a> only;
     * calls to next() will skip comments automatically.
     * The content of the comment can be accessed using the getText()
     * method.
     *
     * @see #nextToken
     * @see #getText
     */
    int COMMENT = 9;

    /**
     * An XML document type declaration was just read. This token is
     * available from <a href="#nextToken()">nextToken()</a> only.
     * The unparsed text inside the doctype is available via
     * the getText() method.
     *
     * @see #nextToken
     * @see #getText
     */
    int DOCDECL = 10;

    /**
     * This array can be used to convert the event type integer constants
     * such as START_TAG or TEXT to
     * to a string. For example, the value of TYPES[START_TAG] is
     * the string "START_TAG".
     *
     * This array is intended for diagnostic output only. Relying
     * on the contents of the array may be dangerous since malicious
     * applications may alter the array, although it is final, due
     * to limitations of the Java language.
     */
    String [] TYPES = {
        "START_DOCUMENT",
            "END_DOCUMENT",
            "START_TAG",
            "END_TAG",
            "TEXT",
            "CDSECT",
            "ENTITY_REF",
            "IGNORABLE_WHITESPACE",
            "PROCESSING_INSTRUCTION",
            "COMMENT",
            "DOCDECL"
    };


    // ----------------------------------------------------------------------------
    // namespace related features

    /**
     * This feature determines whether the parser processes
     * namespaces. As for all features, the default value is false.
     * <p><strong>NOTE:</strong> The value can not be changed during
     * parsing an must be set before parsing.
     *
     * @see #getFeature
     * @see #setFeature
     */
    String FEATURE_PROCESS_NAMESPACES =
        "http://xmlpull.org/v1/doc/features.html#process-namespaces";

    /**
     * This feature determines whether namespace attributes are
     * exposed via the attribute access methods. Like all features,
     * the default value is false. This feature cannot be changed
     * during parsing.
     *
     * @see #getFeature
     * @see #setFeature
     */
    String FEATURE_REPORT_NAMESPACE_ATTRIBUTES =
        "http://xmlpull.org/v1/doc/features.html#report-namespace-prefixes";

    /**
     * This feature determines whether the document declaration
     * is processed. If set to false,
     * the DOCDECL event type is reported by nextToken()
     * and ignored by next().
     *
     * If this feature is activated, then the document declaration
     * must be processed by the parser.
     *
     * <p><strong>Please note:</strong> If the document type declaration
     * was ignored, entity references may cause exceptions
     * later in the parsing process.
     * The default value of this feature is false. It cannot be changed
     * during parsing.
     *
     * @see #getFeature
     * @see #setFeature
     */
    String FEATURE_PROCESS_DOCDECL =
        "http://xmlpull.org/v1/doc/features.html#process-docdecl";

    /**
     * If this feature is activated, all validation errors as
     * defined in the XML 1.0 specification are reported.
     * This implies that FEATURE_PROCESS_DOCDECL is true and both, the
     * internal and external document type declaration will be processed.
     * <p><strong>Please Note:</strong> This feature can not be changed
     * during parsing. The default value is false.
     *
     * @see #getFeature
     * @see #setFeature
     */
    String FEATURE_VALIDATION =
        "http://xmlpull.org/v1/doc/features.html#validation";

    /**
     * Use this call to change the general behaviour of the parser,
     * such as namespace processing or doctype declaration handling.
     * This method must be called before the first call to next or
     * nextToken. Otherwise, an exception is thrown.
     * <p>Example: call setFeature(FEATURE_PROCESS_NAMESPACES, true) in order
     * to switch on namespace processing. The initial settings correspond
     * to the properties requested from the XML Pull Parser factory.
     * If none were requested, all features are deactivated by default.
     *
     * @exception XmlPullParserException If the feature is not supported or can not be set
     * @exception IllegalArgumentException If string with the feature name is null
     */
    void setFeature(String name,
                           boolean state) throws XmlPullParserException;

    /**
     * Returns the current value of the given feature.
     * <p><strong>Please note:</strong> unknown features are
     * <strong>always</strong> returned as false.
     *
     * @param name The name of feature to be retrieved.
     * @return The value of the feature.
     * @exception IllegalArgumentException if string the feature name is null
     */

    boolean getFeature(String name);

    /**
     * Set the value of a property.
     *
     * The property name is any fully-qualified URI.
     *
     * @exception XmlPullParserException If the property is not supported or can not be set
     * @exception IllegalArgumentException If string with the property name is null
     */
    void setProperty(String name,
                            Object value) throws XmlPullParserException;

    /**
     * Look up the value of a property.
     *
     * The property name is any fully-qualified URI.
     * <p><strong>NOTE:</strong> unknown properties are <strong>always</strong>
     * returned as null.
     *
     * @param name The name of property to be retrieved.
     * @return The value of named property.
     */
    Object getProperty(String name);


    /**
     * Set the input source for parser to the given reader and
     * resets the parser. The event type is set to the initial value
     * START_DOCUMENT.
     * Setting the reader to null will just stop parsing and
     * reset parser state,
     * allowing the parser to free internal resources
     * such as parsing buffers.
     */
    void setInput(Reader in) throws XmlPullParserException;


    /**
     * Sets the input stream the parser is going to process.
     * This call resets the parser state and sets the event type
     * to the initial value START_DOCUMENT.
     *
     * <p><strong>NOTE:</strong> If an input encoding string is passed,
     *  it MUST be used. Otherwise,
     *  if inputEncoding is null, the parser SHOULD try to determine
     *  input encoding following XML 1.0 specification (see below).
     *  If encoding detection is supported then following feature
     *  <a href="http://xmlpull.org/v1/doc/features.html#detect-encoding">http://xmlpull.org/v1/doc/features.html#detect-encoding</a>
     *  MUST be true amd otherwise it must be false
     *
     * @param inputStream contains a raw byte input stream of possibly
     *     unknown encoding (when inputEncoding is null).
     *
     * @param inputEncoding if not null it MUST be used as encoding for inputStream
     */
    void setInput(InputStream inputStream, String inputEncoding)
        throws XmlPullParserException;

    /**
     * Returns the input encoding if known, null otherwise.
     * If setInput(InputStream, inputEncoding) was called with an inputEncoding
     * value other than null, this value must be returned
     * from this method. Otherwise, if inputEncoding is null and
     * the parser supports the encoding detection feature
     * (http://xmlpull.org/v1/doc/features.html#detect-encoding),
     * it must return the detected encoding.
     * If setInput(Reader) was called, null is returned.
     * After first call to next if XML declaration was present this method
     * will return encoding declared.
     */
    String getInputEncoding();

    /**
     * Set new value for entity replacement text as defined in
     * <a href="http://www.w3.org/TR/REC-xml#intern-replacement">XML 1.0 Section 4.5
     * Construction of Internal Entity Replacement Text</a>.
     * If FEATURE_PROCESS_DOCDECL or FEATURE_VALIDATION are set, calling this
     * function will result in an exception -- when processing of DOCDECL is
     * enabled, there is no need to the entity replacement text manually.
     *
     * <p>The motivation for this function is to allow very small
     * implementations of XMLPULL that will work in J2ME environments.
     * Though these implementations may not be able to process the document type
     * declaration, they still can work with known DTDs by using this function.
     *
     * <p><b>Please notes:</b> The given value is used literally as replacement text
     * and it corresponds to declaring entity in DTD that has all special characters
     * escaped: left angle bracket is replaced with &amp;lt;, ampersand with &amp;amp;
     * and so on.
     *
     * <p><b>Note:</b> The given value is the literal replacement text and must not
     * contain any other entity reference (if it contains any entity reference
     * there will be no further replacement).
     *
     * <p><b>Note:</b> The list of pre-defined entity names will
     * always contain standard XML entities such as
     * amp (&amp;amp;), lt (&amp;lt;), gt (&amp;gt;), quot (&amp;quot;), and apos (&amp;apos;).
     * Those cannot be redefined by this method!
     *
     * @see #setInput
     * @see #FEATURE_PROCESS_DOCDECL
     * @see #FEATURE_VALIDATION
     */
    void defineEntityReplacementText( String entityName,
                                            String replacementText ) throws XmlPullParserException;

    /**
     * Returns the numbers of elements in the namespace stack for the given
     * depth.
     * If namespaces are not enabled, 0 is returned.
     *
     * <p><b>NOTE:</b> when parser is on END_TAG then it is allowed to call
     *  this function with getDepth()+1 argument to retrieve position of namespace
     *  prefixes and URIs that were declared on corresponding START_TAG.
     * <p><b>NOTE:</b> to retrieve list of namespaces declared in current element:<pre>
     *       XmlPullParser pp = ...
     *       int nsStart = pp.getNamespaceCount(pp.getDepth()-1);
     *       int nsEnd = pp.getNamespaceCount(pp.getDepth());
     *       for (int i = nsStart; i < nsEnd; i++) {
     *          String prefix = pp.getNamespacePrefix(i);
     *          String ns = pp.getNamespaceUri(i);
     *           // ...
     *      }
     * </pre>
     *
     * @see #getNamespacePrefix
     * @see #getNamespaceUri
     * @see #getNamespace()
     * @see #getNamespace(String)
     */
    int getNamespaceCount(int depth) throws XmlPullParserException;

    /**
     * Returns the namespace prefix for the given position
     * in the namespace stack.
     * Default namespace declaration (xmlns='...') will have null as prefix.
     * If the given index is out of range, an exception is thrown.
     * <p><b>Please note:</b> when the parser is on an END_TAG,
     * namespace prefixes that were declared
     * in the corresponding START_TAG are still accessible
     * although they are no longer in scope.
     */
    String getNamespacePrefix(int pos) throws XmlPullParserException;

    /**
     * Returns the namespace URI for the given position in the
     * namespace stack
     * If the position is out of range, an exception is thrown.
     * <p><b>NOTE:</b> when parser is on END_TAG then namespace prefixes that were declared
     *  in corresponding START_TAG are still accessible even though they are not in scope
     */
    String getNamespaceUri(int pos) throws XmlPullParserException;

    /**
     * Returns the URI corresponding to the given prefix,
     * depending on current state of the parser.
     *
     * <p>If the prefix was not declared in the current scope,
     * null is returned. The default namespace is included
     * in the namespace table and is available via
     * getNamespace (null).
     *
     * <p>This method is a convenience method for
     *
     * <pre>
     *  for (int i = getNamespaceCount(getDepth ())-1; i >= 0; i--) {
     *   if (getNamespacePrefix(i).equals( prefix )) {
     *     return getNamespaceUri(i);
     *   }
     *  }
     *  return null;
     * </pre>
     *
     * <p><strong>Please note:</strong> parser implementations
     * may provide more efficient lookup, e.g. using a Hashtable.
     * The 'xml' prefix is bound to "http://www.w3.org/XML/1998/namespace", as
     * defined in the
     * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in XML</a>
     * specification. Analogous, the 'xmlns' prefix is resolved to
     * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a>
     *
     * @see #getNamespaceCount
     * @see #getNamespacePrefix
     * @see #getNamespaceUri
     */
    String getNamespace (String prefix);


    // --------------------------------------------------------------------------
    // miscellaneous reporting methods

    /**
     * Returns the current depth of the element.
     * Outside the root element, the depth is 0. The
     * depth is incremented by 1 when a start tag is reached.
     * The depth is decremented AFTER the end tag
     * event was observed.
     *
     * <pre>
     * &lt;!-- outside --&gt;     0
     * &lt;root>                  1
     *   sometext                 1
     *     &lt;foobar&gt;         2
     *     &lt;/foobar&gt;        2
     * &lt;/root&gt;              1
     * &lt;!-- outside --&gt;     0
     * </pre>
     */
    int getDepth();

    /**
     * Returns a short text describing the current parser state, including
     * the position, a
     * description of the current event and the data source if known.
     * This method is especially useful to provide meaningful
     * error messages and for debugging purposes.
     */
    String getPositionDescription ();


    /**
     * Returns the current line number, starting from 1.
     * When the parser does not know the current line number
     * or can not determine it,  -1 is returned (e.g. for WBXML).
     *
     * @return current line number or -1 if unknown.
     */
    int getLineNumber();

    /**
     * Returns the current column number, starting from 0.
     * When the parser does not know the current column number
     * or can not determine it,  -1 is returned (e.g. for WBXML).
     *
     * @return current column number or -1 if unknown.
     */
    int getColumnNumber();


    // --------------------------------------------------------------------------
    // TEXT related methods

    /**
     * Checks whether the current TEXT event contains only whitespace
     * characters.
     * For IGNORABLE_WHITESPACE, this is always true.
     * For TEXT and CDSECT, false is returned when the current event text
     * contains at least one non-white space character. For any other
     * event type an exception is thrown.
     *
     * <p><b>Please note:</b> non-validating parsers are not
     * able to distinguish whitespace and ignorable whitespace,
     * except from whitespace outside the root element. Ignorable
     * whitespace is reported as separate event, which is exposed
     * via nextToken only.
     *
     */
    boolean isWhitespace() throws XmlPullParserException;

    /**
     * Returns the text content of the current event as String.
     * The value returned depends on current event type,
     * for example for TEXT event it is element content
     * (this is typical case when next() is used).
     *
     * See description of nextToken() for detailed description of
     * possible returned values for different types of events.
     *
     * <p><strong>NOTE:</strong> in case of ENTITY_REF, this method returns
     * the entity replacement text (or null if not available). This is
     * the only case where
     * getText() and getTextCharacters() return different values.
     *
     * @see #getEventType
     * @see #next
     * @see #nextToken
     */
    String getText ();


    /**
     * Returns the buffer that contains the text of the current event,
     * as well as the start offset and length relevant for the current
     * event. See getText(), next() and nextToken() for description of possible returned values.
     *
     * <p><strong>Please note:</strong> this buffer must not
     * be modified and its content MAY change after a call to
     * next() or nextToken(). This method will always return the
     * same value as getText(), except for ENTITY_REF. In the case
     * of ENTITY ref, getText() returns the replacement text and
     * this method returns the actual input buffer containing the
     * entity name.
     * If getText() returns null, this method returns null as well and
     * the values returned in the holder array MUST be -1 (both start
     * and length).
     *
     * @see #getText
     * @see #next
     * @see #nextToken
     *
     * @param holderForStartAndLength Must hold an 2-element int array
     * into which the start offset and length values will be written.
     * @return char buffer that contains the text of the current event
     *  (null if the current event has no text associated).
     */
    char[] getTextCharacters(int [] holderForStartAndLength);

    // --------------------------------------------------------------------------
    // START_TAG / END_TAG shared methods

    /**
     * Returns the namespace URI of the current element.
     * The default namespace is represented
     * as empty string.
     * If namespaces are not enabled, an empty String ("") is always returned.
     * The current event must be START_TAG or END_TAG; otherwise,
     * null is returned.
     */
    String getNamespace ();

    /**
     * For START_TAG or END_TAG events, the (local) name of the current
     * element is returned when namespaces are enabled. When namespace
     * processing is disabled, the raw name is returned.
     * For ENTITY_REF events, the entity name is returned.
     * If the current event is not START_TAG, END_TAG, or ENTITY_REF,
     * null is returned.
     * <p><b>Please note:</b> To reconstruct the raw element name
     *  when namespaces are enabled and the prefix is not null,
     * you will need to  add the prefix and a colon to localName..
     *
     */
    String getName();

    /**
     * Returns the prefix of the current element.
     * If the element is in the default namespace (has no prefix),
     * null is returned.
     * If namespaces are not enabled, or the current event
     * is not  START_TAG or END_TAG, null is returned.
     */
    String getPrefix();

    /**
     * Returns true if the current event is START_TAG and the tag
     * is degenerated
     * (e.g. &lt;foobar/&gt;).
     * <p><b>NOTE:</b> if the parser is not on START_TAG, an exception
     * will be thrown.
     */
    boolean isEmptyElementTag() throws XmlPullParserException;

    // --------------------------------------------------------------------------
    // START_TAG Attributes retrieval methods

    /**
     * Returns the number of attributes of the current start tag, or
     * -1 if the current event type is not START_TAG
     *
     * @see #getAttributeNamespace
     * @see #getAttributeName
     * @see #getAttributePrefix
     * @see #getAttributeValue
     */
    int getAttributeCount();

    /**
     * Returns the namespace URI of the attribute
     * with the given index (starts from 0).
     * Returns an empty string ("") if namespaces are not enabled
     * or the attribute has no namespace.
     * Throws an IndexOutOfBoundsException if the index is out of range
     * or the current event type is not START_TAG.
     *
     * <p><strong>NOTE:</strong> if FEATURE_REPORT_NAMESPACE_ATTRIBUTES is set
     * then namespace attributes (xmlns:ns='...') must be reported
     * with namespace
     * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a>
     * (visit this URL for description!).
     * The default namespace attribute (xmlns="...") will be reported with empty namespace.
     * <p><strong>NOTE:</strong>The xml prefix is bound as defined in
     * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in XML</a>
     * specification to "http://www.w3.org/XML/1998/namespace".
     *
     * @param index zero-based index of attribute
     * @return attribute namespace,
     *   empty string ("") is returned  if namespaces processing is not enabled or
     *   namespaces processing is enabled but attribute has no namespace (it has no prefix).
     */
    String getAttributeNamespace (int index);

    /**
     * Returns the local name of the specified attribute
     * if namespaces are enabled or just attribute name if namespaces are disabled.
     * Throws an IndexOutOfBoundsException if the index is out of range
     * or current event type is not START_TAG.
     *
     * @param index zero-based index of attribute
     * @return attribute name (null is never returned)
     */
    String getAttributeName (int index);

    /**
     * Returns the prefix of the specified attribute
     * Returns null if the element has no prefix.
     * If namespaces are disabled it will always return null.
     * Throws an IndexOutOfBoundsException if the index is out of range
     * or current event type is not START_TAG.
     *
     * @param index zero-based index of attribute
     * @return attribute prefix or null if namespaces processing is not enabled.
     */
    String getAttributePrefix(int index);

    /**
     * Returns the type of the specified attribute
     * If parser is non-validating it MUST return CDATA.
     *
     * @param index zero-based index of attribute
     * @return attribute type (null is never returned)
     */
    String getAttributeType(int index);

    /**
     * Returns if the specified attribute was not in input was declared in XML.
     * If parser is non-validating it MUST always return false.
     * This information is part of XML infoset:
     *
     * @param index zero-based index of attribute
     * @return false if attribute was in input
     */
    boolean isAttributeDefault(int index);

    /**
     * Returns the given attributes value.
     * Throws an IndexOutOfBoundsException if the index is out of range
     * or current event type is not START_TAG.
     *
     * <p><strong>NOTE:</strong> attribute value must be normalized
     * (including entity replacement text if PROCESS_DOCDECL is false) as described in
     * <a href="http://www.w3.org/TR/REC-xml#AVNormalize">XML 1.0 section
     * 3.3.3 Attribute-Value Normalization</a>
     *
     * @see #defineEntityReplacementText
     *
     * @param index zero-based index of attribute
     * @return value of attribute (null is never returned)
     */
    String getAttributeValue(int index);

    /**
     * Returns the attributes value identified by namespace URI and namespace localName.
     * If namespaces are disabled namespace must be null.
     * If current event type is not START_TAG then IndexOutOfBoundsException will be thrown.
     *
     * <p><strong>NOTE:</strong> attribute value must be normalized
     * (including entity replacement text if PROCESS_DOCDECL is false) as described in
     * <a href="http://www.w3.org/TR/REC-xml#AVNormalize">XML 1.0 section
     * 3.3.3 Attribute-Value Normalization</a>
     *
     * @see #defineEntityReplacementText
     *
     * @param namespace Namespace of the attribute if namespaces are enabled otherwise must be null
     * @param name If namespaces enabled local name of attribute otherwise just attribute name
     * @return value of attribute or null if attribute with given name does not exist
     */
    String getAttributeValue(String namespace,
                                    String name);

    // --------------------------------------------------------------------------
    // actual parsing methods

    /**
     * Returns the type of the current event (START_TAG, END_TAG, TEXT, etc.)
     *
     * @see #next()
     * @see #nextToken()
     */
    int getEventType()
        throws XmlPullParserException;

    /**
     * Get next parsing event - element content will be coalesced and only one
     * TEXT event must be returned for whole element content
     * (comments and processing instructions will be ignored and entity references
     * must be expanded or exception mus be thrown if entity reference can not be expanded).
     * If element content is empty (content is "") then no TEXT event will be reported.
     *
     * <p><b>NOTE:</b> empty element (such as &lt;tag/>) will be reported
     *  with  two separate events: START_TAG, END_TAG - it must be so to preserve
     *   parsing equivalency of empty element to &lt;tag>&lt;/tag>.
     *  (see isEmptyElementTag ())
     *
     * @see #isEmptyElementTag
     * @see #START_TAG
     * @see #TEXT
     * @see #END_TAG
     * @see #END_DOCUMENT
     */

    int next()
        throws XmlPullParserException, IOException;


    /**
     * This method works similarly to next() but will expose
     * additional event types (COMMENT, CDSECT, DOCDECL, ENTITY_REF, PROCESSING_INSTRUCTION, or
     * IGNORABLE_WHITESPACE) if they are available in input.
     *
     * <p>If special feature
     * <a href="http://xmlpull.org/v1/doc/features.html#xml-roundtrip">FEATURE_XML_ROUNDTRIP</a>
     * (identified by URI: http://xmlpull.org/v1/doc/features.html#xml-roundtrip)
     * is enabled it is possible to do XML document round trip ie. reproduce
     * exectly on output the XML input using getText():
     * returned content is always unnormalized (exactly as in input).
     * Otherwise returned content is end-of-line normalized as described
     * <a href="http://www.w3.org/TR/REC-xml#sec-line-ends">XML 1.0 End-of-Line Handling</a>
     * and. Also when this feature is enabled exact content of START_TAG, END_TAG,
     * DOCDECL and PROCESSING_INSTRUCTION is available.
     *
     * <p>Here is the list of tokens that can be  returned from nextToken()
     * and what getText() and getTextCharacters() returns:<dl>
     * <dt>START_DOCUMENT<dd>null
     * <dt>END_DOCUMENT<dd>null
     * <dt>START_TAG<dd>null unless FEATURE_XML_ROUNDTRIP
     *   enabled and then returns XML tag, ex: &lt;tag attr='val'>
     * <dt>END_TAG<dd>null unless FEATURE_XML_ROUNDTRIP
     *  id enabled and then returns XML tag, ex: &lt;/tag>
     * <dt>TEXT<dd>return element content.
     *  <br>Note: that element content may be delivered in multiple consecutive TEXT events.
     * <dt>IGNORABLE_WHITESPACE<dd>return characters that are determined to be ignorable white
     * space. If the FEATURE_XML_ROUNDTRIP is enabled all whitespace content outside root
     * element will always reported as IGNORABLE_WHITESPACE otherwise reporting is optional.
     *  <br>Note: that element content may be delivered in multiple consecutive IGNORABLE_WHITESPACE events.
     * <dt>CDSECT<dd>
     * return text <em>inside</em> CDATA
     *  (ex. 'fo&lt;o' from &lt;!CDATA[fo&lt;o]]>)
     * <dt>PROCESSING_INSTRUCTION<dd>
     *  if FEATURE_XML_ROUNDTRIP is true
     *  return exact PI content ex: 'pi foo' from &lt;?pi foo?>
     *  otherwise it may be exact PI content or concatenation of PI target,
     * space and data so for example for
     *   &lt;?target    data?> string &quot;target data&quot; may
     *       be returned if FEATURE_XML_ROUNDTRIP is false.
     * <dt>COMMENT<dd>return comment content ex. 'foo bar' from &lt;!--foo bar-->
     * <dt>ENTITY_REF<dd>getText() MUST return entity replacement text if PROCESS_DOCDECL is false
     * otherwise getText() MAY return null,
     * additionally getTextCharacters() MUST return entity name
     * (for example 'entity_name' for &amp;entity_name;).
     * <br><b>NOTE:</b> this is the only place where value returned from getText() and
     *   getTextCharacters() <b>are different</b>
     * <br><b>NOTE:</b> it is user responsibility to resolve entity reference
     *    if PROCESS_DOCDECL is false and there is no entity replacement text set in
     *    defineEntityReplacementText() method (getText() will be null)
     * <br><b>NOTE:</b> character entities (ex. &amp;#32;) and standard entities such as
     *  &amp;amp; &amp;lt; &amp;gt; &amp;quot; &amp;apos; are reported as well
     *  and are <b>not</b> reported as TEXT tokens but as ENTITY_REF tokens!
     *  This requirement is added to allow to do roundtrip of XML documents!
     * <dt>DOCDECL<dd>
     * if FEATURE_XML_ROUNDTRIP is true or PROCESS_DOCDECL is false
     * then return what is inside of DOCDECL for example it returns:<pre>
     * &quot; titlepage SYSTEM "http://www.foo.bar/dtds/typo.dtd"
     * [&lt;!ENTITY % active.links "INCLUDE">]&quot;</pre>
     * <p>for input document that contained:<pre>
     * &lt;!DOCTYPE titlepage SYSTEM "http://www.foo.bar/dtds/typo.dtd"
     * [&lt;!ENTITY % active.links "INCLUDE">]></pre>
     * otherwise if FEATURE_XML_ROUNDTRIP is false and PROCESS_DOCDECL is true
     *    then what is returned is undefined (it may be even null)
     * </dd>
     * </dl>
     *
     * <p><strong>NOTE:</strong> there is no guarantee that there will only one TEXT or
     * IGNORABLE_WHITESPACE event from nextToken() as parser may chose to deliver element content in
     * multiple tokens (dividing element content into chunks)
     *
     * <p><strong>NOTE:</strong> whether returned text of token is end-of-line normalized
     *  is depending on FEATURE_XML_ROUNDTRIP.
     *
     * <p><strong>NOTE:</strong> XMLDecl (&lt;?xml ...?&gt;) is not reported but its content
     * is available through optional properties (see class description above).
     *
     * @see #next
     * @see #START_TAG
     * @see #TEXT
     * @see #END_TAG
     * @see #END_DOCUMENT
     * @see #COMMENT
     * @see #DOCDECL
     * @see #PROCESSING_INSTRUCTION
     * @see #ENTITY_REF
     * @see #IGNORABLE_WHITESPACE
     */
    int nextToken()
        throws XmlPullParserException, IOException;

    //-----------------------------------------------------------------------------
    // utility methods to mak XML parsing easier ...

    /**
     * Test if the current event is of the given type and if the
     * namespace and name do match. null will match any namespace
     * and any name. If the test is not passed, an exception is
     * thrown. The exception text indicates the parser position,
     * the expected event and the current event that is not meeting the
     * requirement.
     *
     * <p>Essentially it does this
     * <pre>
     *  if (type != getEventType()
     *  || (namespace != null &amp;&amp;  !namespace.equals( getNamespace () ) )
     *  || (name != null &amp;&amp;  !name.equals( getName() ) ) )
     *     throw new XmlPullParserException( "expected "+ TYPES[ type ]+getPositionDescription());
     * </pre>
     */
    void require(int type, String namespace, String name)
        throws XmlPullParserException, IOException;

    /**
     * If current event is START_TAG then if next element is TEXT then element content is returned
     * or if next event is END_TAG then empty string is returned, otherwise exception is thrown.
     * After calling this function successfully parser will be positioned on END_TAG.
     *
     * <p>The motivation for this function is to allow to parse consistently both
     * empty elements and elements that has non empty content, for example for input: <ol>
     * <li>&lt;tag&gt;foo&lt;/tag&gt;
     * <li>&lt;tag&gt;&lt;/tag&gt; (which is equivalent to &lt;tag/&gt;
     * both input can be parsed with the same code:
     * <pre>
     *   p.nextTag()
     *   p.requireEvent(p.START_TAG, "", "tag");
     *   String content = p.nextText();
     *   p.requireEvent(p.END_TAG, "", "tag");
     * </pre>
     * This function together with nextTag make it very easy to parse XML that has
     * no mixed content.
     *
     *
     * <p>Essentially it does this
     * <pre>
     *  if(getEventType() != START_TAG) {
     *     throw new XmlPullParserException(
     *       "parser must be on START_TAG to read next text", this, null);
     *  }
     *  int eventType = next();
     *  if(eventType == TEXT) {
     *     String result = getText();
     *     eventType = next();
     *     if(eventType != END_TAG) {
     *       throw new XmlPullParserException(
     *          "event TEXT it must be immediately followed by END_TAG", this, null);
     *      }
     *      return result;
     *  } else if(eventType == END_TAG) {
     *     return "";
     *  } else {
     *     throw new XmlPullParserException(
     *       "parser must be on START_TAG or TEXT to read text", this, null);
     *  }
     * </pre>
     *
     * <p><strong>Warning:</strong> Prior to API level 14, the pull parser returned by {@code
     * android.util.Xml} did not always advance to the END_TAG event when this method was called.
     * Work around by using manually advancing after calls to nextText(): <pre>
     *  String text = xpp.nextText();
     *  if (xpp.getEventType() != XmlPullParser.END_TAG) {
     *      xpp.next();
     *  }
     * </pre>
     */
    String nextText() throws XmlPullParserException, IOException;

    /**
     * Call next() and return event if it is START_TAG or END_TAG
     * otherwise throw an exception.
     * It will skip whitespace TEXT before actual tag if any.
     *
     * <p>essentially it does this
     * <pre>
     *   int eventType = next();
     *   if(eventType == TEXT &amp;&amp;  isWhitespace()) {   // skip whitespace
     *      eventType = next();
     *   }
     *   if (eventType != START_TAG &amp;&amp;  eventType != END_TAG) {
     *      throw new XmlPullParserException("expected start or end tag", this, null);
     *   }
     *   return eventType;
     * </pre>
     */
    int nextTag() throws XmlPullParserException, IOException;

}
