/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans;

import javax.xml.namespace.QName;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Map;

/**
 * Represents a position between two logical tokens in an XML document.
 * <p>
 * The tokens themselves are not exposed as objects, but their type and properties
 * are discoverable through methods on the cursor.  In particular, the general
 * category of token is represented by a {@link XmlCursor.TokenType TokenType}.
 * <p>
 * You use an XmlCursor instance to navigate through and manipulate an XML
 * instance document.
 * Once you obtain an XML document, you can create a cursor to represent
 * a specific place in the XML. Because you can use a cursor with or
 * without a schema corresponding to the XML, cursors are an ideal
 * way to handle XML without a schema. You can create a new cursor by
 * calling the {@link XmlTokenSource#newCursor() newCursor} method
 * exposed by an object representing
 * the XML, whether it was parsed into a strong type compiled from
 * schema or an {@link XmlObject XmlObject} (as in the no-schema case).
 * <p>
 * With an XmlCursor, you can also:
 *
 * <ul>
 * <li>Execute XQuery and XPath expressions against the XML with the
 * execQuery and selectPath methods.</li>
 *
 * <li>Edit and reshape the document by inserting, moving, copying, and removing
 * XML.</li>
 *
 * <li>Insert bookmarks that "stick" to the XML at the cursor's
 * position even if the cursor or XML moves.</li>
 *
 * <li>Get and set values for containers (elements and whole documents),
 * attributes, processing instructions, and comments.</li>
 * </ul>
 * <p>
 * A cursor moves through XML by moving past tokens. A
 * token represents a category of XML markup, such as the start of an element,
 * its end, an attribute, comment, and so on. XmlCursor methods such as
 * toNextToken, toNextSibling, toParent, and so on move the cursor
 * among tokens. Each token's category is of a particular <em>type</em>, represented
 * by one of the nine types defined by the {@link XmlCursor.TokenType TokenType} class.
 * <p>
 * When you get a new cursor for a whole instance document, the cursor is
 * intially located before the STARTDOC token. This token, which has no analogy
 * in the XML specification, is present in this logical model of XML
 * so that you may distinguish between the document as a whole
 * and the content of the document. Terminating the document is an ENDDOC
 * token. This token is also not part of the XML specification. A cursor
 * located immediately before this token is at the very end of the document.
 * It is not possible to position the cursor after the ENDDOC token.
 * Thus, the STARTDOC and ENDDOC tokens are effectively "bookends" for the content of
 * the document.
 * <p>
 * For example, for the following XML, if you were the navigate a cursor
 * through the XML document using toNextToken(), the list of token types that
 * follows represents the token sequence you would encounter.
 *
 * <pre>
 * &lt;sample x='y'&gt;
 *     &lt;value&gt;foo&lt;/value&gt;
 * &lt;/sample&gt;
 * </pre>
 * <p>
 * STARTDOC <br>
 * START (sample) <br>
 * ATTR (x='y') <br>
 * TEXT ("\n    ") <br>
 * START (value) <br>
 * TEXT ("foo") <br>
 * END (value) <br>
 * TEXT ("\n") <br>
 * END (sample)<br>
 * ENDDOC
 * <p>
 * When there are no more tokens available, hasNextToken() returns
 * false and toNextToken() returns the special token type NONE and does not move
 * the cursor.
 *
 * <p>
 * The {@link #currentTokenType() currentTokenType()} method
 * will return the type of the token that is immediately after the cursor.
 * You can also use a number of convenience methods that test for a particular
 * token type. These include the methods isStart(),
 * isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean
 * value indicating whether the token that follows the cursor is the type
 * in question.
 *
 * <p>
 * A few other methods determine whether the token is of a kind that may include
 * multiple token types. The isAnyAttr() method, for example, returns true if
 * the token immediately following the cursor is any kind of attribute,
 * including those of the ATTR token type and xmlns attributes.
 *
 * <p>
 * Legitimate sequences of tokens for an XML document are described
 * by the following Backus-Naur Form (BNF): <br>
 *
 * <pre>
 * &lt;doc&gt; ::= STARTDOC &lt;attributes&gt; &lt;content&gt; ENDDOC
 * &lt;element&gt; ::= START &lt;attributes&gt; &lt;content&gt; END
 * &lt;attributes&gt; ::= ( ATTR | NAMESPACE ) *
 * &lt;content&gt; ::= ( COMMENT | PROCINST | TEXT | &lt;element&gt; ) *
 * </pre>
 * <p>
 * Note that a legitimate sequence is STARTDOC ENDDOC, the result of
 * creating a brand new instance of an empty document. Also note that
 * attributes may only follow container tokens (STARTDOC or START)
 */
public interface XmlCursor extends XmlTokenSource, AutoCloseable {
    /**
     * An enumeration that identifies the type of an XML token.
     */
    public static final class TokenType {
        public String toString() {
            return _name;
        }

        /**
         * Returns one of the INT_ values defined in this class.
         */
        public int intValue() {
            return _value;
        }

        /**
         * No token.  See {@link #intValue}.
         */
        public static final int INT_NONE = 0;
        /**
         * The start-document token.  See {@link #intValue}.
         */
        public static final int INT_STARTDOC = 1;
        /**
         * The end-document token.  See {@link #intValue}.
         */
        public static final int INT_ENDDOC = 2;
        /**
         * The start-element token.  See {@link #intValue}.
         */
        public static final int INT_START = 3;
        /**
         * The end-element token.  See {@link #intValue}.
         */
        public static final int INT_END = 4;
        /**
         * The text token.  See {@link #intValue}.
         */
        public static final int INT_TEXT = 5;
        /**
         * The attribute token.  See {@link #intValue}.
         */
        public static final int INT_ATTR = 6;
        /**
         * The namespace declaration token.  See {@link #intValue}.
         */
        public static final int INT_NAMESPACE = 7;
        /**
         * The comment token.  See {@link #intValue}.
         */
        public static final int INT_COMMENT = 8;
        /**
         * The processing instruction token.  See {@link #intValue}.
         */
        public static final int INT_PROCINST = 9;

        /**
         * True if no token.
         */
        public boolean isNone() {
            return this == NONE;
        }

        /**
         * True if is start-document token.
         */
        public boolean isStartdoc() {
            return this == STARTDOC;
        }

        /**
         * True if is end-document token.
         */
        public boolean isEnddoc() {
            return this == ENDDOC;
        }

        /**
         * True if is start-element token.
         */
        public boolean isStart() {
            return this == START;
        }

        /**
         * True if is end-element token.
         */
        public boolean isEnd() {
            return this == END;
        }

        /**
         * True if is text token.
         */
        public boolean isText() {
            return this == TEXT;
        }

        /**
         * True if is attribute token.
         */
        public boolean isAttr() {
            return this == ATTR;
        }

