/* -*-             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 must 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;

}
