/*
* 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.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 javax.xml.stream.XMLStreamReader;
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
        {
            // As of piccolo 1.03 this is never called
            throw new UnsupportedOperationException( "Should not be called" );
        }

        public void warning ( SAXParseException e ) throws SAXException
        {
            // As of piccolo 1.03 this is never called
            throw new UnsupportedOperationException( "Should not be called" );
        }

        // 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 ( XMLStreamReader xsr, SchemaType type, XmlOptions options )
        throws XmlException
    {
        try
        {
            loadXMLStreamReader( xsr, options );
        }
        catch ( javax.xml.stream.XMLStreamException e )
        {
            throw new XmlException( e.getMessage(), e );
        }

        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 ( XMLStreamReader xsr )
        {
            javax.xml.stream.Location loc = xsr.getLocation();

            if (loc != null)
            {
                lineNumberAnnotation(
                    loc.getLineNumber(), loc.getColumnNumber(), loc.getCharacterOffset() );
            }
        }
        
        void lineNumberAnnotation ( XMLEvent xe )
        {
            weblogic.xml.stream.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 XmlException, weblogic.xml.stream.XMLStreamException
    {
        loadXmlInputStream( xis, options );

        return autoTypedDocument( type, options );
    }

    public void loadXMLStreamReader ( XMLStreamReader xsr, XmlOptions options )
        throws XmlException, javax.xml.stream.XMLStreamException
    {
        options = XmlOptions.maskNull( options );
        
        LoadContext context = new LoadContext( this, options );
        
        boolean lineNums = options.hasOption( XmlOptions.LOAD_LINE_NUMBERS );

        events:
        for ( int eventType = xsr.getEventType() ; ; eventType = xsr.next() )
        {
            switch ( eventType )
            {
            case XMLStreamReader.START_DOCUMENT :
            {
                _props.setEncoding( xsr.getCharacterEncodingScheme() );
                _props.setVersion( xsr.getVersion() );
                _standAlone = xsr.isStandalone();

                if (lineNums)
                    context.lineNumberAnnotation( xsr );

                break;
            }
            
            case XMLStreamReader.END_DOCUMENT :
            {
                if (lineNums)
                    context.lineNumberAnnotation( xsr );

                break events;
            }
            
            case XMLStreamReader.START_ELEMENT :
            {
                context.begin( xsr.getName() );
                
                if (lineNums)
                    context.lineNumberAnnotation( xsr );

                int n = xsr.getAttributeCount();

                for ( int a = 0 ; a < n ; a++ )
                    context.attr( xsr.getAttributeName( a ), xsr.getAttributeValue( a ) );
                
                n = xsr.getNamespaceCount();

                for ( int a = 0 ; a < n ; a++ )
                    context.xmlns( xsr.getNamespacePrefix( a ), xsr.getNamespaceURI( a ) );
                
                break;
            }
            
            case XMLStreamReader.END_ELEMENT :
            {
                context.end();
                
                if (lineNums)
                    context.lineNumberAnnotation( xsr );
                
                break;
            }
            
            case XMLStreamReader.CHARACTERS :
            case XMLStreamReader.CDATA :
            {
                context.text( xsr.getTextCharacters(), xsr.getTextStart(), xsr.getTextLength() );
                
                if (lineNums)
                    context.lineNumberAnnotation( xsr );
                
                break;
            }
            
            case XMLStreamReader.COMMENT :
            {
                context.comment( xsr.getText() );
                
                if (lineNums)
                    context.lineNumberAnnotation( xsr );
                
                break;
            }
            
            case XMLStreamReader.PROCESSING_INSTRUCTION :
            {
                context.procinst( xsr.getPITarget(), xsr.getPIData() );
                
                if (lineNums)
                    context.lineNumberAnnotation( xsr );
                
                break;
            }
            
            case XMLStreamReader.ATTRIBUTE :
            {
                int n = xsr.getAttributeCount();

                for ( int a = 0 ; a < n ; a++ )
                    context.attr( xsr.getAttributeName( a ), xsr.getAttributeValue( a ) );
                
                break;
            }
            
            case XMLStreamReader.NAMESPACE :
            {
                int n = xsr.getNamespaceCount();

                for ( int a = 0 ; a < n ; a++ )
                    context.xmlns( xsr.getNamespacePrefix( a ), xsr.getNamespaceURI( a ) );
                
                break;
            }
            
            case XMLStreamReader.ENTITY_REFERENCE :
            {
                context.text( xsr.getText() );
                break;
            }
            
            case XMLStreamReader.SPACE :
            case XMLStreamReader.DTD :
                break;

            default :
                throw new RuntimeException( "Unhandled xml event type: " + eventType );
            }

            if (!xsr.hasNext())
                break;
        }
        
        context.finish();

        associateSourceName( options );

        assert validate();
        assert isLeftOnly();
    }
    
    public void loadXmlInputStream ( XMLInputStream xis, XmlOptions options )
        throws weblogic.xml.stream.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;
}
