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

package org.apache.xmlbeans.impl.store;

import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.w3c.dom.DOMImplementation;

// DOM Level 3
import org.w3c.dom.UserDataHandler;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.TypeInfo;


import javax.xml.transform.Source;

import java.io.PrintStream;

import java.util.Iterator;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

import org.apache.xmlbeans.impl.soap.Detail;
import org.apache.xmlbeans.impl.soap.DetailEntry;
import org.apache.xmlbeans.impl.soap.MimeHeaders;
import org.apache.xmlbeans.impl.soap.Name;
import org.apache.xmlbeans.impl.soap.SOAPBody;
import org.apache.xmlbeans.impl.soap.SOAPBodyElement;
import org.apache.xmlbeans.impl.soap.SOAPElement;
import org.apache.xmlbeans.impl.soap.SOAPEnvelope;
import org.apache.xmlbeans.impl.soap.SOAPException;
import org.apache.xmlbeans.impl.soap.SOAPFactory;
import org.apache.xmlbeans.impl.soap.SOAPFault;
import org.apache.xmlbeans.impl.soap.SOAPFaultElement;
import org.apache.xmlbeans.impl.soap.SOAPHeader;
import org.apache.xmlbeans.impl.soap.SOAPHeaderElement;
import org.apache.xmlbeans.impl.soap.SOAPPart;
import org.apache.xmlbeans.impl.store.Xobj.Bookmark;

import org.apache.xmlbeans.impl.store.Locale.LoadContext;

import org.apache.xmlbeans.impl.store.DomImpl.Dom;
import org.apache.xmlbeans.impl.store.DomImpl.CharNode;
import org.apache.xmlbeans.impl.store.DomImpl.TextNode;
import org.apache.xmlbeans.impl.store.DomImpl.CdataNode;
import org.apache.xmlbeans.impl.store.DomImpl.SaajTextNode;
import org.apache.xmlbeans.impl.store.DomImpl.SaajCdataNode;

import org.apache.xmlbeans.CDataBookmark;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlLineNumber;
import org.apache.xmlbeans.SchemaField;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.QNameSet;
import org.apache.xmlbeans.XmlDocumentProperties;
import org.apache.xmlbeans.XmlCursor.XmlBookmark;

import org.apache.xmlbeans.impl.values.TypeStore;
import org.apache.xmlbeans.impl.values.TypeStoreUser;
import org.apache.xmlbeans.impl.values.TypeStoreVisitor;
import org.apache.xmlbeans.impl.values.TypeStoreUserFactory;

import javax.xml.namespace.QName;

import org.apache.xmlbeans.impl.common.ValidatorListener;
import org.apache.xmlbeans.impl.common.XmlLocale;
import org.apache.xmlbeans.impl.common.QNameHelper;


final class Cur
{
    static final int TEXT     = 0; // Must be 0
    static final int ROOT     = 1;
    static final int ELEM     = 2;
    static final int ATTR     = 3;
    static final int COMMENT  = 4;
    static final int PROCINST = 5;

    static final int POOLED       = 0;
    static final int REGISTERED   = 1;
    static final int EMBEDDED     = 2;
    static final int DISPOSED     = 3;

    static final int END_POS = -1;
    static final int NO_POS  = -2;

    Cur ( Locale l )
    {
        _locale = l;
        _pos = NO_POS;

        _tempFrame = -1;

        _state = POOLED;

        _stackTop = Locations.NULL;
        _selectionFirst = -1;
        _selectionN = -1;
        _selectionLoc = Locations.NULL;
        _selectionCount = 0;
    }

    boolean isPositioned ( ) { assert isNormal(); return _xobj != null; }

    static boolean kindIsContainer ( int k ) { return k ==  ELEM || k ==  ROOT; }
    static boolean kindIsFinish    ( int k ) { return k == -ELEM || k == -ROOT; }

    int kind ( )
    {
        assert isPositioned();
        int kind = _xobj.kind();
        return _pos == 0 ? kind : (_pos == END_POS ? - kind : TEXT);
    }

