/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans.impl.store;

import javax.xml.namespace.QName;

import org.apache.xmlbeans.SystemProperties;
import org.apache.xmlbeans.XmlDocumentProperties;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlOptionCharEscapeMap;
import org.apache.xmlbeans.xml.stream.*;

import org.apache.xmlbeans.impl.common.*;

import java.io.Writer;
import java.io.Reader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.SAXException;

import org.xml.sax.helpers.AttributesImpl;

import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.ConcurrentModificationException;

abstract class Saver {
    static final int ROOT = Cur.ROOT;
    static final int ELEM = Cur.ELEM;
    static final int ATTR = Cur.ATTR;
    static final int COMMENT = Cur.COMMENT;
    static final int PROCINST = Cur.PROCINST;
    static final int TEXT = Cur.TEXT;

    protected abstract boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues);

    protected abstract void emitFinish(SaveCur c);

    protected abstract void emitText(SaveCur c);

    protected abstract void emitComment(SaveCur c);

    protected abstract void emitProcinst(SaveCur c);

    protected abstract void emitDocType(String docTypeName, String publicId, String systemId);

    protected abstract void emitStartDoc(SaveCur c);

    protected abstract void emitEndDoc(SaveCur c);

    protected void syntheticNamespace(String prefix, String uri, boolean considerDefault) {
    }

    Saver(Cur c, XmlOptions options) {
        assert c._locale.entered();

        options = XmlOptions.maskNull(options);

        _cur = createSaveCur(c, options);

        _locale = c._locale;
        _version = _locale.version();

        _namespaceStack = new ArrayList();
        _uriMap = new HashMap();
        _prefixMap = new HashMap();

        _attrNames = new ArrayList();
        _attrValues = new ArrayList();

        // Define implicit xml prefixed namespace

        addMapping("xml", Locale._xml1998Uri);

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

        // define character map for escaped replacements
        if (options.hasOption(XmlOptions.SAVE_SUBSTITUTE_CHARACTERS)) {
            _replaceChar = (XmlOptionCharEscapeMap)
                    options.get(XmlOptions.SAVE_SUBSTITUTE_CHARACTERS);
        }

        // If the default prefix has not been mapped, do so now

        if (getNamespaceForPrefix("") == null) {
            _initialDefaultUri = new String("");
            addMapping("", _initialDefaultUri);
        }

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

            while (saver.process())
                ;

            if (!saver._synthNamespaces.isEmpty())
                _preComputedNamespaces = saver._synthNamespaces;
        }

        _useDefaultNamespace =
                options.hasOption(XmlOptions.SAVE_USE_DEFAULT_NAMESPACE);

        _saveNamespacesFirst = options.hasOption(XmlOptions.SAVE_NAMESPACES_FIRST);

        if (options.hasOption(XmlOptions.SAVE_SUGGESTED_PREFIXES))
            _suggestedPrefixes = (Map) options.get(XmlOptions.SAVE_SUGGESTED_PREFIXES);

        _ancestorNamespaces = _cur.getAncestorNamespaces();
    }

    private static SaveCur createSaveCur(Cur c, XmlOptions options) {
        QName synthName = (QName) options.get(XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT);

        QName fragName = synthName;

        if (fragName == null) {
            fragName =
                    options.hasOption(XmlOptions.SAVE_USE_OPEN_FRAGMENT)
                            ? Locale._openuriFragment
                            : Locale._xmlFragment;
        }

        boolean saveInner =
                options.hasOption(XmlOptions.SAVE_INNER) &&
                        !options.hasOption(XmlOptions.SAVE_OUTER);

        Cur start = c.tempCur();
        Cur end = c.tempCur();

        SaveCur cur = null;

        int k = c.kind();

        switch (k) {
            case ROOT: {
                positionToInner(c, start, end);

                if (Locale.isFragment(start, end))
                    cur = new FragSaveCur(start, end, fragName);
                else if (synthName != null)
                    cur = new FragSaveCur(start, end, synthName);
                else
                    cur = new DocSaveCur(c);

                break;
            }

            case ELEM: {
                if (saveInner) {
                    positionToInner(c, start, end);

                    cur =
                            new FragSaveCur(
                                    start, end, Locale.isFragment(start, end) ? fragName : synthName);
                } else if (synthName != null) {
                    positionToInner(c, start, end);

                    cur = new FragSaveCur(start, end, synthName);
                } else {
                    start.moveToCur(c);
                    end.moveToCur(c);
                    end.skip();

                    cur = new FragSaveCur(start, end, null);
                }

                break;
            }
        }

        if (cur == null) {
            assert k < 0 || k == ATTR || k == COMMENT || k == PROCINST || k == TEXT;

            if (k < 0) {
                // Save out ""
                start.moveToCur(c);
                end.moveToCur(c);
            } else if (k == TEXT) {
                start.moveToCur(c);
                end.moveToCur(c);
                end.next();
            } else if (saveInner) {
                start.moveToCur(c);
                start.next();

                end.moveToCur(c);
                end.toEnd();
            } else if (k == ATTR) {
                start.moveToCur(c);
                end.moveToCur(c);
            } else {
                assert k == COMMENT || k == PROCINST;

                start.moveToCur(c);
                end.moveToCur(c);
                end.skip();
            }

            cur = new FragSaveCur(start, end, fragName);
        }

        String filterPI = (String) options.get(XmlOptions.SAVE_FILTER_PROCINST);

        if (filterPI != null)
            cur = new FilterPiSaveCur(cur, filterPI);

        if (options.hasOption(XmlOptions.SAVE_PRETTY_PRINT))
            cur = new PrettySaveCur(cur, options);

        start.release();
        end.release();

        return cur;
    }

    private static void positionToInner(Cur c, Cur start, Cur end) {
        assert c.isContainer();

        start.moveToCur(c);

        if (!start.toFirstAttr())
            start.next();

        end.moveToCur(c);
        end.toEnd();
    }

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

    protected boolean saveNamespacesFirst() {
        return _saveNamespacesFirst;
    }

    protected void enterLocale() {
        _locale.enter();
    }

    protected void exitLocale() {
        _locale.exit();
    }

    protected final boolean process() {
        assert _locale.entered();

        if (_cur == null)
            return false;

        if (_version != _locale.version())
            throw new ConcurrentModificationException("Document changed during save");

        switch (_cur.kind()) {
            case ROOT: {
                processRoot();
                break;
            }
            case ELEM: {
                processElement();
                break;
            }
            case -ELEM: {
                processFinish();
                break;
            }
            case TEXT: {
                emitText(_cur);
                break;
            }

            case COMMENT: {
                emitComment(_cur);
                _cur.toEnd();
                break;
            }
            case PROCINST: {
                emitProcinst(_cur);
                _cur.toEnd();
                break;
            }

            case -ROOT: {
                emitEndDoc(_cur);
                _cur.release();
                _cur = null;

                return true;
            }

            default:
                throw new RuntimeException("Unexpected kind");
        }

        _cur.next();

        return true;
    }

    private final void processFinish() {
        emitFinish(_cur);
        popMappings();
    }

    private final void processRoot() {
        assert _cur.isRoot();

        XmlDocumentProperties props = _cur.getDocProps();
        String systemId = null;
        String docTypeName = null;
        if (props != null) {
            systemId = props.getDoctypeSystemId();
            docTypeName = props.getDoctypeName();
        }

        if (systemId != null || docTypeName != null) {
            if (docTypeName == null) {
                _cur.push();
                while (!_cur.isElem() && _cur.next())
                    ;
                if (_cur.isElem())
                    docTypeName = _cur.getName().getLocalPart();
                _cur.pop();
            }

            String publicId = props.getDoctypePublicId();

            if (docTypeName != null) {
                QName rootElemName = _cur.getName();

                if (rootElemName == null) {
                    _cur.push();
                    while (!_cur.isFinish()) {
                        if (_cur.isElem()) {
                            rootElemName = _cur.getName();
                            break;
                        }
                        _cur.next();
                    }
                    _cur.pop();
                }

                if (rootElemName != null && docTypeName.equals(rootElemName.getLocalPart())) {
                    emitDocType(docTypeName, publicId, systemId);
                    return;
                }
            }
        }

        emitStartDoc(_cur);
    }

    private final void processElement() {
        assert _cur.isElem() && _cur.getName() != null;

        QName name = _cur.getName();

        // 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.getNamespaceURI().length() == 0;

        pushMappings(_cur, 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)

        ensureMapping(name.getNamespaceURI(), name.getPrefix(), !ensureDefaultEmpty, false);

        //
        //
        //

        _attrNames.clear();
        _attrValues.clear();

        _cur.push();

        attrs:
        for (boolean A = _cur.toFirstAttr(); A; A = _cur.toNextAttr()) {
            if (_cur.isNormalAttr()) {
                QName attrName = _cur.getName();

                _attrNames.add(attrName);

                for (int i = _attrNames.size() - 2; i >= 0; i--) {
                    if (_attrNames.get(i).equals(attrName)) {
                        _attrNames.remove(_attrNames.size() - 1);
                        continue attrs;
                    }
                }

                _attrValues.add(_cur.getAttrValue());

                ensureMapping(attrName.getNamespaceURI(), attrName.getPrefix(), false, true);
            }
        }

        _cur.pop();

        // 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) {
            for (Iterator i = _preComputedNamespaces.keySet().iterator(); i.hasNext(); ) {
                String uri = (String) i.next();
                String prefix = (String) _preComputedNamespaces.get(uri);
                boolean considerDefault = prefix.length() == 0 && !ensureDefaultEmpty;

                ensureMapping(uri, prefix, considerDefault, false);
            }

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

        if (emitElement(_cur, _attrNames, _attrValues)) {
            popMappings();
            _cur.toEnd();
        }
    }

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

    private final void pushMappings(SaveCur c, boolean ensureDefaultEmpty) {
        assert c.isContainer();

        _namespaceStack.add(null);

        c.push();

        namespaces:
        for (boolean A = c.toFirstAttr(); A; A = c.toNextAttr())
            if (c.isXmlns())
                addNewFrameMapping(c.getXmlnsPrefix(), c.getXmlnsUri(), ensureDefaultEmpty);

        c.pop();

        if (_ancestorNamespaces != null) {
            for (int i = 0; i < _ancestorNamespaces.size(); i += 2) {
                String prefix = (String) _ancestorNamespaces.get(i);
                String uri = (String) _ancestorNamespaces.get(i + 1);

                addNewFrameMapping(prefix, uri, ensureDefaultEmpty);
            }

            _ancestorNamespaces = null;
        }

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

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

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

    private final void addNewFrameMapping(String prefix, String uri, boolean ensureDefaultEmpty) {
        // If the prefix maps to "", this don't include this mapping 'cause it's not well formed.
        // Also, if we want to make sure that the default namespace is always "", then check that
        // here as well.

        if ((prefix.length() == 0 || uri.length() > 0) &&
                (!ensureDefaultEmpty || prefix.length() > 0 || uri.length() == 0)) {
            // Make sure the prefix is not already mapped in this frame

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

            // Also make sure that the prefix declaration is not redundant
            // This has the side-effect of making it impossible to set a
            // redundant prefix declaration, but seems that it's better
            // to just never issue a duplicate prefix declaration.
            if (uri.equals(getNamespaceForPrefix(prefix)))
                return;

            addMapping(prefix, uri);
        }
    }

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

    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 String ensureMapping(
            String uri, String candidatePrefix,
            boolean considerCreatingDefault, boolean mustHavePrefix) {
        assert uri != null;

        // 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 && candidatePrefix.length() == 0)
            candidatePrefix = null;

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

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

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

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

        for (Iterator keys = _prefixMap.keySet().iterator(); keys.hasNext(); ) {
            prefix = (String) keys.next();

            if (prefix.length() > 0 && _prefixMap.get(prefix).equals(uri))
                return prefix;
        }

        assert false : "Could not find non-default mapping";

        return null;
    }

    private final boolean tryPrefix(String prefix) {
        if (prefix == null || Locale.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;
    }

    public final String getNamespaceForPrefix(String prefix) {
        assert !prefix.equals("xml") || _prefixMap.get(prefix).equals(Locale._xml1998Uri);

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

    protected Map getPrefixMap() {
        return _prefixMap;
    }

    //
    //
    //

    static final class SynthNamespaceSaver extends Saver {
        LinkedHashMap _synthNamespaces = new LinkedHashMap();

        SynthNamespaceSaver(Cur c, XmlOptions options) {
            super(c, options);
        }

        protected void syntheticNamespace(
                String prefix, String uri, boolean considerCreatingDefault) {
            _synthNamespaces.put(uri, considerCreatingDefault ? "" : prefix);
        }

        protected boolean emitElement(
                SaveCur c, ArrayList attrNames, ArrayList attrValues) {
            return false;
        }

        protected void emitFinish(SaveCur c) {
        }

        protected void emitText(SaveCur c) {
        }

        protected void emitComment(SaveCur c) {
        }

        protected void emitProcinst(SaveCur c) {
        }

        protected void emitDocType(String docTypeName, String publicId, String systemId) {
        }

        protected void emitStartDoc(SaveCur c) {
        }

        protected void emitEndDoc(SaveCur c) {
        }
    }

    //
    //
    //

    static final class TextSaver extends Saver {
        TextSaver(Cur c, XmlOptions options, String encoding) {
            super(c, options);

            boolean noSaveDecl =
                    options != null && options.hasOption(XmlOptions.SAVE_NO_XML_DECL);

            if (options != null && options.hasOption(XmlOptions.SAVE_CDATA_LENGTH_THRESHOLD))
                _cdataLengthThreshold = ((Integer) options.get(XmlOptions.SAVE_CDATA_LENGTH_THRESHOLD)).intValue();

            if (options != null && options.hasOption(XmlOptions.SAVE_CDATA_ENTITY_COUNT_THRESHOLD))
                _cdataEntityCountThreshold = ((Integer) options.get(XmlOptions.SAVE_CDATA_ENTITY_COUNT_THRESHOLD)).intValue();

            if (options != null && options.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS))
                _useCDataBookmarks = true;

            if (options != null && options.hasOption(XmlOptions.SAVE_PRETTY_PRINT))
                _isPrettyPrint = true;

            _in = _out = 0;
            _free = 0;

            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

            if (encoding != null && !noSaveDecl) {
                XmlDocumentProperties props = Locale.getDocProps(c, false);

                String version = props == null ? null : props.getVersion();

                if (version == null)
                    version = "1.0";

                Boolean standalone = null;
                if (props != null && props.get(XmlDocumentProperties.STANDALONE) != null)
                    standalone = props.getStandalone();

                emit("<?xml version=\"");
                emit(version);
                emit( "\" encoding=\"" + encoding + "\"");
                if (standalone != null)
                    emit( " standalone=\"" + (standalone.booleanValue() ? "yes" : "no") + "\"");
                emit( "?>" + _newLine );
            }
        }

        protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
            assert c.isElem();

            emit('<');
            emitName(c.getName(), false);

            if (saveNamespacesFirst())
                emitNamespacesHelper();

            for (int i = 0; i < attrNames.size(); i++)
                emitAttrHelper((QName) attrNames.get(i), (String) attrValues.get(i));

            if (!saveNamespacesFirst())
                emitNamespacesHelper();

            if (!c.hasChildren() && !c.hasText()) {
                emit('/', '>');
                return true;
            } else {
                emit('>');
                return false;
            }
        }

        protected void emitFinish(SaveCur c) {
            emit('<', '/');
            emitName(c.getName(), false);
            emit('>');
        }

        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(false);

            emit('"');
        }

        private void emitNamespacesHelper() {
            for (iterateMappings(); hasMapping(); nextMapping()) {
                emit(' ');
                emitXmlns(mappingPrefix(), mappingUri());
            }
        }

        private void emitAttrHelper(QName attrName, String attrValue) {
            emit(' ');
            emitName(attrName, true);
            emit('=', '\"');
            emit(attrValue);
            entitizeAttrValue(true);
            emit('"');
        }

        protected void emitText(SaveCur c) {
            assert c.isText();

            // c.isTextCData() is expensive do it only if useCDataBookmarks option is enabled
            boolean forceCData = _useCDataBookmarks && c.isTextCData();

            emit(c);

            entitizeContent(forceCData);
        }

        protected void emitComment(SaveCur c) {
            assert c.isComment();

            emit("<!--");

            c.push();
            c.next();

            emit(c);

            c.pop();

            entitizeComment();
            emit("-->");
        }

        protected void emitProcinst(SaveCur c) {
            assert c.isProcinst();

            emit("<?");

            // TODO - encoding issues here?
            emit(c.getName().getLocalPart());

            c.push();

            c.next();

            if (c.isText()) {
                emit(" ");
                emit(c);
                entitizeProcinst();
            }

            c.pop();

            emit("?>");
        }

        private void emitLiteral(String literal) {
            // TODO: systemId production http://www.w3.org/TR/REC-xml/#NT-SystemLiteral
            // TODO: publicId production http://www.w3.org/TR/REC-xml/#NT-PubidLiteral
            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(">");
            emit(_newLine);
        }

        protected void emitStartDoc(SaveCur c) {
        }

        protected void emitEndDoc(SaveCur c) {
        }

        //
        //
        //

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

            String uri = name.getNamespaceURI();

            assert uri != null;

            if (uri.length() != 0) {
                String prefix = name.getPrefix();
                String mappedUri = getNamespaceForPrefix(prefix);

                if (mappedUri == null || !mappedUri.equals(uri))
                    prefix = getUriMapping(uri);

                // Attrs need a prefix.  If I have not found one, then there must be a default
                // prefix obscuring the prefix needed for this attr.  Find it manually.

                // NOTE - Consider keeping the currently mapped default URI separate fromn the
                // _urpMap and _prefixMap.  This way, I would not have to look it up manually
                // here

                if (needsPrefix && prefix.length() == 0)
                    prefix = getNonDefaultUriMapping(uri);

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

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

            emit(name.getLocalPart());
        }

        private void emit(char ch) {
            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

            preEmit(1);

            _buf[_in] = ch;

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

            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
        }

        private void emit(char ch1, char ch2) {
            if (preEmit(2))
                return;

            _buf[_in] = ch1;
            _in = (_in + 1) % _buf.length;

            _buf[_in] = ch2;
            _in = (_in + 1) % _buf.length;

            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
        }

        private void emit(String s) {
            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

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

            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
        }

        private void emit(SaveCur c) {
            if (c.isText()) {
                Object src = c.getChars();
                int cch = c._cchSrc;

                if (preEmit(cch))
                    return;

                int chunk;

                if (_in <= _out || cch < (chunk = _buf.length - _in)) {
                    CharUtil.getChars(_buf, _in, src, c._offSrc, cch);
                    _in += cch;
                } else {
                    CharUtil.getChars(_buf, _in, src, c._offSrc, chunk);
                    CharUtil.getChars(_buf, 0, src, c._offSrc + chunk, cch - chunk);
                    _in = (_in + cch) % _buf.length;
                }
            } else
                preEmit(0);
        }

        private boolean preEmit(int cch) {
            assert cch >= 0;
            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

            _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;
            assert _buf == null || _free == (_in >= _out ? _buf.length - (_in - _out) : _out - _in) - cch : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out) - cch) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in - cch) ||                  // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length - cch) ||                 // no data, all buffer free
                    (_out == _in && _free == 0)                                    // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

            return false;
        }

        private void entitizeContent(boolean forceCData) {
            assert _free >= 0;

            if (_lastEmitCch == 0)
                return;

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

            boolean hasCharToBeReplaced = false;

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

                if (ch == '<' || ch == '&')
                    count++;
                else if (prevPrevChar == ']' && prevChar == ']' && ch == '>')
                    hasCharToBeReplaced = true;
                else if (isBadChar(ch) || isEscapedChar(ch) || (!_isPrettyPrint && ch == '\r'))
                    hasCharToBeReplaced = true;

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

                prevPrevChar = prevChar;
                prevChar = ch;
            }

            if (!forceCData && count == 0 && !hasCharToBeReplaced && count < _cdataEntityCountThreshold)
                return;

            i = _lastEmitIn;

            //
            // Heuristic for knowing when to save out stuff as a CDATA.
            //
            if (forceCData || (_lastEmitCch > _cdataLengthThreshold && count > _cdataEntityCountThreshold)) {
                boolean lastWasBracket = _buf[i] == ']';

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

                boolean secondToLastWasBracket = lastWasBracket;

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

                if (++i == _buf.length)
                    i = 0;

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

                    if (ch == '>' && secondToLastWasBracket && lastWasBracket)
                        i = replace(i, "]]>><![CDATA[");
                    else if (isBadChar(ch))
                        i = replace(i, "?");
                    else
                        i++;

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

                    if (i == _buf.length)
                        i = 0;
                }

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

                    if (ch == '<')
                        i = replace(i, "&lt;");
                    else if (ch == '&')
                        i = replace(i, "&amp;");
                    else if (ch == '>' && ch_1 == ']' && ch_2 == ']')
                        i = replace(i, "&gt;");
                    else if (isBadChar(ch))
                        i = replace(i, "?");
                    else if (!_isPrettyPrint && ch == '\r')
                        i = replace(i, "&#13;");
                    else if (isEscapedChar(ch))
                        i = replace(i, _replaceChar.getEscapedString(ch));
                    else
                        i++;

                    if (i == _buf.length)
                        i = 0;
                }
            }
        }

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

            int i = _lastEmitIn;

            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 if (isEscapedChar(ch)) {
                    if (replaceEscapedChar)
                        i = replace(i, _replaceChar.getEscapedString(ch));
                } else
                    i++;

                if (i == _buf.length)
                    i = 0;
            }
        }

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

            int i = _lastEmitIn;

            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 == _buf.length)
                    i = 0;
            }

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

            int offset = (_lastEmitIn + _lastEmitCch - 1) % _buf.length;
            if (_buf[offset] == '-')
                i = replace(offset, " ");
        }

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

            int i = _lastEmitIn;

            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 == _buf.length)
                    i = 0;
            }
        }

        /**
         * Test if a character is to be replaced with an escaped value
         */
        private boolean isEscapedChar(char ch) {
            return (null != _replaceChar && _replaceChar.containsChar(ch));
        }

        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;

            int charsToCopy = dCch + 1;

            if (_out > _in && i >= _out) {
                System.arraycopy(_buf, _out, _buf, _out - dCch, i - _out);
                _out -= dCch;
                i -= dCch;
            } else {
                assert i < _in;
                int availableEndChunk = _buf.length - _in;
                if (dCch <= availableEndChunk) {
                    System.arraycopy(_buf, i, _buf, i + dCch, _in - i);
                    _in = (_in + dCch) % _buf.length;
                } else if (dCch <= availableEndChunk + _in - i - 1) {
                    int numToCopyToStart = dCch - availableEndChunk;
                    System.arraycopy(_buf, _in - numToCopyToStart, _buf, 0, numToCopyToStart);
                    System.arraycopy(_buf, i + 1, _buf, i + 1 + dCch, _in - i - 1 - numToCopyToStart);

                    _in = numToCopyToStart;
                } else {
                    int numToCopyToStart = _in - i - 1;
                    charsToCopy = availableEndChunk + _in - i;

                    System.arraycopy(_buf, _in - numToCopyToStart, _buf, dCch - charsToCopy + 1, numToCopyToStart);
                    replacement.getChars(charsToCopy, dCch + 1, _buf, 0);

                    _in = numToCopyToStart + dCch - charsToCopy + 1;
                }
            }

            replacement.getChars(0, charsToCopy, _buf, i);

            _free -= dCch;

            assert _free >= 0;
            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

            return (i + dCch + 1) % _buf.length;
        }
        //
        //
        //

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

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

        private int resize(int cch, int i) {
            assert _free >= 0;
            assert cch > 0;
            assert cch >= _free;
            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _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;
            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

            return i;
        }

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

            assert getAvailable() > 0;

            int ch = _buf[_out];

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

            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _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 _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

            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;
                assert _in >= _out : "_in:" + _in + " < _out:" + _out;
                assert _free == _buf.length - _in;

                try {
//System.out.println("-------------\nWriting in corverter: TextSaver.write():1703  " + charsAvailable + " chars\n" + new String(_buf, 0, charsAvailable));
                    writer.write(_buf, 0, charsAvailable);
                    writer.flush();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

                _free += charsAvailable;

                assert _free >= 0;

                _in = 0;
            }
            assert _buf == null ||
                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
                    (_out == _in && _free == 0)                               // buffer full
                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;

            return charsAvailable;
        }

        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 _cdataLengthThreshold = 32;
        private int _cdataEntityCountThreshold = 5;
        private boolean _useCDataBookmarks = false;
        private boolean _isPrettyPrint = false;

        private int _lastEmitIn;
        private int _lastEmitCch;

        private int _free;
        private int _in;
        private int _out;
        private char[] _buf;
        /*
        _buf is a circular buffer, useful data is before _in up to _out, there are 2 posible configurations:
        1: _in<=_out  |data|_in  empty  _out|data|
        2: _out<_in   |empty _out|data|_in  empty|
        _free is used to keep around the remaining empty space in the bufer so  assert _buf==null || _free == (_in>=_out ? _buf.length - (_in - _out) : _out - _in ) ;
         */
    }

    static final class OptimizedForSpeedSaver
            extends Saver {
        Writer _w;
        private char[] _buf = new char[1024];


        static private class SaverIOException
                extends RuntimeException {
            SaverIOException(IOException e) {
                super(e);
            }
        }


        OptimizedForSpeedSaver(Cur cur, Writer writer) {
            super(cur, XmlOptions.maskNull(null));
            _w = writer;
        }

        static void save(Cur cur, Writer writer)
                throws IOException {
            try {
                Saver saver = new OptimizedForSpeedSaver(cur, writer);
                while (saver.process()) {
                }
            } catch (SaverIOException e) {
                throw (IOException) e.getCause();
            }
        }

        private void emit(String s) {
            try {
                _w.write(s);
            } catch (IOException e) {
                throw new SaverIOException(e);
            }
        }

        private void emit(char c) {
            try {
                _buf[0] = c;
                _w.write(_buf, 0, 1);
            } catch (IOException e) {
                throw new SaverIOException(e);
            }
        }

        private void emit(char c1, char c2) {
            try {
                _buf[0] = c1;
                _buf[1] = c2;
                _w.write(_buf, 0, 2);
            } catch (IOException e) {
                throw new SaverIOException(e);
            }
        }

        private void emit(char[] buf, int start, int len) {
            try {
                _w.write(buf, start, len);
            } catch (IOException e) {
                throw new SaverIOException(e);
            }
        }

        protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
            assert c.isElem();

            emit('<');
            emitName(c.getName(), false);

            for (int i = 0; i < attrNames.size(); i++)
                emitAttrHelper((QName) attrNames.get(i), (String) attrValues.get(i));

            if (!saveNamespacesFirst())
                emitNamespacesHelper();

            if (!c.hasChildren() && !c.hasText()) {
                emit('/', '>');
                return true;
            } else {
                emit('>');
                return false;
            }
        }

        protected void emitFinish(SaveCur c) {
            emit('<', '/');
            emitName(c.getName(), false);
            emit('>');
        }

        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
            emitAttrValue(uri);

            emit('"');
        }

        private void emitNamespacesHelper() {
            for (iterateMappings(); hasMapping(); nextMapping()) {
                emit(' ');
                emitXmlns(mappingPrefix(), mappingUri());
            }
        }

        private void emitAttrHelper(QName attrName, String attrValue) {
            emit(' ');
            emitName(attrName, true);
            emit('=', '\"');
            emitAttrValue(attrValue);

            emit('"');
        }

        protected void emitComment(SaveCur c) {
            assert c.isComment();

            emit("<!--");

            c.push();
            c.next();

            emitCommentText(c);

            c.pop();

            emit("-->");
        }

        protected void emitProcinst(SaveCur c) {
            assert c.isProcinst();

            emit("<?");

            // TODO - encoding issues here?
            emit(c.getName().getLocalPart());

            c.push();

            c.next();

            if (c.isText()) {
                emit(' ');
                emitPiText(c);
            }

            c.pop();

            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('>');
            emit(_newLine);
        }

        protected void emitStartDoc(SaveCur c) {
        }

        protected void emitEndDoc(SaveCur c) {
        }

        //
        //
        //

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

            String uri = name.getNamespaceURI();

            assert uri != null;

            if (uri.length() != 0) {
                String prefix = name.getPrefix();
                String mappedUri = getNamespaceForPrefix(prefix);

                if (mappedUri == null || !mappedUri.equals(uri))
                    prefix = getUriMapping(uri);

                // Attrs need a prefix.  If I have not found one, then there must be a default
                // prefix obscuring the prefix needed for this attr.  Find it manually.

                // NOTE - Consider keeping the currently mapped default URI separate fromn the
                // _urpMap and _prefixMap.  This way, I would not have to look it up manually
                // here

                if (needsPrefix && prefix.length() == 0)
                    prefix = getNonDefaultUriMapping(uri);

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

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

            emit(name.getLocalPart());
        }

        private void emitAttrValue(CharSequence attVal) {
            int len = attVal.length();

            for (int i = 0; i < len; i++) {
                char ch = attVal.charAt(i);

                if (ch == '<')
                    emit("&lt;");
                else if (ch == '&')
                    emit("&amp;");
                else if (ch == '"')
                    emit("&quot;");
                else
                    emit(ch);
            }
        }

        private void emitLiteral(String literal) {
            // TODO: systemId production http://www.w3.org/TR/REC-xml/#NT-SystemLiteral
            // TODO: publicId production http://www.w3.org/TR/REC-xml/#NT-PubidLiteral
            if (literal.indexOf("\"") < 0) {
                emit('\"');
                emit(literal);
                emit('\"');
            } else {
                emit('\'');
                emit(literal);
                emit('\'');
            }
        }

        protected void emitText(SaveCur c) {
            assert c.isText();

            Object src = c.getChars();
            int cch = c._cchSrc;
            int off = c._offSrc;
            int index = 0;
            int indexLimit = 0;
            while (index < cch) {
                indexLimit = index + 512 > cch ? cch : index + 512;
                CharUtil.getChars(_buf, 0, src, off + index, indexLimit - index);
                entitizeAndWriteText(indexLimit - index);
                index = indexLimit;
            }
        }

        protected void emitPiText(SaveCur c) {
            assert c.isText();

            Object src = c.getChars();
            int cch = c._cchSrc;
            int off = c._offSrc;
            int index = 0;
            int indexLimit = 0;
            while (index < cch) {
                indexLimit = index + 512 > cch ? cch : 512;
                CharUtil.getChars(_buf, 0, src, off + index, indexLimit);
                entitizeAndWritePIText(indexLimit - index);
                index = indexLimit;
            }
        }

        protected void emitCommentText(SaveCur c) {
            assert c.isText();

            Object src = c.getChars();
            int cch = c._cchSrc;
            int off = c._offSrc;
            int index = 0;
            int indexLimit = 0;
            while (index < cch) {
                indexLimit = index + 512 > cch ? cch : 512;
                CharUtil.getChars(_buf, 0, src, off + index, indexLimit);
                entitizeAndWriteCommentText(indexLimit - index);
                index = indexLimit;
            }
        }

        private void entitizeAndWriteText(int bufLimit) {
            int index = 0;
            for (int i = 0; i < bufLimit; i++) {
                char c = _buf[i];
                switch (c) {
                    case '<':
                        emit(_buf, index, i - index);
                        emit("&lt;");
                        index = i + 1;
                        break;
                    case '&':
                        emit(_buf, index, i - index);
                        emit("&amp;");
                        index = i + 1;
                        break;
                }
            }
            emit(_buf, index, bufLimit - index);
        }

        private void entitizeAndWriteCommentText(int bufLimit) {
            boolean lastWasDash = false;

            for (int i = 0; i < bufLimit; i++) {
                char ch = _buf[i];

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

                if (i == _buf.length)
                    i = 0;
            }

            if (_buf[bufLimit - 1] == '-')
                _buf[bufLimit - 1] = ' ';

            emit(_buf, 0, bufLimit);
        }

        private void entitizeAndWritePIText(int bufLimit) {
            boolean lastWasQuestion = false;

            for (int i = 0; i < bufLimit; i++) {
                char ch = _buf[i];

                if (isBadChar(ch)) {
                    _buf[i] = '?';
                    ch = '?';
                }

                if (ch == '>') {
                    // Had to convert to a space here ... imples not well formed XML
                    if (lastWasQuestion)
                        _buf[i] = ' ';

                    lastWasQuestion = false;
                } else {
                    lastWasQuestion = ch == '?';
                }
            }
            emit(_buf, 0, bufLimit);
        }
    }

    static final class TextReader extends Reader {
        TextReader(Cur c, XmlOptions options) {
            _textSaver = new TextSaver(c, options, null);
            _locale = c._locale;
            _closed = false;
        }

        public void close() throws IOException {
            _closed = true;
        }

        public boolean ready() throws IOException {
            return !_closed;
        }

        public int read() throws IOException {
            checkClosed();

            if (_locale.noSync()) {
                _locale.enter();
                try {
                    return _textSaver.read();
                } finally {
                    _locale.exit();
                }
            } else synchronized (_locale) {
                _locale.enter();
                try {
                    return _textSaver.read();
                } finally {
                    _locale.exit();
                }
            }
        }

        public int read(char[] cbuf) throws IOException {
            checkClosed();

            if (_locale.noSync()) {
                _locale.enter();
                try {
                    return _textSaver.read(cbuf, 0, cbuf == null ? 0 : cbuf.length);
                } finally {
                    _locale.exit();
                }
            } else synchronized (_locale) {
                _locale.enter();
                try {
                    return _textSaver.read(cbuf, 0, cbuf == null ? 0 : cbuf.length);
                } finally {
                    _locale.exit();
                }
            }
        }

        public int read(char[] cbuf, int off, int len) throws IOException {
            checkClosed();

            if (_locale.noSync()) {
                _locale.enter();
                try {
                    return _textSaver.read(cbuf, off, len);
                } finally {
                    _locale.exit();
                }
            } else synchronized (_locale) {
                _locale.enter();
                try {
                    return _textSaver.read(cbuf, off, len);
                } finally {
                    _locale.exit();
                }
            }
        }

        private void checkClosed() throws IOException {
            if (_closed)
                throw new IOException("Reader has been closed");
        }

        private Locale _locale;
        private TextSaver _textSaver;
        private boolean _closed;
    }

    static final class InputStreamSaver extends InputStream {
        InputStreamSaver(Cur c, XmlOptions options) {
            _locale = c._locale;

            _closed = false;

            assert _locale.entered();

            options = XmlOptions.maskNull(options);

            _outStreamImpl = new OutputStreamImpl();

            String encoding = null;

            XmlDocumentProperties props = Locale.getDocProps(c, false);

            if (props != null && props.getEncoding() != null)
                encoding = EncodingMap.getIANA2JavaMapping(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(_outStreamImpl, javaEncoding);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }

            _textSaver = new TextSaver(c, options, encoding);
        }

        public void close() throws IOException {
            _closed = true;
        }

        private void checkClosed() throws IOException {
            if (_closed)
                throw new IOException("Stream closed");
        }

        // Having the gateway here is kinda slow for the single character case.  It may be possible
        // to only enter the gate when there are no chars in the buffer.

        public int read() throws IOException {
            checkClosed();

            if (_locale.noSync()) {
                _locale.enter();
                try {
                    return _outStreamImpl.read();
                } finally {
                    _locale.exit();
                }
            } else synchronized (_locale) {
                _locale.enter();
                try {
                    return _outStreamImpl.read();
                } finally {
                    _locale.exit();
                }
            }
        }

        public int read(byte[] bbuf, int off, int len) throws IOException {
            checkClosed();

            if (bbuf == null)
                throw new NullPointerException("buf to read into is null");

            if (off < 0 || off > bbuf.length)
                throw new IndexOutOfBoundsException("Offset is not within buf");

            if (_locale.noSync()) {
                _locale.enter();
                try {
                    return _outStreamImpl.read(bbuf, off, len);
                } finally {
                    _locale.exit();
                }
            } else synchronized (_locale) {
                _locale.enter();
                try {
                    return _outStreamImpl.read(bbuf, off, len);
                } finally {
                    _locale.exit();
                }
            }
        }

        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 = _outStreamImpl.getAvailable();

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

            bytesAvailable = _outStreamImpl.getAvailable();

//            if (bytesAvailable == 0)
//                return 0;

            return bytesAvailable;
        }

        public int available()
                throws IOException {
            if (_locale.noSync()) {
                _locale.enter();
                try {
                    return ensure(1024);
                } finally {
                    _locale.exit();
                }
            } else
                synchronized (_locale) {
                    _locale.enter();
                    try {
                        return ensure(1024);
                    } finally {
                        _locale.exit();
                    }
                }
        }

        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;

