/*   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 xmlcursor.checkin;

import org.apache.xmlbeans.*;
import org.apache.xmlbeans.XmlCursor.TokenType;
import org.apache.xmlbeans.XmlCursor.XmlBookmark;
import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
import org.junit.Ignore;
import org.junit.Test;
import org.xml.sax.*;
import org.xml.sax.ext.LexicalHandler;
import xmlcursor.common.Common;

import javax.xml.namespace.QName;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.StringReader;
import java.util.*;

import static org.junit.Assert.*;

public class StoreTests {

    static String[] _args;
    static String _test;


    private void streamTest(String xml)
        throws Exception {
        XmlObject x1 = XmlObject.Factory.parse(xml);
        XmlObject x2 = XmlObject.Factory.parse(x1.newCursor().newXMLStreamReader());

        String x1Text = x1.xmlText();
        String x2Text = x2.xmlText();

        assertEquals(x1Text, x2Text);
    }

    @Test
    public void testXMLStreamReader() throws Exception {
        streamTest("<a/>");
        streamTest("<a x='y'/>");
        streamTest("<a><b>foo</b></a>");
        streamTest("<a><b>fo<!--moo-->o<?goof ball?>dsfdf</b></a>");
        streamTest("<a xmlns='nnn'></a>");
        streamTest("<a x='y'><!---->x<b/><c p='q'>z</c></a>");
        streamTest("<a x='y'><!----><b>moo</b><c p='q'></c></a>");
        streamTest("<a>asa<b/>sdsd<c>aaz</c>adsasd</a>");
        streamTest("<a><?target value?></a>");
        streamTest("<n:a xmlns:n='nnn'></n:a>");
        streamTest("<j:a x='y' p='q' xmlns:j='k'></j:a>");
        streamTest("<foo xmlns=\"foo.com\"><bar>1</bar></foo>");
        streamTest("<foo><!--comment--><?target foo?></foo>");
        streamTest("<foo>a<bar>b</bar>c<bar>d</bar>e</foo>");
        streamTest("<foo xmlns:x=\"y\"><bar xmlns:x=\"z\"/></foo>");
        streamTest("<foo x=\"y\" p=\"r\"/>");
    }

    @Test
    public void testReplaceContents() throws Exception {
        XmlObject xDst = XmlObject.Factory.newInstance();
        XmlObject xSrc = XmlObject.Factory.parse("<foo/>");
        XmlObject newDst = xDst.set(xSrc);
        assertEquals("<foo/>", newDst.xmlText());

        xDst = XmlObject.Factory.parse("<bar/>");
        xSrc = XmlObject.Factory.parse("<foo/>");
        XmlCursor c = xDst.newCursor();
        c.toNextToken();
        xDst = c.getObject();
        xDst.set(xSrc);
        c.toStartDoc();
        xDst = c.getObject();
        assertEquals("<bar><foo/></bar>", xDst.xmlText());

        xDst = XmlObject.Factory.parse("<bar x='y'/>");
        xSrc = XmlObject.Factory.parse("<foo>moo</foo>");
        c = xDst.newCursor();
        c.toNextToken();
        c.toNextToken();
        xDst = c.getObject();
        xDst.set(xSrc);
        c.toStartDoc();
        xDst = c.getObject();
        assertEquals("<bar x=\"moo\"/>", xDst.xmlText());
    }

    @Test(expected = Exception.class)
    public void testSniffing() throws Exception {
        XmlObject x;

        x = XmlObject.Factory.parse("<xoo/>");
        assertSame(x.schemaType(), XmlBeans.NO_TYPE);

        x = XmlObject.Factory.parse(
            "<schema xmlns='http://www.w3.org/2001/XMLSchema'/>");
        assertSame(x.schemaType(), SchemaDocument.type);

        x = XmlObject.Factory.parse(
            "<schema xmlns='http://www.w3.org/2001/XMLSchema/moo'/>");
        assertSame(x.schemaType(), XmlBeans.NO_TYPE);

        x = XmlObject.Factory.parse(
            "<schema xmlns='http://www.w3.org/2001/XMLSchema'/>");
        assertSame(x.schemaType(), SchemaDocument.type);

        x = org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Factory.parse(
            "<schema xmlns='http://www.w3.org/2001/XMLSchema'/>");
        assertSame(x.schemaType(), SchemaDocument.type);

        org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Factory.parse(
            "<schema xmlns='http://www.w3.org/2001/XMLSchema/moo'/>");
    }

    @Test
    public void testCursorStack() throws Exception {
        XmlObject x = XmlObject.Factory.parse("<foo x='y'/>");
        XmlCursor c = x.newCursor();
        c.push();
        c.toNextToken();
        c.push();
        c.toNextToken();
        assertTrue(c.isAttr());
        c.pop();
        assertTrue(c.isStart());
        c.pop();
        assertTrue(c.isStartdoc());
    }

    @Test
    public void testImplicitNamespaces() {
        Map<String, String> namespaces = new HashMap<>();
        namespaces.put("foo", "foo.com");
        namespaces.put("bar", "bar.com");
        namespaces.put("", "default.com");

        XmlOptions options = new XmlOptions();
        options.setSaveImplicitNamespaces(namespaces);

        XmlObject x = XmlObject.Factory.newInstance();
        XmlCursor c = x.newCursor();

        c.toNextToken();

        c.beginElement("a", "foo.com");
        c.beginElement("b", "default.com");
        c.beginElement("c", "bar.com");

        assertEquals("<foo:a><b><bar:c/></b></foo:a>", x.xmlText(options));
    }

    private static class Content implements ContentHandler, LexicalHandler {
        public void startDocument() {
            add("START_DOCUMENT");
        }

        public void endDocument() {
            add("END_DOCUMENT");
        }

        public void startElement(
            String namespaceURI, String localName,
            String qName, Attributes atts) {
            add("START_ELEMENT");
            add("  namespaceURI: " + namespaceURI);
            add("  localName: " + localName);
//            add( "  qName: " + qName );

            TreeSet<String> sortedAttrs = new TreeSet<>();

            for (int i = 0; i < atts.getLength(); i++) {
                String ln = atts.getLocalName(i);
                String uri = atts.getURI(i);
                String qname = atts.getQName(i);

                if (ln.equals("xmlns")) {
                    continue;
                }
                if (qname.startsWith("xmlns")) {
                    continue;
                }

//                if (ln.equals( "xmlns" ))
//                    ln = "";
//
//                if (uri.equals( "xmlns" ))
//                    uri = "";

                sortedAttrs.add(
                    uri + "-" + ln + "-" +
                    atts.getQName(i) + "-" + atts.getType(i) + "-" +
                    atts.getValue(i));
            }

            for (String sortedAttr : sortedAttrs) {
                add("  Attr: " + sortedAttr);
            }
        }

        public void endElement(
            String namespaceURI, String localName, String qName) {
            add("END_ELEMENT");
            add("  namespaceURI: " + namespaceURI);
            add("  localName: " + localName);
//            add( "  qName: " + qName );
        }

        public void characters(char[] ch, int start, int length) {
            if (length > 0) {
                add("CHARACTERS");
                add(ch, start, length);
            }
        }

        public void comment(char[] ch, int start, int length) {
            add("COMMENT");
            add("  Comment: ", ch, start, length);
        }

        public void processingInstruction(String target, String data) {
            add("PROCESSING_INSTRUCTION");
            add("target: " + target);
            add("data: " + data);
        }

        public void ignorableWhitespace(char[] ch, int start, int length) {
            if (length > 0) {
                add("IGNORABLE_WHITESPACE");
                add("  whitespace: ", ch, start, length);
            }
        }

        public void startPrefixMapping(String prefix, String uri) {
            add("START_PREFIX_MAPPING");
//            add( "  prefix: " + prefix );
            add("  uri: " + uri);
        }

        public void endPrefixMapping(String prefix) {
            add("END_PREFIX_MAPPING");
//            add( "  prefix: " + prefix );
        }

        public void startCDATA() {
            add("START_CDATA");
        }

        public void endCDATA() {
            add("END_CDATA");
        }

        public void startDTD(String name, String publicId, String systemId) {
            add("START_DTD");
            add("  name: " + name);
            add("  publicId: " + publicId);
            add("  systemId: " + systemId);
        }

        public void endDTD() {
            add("END_DTD");
        }

        public void startEntity(String name) {
            add("START_ENTITY");
            add("  name: " + name);
        }

        public void endEntity(String name) {
            add("END_ENTITY");
            add("  name: " + name);
        }

        public void setDocumentLocator(Locator locator) {
            // add( "START_DOCUMENT_LOCATOR" );
        }

        public void skippedEntity(String name) {
            add("SKIPPED_ENTITY");
            add("  name: " + name);
        }

        private void add(String s) {
            _sb.append(s);
            _sb.append("\n");
        }

        private void add(String s, char[] buf, int off, int cch) {
            _sb.append(s);
            if (buf != null) {
                _sb.append(buf, off, cch);
            }
            _sb.append("\n");
        }

        private void add(char[] buf, int off, int cch) {
            _sb.append(buf, off, cch);
            _sb.append("\n");
        }

        public boolean equals(Object that) {
            return toString().equals(that.toString());
        }

        public String toString() {
            return _sb.toString();
        }

        private final StringBuilder _sb = new StringBuilder();
    }

    private void doTestSaxSaver(String xml)
        throws Exception {
        // ME

        Content content2 = new Content();

        XmlObject x = XmlObject.Factory.parse(xml);

        x.save(content2, content2);

        // THEM

        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();

        XMLReader xr = sp.getXMLReader();

        Content content1 = new Content();

        xr.setProperty("http://xml.org/sax/properties/lexical-handler", content1);
        xr.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
        xr.setFeature("http://xml.org/sax/features/namespaces", true);
        xr.setFeature("http://xml.org/sax/features/validation", false);

        xr.setContentHandler(content1);

        InputSource is = new InputSource(new StringReader(xml));

        xr.parse(is);

        assertEquals(content1, content2);
    }

    @Test
    public void testSaxSaver()
        throws Exception {
        doTestSaxSaver("<a xmlns='nnn'></a>");
        doTestSaxSaver("<a x='y'><!---->x<b/><c p='q'>z</c></a>");
        doTestSaxSaver("<a x='y'><!----><b>moo</b><c p='q'></c></a>");
        doTestSaxSaver("<a>asa<b/>sdsd<c>aaz</c>adsasd</a>");
        doTestSaxSaver("<a><?target value?></a>");
        doTestSaxSaver("<n:a xmlns:n='nnn'></n:a>");
        doTestSaxSaver("<j:a x='y' p='q' xmlns:j='k'></j:a>");
    }

    @Test
    @Ignore
    public void testParsing() throws Exception {
        Random r = new Random(1);

        for (int i = 0; i < 100000; i++) {
            String xml = makeRandomDocument(r);
            XmlObject.Factory.parse(xml);
        }
    }

    private void doTestLineNumbers(String xml)
        throws Exception {
        int line = 1;
        int col = 1;

        XmlCursor c =
            XmlObject.Factory.parse(
                xml, new XmlOptions().setLoadLineNumbers()).
                newCursor();

        for (int i = 0; i < xml.length(); i++) {
            char ch = xml.charAt(i);

            if (ch == '<' && Character.isLetter(xml.charAt(i + 1))) {
                while (!c.currentTokenType().isStart()) {
                    c.toNextToken();
                }

                assertTrue(c.currentTokenType().isStart());

                XmlLineNumber ln =
                    (XmlLineNumber)
                        c.getBookmark(XmlLineNumber.class);

                assertNotNull(ln);

                assertTrue(ln.getLine() == -1 || ln.getLine() == line);
                assertTrue(ln.getColumn() == -1 || ln.getColumn() == col);
                assertTrue(ln.getOffset() == -1 || ln.getOffset() == i);

                c.toNextToken();
            }

            if (ch == '\n') {
                line++;
                col = 1;
            } else {
                col++;
            }
        }
    }

    @Test
    @Ignore
    public void testLineNumbers() throws Exception {
        Random r = new Random(1);

        for (int i = 0; i < 1000; i++) {
            String xml = makeRandomDocument(r);
            doTestLineNumbers(xml);
        }
    }

    private static class DocBuilder {
        Random r;
        StringBuilder sb;

        DocBuilder(Random _r, StringBuilder _sb) {
            r = _r;
            sb = _sb;
        }

        void append(char ch) {
            sb.append(ch);
        }

        void append(String s) {
            sb.append(s);
        }

        public void whitespace() {
            int p = r.nextInt(100);

            if (p < 20) {
                append('\t');
            } else if (p < 40) {
                append('\n');
            } else {
                append(' ');
            }
        }

        void whitespaces() {
            for (int i = r.nextInt(8); i > 0; i--) {
                whitespace();
            }
        }

        char makeLetter() {
            return (char) (((int) 'a') + r.nextInt(26));
        }

        public void letter() {
            append(makeLetter());
        }

        void charEntity() {
            switch (r.nextInt(5)) {
                case 0:
                    append("&lt;");
                    break;
                case 1:
                    append("&gt;");
                    break;
                case 2:
                    append("&amp;");
                    break;
                case 3:
                    append("&apos;");
                    break;
                case 4:
                    append("&quot;");
                    break;
            }
        }

        public void text() {
            for (int i = r.nextInt(20); i > 0; i--) {
                int p = r.nextInt(100);

                if (p < 70) {
                    letter();
                } else if (p < 74) {
                    charEntity();
                } else {
                    whitespace();
                }
            }
        }

        String makeNcName() {
            StringBuilder name = new StringBuilder();

            for (; ; ) {
                char ch = makeLetter();

                if (ch == 'x' || ch == 'X') {
                    continue;
                }

                name.append(ch);

                break;
            }

            for (int i = r.nextInt(20); i > 0; i--) {
                name.append(makeLetter());
            }

            return name.toString();
        }

        void ncName() {
            append(makeNcName());
        }

        public void comment() {
            append("<!--");
            text();
            append("-->");
        }

        public void procinst() {
            append("<?");
            ncName();

            if (r.nextInt(100) < 90) {
                whitespace();
                text();
            }

            append("?>");
        }

        void whiteContent() {
            for (; ; ) {
                int p = r.nextInt(100);

                if (p < 20) {
                    break;
                } else if (p < 50) {
                    whitespaces();
                } else if (p < 70) {
                    comment();
                } else {
                    procinst();
                }
            }
        }

        void xmlDecl() {
            append("<?xml version=\"1.0\"?>");
        }

        public void content(int depth) {
            for (int i = r.nextInt(10); i > 0; i--) {
                switch (r.nextInt(4)) {
                    case 0:
                        elementContent(depth + 1);
                        break;

                    case 1:
                        text();
                        break;
                    case 2:
                        comment();
                        break;
                    case 3:
                        procinst();
                        break;
                }
            }
        }

        public void attribute() {
            ncName();

            if (r.nextInt(100) == 0) {
                whitespaces();
            }

            append('=');

            if (r.nextInt(100) == 0) {
                whitespaces();
            }

            char q = r.nextInt(2) == 0 ? '\'' : '"';

            append(q);

            text();

            append(q);
        }

        void elementContent(int depth) {
            // If depth == 0, guarantee an element, otherwise, as depth
            // increases, the probablility we'll spit out an element
            // gets smaller.

            if (r.nextInt(depth + 1) <= 1) {
                String name = makeNcName();

                append('<');
                append(name);

                if (r.nextInt(100) == 0) {
                    whitespaces();
                }

                HashMap<String,Object> attrs = new HashMap<>();

                for (int i = r.nextInt(3); i > 0; i--) {
                    append(' ');

                    String aname;

                    do {
                        aname = makeNcName();

                    } while (attrs.containsKey(aname));

                    attrs.put(aname, null);

                    append(aname);

                    if (r.nextInt(100) == 0) {
                        whitespaces();
                    }

                    append('=');

                    if (r.nextInt(100) == 0) {
                        whitespaces();
                    }

                    char q = r.nextInt(2) == 0 ? '\'' : '"';

                    append(q);

                    text();

                    append(q);

                    if (r.nextInt(10) == 0) {
                        whitespaces();
                    }
                }

                append('>');

                content(depth);

                append("</");
                append(name);

                if (r.nextInt(100) == 0) {
                    whitespaces();
                }

                append('>');
            }
        }

        public void document() {
            if (r.nextInt(2) == 0) {
                xmlDecl();
            }

            whiteContent();

            elementContent(0);

            whiteContent();
        }
    }

    private String makeRandomDocument(Random r) {
        StringBuilder sb = new StringBuilder();

        DocBuilder db = new DocBuilder(r, sb);

        db.document();

        return sb.toString();
    }

    private static class MyMark extends XmlBookmark {
    }

    @Test
    public void testBookmarks()
        throws Exception {
        XmlObject x = XmlObject.Factory.parse("<foo x='y'>abcdefg<!---->xy</foo>");

        XmlCursor c = x.newCursor();
        MyMark m1 = new MyMark();
        c.setBookmark(m1);

        c.toNextToken();
        MyMark m2 = new MyMark();
        c.setBookmark(m2);

        c.toNextToken();
        MyMark m3 = new MyMark();
        c.setBookmark(m3);

        c.toNextToken();
        MyMark m4 = new MyMark();
        c.setBookmark(m4);

        c.toNextChar(1);
        MyMark m5 = new MyMark();
        c.setBookmark(m5);

        c.toNextChar(3);
        MyMark m6 = new MyMark();
        c.setBookmark(m6);

        c.toNextToken();
        c.toNextToken();
        c.toNextToken();
        MyMark m7 = new MyMark();
        c.setBookmark(m7);

        c.toNextToken();
        MyMark m8 = new MyMark();
        c.setBookmark(m8);

        c.toStartDoc();

        assertSame(c.getBookmark(MyMark.class), m1);
        assertSame(c.toNextBookmark(MyMark.class), m2);
        assertSame(c.toNextBookmark(MyMark.class), m3);
        assertSame(c.toNextBookmark(MyMark.class), m4);
        assertSame(c.toNextBookmark(MyMark.class), m5);
        assertSame(c.toNextBookmark(MyMark.class), m6);
        assertSame(c.toNextBookmark(MyMark.class), m7);
        assertSame(c.toNextBookmark(MyMark.class), m8);
        assertNull(c.toNextBookmark(MyMark.class));

        c.toEndDoc();

        assertSame(c.getBookmark(MyMark.class), m8);
        assertSame(c.toPrevBookmark(MyMark.class), m7);
        assertSame(c.toPrevBookmark(MyMark.class), m6);
        assertSame(c.toPrevBookmark(MyMark.class), m5);
        assertSame(c.toPrevBookmark(MyMark.class), m4);
        assertSame(c.toPrevBookmark(MyMark.class), m3);
        assertSame(c.toPrevBookmark(MyMark.class), m2);
        assertSame(c.toPrevBookmark(MyMark.class), m1);
        assertNull(c.toPrevBookmark(MyMark.class));
    }

    @Test
    public void testSetName()
        throws Exception {
        XmlObject x = XmlObject.Factory.parse("<foo x='a'/>");
        XmlCursor c = x.newCursor();
        c.toNextToken();
        c.setName(new QName("bar"));
        c.toNextToken();
        c.setName(new QName("y"));

        assertEquals("<bar y=\"a\"/>", x.xmlText());
    }

    //
    // Basic load up a file and iterate through it
    //
    @Test
    public void testBasicXml()
        throws Exception {
        XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor();

        int n = 0;

        for (; ; ) {
            TokenType t = c.toNextToken();

            n++;

            if (t == TokenType.NONE) {
                break;
            }
        }

        assertEquals(6, n);
    }

    //
    // Make sure the tokens going forward the the reverse of the tokens
    // going backward
    //
    @Test
    public void testConsistentTokenOrder()
        throws Exception {
        ArrayList<TokenType> l = new ArrayList<>();

        XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor();


        do {
            // System.err.println(c.currentTokenType());
            l.add(c.currentTokenType());

        } while (c.toNextToken() != TokenType.NONE);

        c.toEndDoc();
        // System.err.println("Reversing");

        for (int i = l.size() - 1; ; i--) {
            // System.err.println(c.currentTokenType());
            assertEquals(l.get(i), c.currentTokenType());

            if (c.toPrevToken() == TokenType.NONE) {
                break;
            }
        }
    }

    // Make sure you can't insert text before the doc begin
    // going backward
    @Test(expected = IllegalStateException.class)
    public void testIllegalTextInsert()
        throws Exception {
        XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor();
        c.insertChars("Ho ho ho");
    }

    // Make sure getText works in a basic way
    @Test
    public void testgetText()
        throws Exception {
        XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor();
        assertEquals("ab", c.getTextValue()); // Doc node

        c.toNextToken();
        assertEquals("ab", c.getTextValue()); // Doc elem

        c.toNextToken();
        assertEquals("y", c.getTextValue()); // Attr x

        c.toNextToken();
        assertEquals("ab", c.getChars()); // Text

        c.toNextChar(1);
        assertEquals("b", c.getChars()); // Text

        c.toNextToken();
        assertEquals(0, c.getChars().length());       // End tag

        c.toNextToken();
        assertEquals(0, c.getChars().length());       // End doc
    }

    //
    // Text XMLInputStream support
    //

    private void doSaverTest(String xml) throws Exception {
        XmlCursor c = XmlObject.Factory.parse(xml).newCursor();
        assertEquals(xml, c.xmlText());
    }

    private void doSaveTest(String xml) throws Exception {
        doSaverTest(xml);
    }

    @Test
    public void testCDATA() throws Exception {
        // https://issues.apache.org/jira/browse/XMLBEANS-404
        String xml = "<foo>Unable to render embedded object: <![CDATA[>>>>>>>><<<<<<<<<<<]]></foo>";
        String expected = "<foo><![CDATA[Unable to render embedded object: >>>>>>>><<<<<<<<<<<]]></foo>";
        XmlOptions options = new XmlOptions().setSaveCDataLengthThreshold(0);
        XmlCursor c = XmlObject.Factory.parse(xml, options).newCursor();
        assertEquals(expected, c.xmlText(options));
    }

    @Test
    public void testSaving() throws Exception {
        doSaveTest("<foo xmlns=\"foo.com\"><bar>1</bar></foo>");
        doSaveTest("<foo><!--comment--><?target foo?></foo>");
        doSaveTest("<foo>a<bar>b</bar>c<bar>d</bar>e</foo>");
        doSaveTest("<foo xmlns:x=\"y\"><bar xmlns:x=\"z\"/></foo>");
        doSaveTest("<foo x=\"y\" p=\"r\"/>");

        String s = "<foo>aaa</foo>bbb";
        s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s;
        s = "<bar>xxxx" + s + "</bar>";

        doSaveTest(s);

        XmlObject x =
            XmlObject.Factory.parse("<foo xmlns:a='a.com'><bar xmlns:a='b.com'/></foo>");

        XmlCursor c = x.newCursor();

        c.toFirstChild();
        c.toFirstChild();

        assertEquals("<bar xmlns:a=\"b.com\"/>", c.xmlText());

        x = XmlObject.Factory.parse("<foo xmlns:a='a.com'><bar/></foo>");

        c = x.newCursor();

        c.toFirstChild();
        c.toFirstChild();

        assertEquals("<bar xmlns:a=\"a.com\"/>", c.xmlText());
    }


    private XmlCursor navDoc(XmlObject x, String dirs) {
        return navCursor(x.newCursor(), dirs);
    }

    private XmlCursor navNewCursor(XmlCursor c, String dirs) {
        return navCursor(c.newCursor(), dirs);
    }

    //
    // Format:
    //
    //    ( [-][N] type ) *
    //
    //    type:
    //
    //      c - character
    //      t - token
    //      p - parent element
    //      s - sibling element
    //      d - descendent (child) element
    //      r - end of the doc (root)
    //      b - begin of the doc
    //

    private XmlCursor navCursor(XmlCursor c, String dirs) {
        int n = 0;
        boolean prev = false;

        for (int i = 0; i < dirs.length(); i++) {
            char ch = dirs.charAt(i);

            if (ch == '-') {
                prev = !prev;
                continue;
            } else if (ch >= '0' && ch <= '9') {
                n = n * 10 + (ch - '0');
                continue;
            }

            if (n == 0) {
                n = 1;
            }

            if (ch == 'c') {
                if (prev) {
                    assertEquals(c.toPrevChar(n), n);
                } else {
                    assertEquals(c.toNextChar(n), n);
                }
            } else if (ch == 't') {
                while (n-- > 0) {
                    if (prev) {
                        assertNotSame(c.toPrevToken(), TokenType.NONE);
                    } else {
                        assertNotSame(c.toNextToken(), TokenType.NONE);
                    }
                }
            } else if (ch == 'p') {
                assertFalse(prev);

                while (n-- > 0) {
                    assertTrue(c.toParent());
                }
            } else if (ch == 'r') {
                assertFalse(prev);
                assertEquals(1, n);

                c.toEndDoc();
            } else if (ch == 'b') {
                assertFalse(prev);
                assertEquals(1, n);

                c.toStartDoc();
            } else if (ch == 's') {
                while (n-- > 0) {
                    if (prev) {
                        assertTrue(c.toPrevSibling());
                    } else {
                        assertTrue(c.toNextSibling());
                    }
                }
            } else if (ch == 'd') {
                assertFalse(prev);

                while (n-- > 0) {
                    assertTrue(c.toFirstChild());
                }
            } else {
                fail();
            }

            n = 0;
            prev = false;
        }

        return c;
    }

    @Test
    public void testOps()
        throws Exception {
        XmlObject x, x2, y;
        XmlCursor cFrom, cTo, cTemp, cTemp2, c, d;
        XmlBookmark anno;

        //

        x = XmlObject.Factory.parse("<foo>abcdef</foo>");
        cFrom = navDoc(x, "d");
        cTo = navNewCursor(cFrom, "");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        XmlOptions options = new XmlOptions();

        options.setSaveSyntheticDocumentElement(new QName(null, "bar"));

        assertTrue(
            x.xmlText(options).equals("<bar>[TO]<foo>abcdef</foo>[FROM]</bar>") ||
            x.xmlText(options).equals("<bar>[FROM]<foo>abcdef</foo>[TO]</bar>"));

        //

        x = XmlObject.Factory.parse("<foo>abcdef</foo>");

        cFrom = navDoc(x, "d");
        cTo = navNewCursor(cFrom, "ttt");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertTrue(
            x.xmlText(options).equals("<bar><foo>abcdef</foo>[FROM][TO]</bar>") ||
            x.xmlText(options).equals("<bar><foo>abcdef</foo>[TO][FROM]</bar>"));

        //

        x = XmlObject.Factory.parse("<foo>abcdef</foo>");

        cFrom = navDoc(x, "d");
        cTo = navNewCursor(cFrom, "t3c");
        assertFalse(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<bar>[FROM]<foo>abc[TO]def</foo></bar>", x.xmlText(options));

        //

        x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b></r>");

        cFrom = navDoc(x, "dd");
        cTo = navNewCursor(cFrom, "r-1t");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<r>[FROM]<b>pqr</b><a>xyz</a>[TO]</r>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b>AB</r>");

        cFrom = navDoc(x, "dd");
        cTo = navNewCursor(cFrom, "r-1t-1c");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<r>[FROM]<b>pqr</b>A<a>xyz</a>[TO]B</r>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b>AB</r>");

        cFrom = navDoc(x, "dd");
        cTo = navNewCursor(cFrom, "stc");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<r>[FROM]<b>p<a>xyz</a>[TO]qr</b>AB</r>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b>AB</r>");

        cFrom = navDoc(x, "dd");
        cTo = navDoc(x, "d");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        testTextFrag(x.xmlText(), "<a>xyz</a>[TO]<r>[FROM]<b>pqr</b>AB</r>");

        //

        x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b>AB</r>");

        cFrom = navDoc(x, "dd");
        cTo = navDoc(x, "r");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<bar><r>[FROM]<b>pqr</b>AB</r><a>xyz</a>[TO]</bar>", x.xmlText(options));

        //

        x = XmlObject.Factory.parse("<r><a>xyz</a></r>");
        x2 = XmlObject.Factory.parse("<s></s>");

        cFrom = navDoc(x, "dd");
        cTo = navDoc(x2, "dt");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<r>[FROM]</r>", x.xmlText());
        assertEquals("<s><a>xyz</a>[TO]</s>", x2.xmlText());

        //

        x = XmlObject.Factory.parse("<r><a>pq</a><b></b></r>");

        cFrom = navDoc(x, "dd");
        cTo = navDoc(x, "ddst");
        cTemp = navDoc(x, "ddt1c");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");
        cTemp.insertChars("[TEMP]");

        assertEquals("<r>[FROM][TEMP]<b><a>pq</a>[TO]</b></r>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<foo>abcdef</foo>");

        cFrom = navDoc(x, "2t2c");
        cTo = navNewCursor(cFrom, "-1c");
        cFrom.moveChars(2, cTo);
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<foo>acd[TO]b[FROM]ef</foo>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<foo>abcdef</foo>");

        cFrom = navDoc(x, "2t2c");
        cTo = navNewCursor(cFrom, "3c");
        cFrom.moveChars(2, cTo);
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<foo>ab[FROM]ecd[TO]f</foo>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<bar><foo>abcdef</foo><foo>123456</foo></bar>");

        cFrom = navDoc(x, "3t2c");
        cTo = navNewCursor(cFrom, "3t3c");
        cFrom.moveChars(2, cTo);
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<bar><foo>ab[FROM]ef</foo><foo>123cd[TO]456</foo></bar>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<bar><foo>abcdef</foo><foo>123456</foo></bar>");

        cFrom = navDoc(x, "2d");
        cTo = navDoc(x, "2dst2c");
        assertTrue(cFrom.copyXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals(x.xmlText(),
            "<bar>[FROM]<foo>abcdef</foo><foo>12" +
            "<foo>abcdef</foo>[TO]3456</foo></bar>");

        //

        x = XmlObject.Factory.parse("<r><a>xyz</a></r>");
        x2 = XmlObject.Factory.parse("<s></s>");

        cFrom = navDoc(x, "dd");
        cTo = navDoc(x2, "dt");
        assertTrue(cFrom.copyXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<r>[FROM]<a>xyz</a></r>", x.xmlText());
        assertEquals("<s><a>xyz</a>[TO]</s>", x2.xmlText());

        //

        x = XmlObject.Factory.parse(
            "<bar><foo>abcdef</foo>blah<foo>123456</foo></bar>");

        cFrom = navDoc(x, "2d");
        cTo = navDoc(x, "2dst2c");
        assertTrue(cFrom.copyXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals(x.xmlText(), "<bar>[FROM]<foo>abcdef</foo>blah<foo>12" +
                                  "<foo>abcdef</foo>[TO]3456</foo></bar>");

        //

        x = XmlObject.Factory.parse(
            "<bar><foo x='y'>abcdef</foo><foo>123456</foo>7890</bar>");

        cFrom = navDoc(x, "2dt");
        cTo = navDoc(x, "2dst");
        cTemp = navDoc(x, "2dst3c");
        cTemp2 = navDoc(x, "2ds3t2c");
        assertTrue(cFrom.copyXml(cTo));
        cTemp.insertChars("[TEMP]");
        cTemp2.insertChars("[TEMP2]");

        assertEquals(x.xmlText(),
            "<bar><foo x=\"y\">abcdef</foo>" +
            "<foo x=\"y\">123[TEMP]456</foo>78[TEMP2]90</bar>");

        //

        x = XmlObject.Factory.parse(
            "<bar>xy<foo x='y'>abcdef</foo>pqr<foo>123456</foo></bar>");

        cFrom = navDoc(x, "2d");
        cTo = navDoc(x, "2ds-2c");

        assertTrue(cFrom.removeXml());

        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<bar>xy[FROM]p[TO]qr<foo>123456</foo></bar>", x.xmlText());

        //

        x = XmlObject.Factory.parse(
            "<bar>xy<foo x='y'>abcdef</foo>pqr<foo>123456</foo></bar>");

        cFrom = navDoc(x, "2d2t2c");
        cTo = navDoc(x, "2d2t5c");

        cFrom.removeChars(2);

        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals(x.xmlText(),
            "<bar>xy<foo x=\"y\">ab[FROM]e[TO]f" +
            "</foo>pqr<foo>123456</foo></bar>");

        //

        x = XmlObject.Factory.parse("<bar><!---->abc</bar>");

        cFrom = navDoc(x, "tt");
        cTo = navDoc(x, "tttc");

        assertTrue(cFrom.removeXml());

        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");

        assertEquals("<bar>[FROM]a[TO]bc</bar>", x.xmlText());

        //

        x = XmlObject.Factory.newInstance();

        cTo = navDoc(x, "t");
        cTo.insertElement("boo");
        cTo.toPrevToken();
        cTo.insertElement("moo");
        cTo.toPrevToken();
        cTo.insertElement("goo");

        assertEquals("<boo><moo><goo/></moo></boo>", x.xmlText());

        //

        x = XmlObject.Factory.newInstance();

        cTo = navDoc(x, "t");
        cTo.insertElement("boo");
        cTo.toPrevToken();
        cTo.insertElement("moo");
        cTo.toPrevToken();
        cTo.insertAttributeWithValue("x", "y");

        assertEquals("<boo><moo x=\"y\"/></boo>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<bar x='y'>abc</bar>");
        cTo = navDoc(x, "tt");
        cTo.insertAttributeWithValue("p", "q");

        assertEquals("<bar p=\"q\" x=\"y\">abc</bar>", x.xmlText());

        // Text XmlBookmark

        x = XmlObject.Factory.parse("<r><foo>abc</foo><bar></bar></r>");
        cFrom = navDoc(x, "tt");
        anno = new Anno();
        cFrom.setBookmark(anno);
        cTo = navDoc(x, "6t");
        assertTrue(cFrom.moveXml(cTo));
        cFrom.insertChars("[FROM]");
        cTo.insertChars("[TO]");
        anno.createCursor().insertChars("[ANNO]");

        assertEquals("<r>[FROM]<bar>[ANNO]<foo>abc</foo>[TO]</bar></r>", x.xmlText());

        // Test content ops

        x = XmlObject.Factory.parse("<foo x='y'>abc</foo>");
        y = XmlObject.Factory.newInstance();
        d = y.newCursor();
        d.toNextToken();
        x.newCursor().moveXmlContents(d);
        assertEquals("<foo x=\"y\">abc</foo>", y.xmlText());

        x = XmlObject.Factory.parse("<bar><foo x='y'>abc</foo></bar>");
        y = XmlObject.Factory.newInstance();
        c = x.newCursor();
        c.toNextToken();
        d = y.newCursor();
        d.toNextToken();
        c.moveXmlContents(d);
        assertEquals("<foo x=\"y\">abc</foo>", y.xmlText());

        x = XmlObject.Factory.parse("<bar><foo x='y'>abc</foo></bar>");
        c = x.newCursor();
        c.toNextToken();
        c.removeXmlContents();
        assertEquals("<bar/>", x.xmlText());

        x = XmlObject.Factory.parse("<foo x='y'>abc</foo>");
        y = XmlObject.Factory.newInstance();
        d = y.newCursor();
        d.toNextToken();
        x.newCursor().copyXmlContents(d);
        assertEquals("<foo x=\"y\">abc</foo>", y.xmlText());
    }

    private static class Anno extends XmlBookmark {
    }

    @Test
    public void testSave() throws Exception {
        XmlObject x;
        XmlCursor cTo;

        //

        x = XmlObject.Factory.parse("<foo>abcdef</foo>");

        assertEquals("<foo>abcdef</foo>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<foo>a&lt;b&amp;c</foo>");

        assertEquals("<foo>a&lt;b&amp;c</foo>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<foo></foo>");

        cTo = navDoc(x, "dt");
        cTo.insertChars("&<");

        assertEquals("<foo>&amp;&lt;</foo>", x.xmlText());

        //

        x = XmlObject.Factory.parse("<foo><boo>bar</boo></foo>");

        cTo = navDoc(x, "dt");

        assertEquals("<boo>bar</boo>", cTo.xmlText());

        //

        x = XmlObject.Factory.parse("<foo><boo x=\"y\">bar</boo></foo>");

        cTo = navDoc(x, "dt");

        assertEquals("<boo x=\"y\">bar</boo>", cTo.xmlText());

        // Tests fragment saving and loading

        x = XmlObject.Factory.parse("<foo>Eric</foo>");

        cTo = navDoc(x, "dt");

        x = XmlObject.Factory.parse(cTo.xmlText());

        cTo = navDoc(x, "");

        assertEquals("Eric", cTo.getTextValue());

        // test save where I replace the name of an element

        x = XmlObject.Factory.parse("<foo>Eric</foo>");

        cTo = navDoc(x, "d");

        XmlOptions options = new XmlOptions();

        options.setSaveSyntheticDocumentElement(new QName(null, "bar"));

        x = XmlObject.Factory.parse(cTo.xmlText(options));

        cTo = navDoc(x, "");

        assertEquals("<bar>Eric</bar>", cTo.xmlText());

        // test save where I replace the name of the document

        x = XmlObject.Factory.parse("<foo>Eric</foo>");

        cTo = navDoc(x, "");

        options = new XmlOptions();

        options.setSaveSyntheticDocumentElement(new QName(null, "bar"));

        x = XmlObject.Factory.parse(cTo.xmlText(options));

        cTo = navDoc(x, "");

        assertEquals("<bar><foo>Eric</foo></bar>", cTo.xmlText());

        x = XmlObject.Factory.parse("<a xmlns='foo'/>");

        XmlCursor c = x.newCursor();

        c.toFirstContentToken();
        c.toFirstContentToken();

        c.insertElement("b");
        c.toPrevSibling();
        assertEquals("b", c.getName().getLocalPart());
        assertEquals(0, c.getName().getNamespaceURI().length());

        x = XmlObject.Factory.parse(x.xmlText());

        c = x.newCursor();

        c.toFirstContentToken();
        c.toFirstContentToken();

        assertEquals("b", c.getName().getLocalPart());
        assertEquals(0, c.getName().getNamespaceURI().length());
    }

    private void testTextFrag(String actual, String expected) {
        String pre = "<xml-fragment>";

        String post = "</xml-fragment>";

        assertTrue(actual.startsWith(pre));
        assertTrue(actual.endsWith(post));

        assertEquals(expected, actual.substring(
            pre.length(), actual.length() - post.length()));
    }

    @Test
    public void testSaveFrag() {
        XmlObject x;
        XmlCursor c;

        x = XmlObject.Factory.newInstance();

        c = x.newCursor();

        c.toNextToken();

        c.insertChars("Eric");

        testTextFrag(x.xmlText(), "Eric");

        //

        x = XmlObject.Factory.newInstance();

        c = x.newCursor();

        c.toNextToken();

        c.insertComment("");
        c.insertChars("x");

        testTextFrag(x.xmlText(), "<!---->x");

        //

        x = XmlObject.Factory.newInstance();

        c = x.newCursor();

        c.toNextToken();

        c.insertElement("foo");
        c.insertChars("x");

        testTextFrag(x.xmlText(), "<foo/>x");

        //

        x = XmlObject.Factory.newInstance();

        c = x.newCursor();

        c.toNextToken();

        c.insertElement("foo");
        c.insertElement("bar");

        testTextFrag(x.xmlText(), "<foo/><bar/>");
    }

    @Test
    public void testLoad() throws Exception {
        XmlObject x;

        XmlOptions options = new XmlOptions();
        options.setLoadReplaceDocumentElement(null);

        x =
            XmlObject.Factory.parse(
                "<bar p='q' x='y'>ab<foo>xy</foo>cd</bar>", options);

        XmlCursor c = navDoc(x, "t");

        assertSame(c.currentTokenType(), TokenType.ATTR);

        String open = "xmlns:open='http://www.openuri.org/fragment'";

        x =
            XmlObject.Factory.parse(
                "<open:fragment p='q' x='y' " + open +
                ">ab<foo>xy</foo>cd</open:fragment>");

        c = navDoc(x, "t");

        assertSame(c.currentTokenType(), TokenType.ATTR);
    }

    @Test
    public void testCompare() throws Exception {
        XmlObject x;
        XmlCursor cFrom, cTo;

        // Forward navigation

        x = XmlObject.Factory.parse("<bar p='q' x='y'>ab<foo>xy</foo>cd</bar>");

        cFrom = navDoc(x, "");
        cTo = navDoc(x, "");

        for (; ; ) {
            assertEquals(0, cFrom.comparePosition(cTo));
            assertTrue(cFrom.isAtSamePositionAs(cTo));

            TokenType tt = cFrom.currentTokenType();

            if (tt == TokenType.ENDDOC) {
                break;
            } else if (tt == TokenType.TEXT) {
                cFrom.toNextChar(1);
                cTo.toNextChar(1);
            } else {
                cFrom.toNextToken();
                cTo.toNextToken();
            }
        }

        // Backward navigation

        x = XmlObject.Factory.parse("<bar p='q' x='y'>ab<foo>xy</foo>cd</bar>");

        cFrom = navDoc(x, "r");
        cTo = navDoc(x, "r");

        for (; ; ) {
            assertEquals(0, cFrom.comparePosition(cTo));
            assertTrue(cFrom.isAtSamePositionAs(cTo));

            if (cFrom.toPrevChar(1) == 1) {
                cTo.toPrevChar(1);
            } else if (cFrom.toPrevToken() != TokenType.NONE) {
                cTo.toPrevToken();
            } else {
                break;
            }
        }

        //

        x = XmlObject.Factory.parse(
            "<bar p='q' x='y'>ab<foo>xy</foo>c<f y='x'>xy</f>d</bar>");

        cFrom = navDoc(x, "");

        for (; ; ) {
            boolean passed = false;

            cTo = navDoc(x, "");

            for (; ; ) {
                if (cTo.isAtSamePositionAs(cFrom)) {
                    assertFalse(passed);
                    passed = true;
                } else if (cTo.isLeftOf(cFrom)) {
                    assertFalse(passed);
                } else {
                    assertTrue(passed);
                    assertTrue(cTo.isRightOf(cFrom));
                }

                if (cTo.toNextChar(1) != 1) {
                    if (cTo.toNextToken() == TokenType.ENDDOC) {
                        break;
                    }
                }
            }

            if (cFrom.toNextChar(1) != 1) {
                if (cFrom.toNextToken() == TokenType.ENDDOC) {
                    break;
                }
            }
        }
    }

    @Test
    public void testAttrSetter()
        throws Exception {
        XmlObject x = XmlObject.Factory.parse("<foo/>");
        XmlCursor c = x.newCursor();
        c.toNextToken();
        c.setAttributeText(new QName(null, "x"), "hardehar");
        assertEquals("<foo x=\"hardehar\"/>", x.xmlText());
    }

    @Test
    public void testNavigation()
        throws Exception {
        XmlObject x = XmlObject.Factory.parse("<a><x/><y/><z/></a>");
        XmlCursor c = x.newCursor();
        assertFalse(c.toNextSibling());
        assertFalse(c.toPrevSibling());
        assertFalse(c.toFirstAttribute());
        assertFalse(c.toLastAttribute());
        c.toNextToken();
        c.toNextToken();
        assertTrue(c.toNextSibling());
        assertEquals("y", c.getName().getLocalPart());
        assertTrue(c.toNextSibling());
        assertEquals("z", c.getName().getLocalPart());
        assertFalse(c.toNextSibling());

        x = XmlObject.Factory.parse("<a p='q' m='n'><x/><y/><z/></a>");
        c = x.newCursor();
        c.toNextToken();
        c.toNextToken();
        assertTrue(c.currentTokenType().isAttr());
        assertFalse(c.toPrevSibling());
        assertTrue(c.currentTokenType().isAttr());
        assertTrue(c.toNextSibling());
        assertEquals("x", c.getName().getLocalPart());

        c.toEndDoc();
        c.toPrevToken();
        assertTrue(c.toPrevSibling());
        assertEquals("z", c.getName().getLocalPart());
        assertTrue(c.toPrevSibling());
        assertEquals("y", c.getName().getLocalPart());
        assertTrue(c.toPrevSibling());
        assertEquals("x", c.getName().getLocalPart());
        assertFalse(c.toPrevSibling());

        c.toEndDoc();
        c.toPrevToken();
        assertTrue(c.toParent());
        assertEquals("a", c.getName().getLocalPart());

        c.toEndDoc();
        assertTrue(c.toParent());
        assertTrue(c.currentTokenType().isStartdoc());

        x = XmlObject.Factory.parse("<a>moo<!---->foo</a>");
        c = x.newCursor();
        c.toStartDoc();
        c.toNextToken();
        c.toNextToken();
        c.toNextToken();
        assertTrue(c.toParent());
        assertEquals("a", c.getName().getLocalPart());

        c.toStartDoc();
        c.toNextToken();
        c.toNextToken();
        c.toNextToken();
        c.toNextToken();
        assertTrue(c.toParent());
        assertEquals("a", c.getName().getLocalPart());

        c.toStartDoc();
        c.toNextToken();
        c.toNextToken();
        c.toNextToken();
        c.toNextToken();
        c.toNextChar(2);
        assertTrue(c.toParent());
        assertEquals("a", c.getName().getLocalPart());

        x = XmlObject.Factory.parse("<foo>early<bar>text<char>zap</char></bar></foo>");
        c = x.newCursor();
        c.toNextToken();
        c.toNextToken();
        assertTrue(c.toFirstChild());
        assertEquals("zap", c.getTextValue());
    }

    @Test
    public void testGetName()
        throws Exception {
        XmlObject x = XmlObject.Factory.parse("<a x='y'>eric<!----><?moo?></a>");
        XmlCursor c = x.newCursor();
        assertNull(c.getName());
        assertFalse(c.toNextToken().isNone());
        assertEquals("a", c.getName().getLocalPart());
        assertEquals(0, c.getName().getNamespaceURI().length());
        assertFalse(c.toNextToken().isNone());
        assertEquals("x", c.getName().getLocalPart());
        assertEquals(0, c.getName().getNamespaceURI().length());
        assertFalse(c.toNextToken().isNone());
        assertNull(c.getName());
        assertFalse(c.toNextToken().isNone());
        assertNull(c.getName());
        assertFalse(c.toNextToken().isNone());
        assertEquals("moo", c.getName().getLocalPart());
        assertEquals(0, c.getName().getNamespaceURI().length());
        assertFalse(c.toNextToken().isNone());
        assertNull(c.getName());
        assertFalse(c.toNextToken().isNone());
        assertNull(c.getName());
        assertTrue(c.toNextToken().isNone());
    }

    @Test
    public void testGetChars()
        throws Exception {
        XmlObject x = XmlObject.Factory.parse("<foo>abcdefghijkl</foo>");
        XmlCursor c = x.newCursor();
        c.toNextToken();
        c.toNextToken();
        c.toNextChar(2);

        char[] buf = new char[3];
        int n = c.getChars(buf, 0, 400);

        assertEquals(3, n);
        assertEquals('c', buf[0]);
        assertEquals('d', buf[1]);
        assertEquals('e', buf[2]);
    }

    @Test
    public void testNamespaceSubstitution()
        throws Exception {
        HashMap<String, String> subs = new HashMap<>();
        subs.put("foo", "moo");
        subs.put("a", "b");

        XmlOptions options = new XmlOptions();
        options.setLoadSubstituteNamespaces(subs);

        XmlObject x = XmlObject.Factory.parse("<a xmlns='foo' xmlns:a='a' a:x='y'/>", options);

        XmlCursor c = x.newCursor();

        c.toNextToken();
        assertEquals("moo", c.getName().getNamespaceURI());

        c.toNextToken();
        assertEquals("moo", c.getName().getNamespaceURI());

        c.toNextToken();
        assertEquals("b", c.getName().getNamespaceURI());

        c.toNextToken();
        assertEquals("b", c.getName().getNamespaceURI());
    }

    @Test
    public void testNamespaceInsertion() {
        XmlObject x = XmlObject.Factory.newInstance();

        XmlCursor c = x.newCursor();

        c.toNextToken();
        c.insertElement("foo", "http://p.com");
        c.toPrevToken();
        c.insertNamespace("p", "http://p.com");

        assertEquals("<p:foo xmlns:p=\"http://p.com\"/>", x.xmlText());
    }

    private void dotestParser(String xml, String xmlResult)
        throws Exception {
        XmlObject x = XmlObject.Factory.parse(xml);
        String result = x.xmlText();
        assertEquals(xmlResult, result);
    }

    private void dotestParserErrors(String xml) {
        try {
            XmlObject.Factory.parse(xml);
        } catch (Throwable t) {
            return;
        }

        fail();
    }

    @Test
    public void testNil()
        throws Exception {
        XmlObject x = noNamespace.CanBeNilDocument.Factory.parse("<canBeNil/>");
        XmlCursor c = x.newCursor();
        c.toFirstChild();
        XmlObject fc = c.getObject();
        assertFalse(fc.isNil());
        fc.setNil();
        assertTrue(fc.isNil());
        assertEquals("<canBeNil xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>", x.xmlText());
        c.toNextToken();
        assertTrue(c.isAttr());
        c.removeXml();
        assertEquals("<canBeNil/>", x.xmlText());
        assertFalse(fc.isNil());
    }

    @Test
    public void testParser()
        throws Exception {
        dotestParserErrors("<hee yee='five'><haw>66</haw></any>");
        dotestParserErrors("<foo></moo>");
        dotestParserErrors("<a><foo></moo></a>");
        dotestParserErrors("");
        dotestParserErrors("    ");

        dotestParserErrors("har");
        dotestParserErrors("<!-- comment -->");
        dotestParserErrors("<?moo?>");
        dotestParserErrors("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        dotestParserErrors("<a$/>");
        dotestParserErrors("<foo a='<'></foo>");
        dotestParserErrors("<foo a></foo>");
        dotestParserErrors("<foo>");
        dotestParserErrors("</foo>");
        dotestParserErrors("<foo><!-- -- --></foo>");
        dotestParserErrors("<foo><!-- ---></foo>");

        dotestParser("<a b=\"x\n\ny\"/>", "<a b=\"x  y\"/>");
    }

    @Test
    public void testSaxParser()
        throws Exception {
        String xml = "<a x='y'><!---->x<b/><c p='q'>z</c></a>";

        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();
        InputSource is = new InputSource(new StringReader(xml));
        XmlSaxHandler sh = XmlObject.Factory.newXmlSaxHandler();

        xr.setFeature(
            "http://xml.org/sax/features/namespace-prefixes",
            true);

        xr.setFeature(
            "http://xml.org/sax/features/namespaces", true);

        xr.setFeature(
            "http://xml.org/sax/features/validation", false);

        xr.setContentHandler(sh.getContentHandler());

        xr.setProperty(
            "http://xml.org/sax/properties/lexical-handler",
            sh.getLexicalHandler());

        xr.parse(is);

        XmlObject x1 = sh.getObject();

        XmlObject x2 = XmlObject.Factory.parse(xml);

        assertEquals(x1.xmlText(), x2.xmlText());
    }

    @Test
    public void testAdditionalNamespaces()
        throws Exception {
        String xml = "<a xmlns:a='aNS'><a:b/></a>";

        Map<String, String> map = new LinkedHashMap<>();
        map.put("b", "bNS");
        map.put("c", "cNS");
        map.put("a", "not-aNS");

        XmlOptions options = new XmlOptions();
        options.setLoadAdditionalNamespaces(map);

        XmlObject x = XmlObject.Factory.parse(xml, options);

        // 'a' prefix namespace is not remapped

        xml = "<a xmlns='aNS'><b/></a>";

        map = new LinkedHashMap<>();
        map.put("b", "bNS");
        map.put("c", "cNS");
        map.put("", "not-aNS");

        options = new XmlOptions();
        options.setLoadAdditionalNamespaces(map);

        x = XmlObject.Factory.parse(xml, options);

        // default namespace is not remapped
        String expect = "<a xmlns=\"aNS\" xmlns:b=\"bNS\" xmlns:c=\"cNS\"><b/></a>";
        assertEquals(expect, x.xmlText());

    }


}