        /**
         * True if is namespace declaration token.
         */
        public boolean isNamespace() {
            return this == NAMESPACE;
        }

        /**
         * True if is comment token.
         */
        public boolean isComment() {
            return this == COMMENT;
        }

        /**
         * True if is processing instruction token.
         */
        public boolean isProcinst() {
            return this == PROCINST;
        }

        /**
         * True if is start-document or start-element token
         */
        public boolean isContainer() {
            return this == STARTDOC || this == START;
        }

        /**
         * True if is end-document or end-element token
         */
        public boolean isFinish() {
            return this == ENDDOC || this == END;
        }

        /**
         * True if is attribute or namespace declaration token
         */
        public boolean isAnyAttr() {
            return this == NAMESPACE || this == ATTR;
        }

        /**
         * The singleton no-token type
         */
        public static final TokenType NONE = new TokenType("NONE", INT_NONE);
        /**
         * The singleton start-document token type
         */
        public static final TokenType STARTDOC = new TokenType("STARTDOC", INT_STARTDOC);
        /**
         * The singleton start-document token type
         */
        public static final TokenType ENDDOC = new TokenType("ENDDOC", INT_ENDDOC);
        /**
         * The singleton start-element token type
         */
        public static final TokenType START = new TokenType("START", INT_START);
        /**
         * The singleton end-element token type
         */
        public static final TokenType END = new TokenType("END", INT_END);
        /**
         * The singleton text token type
         */
        public static final TokenType TEXT = new TokenType("TEXT", INT_TEXT);
        /**
         * The singleton attribute token type
         */
        public static final TokenType ATTR = new TokenType("ATTR", INT_ATTR);
        /**
         * The singleton namespace declaration token type
         */
        public static final TokenType NAMESPACE = new TokenType("NAMESPACE", INT_NAMESPACE);
        /**
         * The singleton comment token type
         */
        public static final TokenType COMMENT = new TokenType("COMMENT", INT_COMMENT);
        /**
         * The singleton processing instruction token type
         */
        public static final TokenType PROCINST = new TokenType("PROCINST", INT_PROCINST);

        private TokenType(String name, int value) {
            _name = name;
            _value = value;
        }

        private String _name;
        private int _value;
    }

    /**
     * Deallocates resources needed to manage the cursor, rendering this cursor
     * inoperable. Because cursors are managed by a mechanism which stores the
     * XML, simply letting a cursor go out of scope and having the garbage collector
     * attempt to reclaim it may not produce desirable performance.
     * <p>
     * So, explicitly disposing a cursor allows the underlying implementation
     * to release its responsibility of maintaining its position.
     * <p>
     * After a cursor has been closed, it may not be used again.  It can
     * throw IllegalStateException or NullPointerException if used after
     * disposal.
     * <p>
     * XmlCursor implements <code>java.lang.AutoCloseable</code> and the
     * try-with-resources pattern is recommended.
     * <p>
     * Note: Future major release will remove this default implementation.
     */

    default void close() {
        this.dispose();
    }

    /**
     * Deallocates resources needed to manage the cursor. For details see
     * {@link #close()}. XmlCursor implements <code>java.lang.AutoCloseable</code>
     * and the try-with-resources pattern is recommended.
     *
     * @see #close()
     */

    @Deprecated
    void dispose();

    /**
     * Moves this cursor to the same position as the moveTo cursor.  if the
     * moveTo cursor is in a different document from this cursor, this cursor
     * will not be moved, and false returned.
     *
     * @param moveTo The cursor at the location to which this cursor
     *               should be moved.
     * @return true if the cursor moved; otherwise, false.
     */

    boolean toCursor(XmlCursor moveTo);

    /**
     * Saves the current location of this cursor on an internal stack of saved
     * positions (independent of selection). This location may be restored
     * later by calling the pop() method.
     */

    void push();

    /**
     * Restores the cursor location most recently saved with the push() method.
     *
     * @return true if there was a location to restore; otherwise, false.
     */

    boolean pop();

    /**
     * Executes the specified XPath expression against the XML that this
     * cursor is in.  The cursor's position does not change.  To navigate to the
     * selections, use {@link #hasNextSelection} and {@link #toNextSelection} (similar to
     * {@link java.util.Iterator}).
     * <p>
     * The root referred to by the expression should be given as
     * a dot. The following is an example path expression:
     * <pre>
     * cursor.selectPath("./purchase-order/line-item");
     * </pre>
     * <p>
     * Note that this method does not support top-level XPath functions.
     *
     * @param path The path expression to execute.
     * @throws XmlRuntimeException If the query expression is invalid.
     */
    void selectPath(String path);

    /**
     * Executes the specified XPath expression against the XML that this
     * cursor is in. The cursor's position does not change.  To navigate to the
     * selections, use hasNextSelection and toNextSelection (similar to
     * java.util.Iterator).
     * <p>
     * The root referred to by the expression should be given as
     * a dot. The following is an example path expression:
     * <pre>
     * cursor.selectPath("./purchase-order/line-item");
     * </pre>
     * <p>
     * Note that this method does not support top-level XPath functions.
     *
     * @param path    The path expression to execute.
     * @param options Options for the query. For example, you can call
     *                the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)}
     *                method to specify a particular name for the query expression
     *                variable that indicates the context node.
     * @throws XmlRuntimeException If the query expression is invalid.
     */
    void selectPath(String path, XmlOptions options);

    /**
     * Returns whether or not there is a next selection.
     *
     * @return true if there is a next selection; otherwise, false.
     */

    boolean hasNextSelection();

    /**
     * Moves this cursor to the next location in the selection,
     * if any. See the {@link #selectPath} and {@link #addToSelection} methods.
     *
     * @return true if the cursor moved; otherwise, false.
     */

    boolean toNextSelection();

    /**
     * Moves this cursor to the specified location in the selection.
     * If i is less than zero or greater than or equal to the selection
     * count, this method returns false.
     * <p>
     * See also the selectPath() and addToSelection() methods.
     *
     * @param i The index of the desired location.
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toSelection(int i);

    /**
     * Returns the count of the current selection. See also the selectPath()
     * and addToSelection() methods.
     * <p>
     * You may experience better performance if you use the iteration
     * model using the toNextSelection method, rather than
     * the indexing model using the getSelectionCount and
     * toSelection methods.
     *
     * @return A number indicating the size of the current selection.
     */

    int getSelectionCount();


    /**
     * Appends the current location of the cursor to the selection.
     * See also the selectPath() method. You can use this as an
     * alternative to calling the selectPath method when you want
     * to define your own selection.
     */

    void addToSelection();

    /**
     * Clears this cursor's selection, but does not modify the document.
     */
    void clearSelections();

