/*
* 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 org.apache.xmlbeans.impl.common.Chars;
import org.apache.xmlbeans.impl.common.EncodingMap;
import org.apache.xmlbeans.impl.common.GenericXmlInputStream;
import org.apache.xmlbeans.impl.common.ValidatorListener;
import org.apache.xmlbeans.impl.common.XmlEventBase;
import org.apache.xmlbeans.impl.common.XmlNameImpl;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.store.Splay.Container;
import org.apache.xmlbeans.impl.store.Splay.Xmlns;
import org.apache.xmlbeans.impl.values.NamespaceManager;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlOptions;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.ConcurrentModificationException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import weblogic.xml.stream.Attribute;
import weblogic.xml.stream.AttributeIterator;
import weblogic.xml.stream.ChangePrefixMapping;
import weblogic.xml.stream.CharacterData;
import weblogic.xml.stream.Comment;
import weblogic.xml.stream.EndDocument;
import weblogic.xml.stream.EndElement;
import weblogic.xml.stream.EndPrefixMapping;
import weblogic.xml.stream.Location;
import weblogic.xml.stream.ProcessingInstruction;
import weblogic.xml.stream.StartDocument;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.StartPrefixMapping;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.XMLName;
import weblogic.xml.stream.XMLStreamException;

public abstract class Saver implements NamespaceManager
{
    //
    //
    //
    
    private final Object monitor()
    {
        return _root;
    }

    Saver ( Root r, Splay s, int p, XmlOptions options )
    {
        assert Root.dv > 0 || s.getRootSlow() == r;

        // Input s and p must be normalized already
        assert p < s.getEndPos();

        _root = r;
        _top = _splay = s;
        _pos = p;
        _version = r.getVersion();
        _sb = new StringBuffer();
        _attrs = new LinkedHashMap();
        _attrNames = new HashSet();
        _firstPush = true;
        
        _newLine = System.getProperty( "line.separator" );

        if (_newLine == null)
            _newLine = "\n";

        // Initialize the state of the namespaces
        _namespaceStack = new ArrayList();
        _uriMap = new HashMap();
        _prefixMap = new HashMap();

        // Stops the synthesis of this namspace and make for better
        // roundtripping 
        addMapping( "xml", Splay._xml1998Uri );

        // Check for implicit namespaces
        
        options = XmlOptions.maskNull( options );

        if (options.hasOption( XmlOptions.SAVE_IMPLICIT_NAMESPACES ))
        {
            Map m = (Map) options.get( XmlOptions.SAVE_IMPLICIT_NAMESPACES );
            
            for ( Iterator i = m.keySet().iterator() ; i.hasNext() ; )
            {
                String prefix = (String) i.next();
                addMapping( prefix, (String) m.get( prefix ) );
            }
        }

        if (options.hasOption( XmlOptions.SAVE_SUGGESTED_PREFIXES ))
            _suggestedPrefixes = (Map) options.get( XmlOptions.SAVE_SUGGESTED_PREFIXES);
        
        // If the default prefix has not been mapped, do so now
        
        if (getNamespaceForPrefix( "" ) == null)
        {
            _initialDefaultUri = new String( "" );
            addMapping( "", _initialDefaultUri );
        }

        _saveNamespacesFirst = options.hasOption( XmlOptions.SAVE_NAMESPACES_FIRST );

        if (_prettyPrint = options.hasOption( XmlOptions.SAVE_PRETTY_PRINT ))
        {
            _prettyIndent = 2;

            if (options.hasOption( XmlOptions.SAVE_PRETTY_PRINT_INDENT ))
            {
                _prettyIndent =
                    ((Integer) options.get( XmlOptions.SAVE_PRETTY_PRINT_INDENT )).intValue();
            }

            if (options.hasOption( XmlOptions.SAVE_PRETTY_PRINT_OFFSET ))
            {
                _prettyOffset =
                    ((Integer) options.get( XmlOptions.SAVE_PRETTY_PRINT_OFFSET )).intValue();
            }
        }

        if (options.hasOption( XmlOptions.SAVE_AGGRESSIVE_NAMESPACES ) &&
                !(this instanceof SynthNamespaceSaver))
        {
            SynthNamespaceSaver saver =
                new SynthNamespaceSaver( r, s, p, options );

            while ( saver.process() )
                ;

            if (!saver._synthNamespaces.isEmpty())
                _preComputedNamespaces = saver._synthNamespaces;
        }
        
        _useDefaultNamespace =
            options.hasOption( XmlOptions.SAVE_USE_DEFAULT_NAMESPACE );

        if (options.hasOption( XmlOptions.SAVE_FILTER_PROCINST ))
        {
            _filterProcinst =
                (String) options.get( XmlOptions.SAVE_FILTER_PROCINST );
        }

        if (options.hasOption( XmlOptions.SAVE_USE_OPEN_FRAGMENT ))
            _fragment = Splay._openuriFragment;
        else
            _fragment = Splay._xmlFragment;

        // Outer overrides inner
        
        _inner =
            options.hasOption( XmlOptions.SAVE_INNER ) &&
                !options.hasOption( XmlOptions.SAVE_OUTER );
        
        if (_inner && !_top.isDoc())
            _synthElem = _fragment;
        
        else if (options.hasOption( XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT ))
        {
            _fragment = _synthElem =
                (QName) options.get( XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT );

            if (_synthElem == null)
                throw new IllegalArgumentException( "Null synthetic element" );
        }
        
        _preProcess = true;
    }

    protected final void checkVersion ( )
    {
        if (_version != _root.getVersion())
            throw new ConcurrentModificationException( "Document changed during save" );
    }

    protected final Root getRoot ( ) { return _root; }
    protected final Map  getUriMap ( ) { return _uriMap; }
    protected final Map  getPrefixMap ( ) { return _prefixMap; }

    // emitContainer will process leaf contents and the text after a
    // start.  All other text is processed with emitTextAfter.

    protected abstract void emitXmlnsFragment ( Splay s );
    protected abstract void emitAttrFragment ( Splay s );
    protected abstract void emitTextFragment ( Splay s, int p, int cch );
    protected abstract void emitCommentFragment ( Splay s );
    protected abstract void emitProcinstFragment ( Splay s );

    protected abstract void emitDocType(
        String doctypeName, String publicID, String systemID );
    
    protected abstract void emitComment ( Splay s );
    protected abstract void emitTextAfter ( Splay s, int p, int cch );
    protected abstract void emitEnd ( Splay s, QName name );
    protected abstract void emitProcinst ( Splay s );
    protected abstract void emitContainer ( Container c, QName name );

    // Called when a synthetic prefix is created.
    
    protected void syntheticNamespace (
        String prefix, String uri, boolean considerCreatingDefault ) { }

    /*
     * It is vital that the saver does not modify the tree in the process of
     * saving.  So, when there is invalid content or attr values which need
     * new namespace/prefix mappings, I compute the content/values by passing
     * the NamespaceManager implemented by the saver which can cons up mappings
     * just for the purposes of saving without modifying the tree by adding
     * Xmlns splays.
     *
     * Thus, I must not, as a byproduct of saving, validate any content/values
     * into the tree which call back for namespace mappings which need to be
     * created.
     *
     * Also, I need to compute the valid text (if a splay is invalid) before
     * I have closed the attribute list of the enclosing container because
     * I will have to persist out these temporary meppings before they are
     * referenced by the values which need them.
     */

    final String text ( )
    {
        assert _text != null;
        
        return _text.toString();
    }

    final boolean noText ( )
    {
        assert _text != null || _sb.length() == 0;
        assert _text == null || _text == _sb;
        
        return _text == null;
    }

    final void clearText ( )
    {
        _text = null;
        _sb.delete( 0, _sb.length() );
    }

    final static void spaces ( StringBuffer sb, int offset, int count )
    {
        while ( count-- > 0 )
            sb.insert( offset, ' ' );
    }

    final static void trim ( StringBuffer sb )
    {
        int i;

        for ( i = 0 ; i < sb.length() ; i++ )
            if (!Splay.isWhiteSpace( sb.charAt( i ) ))
                break;

        sb.delete( 0, i );

        for ( i = sb.length() ; i > 0 ; i-- )
            if (!Splay.isWhiteSpace( sb.charAt( i - 1 ) ))
                break;

        sb.delete( i, sb.length() );
    }

    // Call process until it returns false to save everything.

    protected final boolean process ( )
    {
        synchronized (monitor())
        {
            checkVersion();
    
            if (_preProcess)
            {
                _preProcess = false;
    
                Splay s = _splay;
                int   p = _pos;
    
                _splay = null;
                _pos = 0;
    
                // Check for position right before end token.  Effectively there
                // is nothing to save here, so save out the empty fragment.
    
                if ((p == 0 && s.isFinish()) ||
                      (s.isLeaf() && p == s.getPosLeafEnd()))
                {
                    assert _splay == null;
                    processTextFragment( null, 0, 0 );
                    return true;
                }
    
                // Here, if p > 0, then we're saving some text
    
                if (p > 0)
                {
                    assert !s.isLeaf() || p != s.getPosLeafEnd();
                    processTextFragment( s, p, s.getPostCch( p ) );
                    assert _splay == null;
                    return true;
                }
    
                if (_inner && (s.isAttr() || s.isComment() || s.isProcinst()))
                {
                    processTextFragment( s, 0, s.getCchValue() );
                    return true;
                }
    
                if (s.isXmlns())
                {
                    processXmlnsFragment( s );
                    return true;
                }
                
                if (s.isAttr())
                {
                    processAttrFragment( s );
                    return true;
                }
                
                if (s.isComment())
                {
                    processCommentFragment( s );
                    return true;
                }
                
                if (s.isProcinst())
                {
                    if (_filterProcinst != null &&
                          s.getLocal().equals( _filterProcinst ))
                    {
                        processTextFragment( null, 0, 0 );
                        return true;
                    }
                    else
                        processProcinstFragment( s );
    
                    return true;
                }
    
                assert s.isContainer();
    
                _splay = s;
                _endSplay = s.isContainer() ? s.getFinishSplay() : s;
            }
    
            // I need to break the processing of a splay into two parts.  The
            // first part is the processing of the splay and the second part is
            // the post processing of the splay.  In particular, the post
            // processing, among other things, pops the mapping stack.  This
            // is done so stuff 'saved' during the first part (the pre-process)
            // can use the mapping stack.  When the next process comes around,
            // the mapping stack will then be updated.
    
            if (_postPop)
            {
                popMappings();
                _postPop = false;
            }
    
            if (_postProcess)
            {
                assert _splay != null;
    
                boolean emitted = false;
    
                if (_splay == _endSplay)
                    _splay = null;
                else
                {
                    Splay s = _splay;
    
                    _splay = _splay.nextNonAttrSplay();
    
                    if (_skipContainerFinish)
                    {
                        assert s.isBegin() && !s.isLeaf() && s.getCchAfter() ==0;
                        assert _splay.isFinish();
    
                        _splay = _splay == _endSplay ? null : _splay.nextSplay();
                    }
    
                    if (_skipContainerFinish || s.isLeaf())
                    {
                        assert !_postPop;
                        _postPop = true;
                    }
    
                    if (!s.isDoc())
                    {
                        assert noText();
    
                        int cchAfter = s.getCchAfter();
    
                        if (_prettyPrint)
                        {
                            _text = _sb;
    
                            if (cchAfter > 0)
                            {
                                Root r = getRoot();
    
                                r._text.fetch(
                                    _text,
                                    s.getCpForPos( r, s.getPosAfter() ), cchAfter );
    
                                trim( _text );
                            }
    
                            Container stop = (Container) _top;
    
                            if (!stop.isDoc())
                                stop = stop.getContainer();
    
                            Container c = s.getContainer( s.getPosAfter() );
    
                            if (_text.length() > 0)
                            {
                                Container p = c;
    
                                for ( ; p != stop ; p = p.getContainer() )
                                    spaces( _text, 0, _prettyIndent );
    
                                if (_prettyIndent >= 0)
                                {
                                    _text.insert( 0, _newLine );
                                    spaces( _text, 1, _prettyOffset );
                                }
                            }
    
                            if (_prettyIndent >= 0)
                            {
                                _text.append( _newLine );
                                spaces( _text, _text.length(), _prettyOffset );
                            }
    
                            Container p = c;
    
                            if (s.nextNonAttrSplay().isEnd())
                                p = p.getContainer();
    
                            for ( ; p != null && p != stop; p = p.getContainer() )
                                spaces( _text, _text.length(), _prettyIndent );
                        }
    
                        if (_text == null ? cchAfter > 0 : _text.length() > 0)
                        {
                            emitTextAfter( s, s.getPosAfter(), cchAfter );
                            emitted = true;
                        }
    
                        clearText();
                    }
                }
    
                _postProcess = false;
    
                // Make sure I only return false if there is *really* nothing more
                // to process
    
                if (emitted)
                    return true;
    
                if (_postPop)
                {
                    popMappings();
                    _postPop = false;
                }
            }
    
            if (_splay == null)
                return false;
    
            if (_version != getRoot().getVersion())
                throw new IllegalStateException( "Document changed" );
    
            _skipContainerFinish = false;
    
            switch ( _splay.getKind() )
            {
            case Splay.DOC :
            case Splay.BEGIN :
            {
                processContainer( (Container) _splay );
                break;
            }
            case Splay.ROOT :
            case Splay.END  :
            {
                processEnd( _splay );
                break;
            }
            case Splay.COMMENT :
            {
                emitComment( _splay );
                break;
            }
            case Splay.PROCINST :
            {
                if (_filterProcinst == null ||
                        !_splay.getLocal().equals( _filterProcinst ))
                {
                    emitProcinst( _splay );
                }
                break;
            }
            case Splay.ATTR :
            default :
            {
                assert false: "Unexpected splay kind " + _splay.getKind();
                return false;
            }
            }
    
            _postProcess = true;
    
            return true;
        }
    }

    private final void processContainer ( Container c )
    {
        assert c.isDoc() || c.isBegin();

        QName name =
            _synthElem != null && c == _top
                ? _synthElem
                : c.isBegin() ? c.getName() : null;

        String nameUri = name == null ? null : name.getNamespaceURI();

        // See if there is a doctype to save out

        if (c.isDoc() )
        {
            String systemId = _root._props.getDoctypeSystemId();
            String docTypeName = _root._props.getDoctypeName();
            
            if (systemId != null || docTypeName != null)
            {
                if (docTypeName == null && name != null)
                    docTypeName = name.getLocalPart();

                if (docTypeName == null)
                {
                    XmlCursor xc = _root.createCursor();
                    
                    if (xc.toFirstChild())
                        docTypeName = xc.getName().getLocalPart();
                    
                    xc.dispose();
                }

                if (docTypeName == null && _fragment != null)
                    docTypeName = _fragment.getLocalPart();

                String publicId = _root._props.getDoctypePublicId();
                
                emitDocType( docTypeName, publicId, systemId );
            }
        }

        // Add a new entry to the frontier.  If this element has a name
        // which has no namespace, then we must make sure that pushing
        // the mappings causes the default namespace to be empty

        boolean ensureDefaultEmpty = name != null && nameUri.length() == 0;

        pushMappings( c, ensureDefaultEmpty );

        //
        // There are four things which use mappings:
        //
        //   1) The element name
        //   2) The element value (qname based)
        //   3) Attribute names
        //   4) The attribute values (qname based)
        //

        // 1) The element name (not for starts)

        if (name != null)
            ensureMapping( nameUri, null, !ensureDefaultEmpty, false );

        assert noText();

        if (c.isInvalid())
        {
            // 2) The element value
            _text = _sb.append( c.peekType().build_text( this ) );
        }

        _attrs.clear();
        _attrNames.clear();

        for ( Splay s = c.nextSplay() ; s.isAttr() ; s = s.nextSplay() )
        {
            if (s.isNormalAttr() &&
                    (_wantDupAttrs || !_attrNames.contains( s.getName() )))
            {
                _attrNames.add( s.getName() );
                
                // 3) Attribute name
                ensureMapping( s.getUri(), null, false, true );

                String invalidValue = null;
                
                if (s.isInvalid())
                    invalidValue = s.peekType().build_text( this ); // #4

                _attrs.put( s, invalidValue );
            }
        }

        // emitContainer handles text only for leaves and starts

        if (_prettyPrint && (c.isDoc() || c.isLeaf()))
        {
            if (_text == null)
            {
                Root r = getRoot();

                r._text.fetch(
                    _text = _sb,
                    r.getCp( c ),
                    c.isLeaf() ? c.getCchValue() : c.getCch() );
            }

            trim( _text );

            if (c.isDoc())
            {
                spaces( _text, 0, _prettyOffset );

                if (_text.length() > _prettyOffset)
                {
                    if (_prettyIndent >= 0)
                    {
                        _text.insert( 0, _newLine );
                        spaces( _text, 1, _prettyOffset );
                        _text.append( _newLine );
                        spaces( _text, _text.length(), _prettyOffset );
                    }
                }
            }
        }

        // derived savers may want to test the stuff being stored to
        // see if is well formed or not in order to save out a
        // fragment.  Do this here when emitting the first container if
        // that container is the root (if not the root, then we are
        // well formed)

        if (_wantFragTest && name == null)
        {
            if ((_text != null && !Splay.isWhiteSpace( _text )) ||
                  !c.isAfterWhiteSpace( getRoot() ))
            {
                _needsFrag = true;
            }
            else
            {
                assert !c.isLeaf();
                
                Splay s = c.nextSplay();

                // Check for leaf anyways -- sometimes it happens!
                if (c.isLeaf() || s.isAttr() || hasMappings())
                    _needsFrag = true;
                else
                {
                    boolean sawBegin = false;
                    Splay cEnd = c.getFinishSplay();

                    for ( ; s != cEnd ; s = s.nextSplay() )
                    {
                        if (s.isBegin())
                        {
                            if (sawBegin)
                            {
                                _needsFrag = true;
                                break;
                            }

                            sawBegin = true;
                            s = s.getFinishSplay();
                        }

                        if (!s.isAfterWhiteSpace( getRoot() ))
                        {
                            _needsFrag = true;
                            break;
                        }
                    }

                    if (!sawBegin)
                        _needsFrag = true;
                }
            }
        }

        // If I am doing aggressive namespaces and we're emitting a
        // container which can contain content, add the namespaces
        // we've computed.  Basically, I'm making sure the pre-computed
        // namespaces are mapped on the first container which has a name.

        if (_preComputedNamespaces != null && (name != null || _needsFrag))
        {
            for ( Iterator i = _preComputedNamespaces.keySet().iterator() ; i.hasNext() ; )
            {
                String uri = (String) i.next();
                
                ensureMapping(
                    uri, null,
                    _preComputedNamespaces.get( uri ) != null && !ensureDefaultEmpty, false );
            }

            // Set to null so we do this once at the top
            _preComputedNamespaces = null;
        }

        if (_wantFragTest)
        {
            // See if I need to gen a fragment for the document

            assert name != null || (c.isDoc() && _synthElem == null);

            if (name == null)
            {
                if (_needsFrag)
                {
                    name = _fragment;
                    ensureFragmentNamespace();
                    _docElem = name;
                }
            }
            else if (c.isDoc())
                _docElem = name;
        }

        emitContainer( c, name );

        clearText();
    }

    private void processEnd ( Splay s )
    {
        Container c = s.getContainer();
        
        QName name =
            _synthElem != null && c == _top
                ? _synthElem
                : c.isBegin() ? c.getName() : null;
        
        if (_wantFragTest && name == null)
        {
            boolean isRoot = s.isRoot();

            if (!isRoot || _docElem != null)
            {
                name = 
                    isRoot
                        ? _docElem
                        : (s.isEnd() ? s.getContainer() : s ).getName();
            }
        }

        emitEnd( _splay, name );

        assert !_postPop;

        _postPop = true;
    }

    private final void pushFragmentMappings ( Splay s )
    {
        // mask the initial frame to hide default mappings
        
        pushMappings(
            s == null ? null : s.getContainer(),
            _fragment.getNamespaceURI().length() == 0 );
        
        ensureFragmentNamespace();
    }

    private final void processXmlnsFragment ( Splay s )
    {
        // Saving a default xmlns mapping is dangerous, just spit out empty
        // text
        
        if (s.getLocal().length() == 0)
        {
            pushFragmentMappings( null );
            _text = _sb;
            emitTextFragment( s, 0, 0 );
        }
        else
        {
            pushFragmentMappings( null );
            ensureMapping( s.getUri(), s.getLocal(), false, true );
            emitXmlnsFragment( s );
        }
    }

    private final void processCommentFragment ( Splay s )
    {
        pushFragmentMappings( null );
        emitCommentFragment( s );
    }

    private final void processProcinstFragment ( Splay s )
    {
        pushFragmentMappings( null );
        emitProcinstFragment( s );
    }
    
    /**
     * This is called only when a single attr is being saved.  It is not called
     * as a consequence of saving out a container.
     */

    private final void processAttrFragment ( Splay s )
    {
        assert s.isNormalAttr();

        pushFragmentMappings( s );

        ensureMapping( s.getUri(), null, false, true );

        assert noText();

        if (s.isInvalid())
        {
            // TODO - pass StringBuffer to buildText to save object creation
            _text = _sb.append( s.peekType().build_text( this ) );
        }

        emitAttrFragment( s );

        clearText();
    }

    /**
     * This is called only when a single chunk of text is to be saved.
     * It is not called as a consequence of saving out a container.
     */

    private final void processTextFragment ( Splay s, int p, int cch )
    {
        // Only need to save ancestor namespace mappings if there could be a
        // qname here.  If the text is of length 0, then there is no qname.

        Splay c = null;
        
        if ((_text != null && _text.length() > 0) || (s != null && cch > 0))
            c = s.getContainer( p );
        
        pushFragmentMappings( c );

        emitTextFragment( s, p, cch );
    }

    //
    // Layout of namespace stack:
    //
    //    URI Undo
    //    URI Rename
    //    Prefix Undo
    //    Mapping
    //

    boolean hasMappings ( )
    {
        int i = _namespaceStack.size();

        return i > 0 && _namespaceStack.get( i - 1 ) != null;
    }

    void iterateMappings ( )
    {
        _currentMapping = _namespaceStack.size();

        while ( _currentMapping > 0 &&
                  _namespaceStack.get( _currentMapping - 1 ) != null )
        {
            _currentMapping -= 8;
        }
    }

    boolean hasMapping ( )
    {
        return _currentMapping < _namespaceStack.size();
    }

    void nextMapping ( )
    {
        _currentMapping += 8;
    }

    String mappingPrefix ( )
    {
        assert hasMapping();
        return (String) _namespaceStack.get( _currentMapping + 6 );
    }

    String mappingUri ( )
    {
        assert hasMapping();
        return (String) _namespaceStack.get( _currentMapping + 7 );
    }

    String mappingPrevPrefixUri ( )
    {
        assert hasMapping();
        return (String) _namespaceStack.get( _currentMapping + 5 );
    }

    //
    //
    //

    private final void pushMappings ( Container c, boolean ensureDefaultEmpty )
    {
        _namespaceStack.add( null );

        for ( ; c != null ; c = c.getContainer() )
        {
            namespaces:
            for ( Splay s = c.nextSplay() ; s.isAttr() ; s = s.nextSplay() )
            {
                if (s.isXmlns())
                {
                    Xmlns x = (Xmlns) s;
                    String prefix = x.getLocal();
                    String uri = x.getUri();

                    if (ensureDefaultEmpty &&
                            prefix.length() == 0 && uri.length() > 0)
                    {
                        continue;
                    }

                    // Make sure the prefix is not already mapped in
                    // this frame

                    for ( iterateMappings() ; hasMapping() ; nextMapping() )
                        if (mappingPrefix().equals( prefix ))
                            continue namespaces;

                    addMapping( prefix, uri );
                }
            }

            // Push all ancestors the first time
            
            if (!_firstPush)
                break;
        }

        if (ensureDefaultEmpty)
        {
            String defaultUri = (String) _prefixMap.get( "" );

            // I map the default to "" at the very beginning
            assert defaultUri != null;

            if (defaultUri.length() > 0)
                addMapping( "", "" );
        }

        _firstPush = false;
    }

    private final void dumpMappings ( )
    {
        for ( int i = _namespaceStack.size() ; i > 0 ; )
        {
            if (_namespaceStack.get( i - 1 ) == null)
            {
                System.out.println( "----------------" );
                i--;
                continue;
            }

            System.out.print( "Mapping: " );
            System.out.print( _namespaceStack.get( i - 2 ) );
            System.out.print( " -> " );
            System.out.print( _namespaceStack.get( i - 1 ) );
            System.out.println();

            System.out.print( "Prefix Undo: " );
            System.out.print( _namespaceStack.get( i - 4 ) );
            System.out.print( " -> " );
            System.out.print( _namespaceStack.get( i - 3 ) );
            System.out.println();

            System.out.print( "Uri Rename: " );
            System.out.print( _namespaceStack.get( i - 5 ) );
            System.out.print( " -> " );
            System.out.print( _namespaceStack.get( i - 6 ) );
            System.out.println();

            System.out.print( "UriUndo: " );
            System.out.print( _namespaceStack.get( i - 7 ) );
            System.out.print( " -> " );
            System.out.print( _namespaceStack.get( i - 8 ) );
            System.out.println();

            System.out.println();

            i -= 8;
        }
    }

    private final void addMapping ( String prefix, String uri )
    {
        assert uri != null;
        assert prefix != null;

        // If the prefix being mapped here is already mapped to a uri,
        // that uri will either go out of scope or be mapped to another
        // prefix.

        String renameUri = (String) _prefixMap.get( prefix );
        String renamePrefix = null;

        if (renameUri != null)
        {
            // See if this prefix is already mapped to this uri.  If
            // so, then add to the stack, but there is nothing to rename
        
            if (renameUri.equals( uri ))
                renameUri = null;
            else
            {
                int i = _namespaceStack.size();

                while ( i > 0 )
                {
                    if (_namespaceStack.get( i - 1 ) == null)
                    {
                        i--;
                        continue;
                    }

                    if (_namespaceStack.get( i - 7 ).equals( renameUri ))
                    {
                        renamePrefix = (String) _namespaceStack.get( i - 8 );

                        if (renamePrefix == null ||
                              !renamePrefix.equals( prefix ))
                        {
                            break;
                        }
                    }

                    i -= 8;
                }

                assert i > 0;
            }
        }

        _namespaceStack.add( _uriMap.get( uri ) );
        _namespaceStack.add( uri );

        if (renameUri != null)
        {
            _namespaceStack.add( _uriMap.get( renameUri ) );
            _namespaceStack.add( renameUri );
        }
        else
        {
            _namespaceStack.add( null );
            _namespaceStack.add( null );
        }

        _namespaceStack.add( prefix );
        _namespaceStack.add( _prefixMap.get( prefix ) );

        _namespaceStack.add( prefix );
        _namespaceStack.add( uri );

        _uriMap.put( uri, prefix );
        _prefixMap.put( prefix, uri );

        if (renameUri != null)
            _uriMap.put( renameUri, renamePrefix );
    }

    private final void popMappings ( )
    {
        for ( ; ; )
        {
            int i = _namespaceStack.size();

            if (i == 0)
                break;

            if (_namespaceStack.get( i - 1 ) == null)
            {
                _namespaceStack.remove( i - 1 );
                break;
            }

            Object oldUri = _namespaceStack.get( i - 7 ); 
            Object oldPrefix = _namespaceStack.get( i - 8 ); 

            if (oldPrefix == null) 
                _uriMap.remove( oldUri ); 
            else 
                _uriMap.put( oldUri, oldPrefix ); 

            oldPrefix = _namespaceStack.get( i - 4 ); 
            oldUri = _namespaceStack.get( i - 3 ); 

            if (oldUri == null) 
                _prefixMap.remove( oldPrefix ); 
            else 
                _prefixMap.put( oldPrefix, oldUri ); 

            String uri = (String) _namespaceStack.get( i - 5 );

            if (uri != null)
                _uriMap.put( uri, _namespaceStack.get( i - 6 ) );

            // Hahahahahaha -- :-(
            _namespaceStack.remove( i - 1 );
            _namespaceStack.remove( i - 2 );
            _namespaceStack.remove( i - 3 );
            _namespaceStack.remove( i - 4 );
            _namespaceStack.remove( i - 5 );
            _namespaceStack.remove( i - 6 );
            _namespaceStack.remove( i - 7 );
            _namespaceStack.remove( i - 8 );
        }
    }

    protected final String getUriMapping ( String uri )
    {
        assert _uriMap.get( uri ) != null;
        return (String) _uriMap.get( uri );
    }

    protected final boolean tryPrefix ( String prefix )
    {
        if (prefix == null || Splay.beginsWithXml( prefix ))
            return false;

        String existingUri = (String) _prefixMap.get( prefix );

        // If the prefix is currently mapped, then try another prefix.  A
        // special case is that of trying to map the default prefix ("").
        // Here, there always exists a default mapping.  If this is the
        // mapping we found, then remap it anyways. I use != to compare
        // strings because I want to test for the specific initial default
        // uri I added when I initialized the saver.

        if (existingUri != null &&
              (prefix.length() > 0 || existingUri != _initialDefaultUri))
        {
            return false;
        }

        return true;
    }

    protected final String ensureMapping (
        String uri, String candidatePrefix,
        boolean considerCreatingDefault, boolean mustHavePrefix )
    {
        assert uri != null;
        assert candidatePrefix == null || candidatePrefix.length() > 0;

        // Can be called for no-namespaced things

        if (uri.length() == 0)
            return null;

        String prefix = (String) _uriMap.get( uri );

        if (prefix != null && (prefix.length() > 0 || !mustHavePrefix))
            return prefix;

        //
        // I try prefixes from a number of places, in order:
        //
        //  1) What was passed in
        //  2) The optional suggestions (for uri's)
        //  3) The default mapping is allowed
        //  4) ns#++
        //
        
        if (candidatePrefix == null || !tryPrefix( candidatePrefix ))
        {
            if (_suggestedPrefixes != null &&
                    _suggestedPrefixes.containsKey( uri ) &&
                        tryPrefix( (String) _suggestedPrefixes.get( uri ) ))
            {
                candidatePrefix = (String) _suggestedPrefixes.get( uri );
            }
            else if (considerCreatingDefault && _useDefaultNamespace && tryPrefix( "" ))
                candidatePrefix = "";
            else
            {
                String basePrefix = QNameHelper.suggestPrefix( uri );
                candidatePrefix = basePrefix;
                
                for ( int i = 1 ; ; i++ )
                {
                    if (tryPrefix( candidatePrefix ))
                        break;
                    
                    candidatePrefix = basePrefix + i;
                }
            }
        }

        assert candidatePrefix != null;

        syntheticNamespace( candidatePrefix, uri, considerCreatingDefault );

        addMapping( candidatePrefix, uri );

        return candidatePrefix;
    }

    public final String find_prefix_for_nsuri ( String uri, String prefix )
    {
        assert uri != null;
        assert prefix == null || prefix.length() > 0;

        boolean emptyUri = uri.length() == 0;
        
        return ensureMapping( uri, prefix, emptyUri, !emptyUri );
    }

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

        return (String) _prefixMap.get( prefix );
    }

    protected final String ensureFragmentNamespace ( )
    {
        if (_fragment.getNamespaceURI().length() == 0)
            return "";
        
        return ensureMapping( _fragment.getNamespaceURI(), "frag", false, false );
    }

    /**
     * A Saver which records synthetic namespaces
     */
    
    static final class SynthNamespaceSaver extends Saver
    {
        LinkedHashMap _synthNamespaces = new LinkedHashMap();
        
        SynthNamespaceSaver ( Root r, Splay s, int p, XmlOptions options )
        {
            super( r, s, p, options );
        }
        
        protected void syntheticNamespace (
            String prefix, String uri, boolean considerCreatingDefault )
        {
            _synthNamespaces.put( uri, considerCreatingDefault ? "useDefault" : null );
        }
        
        protected void emitXmlnsFragment ( Splay s ) { }
        protected void emitAttrFragment ( Splay s ) { }
        protected void emitTextFragment ( Splay s, int p, int cch ) { }
        protected void emitCommentFragment ( Splay s ) { }
        protected void emitProcinstFragment ( Splay s ) { }
        protected void emitComment ( Splay s ) { }
        protected void emitTextAfter ( Splay s, int p, int cch ) { }
        protected void emitEnd ( Splay s, QName name ) { }
        protected void emitProcinst ( Splay s ) { }
        protected void emitContainer ( Container c, QName name ) { }
        
        protected void emitDocType(
            String doctypeName, String publicID, String systemID ) { }
    }

    /**
     * A Saver which generates characters.
     */

    static final class TextSaver extends Saver
    {
        TextSaver (
            Root r, Splay s, int p, XmlOptions options, String encoding )
        {
            super( r, s, p, options );

            _wantFragTest = true;

            if (encoding != null)
            {
                String version = r._props.getVersion();

                if (version == null)
                    version = "1.0";
                
                emit( "<?xml version=\"" );
                emit( version );
                emit( "\" encoding=\"" + encoding + "\"?>" + _newLine );
            }
        }

        protected void emitContainer ( Container c, QName name )
        {
            if (c.isBegin())
            {
                emitContainerHelper( c, name, null, null, false );

                if (c.isLeaf())
                {
                    int cch = _text == null ? c.getCchValue() : _text.length();

                    if (cch > 0)
                    {
                        emit( '>' );

                        if (_text == null)
                            emit( getRoot().getCp( c ), cch );
                        else
                            emit( _text );

                        entitizeContent();

                        emit( "</" );
                        emitName( name );
                    }
                    else
                        emit( '/' );
                }
                else
                {
                    assert !c.isLeaf();

                    if (c.getCchAfter() == 0 && c.nextNonAttrSplay().isEnd())
                    {
                        emit( '/' );
                        _skipContainerFinish = true;
                    }
                }

                emit( '>' );
            }
            else
            {
                assert c.isDoc();

                if (name != null)
                    emitContainerHelper( c, name, null, null, true );

                if (_text == null)
                    emit( getRoot().getCp( c ), c.getCch() );
                else
                    emit( _text );

                entitizeContent();
            }
        }

        private void emitAttrHelper ( Splay s, String invalidValue )
        {
            assert s.isNormalAttr();
            
            emit( ' ' );
            emitName( s.getName() );
            emit( "=\"" );

            if (invalidValue != null)
                emit( invalidValue );
            else
                emit( getRoot().getCp( s ), s.getCch() );

            entitizeAttrValue();

            emit( '"' );
        }

        private void emitNamespacesHelper ( )
        {
            for ( iterateMappings() ; hasMapping() ; nextMapping() )
            {
                emit( ' ' );
                emitXmlns( mappingPrefix(), mappingUri() );
            }
        }
                                     
        private void emitContainerHelper (
            Container c, QName name,
            Splay extraAttr, StringBuffer extraAttrText,
            boolean close )
        {
            assert name != null;

            emit( '<' );
            emitName( name );

            if (_saveNamespacesFirst)
                emitNamespacesHelper();

            if (c != null)
            {
                for ( Iterator i = _attrs.keySet().iterator() ; i.hasNext() ; )
                {
                    Splay s = (Splay) i.next();
                    emitAttrHelper( s, (String) _attrs.get( s ) );
                }
            }

            if (extraAttr != null)
            {
                emitAttrHelper(
                    extraAttr,
                    extraAttrText == null ? null : extraAttrText.toString() );
            }

            if (!_saveNamespacesFirst)
                emitNamespacesHelper();

            if (close)
                emit( '>' );
        }

        protected void emitText ( Splay s, int p, int cch )
        {
            emit( s.getCpForPos( getRoot(), p ), cch );
            entitizeContent();
        }

        protected void emitTextAfter ( Splay s, int p, int cch )
        {
            if (_text == null)
                emitText( s, p, cch );
            else
            {
                emit( _text );
                entitizeContent();
            }
        }

        protected void emitTextFragment ( Splay s, int p, int cch )
        {
            emitContainerHelper( null, _fragment, null, null, false );

            if (_text != null)
            {
                if (_text.length() > 0)
                {
                    emit( ">" );
                    emit( _text );
                    emitEndHelper( _fragment );
                    return;
                }
            }
            else if (s != null)
            {
                if (cch > 0)
                {
                    emit( ">" );
                    emitText( s, p, cch );
                    emitEndHelper( _fragment );
                    return;
                }
            }
            
            emit( "/>" );
        }

        protected void emitAttrFragment ( Splay s )
        {
            emitContainerHelper( null, _fragment, s, _text, false );
            emit( "/>" );
        }

        protected void emitXmlnsFragment ( Splay s )
        {
            emitContainerHelper( null, _fragment, null, null, false );
            emit( "/>" );
        }

        protected void emitCommentFragment ( Splay s )
        {
            emitContainerHelper( null, _fragment, null, null, true );
            emitComment( s );
            emitEndHelper( _fragment );
        }

        protected void emitProcinstFragment ( Splay s )
        {
            emitContainerHelper( null, _fragment, null, null, true );
            emitProcinst( s );
            emitEndHelper( _fragment );
        }

        protected void emitXmlns ( String prefix, String uri )
        {
            assert prefix != null;
            assert uri != null;

            emit( "xmlns" );

            if (prefix.length() > 0)
            {
                emit( ":" );
                emit( prefix );
            }

            emit( "=\"" );

            // TODO - must encode uri properly

            emit( uri );
            entitizeAttrValue();

            emit( '"' );
        }

        protected void emitEndHelper ( QName name )
        {
            emit( "</" );
            emitName( name );
            emit( '>' );
        }

        protected void emitEnd ( Splay s, QName name )
        {
            if (name != null)
                emitEndHelper( name );
        }

        private void emitLiteral ( String literal )
        {
            if (literal.indexOf( "\"" ) < 0)
            {
                emit( "\"" );
                emit( literal );
                emit( "\"" );
            }
            else
            {
                emit( "'" );
                emit( literal );
                emit( "'" );
            }
        }

        protected void emitDocType(
            String doctypeName, String publicID, String systemID )
        {
            assert doctypeName != null;
            
            emit( "<!DOCTYPE " );
            emit( doctypeName );

            if (publicID == null && systemID != null)
            {
                emit( " SYSTEM " );
                emitLiteral( systemID );
            }
            else if (publicID != null)
            {
                emit( " PUBLIC " );
                emitLiteral( publicID );
                emit( " " );
                emitLiteral( systemID );
            }

            emit( ">" + _newLine );
        }
        
        protected void emitComment ( Splay s )
        {
            assert s.isComment();
            emit( "<!--" );
            emit( getRoot().getCp( s ), s.getCchValue() );
            entitizeComment();
            emit( "-->" );
        }

        protected void emitProcinst ( Splay s )
        {
            assert s.isProcinst();
            emit( "<?" );
            // TODO - encoding issues here?
            emit( s.getLocal() );

            if (s.getCchValue() > 0)
            {
                emit( " " );
                emit( getRoot().getCp( s ), s.getCchValue() );
                entitizeProcinst();
            }

            emit( "?>" );
        }

        /**
         * Ensure that there are at least cch chars available in the buffer.
         * Return the actual number of characters available.  If less than cch,
         * then that's all which will ever become available.
         */

        private int ensure ( int cch )
        {
            // Even if we're asked to ensure nothing, still try to ensure
            // atleast one character so we can determine if we're at the
            // end of the stream.

            if (cch <= 0)
                cch = 1;

            int available = getAvailable();

            for ( ; available < cch ; available = getAvailable() )
                if (!process())
                    break;

            assert available == getAvailable();

            if (available == 0)
                return 0;

            return available;
        }

        private void emitName ( QName name )
        {
            assert name != null;

            String uri = name.getNamespaceURI();

            assert uri != null;

            if (uri.length() != 0)
            {
                String prefix = getUriMapping( uri );

                if (prefix.length() > 0)
                {
                    emit( prefix );
                    emit( ":" );
                }
            }

            assert name.getLocalPart().length() > 0;

            emit( name.getLocalPart() );
        }

        private boolean preEmit ( int cch )
        {
            assert cch >= 0;
            
            _lastEmitCch = cch;

            if (cch == 0)
                return true;

            if (_free < cch)
                resize( cch, -1 );

            assert cch <= _free;

            int used = getAvailable();

            // if we are about to emit and there is noting in the buffer, reset
            // the buffer to be at the beginning so as to not grow it anymore
            // than needed.
            
            if (used == 0)
            {
                assert _in == _out;
                assert _free == _buf.length;
                _in = _out = 0;
            }

            _lastEmitIn = _in;

            _free -= cch;
            
            assert _free >= 0;

            return false;
        }

        private void emit ( String s )
        {
            int cch = s == null ? 0 : s.length();

            if (preEmit( cch ))
                return;

            int chunk;

            if (_in <= _out || cch < (chunk = _buf.length - _in))
            {
                s.getChars( 0, cch, _buf, _in );
                _in += cch;
            }
            else
            {
                s.getChars( 0, chunk, _buf, _in );
                s.getChars( chunk, cch, _buf, 0 );
                _in = (_in + cch) % _buf.length;
            }
        }

        private void emit ( StringBuffer sb )
        {
            int cch = sb == null ? 0 : sb.length();

            if (preEmit( cch ))
                return;

            int chunk;

            if (_in <= _out || cch < (chunk = _buf.length - _in))
            {
                sb.getChars( 0, cch, _buf, _in );
                _in += cch;
            }
            else
            {
                sb.getChars( 0, chunk, _buf, _in );
                sb.getChars( chunk, cch, _buf, 0 );
                _in = (_in + cch) % _buf.length;
            }
        }

        private void emit ( int cp, int cch )
        {
            emit(
                getRoot()._text._buf,
                getRoot()._text.unObscure( cp, cch ),
                cch );
        }

        private void emit ( char ch )
        {
            preEmit( 1 );

            _buf[ _in ] = ch;

            _in = (_in + 1) % _buf.length;
        }

        private void emit ( char[] buf, int off, int cch )
        {
            assert cch >= 0;

            if (preEmit( cch ))
                return;

            int chunk;

            if (_in <= _out || cch < (chunk = _buf.length - _in))
            {
                System.arraycopy( buf, off, _buf, _in, cch );
                _in += cch;
            }
            else
            {
                System.arraycopy( buf, off, _buf, _in, chunk );
                System.arraycopy( buf, off + chunk, _buf, 0, cch - chunk );
                _in = (_in + cch) % _buf.length;
            }
        }

        private void entitizeContent ( )
        {
            if (_lastEmitCch == 0)
                return;

            int i = _lastEmitIn;
            final int n = _buf.length;

            boolean hasOutOfRange = false;
            
            int count = 0;
            for ( int cch = _lastEmitCch ; cch > 0 ; cch-- )
            {
                char ch = _buf[ i ];

                if (ch == '<' || ch == '&')
                    count++;
                else if (isBadChar( ch ))
                    hasOutOfRange = true;

                if (++i == n)
                    i = 0;
            }

            if (count == 0 && !hasOutOfRange)
                return;

            i = _lastEmitIn;

            //
            // Heuristic for knowing when to save out stuff as a CDATA.
            //

            if (_lastEmitCch > 32 && count > 5 &&
                  count * 100 / _lastEmitCch > 1)
            {
                boolean lastWasBracket = _buf[ i ] == ']';

                i = replace( i, "<![CDATA[" + _buf[ i ] );

                boolean secondToLastWasBracket = lastWasBracket;

                lastWasBracket = _buf[ i ] == ']';

                if (++i == n)
                    i = 0;

                for ( int cch = _lastEmitCch ; cch > 0 ; cch-- )
                {
                    char ch = _buf[ i ];

                    if (ch == '>' && secondToLastWasBracket && lastWasBracket)
                        i = replace( i, "&gt;" );
                    else if (isBadChar( ch ))
                        i = replace( i, "?" );
                    else
                        i++;

                    secondToLastWasBracket = lastWasBracket;
                    lastWasBracket = ch == ']';

                    if (i == n)
                        i = 0;
                }

                emit( "]]>" );
            }
            else
            {
                for ( int cch = _lastEmitCch ; cch > 0 ; cch-- )
                {
                    char ch = _buf[ i ];

                    if (ch == '<')
                        i = replace( i, "&lt;" );
                    else if (ch == '&')
                        i = replace( i, "&amp;" );
                    else if (isBadChar( ch ))
                        i = replace( i, "?" );
                    else
                        i++;

                    if (i == n)
                        i = 0;
                }
            }
        }

        private void entitizeAttrValue ( )
        {
            if (_lastEmitCch == 0)
                return;

            int i = _lastEmitIn;
            final int n = _buf.length;

            for ( int cch = _lastEmitCch ; cch > 0 ; cch-- )
            {
                char ch = _buf[ i ];

                if (ch == '<')
                    i = replace( i, "&lt;" );
                else if (ch == '&')
                    i = replace( i, "&amp;" );
                else if (ch == '"')
                    i = replace( i, "&quot;" );
                else
                    i++;

                if (i == n)
                    i = 0;
            }
        }

        private void entitizeComment ( )
        {
            if (_lastEmitCch == 0)
                return;

            int i = _lastEmitIn;
            final int n = _buf.length;

            boolean lastWasDash = false;

            for ( int cch = _lastEmitCch ; cch > 0 ; cch-- )
            {
                char ch = _buf[ i ];

                if (isBadChar( ch ))
                    i = replace( i, "?" );
                else if (ch == '-')
                {
                    if (lastWasDash)
                    {
                        // Replace "--" with "- " to make well formed
                        i = replace( i, " " );
                        lastWasDash = false;
                    }
                    else
                    {
                        lastWasDash = true;
                        i++;
                    }
                }
                else
                {
                    lastWasDash = false;
                    i++;
                }

                if (i == n)
                    i = 0;
            }

            // Because I have only replaced chars with single chars,
            // _lastEmitIn will still be ok

            if (_buf[ _lastEmitIn + _lastEmitCch - 1 ] == '-')
                i = replace( _lastEmitIn + _lastEmitCch - 1, " " );
        }

        private void entitizeProcinst ( )
        {
            if (_lastEmitCch == 0)
                return;

            int i = _lastEmitIn;
            final int n = _buf.length;

            boolean lastWasQuestion = false;

            for ( int cch = _lastEmitCch ; cch > 0 ; cch-- )
            {
                char ch = _buf[ i ];

                if (isBadChar( ch ))
                    i = replace( i, "?" );

                if (ch == '>')
                {
    // TODO - Had to convert to a space here ... imples not well formed XML
                    if (lastWasQuestion)
                        i = replace( i, " " );
                    else
                        i++;

                    lastWasQuestion = false;
                }
                else
                {
                    lastWasQuestion = ch == '?';
                    i++;
                }

                if (i == n)
                    i = 0;
            }
        }


        /**
         * Test if a character is valid in xml character content. See
         * http://www.w3.org/TR/REC-xml#NT-Char
         */
        
        private boolean isBadChar ( char ch )
        {
            return ! (
                (ch >= 0x20 && ch <= 0xD7FF ) ||
                (ch >= 0xE000 && ch <= 0xFFFD) ||
                (ch >= 0x10000 && ch <= 0x10FFFF) ||
                (ch == 0x9) || (ch == 0xA) || (ch == 0xD)
                );
        }

        private int replace ( int i, String replacement )
        {
            assert replacement.length() > 0;

            int dCch = replacement.length() - 1;

            if (dCch == 0)
            {
                _buf[ i ] = replacement.charAt( 0 );
                return i + 1;
            }

            assert _free >= 0;

            if (dCch > _free)
                i = resize( dCch, i );
            
            assert _free >= 0;

            assert _free >= dCch;
            assert getAvailable() > 0;

            if (_out > _in && i >= _out)
            {
                System.arraycopy( _buf, _out, _buf, _out - dCch, i - _out );
                _out -= dCch;
                i -= dCch;
            }
            else
            {
                assert i < _in;
                System.arraycopy( _buf, i, _buf, i + dCch, _in - i );
                _in += dCch;
            }

            replacement.getChars( 0, dCch + 1, _buf, i );

            _free -= dCch;
            
            assert _free >= 0;

            return i + dCch + 1;
        }

        int getAvailable ( )
        {
            return _buf == null ? 0 : _buf.length - _free;
        }

        /**
         * Make sure there is enough room for cch chars in the buffer
         */

        private int resize ( int cch, int i )
        {
            assert _free >= 0;
            assert cch > 0;
            assert cch > _free;

            int newLen = _buf == null ? _initialBufSize : _buf.length * 2;
            int used = getAvailable();

            while ( newLen - used < cch )
                newLen *= 2;

            char[] newBuf = new char [ newLen ];

            if (used > 0)
            {
                if (_in > _out)
                {
                    assert i == -1 || (i >= _out && i < _in);
                    System.arraycopy( _buf, _out, newBuf, 0, used );
                    i -= _out;
                }
                else
                {
                    assert i == -1 || (i >= _out || i < _in);
                    System.arraycopy( _buf, _out, newBuf, 0, used - _in );
                    System.arraycopy( _buf, 0, newBuf, used - _in, _in );
                    i = i >= _out ? i - _out : i + _out;
                }
                
                _out = 0;
                _in = used;
                _free += newBuf.length - _buf.length;
            }
            else
            {
                _free += newBuf.length;
                assert _in == 0 && _out == 0;
                assert i == -1;
            }

            _buf = newBuf;

            assert _free >= 0;

            return i;
        }

        public int read ( )
        {
            if (ensure( 1 ) == 0)
                return -1;

            assert getAvailable() > 0;

            int ch = _buf[ _out ];

            _out = (_out + 1) % _buf.length;
            _free++;

            return ch;
        }

        public int read ( char[] cbuf, int off, int len )
        {
            // Check for end of stream even if there is no way to return
            // characters because the Reader doc says to return -1 at end of
            // stream.

            int n;

            if ((n = ensure( len )) == 0)
                return -1;

            if (cbuf == null || len <= 0)
                return 0;

            if (n < len)
                len = n;

            if (_out < _in)
            {
                System.arraycopy( _buf, _out, cbuf, off, len );
            }
            else
            {
                int chunk = _buf.length - _out;

                if (chunk >= len)
                    System.arraycopy( _buf, _out, cbuf, off, len );
                else
                {
                    System.arraycopy( _buf, _out, cbuf, off, chunk );
                    System.arraycopy( _buf, 0, cbuf, off + chunk, len - chunk );
                }
            }

            _out = (_out + len) % _buf.length;
            _free += len;

            assert _free >= 0;

            return len;
        }

        public int write ( Writer writer, int cchMin )
        {
            while ( getAvailable() < cchMin)
            {
                if (!process())
                    break;
            }

            int charsAvailable = getAvailable();

            if (charsAvailable > 0)
            {
                // I don't want to deal with the circular cases

                assert _out == 0;

                try
                {
                    writer.write( _buf, 0, charsAvailable );
                    writer.flush();
                }
                catch ( IOException e )
                {
                    throw new RuntimeException( e );
                }

                _free += charsAvailable;
                
                assert _free >= 0;
                
                _in = 0;
            }

            return charsAvailable;
        }

        /**
         * Ensure all text and return it as a string.
         */

        public String saveToString ( )
        {
            // We're gonna build a string.  Instead of using StringBuffer, may
            // as well use my buffer here.  Fill the whole sucker up and
            // create a String!

            while ( process() )
                ;

            assert _out == 0;

            int available = getAvailable();

            return available == 0 ? "" : new String( _buf, _out, available );
        }

        private static final int _initialBufSize = 4096;

        private int _lastEmitIn;
        private int _lastEmitCch;

        private int    _free;
        private int    _in;
        private int    _out;
        private char[] _buf;
    }

    /**
     * A Reader which exposes the text of a part of the tree.
     */

    static final class TextReader extends Reader
    {
        TextReader ( Root r, Splay s, int p, XmlOptions options )
        {
            _textSaver = new TextSaver( r, s, p, options, null );
        }

        public void close ( ) throws IOException { }

        public boolean ready ( ) throws IOException { return true; }

        public int read ( ) throws IOException
        {
            return _textSaver.read();
        }

        public int read ( char[] cbuf ) throws IOException
        {
            return _textSaver.read( cbuf, 0, cbuf == null ? 0 : cbuf.length );
        }

        public int read ( char[] cbuf, int off, int len ) throws IOException
        {
            return _textSaver.read( cbuf, off, len );
        }

        private TextSaver _textSaver;
    }

    /**
     *
     */

    static final class InputStreamSaver extends InputStream
    {
        InputStreamSaver (
            Root r, Splay s, int p, XmlOptions options )
        {
            options = XmlOptions.maskNull(options);
            _byteBuffer = new OutputStreamImpl();

            String encoding = null;
            
            if (r._props.getEncoding() != null)
            {
                encoding =
                    EncodingMap.getIANA2JavaMapping( r._props.getEncoding() );
            }

            if (options.hasOption(XmlOptions.CHARACTER_ENCODING))
            {
                encoding =
                    (String) options.get(XmlOptions.CHARACTER_ENCODING);
            }

            if (encoding != null)
            {
                String ianaEncoding =
                    EncodingMap.getJava2IANAMapping( encoding );

                if (ianaEncoding != null)
                    encoding = ianaEncoding;
            }

            if (encoding == null)
                encoding = EncodingMap.getJava2IANAMapping( "UTF8" );

            String javaEncoding = EncodingMap.getIANA2JavaMapping( encoding );

            if (javaEncoding == null)
            {
                throw
                    new IllegalStateException(
                        "Unknown encoding: " + encoding );
            }

            try
            {
                _converter = new OutputStreamWriter( _byteBuffer, javaEncoding);
            }
            catch ( UnsupportedEncodingException e )
            {
                throw new RuntimeException( e );
            }

            _textSaver = new TextSaver( r, s, p, options, encoding );
        }

        public int read ( )
        {
            return _byteBuffer.read();
        }

        public int read ( byte[] bbuf, int off, int len )
        {
            return _byteBuffer.read ( bbuf, off, len );
        }

        private int ensure ( int cbyte )
        {
            // Even if we're asked to ensure nothing, still try to ensure
            // atleast one byte so we can determine if we're at the
            // end of the stream.

            if (cbyte <= 0)
                cbyte = 1;

            int bytesAvailable = _byteBuffer.getAvailable();

            for ( ; bytesAvailable < cbyte ;
                  bytesAvailable = _byteBuffer.getAvailable() )
            {
                if (_textSaver.write( _converter, 2048 ) < 2048)
                    break;
            }

            bytesAvailable = _byteBuffer.getAvailable();

            if (bytesAvailable == 0)
                return 0;

            return bytesAvailable;
        }

        private final class OutputStreamImpl extends OutputStream
        {
            int read ( )
            {
                if (InputStreamSaver.this.ensure( 1 ) == 0)
                    return -1;

                assert getAvailable() > 0;

                int bite = _buf[ _out ];

                _out = (_out + 1) % _buf.length;
                _free++;

                return bite;
            }

            int read ( byte[] bbuf, int off, int len )
            {
                // Check for end of stream even if there is no way to return
                // characters because the Reader doc says to return -1 at end of
                // stream.

                int n;

                if ((n = ensure( len )) == 0)
                    return -1;

                if (bbuf == null || len <= 0)
                    return 0;

                if (n < len)
                    len = n;

                if (_out < _in)
                {
                    System.arraycopy( _buf, _out, bbuf, off, len );
                }
                else
                {
                    int chunk = _buf.length - _out;

                    if (chunk >= len)
                        System.arraycopy( _buf, _out, bbuf, off, len );
                    else
                    {
                        System.arraycopy( _buf, _out, bbuf, off, chunk );

                        System.arraycopy(
                            _buf, 0, bbuf, off + chunk, len - chunk );
                    }
                }

                _out = (_out + len) % _buf.length;
                _free += len;

                return len;
            }

            int getAvailable ( )
            {
                return _buf == null ? 0 : _buf.length - _free;
            }

            public void write ( int bite )
            {
                if (_free == 0)
                    resize( 1 );

                assert _free > 0;

                _buf[ _in ] = (byte) bite;

                _in = (_in + 1) % _buf.length;
                _free--;
            }

            public void write ( byte[] buf, int off, int cbyte )
            {
                assert cbyte >= 0;

                if (cbyte == 0)
                    return;

                if (_free < cbyte)
                    resize( cbyte );

                if (_in == _out)
                {
                    assert getAvailable() == 0;
                    assert _free == _buf.length - getAvailable();
                    _in = _out = 0;
                }

                int chunk;

                if (_in <= _out || cbyte < (chunk = _buf.length - _in))
                {
                    System.arraycopy( buf, off, _buf, _in, cbyte );
                    _in += cbyte;
                }
                else
                {
                    System.arraycopy( buf, off, _buf, _in, chunk );

                    System.arraycopy(
                        buf, off + chunk, _buf, 0, cbyte - chunk );

                    _in = (_in + cbyte) % _buf.length;
                }

                _free -= cbyte;
            }

            void resize ( int cbyte )
            {
                assert cbyte > _free;

                int newLen = _buf == null ? _initialBufSize : _buf.length * 2;
                int used = getAvailable();

                while ( newLen - used < cbyte )
                    newLen *= 2;

                byte[] newBuf = new byte [ newLen ];

                if (used > 0)
                {
                    if (_out == _in)
                        System.arraycopy( _buf, 0, newBuf, 0, used );
                    else if (_in > _out)
                        System.arraycopy( _buf, _out, newBuf, 0, used );
                    else
                    {
                        System.arraycopy(
                            _buf, _out, newBuf, 0, used - _in );

                        System.arraycopy(
                            _buf, 0, newBuf, used - _in, _in );
                    }

                    _out = 0;
                    _in = used;
                    _free += newBuf.length - _buf.length;
                }
                else
                {
                    _free += newBuf.length;
                    assert _in == 0 && _out == 0;
                }

                _buf = newBuf;
            }

            private static final int _initialBufSize = 4096;

            int    _free;
            int    _in;
            int    _out;
            byte[] _buf;
        }

        private OutputStreamImpl   _byteBuffer;
        private TextSaver          _textSaver;
        private OutputStreamWriter _converter;
    }

    /**
     *
     */

    static final class XmlInputStreamSaver extends Saver
    {
        XmlInputStreamSaver ( Root r, Splay s, int p, XmlOptions options )
        {
            super( r, s, p, options );
        }

        XMLEvent dequeue ( ) throws XMLStreamException
        {
            if (_out == null && !process())
                return null;

            if (_out == null)
                return null;

            XmlEventImpl e = _out;

            if ((_out = _out._next) == null)
                _in = null;

            return e;
        }

        private void enqueue ( XmlEventImpl e )
        {
            assert e._next == null;

            if (_in == null)
            {
                assert _out == null;
                _out = _in = e;
            }
            else
            {
                _in._next = e;
                _in = e;
            }
        }

        //
        //
        //

        protected void emitXmlnsFragment ( Splay s )
        {
            throw new IllegalStateException( "Can't stream an attribute" );
        }

        protected void emitText ( Splay s, int p, int cch )
        {
            assert cch > 0;
            enqueue( new CharacterDataImpl( getRoot(), s, p, null ) );
        }

        protected void emitTextFragment ( Splay s, int p, int cch )
        {
            // BUGBUG - there could be namespaces pushed for this text, not
            // sure how to communicate those, however

            if (_text != null)
            {
                if (_text.length() > 0)
                    emitText( s, p, cch );
                
                return;
            }
            
            if (s != null && cch > 0)
                emitText( s, p, cch );
        }

        protected void emitTextAfter ( Splay s, int p, int cch )
        {
            if (_text == null)
                emitText( s, p, cch );
            else
                enqueue( new CharacterDataImpl( getRoot(), s, -1, text() ) );
        }

        protected void emitEndPrefixMappings ( )
        {
            Root r = getRoot();

            for ( iterateMappings() ; hasMapping() ; nextMapping() )
            {
                String prevPrefixUri = mappingPrevPrefixUri();

                if (prevPrefixUri == null)
                    enqueue( new EndPrefixMappingImpl( r, mappingPrefix() ) );
                else
                {
                    enqueue(
                        new ChangePrefixMappingImpl(
                            r, mappingPrefix(), mappingUri(), prevPrefixUri ) );
                }
            }
        }

        protected void emitEnd ( Splay s, QName name )
        {
            Root r = getRoot();

            if (s.isRoot())
                enqueue( new EndDocumentImpl( r, s ) );
            else if (s.isEnd())
                enqueue( new EndElementImpl( r, s, name, getUriMap() ) );
            else
            {
                assert s.isLeaf();
                enqueue( new EndElementImpl( r, s, name, getUriMap() ) );
            }

            emitEndPrefixMappings();
        }

        protected void emitCommentFragment ( Splay s )
        {
            emitComment( s );
        }

        protected void emitProcinstFragment ( Splay s )
        {
            emitProcinst( s );
        }

        protected void emitDocType(
            String doctypeName, String publicID, String systemID )
        {
        }
        
        protected void emitComment ( Splay s )
        {
            enqueue( new CommentImpl( getRoot(), s ) );
        }

        protected void emitProcinst ( Splay s )
        {
            enqueue( new ProcessingInstructionImpl( getRoot(), s ) );
        }

        protected void emitAttrFragment ( Splay s )
        {
            throw new IllegalStateException( "Can't stream an attribute" );
        }

        protected void emitContainer ( Container c, QName name )
        {
            Root r = getRoot();

            for ( iterateMappings() ; hasMapping() ; nextMapping() )
            {
                enqueue(
                    new StartPrefixMappingImpl(
                        r, mappingPrefix(), mappingUri() ) );
            }

            if (c.isDoc())
                enqueue( new StartDocumentImpl( r, c ) );

            if (name != null)
            {
                enqueue(
                    new StartElementImpl( r, c, name, this ) );
            }

            if (c.isDoc())
            {
                assert c.isDoc();

                if (_text != null)
                {
                    if (_text.length() > 0)
                        enqueue( new CharacterDataImpl( r, c, -1, text() ) );
                }
                else if (c.getCch() > 0)
                    enqueue( new CharacterDataImpl( r, c, 1, null ) );
            }
            else if (c.isLeaf())
            {
                if (_text != null)
                {
                    if (_text.length() > 0)
                        enqueue( new CharacterDataImpl( r, c, -1, text() ));
                }
                else if (c.getCchValue() > 0)
                    enqueue( new CharacterDataImpl( r, c, 1, null ) );

                enqueue( new EndElementImpl( r, c, name, getUriMap() ) );

                emitEndPrefixMappings();
            }
        }


        //
        //
        //

        private static XMLName computeName ( QName n, Map uriMap )
        {
            String uri = n.getNamespaceURI();

            if (uri.length() == 0)
                uri = null;

            assert n.getLocalPart().length() > 0;

            // The following assert may fire if someone computes a name
            // of an element/attr too late (after other events have been
            // enqueued and the uri map has been updated.  I check later
            // to make sure we don't crash, however.

            assert uri == null || uriMap.containsKey( uri ) : "Problem uri " + uri;

            String prefix = null;

            if (uri != null)
            {
                prefix = (String) uriMap.get( uri );

                if (prefix != null && prefix.length() == 0)
                    prefix = null;
            }

            return new XmlNameImpl( uri, n.getLocalPart(), prefix );
        }

        private static abstract class XmlEventImpl extends XmlEventBase
        {
            public Object monitor()
            {
                return _root;
            }
            
            XmlEventImpl ( int type, Root r, Splay s )
            {
                super( type );
                _root = r;
                _splay = s;
                _version = _root.getVersion();
            }

            public XMLName getName ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return null;
                }
            }

            public XMLName getSchemaType ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    throw new RuntimeException( "NYI" );
                }
            }

            public boolean hasName ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return false;
                }
            }

            public final Location getLocation ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    // TODO - perhaps I can save a location goober sometimes?
                    return null;
                }
            }

            protected final void checkVersion ( )
            {
                if (_version != _root.getVersion())
                    throw new ConcurrentModificationException( "Document changed" );
            }

            protected final Root getRoot ( )
            {
                return _root;
            }

            protected final Splay getSplay ( )
            {
                return _splay;
            }

            private Root  _root;
            private Splay _splay;
            private long  _version;

            XmlEventImpl _next;
        }

        private static class StartDocumentImpl
            extends XmlEventImpl implements StartDocument
        {
            StartDocumentImpl ( Root r, Splay s )
            {
                super( XMLEvent.START_DOCUMENT, r, s );
            }

            public String getSystemId ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return getRoot()._props.getDoctypeSystemId();
                }
            }

            public String getCharacterEncodingScheme ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return getRoot()._props.getEncoding();
                }
            }

            public boolean isStandalone ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return getRoot()._standAlone;
                }
            }

            public String getVersion ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return getRoot()._props.getVersion();
                }
            }
        }

        private static class StartElementImpl
            extends XmlEventImpl implements StartElement
        {
            StartElementImpl ( Root r, Splay s, QName name, Saver saver )
            {
                super( XMLEvent.START_ELEMENT, r, s );

                _name = computeName( name, saver.getUriMap() );

                _prefixMap = saver.getPrefixMap();

                AttributeImpl lastAttr = null;

                for ( Iterator i = saver._attrs.keySet().iterator() ;
                      i.hasNext() ; )
                {
                    Splay a = (Splay) i.next();
                    
                    AttributeImpl attr =
                        new NormalAttributeImpl(
                            r, a, (String) saver._attrs.get( a ),
                            saver.getUriMap() );
                    
                    if (_attributes == null)
                        _attributes = attr;
                    else
                        lastAttr._next = attr;

                    lastAttr = attr;
                }

                lastAttr = null;

                for ( saver.iterateMappings() ;
                      saver.hasMapping() ; saver.nextMapping() )
                {
                    AttributeImpl attr =
                        new XmlnsAttributeImpl(
                            r, saver.mappingPrefix(), saver.mappingUri(),
                            saver.getUriMap() );

                    if (_namespaces == null)
                        _namespaces = attr;
                    else
                        lastAttr._next = attr;

                    lastAttr = attr;
                }
            }

            public boolean hasName()
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return true;
                }
            }

            public XMLName getName ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return _name;
                }
            }

            public AttributeIterator getAttributes ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    return
                        new AttributeIteratorImpl( getRoot(), _attributes, null );
                }
            }

            public AttributeIterator getNamespaces ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    return
                        new AttributeIteratorImpl( getRoot(), null, _namespaces );
                }
            }

            public AttributeIterator getAttributesAndNamespaces ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    return
                        new AttributeIteratorImpl(
                            getRoot(), _attributes, _namespaces );
                }
            }

            public Attribute getAttributeByName ( XMLName xmlName )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    for ( AttributeImpl a = _attributes ; a != null ; a = a._next )
                    {
                        if (xmlName.equals( a.getName() ))
                            return a;
                    }
    
                    return null;
                }
            }

            public String getNamespaceUri ( String prefix )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    return
                        (String) _prefixMap.get( prefix == null ? "" : prefix );
                }
            }

            public Map getNamespaceMap ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    return _prefixMap;
                }
            }

            private static class AttributeIteratorImpl
                implements AttributeIterator
            {
                public Object monitor()
                {
                    return _root;
                }
                
                AttributeIteratorImpl (
                    Root r, AttributeImpl attributes, AttributeImpl namespaces )
                {
                    _root = r;
                    _version = r.getVersion();
                    _attributes = attributes;
                    _namespaces = namespaces;
                }

                public Attribute next ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
    
                        AttributeImpl attr = null;
    
                        if (_attributes != null)
                        {
                            attr = _attributes;
                            _attributes = attr._next;
                        }
                        else if (_namespaces != null)
                        {
                            attr = _namespaces;
                            _namespaces = attr._next;
                        }
    
                        return attr;
                    }
                }

                public boolean hasNext ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
    
                        return _attributes != null || _namespaces != null;
                    }
                }

                public Attribute peek ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
    
                        if (_attributes != null)
                            return _attributes;
                        else if (_namespaces != null)
                            return _namespaces;
    
                        return null;
                    }
                }

                public void skip ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
    
                        if (_attributes != null)
                            _attributes = _attributes._next;
                        else if (_namespaces != null)
                            _namespaces = _namespaces._next;
                    }
                }

                private final void checkVersion ( )
                {
                    if (_version != _root.getVersion())
                        throw new IllegalStateException( "Document changed" );
                }

                private Root          _root;
                private long          _version;
                private AttributeImpl _attributes;
                private AttributeImpl _namespaces;
            }

            private static abstract class AttributeImpl implements Attribute
            {
                public Object monitor()
                {
                    return _root;
                }
                
                AttributeImpl ( Root r )
                {
                    _root = r;
                    _version = r.getVersion();
                }

                public XMLName getName ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
                        return _name;
                    }
                }

                public String getType ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
    // TODO - Make sure throwing away this DTD info is ok.
    // Is there schema info which can return more useful info?
                        return "CDATA";
                    }
                }

                public XMLName getSchemaType ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
    // TODO - Can I return something reasonable here?
                        return null;
                    }
                }

                protected final void checkVersion ( )
                {
                    if (_version != _root.getVersion())
                        throw new IllegalStateException( "Document changed" );
                }

                AttributeImpl _next;

                protected XMLName _name;

                protected Root  _root;
                private long  _version;
            }

            private static class XmlnsAttributeImpl extends AttributeImpl
            {
                XmlnsAttributeImpl (
                    Root r, String prefix, String uri, Map uriMap )
                {
                    super( r );

                    _uri = uri;

                    String local;

                    if (prefix.length() == 0)
                    {
                        prefix = null;
                        local = "xmlns";
                    }
                    else
                    {
                        local = prefix;
                        prefix = "xmlns";
                    }

                    _name = new XmlNameImpl( null, local, prefix );
                }

                public String getValue ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
                        return _uri;
                    }
                }

                private String _uri;
            }

            private static class NormalAttributeImpl extends AttributeImpl
            {
                NormalAttributeImpl (
                    Root r, Splay s, String value, Map uriMap )
                {
                    super( r );
                    assert s.isNormalAttr();
                    _splay = s;
                    _value = value;
                    _name = computeName( s.getName(), uriMap );
                }

                public String getValue ( )
                {
                    synchronized (monitor())
                    {
                        checkVersion();
    
                        return _value != null ? _value : _splay.getText( _root );
                    }
                }

                private String _value; // If invalid in the store
                private Splay _splay;
            }

            private XMLName _name;
            private Map     _prefixMap;

            private AttributeImpl _attributes;
            private AttributeImpl _namespaces;
        }

        private static class StartPrefixMappingImpl
            extends XmlEventImpl implements StartPrefixMapping
        {
            StartPrefixMappingImpl ( Root r, String prefix, String uri )
            {
                super( XMLEvent.START_PREFIX_MAPPING, r, null );

                _prefix = prefix;
                _uri = uri;
            }

            public String getNamespaceUri ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return _uri;
                }
            }

            public String getPrefix ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return _prefix;
                }
            }

            private String _prefix, _uri;
        }

        private static class ChangePrefixMappingImpl
            extends XmlEventImpl implements ChangePrefixMapping
        {
            ChangePrefixMappingImpl (
                Root r, String prefix, String oldUri, String newUri )
            {
                super( XMLEvent.CHANGE_PREFIX_MAPPING, r, null );

                _oldUri = oldUri;
                _newUri = newUri;
                _prefix = prefix;
            }

            public String getOldNamespaceUri ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return _oldUri;
                }
            }

            public String getNewNamespaceUri ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return _newUri;
                }
            }

            public String getPrefix ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return _prefix;
                }
            }

            private String _oldUri, _newUri, _prefix;
        }

        private static class EndPrefixMappingImpl
            extends XmlEventImpl implements EndPrefixMapping
        {
            EndPrefixMappingImpl ( Root r, String prefix )
            {
                super( XMLEvent.END_PREFIX_MAPPING, r, null );
                _prefix = prefix;
            }

            public String getPrefix ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return _prefix;
                }
            }

            private String _prefix;
        }

        private static class CharacterDataImpl
            extends XmlEventImpl implements CharacterData
        {
            CharacterDataImpl ( Root r, Splay s, int p, String charData )
            {
                super( XMLEvent.CHARACTER_DATA, r, s );

                assert p > 0 || (charData != null && charData.length() > 0);

                _pos = p;
                _charData = charData;
            }

            public String getContent ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    Splay s = getSplay();
    
                    if (_pos == -1)
                        return _charData;
    
                    Root r = getRoot();
    
                    return
                        r._text.fetch(
                            s.getCpForPos( r, _pos ), s.getPostCch( _pos ) );
                }
            }

            public boolean hasContent ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return true;
                }
            }

            private int    _pos;
            private String _charData;
        }

        private static class EndElementImpl
            extends XmlEventImpl implements EndElement
        {
            EndElementImpl ( Root r, Splay s, QName name, Map uriMap )
            {
                super( XMLEvent.END_ELEMENT, r, s );

                assert s.isLeaf() || s.isEnd();

                if (name == null)
                {
                    if (s.isEnd())
                        s = s.getContainer();
                    
                    name = s.getName();
                }

                _name = computeName( name, uriMap );
            }

            public boolean hasName ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return true;
                }
            }

            public XMLName getName ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return _name;
                }
            }

            private XMLName _name;
        }

        private static class EndDocumentImpl
            extends XmlEventImpl implements EndDocument
        {
            EndDocumentImpl ( Root r, Splay s )
            {
                super( XMLEvent.END_DOCUMENT, r, s );
            }
        }

        private static class CommentImpl
            extends XmlEventImpl implements Comment
        {
            CommentImpl ( Root r, Splay s )
            {
                super( XMLEvent.COMMENT, r, s );
                assert s.isComment();
            }

            public String getContent ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    Splay s = getSplay();
                    return s.getCch() == 0 ? null : s.getText( getRoot() );
                }
            }

            public boolean hasContent ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
    
                    return getSplay().getCch() > 0;
                }
            }
        }

        private static class ProcessingInstructionImpl
            extends XmlEventImpl implements ProcessingInstruction
        {
            ProcessingInstructionImpl ( Root r, Splay s )
            {
                super( XMLEvent.PROCESSING_INSTRUCTION, r, s );
                assert s.isProcinst();
            }

            public String getTarget ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    return getSplay().getLocal();
                }
            }

            public String getData ( )
            {
                synchronized (monitor())
                {
                    checkVersion();
                    Splay s = getSplay();
                    return s.getCch() == 0 ? null : s.getText( getRoot() );
                }
            }
        }

        private XmlEventImpl _in, _out;
    }

    static final class XmlInputStreamImpl extends GenericXmlInputStream
    {
        XmlInputStreamImpl ( Root r, Splay s, int p, XmlOptions options )
        {
            _xmlInputStreamSaver =
                new XmlInputStreamSaver( r, s, p, options );

            // Make the saver grind away just a bit to throw any exceptions
            // related to the inability to create a stream on this xml
            
            _xmlInputStreamSaver.process();
        }

        protected XMLEvent nextEvent ( ) throws XMLStreamException
        {
            return _xmlInputStreamSaver.dequeue();
        }

        private XmlInputStreamSaver _xmlInputStreamSaver;
    }

    //
    //
    //

    static final class ValidatorSaver
        extends Saver implements ValidatorListener.Event
    {
        ValidatorSaver (
            Root r, Splay s, int p,
            XmlOptions options, ValidatorListener vEventSink )
        {
            super( r, s, p, options );

            _wantDupAttrs = true;

            assert p == 0;

            _startSplay = s;
            _vEventSink = vEventSink;

            while ( process() )
                ;  // Empty
        }

        protected void emitXmlnsFragment ( Splay s )
        {
            throw new IllegalStateException();
        }

        protected void emitTextFragment ( Splay s, int p, int cch )
        {
            throw new IllegalStateException();
        }

        protected void emitCommentFragment ( Splay s )
        {
            throw new IllegalStateException();
        }

        protected void emitProcinstFragment ( Splay s )
        {
            throw new IllegalStateException();
        }

        protected void emitTextAfter ( Splay s, int p, int cch )
        {
            if (_text == null)
            {
                assert cch > 0;
                emitEvent( ValidatorListener.TEXT, s, p, null, s, p );
            }
            else
                emitEvent( ValidatorListener.TEXT, s, p, null, text() );
        }

        protected void emitEnd ( Splay s, QName name )
        {
            emitEvent( ValidatorListener.END, s, 0 );
        }

        protected void emitDocType(
            String doctypeName, String publicID, String systemID )
        {
        }
        
        protected void emitComment ( Splay s )
        {
            if (s.getCchAfter() > 0)
                emitEvent( ValidatorListener.TEXT, s, 0, null, s, 1 );
        }

        protected void emitProcinst ( Splay s )
        {
            if (s.getCchAfter() > 0)
                emitEvent( ValidatorListener.TEXT, s, 0, null, s, 1 );
        }

        protected void emitAttrFragment ( Splay s )
        {
            emitEvent( ValidatorListener.BEGIN, s, 0, null );

            if (_text != null)
            {
                if (_text.length() > 0)
                    emitEvent( ValidatorListener.TEXT, s, 0, null, text() );
            }
            else if (s.getCch() > 0)
                emitEvent( ValidatorListener.TEXT, s, 0, null, s, 0 );

            emitEvent( ValidatorListener.END, s, 0 );
        }

        protected void emitContainer ( Container c, QName name )
        {
            assert _xsiNoLoc == null;
            assert _xsiLoc == null;
            assert _xsiType == null;
            assert _xsiNil == null;

            for ( Splay s = c.nextSplay() ; s.isAttr() ; s = s.nextSplay() )
            {
                if (s.isXsiAttr())
                {
                    String local = s.getLocal();

                    if (local.equals( "type" ))
                        _xsiType = s;
                    else if (local.equals( "nil" ))
                        _xsiNil = s;
                    else if (local.equals( "schemaLocation" ))
                        _xsiLoc = s;
                    else if (local.equals( "noNamespaceSchemaLocation" ))
                        _xsiNoLoc = s;
                }
            }

            emitEvent(
                ValidatorListener.BEGIN, c, 0,
                c == _startSplay ? null : name );

            _xsiNoLoc = _xsiLoc = _xsiType = _xsiNil = null;

            for ( Iterator i = _attrs.keySet().iterator() ; i.hasNext() ; )
            {
                Splay s = (Splay) i.next();
                
                if (s.isXsiAttr())
                {
                    String local = s.getLocal();

                    if (local.equals( "type" ) ||
                        local.equals( "nil" ) ||
                        local.equals( "schemaLocation" ) ||
                        local.equals( "noNamespaceSchemaLocation" ))
                    {
                        continue;
                    }
                }

                String invalidAttrValue = (String) _attrs.get( s );

                if (invalidAttrValue == null)
                {
                    emitEvent(
                        ValidatorListener.ATTR, s, 0, s.getName(), s, 0 );
                }
                else
                {
                    emitEvent(
                        ValidatorListener.ATTR, s, 0, s.getName(),
                        invalidAttrValue );
                }
            }

            emitEvent( ValidatorListener.ENDATTRS, c, 0 );

            if (c.isDoc())
            {
                assert c.isDoc();

                if (_text != null)
                {
                    if (_text.length() > 0)
                        emitEvent( ValidatorListener.TEXT, c, 1, null, text() );
                }
                else if (c.getCch() > 0)
                    emitEvent( ValidatorListener.TEXT, c, 1, null, c, 1 );
            }
            else if (c.isLeaf())
            {
                int cch = _text != null ? _text.length() : c.getCchValue();

                if (cch > 0)
                {
                    if (_text != null)
                    {
                        emitEvent(
                            ValidatorListener.TEXT, c, 1, null, text() );
                    }
                    else
                    {
                        emitEvent(
                            ValidatorListener.TEXT, c, 1, null, c, 1 );
                    }
                }

                emitEvent( ValidatorListener.END, c, c.getPosLeafEnd() );
            }
        }

        protected void emitEvent ( int kind, Splay sLoc, int pLoc )
            { emitEvent( kind, sLoc, pLoc, null, null, 0, null ); }

        protected void emitEvent ( int kind, Splay sLoc, int pLoc, QName name )
            { emitEvent( kind, sLoc, pLoc, name, null, 0, null ); }

        protected void emitEvent (
            int kind, Splay sLoc, int pLoc, QName name, String text )
                { emitEvent ( kind, sLoc, pLoc, name, null, 0, text ); }

        protected void emitEvent (
            int kind, Splay sLoc, int pLoc, QName name, Splay sText, int pText )
                { emitEvent ( kind, sLoc, pLoc, name, sText, pText, null ); }

        protected void emitEvent (
            int kind, Splay sLoc, int pLoc, QName name,
            Splay sText, int pText, String text )
        {
            if (kind == ValidatorListener.TEXT && _emittedText)
                return;

            boolean hasText = text != null || sText != null;

            assert
                !hasText ||
                    (kind == ValidatorListener.ATTR ||
                        kind == ValidatorListener.TEXT);

            assert kind != ValidatorListener.ATTR || hasText;
            assert kind != ValidatorListener.TEXT || hasText;

            assert kind != ValidatorListener.ATTR || name != null;

            _name = name;
            _sText = sText;
            _pText = pText;
            _eventText = text;
            _hasText = hasText;
            _sLoc = sLoc;
            _pLoc = pLoc;

            _vEventSink.nextEvent( kind, this );

            _emittedText = kind == ValidatorListener.TEXT;
        }

        //
        //
        //

        public XmlCursor getLocationAsCursor ( )
        {
            checkVersion();
            return new Cursor( getRoot(), _sLoc, _pLoc );
        }

        public boolean getXsiType ( Chars chars )
        {
            if (_xsiType == null)
                return false;

            setChars( chars, PRESERVE, null, _xsiType, 0 );

            return true;
        }

        public boolean getXsiNil ( Chars chars )
        {
            if (_xsiNil == null)
                return false;


            setChars( chars, PRESERVE, null, _xsiNil, 0 );

            return true;
        }

        public boolean getXsiLoc ( Chars chars )
        {
            if (_xsiLoc == null)
                return false;

            setChars( chars, PRESERVE, null, _xsiLoc, 0 );

            return true;
        }

        public boolean getXsiNoLoc ( Chars chars )
        {
            if (_xsiNoLoc == null)
                return false;

            setChars( chars, PRESERVE, null, _xsiNoLoc, 0 );

            return true;
        }

        public QName getName ( )
        {
            return _name;
        }

        private void setChars (
            Chars chars, int wsr, String string, Splay sText, int pText )
        {
            assert string != null || sText != null;

            checkVersion();

            Root r = getRoot();

            chars.buffer = null;
            chars.string = null;

            if (string != null)
            {
                chars.string = string;
            }
            else if (pText == 0)
            {
                chars.buffer = r._text._buf;
                chars.length = sText.getCch();

                chars.offset =
                    r._text.unObscure(
                        r.getCp( sText ), chars.length );
            }
            else if (pText == 1 && sText.isLeaf())
            {
                chars.buffer = r._text._buf;
                chars.length = sText.getCchValue();

                chars.offset =
                    r._text.unObscure(
                        r.getCp( sText ), chars.length );
            }
            else
            {
                assert pText == sText.getPosAfter();

                boolean moreText = false;

                for ( Splay t = sText.nextNonAttrSplay() ; ;
                      t = t.nextSplay() )
                {
                    if (!t.isComment() && !t.isProcinst())
                        break;

                    if (t.getCchAfter() > 0)
                    {
                        moreText = true;
                        break;
                    }
                }

                if (!moreText)
                {
                    chars.buffer = r._text._buf;
                    chars.length = sText.getCchAfter();

                    chars.offset =
                        r._text.unObscure(
                            sText.getCpForPos( r, pText ),
                            chars.length );
                }
                else
                {
                    StringBuffer sb = new StringBuffer();

                    int cch = sText.getCchAfter();

                    int off =
                        r._text.unObscure(
                            sText.getCpForPos( r, pText ), cch );

                    sb.append( r._text._buf, off, cch );

                    for ( Splay t = sText.nextNonAttrSplay() ; ;
                          t = t.nextSplay() )
                    {
                        if (!t.isComment() && !t.isProcinst())
                            break;

                        if (t.getCchAfter() > 0)
                        {
                            cch = t.getCchAfter();

                            off =
                                r._text.unObscure(
                                    t.getCpForPos( r, 1 ), cch );

                            sb.append( r._text._buf, off, cch );
                        }
                    }

                    chars.length = sb.length();
                    chars.buffer = new char [ chars.length ];
                    chars.offset = 0;

                    sb.getChars( 0, chars.length, chars.buffer, 0 );
                }
            }

            if (wsr != PRESERVE)
            {
                // TODO - this is quick, dirty and very inefficient
                //        make it faster!

                String str = chars.asString();
                StringBuffer sb = new StringBuffer();
                int state = -1, nSpaces = 0, cch = str.length();

                for ( int i = 0 ; i < cch ; i++ )
                {
                    char ch = str.charAt( i );

                    if (ch == '\n' || ch == '\r' || ch == '\t')
                        ch = ' ';

                    if (wsr == COLLAPSE)
                    {
                        if (ch == ' ')
                        {
                            if (state == -1)
                                continue;

                            nSpaces++;

                            continue;
                        }

                        if (nSpaces > 1)
                            nSpaces = 1;

                        for ( ; nSpaces > 0 ; nSpaces-- )
                            sb.append( ' ' );

                        state = 0;
                    }

                    sb.append( ch );
                }

                chars.string = sb.toString();
                chars.buffer = null;
            }
        }

        public void getText ( Chars chars )
        {
            getText( chars, PRESERVE );
        }

        public void getText ( Chars chars, int wsr )
        {
            if (!_hasText)
                throw new RuntimeException( "No text for this event");

            setChars( chars, wsr, _eventText, _sText, _pText );
        }

        // TODO - rather expensive to make Chars and getText and get
        // String
        public boolean textIsWhitespace ( )
        {
            Chars chars = new Chars();
            getText( chars );
            String s = chars.asString();

            for ( int i = 0 ; i < s.length() ; i++ )
            {
                switch ( s.charAt( i ) )
                {
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                        break;

                    default :
                        return false;
                }
            }

            return true;
        }

        private ValidatorListener _vEventSink;
        private Splay             _startSplay;
        private boolean           _emittedText;

        private QName   _name;
        private Splay   _xsiType;
        private Splay   _xsiNil;
        private Splay   _xsiLoc;
        private Splay   _xsiNoLoc;
        private String  _eventText;
        private Splay   _sText;
        private int     _pText;
        private Splay   _sLoc;
        private int     _pLoc;
        private boolean _hasText;
    }

    //
    //
    //

    static final class SaxSaver extends Saver
    {
        SaxSaver (
            Root r, Splay s, int p, XmlOptions options,
            ContentHandler contentHandler, LexicalHandler lexicalhandler )
                throws SAXException
        {
            super( r, s, p, options );

            _attributes = new AttributesImpl();
            
            _wantFragTest = true;
            
            _contentHandler = contentHandler;
            _lexicalhandler = lexicalhandler;

//            _contentHandler.setDocumentLocator( hhmmmm  );
            
            _contentHandler.startDocument();

            try
            {
                while ( process() )
                    ;
            }
            catch ( SaverSAXException e )
            {
                throw e._saxException;
            }
            
            _contentHandler.endDocument();
        }

        private class SaverSAXException extends RuntimeException
        {
            SaverSAXException ( SAXException e )
            {
                _saxException = e;
            }
            
            SAXException _saxException;
        }

        private void throwSaxException ( SAXException e )
        {
            throw new SaverSAXException( e );
        }

        protected void emitContainer ( Container c, QName name )
        {
            if (c.isBegin())
            {
                emitContainerHelper( c, name, null, null );

                if (c.isLeaf())
                {
                    int cch = _text == null ? c.getCchValue() : _text.length();

                    if (cch > 0)
                    {
                        if (_text == null)
                            emitCharacters( c, 0, cch );
                        else
                            emitCharacters( _text );
                    }
                    
                    emitEndElement( c.getName() );
                }
            }
            else
            {
                assert c.isDoc();

                if (name != null)
                    emitContainerHelper( c, name, null, null );

                if (_text == null)
                    emitCharacters( c, 0, c.getCch() );
                else
                    emitCharacters( _text );
            }
        }

        private void emitAttrHelper ( Splay s, String value )
        {
            assert s.isNormalAttr();
            
            String local = s.getLocal();
            String uri = s.getUri();

            _attributes.addAttribute(
                s.getUri(), s.getLocal(),
                getPrefixedName( s.getName() ),
                "CDATA",
                value == null ? s.getText( getRoot() ) : value );
        }

        private void addNamespaceAttr ( String prefix, String uri )
        {
            try
            {
                _contentHandler.startPrefixMapping( prefix, uri );
            }
            catch ( SAXException e )
            {
                throwSaxException( e );
            }

            if (prefix.length() == 0)
                _attributes.addAttribute( "", "", "xmlns", "CDATA", uri );
            else
            {
                _attributes.addAttribute(
                    "", "", "xmlns:" + prefix, "CDATA", uri );
            }
        }
        
        private void emitNamespacesHelper ( )
        {
            for ( iterateMappings() ; hasMapping() ; nextMapping() )
                addNamespaceAttr( mappingPrefix(), mappingUri() );
        }

        private void emitContainerHelper (
            Container c, QName name,
            Splay extraAttr, StringBuffer extraAttrText )
        {
            assert name != null;
            
            _attributes.clear();

            if (_saveNamespacesFirst)
                emitNamespacesHelper();

            for ( Iterator i = _attrs.keySet().iterator() ; i.hasNext() ; )
            {
                Splay s = (Splay) i.next();
                emitAttrHelper( s, (String) _attrs.get( s ) );
            }

            if (extraAttr != null)
            {
                emitAttrHelper(
                    extraAttr,
                    extraAttrText == null ? null : extraAttrText.toString() );
            }

            if (!_saveNamespacesFirst)
                emitNamespacesHelper();
            
            emitElement( name, getPrefixedName( name ) );
        }

        private void emitCharacters ( char[] buf, int off, int cch )
        {
            try
            {
                _contentHandler.characters( buf, off, cch );
            }
            catch ( SAXException e )
            {
                throwSaxException( e );
            }
        }
        
        private void emitCharacters ( Splay s, int p, int cch )
        {
            emitCharacters( s.getCpForPos( getRoot(), p ), cch );
        }
        
        private void emitCharacters ( int cp, int cch )
        {
            if (cch == 0)
                return;

            emitCharacters(
                getRoot()._text._buf, getRoot()._text.unObscure( cp, cch ),
                cch );
        }
        
        private void emitCharacters ( StringBuffer sb )
        {
            if (sb.length() == 0)
                return;
            
            String text = sb.toString(); // Inefficient, use a shared char[]
            
            emitCharacters( text.toCharArray(), 0, text.length() );
        }
        
        private void emitEndElement ( QName name )
        {
            try
            {
                _contentHandler.endElement(
                    name.getNamespaceURI(), name.getLocalPart(),
                    getPrefixedName( name ) );
            }
            catch ( SAXException e )
            {
                throwSaxException( e );
            }
            
            for ( iterateMappings() ; hasMapping() ; nextMapping() )
            {
                try
                {
                    _contentHandler.endPrefixMapping( mappingPrefix() );
                }
                catch ( SAXException e )
                {
                    throwSaxException( e );
                }
            }
        }
        
        private void endNamespaces ( )
        {
            try
            {
                for ( int i = 0 ; i < _attributes.getLength() ; i ++ )
                {
                    String qn = _attributes.getQName( i );
                    
                    if (!qn.startsWith( "xmlns" ))
                        continue;

                    int j = qn.indexOf( ':' );

                    if (j >= 0)
                    {
                        _contentHandler.endPrefixMapping(
                            qn.substring( j + 1 ) );
                    }
                    else
                        _contentHandler.endPrefixMapping( "" );
                }
            }
            catch ( SAXException e )
            {
                throwSaxException( e );
            }
        }
                
        private String getPrefixedName ( QName name )
        {
            String ns = name.getNamespaceURI();
            String lp = name.getLocalPart();

            if (ns.length() == 0)
                return lp;

            String prefix = getUriMapping( ns );

            if (prefix.length() == 0)
                return lp;

            return prefix + ":" + lp;
        }

        private void emitElement ( QName name, String prefixedName )
        {
            try
            {
                _contentHandler.startElement(
                    name.getNamespaceURI(), name.getLocalPart(),
                    getPrefixedName( name ), _attributes );
            }
            catch ( SAXException e )
            {
                throwSaxException( e );
            }
        }

        protected void emitEnd ( Splay s, QName name )
        {
            if (name != null)
                emitEndElement( name );
        }

        protected void emitTextAfter ( Splay s, int p, int cch )
        {
            if (_text == null)
                emitCharacters( s, p, cch );
            else
                emitCharacters( _text );
        }

        protected void emitDocType(
            String doctypeName, String publicID, String systemID )
        {
            if (_lexicalhandler != null)
            {
                try
                {
                    _lexicalhandler.startDTD( doctypeName, publicID, systemID );
                    _lexicalhandler.endDTD();
                }
                catch ( SAXException e )
                {
                    throwSaxException( e );
                }
            }
        }
        
        protected void emitComment ( Splay s )
        {
            if (_lexicalhandler != null)
            {
                int cp = getRoot().getCp( s );
                int cch = s.getCchValue();

                try
                {
                    _lexicalhandler.comment(
                        getRoot()._text._buf,
                        getRoot()._text.unObscure( cp, cch ),
                        cch );
                }
                catch ( SAXException e )
                {
                    throwSaxException( e );
                }
            }
        }

        protected void emitProcinst ( Splay s )
        {
            try
            {
                _contentHandler.processingInstruction(
                    s.getLocal(), s.getText( getRoot() ) );
            }
            catch ( SAXException e )
            {
                throwSaxException( e );
            }
        }

        protected void emitTextFragment ( Splay s, int p, int cch )
        {
            emitContainerHelper( null, _fragment, null, null );
            
            if (_text != null)
            {
                if (_text.length() > 0)
                    emitCharacters( _text );
            }
            else if (s != null && cch > 0)
                emitCharacters( s, p, cch );

            emitEndElement( _fragment );
        }

        protected void emitXmlnsFragment ( Splay s )
        {
            emitContainerHelper( null, _fragment, null, null );
            emitEndElement( _fragment );
        }

        protected void emitAttrFragment ( Splay s )
        {
            emitContainerHelper( null, _fragment, s, _text );
            emitEndElement( _fragment );
        }

        protected void emitCommentFragment ( Splay s )
        {
            emitContainerHelper( null, _fragment, null, null );
            emitComment( s );
            emitEndElement( _fragment );
        }

        protected void emitProcinstFragment ( Splay s )
        {
            emitContainerHelper( null, _fragment, null, null );
            emitProcinst( s );
            emitEndElement( _fragment );
        }
        
        private AttributesImpl _attributes;

        private SAXException _saxException;
        
        private ContentHandler _contentHandler;
        private LexicalHandler _lexicalhandler;
    }

            
    //
    //
    //

    static final class DomSaver extends Saver
    {
        DomSaver ( Root r, Splay s, int p, boolean createDoc, XmlOptions options )
        {
            super( r, s, p, options );
            _createDoc = createDoc;
        }

        Node exportDom ( )
            throws Exception
        {
            // TODO - add an options which specifies a Document with which
            // to create the fragment

            _doc =
                DocumentBuilderFactory.newInstance().
                    newDocumentBuilder().newDocument();

            Node result;

            if (_createDoc)
            {
                result = _currentNode = _doc;
            }
            else
            {
                DocumentFragment frag = _doc.createDocumentFragment();
                result = _currentNode = frag;
            }

            while ( process() )
                ;

            return result;
        }

        protected void emitContainer ( Container c, QName name )
        {
            Root r = getRoot();

            if (c.isDoc())
            {
                if (hasMappings())
                {
                    throw new IllegalStateException(
                        "Namespace attribute not associated with an element" );
                }

                for ( Splay s = c.nextSplay() ; s.isAttr() ; s = s.nextSplay() )
                {
                    if (s.isNormalAttr())
                    {
                        throw new IllegalStateException(
                            "Attribute not associated with an element" );
                    }
                }

                String text = null;

                if (_text != null)
                {
                    if (_text.length() > 0)
                        text = text();
                }
                else if (c.getCch() > 0)
                    text = r._text.fetch( 0, c.getCch() );

                if (text != null && _currentNode != _doc)
                {
                    _currentNode.insertBefore(
                        _doc.createTextNode( text ), null );
                }
            }
            else
            {
                assert c.isBegin();

                String qname = c.getLocal();

                if (c.getUri().length() > 0)
                {
                    String prefix = getUriMapping( c.getUri() );

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

                Element e = _doc.createElementNS( c.getUri(), qname );

                _currentNode.insertBefore( e, null );

                for ( iterateMappings() ; hasMapping() ; nextMapping() )
                {
                    String prefix = mappingPrefix();

                    if (prefix.length() == 0)
                        qname = "xmlns";
                    else
                        qname = "xmlns:" + prefix;

                    e.setAttributeNS( Splay._xmlnsUri, qname, mappingUri() );
                }

                for ( Iterator i = _attrs.keySet().iterator() ; i.hasNext() ; )
                {
                    Splay s = (Splay) i.next();
                    
                    qname = s.getLocal();

                    if (s.getUri().length() > 0)
                    {
                        String prefix = getUriMapping( s.getUri() );

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

                    String invalidAttrValue = (String) _attrs.get( s );

                    e.setAttributeNS(
                        s.getUri(), qname,
                        invalidAttrValue == null
                            ? s.getText( r )
                            : invalidAttrValue );
                }

                if (c.isLeaf())
                {
                    String text = null;

                    if (_text != null)
                    {
                        if (_text.length() > 0)
                            text = text();
                    }
                    else if (c.getCchValue() > 0)
                    {
                        text =
                            r._text.fetch(
                                c.getCpForPos( r, 1 ), c.getCchValue() );
                    }

                    if (text != null && _currentNode != _doc)
                        e.insertBefore( _doc.createTextNode( text ), null );
                }
                else
                {
                    _currentNode = e;
                }
            }
        }

        protected void emitEnd ( Splay s, QName name )
        {
            _currentNode = _currentNode.getParentNode();
        }

        protected void emitTextAfter ( Splay s, int p, int cch )
        {
            assert cch > 0;

            Root r = getRoot();

            String text = null;

            if (_text != null)
            {
                if (_text.length() > 0)
                    text = text();
            }
            else if (cch > 0)
                text = r._text.fetch( s.getCpForPos( r, p ), cch );

            if (_currentNode != _doc)
                _currentNode.insertBefore( _doc.createTextNode( text ), null );
        }

        protected void emitDocType(
            String doctypeName, String publicID, String systemID )
        {
        }
                
        protected void emitComment ( Splay s )
        {
            Root r = getRoot();

            _currentNode.insertBefore(
                _doc.createComment(
                    r._text.fetch(
                        s.getCpForPos( r, 0 ), s.getCchValue() ) ), null );
        }

        protected void emitProcinst ( Splay s )
        {
            Root r = getRoot();

            _currentNode.insertBefore(
                _doc.createProcessingInstruction(
                    s.getLocal(),
                    r._text.fetch(
                        s.getCpForPos( r, 0 ), s.getCchValue() ) ), null );
        }

        protected void emitXmlnsFragment ( Splay s )
        {
            throw new IllegalStateException(
                "Cannot create a node for a namespace attribute" );
        }

        protected void emitAttrFragment ( Splay s )
        {
            throw new IllegalStateException(
                "Cannot create a node for a attribute" );
        }

        protected void emitTextFragment ( Splay s, int p, int cch )
        {
            // BUGBUG - there could be namespaces pushed for this text, but not
            // sure how to represent them here....  I should really put the
            // fragment logic in the base saver and have the base saver
            // synthesize well formed output...
            
            if (s != null)
            {
                Root r = getRoot();

                _currentNode.insertBefore(
                    _doc.createTextNode(
                    _text != null
                        ? _text.toString()
                        : s != null
                            ? r._text.fetch( s.getCpForPos( r, p ), cch )
                                : "" ),
                    null );
            }
        }

        protected void emitCommentFragment ( Splay s )
        {
            Root r = getRoot();

            _currentNode.insertBefore(
                _doc.createComment(
                    r._text.fetch(
                        s.getCpForPos( r, 0 ), s.getCchValue() ) ), null );
        }

        protected void emitProcinstFragment ( Splay s )
        {
            Root r = getRoot();

            _currentNode.insertBefore(
                _doc.createProcessingInstruction(
                    s.getLocal(),
                    r._text.fetch(
                        s.getCpForPos( r, 0 ), s.getCchValue() ) ), null );
        }

        Document _doc;
        Node     _currentNode;
        boolean  _createDoc;
    }

    //
    //
    //

    protected StringBuffer  _text;
    protected StringBuffer  _sb;
    protected boolean       _skipContainerFinish;
    protected LinkedHashMap _attrs;
    
    private HashSet _attrNames;

    private final boolean _inner;
    private final Root    _root;
    private final Splay   _top;
    private final long    _version;

    protected boolean _wantDupAttrs;
    protected boolean _wantFragTest;
    protected boolean _needsFrag;
    protected QName   _fragment;
    protected QName   _docElem;
    
    protected QName _synthElem;

    protected boolean _saveNamespacesFirst;
    protected boolean _useDefaultNamespace;

    private boolean _prettyPrint;
    private int     _prettyIndent;
    private int     _prettyOffset;

    private Splay   _splay;
    private int     _pos;
    private boolean _preProcess;
    private boolean _postProcess;
    private boolean _postPop;
    private Splay   _endSplay;

    private ArrayList _namespaceStack;
    private int       _currentMapping;
    private HashMap   _uriMap;
    private HashMap   _prefixMap;
    private boolean   _firstPush;
    private String    _initialDefaultUri;
    
    private HashMap _preComputedNamespaces;
    private String  _filterProcinst;
    private Map     _suggestedPrefixes;

    protected String  _newLine;
}