    boolean isRoot      ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == ROOT;     }
    boolean isElem      ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == ELEM;     }
    boolean isAttr      ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == ATTR;     }
    boolean isComment   ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == COMMENT;  }
    boolean isProcinst  ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == PROCINST; }
    boolean isText      ( ) { assert isPositioned(); return _pos > 0; }
    boolean isEnd       ( ) { assert isPositioned(); return _pos == END_POS && _xobj.kind() ==ELEM;}
    boolean isEndRoot   ( ) { assert isPositioned(); return _pos == END_POS && _xobj.kind() ==ROOT;}
    boolean isNode      ( ) { assert isPositioned(); return _pos == 0; }
    boolean isContainer ( ) { assert isPositioned(); return _pos == 0       && kindIsContainer( _xobj.kind() ); }
    boolean isFinish    ( ) { assert isPositioned(); return _pos == END_POS && kindIsContainer( _xobj.kind() ); }
    boolean isUserNode  ( ) { assert isPositioned(); int k = kind(); return k == ELEM || k == ROOT || (k == ATTR && !isXmlns()); }

    boolean isContainerOrFinish ( )
    {
        assert isPositioned();

        if (_pos!=0 && _pos!= END_POS)
            return false;

        int kind = _xobj.kind();
        return kind == ELEM || kind == -ELEM || kind == ROOT || kind == -ROOT;
    }

    boolean isNormalAttr ( ) { return isNode() && _xobj.isNormalAttr(); }
    boolean isXmlns      ( ) { return isNode() && _xobj.isXmlns(); }

    boolean isTextCData  ( ) { return _xobj.hasBookmark(CDataBookmark.class, _pos); }

    QName   getName  ( ) { assert isNode() || isEnd(); return _xobj._name; }
    String  getLocal ( ) { return getName().getLocalPart(); }
    String  getUri   ( ) { return getName().getNamespaceURI(); }

    String  getXmlnsPrefix ( ) { assert isXmlns(); return _xobj.getXmlnsPrefix(); }
    String  getXmlnsUri    ( ) { assert isXmlns(); return _xobj.getXmlnsUri(); }

    boolean isDomDocRoot  ( ) { return isRoot() && _xobj.getDom() instanceof Document; }
    boolean isDomFragRoot ( ) { return isRoot() && _xobj.getDom() instanceof DocumentFragment; }

    int cchRight ( ) { assert isPositioned(); return _xobj.cchRight( _pos ); }
    int cchLeft  ( ) { assert isPositioned(); return _xobj.cchLeft ( _pos ); }

    //
    // Creation methods
    //

    void createRoot ( )
    {
        createDomDocFragRoot();
    }

    void createDomDocFragRoot ( )
    {
        moveTo( new Xobj.DocumentFragXobj( _locale ) );
    }

    void createDomDocumentRoot ( )
    {
        moveTo( createDomDocumentRootXobj( _locale ) );
    }

    void createAttr ( QName name )
    {
        createHelper( new Xobj.AttrXobj( _locale, name ) );
    }

    void createComment ( )
    {
        createHelper( new Xobj.CommentXobj( _locale ) );
    }

    void createProcinst ( String target )
    {
        createHelper( new Xobj.ProcInstXobj( _locale, target ) );
    }

    void createElement ( QName name )
    {
        createElement( name, null );
    }

    void createElement ( QName name, QName parentName )
    {
        createHelper( createElementXobj( _locale, name, parentName ) );
    }

    static Xobj createDomDocumentRootXobj ( Locale l )
    {
        return createDomDocumentRootXobj(l, false);
    }

    static Xobj createDomDocumentRootXobj ( Locale l , boolean fragment)
    {
        Xobj xo;

        if (l._saaj == null)
            if (fragment)
                xo = new Xobj.DocumentFragXobj( l );
            else
                xo = new Xobj.DocumentXobj( l );
        else
            xo = new Xobj.SoapPartDocXobj( l );

        if (l._ownerDoc == null)
            l._ownerDoc = xo.getDom();

        return xo;
    }

    static Xobj createElementXobj ( Locale l, QName name, QName parentName )
    {
        if (l._saaj == null)
            return new Xobj.ElementXobj( l, name );

        Class c = l._saaj.identifyElement( name, parentName );

        if (c == SOAPElement.class)       return new Xobj.SoapElementXobj       ( l, name );
        if (c == SOAPBody.class)          return new Xobj.SoapBodyXobj          ( l, name );
        if (c == SOAPBodyElement.class)   return new Xobj.SoapBodyElementXobj   ( l, name );
        if (c == SOAPEnvelope.class)      return new Xobj.SoapEnvelopeXobj      ( l, name );
        if (c == SOAPHeader.class)        return new Xobj.SoapHeaderXobj        ( l, name );
        if (c == SOAPHeaderElement.class) return new Xobj.SoapHeaderElementXobj ( l, name );
        if (c == SOAPFaultElement.class)  return new Xobj.SoapFaultElementXobj  ( l, name );
        if (c == Detail.class)            return new Xobj.DetailXobj            ( l, name );
        if (c == DetailEntry.class)       return new Xobj.DetailEntryXobj       ( l, name );
        if (c == SOAPFault.class)         return new Xobj.SoapFaultXobj         ( l, name );

        throw new IllegalStateException( "Unknown SAAJ element class: " + c );
    }

    private void createHelper ( Xobj x )
    {
        assert x._locale == _locale;

        // insert the new Xobj into an exisiting tree.

        if (isPositioned())
        {
            Cur from = tempCur( x, 0 );
            from.moveNode( this );
            from.release();
        }

        moveTo( x );
    }

    //
    // General operations
    //

    boolean isSamePos ( Cur that )
    {
        assert isNormal() && (that == null || that.isNormal());

        return _xobj == that._xobj && _pos == that._pos;
    }

    // is this just after the end of that (that must be the start of a node)

    boolean isJustAfterEnd ( Cur that )
    {
        assert isNormal() && that != null && that.isNormal() && that.isNode();

        return that._xobj.isJustAfterEnd( _xobj, _pos );
    }

    boolean isJustAfterEnd ( Xobj x )
    {
        return x.isJustAfterEnd( _xobj, _pos );
    }

    boolean isAtEndOf ( Cur that )
    {
        assert that != null && that.isNormal() && that.isNode();

        return _xobj == that._xobj && _pos == END_POS;
    }

    boolean isInSameTree ( Cur that )
    {
        assert isPositioned() && that.isPositioned();

        return _xobj.isInSameTree( that._xobj );
    }

    // Retunr -1, 0 or 1 for relative cursor positions.  Return 2 is not in sames trees.

    int comparePosition ( Cur that )
    {
        assert isPositioned() && that.isPositioned();

        // If in differnet locales, then can't comapre

        if (_locale != that._locale)
            return 2;

        // No need to denormalize, but I want positions which I can compare (no END_POS)

        Xobj xThis = _xobj;
        int  pThis = _pos == END_POS ? xThis.posAfter() - 1 : _pos;

        Xobj xThat = that._xobj;
        int  pThat = that._pos == END_POS ? xThat.posAfter() - 1 : that._pos;

        // There are several cases:
        //
        // 1. Cursors are on the same xobj
        // 2. One cursor is a child of the other
        // 3. Cursors share a common parent
        // 4. Cursors are not in the same trees
        //
        // Check for the first, trivial, case.  Then, compute the depths of the nodes the
        // cursors are on, checkin for case 2
        //

        if (xThis == xThat)
            return pThis < pThat ? -1 : pThis == pThat ? 0 : 1;

        // Compute the depth of xThis.  See if I hit xThat (case 2)

        int dThis = 0;

        for ( Xobj x = xThis._parent ; x != null ; x = x._parent )
        {
            dThis++;

            if (x == xThat)
                return pThat < xThat.posAfter() - 1 ? 1 : -1;
        }

        // Compute the depth of xThat.  See if I hit xThis (case 2)

        int dThat = 0;

        for ( Xobj x = xThat._parent ; x != null ; x = x._parent )
        {
            dThat++;

            if (x == xThis)
                return pThis < xThis.posAfter() - 1 ? -1 : 1;
        }

        // Must be case 3 or 4 now.  Find a common parent.  If none, then it's case 4

        while ( dThis > dThat ) { dThis--; xThis = xThis._parent; }
        while ( dThat > dThis ) { dThat--; xThat = xThat._parent; }

        assert dThat == dThis;

        if (dThat == 0)
            return 2;

        assert xThis._parent != null && xThat._parent != null;

        while ( xThis._parent != xThat._parent )
        {
            if ((xThis = xThis._parent) == null)
                return 2;

            xThat = xThat._parent;
        }

        // Now, see where xThis and XThat are relative to eachother in the childlist.  Apply
        // some quick common checks before iterating.

        if (xThis._prevSibling == null || xThat._nextSibling == null)
            return -1;

        if (xThis._nextSibling == null || xThat._prevSibling == null)
            return 1;

        while ( xThis != null )
            if ((xThis = xThis._prevSibling) == xThat)
                return 1;

        return -1;
    }

    void setName ( QName newName )
    {
        assert isNode() && newName != null;

        _xobj.setName( newName );
    }

    void moveTo ( Xobj x )
    {
        moveTo( x, 0 );
    }

    void moveTo ( Xobj x, int p )
    {
        // This cursor may not be normalized upon entry, don't assert isNormal() here

        assert x == null || _locale == x._locale;
        assert x != null || p == NO_POS;
        assert x == null || x.isNormal( p ) ||  ( x.isVacant() && x._cchValue==0 && x._user == null );
        assert _state == REGISTERED || _state == EMBEDDED;
        assert _state == EMBEDDED || (_xobj == null || !isOnList( _xobj._embedded ));
        assert _state == REGISTERED || (_xobj != null && isOnList( _xobj._embedded ));

        moveToNoCheck( x, p );

        assert isNormal() ||  ( _xobj.isVacant() && _xobj._cchValue==0 && _xobj._user == null );
    }

    void moveToNoCheck ( Xobj x, int p )
    {
        if (_state == EMBEDDED && x != _xobj)
        {
            _xobj._embedded = listRemove( _xobj._embedded );
            _locale._registered = listInsert( _locale._registered );
            _state = REGISTERED;
        }

        _xobj = x;
        _pos = p;
    }

    void moveToCur ( Cur to )
    {
        assert isNormal() && (to == null || to.isNormal());

        if (to == null)
            moveTo( null, NO_POS );
        else
            moveTo( to._xobj, to._pos );
    }

    void moveToDom ( Dom d )
    {
        assert _locale == d.locale();
        assert d instanceof Xobj || d instanceof Xobj.SoapPartDom;

        moveTo( d instanceof Xobj ? (Xobj) d : ((Xobj.SoapPartDom) d)._docXobj );
    }

    static final class Locations
    {
        private static final int NULL = -1;

        Locations ( Locale l )
        {
            _locale = l;

            _xobjs = new Xobj [ _initialSize ];
            _poses = new int  [ _initialSize ];
            _curs  = new Cur  [ _initialSize ];
            _next  = new int  [ _initialSize ];
            _prev  = new int  [ _initialSize ];
            _nextN = new int  [ _initialSize ];
            _prevN = new int  [ _initialSize ];

            for ( int i = _initialSize - 1 ; i >= 0 ; i-- )
            {
                assert _xobjs[ i ] == null;
                _poses [ i ] = NO_POS;
                _next  [ i ] = i + 1;
                _prev  [ i ] = NULL;
                _nextN [ i ] = NULL;
                _prevN [ i ] = NULL;
            }

            _next [ _initialSize - 1 ] = NULL;

            _free = 0;
            _naked = NULL;
        }

        boolean isSamePos ( int i, Cur c )
        {
            if (_curs[ i ] == null)
                return c._xobj == _xobjs[ i ] && c._pos == _poses[ i ];
            else
                return c.isSamePos( _curs[ i ] );
        }

        boolean isAtEndOf ( int i, Cur c )
        {
            assert _curs[ i ] != null || _poses[ i ] == 0;
            assert _curs[ i ] == null || _curs[ i ].isNode();

            if (_curs[ i ] == null)
                return c._xobj == _xobjs[ i ] && c._pos == END_POS;
            else
                return c.isAtEndOf( _curs[ i ] );
        }

        void moveTo ( int i, Cur c )
        {
            if (_curs[ i ] == null)
                c.moveTo( _xobjs[ i ], _poses[ i ] );
            else
                c.moveToCur( _curs[ i ] );
        }

        int insert ( int head, int before, int i )
        {
            return insert( head, before, i, _next, _prev );
        }

        int remove ( int head, int i )
        {
            Cur c = _curs[ i ];

            assert c != null || _xobjs[ i ] != null;
            assert c != null || _xobjs[ i ] != null;

            if (c != null)
            {
                _curs[ i ].release();
                _curs[ i ] = null;

                assert _xobjs[ i ] == null;
                assert _poses [ i ] == NO_POS;
            }
            else
            {
                assert _xobjs[ i ] != null && _poses[ i ] != NO_POS;

                _xobjs[ i ] = null;
                _poses[ i ] = NO_POS;

                _naked = remove( _naked, i, _nextN, _prevN );
            }

            head = remove( head, i, _next, _prev );

            _next[ i ] = _free;
            _free = i;

            return head;
        }

        int allocate ( Cur addThis )
        {
            assert addThis.isPositioned();

            if (_free == NULL)
                makeRoom();

            int i = _free;

            _free = _next [ i ];

            _next [ i ] = NULL;
            assert _prev [ i ] == NULL;

            assert _curs [ i ] == null;
            assert _xobjs[ i ] == null;
            assert _poses[ i ] == NO_POS;

            _xobjs [ i ] = addThis._xobj;
            _poses [ i ] = addThis._pos;

            _naked = insert( _naked, NULL, i, _nextN, _prevN );

            return i;
        }

        private static int insert ( int head, int before, int i, int[] next, int[] prev )
        {
            if (head == NULL)
            {
                assert before == NULL;
                prev[ i ] = i;
                head = i;
            }
            else if (before != NULL)
            {
                prev[ i ] = prev[ before ];
                next[ i ] = before;
                prev[ before ] = i;

                if (head == before)
                    head = i;
            }
            else
            {
                prev[ i ] = prev[ head ];
                assert next[ i ] == NULL;
                next[ prev[ head ] ] = i;
                prev[ head ] = i;
            }

            return head;
        }

        private static int remove ( int head, int i, int[] next, int[] prev )
        {
            if (prev[ i ] == i)
            {
                assert head == i;
                head = NULL;
            }
            else
            {
                if (head == i)
                    head = next[ i ];
                else
                    next[ prev [ i ] ] = next[ i ];

                if (next[ i ] == NULL)
                    prev[ head ] = prev[ i ];
                else
                {
                    prev[ next[ i ] ] = prev[ i ];
                    next[ i ] = NULL;
                }
            }

            prev[ i ] = NULL;
            assert next[ i ] == NULL;

            return head;
        }

        void notifyChange ( )
        {
            for ( int i ; (i = _naked) != NULL ; )
            {
                assert _curs[ i ] == null && _xobjs[ i ] != null && _poses[ i ] != NO_POS;

                _naked = remove( _naked, i, _nextN, _prevN );

                _curs[ i ] = _locale.getCur();
                _curs[ i ].moveTo( _xobjs[ i ], _poses[ i ] );

                _xobjs[ i ] = null;
                _poses[ i ] = NO_POS;
            }
        }

        int next ( int i ) { return _next[ i ]; }
        int prev ( int i ) { return _prev[ i ]; }

        private void makeRoom ( )
        {
            assert _free == NULL;

            int l = _xobjs.length;

            Xobj [] oldXobjs = _xobjs;
            int  [] oldPoses = _poses;
            Cur  [] oldCurs  = _curs;
            int  [] oldNext  = _next;
            int  [] oldPrev  = _prev;
            int  [] oldNextN = _nextN;
            int  [] oldPrevN = _prevN;

            _xobjs = new Xobj [ l * 2 ];
            _poses = new int  [ l * 2 ];
            _curs  = new Cur  [ l * 2 ];
            _next  = new int  [ l * 2 ];
            _prev  = new int  [ l * 2 ];
            _nextN = new int  [ l * 2 ];
            _prevN = new int  [ l * 2 ];

            System.arraycopy( oldXobjs, 0, _xobjs, 0, l );
            System.arraycopy( oldPoses,  0, _poses, 0, l );
            System.arraycopy( oldCurs,  0, _curs,  0, l );
            System.arraycopy( oldNext,  0, _next,  0, l );
            System.arraycopy( oldPrev,  0, _prev,  0, l );
            System.arraycopy( oldNextN, 0, _nextN, 0, l );
            System.arraycopy( oldPrevN, 0, _prevN, 0, l );

            for ( int i = l * 2 - 1 ; i >= l ; i-- )
            {
                _next  [ i ] = i + 1;
                _prev  [ i ] = NULL;
                _nextN [ i ] = NULL;
                _prevN [ i ] = NULL;
                _poses [ i ] = NO_POS;
            }

            _next [ l * 2 - 1 ] = NULL;

            _free = l;
        }

        private static final int _initialSize = 32;

        private Locale _locale;

        private Xobj [] _xobjs;
        private int  [] _poses;
        private Cur  [] _curs;
        private int  [] _next;
        private int  [] _prev;
        private int  [] _nextN;
        private int  [] _prevN;

        private int _free;   // Unused entries
        private int _naked;  // Entries without Curs
    }

    void push ( )
    {
        assert isPositioned();

        int i = _locale._locations.allocate( this );
        _stackTop = _locale._locations.insert( _stackTop, _stackTop, i );
    }

    void pop ( boolean stay )
    {
        if (stay)
            popButStay();
        else
            pop();
    }

    void popButStay ( )
    {
        if (_stackTop != Locations.NULL)
            _stackTop = _locale._locations.remove( _stackTop, _stackTop );
    }

    boolean pop ( )
    {
        if (_stackTop == Locations.NULL)
            return false;

        _locale._locations.moveTo( _stackTop, this );
        _stackTop = _locale._locations.remove( _stackTop, _stackTop );

        return true;
    }

    boolean isAtLastPush ( )
    {
        assert _stackTop != Locations.NULL;

        return _locale._locations.isSamePos( _stackTop, this );
    }

    boolean isAtEndOfLastPush ( )
    {
        assert _stackTop != Locations.NULL;

        return _locale._locations.isAtEndOf( _stackTop, this );
    }

    void addToSelection ( Cur that )
    {
        assert that != null && that.isNormal();
        assert isPositioned() && that.isPositioned();

        int i = _locale._locations.allocate( that );
        _selectionFirst = _locale._locations.insert( _selectionFirst, Locations.NULL, i );

        _selectionCount++;
    }

    void addToSelection ( )
    {
        assert isPositioned();

        int i = _locale._locations.allocate( this );
        _selectionFirst = _locale._locations.insert( _selectionFirst, Locations.NULL, i );

        _selectionCount++;
    }

    private int selectionIndex ( int i )
    {
        assert _selectionN >= -1 && i >= 0 && i < _selectionCount;

        if (_selectionN == -1)
        {
            _selectionN = 0;
            _selectionLoc = _selectionFirst;
        }

        while ( _selectionN < i )
        {
            _selectionLoc = _locale._locations.next( _selectionLoc );
            _selectionN++;
        }

        while ( _selectionN > i )
        {
            _selectionLoc = _locale._locations.prev( _selectionLoc );
            _selectionN--;
        }

        return _selectionLoc;
    }

    void removeSelection ( int i )
    {
        assert i >= 0 && i < _selectionCount;

        int j = selectionIndex( i );

        // Update the nth selection indices to accomodate the deletion

        if (i < _selectionN)
            _selectionN--;
        else if (i == _selectionN)
        {
            _selectionN--;

            if (i == 0)
                _selectionLoc = Locations.NULL;
            else
                _selectionLoc = _locale._locations.prev( _selectionLoc );
        }

        _selectionFirst = _locale._locations.remove( _selectionFirst, j );

        _selectionCount--;
    }

    int selectionCount ( )
    {
        return _selectionCount;
    }

    void moveToSelection ( int i )
    {
        assert i >= 0 && i < _selectionCount;

        _locale._locations.moveTo( selectionIndex( i ), this );
    }

    void clearSelection ( )
    {
        assert _selectionCount >= 0;

        while ( _selectionCount > 0 )
            removeSelection( 0 );
    }

    boolean toParent    ( ) { return toParent( false ); }
    boolean toParentRaw ( ) { return toParent( true  ); }

    Xobj getParent    ( ) { return getParent( false ); }
    Xobj getParentRaw ( ) { return getParent( true  ); }

    boolean hasParent ( )
    {
        assert isPositioned();

        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter()))
            return true;

        assert _pos == 0 || _xobj._parent != null;

        return _xobj._parent != null;
    }

    Xobj getParentNoRoot()
    {
        assert isPositioned();

        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter()))
            return _xobj;

        assert _pos == 0 || _xobj._parent != null;

        if (_xobj._parent != null)
            return _xobj._parent;

        return null;
    }

    Xobj getParent ( boolean raw )
    {
        assert isPositioned();

        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter()))
            return _xobj;

        assert _pos == 0 || _xobj._parent != null;

        if (_xobj._parent != null)
            return _xobj._parent;

        if (raw || _xobj.isRoot())
            return null;

        Cur r = _locale.tempCur();

        r.createRoot();

        Xobj root = r._xobj;

        r.next();
        moveNode( r );
        r.release();

        return root;
    }

    boolean toParent ( boolean raw )
    {
        Xobj parent = getParent( raw );

        if (parent == null)
            return false;

        moveTo( parent );

        return true;
    }

    void toRoot ()
    {
        Xobj xobj = _xobj;
        while (!xobj.isRoot())
        {
            if (xobj._parent==null)
            {
                Cur r = _locale.tempCur();

                r.createRoot();

                Xobj root = r._xobj;

                r.next();
                moveNode( r );
                r.release();

                xobj = root;
                break;
            }
            xobj = xobj._parent;
        }
        moveTo(xobj);
    }

    boolean hasText ( )
    {
        assert isNode();

        return _xobj.hasTextEnsureOccupancy();
    }

    boolean hasAttrs ( )
    {
        assert isNode();

        return _xobj.hasAttrs();
    }

    boolean hasChildren ( )
    {
        assert isNode();

        return _xobj.hasChildren();
    }

    boolean toFirstChild ( )
    {
        assert isNode();

        if (!_xobj.hasChildren())
            return false;

        for ( Xobj x = _xobj._firstChild ; ; x = x._nextSibling )
        {
            if (!x.isAttr())
            {
                moveTo( x );
                return true;
            }
        }
    }

    protected boolean toLastChild ( )
    {
        assert isNode();

        if (!_xobj.hasChildren())
            return false;

        moveTo( _xobj._lastChild );

        return true;
    }

    boolean toNextSibling ( )
    {
        assert isNode();

        if (_xobj.isAttr())
        {
            if (_xobj._nextSibling != null && _xobj._nextSibling.isAttr())
            {
                moveTo( _xobj._nextSibling );
                return true;
            }
        }
        else if (_xobj._nextSibling != null)
        {
            moveTo( _xobj._nextSibling );
            return true;
        }

        return false;
    }

    void setValueAsQName ( QName qname )
    {
        assert isNode();

        String value  = qname.getLocalPart();
        String ns     = qname.getNamespaceURI();

        String prefix =
            prefixForNamespace(
                ns, qname.getPrefix().length() > 0 ? qname.getPrefix() : null, true );

        if (prefix.length() > 0)
            value = prefix + ":" + value;

        setValue( value );
    }

    void setValue ( String value )
    {
        assert isNode();

        moveNodeContents( null, false );

        next();

        insertString( value );

        toParent();
    }

    void removeFollowingAttrs ( )
    {
        assert isAttr();

        QName attrName = getName();

        push();

        if (toNextAttr())
        {
            while ( isAttr() )
            {
                if (getName().equals( attrName ))
                    moveNode( null );
                else if (!toNextAttr())
                    break;
            }
        }

        pop();
    }

    String getAttrValue ( QName name )
    {
        String s = null;

        push();

        if (toAttr( name ))
            s = getValueAsString();

        pop();

        return s;
    }

    void setAttrValueAsQName ( QName name, QName value )
    {
        assert isContainer();

        if (value == null)
        {
            _xobj.removeAttr( name );
        }
        else
        {
            if (toAttr( name ))
            {
                removeFollowingAttrs();
            }
            else
            {
                next();
                createAttr( name );
            }

            setValueAsQName( value );

            toParent();
        }
    }

    boolean removeAttr ( QName name )
    {
        assert isContainer();

        return _xobj.removeAttr( name );
    }

    void setAttrValue ( QName name, String value )
    {
        assert isContainer();

        _xobj.setAttr( name, value );
    }

    boolean toAttr ( QName name )
    {
        assert isNode();

        Xobj a = _xobj.getAttr( name );

        if (a == null)
            return false;

        moveTo( a );

        return true;
    }

    boolean toFirstAttr ( )
    {
        assert isNode();

        Xobj firstAttr = _xobj.firstAttr();

        if (firstAttr == null)
            return false;

        moveTo( firstAttr );

        return true;
    }

    boolean toLastAttr ( )
    {
        assert isNode();

        if (!toFirstAttr())
            return false;

        while ( toNextAttr() )
            ;

        return true;
    }

    boolean toNextAttr ( )
    {
        assert isAttr() || isContainer();

        Xobj nextAttr = _xobj.nextAttr();

        if (nextAttr == null)
            return false;

        moveTo( nextAttr );

        return true;
    }

    boolean toPrevAttr ( )
    {
        if (isAttr())
        {
            if (_xobj._prevSibling == null)
                moveTo( _xobj.ensureParent() );
            else
                moveTo( _xobj._prevSibling );

            return true;
        }

        prev();

        if (!isContainer())
        {
            next();
            return false;
        }

        return toLastAttr();
    }

    boolean skipWithAttrs ( )
    {
        assert isNode();

        if (skip())
            return true;

        if (_xobj.isRoot())
            return false;

        assert _xobj.isAttr();

        toParent();

        next();

        return true;
    }

    boolean skip ( )
    {
        assert isNode();

        if (_xobj.isRoot())
            return false;

        if (_xobj.isAttr())
        {
            if (_xobj._nextSibling == null || !_xobj._nextSibling.isAttr())
                return false;

            moveTo( _xobj._nextSibling, 0 );
        }
        else
            moveTo( getNormal( _xobj, _xobj.posAfter() ), _posTemp );

        return true;
    }

    void toEnd ( )
    {
        assert isNode();

        moveTo( _xobj, END_POS );
    }

    void moveToCharNode ( CharNode node )
    {
        assert node.getDom() != null && node.getDom().locale() == _locale;

        moveToDom( node.getDom() );

        CharNode n;

        _xobj.ensureOccupancy();

        n = _xobj._charNodesValue =
            updateCharNodes( _locale, _xobj, _xobj._charNodesValue, _xobj._cchValue );

        for ( ; n != null ; n = n._next )
        {
            if (node == n)
            {
                moveTo( getNormal( _xobj, n._off + 1 ), _posTemp );
                return;
            }
        }

        n = _xobj._charNodesAfter =
            updateCharNodes( _locale, _xobj, _xobj._charNodesAfter, _xobj._cchAfter );

        for ( ; n != null ; n = n._next )
        {
            if (node == n)
            {
                moveTo( getNormal( _xobj, n._off + _xobj._cchValue + 2 ), _posTemp );
                return;
            }
        }

        assert false;
    }

    boolean prevWithAttrs ( )
    {
        if (prev())
            return true;

        if (!isAttr())
            return false;

        toParent();

        return true;
    }

    boolean prev ( )
    {
        assert isPositioned();

        if (_xobj.isRoot() && _pos == 0)
            return false;

        if (_xobj.isAttr() && _pos == 0 && _xobj._prevSibling == null)
            return false;

        Xobj x = getDenormal();
        int  p = _posTemp;

        assert p > 0 && p != END_POS;

        int pa = x.posAfter();

        if (p > pa)
            p = pa;
        else if (p == pa)
        {
            // Text after an attr is allowed only on the last attr,
            // and that text belongs to the parent container..
            //
            // If we're a thte end of the last attr, then we were just
            // inside the container, and we need to skip the attrs.

            if (x.isAttr() &&
                (x._cchAfter > 0 || x._nextSibling == null || !x._nextSibling.isAttr()))
            {
                x = x.ensureParent();
                p = 0;
            }
            else
                p = END_POS;
        }
        else if (p == pa - 1)
        {
            x.ensureOccupancy();
            p = x._cchValue > 0 ? 1 : 0;
        }
        else if (p > 1)
            p = 1;
        else
        {
            assert p == 1;
            p = 0;
        }

        moveTo( getNormal( x, p ), _posTemp );

        return true;
    }

    boolean next ( boolean withAttrs )
    {
        return withAttrs ? nextWithAttrs() : next();
    }

    boolean nextWithAttrs ( )
    {
        int k = kind();

        if (kindIsContainer( k ))
        {
            if (toFirstAttr())
                return true;
        }
        else if (k == -ATTR)
        {
            if (next())
                return true;

            toParent();

            if (!toParentRaw())
                return false;
        }

        return next();
    }

    boolean next ( )
    {
        assert isNormal();

        Xobj x = _xobj;
        int  p = _pos;

        int pa = x.posAfter();

        if (p >= pa)
            p = _xobj.posMax();
        else if (p == END_POS)
        {
            if (x.isRoot() || (x.isAttr() && (x._nextSibling == null || !x._nextSibling.isAttr())))
                return false;

            p = pa;
        }
        else if (p > 0)
        {
            assert x._firstChild == null || !x._firstChild.isAttr();

            if (x._firstChild != null)
            {
                x = x._firstChild;
                p = 0;
            }
            else
                p = END_POS;
        }
        else
        {
            assert p == 0;

            x.ensureOccupancy();

            p = 1;

            if (x._cchValue == 0)
            {
                if (x._firstChild != null)
                {
                    if (x._firstChild.isAttr())
                    {
                        Xobj a = x._firstChild;

                        while ( a._nextSibling != null && a._nextSibling.isAttr() )
                            a = a._nextSibling;

                        if (a._cchAfter > 0)
                        {
                            x = a;
                            p = a.posAfter();
                        }
                        else if (a._nextSibling != null)
                        {
                            x = a._nextSibling;
                            p = 0;
                        }
                    }
                    else
                    {
                        x = x._firstChild;
                        p = 0;
                    }
                }
            }
        }

        moveTo( getNormal( x, p ), _posTemp );

        return true;
    }

    int prevChars ( int cch )
    {
        assert isPositioned();

        int cchLeft = cchLeft();

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

        // Dang, I love this stmt :-)

        if (cch != 0)
            moveTo( getNormal( getDenormal(), _posTemp - cch ), _posTemp );

        return cch;
    }

    int nextChars ( int cch )
    {
        assert isPositioned();

        int cchRight = cchRight();

        if (cchRight == 0)
            return 0;

        if (cch < 0 || cch >= cchRight)
        {
            // Use next to not skip over children
            next();
            return cchRight;
        }

        moveTo( getNormal( _xobj, _pos + cch ), _posTemp );

        return cch;
    }

    void setCharNodes ( CharNode nodes )
    {
        assert nodes == null || _locale == nodes.locale();
        assert isPositioned();

        Xobj x = getDenormal();
        int  p = _posTemp;

        assert !x.isRoot() || (p > 0 && p < x.posAfter());

        if (p >= x.posAfter())
            x._charNodesAfter = nodes;
        else
            x._charNodesValue = nodes;

        for ( ; nodes != null ; nodes = nodes._next )
            nodes.setDom( (Dom) x );

        // No Need to notify text change or alter version, text nodes are
        // not part of the infoset
    }

    CharNode getCharNodes ( )
    {
        assert isPositioned();
        assert !isRoot();

        Xobj x = getDenormal();

        CharNode nodes;

        if (_posTemp >= x.posAfter())
        {
            nodes = x._charNodesAfter =
                updateCharNodes( _locale, x, x._charNodesAfter, x._cchAfter );
        }
        else
        {
            x.ensureOccupancy();

            nodes = x._charNodesValue =
                updateCharNodes( _locale, x, x._charNodesValue, x._cchValue );
        }

        return nodes;
    }

   // private
    static CharNode updateCharNodes ( Locale l, Xobj x, CharNode nodes, int cch )
    {
        assert nodes == null || nodes.locale() == l;

        CharNode node = nodes;
        int i = 0;

        while ( node != null && cch > 0 )
        {
            assert node.getDom() == x;

            if (node._cch > cch)
                node._cch = cch;

            node._off = i;
            i += node._cch;
            cch -= node._cch;

            node = node._next;
        }

        if (cch <= 0)
        {
            for ( ; node != null ; node = node._next )
            {
                assert node.getDom() == x;

                if (node._cch != 0)
                    node._cch = 0;

                node._off = i;
            }
        }
        else
        {
            node = l.createTextNode();
            node.setDom( (Dom) x );
            node._cch = cch;
            node._off = i;
            nodes = CharNode.appendNode( nodes, node );
        }

        return nodes;
    }

    final QName getXsiTypeName ( )
    {
        assert isNode();

        return _xobj.getXsiTypeName();
    }

    final void setXsiType ( QName value )
    {
        assert isContainer();

        setAttrValueAsQName( Locale._xsiType, value );
    }

    final QName valueAsQName ( )
    {
        throw new RuntimeException( "Not implemented" );
    }

    final String namespaceForPrefix ( String prefix, boolean defaultAlwaysMapped )
    {
        return _xobj.namespaceForPrefix( prefix, defaultAlwaysMapped );
    }

    final String prefixForNamespace ( String ns, String suggestion, boolean createIfMissing )
    {
        return
            (isContainer() ? _xobj : getParent()).
                prefixForNamespace( ns, suggestion, createIfMissing );
    }

    // Does the node at this cursor properly contain the position specified by the argument

    boolean contains ( Cur that )
    {
        assert isNode();
        assert that != null && that.isPositioned();

        return _xobj.contains( that );
    }

    void insertString ( String s )
    {
        if (s != null)
            insertChars( s, 0, s.length() );
    }

    void insertChars ( Object src, int off, int cch )
    {
        assert isPositioned() && !isRoot();
        assert CharUtil.isValid( src, off, cch );

        // Check for nothing to insert

        if (cch <= 0)
            return;

        _locale.notifyChange();

        // The only situation where I need to ensure occupancy is when I'm at the end of a node.
        // All other positions will require occupancy.  For example, if I'm at the beginning of a
        // node, then I will either insert in the after text of the previous sibling, or I will
        // insert in the value of the parent.  In the latter case, because the parent has a child,
        // it cannot be vacant.

        if (_pos == END_POS)
            _xobj.ensureOccupancy();

        // Get the denormailized Xobj and pos.  This is the Xobj which will actually receive
        // the new chars.  Note that a denormalized position can never be <= 0.

        Xobj x = getDenormal();
        int  p = _posTemp;

        assert p > 0;

        // This will move "this" cursor to be after the inserted text. No worries, I'll update its
        // position after.  This insertChars takes care of all the appropriate invalidations
        // (passing true as last arg).

        x.insertCharsHelper( p, src, off, cch, true );

        // Reposition the cursor to be just before the newly inserted text.  It's current
        // position could have been shifted, or it may have been just before the end tag, or
        // normalized on another Xobj.

        moveTo( x, p );

        _locale._versionAll++;
    }

    // Move the chars just after this Cur to the "to" Cur.  If no "to" Cur is specified,
    // then remove the chars.

    Object moveChars ( Cur to, int cchMove )
    {
        assert isPositioned();
        assert cchMove <= 0 || cchMove <= cchRight();
        assert to == null || (to.isPositioned() && !to.isRoot());

        if (cchMove < 0)
            cchMove = cchRight();

        // If we're instructed to move 0 characters, then return the null triple.

        if (cchMove == 0)
        {
            _offSrc = 0;
            _cchSrc = 0;

            return null;
        }

        // Here I record the triple of the chars to move.  I will return this.  No need to save
        // cch 'cause cchMove will be that value.

        Object srcMoved = getChars( cchMove );
        int    offMoved = _offSrc;

        // Either I'm moving text from the value or the after text.  If after, then the container
        // must be occupied.  If in the value, because we're just before text, it must be occupied.

        assert isText() && (_pos >= _xobj.posAfter() ? _xobj._parent : _xobj).isOccupied();

        if (to == null)
        {
            // In this case, I'm removing chars vs moving them.  Normally I would like to blow
            // them away entirely, but if there are any references to those chars via a bookmark
            // I need to keep them alive.  I do this by moving these chars to a new root.  Note
            // that because Curs will stay behind, I don't have to check for them.

            for ( Bookmark b = _xobj._bookmarks ; b != null ; b = b._next )
            {
                if (inChars( b, cchMove, false ))
                {
                    Cur c = _locale.tempCur();

                    c.createRoot();
                    c.next();

                    Object chars = moveChars( c, cchMove );

                    c.release();

                    return chars;
                }
            }
        }
        else
        {
            // If the target, "to", is inside or on the edge of the text to be moved, then this
            // is a no-op.  In this case, I still want to return the text "moved".
            //
            // Note how I move "to" and this cur around.  I move "to" to be at the beginning of the
            // chars moved and "this" to be at the end.  If the text were really moving to a
            // different location, then "to" would be at the beginning of the newly moved chars,
            // and "this" would be at the gap left by the newly removed chars.

            if (inChars( to, cchMove, true ))
            {
                // BUGBUG - may want to consider shuffling the interior cursors to the right just
                // like I move "this" to the right...

                to.moveToCur( this );
                nextChars( cchMove );

                _offSrc = offMoved;
                _cchSrc = cchMove;

                return srcMoved;
            }

            // Copy the chars here, I'll remove the originals next

            to.insertChars( srcMoved, offMoved, cchMove );
        }

        // Notice that I can delay the general change notification to this point because any
        // modifications up to this point are made by calling other high level operations which
        // generate this notification themselves.  Also, no need to notify of general change in
        // the "to" locale because the insertion of chars above handles that.

        _locale.notifyChange();

        //
        //if ( _xobj != null )
        {
            if (to == null)
                _xobj.removeCharsHelper( _pos, cchMove, null, NO_POS, false, true );
            else
                _xobj.removeCharsHelper( _pos, cchMove, to._xobj, to._pos, false, true );
        }

        // Need to update the position of this cursor even though it did not move anywhere.  This
        // needs to happen because it may not be properly normalized anymore.  Note that because
        // of the removal of the text, this cur may not be normal any more, thus I call moveTo
        // which does not assume this.

        _locale._versionAll++;

        _offSrc = offMoved;
        _cchSrc = cchMove;

        return srcMoved;
    }

    void moveNode ( Cur to )
    {
        assert isNode() && !isRoot();
        assert to == null || to.isPositioned();
        assert to == null || !contains( to );
        assert to == null || !to.isRoot();

        // TODO - should assert that is an attr is being moved, it is ok there


        // Record the node to move and skip this cur past it.  This moves this cur to be after
        // the move to move/remove -- it's final resting place.  The only piece of information
        // about the source of the move is the node itself.

        Xobj x = _xobj;

        skip();

        // I call another function here to move the node.  I do this because  I don't have to
        // worry about messing with "this" here given that it not should be treated like any other
        // cursor after this point.

        moveNode( x, to );
    }

    // Moves text from one place to another in a low-level way, used as a helper for the higher
    // level functions.  Takes care of moving bookmarks and cursors.  In the high level content
    // manipulation functions, cursors do not follow content, but this helper moves them.  The
    // arguments are denormalized.  The Xobj's must be different from eachother but from the same
    // locale.  The destination must not be not be vacant.

    private static void transferChars ( Xobj xFrom, int pFrom, Xobj xTo, int pTo, int cch )
    {
        assert xFrom != xTo;
        assert xFrom._locale == xTo._locale;
        assert pFrom > 0 && pFrom <  xFrom.posMax();
        assert pTo   > 0 && pTo   <= xTo  .posMax();
        assert cch > 0 && cch <= xFrom.cchRight( pFrom );
        assert pTo >= xTo.posAfter() || xTo.isOccupied();

        // Copy the chars from -> to without performing any invalidations.  This will scoot curs
        // and marks around appropriately.  Note that I get the cars with getCharsHelper which
        // does not check for normalization because the state of the tree at this moment may not
        // exactly be "correct" here.

        xTo.insertCharsHelper(
            pTo, xFrom.getCharsHelper( pFrom, cch ),
            xFrom._locale._offSrc, xFrom._locale._cchSrc, false );

        xFrom.removeCharsHelper( pFrom, cch, xTo, pTo, true, false );
    }

    // Moves the node x to "to", or removes it if to is null.

    static void moveNode ( Xobj x, Cur to )
    {
        assert x != null && !x.isRoot();
        assert to == null || to.isPositioned();
        assert to == null || !x.contains( to );
        assert to == null || !to.isRoot();

        if (to != null)
        {
            // Before I go much further, I want to make sure that if "to" is in the container of
            // a vacant node, I get it occupied.  I do not need to worry about the source being
            // vacant.

            if (to._pos == END_POS)
                to._xobj.ensureOccupancy();

            // See if the destination is on the edge of the node to be moved (a no-op).  It is
            // illegal to call this fcn when to is contained within the node to be moved.  Note
            // that I make sure that to gets oved to the beginning of the node.  The position of
            // to in all operations should leave to just before the content moved/inserted.

            if ((to._pos == 0 && to._xobj == x) || to.isJustAfterEnd( x ))
            {
                // TODO - should shuffle contained curs to the right???

                to.moveTo( x );
                return;
            }
        }

        // Notify the locale(s) about the change I am about to make.

        x._locale.notifyChange();

        x._locale._versionAll++;
        x._locale._versionSansText++;

        if (to != null && to._locale != x._locale)
        {
            to._locale.notifyChange();

            to._locale._versionAll++;
            to._locale._versionSansText++;
        }

        // Node is going away.  Invalidate the parent (the text around the node is merging).
        // Also, this node may be an attribute -- invalidate special attrs ...

        if (x.isAttr())
            x.invalidateSpecialAttr( to == null ? null : to.getParentRaw() );
        else
        {
            if (x._parent != null)
                x._parent.invalidateUser();

            if (to != null && to.hasParent())
                to.getParent().invalidateUser();
        }

        // If there is any text after x, I move it to be before x.  This frees me to extract x
        // and it's contents with out this text coming along for the ride.  Note that if this
        // node is the last attr and there is text after it, transferText will move the text
        // to a potential previous attr.  This is an invalid state for a short period of time.
        // I need to move this text away here so that when I walk the tree next, *all* curs
        // embedded in this node or deeper will be moved off this node.

        if (x._cchAfter > 0)
            transferChars( x, x.posAfter(), x.getDenormal( 0 ), x.posTemp(), x._cchAfter );

        assert x._cchAfter == 0;

        // Walk the node tree, moving curs out, disconnecting users and relocating to a, possibly,
        // new locale.  I embed the cursors in this locale before itersting to just cause the
        // embed to happen once.

        x._locale.embedCurs();

        for ( Xobj y = x ; y != null ; y = y.walk( x, true ) )
        {
            while ( y._embedded != null )
                y._embedded.moveTo( x.getNormal( x.posAfter() ) );

            y.disconnectUser();

            if (to != null)
                y._locale = to._locale;
        }

        // Now, actually remove the node

        x.removeXobj();

        // Now, if there is a destination, insert the node there and shuffle the text in the
        // vicinity of the destination appropriately.

        if (to != null)
        {
            // To know where I should insert/append the node to move, I need to see where "to"
            // would be if there were no text after it.  However, I need to keep "to" where it
            // is when I move the text after it later.

            Xobj here = to._xobj;
            boolean append = to._pos != 0;

            int cchRight = to.cchRight();

            if (cchRight > 0)
            {
                to.push();
                to.next();
                here = to._xobj;
                append = to._pos != 0;
                to.pop();
            }

            if (append)
                here.appendXobj( x );
            else
                here.insertXobj( x );

            // The only text I need to move is that to the right of "to".  Even considering all
            // the cases where an attribute is involed!

            if (cchRight > 0)
                transferChars( to._xobj, to._pos, x, x.posAfter(), cchRight );

            to.moveTo( x );
        }
    }

    void moveNodeContents ( Cur to, boolean moveAttrs )
    {
        assert _pos==0;
        assert to == null || !to.isRoot();

        // By calling this helper, I do not have to deal with this Cur any longer.  Basically,
        // this Cur is out of the picture, it behaves like any other cur at this point.

        moveNodeContents( _xobj, to, moveAttrs );
    }

    static void moveNodeContents ( Xobj x, Cur to, boolean moveAttrs )
    {
        // TODO - should assert that is an attr is being moved, it is ok there

        assert to == null || !to.isRoot();

        // Collect a bit of information about the contents to move first.  Note that the collection
        // of this info must not cause a vacant value to become occupied.

        boolean hasAttrs = x.hasAttrs();
        boolean noSubNodesToMove = !x.hasChildren() && (!moveAttrs || !hasAttrs);

        // Deal with the cases where only text is involved in the move

        if (noSubNodesToMove)
        {
            // If we're vacant and there is no place to move a potential value, then I can avoid
            // acquiring the text from the TypeStoreUser.  Otherwise, there may be text here I
            // need to move somewhere else.

            if (x.isVacant() && to == null)
            {
                x.clearBit( Xobj.VACANT );

                x.invalidateUser();
                x.invalidateSpecialAttr( null );
                x._locale._versionAll++;
            }
            else if (x.hasTextEnsureOccupancy())
            {
                Cur c = x.tempCur();
                c.next();
                c.moveChars( to, -1 );
                c.release();
            }

            return;
        }

        // Here I check to see if "to" is just inside x.  In this case this is a no-op.  Note that
        // the value of x may still be vacant.

        if (to != null)
        {
            // Quick check of the right edge.  If it is there, I need to move "to" to the left edge
            // so that it is positioned at the beginning of the "moved" content.

            if (x == to._xobj && to._pos == END_POS)
            {
                // TODO - shuffle interior curs?

                to.moveTo( x );
                to.next( moveAttrs && hasAttrs );

                return;
            }

            // Here I need to see if to is at the left edge.  I push to's current position and
            // then navigate it to the left edge then compare it to the pushed position...
            // Note: gotta be careful to make sure to and x are not in different locales, curs
            // may not go to a different locale.

            boolean isAtLeftEdge = false;

            if (to._locale == x._locale)
            {
                to.push();
                to.moveTo( x );
                to.next( moveAttrs && hasAttrs );
                isAtLeftEdge = to.isAtLastPush();
                to.pop();
            }

            // TODO - shuffle interior curs?

            if (isAtLeftEdge)
                return;

            // Now, after dealing with the edge condition, I can assert that to is not inside x

            assert !x.contains( to );

            // So, at this point, I've taken case of the no-op cases and the movement of just text.
            // Also, to must be occupied because I took care of the text only and nothing to move
            // cases.

            assert to.getParent().isOccupied();
        }

        // TODO - did I forget to put a changeNotification here?  Look more closely ...

        // Deal with the value text of x which is either on x or the last attribute of x.
        // I need to get it out of the way to properly deal with the walk of the contents.
        // In order to reposition "to" properly later, I need to record how many chars were moved.

        int valueMovedCch = 0;

        if (x.hasTextNoEnsureOccupancy())
        {
            Cur c = x.tempCur();
            c.next();
            c.moveChars( to, -1 );
            c.release();

            if (to != null)
                to.nextChars( valueMovedCch = c._cchSrc );
        }

        // Now, walk all the contents, invalidating special attrs, reportioning cursors,
        // disconnecting users and relocating to a potentially different locale.  Because I moved
        // the value text above, no top level attrs should have any text.

        x._locale.embedCurs();

        Xobj firstToMove = x.walk( x, true );
        boolean sawBookmark = false;

        for ( Xobj y = firstToMove ; y != null ; y = y.walk( x, true ) )
        {
            if (y._parent == x && y.isAttr())
            {
                assert y._cchAfter == 0;

                if (!moveAttrs)
                {
                    firstToMove = y._nextSibling;
                    continue;
                }

                y.invalidateSpecialAttr( to == null ? null : to.getParent() );
            }

            for ( Cur c ; (c = y._embedded) != null ; )
                c.moveTo( x, END_POS );

            y.disconnectUser();

            if (to != null)
                y._locale = to._locale;

            sawBookmark = sawBookmark || y._bookmarks != null;
        }

        Xobj lastToMove = x._lastChild;

        // If there were any bookmarks in the tree to remove, to preserve the content that these
        // bookmarks reference, move the contents to a new root.  Note that I already moved the
        // first piece of text above elsewhere.  Note: this has the effect of keeping all of the
        // contents alive even if there is one bookmark deep into the tree.  I should really
        // disband all the content, except for the pieces which are bookmarked.

        Cur surragateTo = null;

        if (sawBookmark && to == null)
        {
            surragateTo = to = x._locale.tempCur();
            to.createRoot();
            to.next();
        }

        // Perform the rest of the invalidations.  If only attrs are moving, then no user
        // invalidation needed.  If I've move text to "to" already, no need to invalidate
        // again.

        if (!lastToMove.isAttr())
            x.invalidateUser();

        x._locale._versionAll++;
        x._locale._versionSansText++;

        if (to != null && valueMovedCch == 0)
        {
            to.getParent().invalidateUser();
            to._locale._versionAll++;
            to._locale._versionSansText++;
        }

        // Remove the children and, if needed, move them

        x.removeXobjs( firstToMove, lastToMove );

        if (to != null)
        {
            // To know where I should insert/append the contents to move, I need to see where "to"
            // would be if there were no text after it.

            Xobj here = to._xobj;
            boolean append = to._pos != 0;

            int cchRight = to.cchRight();

            if (cchRight > 0)
            {
                to.push();
                to.next();
                here = to._xobj;
                append = to._pos != 0;
                to.pop();
            }

            // Now, I have to shuffle the text around "to" in special ways.  A complication is
            // the insertion of attributes.  First, if I'm inserting attrs here then, logically,
            // there can be no text to the left because attrs can only live after another attr
            // or just inside a container.  So, If attrs are being inserted and there is value
            // text on the target container, I will need to move this value text to be after
            // the lew last attribute.  Note that this value text may already live on a current
            // last attr (before the inserting).  Also, I need to figure this all out before I
            // move the text after "to" because this text may end up being sent to the same place
            // as the containers value text when the last new node being inserted is an attr!
            // Whew!

            if (firstToMove.isAttr())
            {
                Xobj lastNewAttr = firstToMove;

                while ( lastNewAttr._nextSibling != null && lastNewAttr._nextSibling.isAttr() )
                    lastNewAttr = lastNewAttr._nextSibling;

                // Get to's parnet now before I potentially move him with the next transfer

                Xobj y = to.getParent();

                if (cchRight > 0)
                    transferChars( to._xobj, to._pos, lastNewAttr, lastNewAttr.posMax(), cchRight );

                if (y.hasTextNoEnsureOccupancy())
                {
                    int p, cch;

                    if (y._cchValue > 0)
                    {
                        p = 1;
                        cch = y._cchValue;
                    }
                    else
                    {
                        y = y.lastAttr();
                        p = y.posAfter();
                        cch = y._cchAfter;
                    }

                    transferChars( y, p, lastNewAttr, lastNewAttr.posAfter(), cch );
                }
            }
            else if (cchRight > 0)
                transferChars( to._xobj, to._pos, lastToMove, lastToMove.posMax(), cchRight );

            // After mucking with the text, splice the new tree in

            if (append)
                here.appendXobjs( firstToMove, lastToMove );
            else
                here.insertXobjs( firstToMove, lastToMove );

            // Position "to" to be at the beginning of the newly inserted contents

            to.moveTo( firstToMove );
            to.prevChars( valueMovedCch );
        }

        // If I consed up a to, release it here

        if (surragateTo != null)
            surragateTo.release();
    }

    protected final Bookmark setBookmark ( Object key, Object value )
    {
        assert isNormal();
        assert key != null;

        return _xobj.setBookmark( _pos, key, value );
    }

    Object getBookmark ( Object key )
    {
        assert isNormal();
        assert key != null;

        for ( Bookmark b = _xobj._bookmarks ; b != null ; b = b._next )
            if (b._pos == _pos && b._key == key)
                return b._value;

        return null;
    }

    int firstBookmarkInChars ( Object key, int cch )
    {
        assert isNormal();
        assert key != null;
        assert cch > 0;
        assert cch <= cchRight();

        int d = -1;

        if (isText())
        {
            for ( Bookmark b = _xobj._bookmarks ; b != null ; b = b._next )
                if (b._key == key && inChars( b, cch, false ))
                    d = (d == -1 || b._pos - _pos < d) ? b._pos - _pos : d;
        }

        return d;
    }

    int firstBookmarkInCharsLeft ( Object key, int cch )
    {
        assert isNormal();
        assert key != null;
        assert cch > 0;
        assert cch <= cchLeft();

        int d = -1;

        if (cchLeft() > 0)
        {
            Xobj x = getDenormal();
            int  p = _posTemp - cch;

            for ( Bookmark b = x._bookmarks ; b != null ; b = b._next )
                if (b._key == key && x.inChars( p, b._xobj, b._pos, cch, false ))
                    d = (d == -1 || b._pos - p < d) ? b._pos - p : d;
        }

        return d;
    }

    String getCharsAsString ( int cch )
    {
        assert isNormal() && _xobj != null;

        return getCharsAsString( cch, Locale.WS_PRESERVE );
    }

    String getCharsAsString ( int cch, int wsr )
    {
        return _xobj.getCharsAsString( _pos, cch, wsr );
    }

    String getValueAsString ( int wsr )
    {
        assert isNode();

        return _xobj.getValueAsString( wsr );
    }

    String getValueAsString ( )
    {
        assert isNode();
        assert ! hasChildren();

        return _xobj.getValueAsString();
    }

    Object getChars ( int cch )
    {
        assert isPositioned();

        return _xobj.getChars( _pos, cch, this );
    }

    Object getFirstChars ( )
    {
        assert isNode();

        Object src = _xobj.getFirstChars();

        _offSrc = _locale._offSrc;
        _cchSrc = _locale._cchSrc;

        return src;
    }

    void copyNode ( Cur to )
    {
        assert to != null;
        assert isNode();

        Xobj copy = _xobj.copyNode( to._locale );

        // TODO - in the moveNode case, I would not have to walk the tree for cursors ... optimize

        if (to.isPositioned())
            Cur.moveNode( copy, to );
        else
            to.moveTo( copy );
    }

    Cur weakCur ( Object o )
    {
        Cur c = _locale.weakCur( o );
        c.moveToCur( this );
        return c;
    }

    Cur tempCur ( )
    {
        return tempCur( null );
    }

    Cur tempCur ( String id )
    {
        Cur c = _locale.tempCur( id );
        c.moveToCur( this );
        return c;
    }

    private Cur tempCur ( Xobj x, int p )
    {
        assert _locale == x._locale;
        assert x != null || p == NO_POS;

        Cur c = _locale.tempCur();

        if (x != null)
            c.moveTo( getNormal( x, p ), _posTemp );

        return c;
    }

    // Is a cursor (c) in the chars defined by cch chars after where this Cur is positioned.
    // Is inclusive on the left, and inclusive/exclusive on the right depending on the value
    // of includeEnd.

    boolean inChars ( Cur c, int cch, boolean includeEnd )
    {
        assert isPositioned() && isText() && cchRight() >= cch;
        assert c.isNormal();

        return _xobj.inChars( _pos, c._xobj, c._pos, cch, includeEnd );
    }

    boolean inChars ( Bookmark b, int cch, boolean includeEnd )
    {
        assert isPositioned() && isText() && cchRight() >= cch;
        assert b._xobj.isNormal( b._pos );

        return _xobj.inChars( _pos, b._xobj, b._pos, cch, includeEnd );
    }

    // Can't be static because I need to communicate pos in _posTemp :-(
    // I wish I had multiple return vars ...

    private Xobj getNormal ( Xobj x, int p )
    {
        Xobj nx = x.getNormal( p );
        _posTemp = x._locale._posTemp;
        return nx;
    }

    private Xobj getDenormal ( )
    {
        assert isPositioned();

        return getDenormal( _xobj, _pos );
    }

    private Xobj getDenormal ( Xobj x, int p )
    {
        Xobj dx = x.getDenormal( p );
        _posTemp = x._locale._posTemp;
        return dx;
    }

    // May throw IllegalArgumentException if can't change the type

    void setType ( SchemaType type )
    {
        setType( type, true );
    }

    void setType ( SchemaType type, boolean complain )
    {
        assert type != null;
        assert isUserNode();

        TypeStoreUser user = peekUser();

        if (user != null && user.get_schema_type() == type)
            return;

        if (isRoot())
        {
            _xobj.setStableType( type );
            return;
        }

        // Gotta get the parent user to make sure this type is ok here

        TypeStoreUser parentUser = _xobj.ensureParent().getUser();

        // One may only set the type of an attribute to its 'natural' type because
        // attributes cannot take advantage of the xsiType attribute.

        if (isAttr())
        {
            if (complain && parentUser.get_attribute_type( getName() ) != type)
            {
                throw
                    new IllegalArgumentException(
                        "Can't set type of attribute to " + type.toString() );
            }

            return;
        }

        assert isElem();

        // First check to see if this type can be here sans xsi:type.
        // If so, make sure there is no xsi:type

        if (parentUser.get_element_type( getName(), null ) == type)
        {
            removeAttr( Locale._xsiType );
            return;
        }

        // If the desired type has no name, then it cannot be
        // referenced via xsi:type

        QName typeName = type.getName();

        if (typeName == null)
        {
            if (complain)
                throw new IllegalArgumentException( "Can't set type of element, type is un-named" );
            else
                return;
        }

        // See if setting xsiType would result in the target type

        if (parentUser.get_element_type( getName(), typeName ) != type)
        {
            if (complain)
                throw new IllegalArgumentException( "Can't set type of element, invalid type" );
            else
                return;
        }

        setAttrValueAsQName( Locale._xsiType, typeName );
    }

    void setSubstitution ( QName name, SchemaType type )
    {
        setSubstitution( name, type, true );
    }
    
    void setSubstitution ( QName name, SchemaType type, boolean complain )
    {
        assert name != null;
        assert type != null;
        assert isUserNode();

        TypeStoreUser user = peekUser();

        if (user != null && user.get_schema_type() == type && name.equals(getName()))
            return;

        if (isRoot())
        {
            // If this is the root node, we can't set its name, so the whole
            // operation is aborted
            return;
        }

        // Gotta get the parent user to make sure this type is ok here

        TypeStoreUser parentUser = _xobj.ensureParent().getUser();

        // One may only set the type of an attribute to its 'natural' type because
        // attributes cannot take advantage of the xsiType attribute.

        if (isAttr())
        {
            if (complain)
            {
                throw
                    new IllegalArgumentException(
                        "Can't use substitution with attributes");
            }

            return;
        }

        assert isElem();

        // First check to see if this type can be here sans xsi:type.
        // If so, make sure there is no xsi:type

        if (parentUser.get_element_type( name, null ) == type)
        {
            setName( name );
            removeAttr( Locale._xsiType );
            return;
        }

        // If the desired type has no name, then it cannot be
        // referenced via xsi:type

        QName typeName = type.getName();

        if (typeName == null)
        {
            if (complain)
                throw new IllegalArgumentException( "Can't set xsi:type on element, type is un-named" );
            else
                return;
        }

        // See if setting xsiType would result in the target type
        
        if (parentUser.get_element_type( name, typeName ) != type)
        {
            if (complain)
                throw new IllegalArgumentException( "Can't set xsi:type on element, invalid type" );
            else
                return;
        }

        setName( name );
        setAttrValueAsQName( Locale._xsiType, typeName );
    }

    TypeStoreUser peekUser ( )
    {
        assert isUserNode();

        return _xobj._user;
    }

    XmlObject getObject ( )
    {
        return isUserNode() ? (XmlObject) getUser() : null;
    }

    TypeStoreUser getUser ( )
    {
        assert isUserNode();

        return _xobj.getUser();
    }

    Dom getDom ( )
    {
        assert isNormal();
        assert isPositioned();

        if (isText())
        {
            int cch = cchLeft();

            for ( CharNode cn = getCharNodes() ; ; cn = cn._next )
                if ((cch -= cn._cch) < 0)
                    return cn;
        }

        return _xobj.getDom();
    }

    static void release ( Cur c )
    {
        if (c != null)
            c.release();
    }

    void release ( )
    {
        if (_tempFrame >= 0)
        {
            if (_nextTemp != null)
                _nextTemp._prevTemp = _prevTemp;

            if (_prevTemp == null)
                _locale._tempFrames[ _tempFrame ] = _nextTemp;
            else
                _prevTemp._nextTemp = _nextTemp;

            _prevTemp = _nextTemp = null;
            _tempFrame = -1;
        }

        if (_state != POOLED && _state != DISPOSED)
        {
            // Clean up any state

            while ( _stackTop != -1 )
                popButStay();

            clearSelection();

            _id = null;

            // Unposition

            moveToCur( null );

            assert isNormal();

            assert _xobj == null;
            assert _pos  == NO_POS;

            // Release weak reference and attacked value

            if (_ref != null)
            {
                _ref.clear();
                _ref._cur = null;
            }

            _ref = null;

            // Unregister and either diapose of cursor or add it back to pool

            assert _state == REGISTERED;
            _locale._registered = listRemove( _locale._registered );

            if (_locale._curPoolCount < 16)
            {
                _locale._curPool = listInsert( _locale._curPool );
                _state = POOLED;
                _locale._curPoolCount++;
            }
            else
            {
                _locale = null;
                _state = DISPOSED;
            }
        }
    }

    boolean isOnList ( Cur head )
    {
        for ( ; head != null ; head = head._next )
            if (head == this)
                return true;

        return false;
    }

    Cur listInsert ( Cur head )
    {
        assert _next == null && _prev == null;

        if (head == null)
            head = _prev = this;
        else
        {
            _prev = head._prev;
            head._prev = head._prev._next = this;
        }

        return head;
    }

    Cur listRemove ( Cur head )
    {
        assert _prev != null && isOnList( head );

        if (_prev == this)
            head = null;
        else
        {
            if (head == this)
                head = _next;
            else
                _prev._next = _next;

            if (_next == null)
                head._prev = _prev;
            else
            {
                _next._prev = _prev;
                _next = null;
            }
        }

        _prev = null;
        assert _next == null;

        return head;
    }