//System.out.println("------------------------\nRead out of queue: Saver:2440 InputStreamSaver.read() bbuf   " + len + " bytes :\n" + new String(bbuf, off, 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;
//System.out.println("---------\nAfter converter, write in queue: OutputStreamImpl.write():Saver:2469  " + cbyte + " bytes \n" + new String(buf, off, cbyte));
                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 = _buf.length - _in;

                if (_in <= _out || cbyte < chunk) {
                    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 : 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 (_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 == _out;
                }

                _buf = newBuf;
            }

            private static final int _initialBufSize = 4096;

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

        private Locale _locale;
        private boolean _closed;
        private OutputStreamImpl _outStreamImpl;
        private TextSaver _textSaver;
        private OutputStreamWriter _converter;
    }

    static final class XmlInputStreamSaver extends Saver {
        XmlInputStreamSaver(Cur c, XmlOptions options) {
            super(c, options);
        }

        protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
            assert c.isElem();

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

            StartElementImpl.AttributeImpl lastAttr = null;
            StartElementImpl.AttributeImpl attributes = null;
            StartElementImpl.AttributeImpl namespaces = null;

            for (int i = 0; i < attrNames.size(); i++) {
                XMLName attXMLName = computeName((QName) attrNames.get(i), this, true);
                StartElementImpl.AttributeImpl attr =
                        new StartElementImpl.NormalAttributeImpl(attXMLName, (String) attrValues.get(i));

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

                lastAttr = attr;
            }

            lastAttr = null;

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

                StartElementImpl.AttributeImpl attr =
                        new StartElementImpl.XmlnsAttributeImpl(prefix, uri);

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

                lastAttr = attr;
            }


            QName name = c.getName();
            enqueue(new StartElementImpl(computeName(name, this, false), attributes, namespaces, getPrefixMap()));

            return false;  // still need to be called on end element
        }

        protected void emitFinish(SaveCur c) {
            if (c.isRoot())
                enqueue(new EndDocumentImpl());
            else {
                XMLName xmlName = computeName(c.getName(), this, false);
                enqueue(new EndElementImpl(xmlName));
            }

            emitEndPrefixMappings();
        }

        protected void emitText(SaveCur c) {
            assert c.isText();
            Object src = c.getChars();
            int cch = c._cchSrc;
            int off = c._offSrc;

            enqueue(new CharacterDataImpl(src, cch, off));
        }

        protected void emitComment(SaveCur c) {
            enqueue(new CommentImpl(c.getChars(), c._cchSrc, c._offSrc));
        }

        protected void emitProcinst(SaveCur c) {
            String target = null;
            QName name = c.getName();

            if (name != null)
                target = name.getLocalPart();

            enqueue(new ProcessingInstructionImpl(target, c.getChars(), c._cchSrc, c._offSrc));
        }

        protected void emitDocType(String doctypeName, String publicID, String systemID) {
            enqueue(new StartDocumentImpl(systemID, null, true, null)); //todo
        }

        protected void emitStartDoc(SaveCur c) {
            emitDocType(null, null, null);
        }

        protected void emitEndDoc(SaveCur c) {
            enqueue(new EndDocumentImpl());
        }

        XMLEvent dequeue() {
            if (_out == null) {
                enterLocale();
                try {
                    if (!process())
                        return null;
                } finally {
                    exitLocale();
                }
            }

            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 emitEndPrefixMappings() {
            for (iterateMappings(); hasMapping(); nextMapping()) {
                String prevPrefixUri = null; // todo mappingPrevPrefixUri();
                String prefix = mappingPrefix();
                String uri = mappingUri();

                if (prevPrefixUri == null)
                    enqueue(new EndPrefixMappingImpl(prefix));
                else {
                    enqueue(new ChangePrefixMappingImpl(prefix, uri, prevPrefixUri));
                }
            }
        }

        //
        //
        //

        private static XMLName computeName(QName name, Saver saver, boolean needsPrefix) {
            String uri = name.getNamespaceURI();
            String local = name.getLocalPart();

            assert uri != null;
            assert local.length() > 0;

            String prefix = null;

            if (uri != null && uri.length() != 0) {
                prefix = name.getPrefix();
                String mappedUri = saver.getNamespaceForPrefix(prefix);

                if (mappedUri == null || !mappedUri.equals(uri))
                    prefix = saver.getUriMapping(uri);

                // Attrs need a prefix.  If I have not found one, then there must be a default
                // prefix obscuring the prefix needed for this attr.  Find it manually.

                // NOTE - Consider keeping the currently mapped default URI separate fromn the
                // _urpMap and _prefixMap.  This way, I would not have to look it up manually
                // here

                if (needsPrefix && prefix.length() == 0)
                    prefix = saver.getNonDefaultUriMapping(uri);

            }

            return new XmlNameImpl(uri, local, prefix);
        }

        private static abstract class XmlEventImpl extends XmlEventBase {
            XmlEventImpl(int type) {
                super(type);
            }

            public XMLName getName() {
                return null;
            }

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

            public boolean hasName() {
                return false;
            }

            public final Location getLocation() {
                // (orig v1 comment)TODO - perhaps I can save a location goober sometimes?
                return null;
            }

            XmlEventImpl _next;
        }

        private static class StartDocumentImpl
                extends XmlEventImpl implements StartDocument {
            StartDocumentImpl(String systemID, String encoding, boolean isStandAlone, String version) {
                super(XMLEvent.START_DOCUMENT);
                _systemID = systemID;
                _encoding = encoding;
                _standAlone = isStandAlone;
                _version = version;
            }

            public String getSystemId() {
                return _systemID;
            }

            public String getCharacterEncodingScheme() {
                return _encoding;
            }

            public boolean isStandalone() {
                return _standAlone;
            }

            public String getVersion() {
                return _version;
            }

            String _systemID;
            String _encoding;
            boolean _standAlone;
            String _version;
        }

        private static class StartElementImpl
                extends XmlEventImpl implements StartElement {
            StartElementImpl(XMLName name, AttributeImpl attributes, AttributeImpl namespaces, Map prefixMap) {
                super(XMLEvent.START_ELEMENT);

                _name = name;
                _attributes = attributes;
                _namespaces = namespaces;
                _prefixMap = prefixMap;
            }

            public boolean hasName() {
                return true;
            }

            public XMLName getName() {
                return _name;
            }

            public AttributeIterator getAttributes() {
                return new AttributeIteratorImpl(_attributes, null);
            }

            public AttributeIterator getNamespaces() {
                return new AttributeIteratorImpl(null, _namespaces);
            }

            public AttributeIterator getAttributesAndNamespaces() {
                return new AttributeIteratorImpl(_attributes, _namespaces);
            }

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

                return null;
            }

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

            public Map getNamespaceMap() {
                return _prefixMap;
            }

            private static class AttributeIteratorImpl
                    implements AttributeIterator {
                AttributeIteratorImpl(AttributeImpl attributes, AttributeImpl namespaces) {
                    _attributes = attributes;
                    _namespaces = namespaces;
                }

                public Object monitor() {
                    return this;
                }

                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 long          _version;
                private AttributeImpl _attributes;
                private AttributeImpl _namespaces;
            }

            private static abstract class AttributeImpl implements Attribute {
                /**
                 * Don't forget to set _name
                 */
                AttributeImpl() {
                }

                public XMLName getName() {
                    return _name;
                }

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

                public XMLName getSchemaType() {
                    // (from v1 impl) TODO - Can I return something reasonable here?
                    return null;
                }

                AttributeImpl _next;

                protected XMLName _name;
            }

            private static class XmlnsAttributeImpl extends AttributeImpl {
                XmlnsAttributeImpl(String prefix, String uri) {
                    super();
                    _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() {
                    return _uri;
                }

                private String _uri;
            }

            private static class NormalAttributeImpl extends AttributeImpl {
                NormalAttributeImpl(XMLName name, String value) {
                    _name = name;
                    _value = value;
                }

                public String getValue() {
                    return _value;
                }

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

            private XMLName _name;
            private Map _prefixMap;

            private AttributeImpl _attributes;
            private AttributeImpl _namespaces;
        }

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

                _prefix = prefix;
                _uri = uri;
            }

            public String getNamespaceUri() {
                return _uri;
            }

            public String getPrefix() {
                return _prefix;
            }

            private String _prefix, _uri;
        }

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

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

            public String getOldNamespaceUri() {
                return _oldUri;
            }

            public String getNewNamespaceUri() {
                return _newUri;
            }

            public String getPrefix() {
                return _prefix;
            }

            private String _oldUri, _newUri, _prefix;
        }

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

            public String getPrefix() {
                return _prefix;
            }

            private String _prefix;
        }

        private static class EndElementImpl
                extends XmlEventImpl implements EndElement {
            EndElementImpl(XMLName name) {
                super(XMLEvent.END_ELEMENT);

                _name = name;
            }

            public boolean hasName() {
                return true;
            }

            public XMLName getName() {
                return _name;
            }

            private XMLName _name;
        }

        private static class EndDocumentImpl
                extends XmlEventImpl implements EndDocument {
            EndDocumentImpl() {
                super(XMLEvent.END_DOCUMENT);
            }
        }

        private static class TripletEventImpl
                extends XmlEventImpl implements CharacterData {
            TripletEventImpl(int eventType, Object obj, int cch, int off) {
                super(eventType);
                _obj = obj;
                _cch = cch;
                _off = off;
            }

            public String getContent() {
                return CharUtil.getString(_obj, _off, _cch);
            }

            public boolean hasContent() {
                return _cch > 0;
            }

            private Object _obj;
            private int _cch;
            private int _off;
        }

        private static class CharacterDataImpl
                extends TripletEventImpl implements CharacterData {
            CharacterDataImpl(Object obj, int cch, int off) {
                super(XMLEvent.CHARACTER_DATA, obj, cch, off);
            }
        }

        private static class CommentImpl
                extends TripletEventImpl implements Comment {
            CommentImpl(Object obj, int cch, int off) {
                super(XMLEvent.COMMENT, obj, cch, off);
            }
        }

        private static class ProcessingInstructionImpl
                extends TripletEventImpl implements ProcessingInstruction {
            ProcessingInstructionImpl(String target, Object obj, int cch, int off) {
                super(XMLEvent.PROCESSING_INSTRUCTION, obj, cch, off);
                _target = target;
            }

            public String getTarget() {
                return _target;
            }

            public String getData() {
                return getContent();
            }

            private String _target;
        }

        private XmlEventImpl _in, _out;
    }

    static final class XmlInputStreamImpl extends GenericXmlInputStream {
        XmlInputStreamImpl(Cur cur, XmlOptions options) {
            _xmlInputStreamSaver =
                    new XmlInputStreamSaver(cur, 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 SaxSaver extends Saver {
        SaxSaver(Cur c, XmlOptions options, ContentHandler ch, LexicalHandler lh)
                throws SAXException {
            super(c, options);

            _contentHandler = ch;
            _lexicalHandler = lh;

            _attributes = new AttributesImpl();
            _nsAsAttrs = !options.hasOption(XmlOptions.SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES);

            _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 String getPrefixedName(QName name) {
            String uri = name.getNamespaceURI();
            String local = name.getLocalPart();

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

            String prefix = getUriMapping(uri);

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

            return prefix + ":" + local;
        }

        private void emitNamespacesHelper() {
            for (iterateMappings(); hasMapping(); nextMapping()) {
                String prefix = mappingPrefix();
                String uri = mappingUri();

                try {
                    _contentHandler.startPrefixMapping(prefix, uri);
                } catch (SAXException e) {
                    throw new SaverSAXException(e);
                }

                if (_nsAsAttrs)
                    if (prefix == null || prefix.length() == 0)
                        _attributes.addAttribute("http://www.w3.org/2000/xmlns/", "xmlns", "xmlns", "CDATA", uri);
                    else
                        _attributes.addAttribute("http://www.w3.org/2000/xmlns/", prefix, "xmlns:" + prefix, "CDATA", uri);
            }
        }

        protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
            _attributes.clear();

            if (saveNamespacesFirst())
                emitNamespacesHelper();

            for (int i = 0; i < attrNames.size(); i++) {
                QName name = (QName) attrNames.get(i);

                _attributes.addAttribute(
                        name.getNamespaceURI(), name.getLocalPart(), getPrefixedName(name),
                        "CDATA", (String) attrValues.get(i));
            }

            if (!saveNamespacesFirst())
                emitNamespacesHelper();

            QName elemName = c.getName();

            try {
                _contentHandler.startElement(
                        elemName.getNamespaceURI(), elemName.getLocalPart(),
                        getPrefixedName(elemName), _attributes);
            } catch (SAXException e) {
                throw new SaverSAXException(e);
            }

            return false;
        }

        protected void emitFinish(SaveCur c) {
            QName name = c.getName();

            try {
                _contentHandler.endElement(
                        name.getNamespaceURI(), name.getLocalPart(), getPrefixedName(name));

                for (iterateMappings(); hasMapping(); nextMapping())
                    _contentHandler.endPrefixMapping(mappingPrefix());
            } catch (SAXException e) {
                throw new SaverSAXException(e);
            }
        }

        protected void emitText(SaveCur c) {
            assert c.isText();

            Object src = c.getChars();

            try {
                if (src instanceof char[]) {
                    // Pray the user does not modify the buffer ....
                    _contentHandler.characters((char[]) src, c._offSrc, c._cchSrc);
                } else {
                    if (_buf == null)
                        _buf = new char[1024];

                    while (c._cchSrc > 0) {
                        int cch = java.lang.Math.min(_buf.length, c._cchSrc);

                        CharUtil.getChars(_buf, 0, src, c._offSrc, cch);

                        _contentHandler.characters(_buf, 0, cch);

                        c._offSrc += cch;
                        c._cchSrc -= cch;
                    }
                }
            } catch (SAXException e) {
                throw new SaverSAXException(e);
            }
        }

        protected void emitComment(SaveCur c) {
            if (_lexicalHandler != null) {
                c.push();

                c.next();

                try {
                    if (!c.isText())
                        _lexicalHandler.comment(null, 0, 0);
                    else {
                        Object src = c.getChars();

                        if (src instanceof char[]) {
                            // Pray the user does not modify the buffer ....
                            _lexicalHandler.comment((char[]) src, c._offSrc, c._cchSrc);
                        } else {
                            if (_buf == null || _buf.length < c._cchSrc)
                                _buf = new char[java.lang.Math.max(1024, c._cchSrc)];

                            CharUtil.getChars(_buf, 0, src, c._offSrc, c._cchSrc);

                            _lexicalHandler.comment(_buf, 0, c._cchSrc);
                        }
                    }
                } catch (SAXException e) {
                    throw new SaverSAXException(e);
                }

                c.pop();
            }
        }

        protected void emitProcinst(SaveCur c) {
            String target = c.getName().getLocalPart();

            c.push();

            c.next();

            String value = CharUtil.getString(c.getChars(), c._offSrc, c._cchSrc);

            c.pop();

            try {
                _contentHandler.processingInstruction(c.getName().getLocalPart(), value);
            } catch (SAXException e) {
                throw new SaverSAXException(e);
            }
        }

        protected void emitDocType(String docTypeName, String publicId, String systemId) {
            if (_lexicalHandler != null) {
                try {
                    _lexicalHandler.startDTD(docTypeName, publicId, systemId);
                    _lexicalHandler.endDTD();
                } catch (SAXException e) {
                    throw new SaverSAXException(e);
                }
            }
        }

        protected void emitStartDoc(SaveCur c) {
        }

        protected void emitEndDoc(SaveCur c) {
        }

        private ContentHandler _contentHandler;
        private LexicalHandler _lexicalHandler;

        private AttributesImpl _attributes;

        private char[] _buf;
        private boolean _nsAsAttrs;
    }

    //
    //
    //

    static abstract class SaveCur {
        final boolean isRoot() {
            return kind() == ROOT;
        }

        final boolean isElem() {
            return kind() == ELEM;
        }

        final boolean isAttr() {
            return kind() == ATTR;
        }

        final boolean isText() {
            return kind() == TEXT;
        }

        final boolean isComment() {
            return kind() == COMMENT;
        }

        final boolean isProcinst() {
            return kind() == PROCINST;
        }

        final boolean isFinish() {
            return Cur.kindIsFinish(kind());
        }

        final boolean isContainer() {
            return Cur.kindIsContainer(kind());
        }

        final boolean isNormalAttr() {
            return kind() == ATTR && !isXmlns();
        }

        final boolean skip() {
            toEnd();
            return next();
        }

        abstract void release();

        abstract int kind();

        abstract QName getName();

        abstract String getXmlnsPrefix();

        abstract String getXmlnsUri();

        abstract boolean isXmlns();

        abstract boolean hasChildren();

        abstract boolean hasText();

        abstract boolean isTextCData();

        abstract boolean toFirstAttr();

        abstract boolean toNextAttr();

        abstract String getAttrValue();

        abstract boolean next();

        abstract void toEnd();

        abstract void push();

        abstract void pop();

        abstract Object getChars();

        abstract List getAncestorNamespaces();

        abstract XmlDocumentProperties getDocProps();

        int _offSrc;
        int _cchSrc;
    }

    // TODO - saving a fragment need to take namesapces from root and
    // reflect them on the document element

    private static final class DocSaveCur extends SaveCur {
        DocSaveCur(Cur c) {
            assert c.isRoot();
            _cur = c.weakCur(this);
        }

        void release() {
            _cur.release();
            _cur = null;
        }

        int kind() {
            return _cur.kind();
        }

        QName getName() {
            return _cur.getName();
        }

        String getXmlnsPrefix() {
            return _cur.getXmlnsPrefix();
        }

        String getXmlnsUri() {
            return _cur.getXmlnsUri();
        }

        boolean isXmlns() {
            return _cur.isXmlns();
        }

        boolean hasChildren() {
            return _cur.hasChildren();
        }

        boolean hasText() {
            return _cur.hasText();
        }

        boolean isTextCData() {
            return _cur.isTextCData();
        }

        boolean toFirstAttr() {
            return _cur.toFirstAttr();
        }

        boolean toNextAttr() {
            return _cur.toNextAttr();
        }

        String getAttrValue() {
            assert _cur.isAttr();
            return _cur.getValueAsString();
        }

        void toEnd() {
            _cur.toEnd();
        }

        boolean next() {
            return _cur.next();
        }

        void push() {
            _cur.push();
        }

        void pop() {
            _cur.pop();
        }

        List getAncestorNamespaces() {
            return null;
        }

        Object getChars() {
            Object o = _cur.getChars(-1);

            _offSrc = _cur._offSrc;
            _cchSrc = _cur._cchSrc;

            return o;
        }

        XmlDocumentProperties getDocProps() {
            return Locale.getDocProps(_cur, false);
        }

        private Cur _cur;
    }

    private static abstract class FilterSaveCur extends SaveCur {
        FilterSaveCur(SaveCur c) {
            assert c.isRoot();
            _cur = c;
        }

        // Can filter anything by root and attributes and text
        protected abstract boolean filter();

        void release() {
            _cur.release();
            _cur = null;
        }

        int kind() {
            return _cur.kind();
        }

        QName getName() {
            return _cur.getName();
        }

        String getXmlnsPrefix() {
            return _cur.getXmlnsPrefix();
        }

        String getXmlnsUri() {
            return _cur.getXmlnsUri();
        }

        boolean isXmlns() {
            return _cur.isXmlns();
        }

        boolean hasChildren() {
            return _cur.hasChildren();
        }

        boolean hasText() {
            return _cur.hasText();
        }

        boolean isTextCData() {
            return _cur.isTextCData();
        }

        boolean toFirstAttr() {
            return _cur.toFirstAttr();
        }

        boolean toNextAttr() {
            return _cur.toNextAttr();
        }

        String getAttrValue() {
            return _cur.getAttrValue();
        }

        void toEnd() {
            _cur.toEnd();
        }

        boolean next() {
            if (!_cur.next())
                return false;

            if (!filter())
                return true;

            assert !isRoot() && !isText() && !isAttr();

            toEnd();

            return next();
        }

        void push() {
            _cur.push();
        }

        void pop() {
            _cur.pop();
        }

        List getAncestorNamespaces() {
            return _cur.getAncestorNamespaces();
        }

        Object getChars() {
            Object o = _cur.getChars();

            _offSrc = _cur._offSrc;
            _cchSrc = _cur._cchSrc;

            return o;
        }

        XmlDocumentProperties getDocProps() {
            return _cur.getDocProps();
        }

        private SaveCur _cur;
    }

    private static final class FilterPiSaveCur extends FilterSaveCur {
        FilterPiSaveCur(SaveCur c, String target) {
            super(c);

            _piTarget = target;
        }

        protected boolean filter() {
            return kind() == PROCINST && getName().getLocalPart().equals(_piTarget);
        }

        private String _piTarget;
    }

    private static final class FragSaveCur extends SaveCur {
        FragSaveCur(Cur start, Cur end, QName synthElem) {
            _saveAttr = start.isAttr() && start.isSamePos(end);

            _cur = start.weakCur(this);
            _end = end.weakCur(this);

            _elem = synthElem;

            _state = ROOT_START;

            _stateStack = new int[8];

            start.push();
            computeAncestorNamespaces(start);
            start.pop();
        }

        List getAncestorNamespaces() {
            return _ancestorNamespaces;
        }

        private void computeAncestorNamespaces(Cur c) {
            _ancestorNamespaces = new ArrayList();

            while (c.toParentRaw()) {
                if (c.toFirstAttr()) {
                    do {
                        if (c.isXmlns()) {
                            String prefix = c.getXmlnsPrefix();
                            String uri = c.getXmlnsUri();

                            // Don't let xmlns:foo="" get used

                            if (uri.length() > 0 || prefix.length() == 0) {
                                _ancestorNamespaces.add(c.getXmlnsPrefix());
                                _ancestorNamespaces.add(c.getXmlnsUri());
                            }
                        }
                    }
                    while (c.toNextAttr());

                    c.toParent();
                }
            }
        }

        //
        //
        //

        void release() {
            _cur.release();
            _cur = null;

            _end.release();
            _end = null;
        }

        int kind() {
            switch (_state) {
                case ROOT_START:
                    return ROOT;
                case ELEM_START:
                    return ELEM;
                case ELEM_END:
                    return -ELEM;
                case ROOT_END:
                    return -ROOT;
            }

            assert _state == CUR;

            return _cur.kind();
        }

        QName getName() {
            switch (_state) {
                case ROOT_START:
                case ROOT_END:
                    return null;
                case ELEM_START:
                case ELEM_END:
                    return _elem;
            }

            assert _state == CUR;

            return _cur.getName();
        }

        String getXmlnsPrefix() {
            assert _state == CUR && _cur.isAttr();
            return _cur.getXmlnsPrefix();
        }

        String getXmlnsUri() {
            assert _state == CUR && _cur.isAttr();
            return _cur.getXmlnsUri();
        }

        boolean isXmlns() {
            assert _state == CUR && _cur.isAttr();
            return _cur.isXmlns();
        }

        boolean hasChildren() {
            boolean hasChildren = false;

            if (isContainer()) {   // is there a faster way to do this?
                push();
                next();

                if (!isText() && !isFinish())
                    hasChildren = true;

                pop();
            }

            return hasChildren;
        }

        boolean hasText() {
            boolean hasText = false;

            if (isContainer()) {
                push();
                next();

                if (isText())
                    hasText = true;

                pop();
            }

            return hasText;
        }

        boolean isTextCData() {
            return _cur.isTextCData();
        }

        Object getChars() {
            assert _state == CUR && _cur.isText();

            Object src = _cur.getChars(-1);

            _offSrc = _cur._offSrc;
            _cchSrc = _cur._cchSrc;

            return src;
        }

        boolean next() {
            switch (_state) {
                case ROOT_START: {
                    _state = _elem == null ? CUR : ELEM_START;
                    break;
                }

                case ELEM_START: {
                    if (_saveAttr)
                        _state = ELEM_END;
                    else {
                        if (_cur.isAttr()) {
                            _cur.toParent();
                            _cur.next();
                        }

                        if (_cur.isSamePos(_end))
                            _state = ELEM_END;
                        else
                            _state = CUR;
                    }

                    break;
                }

                case CUR: {
                    assert !_cur.isAttr();

                    _cur.next();

                    if (_cur.isSamePos(_end))
                        _state = _elem == null ? ROOT_END : ELEM_END;

                    break;
                }

                case ELEM_END: {
                    _state = ROOT_END;
                    break;
                }
                case ROOT_END:
                    return false;
            }

            return true;
        }

        void toEnd() {
            switch (_state) {
                case ROOT_START:
                    _state = ROOT_END;
                    return;
                case ELEM_START:
                    _state = ELEM_END;
                    return;
                case ROOT_END:
                case ELEM_END:
                    return;
            }

            assert _state == CUR && !_cur.isAttr() && !_cur.isText();

            _cur.toEnd();
        }

        boolean toFirstAttr() {
            switch (_state) {
                case ROOT_END:
                case ELEM_END:
                case ROOT_START:
                    return false;
                case CUR:
                    return _cur.toFirstAttr();
            }

            assert _state == ELEM_START;

            if (!_cur.isAttr())
                return false;

            _state = CUR;

            return true;
        }

        boolean toNextAttr() {
            assert _state == CUR;
            return !_saveAttr && _cur.toNextAttr();
        }

        String getAttrValue() {
            assert _state == CUR && _cur.isAttr();
            return _cur.getValueAsString();
        }

        void push() {
            if (_stateStackSize == _stateStack.length) {
                int[] newStateStack = new int[_stateStackSize * 2];
                System.arraycopy(_stateStack, 0, newStateStack, 0, _stateStackSize);
                _stateStack = newStateStack;
            }

            _stateStack[_stateStackSize++] = _state;
            _cur.push();
        }

        void pop() {
            _cur.pop();
            _state = _stateStack[--_stateStackSize];
        }

        XmlDocumentProperties getDocProps() {
            return Locale.getDocProps(_cur, false);
        }

        //
        //
        //

        private Cur _cur;
        private Cur _end;

        private ArrayList _ancestorNamespaces;

        private QName _elem;

        private boolean _saveAttr;

        private static final int ROOT_START = 1;
        private static final int ELEM_START = 2;
        private static final int ROOT_END = 3;
        private static final int ELEM_END = 4;
        private static final int CUR = 5;

        private int _state;

        private int[] _stateStack;
        private int _stateStackSize;
    }

    private static final class PrettySaveCur extends SaveCur {
        PrettySaveCur(SaveCur c, XmlOptions options) {
            _sb = new StringBuffer();
            _stack = new ArrayList();

            _cur = c;

            assert options != null;

            _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.LOAD_SAVE_CDATA_BOOKMARKS)) {
                _useCDataBookmarks = true;
            }
        }

        List getAncestorNamespaces() {
            return _cur.getAncestorNamespaces();
        }

        void release() {
            _cur.release();
        }

        int kind() {
            return _txt == null ? _cur.kind() : TEXT;
        }

        QName getName() {
            assert _txt == null;
            return _cur.getName();
        }

        String getXmlnsPrefix() {
            assert _txt == null;
            return _cur.getXmlnsPrefix();
        }

        String getXmlnsUri() {
            assert _txt == null;
            return _cur.getXmlnsUri();
        }

        boolean isXmlns() {
            return _txt == null ? _cur.isXmlns() : false;
        }

        boolean hasChildren() {
            return _txt == null ? _cur.hasChildren() : false;
        }

        boolean hasText() {
            return _txt == null ? _cur.hasText() : false;
        }

        // _cur.isTextCData() is expensive do it only if useCDataBookmarks option is enabled
        boolean isTextCData() {
            return _txt == null ? (_useCDataBookmarks && _cur.isTextCData())
                    : _isTextCData;
        }

        boolean toFirstAttr() {
            assert _txt == null;
            return _cur.toFirstAttr();
        }

        boolean toNextAttr() {
            assert _txt == null;
            return _cur.toNextAttr();
        }

        String getAttrValue() {
            assert _txt == null;
            return _cur.getAttrValue();
        }

        void toEnd() {
            assert _txt == null;
            _cur.toEnd();

            if (_cur.kind() == -ELEM)
                _depth--;
        }

        boolean next() {
            int k;

            if (_txt != null) {
                assert _txt.length() > 0;
                assert !_cur.isText();
                _txt = null;
                _isTextCData = false;
                k = _cur.kind();
            } else {
                int prevKind = k = _cur.kind();

                if (!_cur.next())
                    return false;

                _sb.delete(0, _sb.length());

                assert _txt == null;

                // place any text encountered in the buffer
                if (_cur.isText()) {
                    // _cur.isTextCData() is expensive do it only if useCDataBookmarks option is enabled
                    _isTextCData = _useCDataBookmarks && _cur.isTextCData();
                    CharUtil.getString(_sb, _cur.getChars(), _cur._offSrc, _cur._cchSrc);
                    _cur.next();
                    k = _cur.kind();
                    if (prevKind != ELEM || k != -ELEM) {
                        trim(_sb);
                    }
                }

                k = _cur.kind();

                // Check for non leaf, _prettyIndent < 0 means that the save is all on one line

                if (_prettyIndent >= 0 &&
                        prevKind != COMMENT && prevKind != PROCINST && (prevKind != ELEM || k != -ELEM)) {
                    if (_sb.length() > 0) {
                        _sb.insert(0, _newLine);
                        spaces(_sb, _newLine.length(), _prettyOffset + _prettyIndent * _depth);
                    }

                    if (k != -ROOT) {
                        if (prevKind != ROOT)
                            _sb.append(_newLine);

                        int d = k < 0 ? _depth - 1 : _depth;
                        spaces(_sb, _sb.length(), _prettyOffset + _prettyIndent * d);
                    }
                }

                if (_sb.length() > 0) {
                    _txt = _sb.toString();
                    k = TEXT;
                }
            }

            if (k == ELEM)
                _depth++;
            else if (k == -ELEM)
                _depth--;

            return true;
        }

        void push() {
            _cur.push();
            _stack.add(_txt);
            _stack.add(new Integer(_depth));
            _isTextCData = false;
        }

        void pop() {
            _cur.pop();
            _depth = ((Integer) _stack.remove(_stack.size() - 1)).intValue();
            _txt = (String) _stack.remove(_stack.size() - 1);
            _isTextCData = false;
        }

        Object getChars() {
            if (_txt != null) {
                _offSrc = 0;
                _cchSrc = _txt.length();
                return _txt;
            }

            Object o = _cur.getChars();

            _offSrc = _cur._offSrc;
            _cchSrc = _cur._cchSrc;

            return o;
        }

        XmlDocumentProperties getDocProps() {
            return _cur.getDocProps();
        }

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

        static void trim(StringBuffer sb) {
            int i;

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

            sb.delete(0, i);

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

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

        private SaveCur _cur;

        private int _prettyIndent;
        private int _prettyOffset;

        private String _txt;
        private StringBuffer _sb;

        private int _depth;

        private ArrayList _stack;
        private boolean _isTextCData = false;
        private boolean _useCDataBookmarks = false;
    }


    //
    //
    //

    private final Locale _locale;
    private final long _version;

    private SaveCur _cur;

    private List _ancestorNamespaces;
    private Map _suggestedPrefixes;
    protected XmlOptionCharEscapeMap _replaceChar;
    private boolean _useDefaultNamespace;
    private Map _preComputedNamespaces;
    private boolean _saveNamespacesFirst;

    private ArrayList _attrNames;
    private ArrayList _attrValues;

    private ArrayList _namespaceStack;
    private int _currentMapping;
    private HashMap _uriMap;
    private HashMap _prefixMap;
    private String _initialDefaultUri;

    static final String _newLine =
            SystemProperties.getProperty("line.separator") == null
                    ? "\n"
                    : SystemProperties.getProperty("line.separator");
}
