/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
*    XMLBeans", nor may "Apache" appear in their name, without prior
*    written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/

package org.apache.xmlbeans.impl.store;

import org.apache.xmlbeans.impl.common.XMLChar;
import org.apache.xmlbeans.impl.common.GlobalLock;
import org.apache.xmlbeans.impl.store.Root.ChangeListener;
import org.apache.xmlbeans.impl.store.Saver.XmlInputStreamImpl;
import org.apache.xmlbeans.impl.store.Splay.Annotation;
import org.apache.xmlbeans.impl.store.Splay.Attr;
import org.apache.xmlbeans.impl.store.Splay.Begin;
import org.apache.xmlbeans.impl.store.Splay.Comment;
import org.apache.xmlbeans.impl.store.Splay.CursorGoober;
import org.apache.xmlbeans.impl.store.Splay.Goober;
import org.apache.xmlbeans.impl.store.Splay.Procinst;
import org.apache.xmlbeans.impl.store.Splay.Xmlns;
import org.apache.xmlbeans.XmlCursor.ChangeStamp;
import org.apache.xmlbeans.XmlCursor.TokenType;
import org.apache.xmlbeans.XmlLineNumber;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlDocumentProperties;
import org.apache.xmlbeans.XmlRuntimeException;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.File;
import java.io.Writer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Collection;
import java.util.Iterator;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.Location;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.SAXException;
import weblogic.xml.stream.XMLInputStream;

public final class Cursor implements XmlCursor, ChangeListener
{
    Cursor ( Root r, Splay s )        { assert s != null; _goober = new CursorGoober( r ); set( s ); }
    Cursor ( Root r, Splay s, int p ) { assert s != null; _goober = new CursorGoober( r ); set( s, p ); }

    protected void finalize ( )
    {
        Splay s = getSplay();

        if (s != null)
        {
            dispose();
        }
    }

    //
    //
    //

    public Object monitor()
    {
        return getRoot();
    }

    Root  getRoot ( ) { return _goober.getRoot(); }

    Splay getSplay ( ) { return _goober.getSplay(); }
    int   getPos   ( ) { return _goober.getPos(); }

    void set ( Splay s, int p ) { _goober.set( s, p ); }
    void set ( Splay s        ) { _goober.set( s, 0 ); }
    void set ( int p          ) { _goober.set( p ); }
    void set ( Goober g       ) { _goober.set( g ); }

    int getPostCch ( )
    {
        int p = getPos();

        if (p == 0)
            return 0;

        Splay s = getSplay();

        int pa = s.getPosAfter();

        assert p >= pa || s.isLeaf();

        return p >= pa ? s.getCchAfter() - p + pa : s.getPosLeafEnd() - p;
    }

    int getPreCch ( )
    {
        // TODO - quick and dirty impl, improve

        Splay sOrig = getSplay();
        int   pOrig = getPos();

        int n = toPrevChar( -1 );

        set( sOrig, pOrig );

        return n;
    }

    private void checkDisposed ( )
    {
        checkDisposed( this );
    }

    private static void checkDisposed ( Cursor c )
    {
        if (c.isDisposed())
            throw new IllegalStateException( "Cursor has been disposed" );
    }

    boolean isDisposed ( )
    {
        return getSplay() == null;
    }

    //
    // XmlCursor Methods
    //

    public void dispose ( )
    {
        synchronized ( monitor() )
        {
            if (!isDisposed())
            {
                clearSelections();

                if (_stack != null)
                    _stack.dispose();

                set( (Splay) null );
            }
        }
    }

    public XmlObject getObject ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Root r = getRoot();

            if (getPos() > 0)
                return null;

            Splay s = getSplay();

            if (!s.isTypeable())
                return null;

            Type t = s.getType( r );

            assert t != null;

