/*   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 org.apache.xmlbeans.SystemProperties;
import org.apache.xmlbeans.XmlDocumentProperties;
import org.apache.xmlbeans.XmlOptionCharEscapeMap;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.common.*;
import org.apache.xmlbeans.xml.stream.CharacterData;
import org.apache.xmlbeans.xml.stream.*;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.AttributesImpl;

import javax.xml.namespace.QName;
import java.io.*;
import java.util.*;

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;


    private final Locale _locale;
    private final long _version;

    private SaveCur _cur;

    private List<String> _ancestorNamespaces;
    private final Map<String, String> _suggestedPrefixes;
    protected XmlOptionCharEscapeMap _replaceChar;
    private final boolean _useDefaultNamespace;
    private Map<String, String> _preComputedNamespaces;
    private final boolean _saveNamespacesFirst;

    private final ArrayList<QName> _attrNames = new ArrayList<>();
    private final ArrayList<String> _attrValues = new ArrayList<>();

    private final ArrayList<String> _namespaceStack = new ArrayList<>();
    private int _currentMapping;
    private final HashMap<String, String> _uriMap = new HashMap<>();
    private final HashMap<String, String> _prefixMap = new HashMap<>();
    private String _initialDefaultUri;

    static final String _newLine = SystemProperties.getProperty("line.separator", "\n");


    protected abstract boolean emitElement(SaveCur c, List<QName> attrNames, List<String> 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();

        // Define implicit xml prefixed namespace

        addMapping("xml", Locale._xml1998Uri);

        Map<String, String> m = options.getSaveImplicitNamespaces();
        if (m != null) {
            for (String prefix : m.keySet()) {
                addMapping(prefix, m.get(prefix));
            }
        }

        // define character map for escaped replacements
        _replaceChar = options.getSaveSubstituteCharacters();

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

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

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

            //noinspection StatementWithEmptyBody
            while (saver.process()) { }

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

        _useDefaultNamespace = options.isUseDefaultNamespace();

        _saveNamespacesFirst = options.isSaveNamespacesFirst();


        _suggestedPrefixes = options.getSaveSuggestedPrefixes();

        _ancestorNamespaces = _cur.getAncestorNamespaces();
    }

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

        QName fragName = synthName;

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

        boolean saveInner = options.isSaveInner() && !options.isSaveOuter();

        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 {
                start.moveToCur(c);
                end.moveToCur(c);
                end.skip();
            }

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

        String filterPI = options.getSaveFilterProcinst();

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

        if (options.isSavePrettyPrint()) {
            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) ||
            // TODO: ch >= 0x10000 && ch <= 0x10FFFF is always false for a char, use codepoints/ints
            // (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 void processFinish() {
        emitFinish(_cur);
        popMappings();
    }

    private 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();
                //noinspection StatementWithEmptyBody
                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 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 (Map.Entry<String,String> entry : _preComputedNamespaces.entrySet()) {
                String uri = entry.getKey();
                String prefix = entry.getValue();
                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
    //

    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 _namespaceStack.get(_currentMapping + 6);
    }

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

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

        _namespaceStack.add(null);

        c.push();

        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 = _ancestorNamespaces.get(i);
                String uri = _ancestorNamespaces.get(i + 1);

                addNewFrameMapping(prefix, uri, ensureDefaultEmpty);
            }

            _ancestorNamespaces = null;
        }

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

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

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

    private 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 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 = _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 = _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 void popMappings() {
        for (; ; ) {
            int i = _namespaceStack.size();

            if (i == 0) {
                break;
            }

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

            String oldUri = _namespaceStack.get(i - 7);
            String 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 = _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 void ensureMapping(
        String uri, String candidatePrefix,
        boolean considerCreatingDefault, boolean mustHavePrefix) {
        assert uri != null;

        // Can be called for no-namespaced things

        if (uri.length() == 0) {
            return;
        }

        String prefix = _uriMap.get(uri);

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

        //
        // 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 (!tryPrefix(candidatePrefix)) {
            if (_suggestedPrefixes != null &&
                _suggestedPrefixes.containsKey(uri) &&
                tryPrefix(_suggestedPrefixes.get(uri))) {
                candidatePrefix = _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);
    }

    protected final String getUriMapping(String uri) {
        assert _uriMap.containsKey(uri);
        return _uriMap.get(uri);
    }

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

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

        for (String s : _prefixMap.keySet()) {
            prefix = s;

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

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

        return null;
    }

    private boolean tryPrefix(String prefix) {
        if (prefix == null || Locale.beginsWithXml(prefix)) {
            return false;
        }

        String existingUri = _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.

        return existingUri == null || (prefix.length() <= 0 && Objects.equals(existingUri, _initialDefaultUri));
    }

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

        return _prefixMap.get(prefix);
    }

    protected Map<String,String> getPrefixMap() {
        return _prefixMap;
    }

    //
    //
    //

    static final class SynthNamespaceSaver extends Saver {
        LinkedHashMap<String,String> _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, List<QName> attrNames, List<String> 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.isSaveNoXmlDecl();

            if (options != null && options.getSaveCDataLengthThreshold() != null) {
                _cdataLengthThreshold = options.getSaveCDataLengthThreshold();
            }

            if (options != null && options.getSaveCDataEntityCountThreshold() != null) {
                _cdataEntityCountThreshold = options.getSaveCDataEntityCountThreshold();
            }

            if (options != null && options.isUseCDataBookmarks()) {
                _useCDataBookmarks = true;
            }

            if (options != null && options.isSavePrettyPrint()) {
                _isPrettyPrint = true;
            }

            _in = _out = 0;
            _free = 0;

            //noinspection ConstantConditions
            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 ? "yes" : "no") + "\"");
                }
                emit("?>" + _newLine);
            }
        }

        @Override
        protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues) {
            assert c.isElem();

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

            if (saveNamespacesFirst()) {
                emitNamespacesHelper();
            }

            for (int i = 0; i < attrNames.size(); i++) {
                emitAttrHelper(attrNames.get(i), 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.contains("\"")) {
                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 (_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 (_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) || s == null) {
                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 (_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 _buf == null || _free == _buf.length;
                _in = _out = 0;
            }

            _lastEmitIn = _in;

            _free -= cch;

            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] == '-') {
                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 (_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;
            //noinspection ConstantConditions
            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 (_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 (_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!

            //noinspection StatementWithEmptyBody
            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 final 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);
                //noinspection StatementWithEmptyBody
                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, List<QName> attrNames, List<String> attrValues) {
            assert c.isElem();

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

            for (int i = 0; i < attrNames.size(); i++) {
                emitAttrHelper(attrNames.get(i), 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.contains("\"")) {
                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;
            while (index < cch) {
                int indexLimit = Math.min(index + 512, cch);
                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;
            while (index < cch) {
                int 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;
            while (index < cch) {
                int 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() {
            _closed = true;
        }

        public boolean ready() {
            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 final Locale _locale;
        private final 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());
            }

            String enc = options.getCharacterEncoding();
            if (enc != null) {
                encoding = enc;
            }

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

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

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

            String javaEncoding = (encoding == null) ? null : 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() {
            _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() {
            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;
                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 final Locale _locale;
        private boolean _closed;
        private final OutputStreamImpl _outStreamImpl;
        private final TextSaver _textSaver;
        private final OutputStreamWriter _converter;
    }

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

        @Override
        protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> 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(attrNames.get(i), this, true);
                StartElementImpl.AttributeImpl attr =
                    new StartElementImpl.NormalAttributeImpl(attXMLName, 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.isEmpty()) {
                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<String,String> 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 _prefixMap.get(prefix == null ? "" : prefix);
            }

            public Map<String,String> 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 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 final String _uri;
            }

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

                public String getValue() {
                    return _value;
                }

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

            private final XMLName _name;
            private final Map<String,String> _prefixMap;

            private final AttributeImpl _attributes;
            private final 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 final String _prefix;
            private final String _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 final String _oldUri;
            private final String _newUri;
            private final String _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 final 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 final 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 final Object _obj;
            private final int _cch;
            private final 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 final 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() {
            return _xmlInputStreamSaver.dequeue();
        }

        private final 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.isSaveSaxNoNSDeclsInAttributes();

            _contentHandler.startDocument();

            try {
                //noinspection StatementWithEmptyBody
                while (process()) { }
            } catch (SaverSAXException e) {
                throw e._saxException;
            }

            _contentHandler.endDocument();
        }

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

        @Override
        protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues) {
            _attributes.clear();

            if (saveNamespacesFirst()) {
                emitNamespacesHelper();
            }

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

                _attributes.addAttribute(
                    name.getNamespaceURI(), name.getLocalPart(), getPrefixedName(name),
                    "CDATA", 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) {
            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 final ContentHandler _contentHandler;
        private final LexicalHandler _lexicalHandler;

        private final AttributesImpl _attributes;

        private char[] _buf;
        private final 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();
        }

        @SuppressWarnings("unused")
        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<String> 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<String> 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<String> 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 final 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<String> 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<String> _ancestorNamespaces;

        private final QName _elem;

        private final 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.getSavePrettyPrintIndent() != null) {
                _prettyIndent = options.getSavePrettyPrintIndent();
            }

            if (options.getSavePrettyPrintOffset() != null) {
                _prettyOffset = options.getSavePrettyPrintOffset();
            }

            _useCDataBookmarks = options.isUseCDataBookmarks();
        }

        List<String> 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();
        }

        boolean hasChildren() {
            return _txt == null && _cur.hasChildren();
        }

        boolean hasText() {
            return _txt == null && _cur.hasText();
        }

        // _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 = _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(_depth);
            _isTextCData = false;
        }

        void pop() {
            _cur.pop();
            _depth = (Integer) _stack.remove(_stack.size() - 1);
            _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 final SaveCur _cur;

        private int _prettyIndent;
        private int _prettyOffset;

        private String _txt;
        private final StringBuffer _sb;

        private int _depth;

        private final ArrayList<Object> _stack;
        private boolean _isTextCData = false;
        private final boolean _useCDataBookmarks;
    }
}