    /**
     * Moves this cursor to the same position as the bookmark.  If the
     * bookmark is in a different document from this cursor or if the
     * bookmark is orphaned, this cursor
     * will not be moved, and false will be returned.
     *
     * @param bookmark The bookmark at the location to which this
     *                 cursor should be moved.
     * @return true if the cursor moved; otherwise, false.
     */

    boolean toBookmark(XmlBookmark bookmark);

    /**
     * Moves this cursor to the location after its current position
     * where a bookmark with the given key exists.  Returns false if no
     * such bookmark exists.
     *
     * @param key The key held by the next bookmark at the location to
     *            which this cursor should be moved.
     * @return The next corresponding bookmark, if it exists; null if there
     * is no next bookmark with the specified key.
     */

    XmlBookmark toNextBookmark(Object key);

    /**
     * Moves this cursor to the location before its current position
     * where a bookmark with the given key exists.  Returns false if no
     * such bookmark exists.
     *
     * @param key The key held by the previous bookmark at the location to
     *            which this cursor should be moved.
     * @return The previous corresponding bookmark, if it exists; null if
     * there is no previous bookmark with the specified key.
     */

    XmlBookmark toPrevBookmark(Object key);

    /**
     * Returns the name of the current token. Names may be associated with
     * START, ATTR, NAMESPACE or PROCINST. Returns null if there is no
     * name associated with the current token. For START and ATTR, the
     * name returned identifies the name of the element or attribute.
     * For NAMESPACE, the local part of the name is the prefix, while
     * the URI is the namespace defined. For PROCINST, the local part
     * is the target and the uri is "".
     * <p>
     * In the following example, {@code xmlObject} represents
     * an XML instance whose root element is not preceded by any other XML.
     * This code prints the root element name (here, the local name, or
     * name without URI).
     * <pre>
     * XmlCursor cursor = xmlObject.newCursor();
     * cursor.toFirstContentToken();
     * String elementName = cursor.getName().getLocalPart();
     * System.out.println(elementName);
     * </pre>
     *
     * @return The name of the XML at this cursor's location; null if there
     * is no name.
     */

    QName getName();

    /**
     * Sets the name of the current token. This token can be START, NAMESPACE,
     * ATTR or PROCINST.
     *
     * @param name The new name for the current token.
     */

    void setName(QName name);

    /**
     * Returns the namespace URI indicated by the given prefix. The current
     * context must be at a START or STARTDOC. Namespace prefix mappings
     * are queried for the mappings defined at the current container first,
     * then parents are queried. The prefix can be "" or null to indicate
     * a search for the default namespace.  To conform with the
     * XML spec, the default namespace will return the no-namespace ("")
     * if it is not mapped.
     * <p>
     * Note that this queries the current state of the document. When the
     * document is persisted, the saving mechanism may synthesize namespaces
     * (ns1, ns2, and so on) for the purposes of persistence. These namepaces are
     * only present in the serialized form, and are not reflected back into
     * the document being saved.
     *
     * @param prefix The namespace prefix for the requested namespace.
     * @return The URI for corresponding to the specified prefix if it
     * exists; otherwise, null.
     */
    String namespaceForPrefix(String prefix);

    /**
     * Returns a prefix that can be used to indicate a namespace URI.  The
     * current context must be at a START or STARTDOC.  If there is an
     * existing prefix that indicates the URI in the current context, that
     * prefix may be returned. Otherwise, a new prefix for the URI will be
     * defined by adding an xmlns attribute to the current container or a
     * parent container.
     * <p>
     * Note that this queries the current state of the document. When the
     * document is persisted, the saving mechanism may synthesize namespaces
     * (ns1, ns2, and so on) for the purposes of persistence. These namepaces are
     * only present in the serialized form, and are not reflected back into
     * the document being saved.
     *
     * @param namespaceURI The namespace URI corresponding to the requested
     *                     prefix.
     * @return The prefix corresponding to the specified URI if it exists;
     * otherwise, a newly generated prefix.
     */
    String prefixForNamespace(String namespaceURI);

    /**
     * Adds to the specified map, all the namespaces in scope at the container
     * where this cursor is positioned. This method is useful for
     * container tokens only.
     *
     * @param addToThis The Map to add the namespaces to.
     */

    void getAllNamespaces(Map<String, String> addToThis);

    /**
     * Returns the strongly-typed XmlObject at the current START,
     * STARTDOC, or ATTR.
     * <p>
     * The strongly-typed object can be cast to the strongly-typed
     * XBean interface corresponding to the XML Schema Type given
     * by result.getSchemaType().
     * <p>
     * If a more specific type cannot be determined, an XmlObject
     * whose schema type is anyType will be returned.
     *
     * @return The strongly-typed object at the cursor's current location;
     * null if the current location is not a START, STARTDOC, or ATTR.
     */

    XmlObject getObject();

    /**
     * Returns the type of the current token. By definition, the current
     * token is the token immediately to the right of the cursor.
     * If you're in the middle of text, before a character, you get TEXT.
     * You can't dive into the text of an ATTR, COMMENT or PROCINST.
     * <p>
     * As an alternative, it may be more convenient for you to use one of the
     * methods that test for a particular token type. These include the methods
     * isStart(), isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean
     * value indicating whether the token that follows the cursor is the type
     * in question.
     *
     *
     * @return The TokenType instance for the token at the cursor's current
     * location.
     */

    TokenType currentTokenType();

    /**
     * True if the current token is a STARTDOC token type, meaning
     * at the very root of the document.
     *
     * @return true if this token is a STARTDOC token type;
     * otherwise, false.
     */

    boolean isStartdoc();

    /**
     * True if this token is an ENDDOC token type, meaning
     * at the very end of the document.
     *
     * @return true if this token is an ENDDOC token type;
     * otherwise, false.
     */

    boolean isEnddoc();

    /**
     * True if this token is a START token type, meaning
     * just before an element's start.
     *
     * @return true if this token is a START token type;
     * otherwise, false.
     */

    boolean isStart();

    /**
     * True if this token is an END token type, meaning
     * just before an element's end.
     *
     * @return true if this token is an END token type;
     * otherwise, false.
     */

    boolean isEnd();

    /**
     * True if the this token is a TEXT token type, meaning
     * just before or inside text.
     *
     * @return true if this token is a TEXT token type;
     * otherwise, false.
     */

    boolean isText();

    /**
     * True if this token is an ATTR token type, meaning
     * just before an attribute.
     *
     * @return true if this token is an ATTR token type;
     * otherwise, false.
     */

    boolean isAttr();

    /**
     * True if this token is a NAMESPACE token type, meaning
     * just before a namespace declaration.
     *
     * @return true if this token is a NAMESPACE token type;
     * otherwise, false.
     */

    boolean isNamespace();

