/*   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 misc.detailed;

import dufourrault.DummyDocument;
import dufourrault.Father;
import misc.common.JiraTestBase;
import net.orthogony.xml.sample.structure.ARootDocument;
import net.orthogony.xml.sample.structure.ChildType;
import org.apache.beehive.netui.tools.testrecorder.x2004.session.RecorderSessionDocument;
import org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.tool.Parameters;
import org.apache.xmlbeans.impl.tool.SchemaCompiler;
import org.apache.xmlbeans.impl.xb.xmlconfig.ConfigDocument;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Node;
import test.xbean.xmlcursor.purchaseOrder.PurchaseOrderDocument;
import testDateAttribute.TestDatewTZone;
import testDateAttribute.TestElementWithDateAttributeDocument;
import tools.util.JarUtil;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.util.*;

import static org.junit.jupiter.api.Assertions.*;


public class JiraRegression50_100Test extends JiraTestBase {


    ///**
    // * [XMLBEANS-##]  <BUG TITLE>
    // */
    //public void test_jira_XmlBeans45() throws Exception
    //{
    //
    //}


    /**
     * [XMLBEANS-52]   Validator loops when schema has certain conditions
     */
    @Test
    void test_jira_XmlBeans52() {
        //reusing code from method test_jira_XmlBeans48()
        String correctXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" +
                            "<!--Sample XML file generated by XMLSPY v5 rel. 4 U (http://www.xmlspy.com)--/> \n" +
                            "<aList xmlns=\"http://pfa.dk/dummy/errorInXmlBeansValidation.xsd\" " +
                            "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
                            "xsi:schemaLocation=\"http://pfa.dk/dummy/errorInXmlBeansValidation.xsd \n" +
                            "C:\\pfa\\techr3\\TransformationWorkbench\\schema\\errorInXmlBeansValidation.xsd\"> \n" +
                            "<myListEntry> \n" +
                            "<HelloWorld>Hello World</HelloWorld> \n" +
                            "</myListEntry> \n" +
                            "</aList> ";


    }

    /*
     * [XMLBEANS-54]: problem with default value
     */
    @Test
    void test_jira_xmlbeans54() {
        List<XmlError> errors = new ArrayList<>();

        Parameters params = new Parameters();
        params.setXsdFiles(new File(scompTestFilesRoot + "xmlbeans_54.xsd_"));
        params.setErrorListener(errors);
        params.setSrcDir(schemaCompSrcDir);
        params.setClassesDir(schemaCompClassesDir);
        params.setDownload(true);
        params.setNoPvr(true);

        // Runs out of Heap Memory
        params.setMemoryMaximumSize("1024m");
        params.setMemoryInitialSize("512m");

        SchemaCompiler.compile(params);
    }

    /**
     * [XMLBEANS-56] samples issue with easypo schema and config file
     */
    @Test
    void test_jira_XmlBeans56() throws Exception {
        String xsdConfig = "<xb:config " +
                           " xmlns:xb=\"http://xml.apache.org/xmlbeans/2004/02/xbean/config\"\n" +
                           "    xmlns:ep=\"http://openuri.org/easypo\">\n" +
                           "    <xb:namespace uri=\"http://openuri.org/easypo\">\n" +
                           "        <xb:package>com.easypo</xb:package>\n" +
                           "    </xb:namespace>\n" +
                           "    <xb:namespace uri=\"##any\">\n" +
                           "        <xb:prefix>Xml</xb:prefix>\n" +
                           "        <xb:suffix>Bean</xb:suffix>\n" +
                           "    </xb:namespace>\n" +
                           "    <xb:extension for=\"com.easypo.XmlCustomerBean\">\n" +
                           "        <xb:interface name=\"myPackage.Foo\">\n" +
                           "            <xb:staticHandler>myPackage.FooHandler</xb:staticHandler>\n" +
                           "        </xb:interface>\n" +
                           "    </xb:extension>\n" +
                           "    <xb:qname name=\"ep:purchase-order\" javaname=\"purchaseOrderXXX\"/>\n" +
                           "</xb:config> ";
        ConfigDocument config = ConfigDocument.Factory.parse(xsdConfig);
        xmOpts.setErrorListener(errorList);
        assertTrue(config.validate(xmOpts), "Config File did not validate");
    }

    /**
     * [XMLBEANS-57]   scomp failure for XSD namespace "DAV:"
     */
    @Test
    void test_jira_XmlBeans57() throws Exception {
        String P = File.separator;
        String outputDir = OUTPUTROOT + P + "dav";

        File srcDir = new File(outputDir + P + "src");
        srcDir.mkdirs();
        File classDir = new File(outputDir + P + "classes");
        classDir.mkdirs();

        Parameters params = new Parameters();
        params.setXsdFiles(new File(JIRA_CASES + "xmlbeans_57.xml"));
        params.setErrorListener(errorList);
        params.setSrcDir(srcDir);
        params.setClassesDir(classDir);
        SchemaCompiler.compile(params);
        Collection<XmlError> errs = params.getErrorListener();
        boolean outTextPresent = true;

        for (XmlError o : errs) {
            String out = o.toString();
            System.out.println("Dav: " + out);
            if (out.startsWith("Compiled types to")) {
                outTextPresent = false;
            }
        }

        //cleanup gen'd dirs
        srcDir.deleteOnExit();
        classDir.deleteOnExit();

        if (outTextPresent) {
            System.out.println("No errors when running schemacompiler with DAV namespace");
        } else {
            throw new Exception("There were errors while compiling XSD with DAV " +
                                "namespace. See sys.out for more info");
        }
    }

    /*
     * [XMLBEANS-58]:resolving transitive <redefine>'d types...
     * This is realted to xmlbeans36 - its the same case but the schemas seem to have been updated at the w3c site.
     * Hence adding a new testcase with the new schemas
     */
    @Test
    @Disabled("the url doesn't exist anymore ...")
    public void test_jira_xmlbeans58() throws Exception {
        List<XmlError> errors = new ArrayList<>();
        Parameters params = new Parameters();

        // old url has been retired
        //params.setUrlFiles(new URL[]{new URL("http://devresource.hp.com/drc/specifications/wsrf/interfaces/WS-BrokeredNotification-1-0.wsdl")});
        // this seems to be a url for a WS-BrokeredNotification 1.0 wsdl
        params.setUrlFiles(new URL("http://www.ibm.com/developerworks/library/specification/ws-notification/WS-BrokeredN.wsdl"));
        params.setErrorListener(errors);
        params.setSrcDir(schemaCompSrcDir);
        params.setClassesDir(schemaCompClassesDir);
        params.setDownload(true);

        SchemaCompiler.compile(params);
        assertFalse(hasSevereError(errors));
    }


    /**
     * [XMLBEANS-62]   Avoid class cast exception when compiling older schema namespace
     */
    @Test
    void test_jira_XmlBeans62() throws Exception {
        String P = File.separator;
        String outputDir = "build" + P + "jiratest62";

        File srcDir = new File(outputDir + P + "src");
        srcDir.mkdirs();
        File classDir = new File(outputDir + P + "classes");
        classDir.mkdirs();

        Parameters params = new Parameters();
        params.setWsdlFiles(new File(JIRA_CASES + "xmlbeans_62.xml"));
        params.setErrorListener(errorList);
        params.setSrcDir(srcDir);
        params.setClassesDir(classDir);
        SchemaCompiler.compile(params);
        Collection<XmlError> errs = params.getErrorListener();
        boolean warningPresent = false;
        for (XmlError o : errs) {
            String out = o.toString();
            warningPresent |= out.endsWith("did not have any schema documents in namespace 'http://www.w3.org/2001/XMLSchema'");
        }

        //cleanup gen'd dirs
        srcDir.deleteOnExit();
        classDir.deleteOnExit();

        //validate error present
        assertTrue(warningPresent, "Warning for 1999 schema was not found when compiling srcs");
    }

    /**
     * [XMLBEANS-64] ArrayIndexOutOfBoundsException during validation
     */
    @Test
    void test_jira_XmlBeans64() throws Exception {
        // load the document
        File inst = new File(JIRA_CASES + "xmlbeans_64.xml");
        XmlObject doc = RecorderSessionDocument.Factory.parse(inst);
        // validate
        XmlOptions validateOptions = new XmlOptions();
        validateOptions.setLoadLineNumbers();
        List<XmlError> errorList = new ArrayList<>();
        validateOptions.setErrorListener(errorList);
        boolean isValid = doc.validate(validateOptions);

        if (!isValid) {
            throw new Exception("Errors: " + errorList);
        }
    }

    /**
     * [XMLBEANS-66]   NullPointerException when restricting a union with one of the union members
     */
    @Test
    void test_jira_XmlBeans66() throws Exception {
        String reproXsd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" +
                          "<xsd:schema targetNamespace=\"http://www.w3.org/2003/12/XQueryX\" \n" +
                          "      xmlns=\"http://www.w3.org/2003/12/XQueryX\" \n" +
                          "      xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \n" +
                          "      elementFormDefault=\"qualified\" \n" +
                          "      attributeFormDefault=\"qualified\"> \n" +
                          "  <!-- Kludge for anySimpleType --> \n" +
                          "  <xsd:simpleType name=\"constantValueType\"> \n" +
                          "    <xsd:union memberTypes=\"xsd:integer xsd:decimal xsd:string xsd:double\"/> \n" +
                          "  </xsd:simpleType> \n" +
                          "  <!-- constant expressions. We have 4 different subclasses for this --> \n" +
                          "  <xsd:complexType name=\"constantExpr\"> \n" +
                          "        <xsd:sequence> \n" +
                          "          <xsd:element name=\"value\" type=\"constantValueType\"/> \n" +
                          "        </xsd:sequence> \n" +
                          "  </xsd:complexType> \n" +
                          "  <xsd:complexType name=\"integerConstantExpr\"> \n" +
                          "    <xsd:complexContent> \n" +
                          "      <xsd:restriction base=\"constantExpr\"> \n" +
                          "        <xsd:sequence> \n" +
                          "          <xsd:element name=\"value\" type=\"xsd:integer\"/> \n" +
                          "        </xsd:sequence> \n" +
                          "      </xsd:restriction> \n" +
                          "    </xsd:complexContent> \n" +
                          "  </xsd:complexType>" +
                          "<!-- added for element validation -->" +
                          "<xsd:element name=\"Kludge\" type=\"integerConstantExpr\" />\n" +
                          "</xsd:schema> ";

        SchemaTypeLoader stl = makeSchemaTypeLoader(new String[]{reproXsd});
        QName reproQName = new QName("http://www.w3.org/2003/12/XQueryX", "Kludge");
        SchemaGlobalElement elVal = stl.findElement(reproQName);
        assertTrue((elVal != null), "Element is null or not found");

        String reproInst = "<Kludge xmlns=\"http://www.w3.org/2003/12/XQueryX\"><value>12</value></Kludge>";
        validateInstance(new String[]{reproXsd}, new String[]{reproInst}, null);
    }

    /**
     * [XMLBEANS-68] GDateBuilder outputs empty string when used without time or timezone
     */
    @Test
    void test_jira_XmlBeans68() throws Exception {
        Calendar cal = Calendar.getInstance();
        GDateBuilder gdateBuilder = new GDateBuilder(cal);
        gdateBuilder.clearTime();
        gdateBuilder.clearTimeZone();
        GDate gdate = gdateBuilder.toGDate();
        TestDatewTZone xdate = TestDatewTZone.Factory.newInstance();
        xdate.setGDateValue(gdate);
        TestElementWithDateAttributeDocument doc =
            TestElementWithDateAttributeDocument.Factory.newInstance();
        TestElementWithDateAttributeDocument.TestElementWithDateAttribute root =
            doc.addNewTestElementWithDateAttribute();

        root.xsetSomeDate(xdate);
        System.out.println("Doc: " + doc);
        System.out.println("Date: " + xdate.getStringValue());

        if (xdate.getStringValue().compareTo("") == 0 ||
            xdate.getStringValue().length() <= 1) {
            throw new Exception("Date without TimeZone should not be empty");
        }
        if (root.getSomeDate().getTimeInMillis() != gdate.getCalendar().getTimeInMillis()) {
            throw new Exception("Set Dates were not equal");
        }
    }

    /**
     * This issue needed an elementFormDefault=qualified added to the schema
     * [XMLBEANS-71] when trying to retrieve data from a XMLBean with Input from a XML Document, we cannot get any data from the Bean.
     */
    @Test
    void test_jira_XmlBeans71() throws Exception {
        //schema src lives in cases/xbean/xmlobject/xmlbeans_71.xsd
        abc.BazResponseDocument doc = abc.BazResponseDocument.Factory.parse(JarUtil.getResourceFromJarasFile("xbean/misc/jira/xmlbeans_71.xml"), xmOpts);
        xmOpts.setErrorListener(errorList);
        abc.BazResponseDocument.BazResponse baz = doc.getBazResponse();

        if (!doc.validate(xmOpts)) {
            System.out.println("DOC-ERRORS: " + errorList + "\n" + doc.xmlText());
        } else {
            System.out.println("DOC-XML:\n" + doc.xmlText());
        }

        errorList.clear();
        xmOpts.setErrorListener(errorList);

        if (!baz.validate(xmOpts)) {
            System.out.println("BAZ-ERRORS: " + errorList + "\n" + baz.xmlText());
        }
        //throw new Exception("Response Document did not validate\n"+errorList);
        else {
            System.out.println("BAZ-XML:\n" + baz.xmlText());
        }

        if (baz.getStatus().compareTo("SUCCESS") != 0) {
            throw new Exception("Status was not loaded properly");
        } else {
            System.out.println("Sucess was received correctly");
        }
    }


    /**
     * [XMLBEANS-72]   Document properties are lost
     */
    @Test
    @Disabled
    public void test_jira_XmlBeans72() throws Exception {
        String docTypeName = "struts-config";
        String docTypePublicID = "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN";
        String docTypeSystemID = "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd";
        String fileName = "xmlbeans72.xml";

        //create instance and set doc properties
        PurchaseOrderDocument po = PurchaseOrderDocument.Factory.newInstance();
        org.apache.xmlbeans.XmlDocumentProperties docProps = po.documentProperties();
        docProps.setDoctypeName(docTypeName);
        docProps.setDoctypePublicId(docTypePublicID);
        docProps.setDoctypeSystemId(docTypeSystemID);
        po.addNewPurchaseOrder();
        po.save(new File(fileName));

        //parse saved out file and verify values set above are present
        PurchaseOrderDocument po2 = PurchaseOrderDocument.Factory.parse(new File(fileName));
        //XmlObject po2 = XmlObject.Factory.parse(new File(fileName));

        org.apache.xmlbeans.XmlDocumentProperties doc2Props = po2.documentProperties();

        //verify information using DOM
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(false);
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File(fileName));

        DocumentType docType = document.getDoctype();

        //System.out.println("Name: "+ doc2Props.getDoctypeName() +" = " + docType.getName());
        //System.out.println("System: "+ doc2Props.getDoctypeSystemId() + " = " + docType.getSystemId());
        //System.out.println("Public: "+ doc2Props.getDoctypePublicId()+ " = " + docType.getPublicId());

        StringBuilder compareText = new StringBuilder();
        //check values - compare to expected and DOM
        if (doc2Props != null) {
            if (doc2Props.getDoctypeName() == null ||
                doc2Props.getDoctypeName().compareTo(docTypeName) != 0 ||
                doc2Props.getDoctypeName().compareTo(docType.getName()) != 0) {
                compareText.append("docTypeName was not as expected in the document properties ").append(doc2Props.getDoctypeName()).append("\n");
            }

            if (doc2Props.getDoctypePublicId() == null ||
                doc2Props.getDoctypePublicId().compareTo(docTypePublicID) != 0 ||
                doc2Props.getDoctypePublicId().compareTo(docType.getPublicId()) != 0) {
                compareText.append("docTypePublicID was not as expected in the document properties ").append(doc2Props.getDoctypePublicId()).append("\n");
            }

            if (doc2Props.getDoctypeSystemId() == null ||
                doc2Props.getDoctypeSystemId().compareTo(docTypeSystemID) != 0 ||
                doc2Props.getDoctypeSystemId().compareTo(docType.getSystemId()) != 0) {
                compareText.append("docTypeSystemID was not as expected in the document properties ").append(doc2Props.getDoctypeSystemId()).append("\n");
            }
        } else {
            compareText.append("Document Properties were null, should have been set");
        }

        //cleanup
        new File(fileName).deleteOnExit();

        if (compareText.toString().length() > 1) {
            throw new Exception("Doc properties were not saved or read correctly\n" + compareText);
        }
    }

    /**
     * BUGBUG: XMLBEANS-78 - NPE when processing XMLStreamReader Midstream
     * XMLBEANS-78 - NPE when processing XMLStreamReader Midstream
     */
    @Test
    void test_jira_xmlbeans78() throws Exception {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        FileInputStream fis = new FileInputStream(JIRA_CASES + "xmlbeans_78.xml");
        XMLStreamReader reader = factory.createXMLStreamReader(fis);
        skipToBody(reader);
        XmlObject.Factory.parse(reader);
    }

    /**
     * Move reader to element of SOAP Body
     */
    private void skipToBody(XMLStreamReader reader) throws javax.xml.stream.XMLStreamException {
        while (true) {
            int event = reader.next();
            switch (event) {
                case XMLStreamReader.END_DOCUMENT:
                    return;
                case XMLStreamReader.START_ELEMENT:
                    if (reader.getLocalName().equals("Body")) {
                        return;
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * Repro case for jira issue
     * XMLBEANS-80  problems in XPath selecting with namespaces and Predicates.
     */
    @Test
    void test_jira_xmlbeans80() throws Exception {
        String xpathDoc = "<?xml version=\"1.0\"?> \n" +
                          "<doc xmlns:ext=\"http://somebody.elses.extension\"> \n" +
                          "  <ext:a test=\"test\" /> \n" +
                          "  <b attr1=\"a1\" attr2=\"a2\" \n" +
                          "  xmlns:java=\"http://xml.apache.org/xslt/java\"> \n" +
                          "    <a> \n" +
                          "    </a> \n" +
                          "  </b> \n" +
                          "</doc> ";
        XmlObject xb80 = XmlObject.Factory.parse(xpathDoc);
        // change $this to '.' to avoid XQuery syntax error for $this not being declared
        //XmlObject[] resSet = xb80.selectPath("declare namespace " +
        //        "ext='http://somebody.elses.extension'; $this//ext:a[@test='test']");

        XmlObject[] resSet = xb80.selectPath("declare namespace " +
                                             "ext='http://somebody.elses.extension'; .//ext:a[@test='test']");


        assertEquals(1, resSet.length);
        System.out.println("Result was: " + resSet[0].xmlText());
    }

    /**
     * Repro case for jira issue
     * XMLBEANS-81  Cursor selectPath() method not working with predicates
     */
    @Test
    void test_jira_xmlbeans81() throws Exception {
        String xpathDoc = "<MatchedRecords>" +
                          "  <MatchedRecord>" +
                          "     <TableName>" +
                          "ABC" +
                          "</TableName>" +
                          "  </MatchedRecord>" +
                          "  <MatchedRecord>" +
                          "     <TableName>\n" +
                          "       BCD \n" +
                          "     </TableName> \n" +
                          "  </MatchedRecord> \n" +
                          "</MatchedRecords> ";
        XmlObject xb81 = XmlObject.Factory.parse(xpathDoc);
        // change $this to '.' to avoid XQuery syntax error for $this not being declared
        //XmlObject[] resSet = xb81.selectPath("$this//MatchedRecord[TableName=\"ABC\"]/TableName");
        XmlObject[] resSet = xb81.selectPath(".//MatchedRecord[TableName=\"ABC\"]/TableName");
        assertEquals(resSet.length, 1);
        try (XmlCursor cursor = xb81.newCursor()) {
            //cursor.selectPath("$this//MatchedRecord[TableName=\"ABC\"]/TableName");
            cursor.selectPath(".//MatchedRecord[TableName=\"ABC\"]/TableName");
        }
    }

    /**
     * XMLBeans-84 Cannot run XmlObject.selectPath using Jaxen in multi threaded environment
     */
    @Test
    void test_jira_XmlBeans84() throws Exception {
        XPathThread[] threads = new XPathThread[15];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new XPathThread();
            System.out.println("Thread[" + i + "]-starting ");
            threads[i].start();
        }

        Thread.sleep(6000);
        System.out.println("Done with XPaths?...");

        for (XPathThread thread : threads) {
            assertNull(thread.getException());
        }

    }

    /*
     * [XMLBEANS-88]:Cannot compile eBay schema
     */
    @Disabled
    @Test
    void test_jira_xmlbeans88() throws Exception {
        List<XmlError> errors = new ArrayList<>();
        Parameters params = new Parameters();

        params.setUrlFiles(new URL("http://developer.ebay.com/webservices/latest/eBaySvc.wsdl"));
        params.setErrorListener(errors);
        params.setSrcDir(schemaCompSrcDir);
        params.setClassesDir(schemaCompClassesDir);
        params.setDownload(true);

        // ignore unique particle rule in order to compile this schema
        params.setNoUpa(true);

        // runs out of memory..
        params.setMemoryMaximumSize("512m");

        try {
            SchemaCompiler.compile(params);
        } catch (java.lang.OutOfMemoryError ome) {
            System.out.println(ome.getCause());
            System.out.println(ome.getMessage());
            System.out.println(ome.getStackTrace());
            Assertions.fail("test_jira_xmlbeans88(): Out Of Memory Error");
        } catch (Throwable t) {
            t.getMessage();
            System.out.println("Ok Some Exception is caught here");
        }

        assertFalse(hasSevereError(errors));
    }

    /**
     * [XMLBEANS-96]:XmlDocumentProperties missing version and encoding
     */
    @Test
    @Disabled
    public void test_jira_xmlbeans96() throws Exception {
        String xmlstringbuf =
            "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" +
            "<test>" +
            "<testchild attr=\"abcd\"> Jira02 </testchild>" +
            "</test>";

        XmlObject doc = XmlObject.Factory.parse(xmlstringbuf);
        XmlDocumentProperties props = doc.documentProperties();
        assertEquals("1.0", props.getVersion(), "test_jira_xmlbeans96() : Xml Version is not picked up");
        assertEquals("UTF-8", props.getEncoding(), "test_jira_xmlbeans96() : Xml Encoding is not picked up");

    }

    /**
     * [XMLBEANS-98]   setSaveSuggestedPrefixes doesn't
     * work for QName attribute values
     */
    @Test
    @Disabled
    public void test_jira_xmlbeans98() throws Exception {
        String outfn = outputroot + "xmlbeans_98.xml";
        String structnamespace = "http://www.orthogony.net/xml/sample/structure";
        String datanamespace = "http://www.orthogony.net/xml/sample/data";
        String schemaloc = "xmlbeans_98.xsd";
        String xsinamespace = "http://www.w3.org/2001/XMLSchema-instance";

        File out = new File(outfn);
        XmlOptions options = new XmlOptions();

        // associate namespaces with prefixes
        Map<String, String> prefixes = new HashMap<>();
        prefixes.put(structnamespace, "s");
        prefixes.put(datanamespace, "d");
        prefixes.put(xsinamespace, "v");
        options.setSaveSuggestedPrefixes(prefixes);
        options.setSavePrettyPrint();

        // create a sample document
        ARootDocument doc = ARootDocument.Factory.newInstance();
        ARootDocument.ARoot root = doc.addNewARoot();
        ChildType child = root.addNewAChild();
        // This is where the prefix map should take effect
        child.setQualifiedData(new QName(datanamespace, "IAmQualified"));

        // Add a schema location attribute to the doc element
        try (XmlCursor c = root.newCursor()) {
            c.toNextToken();
            c.insertAttributeWithValue("schemaLocation", xsinamespace,
                structnamespace + " " + schemaloc);
        }

        //String expXML = doc.xmlText(options.setSavePrettyPrint())
        // save as XML text using the options
        //System.out.println("OUT: \n"+doc.xmlText());
        //doc.save(out, options);
        doc.save(out, options);
        XmlObject xObj = XmlObject.Factory.parse(out);

        String expXText =
            "<s:a-root v:schemaLocation=\"http://www.orthogony.net/xml/sample/structure xmlbeans_98.xsd\" xmlns:s=\"http://www.orthogony.net/xml/sample/structure\" xmlns:v=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
            "  <s:a-child qualified-data=\"data:IAmQualified\" xmlns:data=\"http://www.orthogony.net/xml/sample/data\"/>\n" +
            "</s:a-root>";
        XmlObject.Factory.parse(doc.xmlText());
        System.out.println("xObj: " + xObj.xmlText());
        //NamedNodeMap n = xObj.getDomNode().getAttributes();
        //Assert.assertTrue("Length was not as expected", n.getLength() == 3);
        Node no = xObj.getDomNode();//n.getNamedItem("a-root");
        assertEquals(0, no.getPrefix().compareTo("s"), "Expected Prefix was not present: " + no.getPrefix());
        //Assert.assertTrue("s prefix was not found " + no.lookupPrefix(structnamespace), no.lookupPrefix(structnamespace).compareTo("s") == 0);
        //Assert.assertTrue("d prefix was not found " + no.lookupPrefix(datanamespace), no.lookupPrefix(datanamespace).compareTo("s") == 0);
        //Assert.assertTrue("v prefix was not found " + no.lookupPrefix(xsinamespace), no.lookupPrefix(xsinamespace).compareTo("s") == 0);


        // throw new Exception(out.getCanonicalPath());

    }

    /**
     * [XMLBEANS-99]   NPE/AssertionFailure in newDomNode()
     */
    @Test
    void test_jira_xmlbeans99_a() throws Exception {
        //typed verification
        DummyDocument doc = DummyDocument.Factory.parse(new File(JIRA_CASES + "xmlbeans_99.xml"));
        org.w3c.dom.Node node = doc.newDomNode();
        System.out.println("node = " + node);
        //UnTyped Verification
        XmlObject xObj = XmlObject.Factory.parse(new File(JIRA_CASES +
                                                          "xmlbeans_99.xml"));
        org.w3c.dom.Node xNode = xObj.newDomNode();
        System.out.println("xNode: " + xNode);
    }

    /*
     * [XMLBEANS-99]: NPE/AssertionFailure in newDomNode()
     * refer to [XMLBEANS-14]
     */
    @Test
    void test_jira_xmlbeans99_b() throws XmlException {
        String xmlstringbuf =
            "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?> \n" +
            "<x:dummy xmlns:x=\"http://dufourrault\" xmlns:xsi=\"http://www.w3.org/2000/10/XMLSchema-instance\" xsi:SchemaLocation=\"dummy.xsd\">\n" +
            "    <x:father>\n" +
            "        <x:son>toto</x:son> \n" +
            "    </x:father>\n" +
            "</x:dummy>";

        //From empty instance
        DummyDocument newDoc = DummyDocument.Factory.newInstance();
        DummyDocument.Dummy newDummy = newDoc.addNewDummy();
        Node newNode = newDummy.newDomNode();
        assertNotNull(newNode);

        //set Item
        DummyDocument new2Doc = DummyDocument.Factory.newInstance();
        DummyDocument.Dummy new2Dummy = new2Doc.addNewDummy();
        Father newFather = Father.Factory.newInstance();
        newFather.setSon("son");
        new2Dummy.setFather(newFather);
        Node new2Node = new2Dummy.newDomNode();
        assertNotNull(new2Node);

        //With Loaded instance Document
        DummyDocument doc = DummyDocument.Factory.parse(xmlstringbuf);
        Node node = doc.newDomNode();
        assertNotNull(node);
        //Just Element Type Node
        dufourrault.DummyDocument.Dummy dummy = doc.addNewDummy();
        Node typeNode = dummy.newDomNode();
        assertNotNull(typeNode);

        dufourrault.Father fatherType = Father.Factory.newInstance();
        fatherType.setSon("son");
        Node fatherTypeNode = fatherType.newDomNode();
        assertNotNull(fatherTypeNode);
    }


    /**
     * For Testing jira issue 84
     */
    public static class XPathThread extends TestThread {
        public XPathThread() {
            super();
        }

        public void run() {

            try {
                for (int i = 0; i < ITERATION_COUNT; i++) {
                    switch (i % 2) {
                        case 0:
                            runStatusXPath();
                            break;
                        case 1:
                            runDocXPath();
                            break;
                        default:
                            System.out.println("Val: " + i);
                            break;
                    }

                }
                _result = true;

            } catch (Throwable t) {
                _throwable = t;
                t.printStackTrace();
            }
        }

        public void runStatusXPath() {
            try {
                System.out.println("Testing Status");
                String statusDoc = "<statusreport xmlns=\"http://openuri.org/enumtest\">\n" +
                                   "  <status name=\"first\" target=\"all\">all</status>\n" +
                                   "  <status name=\"second\" target=\"all\">few</status>\n" +
                                   "  <status name=\"third\" target=\"none\">most</status>\n" +
                                   "  <status name=\"first\" target=\"none\">none</status>\n" +
                                   "</statusreport>";
                XmlObject path = XmlObject.Factory.parse(statusDoc, xm);
                XmlObject[] resSet = path.selectPath("//*:status");
                assertEquals(4, resSet.length, resSet.length + "");
                resSet = path.selectPath("//*:status[@name='first']");
                assertEquals(2, resSet.length);

            } catch (Throwable t) {
                _throwable = t;
                t.printStackTrace();
            }
        }

        public void runDocXPath() {
            try {
                System.out.println("Testing Doc");
                String docDoc = "<?xml version=\"1.0\"?>\n" +
                                "<doc xmlns:ext=\"http://somebody.elses.extension\">\n" +
                                "  <a test=\"test\" />\n" +
                                "  <b attr1=\"a1\" attr2=\"a2\"   \n" +
                                "  xmlns:java=\"http://xml.apache.org/xslt/java\">\n" +
                                "    <a>\n" +
                                "    </a> \n" +
                                "  </b>\n" +
                                "</doc><!-- -->  ";
                XmlObject path = XmlObject.Factory.parse(docDoc, xm);
                XmlObject[] resSet = path.selectPath("//a");
                assertEquals(2, resSet.length);
                resSet = path.selectPath("//b[@attr2]");
                assertEquals(1, resSet.length);

            } catch (Throwable t) {
                _throwable = t;
                t.printStackTrace();
            }
        }
    }
}

