/*   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.apache.xmlbeans.*;
import org.apache.xmlbeans.XmlCursor.XmlBookmark;
import org.apache.xmlbeans.impl.soap.*;
import org.apache.xmlbeans.impl.store.DomImpl.Dom;
import org.apache.xmlbeans.impl.store.Locale.LoadContext;
import org.apache.xmlbeans.impl.values.TypeStoreUser;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;

import javax.xml.namespace.QName;
import java.io.PrintStream;
import java.util.Map;

// DOM Level 3


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 DocumentFragXobj(_locale));
    }

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

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

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

    void createProcinst(String target) {
        createHelper(new 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 DocumentFragXobj(l);
            else
                xo = new DocumentXobj(l);
        else
            xo = new 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 ElementXobj(l, name);

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

        if (c == SOAPElement.class) return new SoapElementXobj(l, name);
        if (c == SOAPBody.class) return new SoapBodyXobj(l, name);
        if (c == SOAPBodyElement.class) return new SoapBodyElementXobj(l, name);
        if (c == SOAPEnvelope.class) return new SoapEnvelopeXobj(l, name);
        if (c == SOAPHeader.class) return new SoapHeaderXobj(l, name);
        if (c == SOAPHeaderElement.class) return new SoapHeaderElementXobj(l, name);
        if (c == SOAPFaultElement.class) return new SoapFaultElementXobj(l, name);
        if (c == Detail.class) return new DetailXobj(l, name);
        if (c == DetailEntry.class) return new DetailEntryXobj(l, name);
        if (c == SOAPFault.class) return new 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 Integer.compare(pThis, pThat);
        }

        // 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--;
            assert(xThis != null);
            xThis = xThis._parent;
        }
        while (dThat > dThis) {
            dThat--;
            assert(xThat != null);
            xThat = xThat._parent;
        }

        assert dThat == dThis;

        if (dThat == 0) {
            return 2;
        }

        assert xThis != null && xThis._parent != null && xThat != 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 SoapPartDom;

        moveTo(d instanceof Xobj ? (Xobj) d : ((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 final 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 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 removeFirstSelection() {
        final int i = 0;
        assert i < _selectionCount;

        int j = selectionIndex(i);

        // Update the nth selection indices to accomodate the deletion

        if (i < _selectionN) {
            _selectionN--;
        } else if (i == _selectionN) {
            _selectionN--;
            _selectionLoc = Locations.NULL;
        }

        _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) {
            removeFirstSelection();
        }
    }

    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 value) {
        assert isContainer();

        final QName name = Locale._xsiType;

        if (value == null) {
            _xobj.removeAttr(name);
            return;
        }

        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;
        }

        //noinspection StatementWithEmptyBody
        while (toNextAttr()) ;

        return true;
    }

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

        Xobj nextAttr = _xobj.nextAttr();

        if (nextAttr == null) {
            return false;
        }

        moveTo(nextAttr);

        return true;
    }

    @SuppressWarnings("UnusedReturnValue")
    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();
    }

    @SuppressWarnings("UnusedReturnValue")
    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;
    }

    @SuppressWarnings("UnusedReturnValue")
    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;

        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 {
            //noinspection ConstantConditions
            assert p == 1;
            p = 0;
        }

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

        return true;
    }

    @SuppressWarnings("UnusedReturnValue")
    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(value);
    }

    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();
                        assert(y != null);
                        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() {
        assert isNormal() && _xobj != null;

        return getCharsAsString(Locale.WS_PRESERVE);
    }

    String getCharsAsString(int wsr) {
        return _xobj.getCharsAsString(_pos, -1, 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() {
        String id = null;
        Cur c = _locale.tempCur(id);
        c.moveToCur(this);
        return c;
    }

    private Cur tempCur(Xobj x, int p) {
        assert (x == null || _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(typeName);
    }

    void setSubstitution(QName name, SchemaType type) {
        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()) {
            // 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) {
            // Can't set xsi:type on element, type is un-named
            return;
        }

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

        if (parentUser.get_element_type(name, typeName) != type) {
            // Can't set xsi:type on element, invalid type
            return;
        }

        setName(name);
        setAttrValueAsQName(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();
    }

    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) {
                if (head != 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 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 AttrIdXobj(_locale, checkName(name, true)) :
                new 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 DocumentXobj) {
                    ((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 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 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.

                    //noinspection StatementWithEmptyBody
                    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 final Locale _locale;
        private final CharUtil _charUtil;

        private Xobj _frontier;
        private boolean _after;

        private Xobj _lastXobj;
        private int _lastPos;

        private boolean _discardDocElem;
        private QName _replaceDocElem;
        private final boolean _stripWhitespace;
        private final boolean _stripComments;
        private final boolean _stripProcinsts;
        private final Map _substituteNamespaces;
        private final 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 + ") >>";
        }
    }

    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) {

        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 && ch != '\"') {
                    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;
}