            XmlObject result = t.getXmlObject();
            assert result != null;
            return result;
        }
    }

    public boolean toCursor ( XmlCursor moveTo )
    {
        if (moveTo == null)
            throw new IllegalArgumentException( "Invalid destination cursor" );

        if (monitor() == moveTo.monitor())
        {
            synchronized ( monitor() )
            {
                return toCursorImpl( moveTo );
            }
        }
        else
        {
            boolean acquired = false;
            try
            {
                GlobalLock.acquire();
                acquired = true;
                synchronized ( monitor() )
                {
                    synchronized (moveTo.monitor())
                    {
                        GlobalLock.release();
                        acquired = false;

                        return toCursorImpl( moveTo );
                    }
                }
            }
            catch (InterruptedException e)
            {
                throw new XmlRuntimeException(e.getMessage(), e);
            }
            finally
            {
                if (acquired)
                    GlobalLock.release();
            }
        }
    }

    private boolean toCursorImpl ( XmlCursor moveTo )
    {
        checkDisposed();

        Cursor c = null;

        if (moveTo instanceof Cursor)
        {
            c = (Cursor) moveTo;

            checkDisposed( c );

            if (c.getRoot() != getRoot())
                c = null;
        }

        if (c == null)
            return false;

        set( c._goober );

        return true;
    }

    public XmlDocumentProperties documentProperties ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return getRoot().documentProperties();
        }
    }

    public XmlCursor newCursor ( )
    {   
        synchronized ( monitor() )
        {
            checkDisposed();

            return new Cursor( getRoot(), getSplay(), getPos() );
        }
    }

    public boolean toBookmark ( XmlBookmark bm )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (bm == null)
                return false;

            if (!(bm._currentMark instanceof Annotation))
                return false;

            Annotation a = (Annotation) bm._currentMark;

            if (a.getRoot() != getRoot())
                return false;

            assert a.getSplay() != null;

            set( a );

            return true;
        }
    }

    public XmlBookmark toNextBookmark ( Object key )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (key == null)
                return null;

            Splay sOrig = getSplay();
            int   pOrig = getPos();

            TokenType tt = currentTokenType();

            // Advance the cursor past the current spot by the minimun amount

            if (tt.isText())
            {
                toNextChar( 1 );
                tt = currentTokenType();
            }
            else if ((tt = toNextToken()).isNone())
            {
                set( sOrig, pOrig );
                return null;
            }

            for ( ; ; )
            {
                XmlBookmark bm = getBookmark( key );

                if (bm != null)
                    return bm;

                int postCch;

                if (tt.isText() && (postCch = getPostCch()) > 1)
                {
                    Splay s = getSplay();
                    int   p = getPos();
                    int   d = postCch;

                    for ( Goober g = s.firstGoober() ; g != null ;
                          g = s.nextGoober( g ) )
                    {
                        int dist;
                        XmlBookmark mark;

                        if (g.isAnnotation() && (dist = g.getPos() - p) > 1 &&
                                dist < d && (mark = g.getBookmark()) != null &&
                                    mark.getKey().equals( key ))
                        {
                            bm = mark;
                            d = dist;
                        }
                    }

                    if (bm != null)
                    {
                        set( s, p + d );
                        return bm;
                    }
                }

                if ((tt = toNextToken()).isNone())
                {
                    set( sOrig, pOrig );
                    return null;
                }
            }
        }
    }

    public XmlBookmark toPrevBookmark ( Object key )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (key == null)
                return null;

            Splay sOrig = getSplay();
            int   pOrig = getPos();

            TokenType tt = prevTokenType();

            // Retreat the cursor past the current spot by the minimun amount

            if (tt.isText())
            {
                toPrevChar( 1 );
                tt = prevTokenType();
            }
            else if (toPrevToken().isNone())
            {
                set( sOrig, pOrig );
                return null;
            }
            else
                tt = prevTokenType();

            for ( ; ; )
            {
                XmlBookmark bm = getBookmark( key );

                if (bm != null)
                    return bm;

                int preCch;

                if (tt.isText() && (preCch = getPreCch()) > 1)
                {
                    Splay s;
                    int   p;

                    if (getPos() == 0)
                    {
                        s = getSplay().prevNonAttrSplay();
                        p = s.getEndPos();
                    }
                    else
                    {
                        s = getSplay();
                        p = getPos();
                    }

                    int d = preCch;

                    for ( Goober g = s.firstGoober() ; g != null ;
                          g = s.nextGoober( g ) )
                    {
                        int dist;
                        XmlBookmark mark;

                        if (g.isAnnotation() && (dist = p - g.getPos()) > 1 &&
                                dist < d && (mark = g.getBookmark()) != null &&
                                    mark.getKey().equals( key ))
                        {
                            bm = mark;
                            d = dist;
                        }
                    }

                    if (bm != null)
                    {
                        set( s, p - d );
                        return bm;
                    }
                }

                if (tt.isText())
                {
                    toPrevChar( -1 );
                    tt = prevTokenType();
                }
                else if (toPrevToken().isNone())
                {
                    set( sOrig, pOrig );
                    return null;
                }
                else
                    tt = prevTokenType();
            }
        }
    }

    public TokenType currentTokenType ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return getSplay().getTokenType( getPos() );
        }
    }

    public boolean isStartdoc  ( ) { return currentTokenType().isStartdoc(); }
    public boolean isEnddoc    ( ) { return currentTokenType().isEnddoc(); }
    public boolean isStart     ( ) { return currentTokenType().isStart(); }
    public boolean isEnd       ( ) { return currentTokenType().isEnd(); }
    public boolean isText      ( ) { return currentTokenType().isText(); }
    public boolean isAttr      ( ) { return currentTokenType().isAttr(); }
    public boolean isNamespace ( ) { return currentTokenType().isNamespace(); }
    public boolean isComment   ( ) { return currentTokenType().isComment(); }
    public boolean isProcinst  ( ) { return currentTokenType().isProcinst(); }
    public boolean isContainer ( ) { return currentTokenType().isContainer(); }
    public boolean isFinish    ( ) { return currentTokenType().isFinish(); }
    public boolean isAnyAttr   ( ) { return currentTokenType().isAnyAttr(); }

    public TokenType prevTokenType ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            // TODO - quick and dirty implementation, improve

            Splay sOrig = getSplay();
            int   pOrig = getPos();

            TokenType tt;

            if (toPrevChar( 1 ) == 1)
                tt = TokenType.TEXT;
            else if (!(tt = toPrevToken()).isNone())
                tt = currentTokenType();

            set( sOrig, pOrig );

            return tt;
        }
    }

    public TokenType toNextToken ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay os = getSplay(); // Orignal splay
            Splay s = os;
            int   p = getPos();

            if (p == 0)
            {
                if (s.isRoot())
                    return TokenType.NONE;

                //
                // Look see if there is an attr we should visit before visiting
                // any following content in this container.
                //

                if (s.isContainer())
                {
                    Splay t = s.nextSplay();

                    if (t.isAttr())
                    {
                        set( t, 0 );
                        return currentTokenType();
                    }

                    //
                    // Now we're going into the content of this container.  Flush
                    // out any cached type value.
                    //

                    s.ensureContentValid();
                }

                if (s.getMaxPos() > 0)
                    p = 1;
                else
                {
                    s = s.nextSplay();
                    p = 0;
                }
            }
            else
            {
                assert p > 0;
                assert !s.isRoot();

                if (p >= s.getPosAfter() && s.getCchAfter() > 0)
                {
                    s = s.nextSplay();
                    p = 0;
                }
                else
                {
                    assert s.isLeaf();
                    assert p < s.getPosAfter();

                    if (p != s.getPosLeafEnd())
                        p = s.getPosLeafEnd();
                    else if (s.getCchAfter() > 0)
                        p = s.getPosAfter();
                    else
                    {
                        s = s.nextSplay();
                        p = 0;
                    }
                }
            }

            //
            // If we are transitioning from an attr to a non attr, see if there
            // is content in a DOC or BEGIN which needs to be visited after
            // the attributes.
            //
            // Also, if we are transitioning from an attr container (BEGIN or
            // DOC) to an attr, where the attr container has interior content,
            // we have already visited the attrs and must skip them now.
            //
            // Also, if we are transitioning from pos 0 to pos 1 on an attr
            // container, we need to visit any attributes before visiting the
            // interior content of the attr container.
            //

            if (p == 0)
            {
                if (!s.isAttr() && os.isAttr())
                {
                    Splay t = os.prevNonAttrSplay();

                    assert t.isContainer();

                    //
                    // We're navigating to the content of a container.  Flush
                    // out any cached type value.
                    //

                    t.ensureContentValid();

                    if (t.getMaxPos() > 0)
                    {
                        s = t;
                        p = 1;
                    }
                }
                else if (s.isAttr() && !os.isAttr() && os.getMaxPos() > 0)
                {
                    assert os.isContainer();

                    s = s.nextNonAttrSplay();
                }
            }

            set( s, p );

            return currentTokenType();
        }
    }

    public TokenType toPrevToken ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

    // TODO - This code is not as compact as it can be, there is some redundancy
    // -- rethink it later ...

            Splay s = getSplay();
            int   p = getPos();

            if (p == 1 && s.isInvalid())
            {
                assert s.isLeaf();
                p += s.ensureContentValid();
            }

            if (p == 1 && s.isContainer())
            {
                Splay t = s.nextSplay();

                if (t.isAttr())
                {
                    s = t;

                    for ( t = t.nextSplay() ; t.isAttr() ; t = t.nextSplay() )
                        s = t;

                    set( s, 0 );

                    return currentTokenType();
                }
            }

            if (p == 0 && !s.isAttr())
            {
                if (s.isDoc())
                    return TokenType.NONE;

                Splay t = s.prevSplay();

                if (t.isAttr())
                {
                    t = t.prevNonAttrSplay();

                    assert t.isContainer();

                    if (t.isDoc())
                        t.ensureContentValid();

                    if (t.getMaxPos() > 0)
                    {
                        set(
                            t,
                            t.getCchAfter() > 0 ? t.getPosAfter() : t.getMaxPos() );

                        return currentTokenType();
                    }
                }
            }

            if (s.isAttr())
            {
                assert p == 0;

                Splay t = s.prevSplay();

                if (!t.isAttr())
                {
                    assert t.isContainer();

                    set( t, 0 );
                    return currentTokenType();
                }
            }

            if (p == 0)
            {
                if (s.isDoc())
                    return TokenType.NONE;

                s = s.prevSplay();

                if (s.isDoc())
                    s.ensureContentValid();

                p = s.getCchAfter() > 0 ? s.getPosAfter() : s.getMaxPos();
            }
            else
            {
                assert p > 0;
                assert !s.isRoot();

                int posAfter = s.getPosAfter();

                if (p >= posAfter)
                {
                    assert s.getCchAfter() > 0;
                    p = posAfter - 1;
                }
                else
                {
                    assert s.isValid();
                    assert s.isLeaf();

                    p = p > 1 && p == posAfter - 1 ? 1 : 0;
                }
            }

            set( s, p );

            return currentTokenType();
        }
    }

    public void insertChars ( String text )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();
            int   p = getPos();

            if (p == 0)
            {
                if (s.isDoc() || s.isAttr())
                    throw new IllegalStateException( "Invalid location for text" );

                s = s.prevNonAttrSplay();
                p = s.getEndPos();
            }

            if (text == null)
                return;

            int cch = text.length();

            if (cch > 0)
                s.insertChars( p, getRoot(), text, 0, cch );
        }
    }

    private static void validateLocalName ( QName name )
    {
        if (name == null)
            throw new IllegalArgumentException( "QName is null" );

        validateLocalName( name.getLocalPart() );
    }

    private static void validateLocalName ( String name )
    {
        if (name == null)
            throw new IllegalArgumentException( "Name is null" );

        if (name.length() == 0)
            throw new IllegalArgumentException( "Name is empty" );

        if (!XMLChar.isValidNCName( name ))
            throw new IllegalArgumentException( "Name is not valid" );
    }

    private static void validatePrefix ( String name )
    {
        if (name == null)
            throw new IllegalArgumentException( "Prefix is null" );

        if (name.length() == 0)
            throw new IllegalArgumentException( "Prefix is empty" );

        if (Splay.beginsWithXml( name ))
            throw new IllegalArgumentException( "Prefix begins with 'xml'" );

        if (!XMLChar.isValidNCName( name ))
            throw new IllegalArgumentException( "Prefix is not valid" );
    }

    private void insertAttribute ( QName name, String value )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            insert( new Attr( name ), value );
        }
    }

    public void insertAttribute ( String name )
    {
        insertAttributeWithValue( name, null, null );
    }

    public void insertAttribute ( String name, String uri )
    {
        insertAttributeWithValue( name, uri, null );
    }

    public void insertAttributeWithValue ( String name, String value )
    {
        insertAttributeWithValue( name, null, value );
    }

    public void insertAttributeWithValue (
        String name, String uri, String value )
    {
        validateLocalName( name );

        insertAttribute( new QName( uri, name ), value );
    }

    public void insertAttribute ( QName name )
    {
        validateLocalName( name );

        insertAttribute( name, null );
    }

    public void insertAttributeWithValue ( QName name, String value )
    {
        validateLocalName( name );

        insertAttribute( name, value );
    }

    public void insertNamespace ( String prefix, String namespace )
    {
        synchronized ( monitor() )
        {
            if (prefix == null)
                prefix = "";
            else if (prefix.length() > 0)
                validatePrefix( prefix );

            if (namespace == null)
                namespace = "";

            if (namespace.length() == 0 && prefix.length() > 0)
            {
                throw
                    new IllegalArgumentException(
                        "Can't map a prefix to no namespace" );
            }

            insert( new Xmlns( new QName( namespace, prefix ) ), null );
        }
    }

    public void insertComment ( String value )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            insert( new Comment(), value );
        }
    }

    public void insertProcInst ( String target, String value )
    {
        validatePrefix( target ); // used becuase "<?xml...?> is disallowed

        synchronized ( monitor() )
        {
            checkDisposed();

            insert( new Procinst( target ), value );
        }
    }

    public void insertElement ( String name )
    {
        insertElementWithText( name, null, null );
    }

    public void insertElementWithText ( String name, String text )
    {
        insertElementWithText( name, null, text );
    }

    public void insertElement ( String name, String uri )
    {
        insertElementWithText( name, uri, null );
    }

    public void insertElement ( QName name )
    {
        insertElementWithText( name, null );
    }

    public void beginElement ( QName name )
    {
        insertElement( name );
        toPrevToken();
    }

    public void beginElement ( String name )
    {
        insertElement( name );
        toPrevToken();
    }

    public void beginElement ( String name, String uri )
    {
        insertElement( name, uri );
        toPrevToken();
    }

    public void insertElementWithText ( QName name, String text )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            validateLocalName( name.getLocalPart() );

            Begin b = new Begin( name, null );

            b.toggleIsLeaf();

            insert( b, text );
        }
    }

    public void insertElementWithText ( String name, String uri, String text )
    {
        insertElementWithText( new QName( uri, name ), text );
    }

    void insert ( Splay sInsert, String value )
    {
        assert !isDisposed();
        assert Root.dv > 0 || sInsert.getRootSlow() == null;
        assert sInsert.getCch() == 0;

        if (value != null)
            sInsert.adjustCch( value.length() );

        Splay s = getSplay();
        int   p = getPos();

        sInsert.checkInsertionValidity( 0, s, p, false );

        if (value != null)
            s.insert( getRoot(), p, sInsert, value, 0, value.length(), true );
        else
            s.insert( getRoot(), p, sInsert, null, 0, 0, true );

        assert validate();
    }

    public String getTextValue ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();

            if (getPos() > 0 || s.isFinish() || s.isXmlns())
            {
                throw new IllegalStateException(
                    "Can't get text value, current token can have no text value" );
            }

            return getSplay().getText( getRoot() );
        }
    }

    public int getTextValue ( char[] buf, int off, int cch )
    {
//        synchronized ( monitor() )
//        {
//            checkDisposed();
//
//            Splay s = getSplay();
//
//            if (getPos() > 0 || s.isFinish() || s.isXmlns())
//            {
//                throw new IllegalStateException(
//                    "Can't get text value, current token can have no text value" );
//            }
//
//            return getSplay().getText( getRoot() );
//        }

        // Hack impl for now

        String s = getTextValue();

        int n = s.length();

        if (n > cch)
            n = cch;

        if (n <= 0)
            return 0;

        s.getChars( 0, n, buf, off );

        return n;
    }

    public void setTextValue ( String text )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();
            int   p = getPos();

            if (p > 0 || s.isXmlns() || s.isFinish())
            {
                throw new IllegalStateException(
                    "Can't set text value, current token can have no text value" );
            }


            s.setText( getRoot(), text, 0, text == null ? 0 : text.length() );
        }
    }

    public void setTextValue ( char[] buf, int off, int len )
    {
        setTextValue( String.copyValueOf( buf, off, len ) );
    }

    public String getChars ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            int cch = -1;

            int postCch = getPostCch();

            if (cch < 0 || cch > postCch)
                cch = postCch;

            return
                getRoot()._text.fetch(
                    getSplay().getCpForPos( getRoot(), getPos() ), cch );
        }
    }

    public int getChars ( char[] buf, int off, int cch )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            int postCch = getPostCch();

            if (cch < 0 || cch > postCch)
                cch = postCch;

            if (buf == null || off >= buf.length)
                return 0;

            if (buf.length - off < cch)
                cch = buf.length - off;

            getRoot()._text.fetch(
                buf, off, getSplay().getCpForPos( getRoot(), getPos() ), cch );

            return cch;
        }
    }

    public void setBookmark ( XmlBookmark annotation )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (annotation == null)
                return;

            clearBookmark( annotation.getKey() );

            Annotation a = new Annotation( getRoot(), annotation );

            if (a._key == null)
                throw new IllegalArgumentException( "Annotation key is null" );

            a.set( _goober );
            annotation._currentMark = a;
        }
    }

    public XmlBookmark getBookmark ( Object key )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (key == null)
                return null;

            Splay s = getSplay();
            int   p = getPos();

            for ( Goober g = s.firstGoober() ; g != null ; g = s.nextGoober( g ) )
            {
                if (g.getKind() == Splay.ANNOTATION && g.getPos() == p)
                {
                    Annotation a = (Annotation) g;

                    XmlBookmark xa = a.getXmlBookmark();

                    if (xa != null && a._key.equals( key ))
                        return xa;
                }
            }

            return null;
        }
    }

    public void clearBookmark ( Object key )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (key == null)
                return;

            Splay s = getSplay();
            int   p = getPos();

            for ( Goober g = s.firstGoober() ; g != null ; g = s.nextGoober( g ) )
            {
                if (g.getKind() == Splay.ANNOTATION && g.getPos() == p)
                {
                    Annotation a = (Annotation) g;

                    XmlBookmark xa = a.getXmlBookmark();

                    if (xa != null && a._key.equals( key ))
                    {
                        g.set( null, 0 );
                        return;
                    }
                }
            }
        }
    }

    public void getAllBookmarkRefs ( Collection listToFill )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (listToFill == null)
                return;

            Splay s = getSplay();
            int   p = getPos();

            for ( Goober g = s.firstGoober() ; g != null ; g = s.nextGoober( g ) )
            {
                if (g.getKind() == Splay.ANNOTATION && g.getPos() == p)
                    listToFill.add( ((Annotation) g).getXmlBookmark() );
            }
        }
    }

    public boolean hasNextToken ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            assert !getSplay().isRoot() || getPos() == 0;
            return !getSplay().isRoot();
        }
    }

    public boolean hasPrevToken ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return !getSplay().isDoc() || getPos() > 0;
        }
    }

    public QName getName ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (getPos() > 0)
                return null;

            Splay s = getSplay();

            switch ( s.getKind() )
            {
            case Splay.BEGIN :
            case Splay.ATTR :
            case Splay.PROCINST :
                return s.getName();
            }

            return null;
        }
    }

    public void setName ( QName name )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (name == null)
                throw new IllegalArgumentException( "Name is null" );

            Splay s = getSplay();

            if (getPos() > 0 || !(s.isBegin() || s.isAttr() || s.isProcinst()))
            {
                throw
                    new IllegalStateException(
                        "Can't set name here: " + currentTokenType() );
            }

            if (s.isProcinst())
            {
                validatePrefix( name.getLocalPart() );

                if (name.getNamespaceURI().length() > 0)
                {
                    throw
                        new IllegalArgumentException(
                            "Procinst name must have no URI" );
                }
            }
            else if (s.isXmlns())
            {
                if (name.getLocalPart().length() > 0)
                    validatePrefix( name.getLocalPart() );
            }
            else
                validateLocalName( name.getLocalPart() );

            s.setName( getRoot(), name );
        }
    }

    public int toNextChar ( int cch )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();
            int   p = getPos();

            int maxCch = getPostCch();

            if (maxCch == 0 || cch == 0)
                return 0;

            if (cch < 0 || cch > maxCch)
                cch = maxCch;

            assert p + cch <= s.getEndPos();

            if (p + cch == s.getEndPos())
                toNextToken();
            else
                set( p + cch );

            return cch;
        }
    }

    public int toPrevChar ( int cch )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();
            int   p = getPos();

            Splay sText = s;  // The splay and pos where the text exists
            int   pText = p;
            int   maxCch = 0; // Max chars to move over

            if (p == 0)
            {
                if (!s.isDoc() && !s.isAttr())
                {
                    sText = s.prevNonAttrSplay();
                    pText = sText.getEndPos();
                    maxCch = sText.getCchAfter();
                }
            }
            else if (s.isLeaf() && p <= s.getPosLeafEnd())
            {
                int dCch = s.ensureContentValid();
                p += dCch;
                pText = p;
                maxCch = p - 1;
            }
            else
                maxCch = p - s.getPosAfter();

            assert pText <= sText.getEndPos();

            if (maxCch == 0 || cch == 0)
                return 0;

            if (cch < 0 || cch > maxCch)
                cch = maxCch;

            set( sText, pText - cch );

            return cch;
        }
    }

    public void toEndDoc ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            set( getRoot(), 0 );
        }
    }

    public void toStartDoc ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            set( getRoot()._doc, 0 );
        }
    }

    public TokenType toFirstContentToken ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();

            if (getPos() > 0 || !s.isContainer())
                return TokenType.NONE;

            s.ensureContentValid();

            if (s.getCch() > 0 || s.isLeaf())
                set( 1 );
            else
                set( s.nextNonAttrSplay(), 0 );

            return currentTokenType();
        }
    }

    public TokenType toEndToken ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();

            if (getPos() > 0 || !s.isContainer())
                return TokenType.NONE;

            if (s.isLeaf())
                set( s.getPosLeafEnd() );
            else
                set( s.getFinishSplay() );

            return currentTokenType();
        }
    }

    public boolean toParent ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();
            int   p = getPos();

            if (p == 0 && s.isDoc())
                return false;

            set( s.getContainer( p ), 0 );

            return true;
        }
    }

    public boolean toNextSibling ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();
            int   p = getPos();

            if (p == 0)
            {
                if (s.isDoc())
                    return false;

                if (s.isBegin())
                    s = s.getFinishSplay().nextSplay();
            }
            else
            {
                if (s.isLeaf() && p <= s.getPosLeafEnd())
                    return false;

                s = s.nextSplay();
            }

            for ( ; !s.isBegin() ; s = s.nextSplay() )
            {
                if (s.isFinish())
                    return false;
            }

            set( s, 0 );

            return true;
        }
    }

    public boolean toNextSibling ( String name )
    {
        return toNextSibling( new QName( name ) );
    }

    public boolean toNextSibling ( String namespace, String name )
    {
        return toNextSibling( new QName( namespace, name ) );
    }

    public boolean toNextSibling ( QName name )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay sOriginal = getSplay();
            int   pOriginal = getPos();

            for ( ; ; )
            {
                if (!toNextSibling())
                    break;

                if (getName().equals( name ))
                    return true;
            }

            set( sOriginal, pOriginal );

            return false;
        }
    }

    public boolean toPrevSibling ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();
            int   p = getPos();

            if (p == 0)
            {
                if (s.isDoc() || s.isAttr())
                    return false;

                s = s.prevSplay();
            }
            else
            {
                assert p > 0;

                if (s.isContainer())
                {
                    if (s.isLeaf())
                    {
                        if (p <= s.getPosLeafEnd())
                            return false;

                        set( 0 );

                        return true;
                    }

                    return false;
                }
            }

            for ( ; ; )
            {
                if (s.isEnd())
                {
                    s = s.getContainer();
                    break;
                }

                if (s.isLeaf())
                    break;

                if (s.isContainer())
                    return false;

                s = s.prevSplay();
            }

            set( s, 0 );

            return true;
        }
    }

    private Splay getStart ( )
    {
        checkDisposed();

        Splay s = getSplay();

        if (!s.isContainer() || getPos() != 0)
        {
            push();

            if (toNextSibling())
                s = getSplay();
            else
                s = null;

            pop();
        }

        return s;
    }

    public boolean toFirstChild ( )
    {
        return toChild( (QName) null );
    }

    public boolean toChild ( String name )
    {
        return toChild( new QName( name ) );
    }

    public boolean toChild ( String namespace, String name )
    {
        return toChild( new QName( namespace, name ) );
    }

    public boolean toChild ( QName name )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getRoot().findNthBegin( getStart(), name, null, 0 );

            if (s == null)
                return false;

            set( s, 0 );

            return true;
        }
    }

    public boolean toChild ( int n )
    {
        return toChild( null, n );
    }

    public boolean toChild ( QName name, int n )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getRoot().findNthBegin( getStart(), name, null, n );

            if (s == null)
                return false;

            set( s, 0 );

            return true;
        }
    }

    public boolean toLastChild ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay sOriginal = getSplay();
            int   pOriginal = getPos();

            if (!sOriginal.isContainer() || pOriginal != 0)
            {
                if (!toNextSibling())
                    return false;
            }

            if (!toEndToken().isNone() && toPrevSibling())
                return true;

            set( sOriginal, pOriginal );

            return false;
        }
    }

    public boolean toFirstAttribute ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay sOriginal = getSplay();
            int   pOriginal = getPos();

            if (!sOriginal.isContainer() || pOriginal != 0)
                return false;

            for ( Splay s = sOriginal.nextSplay() ; s.isAttr() ; s = s.nextSplay() )
            {
                if (s.isNormalAttr())
                {
                    set( s, 0 );
                    return true;
                }
            }

            set( sOriginal, pOriginal );
            return false;
        }
    }

    public boolean toLastAttribute ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay sOriginal = getSplay();
            int   pOriginal = getPos();

            if (!sOriginal.isContainer() || pOriginal != 0)
                return false;

            Splay lastNormalAttr = null;

            for ( Splay s = sOriginal.nextSplay() ; s.isAttr() ; s = s.nextSplay() )
            {
                if (s.isNormalAttr())
                    lastNormalAttr = s;
            }

            if (lastNormalAttr != null)
            {
                set( lastNormalAttr, 0 );
                return true;
            }

            set( sOriginal, pOriginal );
            return false;
        }
    }

    public boolean toNextAttribute ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();

            if (!s.isAttr())
                return false;

            for ( s = s.nextSplay() ; s.isAttr() ; s = s.nextSplay() )
            {
                if (s.isNormalAttr())
                {
                    set( s, 0 );
                    return true;
                }
            }

            return false;
        }
    }

    public boolean toPrevAttribute ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();

            if (!s.isAttr())
                return false;

            for ( s = s.prevSplay() ; s.isAttr() ; s = s.prevSplay() )
            {
                if (s.isNormalAttr())
                {
                    set( s, 0 );
                    return true;
                }
            }

            return false;
        }
    }

    public String getAttributeText ( QName attrName )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (attrName == null)
                throw new IllegalArgumentException( "Attr name is null" );

            if (getPos() > 0)
                return null;

            Splay s = getSplay().getAttr( attrName );

            return s == null ? null : s.getText( getRoot() );
        }
    }

    public boolean setAttributeText ( QName attrName, String value )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (attrName == null)
                throw new IllegalArgumentException( "Attr name is null" );

            validateLocalName( attrName.getLocalPart() );

            if (getPos() > 0)
                return false;

            Splay s = getSplay();

            if (!s.isContainer())
                return false;

            if (value == null)
                value = "";

            s = getSplay().getAttr( attrName );

            if (s == null)
            {
                XmlCursor c = newCursor();

                try
                {
                    // Insert the new attr at the end

                    do {
                        c.toNextToken();
                    } while ( c.isAnyAttr() );

                    c.insertAttributeWithValue( attrName, value );
                }
                finally
                {
                    c.dispose();
                }
            }
            else
                s.setText( getRoot(), value, 0, value.length() );

            return true;
        }
    }

    public boolean removeAttribute ( QName attrName )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (attrName == null)
                throw new IllegalArgumentException( "Attr name is null" );

            if (getPos() > 0)
                return false;

            boolean removed = false;

            for ( ; ; )
            {
                Splay s = getSplay().getAttr( attrName );

                if (s == null)
                    break;

                s.remove( getRoot(), true );

                removed = true;
            }

            return removed;
        }
    }

    public int removeChars ( int cch )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            int postCch = getPostCch();

            if (postCch == 0 || cch == 0)
                return 0;

            if (cch < 0 || cch > postCch)
                cch = postCch;

            return getSplay().removeChars( getRoot(), getPos(), cch );
        }
    }

    public int moveChars ( int cch, XmlCursor dst )
    {
        if (dst == null)
            throw new IllegalArgumentException( "Destination is null" );

        if (monitor() == dst.monitor())
        {
            synchronized ( monitor() )
            {
                return moveCharsImpl( cch, dst );
            }
        }
        else
        {
            boolean acquired = false;
            try
            {
                GlobalLock.acquire();
                acquired = true;
                synchronized ( monitor() )
                {
                    synchronized (dst.monitor())
                    {
                        GlobalLock.release();
                        acquired = false;

                        return moveCharsImpl( cch, dst );
                    }
                }
            }
            catch (InterruptedException e)
            {
                throw new XmlRuntimeException(e.getMessage(), e);
            }
            finally
            {
                if (acquired)
                    GlobalLock.release();
            }
        }
    }

    private int moveCharsImpl ( int cch, XmlCursor dst )
    {
        checkDisposed();

        if (dst == null || !(dst instanceof Cursor))
            throw new IllegalArgumentException( "Invalid destination cursor" );

        Cursor cDst = (Cursor) dst;

        checkDisposed( cDst );

        Root  rDst = cDst.getRoot();
        Splay sDst = cDst.getSplay();
        int   pDst = cDst.getPos();

        if (pDst == 0 && (sDst.isDoc() || sDst.isAttr()))
            throw new IllegalArgumentException( "Invalid destination" );

        return
            getSplay().moveChars(
                getRoot(), getPos(), cch, rDst, sDst, pDst, false );
    }

    public int copyChars ( int cch, XmlCursor dst )
    {
        if (dst == null)
            throw new IllegalArgumentException( "Destination is null" );

        if (dst.monitor() == monitor())
        {
            synchronized ( monitor() )
            {
                return copyCharsImpl( cch, dst );
            }
        }
        else
        {
            boolean acquired = false;
            try
            {
                GlobalLock.acquire();
                acquired = true;
                synchronized ( monitor() )
                {
                    synchronized (dst.monitor())
                    {
                        GlobalLock.release();
                        acquired = false;

                        return copyCharsImpl( cch, dst );
                    }
                }
            }
            catch (InterruptedException e)
            {
                throw new XmlRuntimeException(e.getMessage(), e);
            }
            finally
            {
                if (acquired)
                    GlobalLock.release();
            }
        }
    }

    private int copyCharsImpl ( int cch, XmlCursor dst )
    {
        checkDisposed();

        if (dst == null || !(dst instanceof Cursor))
            throw new IllegalArgumentException( "Invalid destination cursor" );

        Cursor cDst = (Cursor) dst;

        checkDisposed( cDst );

        Root  rDst = cDst.getRoot();
        Splay sDst = cDst.getSplay();
        int   pDst = cDst.getPos();

        if (pDst == 0)
        {
            if (sDst.isDoc() || sDst.isAttr())
                throw new IllegalArgumentException( "Invalid destination" );

            sDst = sDst.prevNonAttrSplay();
            pDst = sDst.getEndPos();
        }

        return
            getSplay().copyChars( getRoot(), getPos(), cch, rDst, sDst, pDst );
    }

    public String namespaceForPrefix ( String prefix )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();

            if (getPos() > 0 || !s.isContainer())
                throw new IllegalStateException( "Not on a container" );

            return s.namespaceForPrefix( prefix );
        }
    }

    public String prefixForNamespace ( String ns )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (ns == null || ns.length() == 0)
                throw new IllegalArgumentException( "Must specify a namespace" );

            Splay s = getSplay();

            if (getPos() > 0 || !s.isContainer())
                throw new IllegalStateException( "Not on a container" );

            String result = s.prefixForNamespace( getRoot(), ns, null, true);

            assert result != null;

            return result;
        }
    }

    public void getAllNamespaces ( Map addToThis )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();

            if (getPos() > 0 || !s.isContainer())
                throw new IllegalStateException( "Not on a container" );

            // Do this with cursor for now...

            XmlCursor c = newCursor();

            do
            {
                assert c.isContainer();

                QName cName = c.getName();

                while ( !c.toNextToken().isNone() && c.isAnyAttr() )
                {
                    if (c.isNamespace())
                    {
                        String prefix = c.getName().getLocalPart();
                        String uri    = c.getName().getNamespaceURI();

                        // Here I check to see if there is a default namespace
                        // mapping which is not empty on a non root container which
                        // is in a namespace.  This this case, I do not want to add
                        // this mapping because it could not be persisted out this
                        // way.

                        if (prefix.length() == 0 && uri.length() > 0 &&
                                cName != null && cName.getNamespaceURI().length()>0)
                        {
                            continue;
                        }

                        if (!addToThis.containsKey( prefix ))
                            addToThis.put( prefix, uri );
                    }
                }

                c.toParent();
            }
            while ( c.toParent() );

            c.dispose();
        }
    }

    /**
     * Returns:
     *
     *   -1 is this is left of that
     *    0 is this is left is at same position as that
     *    1 is this is right of that
     */

    public int comparePosition ( XmlCursor xthat )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (xthat == null || !(xthat instanceof Cursor))
                throw new IllegalArgumentException( "Invalid that cursor" );

            Cursor that = (Cursor) xthat;

            Root r = getRoot();

            if (r != that.getRoot())
                throw new IllegalArgumentException( "Cursors not in same document" );

            checkDisposed( that );

            return
                getSplay().compare( r, getPos(), that.getSplay(), that.getPos() );
        }
    }

    public boolean isLeftOf ( XmlCursor that )
    {
        return comparePosition( that ) < 0;
    }

    public boolean isAtSamePositionAs ( XmlCursor that )
    {
        return comparePosition( that ) == 0;
    }

    public boolean isRightOf ( XmlCursor that )
    {
        return comparePosition( that ) > 0;
    }

    public InputStream newInputStream ( XmlOptions options )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return
                new Saver.InputStreamSaver(
                    getRoot(), getSplay(), getPos(), options );
        }
    }

    public InputStream newInputStream ( )
    {
        return newInputStream( null );
    }

    public Reader newReader ( )
    {
        return newReader( null );
    }

    public Reader newReader ( XmlOptions options )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return new Saver.TextReader( getRoot(), getSplay(), getPos(), options );
        }
    }

    public XMLInputStream newXMLInputStream ( )
    {
        return newXMLInputStream( null );
    }

    public XMLInputStream newXMLInputStream ( XmlOptions options )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return
                new XmlInputStreamImpl( getRoot(), getSplay(), getPos(), options );
        }
    }

    public XMLStreamReader newXMLStreamReader ( )
    {
        return newXMLStreamReader( null );
    }

    public XMLStreamReader newXMLStreamReader ( XmlOptions options )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            boolean inner = XmlOptions.maskNull( options ).hasOption( XmlOptions.SAVE_INNER );

            if (inner)
            {
                if (isNamespace())
                    return new XMLStreamReaderForString( newCursor(), getName().getNamespaceURI() );

                if (isAttr() || isComment() || isProcinst())
                    return new XMLStreamReaderForString( newCursor(), getTextValue() );
            }

            if (isText())
                return new XMLStreamReaderForString( newCursor(), getChars() );

            if (isFinish())
                return new XMLStreamReaderForString( newCursor(), "" );

            assert !isText() && !isFinish();
            assert !inner || isContainer();

            XmlCursor start = newCursor();
            XmlCursor last = newCursor();

            if (inner)
            {
                start.toNextToken();
                last.toEndToken();

                if (start.isAtSamePositionAs( last ))
                    return new XMLStreamReaderForString( start, "" );

                last.toPrevToken();
            }
            else
            {
                if (isContainer())
                    last.toEndToken();
            }

            return new XMLStreamReaderImpl( start, last );
        }
    }

    private static final XmlOptions _toStringOptions =
        buildPrettyOptions();

    static final XmlOptions buildPrettyOptions ( )
    {
        XmlOptions options = new XmlOptions();
        options.put( XmlOptions.SAVE_PRETTY_PRINT );
        options.put( XmlOptions.SAVE_AGGRESSIVE_NAMESPACES );
        options.put( XmlOptions.SAVE_USE_DEFAULT_NAMESPACE );
        return options;
    }

    public String toString (  )
    {
        return xmlText( _toStringOptions );
    }

    public String xmlText (  )
    {
        return xmlText( null );
    }

    public String xmlText ( XmlOptions options )
    {
        Saver.TextSaver saver;
        synchronized ( monitor() )
        {
            checkDisposed();

            saver = new Saver.TextSaver(
                    getRoot(), getSplay(), getPos(), options, null );
        }
        return saver.saveToString();
    }

    static class ChangeStampImpl implements ChangeStamp
    {
        ChangeStampImpl ( Root r )
        {
            _root = r;
            _versionStamp = _root.getVersion();
        }

        public boolean hasChanged ( )
        {
            return _versionStamp != _root.getVersion();
        }

        private final Root _root;
        private final long _versionStamp;
    }

    public ChangeStamp getDocChangeStamp ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return new ChangeStampImpl( getRoot() );
        }
    }

    public boolean removeXml ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            Splay s = getSplay();
            int   p = getPos();

            assert p < s.getEndPos();

            if (p > 0)
            {
                if (s.isLeaf() && p == s.getPosLeafEnd())
                    return false;

                int cchRemove = removeChars( getPostCch() );

                assert cchRemove > 0;

                return true;
            }
            else if (s.isDoc())
            {
                throw
                    new IllegalStateException(
                        "Can't remove a whole document." );
            }
            else if (s.isFinish())
                return false;

            s.remove( getRoot(), true );

            return true;
        }
    }

    public boolean moveXml ( XmlCursor dst )
    {
        if (dst == null)
            throw new IllegalArgumentException( "Destination is null" );

        if (dst.monitor() == monitor())
        {
            synchronized ( monitor() )
            {
                return moveXmlImpl( dst );
            }
        }
        else
        {
            boolean acquired = false;
            try
            {
                GlobalLock.acquire();
                acquired = true;
                synchronized ( monitor() )
                {
                    synchronized (dst.monitor())
                    {
                        GlobalLock.release();
                        acquired = false;

                        return moveXmlImpl ( dst );
                    }
                }
            }
            catch (InterruptedException e)
            {
                throw new XmlRuntimeException(e.getMessage(), e);
            }
            finally
            {
                if (acquired)
                    GlobalLock.release();
            }
        }
    }

    private boolean moveXmlImpl  ( XmlCursor dst )
    {
        checkDisposed();

        if (dst == null || !(dst instanceof Cursor))
        {
            throw
                new IllegalArgumentException(
                    "Can't move to a foreign document" );
        }

        Cursor cDst = (Cursor) dst;

        checkDisposed( cDst );

        Root  rDst = cDst.getRoot();
        Splay sDst = cDst.getSplay();
        int   pDst = cDst.getPos();

        Root  rSrc = getRoot();
        Splay sSrc = getSplay();
        int   pSrc = getPos();

        if (sSrc.checkInsertionValidity( pSrc, sDst, pDst, true ))
        {
            return
                sSrc.moveChars(
                    rSrc, pSrc, getPostCch(), rDst, sDst, pDst, false ) > 0;
        }

        assert pSrc == 0;

        // Check for a movement of stuff into itself!  This case is basically
        // a no-op

        if (rSrc == rDst && sDst.between( rDst, pDst, sSrc ))
        {
// TODO - I might have to orphan types in the range here ....
            return false;
        }

        assert pSrc == 0;

        sSrc.move( rSrc, cDst.getRoot(), cDst.getSplay(), cDst.getPos(), true );

        return true;
    }

    public boolean copyXml ( XmlCursor dst )
    {
        if (dst == null)
            throw new IllegalArgumentException( "Destination is null" );

        if (dst.monitor() == monitor())
        {
            synchronized ( monitor() )
            {
                return copyXmlImpl( dst );
            }
        }
        else
        {
            boolean acquired = false;
            try
            {
                GlobalLock.acquire();
                acquired = true;
                synchronized ( monitor() )
                {
                    synchronized (dst.monitor())
                    {
                        GlobalLock.release();
                        acquired = false;

                        return copyXmlImpl( dst );
                    }
                }
            }
            catch (InterruptedException e)
            {
                throw new XmlRuntimeException(e.getMessage(), e);
            }
            finally
            {
                if (acquired)
                    GlobalLock.release();
            }
        }
    }

    private boolean copyXmlImpl ( XmlCursor dst )
    {
        checkDisposed();

        if (dst == null || !(dst instanceof Cursor))
        {
            throw
                new IllegalArgumentException( "Can't copy to a foreign document" );
        }

        Cursor cDst = (Cursor) dst;

        checkDisposed( cDst );

        Splay sDst = cDst.getSplay();
        int   pDst = cDst.getPos();

        Splay s = getSplay();
        int   p = getPos();

        if (s.checkInsertionValidity( p, sDst, pDst, true ))
            return copyCharsImpl( getPostCch(), dst ) > 0;

        assert p == 0;

        // Need to make a splay copy before getting the text because the copy
        // will validate invalid contents/values

        Root r = getRoot();
        Root rDst = cDst.getRoot();

        Splay copy = s.copySplay();

        Object txt = r._text;
        int cp = r.getCp( s );
        int cch = copy.getCchLeft() + copy.getCch();

        //
        // Remove text after which might be between leaf value and first attr value
        //

        if (s.isLeaf() && s.getCchAfter() > 0)
        {
            int cchValue = s.getCchValue();
            int cchAfter = s.getCchAfter();

            if (cchValue == 0)
                cp += cchAfter;
            else if (s.nextSplay().isAttr())
            {
                char[] buf = new char [ cch ];
                r._text.fetch( buf, 0, cp, cchValue );
                r._text.fetch( buf, cchValue, cp + cchValue + cchAfter, cch - cchValue );

                txt = buf;
                cp = 0;
            }
        }

        sDst.insert( rDst, pDst, copy, txt, cp, cch, true );

        return true;
    }

    public boolean removeXmlContents ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            // TODO - should implement this with internals

            if (!isContainer())
                return false;

            TokenType tt = toFirstContentToken();
            assert !tt.isNone();

            boolean removed = !isFinish();

            try
            {
                while ( !isFinish() )
                {
                    boolean b = removeXml();
                    assert b;
                }
            }
            finally
            {
                toParent();
            }

            return removed;
        }
    }

    private boolean contains ( XmlCursor dst )
    {
        if (isInSameDocument( dst ))
        {
            dst.push();

            for ( ; ; )
            {
                if (dst.isAtSamePositionAs( this ))
                {
                    dst.pop();
                    return true;
                }

                if (!dst.toParent())
                    break;
            }

            dst.pop();
        }

        return false;
    }

    public boolean moveXmlContents ( XmlCursor dst )
    {
        if (dst == null)
            throw new IllegalArgumentException( "Destination is null" );

        if (dst.monitor() == monitor())
        {
            synchronized ( monitor() )
            {
                return moveXmlContentsImpl( dst );
            }
        }
        else
        {
            boolean acquired = false;
            try
            {
                GlobalLock.acquire();
                acquired = true;
                synchronized ( monitor() )
                {
                    synchronized (dst.monitor())
                    {
                        GlobalLock.release();
                        acquired = false;

                        return moveXmlContentsImpl( dst );
                    }
                }
            }
            catch (InterruptedException e)
            {
                throw new XmlRuntimeException(e.getMessage(), e);
            }
            finally
            {
                if (acquired)
                    GlobalLock.release();
            }
        }
    }

    private boolean moveXmlContentsImpl ( XmlCursor dst )
    {
        checkDisposed();

        if (!isContainer())
            return false;

        // Check to see if dst is in src!  In this case, there is nothing to
        // do.

        if (contains( dst ))
            return false;

        TokenType tt = toFirstContentToken();
        assert !tt.isNone();

        boolean moved = !isFinish();

        try
        {
            if (!moveXmlImpl( dst ))
                return false;

            while ( !isFinish() )
            {
                boolean b = moveXmlImpl( dst );
                assert b;
            }
        }
        finally
        {
            toParent();
        }

        return moved;
    }

    public boolean copyXmlContents ( XmlCursor dst )
    {
        if (dst == null)
            throw new IllegalArgumentException( "Destination is null" );

        if (dst.monitor() == monitor())
        {
            synchronized ( monitor() )
            {
                return copyXmlContentsImpl( dst );
            }
        }
        else
        {
            boolean acquired = false;
            try
            {
                GlobalLock.acquire();
                acquired = true;
                synchronized ( monitor() )
                {
                    synchronized (dst.monitor())
                    {
                        GlobalLock.release();
                        acquired = false;

                        return copyXmlContentsImpl( dst );
                    }
                }
            }
            catch (InterruptedException e)
            {
                throw new XmlRuntimeException(e.getMessage(), e);
            }
            finally
            {
                if (acquired)
                    GlobalLock.release();
            }
        }
    }

    private boolean copyXmlContentsImpl ( XmlCursor dst )
    {
        checkDisposed();

        if (!isContainer())
            return false;

        // Check to see if dst is in src!  In this case, copy the src to a new
        // document and then move the copied contents to the destination.

        if (contains( dst ))
        {
            XmlCursor cTmp = XmlObject.Factory.newInstance().newCursor();

            cTmp.toNextToken();

            if (!copyXmlContentsImpl( cTmp ))
            {
                cTmp.dispose();
                return false;
            }

            cTmp.toStartDoc();
            ((Cursor)cTmp).moveXmlContentsImpl( dst );
            cTmp.dispose();
            return true;
        }

        TokenType tt = toFirstContentToken();
        assert !tt.isNone();

        boolean copied = !isFinish();

        try
        {
            if (!copyXmlImpl( dst ))
                return false;

            for ( ; ; )
            {
                if (isStart())
                    toEndToken();

                toNextToken();

                if (isFinish())
                    break;

                boolean b = copyXmlImpl( dst );
                assert b;
            }
        }
        finally
        {
            toParent();
        }

        return copied;
    }

    public boolean isInSameDocument ( XmlCursor xthat )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (xthat == null || !(xthat instanceof Cursor))
                return false;

            Cursor that = (Cursor) xthat;

            checkDisposed( that );

            return getRoot() == that.getRoot();
        }
    }

    public void push ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (_stack == null)
                _stack = new Selections();

            _stack.add( getRoot(), getSplay(), getPos() );

            getRoot().registerForChange( this );
        }
    }

    public boolean pop ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (_stack == null || _stack.size() == 0)
                return false;

            _stack.setCursor( this, _stack.size() - 1 );

            _stack.pop();

            return true;
        }
    }

    public int getSelectionCount ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return _selections == null ? 0 : _selections.size();
        }
    }

    public boolean toSelection ( int i )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (_selections != null && i >= 0 && _selections.setCursor( this, i ))
            {
                _currentSelection = i;
                return true;
            }

            return false;
        }
    }

    public boolean hasNextSelection ( )
    {
        synchronized ( monitor() )
        {
            push();
            int currentSelection = _currentSelection;

            try
            {
                return toNextSelection();
            }
            finally
            {
                pop();
                _currentSelection = currentSelection;
            }
        }
    }

    public boolean toNextSelection ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (_selections == null || _currentSelection < -1)
                return false;

            int nextSelection = _currentSelection + 1;

            if (!_selections.setCursor( this, nextSelection ))
            {
                _currentSelection = -2;
                return false;
            }

            _currentSelection = nextSelection;

            return true;
        }
    }

    public void clearSelections (  )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (_selections != null)
                _selections.dispose();

            _currentSelection = -2;
        }
    }

    public void addToSelection ( )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (_selections == null)
                _selections = Path.newSelections();

            // Force any selection engine to search all...
            _selections.size();

            _selections.add( getRoot(), getSplay(), getPos() );

            getRoot().registerForChange( this );
        }
    }

    public void changeNotification ( )
    {
        if (_selections != null)
        {
            _selections.size();  // Force a full selection
            _selections.cursify( getRoot() );
        }

        if (_stack != null)
            _stack.cursify( getRoot() );
    }

    public void selectPath ( String path, XmlOptions options )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            if (_selections == null)
                _selections = Path.newSelections();
            else
                _selections.dispose();

            _selections.init(
                Path.select( getRoot(), getSplay(), getPos(), path, options ) );

            push();

            if (_selections.setCursor( this, 0 ))
            {
                getRoot().registerForChange( this );
                _currentSelection = -1;
            }
            else
                _currentSelection = -2;

            pop();
        }
    }

    public void selectPath ( String path )
    {
        selectPath( path, null );
    }

    public XmlCursor execQuery ( String queryExpr, XmlOptions options )
    {
        synchronized ( monitor() )
        {
            checkDisposed();

            return Path.query( this, queryExpr, options );
        }
    }

    public XmlCursor execQuery ( String query )
    {
        return execQuery( query, null );
    }

    public Node newDomNode ( )
    {
        return newDomNode( null );
    }

    public Node newDomNode ( XmlOptions options )
    {
        try
        {
            Saver.DomSaver saver;

            synchronized ( monitor() )
            {
                checkDisposed();

                saver = new Saver.DomSaver(
                    getRoot(), getSplay(), getPos(), !isFragment(), options );
            }

            return saver.exportDom();
        }
        catch ( Exception e )
        {
            if (e instanceof RuntimeException)
                throw (RuntimeException) e;

            throw new RuntimeException( e.getMessage(), e );
        }
    }

    private boolean isFragment()
    {
        if (! isStartdoc())
            return true;

        boolean seenElement = false;

        XmlCursor c = newCursor();
        int token = c.toNextToken().intValue();

        try {

            LOOP:
            while (true)
            {
                SWITCH:
                switch (token)
                {
                    case TokenType.INT_START:
                        if (seenElement) return true;
                        seenElement = true;
                        token = c.toEndToken().intValue();
                        break SWITCH;

                    case TokenType.INT_TEXT:
                        if (! Splay.isWhiteSpace(c.getChars()))
                            return true;
                        token = c.toNextToken().intValue();
                        break SWITCH;


                    case TokenType.INT_NONE:
                    case TokenType.INT_ENDDOC:
                        break LOOP;


                    case TokenType.INT_ATTR:
                    case TokenType.INT_NAMESPACE:
                        return true;

                    case TokenType.INT_END:
                    case TokenType.INT_COMMENT:
                    case TokenType.INT_PROCINST:
                        token = c.toNextToken().intValue();
                        break SWITCH;

                    case TokenType.INT_STARTDOC:
                        assert false;
                        break LOOP;

                }

            }
        }

        finally {
            c.dispose();
        }

        return ! seenElement;

    }

    public void save ( ContentHandler ch, LexicalHandler lh )
        throws SAXException
    {
        save( ch, lh, null );
    }

    public void save ( File file ) throws IOException
    {
        save( file, null );
    }

    public void save ( OutputStream os ) throws IOException
    {
        save( os, null );
    }

    public void save ( Writer w ) throws IOException
    {
        save( w, null );
    }

    public void save ( ContentHandler ch, LexicalHandler lh, XmlOptions options)
        throws SAXException
    {
        // todo: don't hold the monitor all this long.
        // Ideally, we'd release the monitor each time we're about to call the
        // ch or lh objects.  However, the saver code isn't _quite_ structure
        // just right to do that.  So instead, the current version will hold
        // the monitor for the duration of the entire SAX save.
        synchronized ( monitor() )
        {
            checkDisposed();

            new Saver.SaxSaver( getRoot(), getSplay(), getPos(), options, ch, lh );
        }
    }

    public void save ( File file, XmlOptions options ) throws IOException
    {
        OutputStream os = new FileOutputStream( file );

        try
        {
            save( os, options );
        }
        finally
        {
            os.close();
        }
    }

    public void save ( OutputStream os, XmlOptions options ) throws IOException
    {
        // note that we do not hold the monitor for the duration of a save.
        // Instead, a concurrent modification exception is thrown if the
        // document is modified while the save is in progress. If the user
        // wishes to protect against this, he can synchronize on the monitor
        // himself.
        InputStream is = newInputStream( options );

        try
        {
            byte[] bytes = new byte[ 8192 ];

            for ( ; ; )
            {
                int n = is.read( bytes );

                if (n < 0)
                    break;

                os.write( bytes, 0, n );
            }
        }
        finally
        {
            is.close();
        }
    }

    public void save ( Writer w, XmlOptions options ) throws IOException
    {
        Reader r = newReader( options );

        try
        {
            char[] chars = new char[ 8192 ];

            for ( ; ; )
            {
                int n = r.read( chars );

                if (n < 0)
                    break;

                w.write( chars, 0, n );
            }
        }
        finally
        {
            r.close();
        }
    }

    //
    //
    //

    private boolean validate ( )
    {
        assert _goober.getRoot().validate();
        return true;
    }

    public void dump ( ) { _goober.getRoot().dump(); }
    public void dump ( boolean verbose ) { _goober.getRoot().dump( verbose ); }

    interface PathEngine
    {
        boolean next ( Selections selections );
    }

    static class Selections
    {
        void init ( PathEngine pathEngine )
        {
            dispose();

            _pathEngine = pathEngine;
        }

        void add ( Root r, Splay s )
        {
            add( r, s, 0 );
        }

        void add ( Root r, Splay s, int p )
        {
            assert s.getRootSlow() == r;

            if (_cursors != null)
            {
                CursorGoober g = new CursorGoober( r );

                g.set( s, p );

                _cursors.add( g );

                return;
            }

            if (_splays == null)
            {
                assert _count == 0;
                _splays = new Splay [ 16 ];
                _positions = new int [ 16 ];
            }
            else if (_count == _splays.length)
            {
                Splay[] newSplays = new Splay [ _count * 2 ];
                int[]   newPositions = new int [ _count * 2 ];

                System.arraycopy( _splays, 0, newSplays, 0, _count );
                System.arraycopy( _positions, 0, newPositions, 0, _count );

                _splays = newSplays;
                _positions = newPositions;
            }

            _splays[ _count ] = s;
            _positions[ _count ] = p;

            _count++;
        }

        void pop ( )
        {
            assert size() > 0;

            if (_cursors != null)
            {
                int i = _cursors.size() - 1;
                ((CursorGoober) _cursors.get( i )).set( null, 0 );
                _cursors.remove( i );
            }
            else
                _count--;
        }

        void cursify ( Root r )
        {
            if (_cursors != null || _count <= 0)
                return;

            _cursors = new ArrayList();

            for ( int i = 0 ; i < _count ; i++ )
            {
                CursorGoober g = new CursorGoober( r );

                g.set( _splays[ i ], _positions[ i ] );

                _cursors.add( g );
            }

            _count = 0;
        }

        int size ( )
        {
            if (_pathEngine != null)
            {
                while ( _pathEngine.next( this ) )
                    ;

                _pathEngine = null;
            }

            return currentSize();
        }

        int currentSize ( )
        {
            return _cursors != null ? _cursors.size() : _count;
        }

        boolean setCursor ( Cursor c, int i )
        {
            assert i >= 0;

            while ( _pathEngine != null && currentSize() <= i )
            {
                if (!_pathEngine.next( this ))
                    _pathEngine = null;
            }

            if (i >= currentSize())
                return false;

            if (_cursors != null)
            {
                assert i < _cursors.size();
                c.set( (CursorGoober) _cursors.get( i ) );
            }
            else
            {
                assert i < _count;
                c.set( _splays[ i ], _positions[ i ] );
            }

            return true;
        }

        void dispose ( )
        {
            if (_cursors != null)
            {
                for ( int i = 0 ; i < _cursors.size() ; i++ )
                    ((CursorGoober) _cursors.get( i )).set( null, 0 );

                _cursors.clear();

                _cursors = null;
            }

            _count = 0;

            // TODO - cache unused Seleciton objects for later reuse
        }

        private Splay[] _splays;
        private int[]   _positions;
        private int     _count;

        private ArrayList _cursors;

        private PathEngine _pathEngine;
    }

    //
    // XMLStreamReader
    //

    private static abstract class XMLStreamReaderBase
        implements XMLStreamReader, NamespaceContext, Location
    {
        XMLStreamReaderBase ( XmlCursor c )
        {
            _changeStamp = c.getDocChangeStamp();
        }

        protected void checkChanged ( )
        {
            if (_changeStamp.hasChanged())
                throw new ConcurrentModificationException( "Document changed while streaming" );
        }

        //
        // XMLStreamReader methods
        //

        public void close ( )
        {
            checkChanged();
        }

        public Location getLocation ( )
        {
            checkChanged();

            XmlCursor c = getCursor();

            XmlLineNumber ln = (XmlLineNumber) c.getBookmark( XmlLineNumber.class );

            // BUGBUG - put source name here
            _uri = null;

            if (ln != null)
            {
                _line = ln.getLine();
                _column = ln.getColumn();
                _offset = ln.getOffset();
            }
            else
            {
                _line = -1;
                _column = -1;
                _offset = -1;
            }

            return this;
        }

        public NamespaceContext getNamespaceContext ( )
        {
            checkChanged();

            return this;
        }

        public Object getProperty ( String name )
        {
            checkChanged();

            throw new RuntimeException( "Not implemented" );
        }

        public String getCharacterEncodingScheme ( )
        {
            checkChanged();

            XmlDocumentProperties props = getCursor().documentProperties();

            return props == null ? null : props.getEncoding();
        }

        public String getEncoding ( )
        {
            checkChanged();

            return null;
        }

        public String getVersion ( )
        {
            checkChanged();

            XmlDocumentProperties props = getCursor().documentProperties();

            return props == null ? null : props.getVersion();
        }

        public boolean isStandalone ( )
        {
            checkChanged();

            return false;
        }

        public boolean standaloneSet ( )
        {
            checkChanged();

            return false;
        }

        public void require ( int type, String namespaceURI, String localName )
            throws XMLStreamException
        {
            checkChanged();

            if (type != getEventType())
                throw new XMLStreamException();

            if (namespaceURI != null && !getNamespaceURI().equals( namespaceURI ))
                throw new XMLStreamException();

            if (localName != null && !getLocalName().equals( localName ))
                throw new XMLStreamException();
        }

        //
        // Location and NamespaceContext methods
        //

        public int    getCharacterOffset ( ) { return _offset; }
        public int    getColumnNumber    ( ) { return _column; }
        public int    getLineNumber      ( ) { return _line;   }
        public String getLocationURI     ( ) { return _uri;    }

        public String getNamespaceURI ( String prefix )
        {
            checkChanged();

            XmlCursor c = getCursor();

            boolean pop = false;

            if (!c.isContainer())
            {
                c.push();
                c.toParent();
                pop = true;
            }

            String ns = c.namespaceForPrefix( prefix );

            if (pop)
                c.pop();

            return ns;
        }

        public String getPrefix ( String namespaceURI )
        {
            checkChanged();

            XmlCursor c = getCursor();

            boolean pop = false;

            if (!c.isContainer())
            {
                c.push();
                c.toParent();
                pop = true;
            }

            HashMap map = new HashMap();

            c.getAllNamespaces( map );

            String prefix = (String) map.get( namespaceURI );

            if (pop)
                c.pop();

            return prefix;
        }

        public Iterator getPrefixes ( String namespaceURI )
        {
            checkChanged();

            // BUGBUG - get only one for now ...

            HashMap map = new HashMap();

            map.put( namespaceURI, getPrefix( namespaceURI ) );

            return map.values().iterator();
        }

        //
        //
        //

        protected abstract XmlCursor getCursor ( );

        //
        //
        //

        private ChangeStamp _changeStamp;
        String _uri;
        int _line, _column, _offset;
    }


    private static final class XMLStreamReaderForString extends XMLStreamReaderBase
    {
        XMLStreamReaderForString ( XmlCursor c, String s )
        {
            super( c );

            _cursor = c;

            _string = s == null ? "" : s;
        }

        protected XmlCursor getCursor ( )
        {
            return _cursor;
        }

        //
        // Legal stream methods
        //

        public int     getEventType      ( ) { checkChanged(); return CHARACTERS;            }
        public String  getText           ( ) { checkChanged(); return _string;               }
        public char[]  getTextCharacters ( ) { checkChanged(); return _string.toCharArray(); }
        public int     getTextStart      ( ) { checkChanged(); return 0;                     }
        public int     getTextLength     ( ) { checkChanged(); return _string.length();      }
        public boolean hasName           ( ) { checkChanged(); return false;                 }
        public boolean hasNext           ( ) { checkChanged(); return false;                 }
        public boolean hasText           ( ) { checkChanged(); return true;                  }
        public boolean isCharacters      ( ) { checkChanged(); return true;                  }
        public boolean isEndElement      ( ) { checkChanged(); return false;                 }
        public boolean isStartElement    ( ) { checkChanged(); return false;                 }

        public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length )
        {
            checkChanged();

            int sourceEnd = sourceStart + length;

            if (sourceEnd >= _string.length())
                sourceEnd = _string.length();

            _string.getChars( sourceStart, sourceEnd, target, targetStart );

            return sourceEnd - sourceStart;
        }

        public boolean isWhiteSpace ( )
        {
            checkChanged();

            for ( int i = 0 ; i < _string.length() ; i++ )
            {
                if (!Splay.isWhiteSpace( _string.charAt( i ) ))
                    return false;
            }

            return true;
        }

        //
        // Illegal stream methods
        //

        public int     getAttributeCount ( ) { throw new IllegalStateException(); }
        public String  getAttributeLocalName ( int index ) { throw new IllegalStateException(); }
        public QName   getAttributeName ( int index ) { throw new IllegalStateException(); }
        public String  getAttributeNamespace ( int index ) { throw new IllegalStateException(); }
        public String  getAttributePrefix ( int index ) { throw new IllegalStateException(); }
        public String  getAttributeType ( int index ) { throw new IllegalStateException(); }
        public String  getAttributeValue ( int index ) { throw new IllegalStateException(); }
        public String  getAttributeValue ( String namespaceURI, String localName ) { throw new IllegalStateException(); }
        public String  getElementText ( ) { throw new IllegalStateException(); }
        public String  getLocalName ( ) { throw new IllegalStateException(); }
        public QName   getName ( ) { throw new IllegalStateException(); }
        public int     getNamespaceCount ( ) { throw new IllegalStateException(); }
        public String  getNamespacePrefix ( int index ) { throw new IllegalStateException(); }
        public String  getNamespaceURI ( int index ) { throw new IllegalStateException(); }
        public String  getNamespaceURI ( ) { throw new IllegalStateException(); }
        public String  getPIData ( ) { throw new IllegalStateException(); }
        public String  getPITarget ( ) { throw new IllegalStateException(); }
        public String  getPrefix ( ) { throw new IllegalStateException(); }
        public boolean isAttributeSpecified ( int index ) { throw new IllegalStateException(); }
        public int     next ( ) { throw new IllegalStateException(); }
        public int     nextTag ( ) { throw new IllegalStateException(); }

        private XmlCursor _cursor;
        private String    _string;
    }

    private static final class XMLStreamReaderImpl extends XMLStreamReaderBase
    {
        XMLStreamReaderImpl ( XmlCursor start, XmlCursor last )
        {
            super( start );

            assert ! start.isAtSamePositionAs( last );

            _cursor = start;
            _last = last;
            _didLast = false;
        }

        protected XmlCursor getCursor ( )
        {
            return _cursor;
        }

        //
        //
        //

        public boolean hasNext ( )
        {
            checkChanged();

            return !_didLast;
        }

        public int next ( )
        {
            checkChanged();

            if (_didLast)
                throw new IllegalStateException();

            if (_cursor.isStart())
                _cursor.toFirstContentToken();
            else
                _cursor.toNextToken();

            if (_cursor.isAtSamePositionAs( _last ))
                _didLast = true;

            return getEventType();
        }

        public int getEventType ( )
        {
            checkChanged();

            switch ( _cursor.currentTokenType().intValue() )
            {
            case TokenType.INT_STARTDOC  : return START_DOCUMENT;
            case TokenType.INT_ENDDOC    : return END_DOCUMENT;
            case TokenType.INT_START     : return START_ELEMENT;
            case TokenType.INT_END       : return END_ELEMENT;
            case TokenType.INT_TEXT      : return CHARACTERS;
            case TokenType.INT_ATTR      : return ATTRIBUTE;
            case TokenType.INT_NAMESPACE : return NAMESPACE;
            case TokenType.INT_COMMENT   : return COMMENT;
            case TokenType.INT_PROCINST  : return PROCESSING_INSTRUCTION;

            default                      : throw new IllegalStateException();
            }
        }

        public int getAttributeCount ( )
        {
            checkChanged();

            int count = 0;

            if (_cursor.isAttr())
                count = 1;
            else if (_cursor.isStart())
            {
                _cursor.push();

                for ( _cursor.toNextToken() ; _cursor.isAnyAttr() ; _cursor.toNextToken() )
                    if (_cursor.isAttr())
                        count++;

                _cursor.pop();
            }
            else
                throw new IllegalStateException();

            return count;
        }

        public int getNamespaceCount ( )
        {
            checkChanged();

            int count = 0;

            if (_cursor.isNamespace())
                count = 1;
            else if (_cursor.isStart())
            {
                _cursor.push();

                for ( _cursor.toNextToken() ; _cursor.isAnyAttr() ; _cursor.toNextToken() )
                    if (_cursor.isNamespace())
                        count++;

                _cursor.pop();
            }
            else
                throw new IllegalStateException();

            return count;
        }

        private void toAttr ( int index )
        {
            if (index < 0)
                throw new IllegalArgumentException();

            if (_cursor.isAttr())
            {
                if (index > 0)
                    throw new IllegalArgumentException();
            }
            else if (_cursor.isStart())
            {
                for ( _cursor.toNextToken() ; _cursor.isAnyAttr() ; _cursor.toNextToken() )
                    if (_cursor.isAttr() && index-- == 0)
                        return;

                throw new IllegalArgumentException();
            }
            else
                throw new IllegalStateException();
        }

        private void toNamespace ( int index )
        {
            if (index < 0)
                throw new IllegalArgumentException();

            if (_cursor.isNamespace())
            {
                if (index > 0)
                    throw new IllegalArgumentException();
            }
            else if (_cursor.isStart())
            {
                for ( _cursor.toNextToken() ; _cursor.isAnyAttr() ; _cursor.toNextToken() )
                    if (_cursor.isNamespace() && index-- == 0)
                        return;

                throw new IllegalArgumentException();
            }
            else
                throw new IllegalStateException();
        }

        private boolean toAttr ( String namespaceURI, String localName )
        {
            if (namespaceURI == null || localName == null || localName.length() == 0)
                throw new IllegalArgumentException();

            QName qn = new QName( namespaceURI, localName );

            if (_cursor.isAttr())
            {
                return _cursor.getName().equals( qn );
            }
            else if (_cursor.isStart())
            {
                _cursor.toNextToken();

                while ( _cursor.isAnyAttr() )
                {
                    if (_cursor.isAttr() && _cursor.getName().equals( qn ))
                        return true;
                }

                return false;
            }
            else
                throw new IllegalStateException();
        }

        public String getAttributeLocalName ( int index )
        {
            checkChanged();

            _cursor.push();

            try
            {
                toAttr( index );

                return _cursor.getName().getLocalPart();
            }
            finally
            {
                _cursor.pop();
            }
        }

        public QName getAttributeName ( int index )
        {
            checkChanged();

            _cursor.push();

            try
            {
                toAttr( index );

                return _cursor.getName();
            }
            finally
            {
                _cursor.pop();
            }
        }

        public String getAttributeNamespace ( int index )
        {
            checkChanged();

            _cursor.push();

            try
            {
                toAttr( index );

                return _cursor.getName().getNamespaceURI();
            }
            finally
            {
                _cursor.pop();
            }
        }

        public String getAttributePrefix ( int index )
        {
            checkChanged();

            _cursor.push();

            try
            {
                toAttr( index );

                return getPrefix( _cursor.getName().getNamespaceURI() );
            }
            finally
            {
                _cursor.pop();
            }
        }

        public String getAttributeType ( int index )
        {
            checkChanged();

            _cursor.push();

            try
            {
                toAttr( index );

                return "CDATA";
            }
            finally
            {
                _cursor.pop();
            }
        }

        public String getAttributeValue ( int index )
        {
            checkChanged();

            _cursor.push();

            try
            {
                toAttr( index );

                return _cursor.getTextValue();
            }
            finally
            {
                _cursor.pop();
            }
        }

        public String getAttributeValue ( String namespaceURI, String localName )
        {
            checkChanged();

            _cursor.push();

            try
            {
                if (!toAttr( namespaceURI, localName ))
                    return null;

                return _cursor.getTextValue();
            }
            finally
            {
                _cursor.pop();
            }
        }

        public String getNamespacePrefix ( int index )
        {
            checkChanged();

            _cursor.push();

            try
            {
                toNamespace( index );

                return _cursor.getName().getLocalPart();
            }
            finally
            {
                _cursor.pop();
            }
        }

        public String getNamespaceURI ( int index )
        {
            checkChanged();

            _cursor.push();

            try
            {
                toNamespace( index );

                return _cursor.getName().getNamespaceURI();
            }
            finally
            {
                _cursor.pop();
            }
        }

        public String getElementText ( ) throws XMLStreamException
        {
            checkChanged();

            if (!isStartElement())
                throw new IllegalStateException();

            StringBuffer sb = new StringBuffer();

            for ( int depth = 1 ; depth > 0 ; )
            {
                if (!hasNext())
                    throw new XMLStreamException();

                int e = next();

                if (e == END_ELEMENT)
                {
                    depth--;
                    continue;
                }

                if (e == START_ELEMENT)
                    depth++;

                if (e != CHARACTERS)
                    throw new XMLStreamException();

                sb.append( getText() );
            }

            return sb.toString();
        }

        private QName getElemName ( )
        {
            _cursor.push();

            try
            {
                if (_cursor.isEnd())
                    _cursor.toParent();
                else if (!_cursor.isStart())
                    throw new IllegalStateException();

                return _cursor.getName();
            }
            finally
            {
                _cursor.pop();
            }
        }

        public QName getName ( )
        {
            checkChanged();

            return getElemName();
        }

        public String getLocalName ( )
        {
            checkChanged();

            return getElemName().getLocalPart();
        }

        public String getNamespaceURI ( )
        {
            checkChanged();

            return getElemName().getNamespaceURI();
        }

        public String getPIData ( )
        {
            checkChanged();

            if (!_cursor.isProcinst())
                throw new IllegalStateException();

            return _cursor.getTextValue();
        }

        public String getPITarget ( )
        {
            checkChanged();

            if (!_cursor.isProcinst())
                throw new IllegalStateException();

            return _cursor.getName().getLocalPart();
        }

        public String getPrefix ( )
        {
            checkChanged();

            return getPrefix( getNamespaceURI() );
        }

        public String getText ( )
        {
            checkChanged();

            if (_cursor.isComment())
                return _cursor.getTextValue();

            if (_cursor.isText())
                return _cursor.getChars();

            throw new IllegalStateException();
        }

        public char[] getTextCharacters ( )
        {
            checkChanged();

            return getText().toCharArray();
        }

        public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length )
        {
            checkChanged();

            if (length < 0)
                throw new IllegalStateException();

            char[] chars = getTextCharacters();

            if (length > chars.length)
                length = chars.length;

            System.arraycopy( chars, 0, target, targetStart, length );

            return length;
        }

        public int getTextLength ( )
        {
            checkChanged();

            return getText().length();
        }

        public int getTextStart ( )
        {
            checkChanged();

            return 0;
        }

        public boolean hasName ( )
        {
            checkChanged();

            try
            {
                getName();

                return true;
            }
            catch ( IllegalStateException e )
            {
                return false;
            }
        }

        public boolean hasText ( )
        {
            checkChanged();

            try
            {
                getText();

                return true;
            }
            catch ( IllegalStateException e )
            {
                return false;
            }
        }

        public boolean isAttributeSpecified ( int index )
        {
            checkChanged();

            return false;
        }

        public boolean isCharacters ( )
        {
            checkChanged();

            return _cursor.isText();
        }

        public boolean isEndElement ( )
        {
            checkChanged();

            return _cursor.isEnd();
        }

        public boolean isStartElement ( )
        {
            checkChanged();

            return _cursor.isStart();
        }

        public boolean isWhiteSpace ( )
        {
            checkChanged();

            try
            {
                String s = getText();

                for ( int i = 0 ; i < s.length() ; i++ )
                {
                    if (!Splay.isWhiteSpace( s.charAt( i ) ))
                        return false;
                }

                return true;
            }
            catch ( IllegalStateException e )
            {
                return false;
            }
        }

        public int nextTag ( ) throws XMLStreamException
        {
            checkChanged();

            for ( ; ; )
            {
                if (isStartElement() || isEndElement())
                    return getEventType();

                if (!isWhiteSpace())
                    throw new XMLStreamException();

                if (!hasNext())
                    throw new XMLStreamException();

                next();
            }
        }

        XmlCursor _cursor;
        XmlCursor _last;

        boolean   _didLast;
    }

    //
    //
    //

    final CursorGoober _goober;

    private Selections _stack;

    private Selections _selections;
    private int        _currentSelection;
}
