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

package org.apache.xmlbeans.impl.store;

import 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 weblogic.xml.stream.Attribute;
import weblogic.xml.stream.AttributeIterator;
import weblogic.xml.stream.CharacterData;
import weblogic.xml.stream.Location;
import weblogic.xml.stream.ProcessingInstruction;
import weblogic.xml.stream.Space;
import weblogic.xml.stream.StartDocument;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLName;
import weblogic.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 ) == 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)
                    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 :
        {
            context.begin( n.getLocalName(), 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 (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 :
                weblogic.xml.stream.Comment comment =
                    (weblogic.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)._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;
}