    /**
     * True if this token is a COMMENT token type, meaning
     * just before a comment.
     *
     * @return true if this token is a COMMENT token type;
     * otherwise, false.
     */

    boolean isComment();

    /**
     * True if this token is a PROCINST token type, meaning
     * just before a processing instruction.
     *
     * @return true if this token is a PROCINST token type;
     * otherwise, false.
     */

    boolean isProcinst();

    /**
     * True if this token is a container token. The STARTDOC and START
     * token types are containers. Containers, including documents and elements,
     * have the same content model. In other words, a document and an element
     * may have the same contents. For example, a document may contain attributes
     * or text, without any child elements.
     *
     * @return true if this token is a container token; otherwise, false.
     */

    boolean isContainer();

    /**
     * True if this token is a finish token. A finish token can be an ENDDOC
     * or END token type.
     *
     * @return true if this token is a finish token; otherwise, false.
     */

    boolean isFinish();

    /**
     * True if this token is any attribute. This includes an ATTR token type and
     * the NAMESPACE token type attribute.
     *
     * @return true if the current cursor is at any attribute; otherwise, false.
     */

    boolean isAnyAttr();

    /**
     * Returns the type of the previous token. By definition, the previous
     * token is the token immediately to the left of the cursor.
     * <p>
     * If you're in the middle of text, after a character, you get TEXT.
     *
     * @return The TokenType instance for the token immediately before the
     * token at the cursor's current location.
     */

    TokenType prevTokenType();

    /**
     * True if there is a next token. When this is false, as when the cursor is
     * at the ENDDOC token, the toNextToken() method returns NONE and does not
     * move the cursor.
     *
     * @return true if there is a next token; otherwise, false.
     */

    boolean hasNextToken();


    /**
     * True if there is a previous token. When this is false, toPrevToken
     * returns NONE and does not move the cursor.
     *
     * @return true if there is a previous token; otherwise, false.
     */

    boolean hasPrevToken();

    /**
     * Moves the cursor to the next token. When there are no more tokens
     * available, hasNextToken returns false and toNextToken() returns
     * NONE and does not move the cursor. Returns the token type
     * of the token to the right of the cursor upon a successful move.
     *
     * @return The token type for the next token if the cursor was moved;
     * otherwise, NONE.
     */

    TokenType toNextToken();

    /**
     * Moves the cursor to the previous token. When there is no
     * previous token, returns NONE, otherwise returns the token
     * to the left of the new position of the cursor.
     *
     * @return The token type for the previous token if the cursor was moved;
     * otherwise, NONE.
     */

    TokenType toPrevToken();

    /**
     * Moves the cursor to the first token in the content of the current
     * START or STARTDOC. That is, the first token after all ATTR and NAMESPACE
     * tokens associated with this START.
     * <p>
     * If the current token is not a START or STARTDOC, the cursor is not
     * moved and NONE is returned. If the current START or STARTDOC
     * has no content, the cursor is moved to the END or ENDDOC token.
     *
     * @return The new current token type.
     */

    TokenType toFirstContentToken();


    /**
     * Moves the cursor to the END or ENDDOC token corresponding to the
     * current START or STARTDOC, and returns END or ENDDOC.
     * <p>
     * If the current token is not a START or STARTDOC, the cursor is not
     * moved and NONE is returned.
     *
     * @return The new current token type.
     */

    TokenType toEndToken();

    /**
     * Moves the cursor forward by the specified number of characters, and
     * stops at the next non-TEXT token. Returns the number of characters
     * actually moved across, which is guaranteed to be less than or equal to
     * <em>maxCharacterCount</em>. If there is no further text, or if
     * there is no text at all, returns zero.
     * <p>
     * Note this does not dive into attribute values, comment contents,
     * processing instruction contents, etc., but only content text.
     * <p>
     * You can pass maxCharacterCount &lt; 0 to move over all the text to the
     * right. This has the same effect as toNextToken, but returns the amount
     * of text moved over.
     *
     * @param maxCharacterCount The maximum number of characters by which
     *                          the cursor should be moved.
     * @return The actual number of characters by which the cursor was moved;
     * 0 if the cursor was not moved.
     */

    int toNextChar(int maxCharacterCount);

    /**
     * Moves the cursor backwards by the number of characters given.  Has
     * similar characteristics to the {@link #toNextChar(int) toNextChar} method.
     *
     * @param maxCharacterCount The maximum number of characters by which
     *                          the cursor should be moved.
     * @return The actual number of characters by which the cursor was moved;
     * 0 if the cursor was not moved.
     */

    int toPrevChar(int maxCharacterCount);

    /**
     * Moves the cursor to the next sibling element, or returns
     * false and does not move the cursor if there is no next sibling
     * element. (By definition the position of an element is the same
     * as the position of its START token.)
     * <p>
     * If the current token is not s START, the cursor will be
     * moved to the next START without moving out of the scope of the
     * current element.
     *
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toNextSibling();

    /**
     * Moves the cursor to the previous sibling element, or returns
     * false and does not move the cursor if there is no previous sibling
     * element. (By definition the position of an element is the same
     * as the position of its START token.)
     *
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toPrevSibling();

    /**
     * Moves the cursor to the parent element or STARTDOC, or returns
     * false and does not move the cursor if there is no parent.
     * <p>
     * Works if you're in attributes or content. Returns false only if at
     * STARTDOC. Note that the parent of an END token is the corresponding
     * START token.
     *
     * @return true if the cursor was moved; false if the cursor is at the STARTDOC
     * token.
     */

    boolean toParent();

    /**
     * Moves the cursor to the first child element, or returns false and
     * does not move the cursor if there are no element children.
     * <p>
     * If the cursor is not currently in an element, it moves into the
     * first child element of the next element.
     *
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toFirstChild();

    /**
     * Moves the cursor to the last element child, or returns false and
     * does not move the cursor if there are no element children.
     *
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toLastChild();

    /**
     * Moves the cursor to the first child element of the specified name in
     * no namespace.
     *
     * @param name The name of the element to move the cursor to.
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toChild(String name);

    /**
     * Moves the cursor to the first child element of the specified name in the
     * specified namespace.
     *
     * @param namespace The namespace URI for the element to move the cursor
     *                  to.
     * @param name      The name of the element to move to.
     * @return true if the cursor was moved; otherwise, false.
     * @throws IllegalArgumentException If the name is not a valid local name.
     */

    boolean toChild(String namespace, String name);

    /**
     * Moves the cursor to the first child element of the specified qualified name.
     *
     * @param name The name of the element to move the cursor to.
     */

    boolean toChild(QName name);

