/*   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 java.lang.reflect.Method;

import org.apache.xmlbeans.impl.common.EncodingMap;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.XMLNameHelper;
import org.apache.xmlbeans.impl.store.Splay.Finish;
import org.apache.xmlbeans.impl.values.NamespaceManager;
import org.apache.xmlbeans.impl.values.XmlStore;
import org.apache.xmlbeans.impl.values.TypeStoreFactory;
import org.apache.xmlbeans.QNameCache;
import org.apache.xmlbeans.QNameSet;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlCursor.XmlBookmark;
import org.apache.xmlbeans.XmlDocumentProperties;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlLineNumber;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlRuntimeException;
import org.apache.xmlbeans.XmlSaxHandler;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.apache.xmlbeans.xml.stream.Attribute;
import org.apache.xmlbeans.xml.stream.AttributeIterator;
import org.apache.xmlbeans.xml.stream.CharacterData;
import org.apache.xmlbeans.xml.stream.Location;
import org.apache.xmlbeans.xml.stream.ProcessingInstruction;
import org.apache.xmlbeans.xml.stream.Space;
import org.apache.xmlbeans.xml.stream.StartDocument;
import org.apache.xmlbeans.xml.stream.StartElement;
import org.apache.xmlbeans.xml.stream.XMLEvent;
import org.apache.xmlbeans.xml.stream.XMLInputStream;
import org.apache.xmlbeans.xml.stream.XMLName;
import org.apache.xmlbeans.xml.stream.XMLStreamException;

import javax.xml.namespace.QName;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

public final class Root extends Finish implements XmlStore
{
    public Root ( SchemaTypeLoader stl, SchemaType type, XmlOptions options )
    {
        super( ROOT );

        assert stl != null;

        _schemaTypeSystem = stl;

        _leftOnly = true;

        _props = new DocProps();

        _doc = new Doc( this, null );

        _leftSplay = _doc;
        _doc._parentSplay = this;
        adjustCdocBeginLeft( _doc.getCdocBegin() );

        _text = new Text();

        SchemaType sType = null;

        options = XmlOptions.maskNull( options );
        
        if (options.hasOption( XmlOptions.DOCUMENT_TYPE ))
            sType = (SchemaType) options.get( XmlOptions.DOCUMENT_TYPE );

        if (sType == null)
            sType = type;

        if (sType == null)
            sType = XmlObject.type;

        _validateOnSet = options.hasOption( XmlOptions.VALIDATE_ON_SET );

        _factory = (TypeStoreFactory) options.get( TypeStoreFactory.KEY );

        _doc.setType( this, sType );
    }

    public static XmlStore newStore ( SchemaTypeLoader stl, SchemaType type, XmlOptions options )
    {
        return new Root( stl, type, options );
    }

    public XmlDocumentProperties documentProperties ( )
    {
        return _props;
    }

    public XmlCursor createCursor ( )
    {
        assert validate();
        return new Cursor( this, _doc );
    }

    Container getContainer ( ) { return _doc; }

    boolean validateOnSet ( ) { return _validateOnSet; }

    public XmlObject getObject ( )
    {
        Type t = _doc.peekType();

        return t == null ? null : t.getXmlObject();
    }

    public SchemaTypeLoader getSchemaTypeLoader ( )
    {
        return _schemaTypeSystem;
    }

    boolean isEmpty ( )
    {
        return _leftSplay == _doc && _doc._rightSplay == null && _doc.isValid();
    }

    boolean isLeftOnly ( ) { return _leftOnly; }

    void ensureEmpty ( )
    {
        if (!isEmpty())
            _doc.removeContent( this, true );

        assert isEmpty();
        assert validate();
        assert _leftOnly;
        assert getCchLeft() == 0;
        assert _text.length() == 0;
        assert getCdocBeginLeft() == 1;
        assert _doc != null && _leftSplay == _doc;
    }

    void updateCch ( Splay s, int deltaCch )
    {
        assert !s.isRoot();

        if (deltaCch != 0)
        {
            s.splay( this, this );

            s.adjustCch( deltaCch );
            adjustCchLeft( deltaCch );
        }
    }

    int getCp ( Splay s )
    {
        //
        // A left only tree has the nice property that _cchLeft is
        // also the cp!
        //

        if (!_leftOnly && s != this)
            s.splay( this, this );

        return s.getCchLeft();
    }

    int getDocBeginIndex ( Splay s )
    {
        //
        // A left only tree has the nice property that cdocBeginLeft is
        // also the pos!
        //

        if (!_leftOnly)
            s.splay( this, this );

        return s.getCdocBeginLeft();
    }
    
    Begin findNthBegin ( Splay parent, QName name, QNameSet set, int n )
    {
        // only one of (set or name) is not null
        // or both are null for a wildcard
        assert ( name == null || set == null );
        assert n >= 0;

        if (parent == null || parent.isLeaf())
            return null;

        int da = _nthCache_A.distance( parent, name, set, n );
        int db = _nthCache_B.distance( parent, name, set, n );

        Begin b =
            da <= db
                ? _nthCache_A.fetch( parent, name, set, n )
                : _nthCache_B.fetch( parent, name, set, n );

        if (da == db)
        {
            nthCache temp = _nthCache_A;
            _nthCache_A = _nthCache_B;
            _nthCache_B = temp;
        }

        return b;
    }

    int count ( Container parent, QName name, QNameSet set )
    {
        Splay s = findNthBegin( parent, name, set, 0 );

        if (s == null)
            return 0;

        int n = 0;

        for ( ; ; s = s.nextSplay() )
        {
            if (s.isFinish())
                break;

            if (!s.isBegin())
                continue;

            if (set == null)
            {
                if (s.getName().equals(name))
                    n++;
            }
            else
            {
                if (set.contains(s.getName()))
                    n++;
            }

            s = s.getFinishSplay();
        }

        return n;
    }

    /**
     * Set up strong type information based on this schema type system.
     */

    private boolean namespacesSame ( QName n1, QName n2 )
    {
        if (n1 == n2)
            return true;

        if (n1 == null || n2 == null)
            return false;

        if (n1.getNamespaceURI() == n2.getNamespaceURI())
            return true;

        if (n1.getNamespaceURI() == null || n2.getNamespaceURI() == null)
            return false;

        return n1.getNamespaceURI().equals( n2.getNamespaceURI() );
    }

    private void addNamespace ( StringBuffer sb, QName name )
    {
        if (name.getNamespaceURI() == null)
            sb.append( "<no namespace>" );
        else
        {
            sb.append( "\"" );
            sb.append( name.getNamespaceURI() );
            sb.append( "\"" );
        }
    }

    XmlObject autoTypedDocument (
        SchemaType factoryType, XmlOptions options )
            throws XmlException
    {
        // The type in the options has highest precidence because it is
        // supplied by the user.
        
        SchemaType overrideType =
            (SchemaType) XmlOptions.safeGet( options, XmlOptions.DOCUMENT_TYPE );

        // precedence is given to the override above all
        
        SchemaType theType = overrideType;

        // Document and attribute types have no name
        
        if (theType == null &&
                (factoryType == null ||
                    (!factoryType.isDocumentType() &&
                        !factoryType.isAttributeType())))
        {
            // infer type from xsi:type
            QName typeName = _doc.getXsiTypeName( this );

            SchemaType sniffedType =
                typeName == null
                    ? null
                    : _schemaTypeSystem.findType( typeName );

            if (factoryType == null ||
                    factoryType.isAssignableFrom( sniffedType ))
            {
                theType = sniffedType;
            }
        }

        // todo:
        // use the following when implementing subst groups:
        //     factoryType == null || expectedType.isDocumentType()

        if (factoryType == null || factoryType.isDocumentType())
        {
            if (theType == null)
            {
                // infer type based on root elt

                QName docElemName = null;

                XmlCursor c = createCursor();

                if (c.toFirstChild() && !c.toNextSibling())
                    docElemName = c.getName();

                c.dispose();

                if (docElemName != null)
                    theType = _schemaTypeSystem.findDocumentType( docElemName );

                // verify elt inheritance when implementing subst groups
                if (factoryType != null && theType != null)
                {
                    QName factoryElemName = factoryType.getDocumentElementName();

                    if (!factoryElemName.equals(docElemName) &&
                        !factoryType.isValidSubstitution(docElemName))

                        throw new XmlException("Element " + QNameHelper.pretty(docElemName) +
                            " is not a valid " + QNameHelper.pretty(factoryElemName) +
                            " document or a valid substitution.");
                }

            }

            if (theType == null)
            {
                // infer type based on root attr

                QName attrName = null;

                XmlCursor c = createCursor();

                if (c.toFirstAttribute() && !c.toNextAttribute())
                    attrName = c.getName();

                c.dispose();

                if (attrName != null)
                    theType = _schemaTypeSystem.findAttributeType( attrName );
            }
        }

        // sniffing doesn't say anything: assume the expected type
        if (theType == null)
            theType = factoryType;

        // Still nothing: the no type.
        if (theType == null)
            theType = XmlBeans.NO_TYPE;

        // assign type
        _doc.setType( this, theType );

        // todo: Have a similar attribute type check
        if (factoryType != null)
        {
            if (theType.isDocumentType())
                verifyDocumentType( theType.getDocumentElementName() );
            else if (theType.isAttributeType())
                verifyAttributeType( theType.getAttributeTypeAttributeName() );
        }

        //
        // If a type was passed in, usually from generated code which needs the
        // type to be something specific because of a pending cast, then check
        // the resulting type and throw a nice exception.
        //

        if (factoryType != null && !factoryType.isAssignableFrom(theType))
        {
            /*
            System.out.println("Factory type = " + factoryType);
            System.out.println("The type = " + theType);
            System.out.println("basetype of the type = " + theType.getBaseType());
            */

            throw
                new XmlException( "XML object is not of type " + factoryType );
        }

        return getObject();
    }

    private void verifyDocumentType ( QName docElemName )
        throws XmlException
    {
        XmlCursor c = createCursor();

        try
        {
            StringBuffer sb = null;

            if (!c.toFirstChild() || c.toNextSibling())
            {
                sb = new StringBuffer();

                sb.append( "The document is not a " );
                sb.append( QNameHelper.pretty( docElemName ) );

                if (c.currentTokenType().isStartdoc())
                    sb.append( ": no document element" );
                else
                    sb.append( ": multiple document elements" );
            }
            else
            {
                QName name = c.getName();

                if (!name.equals( docElemName ))
                {
                    sb = new StringBuffer();

                    sb.append( "The document is not a " );
                    sb.append( QNameHelper.pretty( docElemName ) );

                    if (docElemName.getLocalPart().equals( name.getLocalPart() ))
                    {
                        sb.append( ": document element namespace mismatch " );
                        sb.append( "expected " );
                        addNamespace( sb, docElemName );
                        sb.append( " got " );
                        addNamespace(sb,  name );
                    }
                    else if (namespacesSame( docElemName, name ))
                    {
                        sb.append( ": document element local name mismatch " );
                        sb.append( "expected " + docElemName.getLocalPart() );
                        sb.append( " got " + name.getLocalPart() );
                    }
                    else
                    {
                        sb.append( ": document element mismatch " );
                        sb.append( "got " );
                        sb.append( QNameHelper.pretty( name ) );
                    }
                }
            }

            if (sb != null)
            {
                XmlError err = XmlError.forCursor(sb.toString(), c.newCursor());
                throw new XmlException( err.toString(), null, err );
            }
        }
        finally
        {
            c.dispose();
        }
    }

    private void verifyAttributeType ( QName attrName )
        throws XmlException
    {
        XmlCursor c = createCursor();

        try
        {
            StringBuffer sb = null;

            if (!c.toFirstAttribute() || c.toNextAttribute())
            {
                sb = new StringBuffer();

                sb.append( "The document is not a " );
                sb.append( QNameHelper.pretty( attrName ) );

                if (c.currentTokenType().isStartdoc())
                    sb.append( ": no attributes" );
                else
                    sb.append( ": multiple attributes" );
            }
            else
            {
                QName name = c.getName();

                if (!name.equals( attrName ))
                {
                    sb = new StringBuffer();

                    sb.append( "The document is not a " );
                    sb.append( QNameHelper.pretty( attrName ) );

                    if (attrName.getLocalPart().equals( name.getLocalPart() ))
                    {
                        sb.append( ": attribute namespace mismatch " );
                        sb.append( "expected " );
                        addNamespace( sb, attrName );
                        sb.append( " got " );
                        addNamespace(sb,  name );
                    }
                    else if (namespacesSame( attrName, name ))
                    {
                        sb.append( ": attribute local name mismatch " );
                        sb.append( "expected " + attrName.getLocalPart() );
                        sb.append( " got " + name.getLocalPart() );
                    }
                    else
                    {
                        sb.append( ": attribute element mismatch " );
                        sb.append( "got " );
                        sb.append( QNameHelper.pretty( name ) );
                    }
                }
            }

            if (sb != null)
            {
                XmlError err = XmlError.forCursor(sb.toString(), c.newCursor());
                throw new XmlException( err.toString(), null, err );
            }
        }
        finally
        {
            c.dispose();
        }
    }

    //
    //
    //

    private static ThreadLocal tl_SaxLoaders =
        new ThreadLocal()
        {
            protected Object initialValue()
            {
                SaxLoader sl = PiccoloSaxLoader.newInstance();

                if (sl == null)
                    sl = DefaultSaxLoader.newInstance();

                if (sl == null)
                    throw new RuntimeException( "Can't find an XML parser" );

                return sl;
            }
        };

    private static SaxLoader getSaxLoader ( )
    {
        return (SaxLoader) tl_SaxLoaders.get();
    }
    

    private static class PiccoloSaxLoader extends SaxLoader
    {
        public static SaxLoader newInstance ( )
        {
            try
            {
                Class pc = Class.forName( "com.bluecast.xml.Piccolo" );
                
                XMLReader xr = (XMLReader) pc.newInstance();

                Method m_getEncoding     = pc.getMethod( "getEncoding", null );
                Method m_getVersion      = pc.getMethod( "getVersion", null );
                Method m_getStartLocator = pc.getMethod( "getStartLocator", null );

                Locator startLocator =
                    (Locator) m_getStartLocator.invoke( xr, null );

                return new PiccoloSaxLoader( xr, startLocator, m_getEncoding, m_getVersion );
            }
            catch ( ClassNotFoundException e )
            {
                return null;
            }
            catch ( Exception e )
            {
                throw new RuntimeException( e.getMessage(), e );
            }
        }
        
        protected void postLoad ( Root r )
        {
            try
            {
                r._props.setEncoding( (String) _m_getEncoding.invoke( _xr, null ) );
                r._props.setVersion ( (String) _m_getVersion .invoke( _xr, null ) );
            }
            catch ( Exception e )
            {
                throw new RuntimeException( e.getMessage(), e );
            }
        }
        
        private PiccoloSaxLoader (
            XMLReader xr, Locator startLocator, Method m_getEncoding, Method m_getVersion )
        {
            super( xr, startLocator );

            _m_getEncoding = m_getEncoding;
            _m_getVersion = m_getVersion;
        }

        private Method _m_getEncoding;
        private Method _m_getVersion;
    }
    
    private static class DefaultSaxLoader extends SaxLoader
    {
        public static SaxLoader newInstance ( )
        {
            try
            {
                return
                    new DefaultSaxLoader(
                        SAXParserFactory.newInstance().newSAXParser().getXMLReader() );
            }
            catch ( Throwable e )
            {
                throw new RuntimeException( e.getMessage(), e );
            }
        }

        private DefaultSaxLoader ( XMLReader xr )
        {
            super( xr, null );
        }
    }

    private static class SaxLoader
        implements ContentHandler, LexicalHandler, ErrorHandler, EntityResolver
    {
        protected SaxLoader ( XMLReader xr, Locator startLocator )
        {
            _xr = xr;
            _startLocator = startLocator;

            if (xr != null)
            {
                try
                {
                    xr.setFeature( "http://xml.org/sax/features/namespace-prefixes", true );
                    xr.setFeature( "http://xml.org/sax/features/namespaces", true );
                    xr.setFeature( "http://xml.org/sax/features/validation", false );


                    xr.setProperty( "http://xml.org/sax/properties/lexical-handler", this );
                    xr.setContentHandler( this );
                    xr.setErrorHandler( this );
                    xr.setEntityResolver( this );
                }
                catch ( Throwable e )
                {
                    throw new RuntimeException( e.getMessage(), e );
                }
            }
        }

        protected void setContext ( LoadContext context, XmlOptions options )
        {
            _context = context;

            _wantLineNumbers =
                XmlOptions.maskNull(
                    options ).hasOption( XmlOptions.LOAD_LINE_NUMBERS ) &&
                    _startLocator != null;
        }

        protected void postLoad ( Root r )
        {
        }

        public void load ( Root r, InputSource inputSource, XmlOptions options )
            throws IOException, XmlException
        {
            LoadContext context = new LoadContext( r, options );
            
            setContext( context, options );
            
            try
            {
                assert r.disableStoreValidation();

                _xr.parse( inputSource );

                postLoad( r );

//                // Piccolo specific access to encoding and version
//                _props.setEncoding( piccolo.getEncoding() );
//                _props.setVersion( piccolo.getVersion() );

                context.finish();

                r.associateSourceName( options );
            }
            catch ( XmlRuntimeException e )
            {
                context.abort();
                throw new XmlException( e );
            }
            catch ( SAXParseException e )
            {
                context.abort();

                XmlError err =
                    XmlError.forLocation(
                        e.getMessage(),
                        (String) XmlOptions.safeGet( options, XmlOptions.DOCUMENT_SOURCE_NAME ),
                        e.getLineNumber(), e.getColumnNumber(), -1 );

                throw new XmlException( err.toString(), e, err );
            }
            catch ( SAXException e )
            {
                context.abort();
                
                XmlError err = XmlError.forMessage( e.getMessage() );
                
                throw new XmlException( err.toString(), e, err );
            }
            catch ( RuntimeException e )
            {
                context.abort();
                throw e;
            }
            finally
            {
                assert r.enableStoreValidation();
            }
        }

        // Sax ContentHandler

        public void startDocument ( ) throws SAXException
        {
        }

        public void endDocument ( ) throws SAXException
        {
            // Set context to null
            // This prevents the handler (which is held in TLS from keeping
            // the entire document in memory
            _context = null;
        }

        public void startElement (
            String namespaceURI, String localName,
            String qName, Attributes atts )
                throws SAXException
        {
            if (localName.length() == 0)
                localName = qName;

            // Out current parser (Piccolo) does not error when a
            // namespace is used and not defined.  Check for these here

            if (qName.indexOf( ':' ) >= 0 && namespaceURI.length() == 0)
            {
                XmlError err =
                    XmlError.forMessage(
                        "Use of undefined namespace prefix: " +
                            qName.substring( 0, qName.indexOf( ':' ) ));

                throw new XmlRuntimeException( err.toString(), null, err );
            }

            _context.begin( localName, namespaceURI );

            // BUGBUG - do more of the following to get line number for
            // as many parts of the XML as we can
            if (_wantLineNumbers)
            {
                _context.lineNumberAnnotation(
                    _startLocator.getLineNumber(),
                    _startLocator.getColumnNumber(),
                    -1 );
            }

            for ( int i = 0, len = atts.getLength() ; i < len ; i++ )
            {
                String aqn = atts.getQName( i );

                if (aqn.equals( "xmlns" ))
                {
                    _context.xmlns( "", atts.getValue( i ) );
                }
                else if (aqn.startsWith( "xmlns:" ))
                {
                    String prefix = aqn.substring( 6 );

                    if (prefix.length() == 0)
                    {
                        XmlError err =
                            XmlError.forMessage( "Prefix not specified", XmlError.SEVERITY_ERROR );

                        throw new XmlRuntimeException( err.toString(), null, err );
                    }

                    String uri = atts.getValue( i );

                    if (uri.length() == 0)
                    {
                        XmlError err =
                            XmlError.forMessage(
                                "Prefix can't be mapped to no namespace: " + prefix,
                                XmlError.SEVERITY_ERROR );

                        throw new XmlRuntimeException( err.toString(), null, err );
                    }

                    _context.xmlns( prefix, uri );
                }
                else
                {
                    String attrUri = atts.getURI( i );
                    String attrLocal = atts.getLocalName( i );

                    if (attrLocal.length() == 0)
                        attrLocal = aqn;

// given the doc <a x:y='z'/>, piccolo will report the uri of the y
// attribute as 'x'!  Bad Piccolo.  Thus, I can't perform the undefined
// prefix check here.
//
//                    if (aqn.indexOf( ':' ) >= 0 && attrUri.length() == 0)
//                    {
//                        XmlError err =
//                            new CursorXmlError(
//                                "Use of undefined namespace prefix: " +
//                                    aqn.substring( 0, aqn.indexOf( ':' ) ),
//                                XmlError.SEVERITY_ERROR,
//                                null );
//
//                        throw
//                            new XmlRuntimeException(
//                                err.toString(), null, err );
//                    }

                    _context.attr( attrLocal, attrUri, atts.getValue( i ) );
                }
            }
        }

        public void endElement (
            String namespaceURI, String localName, String qName )
                throws SAXException
        {
            _context.end();
        }
        public void characters ( char ch[], int start, int length )

            throws SAXException
        {
            _context.text( ch, start, length );
        }

        public void ignorableWhitespace ( char ch[], int start, int length )
            throws SAXException
        {
            _context.text( ch, start, length );
        }

        public void comment ( char ch[], int start, int length )
            throws SAXException
        {
            _context.comment( ch, start, length );
        }

        public void processingInstruction ( String target, String data )
            throws SAXException
        {
            _context.procinst( target, data );
        }

        public void startDTD ( String name, String publicId, String systemId )
            throws SAXException
        {
            _context.doctype( name, publicId, systemId );
        }

        public void endDTD ( ) throws SAXException
        {
        }

        // Error Handling
        public void fatalError ( SAXParseException e ) throws SAXException
        {
            throw e;
        }

        public void error ( SAXParseException e ) throws SAXException
        {
            XmlError err =
                XmlError.forMessage( "Error: " + e.getMessage(), XmlError.SEVERITY_ERROR );

            throw new XmlRuntimeException( err.toString(), null, err );
        }

        public void warning ( SAXParseException e ) throws SAXException
        {
            // Throw away warings for now
        }

        // Entity Resolver
        public InputSource resolveEntity( String publicId, String systemId )
        {
            // System.out.println("public id = " + publicId);
            // System.out.println("system id = " + systemId);

            return new InputSource( new StringReader( "" ) );
        }

        public void setDocumentLocator ( Locator locator )
        {
            _locator = locator;
        }

        public void startPrefixMapping ( String prefix, String uri )
            throws SAXException
        {
            if (beginsWithXml( prefix ) &&
                ! ( "xml".equals( prefix ) && _xml1998Uri.equals( uri ) ))
            {
                XmlError err =
                    XmlError.forMessage(
                        "Prefix can't begin with XML: " + prefix,
                        XmlError.SEVERITY_ERROR );

                throw
                    new XmlRuntimeException(
                        err.toString(), null, err );
            }
        }

        // Ignored
        public void endPrefixMapping ( String prefix ) throws SAXException {}
        public void skippedEntity ( String name ) throws SAXException {}
        public void startCDATA ( ) throws SAXException { }
        public void endCDATA ( ) throws SAXException { }
        public void startEntity ( String name ) throws SAXException { }
        public void endEntity ( String name ) throws SAXException { }

        protected XMLReader _xr;
        
        private Locator     _locator;
        private LoadContext _context;
        private boolean     _wantLineNumbers;
        private Locator     _startLocator;
    }
    
    //
    //
    //

    public XmlObject loadXml ( InputStream in, SchemaType type, XmlOptions options )
        throws IOException, XmlException
    {
        String encodingOverride =
            (String) XmlOptions.safeGet( options, XmlOptions.CHARACTER_ENCODING );

        if (encodingOverride != null)
        {
            String javaEncoding = EncodingMap.getIANA2JavaMapping( encodingOverride );

            if (javaEncoding == null)
                javaEncoding = encodingOverride;

            return loadXml( new InputStreamReader( in, javaEncoding ), type, options );
        }

        return loadXml( new InputSource( in ), type, options );
    }

    public XmlObject loadXml ( Reader r, SchemaType type, XmlOptions options )
        throws IOException, XmlException
    {
        return loadXml( new InputSource( r ), type, options );
    }

    public XmlObject loadXml ( InputSource is, SchemaType type, XmlOptions options )
        throws IOException, XmlException
    {
        is.setSystemId( "file://" );

        getSaxLoader().load( this, is, options );

        return autoTypedDocument( type, options );
    }
    
    public XmlObject loadXml ( String s, SchemaType type, XmlOptions options )
        throws XmlException
    {
        Reader r = new StringReader( s );

        try
        {
            return loadXml( r, type, options );
        }
        catch ( IOException e )
        {
            assert false: "StringReader should not throw IOException";
            throw new XmlException( e.getMessage(), e );
        }
        finally
        {
            try { r.close(); } catch ( IOException e ) { }
        }
    }

    private void associateSourceName ( XmlOptions options )
    {
        String sourceName =
            (String) XmlOptions.safeGet(
                options, XmlOptions.DOCUMENT_SOURCE_NAME );

        if (sourceName != null)
            _props.setSourceName( sourceName );
    }

    //
    // XmlSaxHandler is returned to a user so that user may obtain the content
    // and lexical handlers to push content and then get the XmlObject at the
    // end of the parse push.
    //

    private class XmlSaxHandlerImpl extends SaxLoader implements XmlSaxHandler
    {
        XmlSaxHandlerImpl ( SchemaType type, XmlOptions options )
        {
            super( null, null );
            
            assert isEmpty();

            _options = options;
            _type = type;

            _context = new LoadContext( Root.this, options );

            setContext( _context, options );
        }

        public ContentHandler getContentHandler ( )
        {
            return _context == null ? null : this;
        }

        public LexicalHandler getLexicalHandler ( )
        {
            return _context == null ? null : this;
        }

        public XmlObject getObject ( ) throws XmlException
        {
            if (_context == null)
                return null;

            _context.finish();

            _context = null;

            Root.this.associateSourceName( _options );

            return Root.this.autoTypedDocument( _type, _options );
        }

        private LoadContext _context;
        private SchemaType  _type;
        private XmlOptions  _options;
    }

    public XmlSaxHandler newSaxHandler ( SchemaType type, XmlOptions options )
    {
        return new XmlSaxHandlerImpl( type, options );
    }

    //
    //
    //

    private void newParseSax ( InputSource in, XmlOptions options )
    {
        LoadContext context = new LoadContext( this, options );
    }

    //
    // Helper object for creating documents in a "load" kinda way
    //

    static final class LoadContext
    {
        LoadContext ( Root root, XmlOptions options )
        {
            assert root != null;

            _options = options = XmlOptions.maskNull( options );

            _qnameCache = XmlBeans.getQNameCache();

            if (options.hasOption( XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT ))
            {
                QName name = (QName) options.get( XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT );

                if (name != null && name.getLocalPart().length() == 0)
                {
                    throw
                        new IllegalArgumentException(
                            "Load Replace Document Element: Invalid name, local part empty" );
                }
                
                _discardDocElem = true;
                _replaceDocElem = name;
            }

            _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);

            _root = root;
            _root.ensureEmpty();

            _lastNonAttr = _root._doc;
            _lastSplay = _root._doc;
            _lastPos = 0;

            _frontier = _root._doc;
        }

        private Root getRoot ( )
        {
            return _root;
        }

        private int getCp ( Splay s )
        {
            assert _root.isLeftOnly();
            assert dv > 0 || s.getCpSlow() == s.getCchLeft();
            return s.getCchLeft();
        }

        private void adjustCch ( Splay s, int delta )
        {
            assert _root.isLeftOnly();

            s.adjustCch( delta );

            // There may be attrs after this splay which need their cchLeft's
            // to be updated.  To avoid splaying, update them by hand.

            for ( s = s.nextSplay() ; s != null ; s = s.nextSplay() )
            {
                assert s.isAttr() || s.isRoot();
                s.adjustCchLeft( delta );
            }
        }

        private void insert ( Splay s )
        {
            assert !_finished;
            assert s.getCch() == 0;

            _root.insertSplay( s, _root._leftSplay );

            _lastSplay = s;
            _lastPos = 0;

            if (!s.isAttr())
                _lastNonAttr = s;
        }

        private void insert ( Splay s, char[] buf, int off, int cch )
        {
            assert !_finished;
            assert s.getCch() == 0;
            insert( s );
            _root._text.insert( getCp( s ), buf, off, cch );
            adjustCch( s, cch );
        }

        private void insert ( Splay s, String text )
        {
            assert !_finished;
            assert s.getCch() == 0;
            insert( s );
            _root._text.insert( getCp( s ), text );
            adjustCch( s, text.length() );
        }

        private void stripLeadingWhitespace ( )
        {
            int cchAfter = _lastNonAttr.getCchAfter();

            if (cchAfter > 0)
            {
                int cch = cchAfter;

                int cpAfter =
                    _lastNonAttr.getCpForPos(
                        _root, _lastNonAttr.getPosAfter() );

                int off = _root._text.unObscure( cpAfter, cch );

                for ( ; cch > 0 ; cch-- )
                {
                    if (!isWhiteSpace( _root._text._buf[ off + cch - 1 ]))
                        break;
                }

                int delta = cch - cchAfter;

                if (delta < 0)
                {
                    _root._text.remove( cpAfter + cchAfter + delta, - delta );
                    _lastNonAttr.adjustCchAfter( delta );
                    adjustCch( _lastNonAttr, delta );
                }
            }
        }

        void abort ( )
        {
            // The shit must have hit the fan ...

            // Close all elements

            while ( _frontier != _root._doc )
                end();

            try
            {
                finish();
            }
            catch ( XmlException e )
            {
                assert false;
            }
        }

        void finish ( ) throws XmlException
        {
            if (_stripWhitespace)
                stripLeadingWhitespace();

            // TODO: deal with unterminated begins here

            if (_frontier != _root._doc)
                throw new XmlException( "Document not ended" );

            assert _root._leftOnly;

            _finished = true;

            _lastSplay = _root;
            _lastPos = 0;

            if (_options.hasOption(XmlOptions.LOAD_TRIM_TEXT_BUFFER))
                _root._text.trim();

            // If we have additional namespaces, add them now, making sure we
            // done over ride exisitng ones.

            if (_additionalNamespaces != null)
            {
                Splay s = _root._doc;

                while ( !s.isRoot() && !s.isBegin() )
                    s = s.nextSplay();

                if (s.isBegin())
                {
                    java.util.Iterator i =
                        _additionalNamespaces.keySet().iterator();

                    while ( i.hasNext() )
                    {
                        String prefix = (String) i.next();

                        // Usually, this is the predefined xml namespace
                        if (prefix.toLowerCase().startsWith( "xml" ))
                            continue;

                        String namespace =
                            (String) _additionalNamespaces.get( prefix );

                        if (s.namespaceForPrefix( prefix, false ) == null)
                        {
                            _root.insertSingleSplaySansSplayInLeftOnlyTree(
                                new Xmlns( new QName( namespace, prefix ) ),
                                s );

                            // The above insert should not splay the tree
                            assert _root.isLeftOnly();
                        }
                    }
                }
            }

            // For most of loading, I don't invalidate the document
            // version because nothing should be sensitive to it while
            // loading.  When finished loading, bump it.

            _root.invalidateVersion();
            
            assert _root.isLeftOnly();
        }

        private QName checkName ( String local, String uri )
        {
            if (_substituteNamespaces != null)
            {
                String substituteUri =
                    (String) _substituteNamespaces.get( uri );

                if (substituteUri != null)
                    return _qnameCache.getName( substituteUri, local );
            }

            return _qnameCache.getName( uri, local );
        }

        private QName checkName ( QName name )
        {
            if (_substituteNamespaces != null)
            {
                String substituteUri =
                    (String)
                        _substituteNamespaces.get( name.getNamespaceURI() );

                if (substituteUri != null)
                {
                    name =
                        _qnameCache.getName(
                            substituteUri, name.getLocalPart() );
                }
            }

            return name;
        }

        private QName checkNameAttr ( String local, String uri )
        {
            if (_substituteNamespaces != null && uri.length() > 0)
            {
                String substituteUri =
                    (String) _substituteNamespaces.get( uri );

                if (substituteUri != null)
                    return _qnameCache.getName( substituteUri, local );
            }

            return _qnameCache.getName( uri, local );
        }

        private QName checkNameAttr ( QName name )
        {
            if (_substituteNamespaces != null && name.getNamespaceURI().length() > 0 )
            {
                String substituteUri =
                    (String)
                        _substituteNamespaces.get( name.getNamespaceURI() );

                if (substituteUri != null)
                {
                    name =
                        _qnameCache.getName(
                            substituteUri, name.getLocalPart() );
                }
            }

            return name;
        }

        void doctype ( String name, String publicID, String systemID )
        {
            _root._props.setDoctypeName( name );
            _root._props.setDoctypePublicId( publicID );
            _root._props.setDoctypeSystemId( systemID );
        }

        private void insertBegin ( QName name )
        {
            if (_stripWhitespace)
                stripLeadingWhitespace();

            if (_frontier.isDoc() && !_docElemDiscarded &&
                    (_discardDocElem || isXmlFragment( name )))
            {
                _docElemDiscarded = true;

                if (_replaceDocElem == null)
                {
                    // Remove all content up to now because the
                    // document element is to be removed, and I dont
                    // want that content to mix with the real content.
                    
                    _root.ensureEmpty();
                    _lastNonAttr = _root._doc;
                    _lastSplay = _root._doc;
                    _lastPos = 0;
                    _frontier = _root._doc;
                    
                    return;
                }

                name = _replaceDocElem;
            }

            insert( _frontier = new Begin( name, _frontier ) );
        }

        void begin ( String local, String uri )
        {
            insertBegin( checkName( local, uri ) );
        }

        void begin ( QName name )
        {
            insertBegin( checkName( name ) );
        }

        void end ( )
        {
            if (_stripWhitespace)
                stripLeadingWhitespace();

            if (_frontier.isDoc())
            {
                if (!_docElemDiscarded)
                    throw new IllegalStateException( "Too many end elements" );
            }
            else
            {
                assert !_finished;
                assert _frontier.isBegin();
                assert !_frontier.isLeaf();

                if (_lastNonAttr == _frontier)
                {
                    _lastSplay = _frontier;
                    _lastPos = 1 + _frontier.getCch();
                    _frontier.toggleIsLeaf();
                    int cch = _frontier.getCchAfter();
                    _frontier.adjustCchAfter( - cch );
                }
                else
                {
                    Begin b = (Begin) _frontier;
                    End e = new End( b );
                    b._end = e;
                    insert( e );
                }

                _frontier = _frontier.getContainer();
            }
        }

        void attr ( QName name, char[] buf, int off, int cch )
        {
            insert( new Attr( checkNameAttr( name ) ), buf, off, cch );
        }

        void attr ( QName name, String value )
        {
            insert( new Attr( checkNameAttr( name ) ), value );
        }

        void attr ( String local, String uri, String value )
        {
            insert( new Attr( checkNameAttr( local, uri ) ), value );
        }

        private boolean discardXmlns ( QName name )
        {
            return
                _docElemDiscarded && _frontier.isDoc() &&
                    name.getNamespaceURI().equals( _openFragUri );
        }

        void xmlns ( String prefix, String uri )
        {
            QName name = checkName( prefix, uri );

            if (!discardXmlns( name ))
                insert( new Xmlns( name ) );
        }

        void xmlns ( QName name )
        {
            name = checkName( name );

            if (!discardXmlns( name ))
                insert( new Xmlns( name ) );
        }

        void comment ( char[] buf, int off, int cch )
        {
            if (!_stripComments)
                insert( new Comment(), buf, off, cch );
        }

        void comment ( String value )
        {
            if (!_stripComments)
                insert( new Comment(), value );
        }

        void procinst ( String target, char[] buf, int off, int cch )
        {
            if (!_stripProcinsts)
                insert( new Procinst( target ), buf, off, cch );
        }

        void procinst ( String target, String value )
        {
            if (!_stripProcinsts)
                insert( new Procinst( target ), value );
        }

        //
        // returns the cp where new text should go.
        //

        int preText ( )
        {
            assert !_finished;

            return getCp( _lastNonAttr ) + _lastNonAttr.getCch();
        }

        //
        // New text has been placed, adjust...
        //

        void postText ( int cp, int cch )
        {
            if (_stripWhitespace && _lastNonAttr.getCchAfter() == 0)
            {
                int off = _root._text.unObscure( cp, cch );

                int i = 0;

                while ( i < cch && isWhiteSpace( _root._text._buf[ off + i ] ) )
                    i++;

                if (i > 0)
                {
                    _root._text.remove( cp, i );
                    cch -= i;
                }
            }

            if (cch > 0)
            {
                _lastSplay = _lastNonAttr;
                _lastPos = _lastNonAttr.getEndPos();
                _lastNonAttr.adjustCchAfter( cch );

                adjustCch( _lastNonAttr, cch );
            }
        }

        void text ( char[] buf, int off, int cch )
        {
            assert !_finished;

            int start = off;
            int end = off + cch;

            if (_stripWhitespace && _lastNonAttr.getCchAfter() == 0)
            {
                while ( start < end && isWhiteSpace( buf[ start ] ) )
                    start++;
            }

            int cchText = end - start;

            if (cchText > 0)
            {
                _lastSplay = _lastNonAttr;
                _lastPos = _lastNonAttr.getEndPos();

                _root._text.insert(
                    getCp( _lastNonAttr ) + _lastNonAttr.getCch(),
                    buf, start, cchText );

                _lastNonAttr.adjustCchAfter( cchText );
                adjustCch( _lastNonAttr, cchText );
            }
        }

        void text ( String text )
        {
            assert !_finished;

            int start = 0;
            int end = text.length();

            if (_stripWhitespace && _lastNonAttr.getCchAfter() == 0)
            {
                while ( start < end && isWhiteSpace( text.charAt( start ) ) )
                    start++;
            }

            int cchText = end - start;

            if (cchText > 0)
            {
                _lastSplay = _lastNonAttr;
                _lastPos = _lastNonAttr.getEndPos();

                _root._text.insert(
                    getCp( _lastNonAttr ) + _lastNonAttr.getCch(),
                    text, start, cchText );

                _lastNonAttr.adjustCchAfter( cchText );
                adjustCch( _lastNonAttr, cchText );
            }
        }

        // Annotates the last thing inserted
        void annotate ( XmlBookmark xmlBookmark )
        {
            new Annotation( _root, xmlBookmark ).
                set( _lastSplay, _lastPos );
        }

        void lineNumberAnnotation ( int line, int column, int offset )
        {
            annotate( new XmlLineNumber( line, column, offset ) );
        }

        void lineNumberAnnotation ( XMLEvent xe )
        {
            Location loc = xe.getLocation();

            if (loc != null)
            {
                lineNumberAnnotation(
                    loc.getLineNumber(), loc.getColumnNumber(), -1 );
            }
        }

        void javelinAnnotation ( XmlCursor.XmlBookmark ja )
        {
            if (ja != null)
               annotate( ja );
        }

        private Root       _root;
        private Splay      _lastNonAttr;
        private Container  _frontier;
        private Splay      _lastSplay;
        private int        _lastPos;
        private boolean    _finished;
        private boolean    _discardDocElem;
        private QName      _replaceDocElem;
        private boolean    _stripWhitespace;
        private boolean    _stripComments;
        private boolean    _stripProcinsts;
        private boolean    _docElemDiscarded;
        private Map        _substituteNamespaces;
        private Map        _additionalNamespaces;
        private QNameCache _qnameCache;
        private XmlOptions _options;
    }

    private void loadNodeChildren ( Node n, LoadContext context )
    {
        for ( Node c = n.getFirstChild() ; c != null ; c = c.getNextSibling() )
            loadNode( c, context );
    }

    private void loadNode ( Node n, LoadContext context )
    {
        switch ( n.getNodeType() )
        {
        case Node.DOCUMENT_NODE :
        case Node.DOCUMENT_FRAGMENT_NODE :
        case Node.ENTITY_REFERENCE_NODE :
        {
            loadNodeChildren( n, context );

            break;
        }
        case Node.ELEMENT_NODE :
        {
            String localName = n.getLocalName();

            if (localName == null)
                localName = n.getNodeName();
            
            context.begin( localName, n.getNamespaceURI() );

            NamedNodeMap attrs = n.getAttributes();

            for ( int i = 0 ; i < attrs.getLength() ; i++ )
            {
                Node a = attrs.item( i );

                String uri = a.getNamespaceURI();
                String local = a.getLocalName();
                String value = a.getNodeValue();

                if (local == null)
                    local = a.getNodeName();

                if (uri != null && uri.equals( _xmlnsUri ))
                {
                    if (local.equals( "xmlns" ))
                        context.xmlns( "", value );
                    else
                        context.xmlns( local, value );
                }
                else
                {
                    context.attr( local, uri, value );
                }
            }

            loadNodeChildren( n, context );

            context.end();

            break;
        }
        case Node.TEXT_NODE :
        case Node.CDATA_SECTION_NODE :
        {
            context.text( n.getNodeValue() );
            break;
        }
        case Node.COMMENT_NODE :
        {
            context.comment( n.getNodeValue() );
            break;
        }
        case Node.PROCESSING_INSTRUCTION_NODE :
        {
            context.procinst( n.getNodeName(), n.getNodeValue() );
            break;
        }
        case Node.DOCUMENT_TYPE_NODE :
        case Node.ENTITY_NODE :
        case Node.NOTATION_NODE :
        case Node.ATTRIBUTE_NODE :
        {
            throw new RuntimeException( "Unexpected node" );
        }
        }
    }

    public XmlObject loadXml ( Node node, SchemaType type, XmlOptions options )
        throws XmlException
    {
        LoadContext context = new LoadContext( this, options );

        loadNode( node, context );

        associateSourceName( options );

        return autoTypedDocument( type, options );
    }

    public XmlObject loadXml (
        XMLInputStream xis, SchemaType type, XmlOptions options )
            throws XMLStreamException, XmlException
    {
        loadXmlInputStream( xis, options );

        return autoTypedDocument( type, options );
    }

    public void loadXmlInputStream ( XMLInputStream xis, XmlOptions options )
        throws XMLStreamException, XmlException
    {
        options = XmlOptions.maskNull( options );

        XMLEvent x = xis.peek();
        
        if (x != null && x.getType() == XMLEvent.START_ELEMENT)
        {
            Map nsMap = ((StartElement) x).getNamespaceMap();

            if (nsMap != null && nsMap.size() > 0)
            {
                Map namespaces = new HashMap();
                
                namespaces.putAll( nsMap );

                options = new XmlOptions( options );

                options.put( XmlOptions.LOAD_ADDITIONAL_NAMESPACES, namespaces );
            }
        }

        LoadContext context = new LoadContext( this, options );

        boolean lineNums = options.hasOption( XmlOptions.LOAD_LINE_NUMBERS );

        events:
        for ( XMLEvent xe = xis.next() ; xe != null ; xe = xis.next() )
        {
            switch ( xe.getType() )
            {
            case XMLEvent.START_DOCUMENT :
                // BUGBUG (ericvas) 12258 - FIXED below
                StartDocument doc = (StartDocument) xe;

//                context.doctype(
//                    doc.getname().getLocalName(),
//                    "", doc.getPublicId()

                _props.setDoctypeSystemId( doc.getSystemId() );
//                _publicID = doc.getPublicId();
                _props.setEncoding( doc.getCharacterEncodingScheme() );
                _props.setVersion( doc.getVersion() );
                _standAlone = doc.isStandalone();

                if (lineNums)
                    context.lineNumberAnnotation( xe );

                break;

            case XMLEvent.END_DOCUMENT :
                if (lineNums)
                    context.lineNumberAnnotation( xe );

                break events;

            case XMLEvent.NULL_ELEMENT :
                if (!xis.hasNext())
                    break events;
                break;

            case XMLEvent.START_ELEMENT :
                context.begin( XMLNameHelper.getQName( xe.getName() ) );

                if (lineNums)
                    context.lineNumberAnnotation( xe );

                for ( AttributeIterator ai = ((StartElement) xe).getAttributes()
                      ; ai.hasNext() ; )
                {
                    Attribute attr = ai.next();

                    context.attr(
                        XMLNameHelper.getQName( attr.getName() ),
                        attr.getValue() );
                }

                for ( AttributeIterator ai = ((StartElement) xe).getNamespaces()
                      ; ai.hasNext() ; )
                {
                    Attribute attr = ai.next();

                    XMLName name = attr.getName();
                    String local = name.getLocalName();

                    if (name.getPrefix() == null && local.equals( "xmlns" ))
                        local = "";

                    context.xmlns( local, attr.getValue() );
                }

                break;

            case XMLEvent.END_ELEMENT :
                context.end();

                if (lineNums)
                    context.lineNumberAnnotation( xe );

                break;

            case XMLEvent.SPACE :
                if (((Space) xe).ignorable())
                    break;

                // Fall through

            case XMLEvent.CHARACTER_DATA :
                CharacterData cd = (CharacterData) xe;

                if (cd.hasContent())
                {
                    context.text( cd.getContent() );

                    if (lineNums)
                        context.lineNumberAnnotation( xe );
                }

                break;

            case XMLEvent.COMMENT :
                org.apache.xmlbeans.xml.stream.Comment comment =
                    (org.apache.xmlbeans.xml.stream.Comment) xe;

                if (comment.hasContent())
                {
                    context.comment( comment.getContent() );

                    if (lineNums)
                        context.lineNumberAnnotation( xe );
                }

                break;

            case XMLEvent.PROCESSING_INSTRUCTION :
                ProcessingInstruction procInstr = (ProcessingInstruction) xe;

                context.procinst( procInstr.getTarget(), procInstr.getData() );

                if (lineNums)
                    context.lineNumberAnnotation( xe );

                break;

            // These are ignored
            case XMLEvent.ENTITY_REFERENCE :
            case XMLEvent.START_PREFIX_MAPPING :
            case XMLEvent.END_PREFIX_MAPPING :
            case XMLEvent.CHANGE_PREFIX_MAPPING :
            case XMLEvent.XML_EVENT :
                break;

            default :
                throw new RuntimeException(
                    "Unhandled xml event type: " + xe.getTypeAsString() );
            }
        }

        context.finish();

        associateSourceName( options );

        assert validate();
        assert isLeftOnly();
    }

    public static void dump ( XmlObject x )
    {
        dump( x, System.out );
    }

    public static void dump ( XmlObject x, PrintStream ps )
    {
        XmlCursor xc = x.newCursor();
        Root r = ((Cursor) xc).getRoot();
        r.dump( ps, null, ((Cursor) xc).getSplay(), false );
        xc.dispose();
    }

    public static void dump ( XmlCursor xc )
    {
        dump( xc, System.out );
    }

    public static void dump ( XmlCursor xc, PrintStream ps )
    {
        Root r = ((Cursor) xc).getRoot();
        r.dump( ps, null, ((Cursor) xc).getSplay(), false );
    }

    //
    //
    //

    private void dumpText ( PrintStream ps, int cp, int cch, Splay s, int p )
    {
        if (cp >= 0 && cp + cch <= _text.length())
            dumpString( ps, _text.fetch( cp, cch ), s, p );
        else
            ps.print( "[string: cp=" + cp + ", cch=" + cch + " ]" );
    }

    private void dumpText ( PrintStream ps, int cp, int cch )
    {
        if (cp >= 0 && cp + cch <= _text.length())
            dumpString( ps, _text.fetch( cp, cch ), null, 0 );
        else
            ps.print( "[string: cp=" + cp + ", cch=" + cch + " ]" );
    }

    private void dumpString ( PrintStream ps, String s )
    {
        dumpString( ps, s, null, 0 );
    }

    private void dumpGoobersInline ( PrintStream ps, Splay s, int p )
    {
        for ( Goober g = s.firstGoober() ; g != null ;
              g = s.nextGoober( g ) )
        {
            if (g.getKind() == CURSOR && g.getPos() == p)
            {
                CursorGoober cg = (CursorGoober) g;

                ps.print( "[" + ((CursorGoober) g).getDebugId() + "]" );
            }
        }
    }

    private void dumpString ( PrintStream ps, String str, Splay s, int p )
    {
        for ( int i = 0 ; i < str.length() ; i++ )
        {
            if (s != null)
                dumpGoobersInline( ps, s, i + p );

            if (i == 36)
            {
                ps.print( "..." );
                break;
            }

            char ch = str.charAt( i );

            if (ch == '\n')
                ps.print( "\\n" );
            else if (ch == '\r')
                ps.print( "\\r" );
            else if (ch == '\t')
                ps.print( "\\t" );
            else if (ch == '\"')
                ps.print( "\\\"" );
            else
                ps.print( ch );
        }
    }

    private void dumpGoobers ( PrintStream ps, Goober g )
    {
        if (g == null)
            return;

        if (g.getKind() == AGGREGATE)
        {
            ps.print( " {" );
            dumpGoobers( ps, g._goobers );
            ps.print( "}" );
        }
        else
            ps.print( " - " + g.getKindName() + " pos: " + g.getPos() );

        if (g.getKind() == CURSOR)
            ps.print( " id: " + ((CursorGoober) g).getDebugId() );

        if (g._next != g._parent._goobers)
            dumpGoobers( ps, g._next );
    }

    private void dumpSplayTree( Splay s, PrintStream ps )
    {
        if (s == null)
            return;

        if (s._rightSplay != null)
            dumpSplayTree( s._rightSplay, ps );

        for ( Splay t = s._parentSplay ; t != null ; t = t._parentSplay )
            ps.print( "  " );

        ps.print( "[" + s.getDebugId() );
        ps.print( " c:" + s.getCchLeft() + "(" + s.getCch() + ")");
        ps.print( " b:" + s.getCdocBeginLeft() + "(" + s.getCdocBegin() + ")");

        if (s._parentSplay != null)
        {
            ps.print( " p:" + s._parentSplay.getDebugId() );
            ps.print( s._parentSplay._leftSplay == s ? "L" : "R" );
        }

        ps.println( "]" );

        if (s._leftSplay != null)
            dumpSplayTree( s._leftSplay, ps );
    }

    public static void dump ( XmlCursor c, boolean verbose )
    {
        ((Cursor) c).dump( verbose );
    }

    public void dump ( )
    {
        dump( System.out, null, this, false );
    }

    public void dump ( boolean verbose )
    {
        dump( System.out, null, this, verbose );
    }

    public void dump ( PrintStream ps )
    {
        dump( ps, null, this, false );
    }

    public void dump ( PrintStream ps, String msg, Object src, boolean verbose )
    {
        // Under IntelliJ, if you call a function from the expression
        // evaluator and it produces too much output, IntelliJ will not
        // show you the output of the function.  So, I dump to a file
        // here as well and the given print stream!

        File f = new File( "c:\\" );

        if (f.exists())
        {
            f = new File( f, "xbean.dmp" );

            OutputStream os = null;
            PrintStream ps2 = null;

            try
            {
                os = new FileOutputStream( f );
                ps2 = new PrintStream( os );

                doDump( ps2, msg, src, verbose );
            }
            catch ( Throwable t )
            {
                if (ps2 != null)
                {
                    ps2.println( "Exception during dump." );
                    t.printStackTrace( ps2 );
                }
            }

            if (os != null)
            {
                try { os.close(); } catch ( Exception e ) { }
            }
        }

        try
        {
            doDump( ps, msg, src, verbose );
        }
        catch ( Throwable t )
        {
            System.out.println( "Exception during dump." );
            t.printStackTrace( System.out );
        }
    }

    static class DumpNsManager implements NamespaceManager
    {
        DumpNsManager ( PrintStream ps )
        {
            this.ps = ps;
        }

        public String find_prefix_for_nsuri ( String uri, String suggestion )
        {
            String prefix = "debug_prefix_" + i++;

            ps.print( " [find_prefix_for_nsuri: " );
            ps.print( "\"" + uri + "\" (" + suggestion + ") -> " + prefix );
            ps.print( "]" );

            return prefix;
        }

        public String getNamespaceForPrefix ( String prefix )
        {
            if (prefix != null && prefix.equals( "xml" ))
                return _xml1998Uri;

            String uri = "debug_ns_" + i++;

            ps.print( " [lookup_nsuri_for_prefix: " );
            ps.print( prefix + " -> \"" + uri + "\"" );
            ps.print( "]" );

            return uri;
        }

        PrintStream ps;

        private int i = 1;
    }

    public void doDump (
        PrintStream ps, String msg, Object src, boolean verbose )
    {
        if (!_assertEnabled)
        {
            ps.println( "No dump produced (assert needs to be enabled)" );
            return;
        }

        NamespaceManager nsm = new DumpNsManager( ps );

        if (msg != null)
            ps.println( msg );
        else
            ps.println( "Dump:" );

        if (src != null)
        {
            if (src instanceof Cursor)
            {
                ps.println(
                    "  from cursor " + ((CursorGoober)((Cursor) src)._data._goober).getDebugId() );
            }
            else if (src instanceof Splay)
                ps.println( "  from splay " + ((Splay) src).getDebugId() );
            else
                ps.println( "  from src " + src );
        }

        int depth = 0;

        for ( Splay s = _doc ; s != null ; s = s.nextSplay() )
        {
            int kind = s.getKind();

            String ids = "" + s.getDebugId();
            ids = "        ".substring( 0, 6 - ids.length() ) + ids;
            ps.print( ids + ": " );

            if (kind == END)
                depth--;

            if (!s.isRoot())
            {
                for ( int i = 0 ; i < depth ; i++ )
                    ps.print( "  " );
            }

            dumpGoobersInline( ps, s, 0 );

            switch ( kind )
            {
            case DOC :
                ps.print( "DOC" );
                break;

            case BEGIN :
            {
                Begin b = (Begin) s;

                if (!b.isLeaf())
                    depth++;

                ps.print( "<" );
                ps.print( s.getName().toString() );
                ps.print( ">" );

                if (b.isLeaf())
                {
                    if (b.getCchValue() > 0)
                    {
                        ps.print( "\"" );
                        dumpText( ps, s.getCpSlow(), b.getCchValue(), s, 1 );
                        ps.print( "\"" );
                    }

                    dumpGoobersInline( ps, s, s.getPosLeafEnd() );

                    ps.print( "</" );
                    ps.print( s.getName().getLocalPart() );
                    ps.print( "/>" );
                }

                break;
            }

            case ATTR :
            {
                if (s.isXmlns())
                {
                    ps.print( "#xmlns:" );
                    ps.print( s.getName().getLocalPart() );
                    ps.print( "=\"" );
                    ps.print( s.getName().getNamespaceURI() );
                    ps.print( "\"" );
                }
                else
                {
                    ps.print( "@" );
                    ps.print( s.getName() );
                    ps.print( "=\"" );
                    dumpText( ps, s.getCpSlow(), s.getCchValue() );
                    ps.print( "\"" );
                }

                break;
            }

            case END :
            {
                End es = (End) s;
                Begin b = es._begin;

                ps.print( "</" );
                ps.print( b.getName().getLocalPart() );
                ps.print( "/>" );

                break;
            }

            case COMMENT :
            {
                if (s.isFragment())
                {
                    ps.print( "FRAG" );
                }
                else
                {
                    ps.print( "<!--" );
                    dumpText( ps, s.getCpSlow(), s.getCchValue() );
                    ps.print( "-->" );
                }
                break;
            }

            case PROCINST :
            {
                ps.print( "<?" );
                ps.print( s.getLocal() );
                ps.print( " " );
                dumpText( ps, s.getCpSlow(), s.getCchValue() );
                ps.print( "?>" );
                break;
            }

            case ROOT :
            {
                ps.print( "ROOT" );
                break;
            }

            default:
                throw new RuntimeException( "Unknown splay kind" );
            }

            if (s.getCchAfter() > 0)
            {
                ps.print( "\"" );

                dumpText(
                    ps, s.getCpSlow() + s.getCchValue(), s.getCchAfter(),
                    s, s.getPosAfter() );

                ps.print( "\"" );
            }

            dumpGoobersInline( ps, s, s.getEndPos() );

            if (s.isInvalid())
            {
                String value = s.peekType().build_text( nsm );

                ps.print( " [invalid:" );
                ps.print( "\"" );
                dumpString( ps, value );
                ps.print( "\"" );
                ps.print( "]" );
            }

            dumpGoobers( ps, s._goobers );

            if (verbose)
            {
                switch ( kind )
                {
                case BEGIN :
                {
                    Begin b = (Begin) s;

                    if (b.getFinish() != null)
                    {
                        ps.print( " [end: " );
                        ps.print( b.getFinish().getDebugId() );
                        ps.print( "]" );
                    }

                    if (b.getContainer() != null)
                    {
                        ps.print(
                            " [container: " +
                                b.getContainer().getDebugId() + "]" );
                    }

                    break;
                }

                case END :
                {
                    End es = (End) s;
                    Begin b = es._begin;

                    ps.print( " [begin: " + b.getDebugId() + "]" );

                    break;
                }
                }
            }

            ps.println();
        }

        ps.println();

        if (getCchLeft() > _text.length())
        {
            ps.println(
                "Text buffer has too few characters (" +
                    (getCchLeft() - _text.length()) + ")" );
        }
        else if (getCchLeft() < _text.length())
        {
            ps.println(
                "Text buffer has too many characters (" +
                    (_text.length() - getCchLeft()) + "): " );

            dumpString(
                ps,
                _text.fetch( getCchLeft(), _text.length() - getCchLeft() ) );
        }

        if (verbose)
        {
            ps.println( "Splay tree:" );

            ps.println( "  isLeftOnly: " + _leftOnly );
            ps.println( "  version: " + getVersion() );
            ps.println( "  first: " + _doc.getDebugId() );

            ps.println();
            dumpSplayTree( this, ps );
            ps.println();
            ps.println();
        }

        ps.println();
    }

    /**
     * Insert a splay (or splays) into the tree.  This is a low level
     * operation, and operates only on the splay aspect of the tree.
     * Any invalidation maintenance must be handled by callers.
     */

    void insertSplay ( Splay s, Splay a )
    {
        assert s != null;
        assert !s.isRoot();
        assert a != null;
        assert Root.dv > 0 || validateSplayTree();
        assert !a.isRoot();
        assert Root.dv > 0 || a.getRootSlow() == this;
        assert s._parentSplay == null;
        assert s._rightSplay == null;
        assert s._leftSplay != null || s.getCchLeft() == 0;
        assert s._leftSplay != null || s.getCdocBeginLeft() == 0;

        int cch = s.getCch();
        int cbegin = s.getCdocBegin();

        if (s._leftSplay != null)
        {
            cch += s.getCchLeft();
            cbegin += s.getCdocBeginLeft();
            _leftOnly = false;
        }

        if (_leftOnly && a == _leftSplay)
        {
            s._leftSplay = _leftSplay;
            s._parentSplay = this;

            assert s.getCchLeft() == 0;
            s.adjustCchLeft(
                _leftSplay.getCchLeft() + _leftSplay.getCch() );

            assert s.getCdocBeginLeft() == 0;
            s.adjustCdocBeginLeft(
                _leftSplay.getCdocBeginLeft() + _leftSplay.getCdocBegin() );

            _leftSplay._parentSplay = s;
            _leftSplay = s;

            adjustCchLeft( cch );
            adjustCdocBeginLeft( cbegin );
        }
        else if (_leftOnly && cch == 0 && cbegin == 0)
        {
            //
            // If the splay to insert has no cch or cbegin, then when
            // the tree is left only children, I need not splay.
            //

            s._parentSplay = a._parentSplay;
            s._leftSplay = a;
            a._parentSplay = s;
            s._parentSplay._leftSplay = s;

            s.adjustCchLeft( a.getCchLeft() + a.getCch() );

            s.adjustCdocBeginLeft(
                a.getCdocBeginLeft() + a.getCdocBegin() );
        }
        else
        {
            Splay p;

            if (a._rightSplay == null)
            {
                (p = a)._rightSplay = s;
                _leftOnly = false;
            }
            else
            {
                for ( p = a._rightSplay ; p._leftSplay != null ; )
                    p = p._leftSplay;

                p._leftSplay = s;
            }

            s._parentSplay = p;

            for ( p = s ; ; )
            {
                Splay t = p._parentSplay;

                if (t == null)
                    break;

                if (t._leftSplay == p)
                {
                    t.adjustCchLeft( cch );
                    t.adjustCdocBeginLeft( cbegin );
                }

                p = t;
            }

            s.splay( this, this );
        }

        assert validateSplayTree();
    }

    /**
     * Special insert to insert a single splay into a leftonly tree without
     * causing the tree to go non left only.  Because this does not splay,
     * doing this too many times can be very inefficient.
     */
    
    void insertSingleSplaySansSplayInLeftOnlyTree ( Splay s, Splay a )
    {
        assert _leftOnly;
        assert s._rightSplay == null;
        assert s._leftSplay == null;

        s._leftSplay = a;
        s._parentSplay = a._parentSplay;
        a._parentSplay._leftSplay = s;
        a._parentSplay = s;

        s.adjustCchLeft( a.getCchLeft() + a.getCch() );
        s.adjustCdocBeginLeft( a.getCdocBeginLeft() + a.getCdocBegin() );
        
        int cch = s.getCch();
        int cbegin = s.getCdocBegin();
        
        for ( Splay p = s._parentSplay ; p != null ; p = p._parentSplay )
        {
            p.adjustCchLeft( cch );
            p.adjustCdocBeginLeft( cbegin );
        }
    }
            
    /**
     * Remove [ first, last ) splays from total sequence:
     *
     *     A - first - B - x - last - C
     *
     * where first, last and x are individual splays and A, B and C are
     * multiple, intervening splays.  Return the result with x at the top
     * and first his left child.  This allows x to have the splay
     * characteristics for the whole removed tree.
     */

    Splay removeSplays ( Splay first, Splay last )
    {
        assert validateSplayTree();
        assert first != last;;
        assert !first.isRoot();
        assert !first.isDoc();
        assert Root.dv > 0 || first.getRootSlow() == this;
        assert Root.dv > 0 || last.getRootSlow() == this;
        assert Root.dv > 0 || first.compareSlow( last ) == -1;
        assert !last.isRoot() || last == this;

        Splay x = last.prevSplay();

        if (x == first)
            return x.removeSplay( this );

        // Make the dog leg!

        if (last != this)
            last.splay( this, this );

        x.splay( this, last );
        first.splay( this, x );

        assert this == last || this._leftSplay == last;
        assert last._leftSplay == x;
        assert x._leftSplay == first;
        assert x._rightSplay == null;
        assert first._leftSplay != null;

        int firstCchLeft = first.getCchLeft();
        int firstCbeginLeft = first.getCdocBeginLeft();

        int deltaCchLeft = firstCchLeft - last.getCchLeft();
        int deltaCbeginLeft = firstCbeginLeft - last.getCdocBeginLeft();

        last.adjustCchLeft( deltaCchLeft );
        last.adjustCdocBeginLeft( deltaCbeginLeft );

        if (last != this)
        {
            adjustCchLeft( deltaCchLeft );
            adjustCdocBeginLeft( deltaCbeginLeft );
        }

        x.adjustCchLeft( - firstCchLeft );
        x.adjustCdocBeginLeft( - firstCbeginLeft );

        first.adjustCchLeft( - firstCchLeft );
        first.adjustCdocBeginLeft( - firstCbeginLeft );

        assert first.getCchLeft() == 0;
        assert first.getCdocBeginLeft() == 0;

        assert x.getCchLeft() + deltaCchLeft + x.getCch() == 0;
        assert x.getCdocBeginLeft() + deltaCbeginLeft + x.getCdocBegin() == 0;

        first._leftSplay._parentSplay = last;
        last._leftSplay = first._leftSplay;
        x._parentSplay = null;

        first._leftSplay = null;
        first._parentSplay = null;

        assert validateSplayTree();

        return x;
    }

    public static synchronized boolean disableStoreValidation ( )
        { dv++; return true; }

    public static synchronized boolean enableStoreValidation  ( )
        { dv--; return true; }

    public static int dv;

    {
        if (!"true".equals( System.getProperty( "treeasserts" )))
            disableStoreValidation();
    }

    public boolean validate ( )
    {
        if (dv != 0)
            return true;

        try
        {
            return doValidate();
        }
        catch ( RuntimeException rte )
        {
            System.out.println( "Document invalid: " + rte.getMessage() );
            rte.printStackTrace();
            dump( true );
            throw rte;
        }
    }

    //
    // Recursive descent validation of the content of the document
    //
    // Grammer for valid content of a document
    //
    // <doc>        ::= DOC <attributes> <content> ROOT
    // <attributes> ::= ( ATTR )*
    // <content>    ::= ( ( COMMENT | PROCINST | <element>) )*
    // <element>    ::= ( LEAF  <attributes> ) |
    //                    ( BEGIN <attributes> <content> END )
    //

    private Splay validateAttributes ( Splay s )
    {
        while ( s.getKind() == ATTR )
            s = s.nextSplay();

        return s;
    }

    private Splay validateContent ( Splay s )
    {
        for ( ; ; )
        {
            int k = s.getKind();

            if (k == COMMENT || k == PROCINST)
                s = s.nextSplay();
            else
            {
                Splay q = s;
                s = validateElement( s );

                if (q == s)
                    break;
            }
        }

        return s;
    }

    private Splay validateElement ( Splay s )
    {
        if (s.getKind() == BEGIN)
        {
            Splay b = s;

            s = validateAttributes( s.nextSplay() );

            if (!b.isLeaf())
            {
                s = validateContent( s );

                assert s.isEnd(): "Missing END, splay: " + s.getDebugId();

                s = s.nextSplay();
            }
        }

        return s;
    }

    private boolean validateDoc ( )
    {
        Splay s = _doc.nextSplay();

        s = validateAttributes( s );

        s = validateContent( s );

        assert s.isRoot(): "Expected root";

        return true;
    }

    private static class ValidateContext
    {
        int _numSplayTypes;
        int _cInvalidatableTypes;
        int _cElemOrderSensitiveTypes;
    }

    private void validateGoober ( Goober g, Splay s, ValidateContext context )
    {
        if (g instanceof Type)
        {
            assert g.getKind() == TYPE;
            assert s.isTypeable();

            context._numSplayTypes++;

            Type type = (Type) g;

            if (type.uses_invalidate_value())
                context._cInvalidatableTypes++;

            if (type.is_child_element_order_sensitive())
                context._cElemOrderSensitiveTypes++;
        }
        else
        {
            assert g.getKind() != TYPE;
        }

        assert g.getSplay() == s;
        assert g.getRoot() == this;
        assert g.getPos() >= 0;
        assert g.getPos() <= s.getMaxPos();
    }

    private boolean doValidate ( )
    {
        assert validateDoc();
        assert validateSplayTree();
        assert getCchLeft() == _text.length();

        validateChangeListenerState();

// TODO: Validate that is the root type is null, there are no types in
// tree at all

// TODO: Check the invarient that if there is a Type anywhere
// in the document, that there is an existing chain of types
// all the way to the root and is_ok_element_user or is_ok_attribute_user,
// depending on the case, returns ok.

        ValidateContext context = new ValidateContext();

        Container recentContainer = null;

        for ( Splay s = _doc ; s != null ; s = s.nextSplay() )
        {
            if (s.isRoot())
            {
                assert s.getCchAfter() == 0;
            }
            else if (s.isBegin())
            {
                Begin b = (Begin) s;

                assert b.getName() != null;

                assert
                    b.getFinish() == null ||
                        b.getFinish().getContainer() == b;

                if (b.isLeaf())
                {
                    assert b.getFinish() == null;
                }
                else
                {
                    assert b.getFinish() != null;
                    assert b.getFinish().getContainer() == b;
                    assert b.getCchValue() == 0;
                }
            }
            else if (s.isAttr())
            {
                assert s.getName() != null;
                assert s.getCchAfter() == 0;
            }

            if (s.isProcinst())
            {
                assert s.getName().getNamespaceURI() != null;
                assert s.getName().getNamespaceURI().length() == 0;
            }

            if (s.isContainer())
            {
                assert s.getContainer() == recentContainer;

                if (!s.isLeaf())
                    recentContainer = (Container) s;
            }
            else if (s.isFinish())
            {
                assert s.getContainer() == recentContainer;
                recentContainer = recentContainer.getContainer();
            }

            context._numSplayTypes = 0;

            for ( Goober g = s.firstGoober() ; g != null ;
                  g = s.nextGoober( g ) )
            {
                validateGoober( g, s, context );
            }

            if (isInvalid())
            {
                assert s.isTypeable();
                assert s.peekType() != null;

                assert context._numSplayTypes == 1;

                if (s.isDoc())
                {
                    assert s.getCchAfter() == 0;
                    Splay n = s.nextNonAttrSplay();

                    assert n.isRoot();
                }
                else if (s.isBegin())
                {
                    assert s.isLeaf();
                    assert s.getCchValue() == 0;
                }
                else if (s.isAttr())
                {
                    assert s.getCchValue() == 0;
                }
            }
            else
            {
                assert context._numSplayTypes <= 1;
            }
        }

        assert context._cInvalidatableTypes == _cInvalidatableTypes;
        assert context._cElemOrderSensitiveTypes ==_cElemOrderSensitiveTypes;

        // TODO: Validate indices

        return true;
    }

    boolean validateSplayTree ( )
    {
        if (dv != 0)
            return true;

        try
        {
            return doValidateSplayTree();
        }
        catch ( RuntimeException rte )
        {
            System.out.println( "Splay tree invalid: " + rte );

            dump( true );

            throw rte;
        }
    }

    private static class ValidateStats extends HashMap
    {
        int getCch ( Splay s )
        {
            return getStats( s )._cch;
        }

        void adjustCch ( Splay s, int cchDelta )
        {
            Stats stats = getStats( s );
            stats._cch += cchDelta;
        }

        int getCbegin ( Splay s )
        {
            return getStats( s )._cbegin;
        }

        void adjustCbegin ( Splay s, int cbeginDelta )
        {
            Stats stats = getStats( s );
            stats._cbegin += cbeginDelta;
        }

        private Stats getStats ( Splay s )
        {
            Stats stats = (Stats) get( s );

            if (stats == null)
                put( s, stats = new Stats() );

            return stats;
        }

        private static class Stats
        {
            public int _cch;
            public int _cbegin;
        }
    }

    boolean doValidateSplayTree ( )
    {
        assertAssertEnabled();

        ValidateStats stats = new ValidateStats();

        assert _parentSplay == null;
        assert _rightSplay  == null;
        assert _doc._leftSplay == null;

        Splay s = this;

        if (s._leftSplay != null)
        {
            s = s._leftSplay;

            while ( s != null && s._leftSplay != null )
                s = s._leftSplay;
        }

        assert s == _doc;

        loop:
        for ( ; ; )
        {
            if (s._leftSplay == null && s._rightSplay == null)
            {
                stats.adjustCch( s, s.getCch() );
                stats.adjustCbegin( s, s.getCdocBegin() );
            }

            if (s._rightSplay != null)
            {
                for ( s = s._rightSplay ; s._leftSplay != null ; )
                    s = s._leftSplay;
            }
            else
            {
                for ( ; ; )
                {
                    Splay p = s._parentSplay;

                    if (p == null)
                        break loop;

                    if (p._rightSplay == null || p._rightSplay == s)
                    {
                        s = p;

                        stats.adjustCch( s, s.getCch() );
                        stats.adjustCbegin( s, s.getCdocBegin() );

                        if (s._leftSplay != null)
                        {
                            stats.adjustCch( s, stats.getCch( s._leftSplay ) );

                            stats.adjustCbegin(
                                s, stats.getCbegin( s._leftSplay ) );
                        }

                        if (s._rightSplay != null)
                        {
                            stats.adjustCch( s, stats.getCch( s._rightSplay ) );

                            stats.adjustCbegin(
                                s, stats.getCbegin( s._rightSplay ) );
                        }
                    }
                    else
                    {
                        assert p._leftSplay == s;
                        assert p._rightSplay != null;

                        s = p._rightSplay;

                        while ( s._leftSplay != null )
                            s = s._leftSplay;

                        break;
                    }
                }
            }
        }

        for ( s = _doc ; s != null ; s = s.nextSplay() )
        {
            assert !_leftOnly || s._rightSplay == null: "" + s.getDebugId();
            assert s._leftSplay  == null || s._leftSplay ._parentSplay == s;
            assert s._rightSplay == null || s._rightSplay._parentSplay == s;

            if (s._leftSplay == null)
            {
                assert s.getCchLeft() == 0;
                assert s.getCdocBeginLeft() == 0;
            }
            else
            {
                assert
                    s.getCchLeft() == stats.getCch( s._leftSplay ):
                        "" + s.getDebugId();

                assert s.getCdocBeginLeft() == stats.getCbegin( s._leftSplay );
            }
        }

        return true;
    }

    //
    //
    //

    interface ChangeListener
    {
        void changeNotification ( );
    }

    private static class ChangeClient
    {
        ChangeListener _listener;
        ChangeClient   _next;
    }

    long getVersion ( )
    {
        return __version;
    }

    void invalidateVersion ( )
    {
        assert _changeClients == null;

        __version++;

        assert (_debugChangeVersion = __version) == 0 || true;
    }

    // Use this *only* if you know what you are doing!
    void restoreVersion ( long oldVersion )
    {
        assert __version >= oldVersion;
        __version = oldVersion;
        assert (_debugChangeVersion = __version) == 0 || true;
    }

    boolean validateChangeStarted ( )
    {
        assert _changeClients == null;
        return _changeClients == null;
    }

    boolean validateChangeListenerState ( )
    {
        assert _debugChangeVersion == __version;
        return true;
    }

    void registerForChange ( ChangeListener listener )
    {
        assert validateChangeListenerState();

        // See if this listener is the first one on the list.  Easy but not
        // totally complete  optimization

        if (_changeClients != null && _changeClients._listener == listener)
            return;

        ChangeClient client = new ChangeClient();

        client._next = _changeClients;
        client._listener = listener;
        _changeClients = client;
    }

    void startChange ( )
    {
        assert validateChangeListenerState();

        long currentVersion = 0;

        assert (currentVersion = __version) == 0 || true;

        while ( _changeClients != null )
        {
            _changeClients._listener.changeNotification();
            _changeClients = _changeClients._next;
        }

        assert currentVersion == __version;
    }

    //
    // Document properties
    //

    static class DocProps
        extends XmlDocumentProperties
    {
        private HashMap _map = new HashMap();

        public Object put ( Object key, Object value )
        {
            return _map.put( key, value );
        }

        public Object get ( Object key )
        {
            return _map.get( key );
        }

        public Object remove ( Object key )
        {
            return _map.remove( key );
        }
    }

    class nthCache
    {
        private boolean namesSame ( QName pattern, QName name )
        {
            return pattern == null || pattern.equals( name );
        }

        private boolean setsSame ( QNameSet patternSet, QNameSet set)
        {
            // value equality is probably too expensive. Since the use case
            // involves QNameSets that are generated by the compiler, we
            // can use identity comparison.
            return patternSet != null && patternSet == set;
        }

        private boolean nameHit(QName namePattern,  QNameSet setPattern, QName name)
        {
            if (setPattern == null)
                return namesSame(namePattern, name);
            else
                return setPattern.contains(name);
        }

        private boolean cacheSame (QName namePattern,  QNameSet setPattern)
        {
            return setPattern == null ? namesSame(namePattern, _name) :
                setsSame(setPattern, _set);
        }

        int distance ( Splay parent, QName name, QNameSet set, int n )
        {
            assert n >= 0;

            if (_version != Root.this.getVersion())
                return Integer.MAX_VALUE - 1;

            if (parent != _parent || !cacheSame(name, set))
                return Integer.MAX_VALUE;

            return n > _n ? n - _n : _n - n;
        }

        Begin fetch ( Splay parent, QName name, QNameSet set, int n )
        {
            assert n >= 0;

            if (_version != Root.this.getVersion() || _parent != parent ||
                  ! cacheSame(name, set) || n == 0)
            {
                _version = Root.this.getVersion();
                _parent = parent;
                _name = name;
                _child = null;
                _n = -1;

                if (!parent.isLeaf())
                {
                    loop:
                    for ( Splay s = parent.nextSplay() ; ; s = s.nextSplay() )
                    {
                        switch ( s.getKind() )
                        {
                        case END  :
                        case ROOT : break loop;

                        case BEGIN :
                            if (nameHit( name, set, s.getName() ))
                            {
                                _child = s;
                                _n = 0;
                                break loop;
                            }

                            s = s.getFinishSplay();
                            break;
                        }
                    }
                }
            }

            if (_n < 0)
                return null;

            if (n > _n)
            {
                while ( n > _n )
                {
                    for ( Splay s = _child.getFinishSplay().nextSplay() ; ;
                          s = s.nextSplay() )
                    {
                        if (s.isFinish())
                            return null;

                        if (s.isBegin())
                        {
                            if (nameHit( name, set, s.getName() ))
                            {
                                _child = s;
                                _n++;
                                break;
                            }

                            s = s.getFinishSplay();
                        }
                    }
                }
            }
            else if (n < _n)
            {
                while ( n < _n )
                {
                    Splay s = _child;

                    for ( ; ; )
                    {
                        s = s.prevSplay();

                        if (s.isLeaf() || s.isEnd())
                        {
                            if (s.isEnd())
                                s = s.getContainer();

                            if (nameHit( name, set, s.getName() ))
                            {
                                _child = s;
                                _n--;
                                break;
                            }
                        }
                        else if (s.isContainer())
                            return null;
                    }
                }
            }

            return (Begin) _child;
        }

        private long     _version;
        private Splay    _parent;
        private QName    _name;
        private QNameSet _set;
        
        private Splay _child;
        private int   _n;
    }

    //
    // Da fields.  Da Bears.  Ditka is God.
    //

    boolean _leftOnly;
    Doc     _doc;
    Text    _text;
    boolean _validateOnSet;

    //
    // Document version.  These numbers get incremented when the document
    // changes in a variety of ways.
    //

    private long __version = 1;
    private long _debugChangeVersion = 1; // Debug only

    private ChangeClient _changeClients;

    DocProps _props;

    //
    // XmlInputStream
    //

    boolean _standAlone;

    //
    //
    //

    final SchemaTypeLoader _schemaTypeSystem;

    int _cInvalidatableTypes;
    int _cElemOrderSensitiveTypes;

    //
    //
    //

    nthCache _nthCache_A = new nthCache();
    nthCache _nthCache_B = new nthCache();
    TypeStoreFactory _factory;
}