//    boolean isNormal ( Cur that )
//    {
//        return isNormal() && (that == null || (_locale == that._locale && that.isNormal()));
//    }

    boolean isNormal ( )
    {
        if (_state == POOLED || _state == DISPOSED)
            return false;

        if (_xobj == null)
            return _pos == NO_POS;

        if (!_xobj.isNormal( _pos ))
            return false;

        if (_state == EMBEDDED)
            return isOnList( _xobj._embedded );

        assert _state == REGISTERED;

        return isOnList( _locale._registered );
    }

    static final String LOAD_USE_LOCALE_CHAR_UTIL = "LOAD_USE_LOCALE_CHAR_UTIL";

    static final class CurLoadContext extends LoadContext
    {
        CurLoadContext ( Locale l, XmlOptions options )
        {
            options = XmlOptions.maskNull( options );

            _locale = l;

            _charUtil =
                options.hasOption( LOAD_USE_LOCALE_CHAR_UTIL )
                    ? _locale.getCharUtil()
                    : CharUtil.getThreadLocalCharUtil();

            _frontier = createDomDocumentRootXobj( _locale );
            _after = false;

            _lastXobj = _frontier;
            _lastPos  = 0;

            if (options.hasOption( XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT ))
            {
                _replaceDocElem = (QName) options.get( XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT );
                _discardDocElem = true;
            }

            _stripWhitespace = options.hasOption( XmlOptions.LOAD_STRIP_WHITESPACE );
            _stripComments   = options.hasOption( XmlOptions.LOAD_STRIP_COMMENTS   );
            _stripProcinsts  = options.hasOption( XmlOptions.LOAD_STRIP_PROCINSTS  );

            _substituteNamespaces = (Map) options.get( XmlOptions.LOAD_SUBSTITUTE_NAMESPACES );
            _additionalNamespaces = (Map) options.get( XmlOptions.LOAD_ADDITIONAL_NAMESPACES );

            _locale._versionAll++;
            _locale._versionSansText++;
        }

        //
        // Really primitive load context operations
        //

        private void start ( Xobj xo )
        {
            assert _frontier != null;
            assert !_after || _frontier._parent != null;

            flushText();

            if (_after)
            {
                _frontier = _frontier._parent;
                _after = false;
            }

            _frontier.appendXobj( xo );
            _frontier = xo;

            _lastXobj = xo;
            _lastPos  = 0;
        }

        private void end ( )
        {
            assert _frontier != null;
            assert !_after || _frontier._parent != null;

            flushText();

            if (_after)
                _frontier = _frontier._parent;
            else
                _after = true;

            _lastXobj = _frontier;
            _lastPos  = END_POS;
        }

        private void text ( Object src, int off, int cch )
        {
            if (cch <= 0)
                return;

            _lastXobj = _frontier;
            _lastPos  = _frontier._cchValue + 1;

            if (_after)
            {
                _lastPos += _frontier._cchAfter + 1;

                _frontier._srcAfter =
                    _charUtil.saveChars(
                        src, off, cch,
                        _frontier._srcAfter, _frontier._offAfter, _frontier._cchAfter );

                _frontier._offAfter = _charUtil._offSrc;
                _frontier._cchAfter = _charUtil._cchSrc;

            }
            else
            {
                _frontier._srcValue =
                    _charUtil.saveChars(
                        src, off, cch,
                        _frontier._srcValue, _frontier._offValue, _frontier._cchValue );

                _frontier._offValue = _charUtil._offSrc;
                _frontier._cchValue = _charUtil._cchSrc;
            }
        }

        private void flushText ( )
        {
            if (_stripWhitespace)
            {
                if (_after)
                {
                    _frontier._srcAfter =
                        _charUtil.stripRight(
                            _frontier._srcAfter, _frontier._offAfter, _frontier._cchAfter );

                    _frontier._offAfter = _charUtil._offSrc;
                    _frontier._cchAfter = _charUtil._cchSrc;
                }
                else
                {
                    _frontier._srcValue =
                        _charUtil.stripRight(
                            _frontier._srcValue, _frontier._offValue, _frontier._cchValue );

                    _frontier._offValue = _charUtil._offSrc;
                    _frontier._cchValue = _charUtil._cchSrc;
                }
            }
        }

        private Xobj parent ( )
        {
            return _after ? _frontier._parent : _frontier;
        }

        private QName checkName ( QName name, boolean local )
        {
            if (_substituteNamespaces != null && (!local || name.getNamespaceURI().length() > 0))
            {
                String substituteUri = (String) _substituteNamespaces.get( name.getNamespaceURI() );

                if (substituteUri != null)
                    name = _locale.makeQName( substituteUri, name.getLocalPart(), name.getPrefix());
            }

            return name;
        }

        //
        //
        //

        protected void startDTD (String name, String publicId, String systemId )
        {
            _doctypeName = name;
            _doctypePublicId = publicId;
            _doctypeSystemId = systemId;
        }
        
        protected void endDTD ( )
        {
        }
        
        protected void startElement ( QName name )
        {
            start( createElementXobj( _locale, checkName( name, false ), parent()._name ) );
            _stripLeft = true;
        }

        protected void endElement ( )
        {
            assert parent().isElem();

            end();
            _stripLeft = true;
        }

        protected void xmlns ( String prefix, String uri )
        {
            assert parent().isContainer();
            // BUGBUG - should assert there that there is no text before this attr

            // Namespace attrs are different than regular attrs -- I don't change their name,
            // I change their value!

            if (_substituteNamespaces != null)
            {
                String substituteUri = (String) _substituteNamespaces.get( uri );

                if (substituteUri != null)
                    uri = substituteUri;
            }

            Xobj x = new Xobj.AttrXobj( _locale, _locale.createXmlns( prefix ) );

            start( x );
            text( uri, 0, uri.length() );
            end();

            _lastXobj = x;
            _lastPos  = 0;
        }

        protected void attr ( QName name, String value )
         {
            assert parent().isContainer();
            // BUGBUG - should assert there that there is no text before this attr

            QName parentName = _after?
                _lastXobj._parent.getQName(): _lastXobj.getQName();
            boolean isId = isAttrOfTypeId(name, parentName);

            Xobj x = isId ?
                new Xobj.AttrIdXobj(_locale, checkName(name, true)) :
                new Xobj.AttrXobj(_locale, checkName(name, true));
            start(x);
            text(value, 0, value.length());
            end();
            if (isId)
            {
                Cur c1 = x.tempCur();
                c1.toRoot();
                Xobj doc = c1._xobj;
                c1.release();
                if (doc instanceof Xobj.DocumentXobj)
                    ((Xobj.DocumentXobj) doc).addIdElement(value,
                        x._parent.getDom());
            }
            _lastXobj = x;
            _lastPos = 0;
        }
        protected void attr ( String local, String uri, String prefix, String value )
        {
            attr( _locale.makeQName( uri, local, prefix ), value );
        }

        protected void procInst ( String target, String value )
        {
            if (!_stripProcinsts)
            {
                Xobj x = new Xobj.ProcInstXobj( _locale, target );

                start( x );
                text( value, 0, value.length() );
                end();

                _lastXobj = x;
                _lastPos  = 0;
            }
            _stripLeft = true;
        }

        protected void comment ( String comment )
        {
            if (!_stripComments)
                comment( comment, 0, comment.length() );
            _stripLeft = true;
        }

        protected void comment ( char[] chars, int off, int cch )
        {
            if (!_stripComments)
            {
                comment(
                    _charUtil.saveChars( chars, off, cch ),
                    _charUtil._offSrc, _charUtil._cchSrc );
            }
            _stripLeft = true;
        }

        private void comment ( Object src, int off, int cch )
        {
            Xobj x = new Xobj.CommentXobj( _locale );

            start( x );
            text( src, off, cch );
            end();

            _lastXobj = x;
            _lastPos  = 0;
        }

        private boolean _stripLeft = true;

        private void stripText ( Object src, int off, int cch )
        {
            if (_stripWhitespace)
            {
                // this is to avoid bug in cases like <company>Procter &amp; Gamble</company>
                if (_stripLeft)
                {
                    src = _charUtil.stripLeft( src, off, cch );
                    _stripLeft = false;
                    off = _charUtil._offSrc;
                    cch = _charUtil._cchSrc;
                }
            }

            text( src, off, cch );
        }

        protected void text ( String s )
        {
            if (s == null)
                return;

            stripText( s, 0, s.length() );
        }

        protected void text ( char[] src, int off, int cch )
        {
            stripText( src, off, cch );
        }

        protected void bookmark ( XmlBookmark bm )
        {
            _lastXobj.setBookmark( _lastPos, bm.getKey(), bm );
        }

        protected void bookmarkLastNonAttr ( XmlBookmark bm )
        {
            if (_lastPos > 0 || !_lastXobj.isAttr())
                _lastXobj.setBookmark( _lastPos, bm.getKey(), bm );
            else
            {
                assert _lastXobj._parent != null;

                _lastXobj._parent.setBookmark( 0, bm.getKey(), bm );
            }
        }

        protected void bookmarkLastAttr ( QName attrName, XmlBookmark bm )
        {
            if (_lastPos == 0 && _lastXobj.isAttr())
            {
                assert _lastXobj._parent != null;

                Xobj a = _lastXobj._parent.getAttr( attrName );

                if (a != null)
                    a.setBookmark( 0, bm.getKey(), bm );
            }
        }

        protected void lineNumber ( int line, int column, int offset )
        {
            _lastXobj.setBookmark(
                _lastPos,
                XmlLineNumber.class,
                new XmlLineNumber( line, column, offset ) );
        }

        protected void abort ( )
        {
            _stripLeft = true;
            while ( !parent().isRoot() )
                end();

            finish().release();
        }

        protected Cur finish ( )
        {
            flushText();

            if (_after)
                _frontier = _frontier._parent;

            assert _frontier != null && _frontier._parent == null && _frontier.isRoot();

            Cur c = _frontier.tempCur();

            if (!Locale.toFirstChildElement( c ))
                return c;

            // See if the document element is a fragment

            boolean isFrag = Locale.isFragmentQName( c.getName() );

            if (_discardDocElem || isFrag)
            {
                if (_replaceDocElem != null)
                    c.setName( _replaceDocElem );
                else
                {
                    // Remove the content around the element to remove so that that content
                    // does not appear to have been the contents of the removed element.

                    while ( c.toParent() )
                        ;

                    c.next();

                    while ( !c.isElem() )
                        if (c.isText()) c.moveChars( null, -1 ); else c.moveNode( null );

                    assert c.isElem();
                    c.skip();

                    while ( !c.isFinish() )
                        if (c.isText()) c.moveChars( null, -1 ); else c.moveNode( null );

                    c.toParent();

                    c.next();

                    assert c.isElem();

                    Cur c2 = c.tempCur();

                    c.moveNodeContents( c, true );

                    c.moveToCur( c2 );

                    c2.release();

                    c.moveNode( null );
                }

                // Remove the fragment namespace decl

                if (isFrag)
                {
                    c.moveTo( _frontier );

                    if (c.toFirstAttr())
                    {
                        for ( ; ; )
                        {
                            if (c.isXmlns() && c.getXmlnsUri().equals( Locale._openFragUri ))
                            {
                                c.moveNode( null );

                                if (!c.isAttr())
                                    break;
                            }
                            else if (!c.toNextAttr())
                                break;
                        }
                    }

                    c.moveTo(_frontier);
                    _frontier = createDomDocumentRootXobj( _locale, true );

                    Cur c2 = _frontier.tempCur();
                    c2.next();
                    c.moveNodeContents(c2, true);
                    c.moveTo(_frontier);
                    c2.release();
                }
            }


            if (_additionalNamespaces != null)
            {
                c.moveTo( _frontier );
                Locale.toFirstChildElement( c );
                Locale.applyNamespaces( c, _additionalNamespaces );
            }

            if (_doctypeName != null && (_doctypePublicId != null || _doctypeSystemId != null))
            {
                XmlDocumentProperties props = Locale.getDocProps(c, true);
                props.setDoctypeName(_doctypeName);
                if (_doctypePublicId != null)
                    props.setDoctypePublicId(_doctypePublicId);
                if (_doctypeSystemId != null)
                    props.setDoctypeSystemId(_doctypeSystemId);
            }
            
            c.moveTo( _frontier );

            assert c.isRoot();

            return c;
        }

        public void dump ( )
        {
            _frontier.dump();
        }

        private Locale   _locale;
        private CharUtil _charUtil;

        private Xobj     _frontier;
        private boolean  _after;

        private Xobj     _lastXobj;
        private int      _lastPos;

        private boolean  _discardDocElem;
        private QName    _replaceDocElem;
        private boolean  _stripWhitespace;
        private boolean  _stripComments;
        private boolean  _stripProcinsts;
        private Map      _substituteNamespaces;
        private Map      _additionalNamespaces;
        
        private String   _doctypeName;
        private String   _doctypePublicId;
        private String   _doctypeSystemId;
    }

    //
    //
    //

    static String kindName ( int kind )
    {
        switch ( kind )
        {
            case ROOT     : return "ROOT";
            case ELEM     : return "ELEM";
            case ATTR     : return "ATTR";
            case COMMENT  : return "COMMENT";
            case PROCINST : return "PROCINST";
            case TEXT     : return "TEXT";
            default       : return "<< Unknown Kind (" + kind + ") >>";
        }
    }

    static void dump ( PrintStream o, Dom d, Object ref )
    {
    }

    static void dump ( PrintStream o, Dom d )
    {
        d.dump( o );
    }

    static void dump ( Dom d )
    {
        dump( System.out, d );
    }

    static void dump ( Node n )
    {
        dump( System.out, n );
    }

    static void dump ( PrintStream o, Node n )
    {
        dump( o, (Dom) n );
    }

    void dump ( )
    {
        dump( System.out, _xobj, this );
    }

    void dump ( PrintStream o )
    {
        if (_xobj == null)
        {
            o.println( "Unpositioned xptr" );
            return;
        }

        dump( o, _xobj, this );
    }

    public static void dump ( PrintStream o, Xobj xo, Object ref )
    {
        if (ref == null)
            ref = xo;

        while ( xo._parent != null )
            xo = xo._parent;

        dumpXobj( o, xo, 0, ref );

        o.println();
    }

    private static void dumpCur ( PrintStream o, String prefix, Cur c, Object ref )
    {
        o.print( " " );

        if (ref == c)
            o.print( "*:" );

        o.print( prefix + (c._id == null ? "<cur>" : c._id) + "[" + c._pos + "]" );
    }

    private static void dumpCurs ( PrintStream o, Xobj xo, Object ref )
    {
        for ( Cur c = xo._embedded ; c != null ; c = c._next )
            dumpCur( o, "E:", c, ref );

        for ( Cur c = xo._locale._registered ; c != null ; c = c._next )
        {
            if (c._xobj == xo)
                dumpCur( o, "R:", c, ref );
        }
    }

    private static void dumpBookmarks ( PrintStream o, Xobj xo, Object ref )
    {
        for ( Bookmark b = xo._bookmarks ; b != null ; b = b._next )
        {
            o.print( " " );

            if (ref == b)
                o.print( "*:" );

            if (b._value instanceof XmlLineNumber)
            {
                XmlLineNumber l = (XmlLineNumber) b._value;
                o.print( "<line:" + l.getLine() + ">" + "[" + b._pos + "]" );
            }
            else
                o.print( "<mark>" + "[" + b._pos + "]" );
        }
    }

    private static void dumpCharNodes ( PrintStream o, CharNode nodes, Object ref )
    {
        for ( CharNode n = nodes ; n != null ; n = n._next )
        {
            o.print( " " );

            if (n == ref)
                o.print( "*" );

            o.print( (n instanceof TextNode ? "TEXT" : "CDATA") + "[" + n._cch + "]" );
        }
    }

    private static void dumpChars ( PrintStream o, Object src, int off, int cch )
    {
//        CharUtil.dumpChars( o, src, off, cch );

        o.print( "\"" );

        String s = CharUtil.getString( src, off, cch );

        for ( int i = 0 ; i < s.length(); )
        {
            if (i == 36)
            {
                o.print( "..." );
                break;
            }

            int codePoint = s.codePointAt( i );
            char[] chars = Character.toChars(codePoint);
            
            if ( chars.length == 1 ) {
                char ch = chars[0];
                if (ch >= 32 && ch < 127)
                    o.print( ch );
                else if (ch == '\n')
                    o.print( "\\n" );
                else if (ch == '\r')
                    o.print( "\\r" );
                else if (ch == '\t')
                    o.print( "\\t" );
                else if (ch == '\"')
                    o.print( "\\\"" );
                else
                    o.print( "<#" + ((int) ch) + ">" );
            } else {
                o.print( "<#" + codePoint + ">" );
            }
            
            i += Character.charCount(codePoint);
        }

        o.print( "\"" );
    }

    private static void dumpXobj ( PrintStream o, Xobj xo, int level, Object ref )
    {
        if (xo == null)
            return;

        if (xo == ref)
            o.print( "* " );
        else
            o.print( "  " );

        for ( int i = 0 ; i < level ; i++ )
            o.print( "  " );

        o.print( kindName( xo.kind() ) );

        if (xo._name != null)
        {
            o.print( " " );

            if (xo._name.getPrefix().length() > 0)
                o.print( xo._name.getPrefix() + ":" );

            o.print( xo._name.getLocalPart() );

            if (xo._name.getNamespaceURI().length() > 0)
                o.print( "@" + xo._name.getNamespaceURI() );
        }

        if (xo._srcValue != null || xo._charNodesValue != null)
        {
            o.print( " Value( " );
            dumpChars( o, xo._srcValue, xo._offValue, xo._cchValue );
            dumpCharNodes( o, xo._charNodesValue, ref );
            o.print( " )" );
        }

        if (xo._user != null)
            o.print( " (USER)" );

        if (xo.isVacant())
            o.print( " (VACANT)" );

        if (xo._srcAfter != null || xo._charNodesAfter != null)
        {
            o.print( " After( " );
            dumpChars( o, xo._srcAfter, xo._offAfter, xo._cchAfter );
            dumpCharNodes( o, xo._charNodesAfter, ref );
            o.print( " )" );
        }

        dumpCurs( o, xo, ref );
        dumpBookmarks( o, xo, ref );

        String className = xo.getClass().getName();

        int i = className.lastIndexOf( '.' );

        if (i > 0)
        {
            className = className.substring( i + 1 );

            i = className.lastIndexOf( '$' );

            if (i > 0)
                className = className.substring( i + 1 );
        }

        o.print( " (" );
        o.print( className );
        o.print( ")" );

        o.println();

        for ( xo = xo._firstChild ; xo != null ; xo = xo._nextSibling )
            dumpXobj( o, xo, level + 1, ref );
    }

    void setId ( String id )
    {
        _id = id;
    }

    //
    //
    //

    Locale _locale;

    Xobj _xobj;
    int _pos;

    int _state;

    String _id;

    Cur _nextTemp;
    Cur _prevTemp;
    int _tempFrame;

    Cur _next;
    Cur _prev;

    Locale.Ref _ref;

    int _stackTop;

    int _selectionFirst;
    int _selectionN;
    int _selectionLoc;
    int _selectionCount;

    private int _posTemp;

    int _offSrc;
    int _cchSrc;
}