    /**
     * Moves the cursor to the child element specified by <em>index</em>.
     *
     * @param index The position of the element in the sequence of child
     *              elements.
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toChild(int index);

    /**
     * Moves the cursor to the specified <em>index</em> child element of the
     * specified name, where that element is the .
     *
     * @param name  The name of the child element to move the cursor to.
     * @param index The position of the element in the sequence of child
     *              elements.
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toChild(QName name, int index);

    /**
     * Moves the cursor to the next sibling element of the specified name in no
     * namespace.
     *
     * @param name The name of the element to move the cursor to.
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toNextSibling(String name);

    /**
     * Moves the cursor to the next sibling element of the specified name
     * in the specified namespace.
     *
     * @param namespace The namespace URI for the element to move the cursor
     *                  to.
     * @param name      The name of the element to move the cursor to.
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toNextSibling(String namespace, String name);


    /**
     * Moves the cursor to the next sibling element of the specified
     * qualified name.
     *
     * @param name The name of the element to move the cursor to.
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toNextSibling(QName name);

    /**
     * Moves the cursor to the first attribute of this element, or
     * returns false and does not move the cursor if there are no
     * attributes. The order of attributes is arbitrary, but stable.
     * <p>
     * If the cursor is on a STARTDOC of a document-fragment, this method will
     * move it to the first top level attribute if one exists.
     * <p>
     * xmlns attributes (namespace declarations) are not considered
     * attributes by this function.
     * <p>
     * The cursor must be on a START or STARTDOC (in the case of a
     * document fragment with top level attributes) for this method to
     * succeed.
     * <p>
     * Example for looping through attributes:
     * <pre>{@code
     *      XmlCursor cursor = ... //cursor on START or STARTDOC
     *      if (cursor.toFirstAttribute())
     *      {
     *          do
     *          {
     *              // do something using attribute's name and value
     *              cursor.getName();
     *              cursor.getTextValue();
     *          }
     *          while (cursor.toNextAttribute());
     *      }
     * }</pre>
     *
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toFirstAttribute();

    /**
     * Moves the cursor to the last attribute of this element, or
     * returns false and does not move the cursor if there are no
     * attributes. The order of attributes is arbitrary, but stable.
     * <p>
     * xmlns attributes (namespace declarations) are not considered
     * attributes by this function.
     * <p>
     * The cursor must be on a START or STARTDOC for this method
     * to succeed.
     *
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toLastAttribute();

    /**
     * Moves the cursor to the next sibling attribute, or returns
     * false and does not move the cursor if there is no next
     * sibling attribute. The order of attributes is arbitrary, but stable.
     * <p>
     * xmlns attributes (namespace declarations) are not considered
     * attributes by this function.
     * <p>
     * The cursor must be on an attribute for this method to succeed.
     *
     * @return true if the cursor was moved; otherwise, false.
     * @see #toFirstAttribute()
     */

    boolean toNextAttribute();

    /**
     * Moves the cursor to the previous sibling attribute, or returns
     * false and does not move the cursor if there is no previous
     * sibling attribute. The order of attributes is arbitrary, but stable.
     * <p>
     * xmlns attributes (namespace declarations) are not considered
     * attributes by this function.
     * <p>
     * The cursor must be on an attribute for this method to succeed.
     *
     * @return true if the cursor was moved; otherwise, false.
     */

    boolean toPrevAttribute();

    /**
     * When at a START or STARTDOC, returns the attribute text for the given
     * attribute. When not at a START or STARTDOC or the attribute does not
     * exist, returns null.
     *
     * @param attrName The name of the attribute whose value is requested.
     * @return The attribute's value if it has one; otherwise, null.
     */

    String getAttributeText(QName attrName);

    /**
     * When at a START or STARTDOC, sets the attribute text for the given
     * attribute. When not at a START or STARTDOC returns false.
     * If the attribute does not exist, one is created.
     *
     * @param attrName The name of the attribute whose value is being set.
     * @param value    The new value for the attribute.
     * @return true if the new value was set; otherwise, false.
     */

    boolean setAttributeText(QName attrName, String value);

    /**
     * When at a START or STARTDOC, removes the attribute with the given name.
     *
     * @param attrName The name of the attribute that should be removed.
     * @return true if the attribute was removed; otherwise, false.
     */

    boolean removeAttribute(QName attrName);

    /**
     * Gets the text value of the current document, element, attribute,
     * comment, procinst or text token.
     * <p>
     * When getting the text value of an element, non-text content such
     * as comments and processing instructions are ignored and text is concatenated.
     * For elements that have nested element children, this
     * returns the concatenated text of all mixed content and the
     * text of all the element children, recursing in first-to-last
     * depthfirst order.
     * <p>
     * For attributes, including namespaces, this returns the attribute value.
     * <p>
     * For comments and processing instructions, this returns the text content
     * of the comment or PI, not including the delimiting sequences &lt;!-- --&gt;, &lt;? ?&gt;.
     * For a PI, the name of the PI is also not included.
     *
     * The value of an empty tag is the empty string.
     * <p>
     * If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.
     *
     * @return The text value of the current token if the token's type is
     * START, STARTDOC, TEXT, ATTR, COMMENT, PROCINST, or NAMESPACE; null
     * if the type is NONE.
     */

    String getTextValue();

    /**
     * Copies the text value of the current document, element, attribute,
     * comment, processing instruction or text token, counting right from
     * this cursor's location up to <em>maxCharacterCount</em>,
     * and copies the returned text into <em>returnedChars</em>.
     * <p>
     * When getting the text value of an element, non-text content such
     * as comments and processing instructions are ignored and text is concatenated.
     * For elements that have nested element children, this
     * returns the concatenated text of all mixed content and the
     * text of all the element children, recursing in first-to-last
     * depthfirst order.
     * <p>
     * For attributes, including namespaces, this returns the attribute value.
     * <p>
     * For comments and processing instructions, this returns the text contents
     * of the comment or PI, not including the delimiting sequences &lt;!-- --&gt;, &lt;? ?&gt;. For
     * a PI, the text will not include the name of the PI.
     * <p>
     * If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.
     * <p>
     * The value of an empty tag is the empty string.
     *
     * @param returnedChars     A character array to hold the returned characters.
     * @param offset            The position within returnedChars to which the first of the
     *                          returned characters should be copied.
     * @param maxCharacterCount The maximum number of characters after this cursor's
     *                          location to copy. A negative value specifies that all characters should be copied.
     * @return The actual number of characters copied; 0 if no characters
     * were copied.
     */

    int getTextValue(char[] returnedChars, int offset, int maxCharacterCount);

    /**
     * Sets the text value of the XML at this cursor's location if that XML's
     * token type is START, STARTDOC, ATTR, COMMENT or PROCINST.
     * <p>
     * For elements that have nested children this first removes all
     * the content of the element and replaces it with the given text.
     *
     * @param text The text to use as a new value.
     * @throws java.lang.IllegalStateException If the token type at this
     *                                         cursor's location is not START, STARTDOC, ATTR, COMMENT or
     *                                         PROCINST.
     */
    void setTextValue(String text);

