/*   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.EncodingMap;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.XmlEventBase;
import org.apache.xmlbeans.impl.common.XmlNameImpl;
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 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;
    }
}