    /**
     * Sets the text value of the XML at this cursor's location (if that XML's
     * token type is START, STARTDOC, ATTR, COMMENT or PROCINST) to the
     * contents of the specified character array.
     * <p>
     * For elements that have nested children this first removes all
     * the content of the element and replaces it with the given text.
     *
     * @param sourceChars A character array containing the XML's new value.
     * @param offset      The position within sourceChars from which the first of
     *                    the source characters should be copied.
     * @param length      The maximum number of characters to set as the XML's new
     *                    value.
     * @throws java.lang.IllegalArgumentException If the token type at this
     *                                            cursor's location is not START, STARTDOC, ATTR, COMMENT or
     *                                            PROCINST.
     */
    void setTextValue(char[] sourceChars, int offset, int length);

    /**
     * Returns characters to the right of the cursor up to the next token.
     */
    String getChars();

    /**
     * Copies characters up to the specified maximum number, counting right from
     * this cursor's location to the character at <em>maxCharacterCount</em>.  The
     * returned characters are added to <em>returnedChars</em>, with the first
     * character copied to the <em>offset</em> position. The <em>maxCharacterCount</em>
     * parameter should be less than or equal to the length of <em>returnedChars</em>
     * minus <em>offset</em>. Copies a number of characters, which is
     * either <em>maxCharacterCount</em> or the number of characters up to the next token,
     * whichever is less.
     *
     * @param returnedChars     A character array to hold the returned characters.
     * @param offset            The position within returnedChars at which the first of the
     *                          returned characters should be added.
     * @param maxCharacterCount The maximum number of characters after this cursor's
     *                          location to return.
     * @return The actual number of characters returned; 0 if no characters
     * were returned or if the current token is not TEXT.
     */

    int getChars(char[] returnedChars, int offset, int maxCharacterCount);

    /**
     * Moves the cursor to the STARTDOC token, which is the
     * root of the document.
     */

    void toStartDoc();

    /**
     * Moves the cursor to the ENDDOC token, which is the end
     * of the document.
     */

    void toEndDoc();

    /**
     * Determines if the specified cursor is in the same document as
     * this cursor.
     *
     * @param cursor The cursor that may be in the same document
     *               as this cursor.
     * @return true if the specified cursor is in the same document;
     * otherwise, false.
     */

    boolean isInSameDocument(XmlCursor cursor);

    /**
     * Returns an integer indicating whether this cursor is before,
     * after, or at the same position as the specified cursor.
     *
     * {@code a.comparePosition(b) < 0} means a is to the left of b.<br>
     * {@code a.comparePosition(b) == 0} means a is at the same position as b.<br>
     * {@code a.comparePosition(b) > 0} means a is to the right of b.
     * <p>
     * The sort order of cursors in the document is the token order.
     * For example, if cursor "a" is at a START token and the cursor "b"
     * is at a token within the contents of the same element, then
     * a.comparePosition(b) will return -1, meaning that the position
     * of a is before b.
     *
     * @param cursor The cursor whose position should be compared
     *               with this cursor.
     * @return 1 if this cursor is after the specified cursor; 0 if
     * this cursor is at the same position as the specified cursor;
     * -1 if this cursor is before the specified cursor.
     * @throws java.lang.IllegalArgumentException If the specified
     *                                            cursor is not in the same document as this cursor.
     */

    int comparePosition(XmlCursor cursor);

    /**
     * Determines if this cursor is to the left of (or before)
     * the specified cursor. Note that this is the same as
     * {@code a.comparePosition(b) &lt; 0 }
     *
     * @param cursor The cursor whose position should be compared
     *               with this cursor.
     * @return true if this cursor is to the left of the specified
     * cursor; otherwise, false.
     */

    boolean isLeftOf(XmlCursor cursor);

    /**
     * Determines if this cursor is at the same position as
     * the specified cursor. Note that this is the same as
     * {@code a.comparePosition(b) == 0 }
     *
     * @param cursor The cursor whose position should be compared
     *               with this cursor.
     * @return true if this cursor is at the same position as
     * the specified cursor; otherwise, false.
     */

    boolean isAtSamePositionAs(XmlCursor cursor);

    /**
     * Determines if this cursor is to the right of (or after)
     * the specified cursor. Note that this is the same as
     * {@code a.comparePosition(b) &gt; 0 }
     *
     * @param cursor The cursor whose position should be compared
     *               with this cursor.
     * @return true if this cursor is to the right of the specified
     * cursor; otherwise, false.
     */

    boolean isRightOf(XmlCursor cursor);

    /**
     * Executes the specified XQuery expression against the XML this
     * cursor is in.
     * <p>
     * The query may be a String or a compiled query. You can precompile
     * an XQuery expression using the XmlBeans.compileQuery method.
     * <p>
     * The root referred to by the expression should be given as
     * a dot. The following is an example path expression:
     * <pre>
     * XmlCursor results = cursor.execQuery("purchase-order/line-item[price &lt;= 20.00]");
     * </pre>
     *
     * @param query The XQuery expression to execute.
     * @return A cursor containing the results of the query.
     * @throws XmlRuntimeException If the query expression is invalid.
     */

    XmlCursor execQuery(String query);

    /**
     * Executes the specified XQuery expression against the XML this
     * cursor is in, and using the specified options.
     *
     * @param query   The XQuery expression to execute.
     * @param options Options for the query. For example, you can call
     *                the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)}
     *                method to specify a particular name for the query expression
     *                variable that indicates the context node.
     * @throws XmlRuntimeException If the query expression is invalid.
     */

    XmlCursor execQuery(String query, XmlOptions options);

    /**
     * Represents the state of a dcoument at a particular point
     * in time.  It is used to determine if a document has been changed
     * since that point in time.
     */
    interface ChangeStamp {
        /**
         * Returns whether or not the document assoiated with this ChangeStamp
         * has been altered since the ChangeStamp had been created.
         */
        public boolean hasChanged();
    }

    /**
     * Returns the current change stamp for the document the current cursor is in.
     * This change stamp can be queried at a later point in time to find out
     * if the document has changed.
     *
     * @return The change stamp for the document the current cursor is in.
     */
    ChangeStamp getDocChangeStamp();

    /**
     * Subclasses of XmlBookmark can be used to annotate an XML document.
     * This class is abstract to prevent parties from inadvertently
     * interfering with each others' bookmarks without explicitly
     * sharing a bookmark class.
     */

    abstract class XmlBookmark {
        /**
         * Constructs a strongly-referenced bookmark.
         */
        public XmlBookmark() {
            this(false);
        }

        /**
         * Constructs a bookmark.
         *
         * @param weak true if the document's reference to the bookmark should be a WeakReference
         */
        public XmlBookmark(boolean weak) {
            _ref = weak ? new WeakReference(this) : null;
        }

        /**
         * Call the createCursor method to create a new cursor which is
         * positioned at the same splace as the bookmark.  It is much more
         * efficient to call toBookmark on an existing cursor than it
         * is to create a new cursor.  However, toBookmark may fail if the
         * bookmark is in a different document than the cursor.  It is
         * under these circumstances where createCursor needs to be called
         * on the bookmark.  Subsequent navigations to bookmark
         * positions should attempt to reuse the last cursor to
         * improve performace.
         *
         * @return the new cursor
         */
        public final XmlCursor createCursor() {
            return _currentMark == null ? null : _currentMark.createCursor();
        }

        /**
         * @param c the cursor to be moved
         * @return the given cursor moved to this bookmark
         */
        public final XmlCursor toBookmark(XmlCursor c) {
            return c == null || !c.toBookmark(this) ? createCursor() : c;
        }

        /**
         * The default key for bookmarks is the class which implements
         * them.  This way, multiple parties using bookmarks in the
         * same instance document will not interfere with eachother.
         * One can, however, override getKey() to use a key other than
         * the class.
         *
         * @return default key for bookmarks
         */
        public Object getKey() {
            return this.getClass();
        }

        /**
         * The mark is set by the host document; it is capable of
         * returning an XmlCursor implementation at the location of
         * the bookmark.
         */
        public XmlMark _currentMark;

        /**
         * If non-null, the ref is used by the host document
         * to maintain a reference to the bookmark.  If it is a weak
         * reference, the host document will not prevent the Bookmark
         * from being garbage collected.
         */
        public final Reference _ref;
    }

    /**
     * An abstract {@link XmlCursor} factory.
     * Implementations of XmlCursor implement XmlMark to be able to
     * reconstitute a cursor from a bookmark. When content moves between
     * implementations, the XmlMark is set to the implmentation's which
     * receives the new content.
     */

    interface XmlMark {
        XmlCursor createCursor();
    }

    /**
     * Sets a bookmark to the document at this cursor's location.
     * <p>
     * The bookmark is attached to the token in the tree immediately
     * after the cursor. If the tree is manipulated to move
     * that object to a different place, the bookmark moves with it.
     * If the tree is manipulated to delete that token from the
     * tree, the bookmark is orphaned. Copy operations do not copy
     * bookmarks.
     *
     * @param bookmark The bookmark to set.
     */

    void setBookmark(XmlBookmark bookmark);

    /**
     * Retrieves the bookmark with the specified key
     * at this cursor's location. If there is no bookmark whose key is
     * given by the specified key at the current position, null is returned.
     * If the {@link XmlCursor.XmlBookmark#getKey() getKey} method is not overridden on
     * the bookmark, then the bookmark's class is used as the key.
     *
     * @param key The key for the bookmark to retrieve.
     * @return The requested bookmark; null if there is no bookmark
     * corresponding to the specified key.
     */

    XmlBookmark getBookmark(Object key);

    /**
     * Clears the bookmark whose key is specified, if the bookmark
     * exists at this cursor's location.
     *
     * @param key The for the bookmark to clear.
     */

    void clearBookmark(Object key);

    /**
     * Retrieves all the bookmarks at this location, adding them to
     * the specified collection. Bookmarks held by weak references are
     * added to this collection as Weak referenced objects pointing to the
     * bookmark.
     *
     * @param listToFill The collection that will contain bookmarks
     *                   returned by this method.
     */

    void getAllBookmarkRefs(Collection<Object> listToFill);

    /**
     * Removes the XML that is immediately after this cursor.
     * <p>
     * For the TEXT, ATTR, NAMESPACE, COMMENT and PROCINST tokens, a single
     * token is removed. For a START token, the corresponding element and all
     * of its contents are removed. For all other tokens, this is a no-op.
     * You cannot remove a STARTDOC.
     * <p>
     * The cursors located in the XML that was removed all collapse to the
     * same location. All bookmarks in this XML will be orphaned.
     *
     * @return true if anything was removed; false only if the cursor is
     * just before END or ENDDOC token.
     * @throws java.lang.IllegalArgumentException If the cursor is at a
     *                                            STARTDOC token.
     */

    boolean removeXml();

    /**
     * Moves the XML immediately after this cursor to the location
     * specified by the <em>toHere</em> cursor, shifting XML at that location
     * to the right to make room. For the TEXT, ATTR, NAMESPACE,
     * COMMENT and PROCINST tokens, a single token is moved. For a start token, the
     * element and all of its contents are moved. For all other tokens, this
     * is a no-op.
     * <p>
     * The bookmarks located in the XML that was moved also move to the
     * new location; the cursors don't move with the content.
     *
     * @param toHere The cursor at the location to which the XML should
     *               be moved.
     * @return true if anything was moved.  This only happens when the XML to be
     * moved contains the target of the move.
     * @throws java.lang.IllegalArgumentException If the operation is not allowed
     *                                            at the cursor's location.  This includes attempting to move an end token or the
     *                                            document as a whole.  Also, moving to a location before the start document or moving
     *                                            an attribute to a location other than after another attribute or start token
     *                                            will throw.
     */

    boolean moveXml(XmlCursor toHere);

    /**
     * Copies the XML immediately after this cursor to the location
     * specified by the <em>toHere</em> cursor. For the TEXT, ATTR, NAMESPACE,
     * COMMENT and PROCINST tokens, a single token is copied.  For a start token,
     * the element and all of its contents are copied. For all other tokens, this
     * is a no-op.
     * <p>
     * The cursors and bookmarks located in the XML that was copied are also copied
     * to the new location.
     *
     * @param toHere The cursor at the location to which the XML should
     *               be copied.
     * @return true if anything was copied; false if the token supports the operation,
     * but nothing was copied.
     * @throws java.lang.IllegalArgumentException If the operation is not allowed
     *                                            at the cursor's location.
     */

    boolean copyXml(XmlCursor toHere);

    /**
     * Removes the contents of the container (STARTDOC OR START) immediately after
     * this cursor. For all other situations, returns false. Does
     * not remove attributes or namspaces.
     *
     * @return true if anything was copied; otherwise, false.
     */

    boolean removeXmlContents();

    /**
     * Moves the contents of the container (STARTDOC OR START) immediately after
     * this cursor to the location specified by the <em>toHere</em> cursor.
     * For all other situations, returns false. Does not move attributes or
     * namespaces.
     *
     * @param toHere The cursor at the location to which the XML should be moved.
     * @return true if anything was moved; otherwise, false.
     */
    boolean moveXmlContents(XmlCursor toHere);

    /**
     * Copies the contents of the container (STARTDOC OR START) immediately to
     * the right of the cursor to the location specified by the <em>toHere</em> cursor.
     * For all other situations, returns false.  Does not copy attributes or
     * namespaces.
     *
     * @param toHere The cursor at the location to which the XML should
     *               be copied.
     * @return true if anything was copied; otherwise, false.
     */
    boolean copyXmlContents(XmlCursor toHere);

    /**
     * Removes characters up to the specified maximum number, counting right from
     * this cursor's location to the character at <em>maxCharacterCount</em>. The
     * space remaining from removing the characters collapses up to this cursor.
     *
     * @param maxCharacterCount The maximum number of characters after this cursor's
     *                          location to remove.
     * @return The actual number of characters removed.
     * @throws java.lang.IllegalArgumentException If the operation is not allowed
     *                                            at the cursor's location.
     */

    int removeChars(int maxCharacterCount);

    /**
     * Moves characters immediately after this cursor to the position immediately
     * after the specified cursor. Characters are counted to the right up to the
     * specified maximum number. XML after the destination cursor is
     * shifted to the right to make room. The space remaining from moving the
     * characters collapses up to this cursor.
     *
     * @param maxCharacterCount The maximum number of characters after this cursor's
     *                          location to move.
     * @param toHere            The cursor to which the characters should be moved.
     * @return The actual number of characters moved.
     * @throws java.lang.IllegalArgumentException If the operation is not allowed
     *                                            at the cursor's location.
     */

    int moveChars(int maxCharacterCount, XmlCursor toHere);

    /**
     * Copies characters to the position immediately after the specified cursor.
     * Characters are counted to the right up to the specified maximum number.
     * XML after the destination cursor is shifted to the right to make room.
     *
     * @param maxCharacterCount The maximum number of characters after this cursor's
     *                          location to copy.
     * @param toHere            The cursor to which the characters should be copied.
     * @return The actual number of characters copied.
     * @throws java.lang.IllegalArgumentException If the operation is not allowed
     *                                            at the cursor's location.
     */

    int copyChars(int maxCharacterCount, XmlCursor toHere);

    /**
     * Inserts the specified text immediately before this cursor's location.
     *
     * @param text The text to insert.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertChars(String text);

    /**
     * Inserts an element immediately before this cursor's location, giving
     * the element the specified qualified name.
     *
     * @param name The qualified name for the element.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertElement(QName name);

    /**
     * Inserts an element immediately before this cursor's location, giving
     * the element the specified local name.
     *
     * @param localName The local name for the new element.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertElement(String localName);

    /**
     * Inserts a new element immediately before this cursor's location, giving the
     * element the specified local name and associating it with specified namespace
     *
     * @param localName The local name for the new element.
     * @param uri       The URI for the new element's namespace.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertElement(String localName, String uri);

    /**
     * Inserts a new element around this cursor, giving the element the specified
     * qualified name. After the element is inserted, this cursor is between its start
     * and end. This cursor can then be used to insert additional XML into
     * the new element.
     *
     * @param name The qualified name for the new element.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void beginElement(QName name);

    /**
     * Inserts a new element around this cursor, giving the element the specified
     * local name. After the element is inserted, this cursor is between its start
     * and end. This cursor can then be used to insert additional XML into
     * the new element.
     *
     * @param localName The local name for the new element.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void beginElement(String localName);

    /**
     * Inserts a new element around this cursor, giving the element the specified
     * local name and associating it with the specified namespace. After the element
     * is inserted, this cursor is between its start and end. This cursor
     * can then be used to insert additional XML into the new element.
     *
     * @param localName The local name for the new element.
     * @param uri       The URI for the new element's namespace.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void beginElement(String localName, String uri);

    /**
     * Inserts a new element immediately before this cursor's location, giving the
     * element the specified qualified name and content.
     *
     * @param name The qualified name for the new element.
     * @param text The content for the new element.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertElementWithText(QName name, String text);

    /**
     * Inserts a new element immediately before this cursor's location, giving the
     * element the specified local name and content.
     *
     * @param localName The local name for the new element.
     * @param text      The content for the new element.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertElementWithText(String localName, String text);

    /**
     * Inserts a new element immediately before this cursor's location, giving the
     * element the specified local name, associating it with the specified namespace,
     * and giving it the specified content.
     *
     * @param localName The local name for the new element.
     * @param uri       The URI for the new element's namespace.
     * @param text      The content for the new element.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertElementWithText(String localName, String uri, String text);

    /**
     * Inserts a new attribute immediately before this cursor's location, giving it
     * the specified local name.
     *
     * @param localName The local name for the new attribute.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertAttribute(String localName);

    /**
     * Inserts a new attribute immediately before this cursor's location, giving it
     * the specified local name and associating it with the specified namespace.
     *
     * @param localName The local name for the new attribute.
     * @param uri       The URI for the new attribute's namespace.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertAttribute(String localName, String uri);

    /**
     * Inserts a new attribute immediately before this cursor's location, giving it
     * the specified name.
     *
     * @param name The local name for the new attribute.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertAttribute(QName name);

    /**
     * Inserts a new attribute immediately before this cursor's location, giving it
     * the specified value and name.
     *
     * @param Name  The local name for the new attribute.
     * @param value The value for the new attribute.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertAttributeWithValue(String Name, String value);

    /**
     * Inserts an attribute immediately before the cursor's location, giving it
     * the specified name and value, and associating it with the specified namespace.
     *
     * @param name  The name for the new attribute.
     * @param uri   The URI for the new attribute's namespace.
     * @param value The value for the new attribute.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertAttributeWithValue(String name, String uri, String value);

    /**
     * Inserts an attribute immediately before the cursor's location, giving it
     * the specified name and value.
     *
     * @param name  The name for the new attribute.
     * @param value The value for the new attribute.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertAttributeWithValue(QName name, String value);

    /**
     * Inserts a namespace declaration immediately before the cursor's location,
     * giving it the specified prefix and URI.
     *
     * @param prefix    The prefix for the namespace.
     * @param namespace The URI for the namespace.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertNamespace(String prefix, String namespace);

    /**
     * Inserts an XML comment immediately before the cursor's location,
     * giving it the specified content.
     *
     * @param text The new comment's content.
     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
     *                                            at the cursor's location.
     */

    void insertComment(String text);

    /**
     * Inserts an XML processing instruction immediately before the cursor's location,
     * giving it the specified target and text.
     *
     * @param target The target for the processing instruction.
     * @param text   The new processing instruction's text.
     * @throws java.lang.IllegalStateException If the insertion is not allowed
     *                                         at the cursor's location.
     */

    void insertProcInst(String target, String text);
}
