/*
 * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     rbarkhouse - 2.1 - initial implementation
package org.eclipse.persistence.testing.jaxb.dynamic;

import java.io.*;
import java.lang.reflect.UndeclaredThrowableException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
import org.eclipse.persistence.testing.jaxb.dynamic.util.CustomEntityResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import junit.framework.TestCase;


public class DynamicJAXBFromXSDTestCases extends TestCase {

    DynamicJAXBContext jaxbContext;
    protected static final String tmpdir = System.getenv("T_WORK") == null
            ? System.getProperty("java.io.tmpdir") : System.getenv("T_WORK");

    static {
        try {
            // Disable XJC's schema correctness check.  XSD imports do not seem to work if this is left on.
            System.setProperty("com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.noCorrectnessCheck", "true");
        } catch (Exception e) {
            // Ignore
        }
    }

    public DynamicJAXBFromXSDTestCases(String name) throws Exception {
        super(name);
    }

    @Override
    public String getName() {
        return "Dynamic JAXB: XSD: " + super.getName();
    }

    // EclipseLink requires JDK >= 1.7
    public void testEclipseLinkSchema() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(ECLIPSELINK_SCHEMA);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);
    }

    // ====================================================================

    public void testXmlSchemaQualified() throws Exception {
        // <xs:schema targetNamespace="myNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"
        //      attributeFormDefault="qualified" elementFormDefault="qualified">

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSCHEMA_QUALIFIED);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("id", 456);
        person.set("name", "Bob Dobbs");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        // Make sure "targetNamespace" was interpreted properly.
        Node node = marshalDoc.getChildNodes().item(0);
        assertEquals("Target Namespace was not set as expected.", "myNamespace", node.getNamespaceURI());

        // Make sure "elementFormDefault" was interpreted properly.
        // elementFormDefault=qualified, so the root node, the
        // root node's attribute, and the child node should all have a prefix.
        assertNotNull("Root node did not have namespace prefix as expected.", node.getPrefix());

        Node attr = node.getAttributes().item(0);
        assertNotNull("Attribute did not have namespace prefix as expected.", attr.getPrefix());

        Node childNode = node.getChildNodes().item(0);
        assertNotNull("Child node did not have namespace prefix as expected.", childNode.getPrefix());
    }

    public void testXmlSchemaUnqualified() throws Exception {
        // <xs:schema targetNamespace="myNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"
        //      attributeFormDefault="unqualified" elementFormDefault="unqualified">

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSCHEMA_UNQUALIFIED);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("id", 456);
        person.set("name", "Bob Dobbs");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        // Make sure "targetNamespace" was interpreted properly.
        Node node = marshalDoc.getChildNodes().item(0);
        assertEquals("Target Namespace was not set as expected.", "myNamespace", node.getNamespaceURI());

        // Make sure "elementFormDefault" was interpreted properly.
        // elementFormDefault=unqualified, so the root node should have a prefix
        // but the root node's attribute and child node should not.
        assertNotNull("Root node did not have namespace prefix as expected.", node.getPrefix());

        // Do not test attribute prefix with the Oracle xmlparserv2, it qualifies attributes by default.
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        if (builderFactory.getClass().getPackage().getName().contains("oracle")) {
            return;
        } else {
            Node attr = node.getAttributes().item(0);
            assertNull("Attribute should not have namespace prefix (" + attr.getPrefix() + ").", attr.getPrefix());
        }

        Node childNode = node.getChildNodes().item(0);
        assertNull("Child node should not have namespace prefix.", childNode.getPrefix());
    }

    public void testXmlSchemaDefaults() throws Exception {
        // <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSCHEMA_DEFAULTS);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(DEF_PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("id", 456);
        person.set("name", "Bob Dobbs");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        // "targetNamespace" should be null by default
        Node node = marshalDoc.getChildNodes().item(0);
        assertNull("Target Namespace was not null as expected.", node.getNamespaceURI());

        // Make sure "elementFormDefault" was interpreted properly.
        // When unset, no namespace qualification is done.
        assertNull("Root node should not have namespace prefix.", node.getPrefix());

        Node attr = node.getAttributes().item(0);
        assertNull("Attribute should not have namespace prefix.", attr.getPrefix());

        Node childNode = node.getChildNodes().item(0);
        assertNull("Child node should not have namespace prefix.", childNode.getPrefix());
    }

    public void testXmlSchemaImport() throws Exception {
        // <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        //       <xs:import schemaLocation="xmlschema-currency" namespace="bankNamespace"/>

        // Do not run this test with the Oracle xmlparserv2, it will not properly hit the EntityResolver
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        if (builderFactory.getClass().getPackage().getName().contains("oracle")) {
            return;
        }

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSCHEMA_IMPORT);

        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, new CustomEntityResolver(false), null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        DynamicEntity salary = jaxbContext.newDynamicEntity(BANK_PACKAGE + "." + CDN_CURRENCY);
        assertNotNull("Could not create Dynamic Entity.", salary);

        salary.set("value", new BigDecimal(75425.75));

        person.set("name", "Bob Dobbs");
        person.set("salary", salary);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);

        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);

        // Nothing to really test, if the import failed we couldn't have created the salary.
    }

    public void testXmlSeeAlso() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSEEALSO);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + EMPLOYEE);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("name", "Bob Dobbs");
        person.set("employeeId", "CA2472");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement<DynamicEntity> jbe = new JAXBElement<DynamicEntity>(new QName("root"), DynamicEntity.class, person);

        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);

        // Nothing to really test, XmlSeeAlso isn't represented in an instance doc.
    }

    public void testXmlRootElement() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLROOTELEMENT);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + INDIVIDUO);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("name", "Bob Dobbs");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getChildNodes().item(0);

        assertEquals("Root element was not 'individuo' as expected.", "individuo", node.getLocalName());
    }

    public void testXmlType() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLTYPE);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);


        person.set("email", "bdobbs@subgenius.com");
        person.set("lastName", "Dobbs");
        person.set("id", 678);
        person.set("phoneNumber", "212-555-8282");
        person.set("firstName", "Bob");

        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);

        // Test that XmlType.propOrder was interpreted properly
        Node node = marshalDoc.getDocumentElement().getChildNodes().item(0);
        assertNotNull("Node was null.", node);
        assertEquals("Unexpected node.", "id", node.getLocalName());

        node = marshalDoc.getDocumentElement().getChildNodes().item(1);
        assertNotNull("Node was null.", node);
        assertEquals("Unexpected node.", "first-name", node.getLocalName());

        node = marshalDoc.getDocumentElement().getChildNodes().item(2);
        assertNotNull("Node was null.", node);
        assertEquals("Unexpected node.", "last-name", node.getLocalName());

        node = marshalDoc.getDocumentElement().getChildNodes().item(3);
        assertNotNull("Node was null.", node);
        assertEquals("Unexpected node.", "phone-number", node.getLocalName());

        node = marshalDoc.getDocumentElement().getChildNodes().item(4);
        assertNotNull("Node was null.", node);
        assertEquals("Unexpected node.", "email", node.getLocalName());
    }

    public void testXmlAttribute() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLATTRIBUTE);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("id", 777);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);

        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);

        Node node = marshalDoc.getChildNodes().item(0);

        if (node.getAttributes() == null || node.getAttributes().getNamedItem("id") == null) {
            fail("Attribute not present.");
        }
    }

    public void testXmlElement() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLELEMENT);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("type", "O+");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);

        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);

        Node node = marshalDoc.getDocumentElement();

        assertNotNull("Element not present.", node.getChildNodes());

        String elemName = node.getChildNodes().item(0).getNodeName();
        assertEquals("Element not present.", "type", elemName);
    }

    public void testXmlElementCollection() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLELEMENTCOLLECTION);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        ArrayList nicknames = new ArrayList();
        nicknames.add("Bobby");
        nicknames.add("Dobsy");
        nicknames.add("Big Kahuna");

        person.set("nickname", nicknames);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);

        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);

        Node node = marshalDoc.getDocumentElement();

        assertNotNull("Element not present.", node.getChildNodes());
        assertEquals("Unexpected number of child nodes present.", 3, node.getChildNodes().getLength());
    }

    public void testXmlElementCustomized() throws Exception {
        // Customize the EclipseLink mapping generation by providing an eclipselink-oxm.xml

        String metadataFile = RESOURCE_DIR + "eclipselink-oxm.xml";
        InputStream iStream = ClassLoader.getSystemResourceAsStream(metadataFile);
        HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
        metadataSourceMap.put(CONTEXT_PATH, new StreamSource(iStream));
        Map<String, Object> props = new HashMap<String, Object>();
        props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, metadataSourceMap);

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLELEMENT);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, props);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("type", "O+");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getDocumentElement();

        assertNotNull("Element not present.", node.getChildNodes());

        String elemName = node.getChildNodes().item(0).getNodeName();

        // 'type' was renamed to 'bloodType' in the OXM bindings file
        assertEquals("Element not present.", "bloodType", elemName);
    }

    public void testXmlList() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLLIST);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        ArrayList<String> codes = new ArrayList<String>(3);
        codes.add("D1182");
        codes.add("D1716");
        codes.add("G7212");

        person.set("name", "Bob Dobbs");
        person.set("codes", codes);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getDocumentElement();

        assertEquals("Unexpected number of nodes in document.", 2, node.getChildNodes().getLength());

        String value = node.getChildNodes().item(1).getTextContent();

        assertEquals("Unexpected element contents.", "D1182 D1716 G7212", value);
    }

    public void testXmlValue() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLVALUE);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        DynamicEntity salary = jaxbContext.newDynamicEntity(PACKAGE + "." + CDN_CURRENCY);
        assertNotNull("Could not create Dynamic Entity.", salary);

        salary.set("value", new BigDecimal(75100));

        person.set("name", "Bob Dobbs");
        person.set("salary", salary);
        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);

        // Nothing to really test, XmlValue isn't represented in an instance doc.
    }

    public void testXmlAnyElement() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLANYELEMENT);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("name", "Bob Dobbs");
        person.set("any", "StringValue");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getDocumentElement();

        assertTrue("Any element not found.", node.getChildNodes().item(1).getNodeType() == Node.TEXT_NODE);
    }

    public void testXmlAnyAttribute() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLANYATTRIBUTE);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        Map<QName, Object> otherAttributes = new HashMap<QName, Object>();
        otherAttributes.put(new QName("foo"), new BigDecimal(1234));
        otherAttributes.put(new QName("bar"), Boolean.FALSE);

        person.set("name", "Bob Dobbs");
        person.set("otherAttributes", otherAttributes);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getDocumentElement();
        Node otherAttributesNode = node.getAttributes().getNamedItem("foo");
        assertNotNull("'foo' attribute not found.", otherAttributesNode);
        otherAttributesNode = node.getAttributes().getNamedItem("bar");
        assertNotNull("'bar' attribute not found.", otherAttributesNode);
    }

    public void testXmlMixed() throws Exception {
        // Also tests XmlElementRef / XmlElementRefs

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLMIXED);

        try {
            jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);
        } catch (JAXBException e) {
            // If running in a non-JAXB 2.2 environment, we will get this error because the required() method
            // on @XmlElementRef is missing.  Just ignore this and pass the test.
            if (e.getLinkedException() instanceof UndeclaredThrowableException) {
                return;
            } else {
                throw e;
            }
        } catch (Exception e) {
            if (e instanceof UndeclaredThrowableException) {
                return;
            } else {
                throw e;
            }
        }

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        ArrayList list = new ArrayList();
        list.add("Hello");
        list.add(new JAXBElement<String>(new QName("myNamespace", "title"), String.class, person.getClass(), "MR"));
        list.add(new JAXBElement<String>(new QName("myNamespace", "name"), String.class, person.getClass(), "Bob Dobbs"));
        list.add(", your point balance is");
        list.add(new JAXBElement<BigInteger>(new QName("myNamespace", "rewardPoints"), BigInteger.class, person.getClass(), BigInteger.valueOf(175)));
        list.add("Visit www.rewards.com!");
        person.set("content", list);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getDocumentElement();

        assertTrue("Unexpected number of elements.", node.getChildNodes().getLength() == 6);
    }

    public void testXmlId() throws Exception {
        // Tests both XmlId and XmlIdRef

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLID);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity data = jaxbContext.newDynamicEntity(PACKAGE + "." + DATA);
        assertNotNull("Could not create Dynamic Entity.", data);
        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);
        DynamicEntity company = jaxbContext.newDynamicEntity(PACKAGE + "." + COMPANY);
        assertNotNull("Could not create Dynamic Entity.", company);

        company.set("name", "ACME International");
        company.set("address", "165 Main St, Anytown US, 93012");
        company.set("id", "882");

        person.set("name", "Bob Dobbs");
        person.set("company", company);

        data.set("person", person);
        data.set("company", company);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(data, marshalDoc);

        // 'person' node
        Node pNode = marshalDoc.getDocumentElement().getChildNodes().item(0);
        // 'company' node
        Node cNode = pNode.getChildNodes().item(1);

        // If IDREF worked properly, the company element should only contain the id of the company object
        assertEquals("'company' has unexpected number of child nodes.", 1, cNode.getChildNodes().getLength());
    }

    public void testXmlElements() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLELEMENTS);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        ArrayList list = new ArrayList(1);
        list.add("BOB");
        person.set("nameOrReferenceNumber", list);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getDocumentElement().getChildNodes().item(0);

        assertEquals("Unexpected element name.", "name", node.getNodeName());

        person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        list = new ArrayList(1);
        list.add(328763);
        person.set("nameOrReferenceNumber", list);
        marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);
        node = marshalDoc.getDocumentElement().getChildNodes().item(0);

        assertEquals("Unexpected element name.", "reference-number", node.getNodeName());
    }

    public void testXmlElementRef() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLELEMENTREF);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        ArrayList list = new ArrayList(1);
        list.add("BOB");
        person.set("nameOrReferenceNumber", list);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getDocumentElement().getChildNodes().item(0);

        assertEquals("Unexpected element name.", "name", node.getNodeName());

        person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        list = new ArrayList(1);
        list.add(328763);
        person.set("nameOrReferenceNumber", list);
        marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);
        node = marshalDoc.getDocumentElement().getChildNodes().item(0);

        assertEquals("Unexpected element name.", "reference-number", node.getNodeName());
    }

    public void testXmlSchemaType() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSCHEMATYPE);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("dateOfBirth", DatatypeFactory.newInstance().newXMLGregorianCalendarDate(1976, 02, 17, DatatypeConstants.FIELD_UNDEFINED));

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        Node node = marshalDoc.getDocumentElement().getChildNodes().item(0);

        assertEquals("Unexpected date value.", "1976-02-17", node.getTextContent());
    }

    public void testXmlEnum() throws Exception {
        // Tests XmlEnum and XmlEnumValue

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLENUM);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        Object NORTH = jaxbContext.getEnumConstant(PACKAGE + "." + COMPASS_DIRECTION, NORTH_CONSTANT);
        assertNotNull("Could not find enum constant.", NORTH);

        person.set("quadrant", NORTH);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);
    }

    public void testXmlEnumBig() throws Exception {
        // Tests XmlEnum and XmlEnumValue
        // This test schema contains >128 enum values to test an ASM boundary case

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLENUM_BIG);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        Object EST = jaxbContext.getEnumConstant(DEF_PACKAGE + "." + TIME_ZONE, EST_CONSTANT);
        assertNotNull("Could not find enum constant.", EST);
    }

    public void testXmlEnumError() throws Exception {
        // Tests XmlEnum and XmlEnumValue

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLENUM);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        Exception caughtException = null;
        try {
            Object NORTHWEST = jaxbContext.getEnumConstant(PACKAGE + "." + COMPASS_DIRECTION, "NORTHWEST");
        } catch (Exception e) {
            caughtException = e;
        }

        assertNotNull("Expected exception was not thrown.", caughtException);
    }

    public void testXmlElementDecl() throws Exception {
        // Also tests XmlRegistry

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLELEMENTDECL);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("name", "Bob Dobbs");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement jbe = new JAXBElement(new QName("individuo"), DynamicEntity.class, person);
        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);


        Node node = marshalDoc.getChildNodes().item(0);

        assertEquals("Root element was not 'individuo' as expected.", "individuo", node.getLocalName());
    }

    public void testSchemaWithJAXBBindings() throws Exception {
        // jaxbcustom.xsd specifies that the generated package name should be "foo.bar" and
        // the person type will be named MyPersonType in Java

        InputStream inputStream = ClassLoader.getSystemResourceAsStream(JAXBCUSTOM);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity("foo.bar.MyPersonType");
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("name", "Bob Dobbs");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);
    }

    public void testSubstitutionGroupsUnmarshal() throws Exception {
        try {
            InputStream xsdStream = ClassLoader.getSystemResourceAsStream(SUBSTITUTION);
            jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(xsdStream, null, null, null);

            InputStream xmlStream = ClassLoader.getSystemResourceAsStream(PERSON_XML);
            JAXBElement person = (JAXBElement) jaxbContext.createUnmarshaller().unmarshal(xmlStream);
            assertEquals("Element was not substituted properly: ", new QName("myNamespace", "person"), person.getName());
            JAXBElement name = ((DynamicEntity) person.getValue()).get("name");
            assertEquals("Element was not substituted properly: ", new QName("myNamespace", "name"), name.getName());

            // ====================================================================

            InputStream xmlStream2 = ClassLoader.getSystemResourceAsStream(PERSONNE_XML);
            JAXBElement person2 = (JAXBElement) jaxbContext.createUnmarshaller().unmarshal(xmlStream2);
            assertEquals("Element was not substituted properly: ", new QName("myNamespace", "personne"), person2.getName());
            JAXBElement name2 = ((DynamicEntity) person2.getValue()).get("name");
            assertEquals("Element was not substituted properly: ", new QName("myNamespace", "nom"), name2.getName());
        } catch (JAXBException e) {
            // If running in a non-JAXB 2.2 environment, we will get this error because the required() method
            // on @XmlElementRef is missing.  Just ignore this and pass the test.
            if (e.getLinkedException() instanceof UndeclaredThrowableException) {
                return;
            } else {
                throw e;
            }
        } catch (Exception e) {
            if (e instanceof UndeclaredThrowableException) {
                return;
            } else {
                throw e;
            }
        }
    }

    public void testSubstitutionGroupsMarshal() throws Exception {
        try {
            InputStream inputStream = ClassLoader.getSystemResourceAsStream(SUBSTITUTION);
            jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

            QName personQName = new QName("myNamespace", "person");
            DynamicEntity person = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
            JAXBElement<DynamicEntity> personElement = new JAXBElement<DynamicEntity>(personQName, DynamicEntity.class, person);
            personElement.setValue(person);

            QName nameQName = new QName("myNamespace", "name");
            JAXBElement<String> nameElement = new JAXBElement<String>(nameQName, String.class, "Marty Friedman");

            person.set("name", nameElement);

            Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            jaxbContext.createMarshaller().marshal(personElement, marshalDoc);

            Node node1 = marshalDoc.getDocumentElement();
            assertEquals("Incorrect element name: ", "person", node1.getLocalName());

            Node node2 = node1.getFirstChild();
            assertEquals("Incorrect element name: ", "name", node2.getLocalName());

            // ====================================================================

            QName personneQName = new QName("myNamespace", "personne");
            DynamicEntity personne = jaxbContext.newDynamicEntity(PACKAGE + "." + PERSON);
            JAXBElement<DynamicEntity> personneElement = new JAXBElement<DynamicEntity>(personneQName, DynamicEntity.class, personne);
            personneElement.setValue(personne);

            QName nomQName = new QName("myNamespace", "nom");
            JAXBElement<String> nomElement = new JAXBElement<String>(nomQName, String.class, "Marty Friedman");

            personne.set("name", nomElement);

            Document marshalDoc2 = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            jaxbContext.createMarshaller().marshal(personneElement, marshalDoc2);

            Node node3 = marshalDoc2.getDocumentElement();
            assertEquals("Incorrect element name: ", "personne", node3.getLocalName());

            Node node4 = node3.getFirstChild();
            assertEquals("Incorrect element name: ", "nom", node4.getLocalName());
        } catch (JAXBException e) {
            // If running in a non-JAXB 2.2 environment, we will get this error because the required() method
            // on @XmlElementRef is missing.  Just ignore this and pass the test.
            if (e.getLinkedException() instanceof UndeclaredThrowableException) {
                return;
            } else {
                throw e;
            }
        } catch (Exception e) {
            if (e instanceof UndeclaredThrowableException) {
                return;
            } else {
                throw e;
            }
        }
    }

    // ====================================================================

    public void testTypePreservation() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSCHEMA_DEFAULTS);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity(DEF_PACKAGE + "." + PERSON);
        assertNotNull("Could not create Dynamic Entity.", person);

        person.set("id", 456);
        person.set("name", "Bob Dobbs");
        person.set("salary", 45000.00);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        DynamicEntity readPerson = (DynamicEntity) jaxbContext.createUnmarshaller().unmarshal(marshalDoc);

        assertEquals("Property type was not preserved during unmarshal.", Double.class, readPerson.<Object>get("salary").getClass());
        assertEquals("Property type was not preserved during unmarshal.", Integer.class, readPerson.<Object>get("id").getClass());
    }

    public void testNestedInnerClasses() throws Exception {
        // Tests multiple levels of inner classes, eg. mynamespace.Person.RelatedResource.Link
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(NESTEDINNERCLASSES);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        DynamicEntity person = jaxbContext.newDynamicEntity("mynamespace.Person");
        DynamicEntity resource = jaxbContext.newDynamicEntity("mynamespace.Person.RelatedResource");
        DynamicEntity link = jaxbContext.newDynamicEntity("mynamespace.Person.RelatedResource.Link");
        DynamicEntity link2 = jaxbContext.newDynamicEntity("mynamespace.Person.RelatedResource.Link");

        link.set("linkName", "LINKFOO");
        link2.set("linkName", "LINKFOO2");

        resource.set("resourceName", "RESBAR");

        ArrayList<DynamicEntity> links = new ArrayList<DynamicEntity>();
        links.add(link);
        links.add(link2);

        resource.set("link", links);
        person.set("name", "Bob Smith");
        person.set("relatedResource", resource);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);
        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);
    }

    public void testBinary() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(BINARY);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        byte[] byteArray = new byte[] {30,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};

        DynamicEntity person = jaxbContext.newDynamicEntity("mynamespace.Person");
        person.set("name", "B. Nary");
        person.set("abyte", (byte) 30);
        person.set("base64", byteArray);
        person.set("hex", byteArray);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);
    }

    public void testBinaryGlobalType() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(BINARY2);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        byte[] byteArray = new byte[] {30,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};

        DynamicEntity person = jaxbContext.newDynamicEntity("mynamespace.Person");
        person.set("name", "B. Nary");
        person.set("abyte", (byte) 30);
        person.set("base64", byteArray);
        person.set("hex", byteArray);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);
        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);
    }

    public void testXMLSchemaSchema() throws Exception {
        try {
            InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSCHEMASCHEMA);
            jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

            DynamicEntity schema = jaxbContext.newDynamicEntity("org.w3._2001.xmlschema.Schema");
            schema.set("targetNamespace", "myNamespace");
            Object QUALIFIED = jaxbContext.getEnumConstant("org.w3._2001.xmlschema.FormChoice", "QUALIFIED");
            schema.set("attributeFormDefault", QUALIFIED);

            DynamicEntity complexType = jaxbContext.newDynamicEntity("org.w3._2001.xmlschema.TopLevelComplexType");
            complexType.set("name", "myComplexType");

            List<DynamicEntity> complexTypes = new ArrayList<DynamicEntity>(1);
            complexTypes.add(complexType);

            schema.set("simpleTypeOrComplexTypeOrGroup", complexTypes);

            List<Object> blocks = new ArrayList<Object>();
            blocks.add("FOOBAR");
            schema.set("blockDefault", blocks);

            File f = new File(tmpdir, "myschema.xsd");
            jaxbContext.createMarshaller().marshal(schema, f);
        } catch (JAXBException e) {
            // If running in a non-JAXB 2.2 environment, we will get this error because the required() method
            // on @XmlElementRef is missing.  Just ignore this and pass the test.
            if (e.getLinkedException() instanceof UndeclaredThrowableException) {
                return;
            } else {
                throw e;
            }
        } catch (Exception e) {
            if (e instanceof UndeclaredThrowableException) {
                return;
            } else {
                throw e;
            }
        }
    }

    /**
     * Test for element type reference across multiple XML schemas with different namespaces.
     * Validates result after marshalling against XML Schema.
     */
    public void testXmlSchemaCrossSchema() throws Exception {
        String backupProperty = null;
        try {
            InputStream inputStream = ClassLoader.getSystemResourceAsStream(XMLSCHEMA_IMPORT_CROSS_SCHEMA);
            DynamicJAXBContext jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, new CustomEntityResolver(true), null, null);
            backupProperty = (System.getProperty(PROP_CORRECTNESS_CHECK_SCHEMA) != null) ? System.getProperty(PROP_CORRECTNESS_CHECK_SCHEMA) : null;
            System.setProperty(PROP_CORRECTNESS_CHECK_SCHEMA, "true");

            DynamicEntity testReq = jaxbContext.newDynamicEntity("com.temp.first.TestReq");

            DynamicEntity fault = jaxbContext.newDynamicEntity("com.temp.third.FaultType");

            DynamicEntity dataReference = jaxbContext.newDynamicEntity("com.temp.second.InheritedFaultType");
            dataReference.set("referenceId", "123456");

            DynamicEntity userKey = jaxbContext.newDynamicEntity("com.temp.fourth.UserType");
            userKey.set("userId", "TestUserID");

            dataReference.set("userKey", userKey);

            fault.set("dataReference", dataReference);

            testReq.set("fault", fault);
            testReq.set("companyId", "TestCompanyID");

            final StringWriter sw = new StringWriter();
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(testReq, sw);

            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            Schema testReqSchema = factory.newSchema(Thread.currentThread().getContextClassLoader().getResource(XMLSCHEMA_IMPORT_CROSS_SCHEMA));
            testReqSchema.newValidator().validate(
                    new StreamSource(new StringReader(sw.getBuffer().toString())));
        } catch (Exception e) {
            throw e;
        } finally {
            if (backupProperty != null) {
                System.setProperty(PROP_CORRECTNESS_CHECK_SCHEMA, backupProperty);
            } else {
                System.clearProperty(PROP_CORRECTNESS_CHECK_SCHEMA);
            }
        }
    }


    public void testGetByXPathPosition() throws Exception {
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XPATH_POSITION);
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

        InputStream xmlStream = ClassLoader.getSystemResourceAsStream(XPATH_POSITION_XML);
        JAXBElement<DynamicEntity> jelem = (JAXBElement<DynamicEntity>) jaxbContext.createUnmarshaller().unmarshal(xmlStream);
        DynamicEntity testBean = jelem.getValue();

        Object o = jaxbContext.getValueByXPath(testBean, "array[1]/text()", null, Object.class);
        assertNotNull("XPath: 'array[1]/text()' returned null.", o);
        o = jaxbContext.getValueByXPath(testBean, "array[2]/text()", null, Object.class);
        assertNull("XPath: 'array[2]/text()' did not return null.", o);
        o = jaxbContext.getValueByXPath(testBean, "map/entry[1]/value/text()", null, Object.class);
        assertEquals("foo", o);
        o = jaxbContext.getValueByXPath(testBean, "sub-bean[1]/map/entry[1]/value/text()", null, Object.class);
        assertEquals("foo2", o);
    }

    public void testDateTimeArray() throws Exception {
        // Tests to ensure that XSD dateTime is always unmarshalled as XMLGregorianCalendar, and never
        // as GregorianCalendar.  This can fail intermittently so is tested in a loop.

        HashSet<Class> elemClasses = new HashSet<Class>();

        for (int i = 0; i < 50; i++) {
            InputStream inputStream = ClassLoader.getSystemResourceAsStream(DATETIME_ARRAY);
            jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(inputStream, null, null, null);

            InputStream xmlStream = ClassLoader.getSystemResourceAsStream(DATETIME_ARRAY_XML);
            JAXBElement<DynamicEntity> jelem = (JAXBElement<DynamicEntity>) jaxbContext.createUnmarshaller().unmarshal(xmlStream);
            DynamicEntity testBean = jelem.getValue();

            ArrayList array = testBean.get("array");
            elemClasses.add(array.get(0).getClass());
        }

        assertEquals("dateTime was not consistently unmarshalled as XMLGregorianCalendar " + elemClasses, 1, elemClasses.size());
        Class elemClass = (Class) elemClasses.toArray()[0];
        boolean isXmlGregorianCalendar = ClassConstants.XML_GREGORIAN_CALENDAR.isAssignableFrom(elemClass);
        assertTrue("dateTime was not unmarshalled as XMLGregorianCalendar", isXmlGregorianCalendar);
    }

    // ====================================================================

    private void print(Object o) throws Exception {
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(o, System.err);
    }

    // ====================================================================

    private static final String RESOURCE_DIR = "org/eclipse/persistence/testing/jaxb/dynamic/";
    private static final String CONTEXT_PATH = "mynamespace";

    // System property name to restrict access to external schemas
    private static final String PROP_ACCESS_EXTERNAL_SCHEMA = "javax.xml.accessExternalSchema";
    // System property name to disable XJC's schema correctness check.  XSD imports do not seem to work if this is left on.
    private static final String PROP_CORRECTNESS_CHECK_SCHEMA = "com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.noCorrectnessCheck";


    // Schema files used to test each annotation
    private static final String XMLSCHEMA_QUALIFIED = RESOURCE_DIR + "xmlschema-qualified.xsd";
    private static final String XMLSCHEMA_UNQUALIFIED = RESOURCE_DIR +  "xmlschema-unqualified.xsd";
    private static final String XMLSCHEMA_DEFAULTS = RESOURCE_DIR + "xmlschema-defaults.xsd";
    private static final String XMLSCHEMA_IMPORT = RESOURCE_DIR + "xmlschema-import.xsd";
    private static final String XMLSCHEMA_IMPORT_CROSS_SCHEMA = RESOURCE_DIR + "xmlschema-import-cross-first.xsd";
    private static final String XMLSCHEMA_CURRENCY = RESOURCE_DIR + "xmlschema-currency.xsd";
    private static final String XMLSEEALSO = RESOURCE_DIR + "xmlseealso.xsd";
    private static final String XMLROOTELEMENT = RESOURCE_DIR + "xmlrootelement.xsd";
    private static final String XMLTYPE = RESOURCE_DIR + "xmltype.xsd";
    private static final String XMLATTRIBUTE = RESOURCE_DIR + "xmlattribute.xsd";
    private static final String XMLELEMENT = RESOURCE_DIR + "xmlelement.xsd";
    private static final String XMLLIST = RESOURCE_DIR + "xmllist.xsd";
    private static final String XMLVALUE = RESOURCE_DIR + "xmlvalue.xsd";
    private static final String XMLANYELEMENT = RESOURCE_DIR + "xmlanyelement.xsd";
    private static final String XMLANYATTRIBUTE = RESOURCE_DIR + "xmlanyattribute.xsd";
    private static final String XMLMIXED = RESOURCE_DIR + "xmlmixed.xsd";
    private static final String XMLID = RESOURCE_DIR + "xmlid.xsd";
    private static final String XMLELEMENTS = RESOURCE_DIR + "xmlelements.xsd";
    private static final String XMLELEMENTREF = RESOURCE_DIR + "xmlelementref.xsd";
    private static final String XMLSCHEMATYPE = RESOURCE_DIR + "xmlschematype.xsd";
    private static final String XMLENUM = RESOURCE_DIR + "xmlenum.xsd";
    private static final String XMLENUM_BIG = RESOURCE_DIR + "xmlenum-big.xsd";
    private static final String XMLELEMENTDECL = RESOURCE_DIR + "xmlelementdecl.xsd";
    private static final String XMLELEMENTCOLLECTION = RESOURCE_DIR + "xmlelement-collection.xsd";
    private static final String JAXBCUSTOM = RESOURCE_DIR + "jaxbcustom.xsd";
    private static final String SUBSTITUTION = RESOURCE_DIR + "substitution.xsd";
    private static final String NESTEDINNERCLASSES = RESOURCE_DIR + "nestedinnerclasses.xsd";
    private static final String BINARY = RESOURCE_DIR + "binary.xsd";
    private static final String BINARY2 = RESOURCE_DIR + "binary2.xsd";
    private static final String XMLSCHEMASCHEMA = RESOURCE_DIR + "XMLSchema.xsd";
    private static final String XPATH_POSITION = RESOURCE_DIR + "xpathposition.xsd";
    private static final String DATETIME_ARRAY = RESOURCE_DIR + "dateTimeArray.xsd";

    private static final String ECLIPSELINK_SCHEMA = "org/eclipse/persistence/jaxb/eclipselink_oxm_2_6.xsd";

    // Test Instance Docs
    private static final String PERSON_XML = RESOURCE_DIR + "sub-person-en.xml";
    private static final String PERSONNE_XML = RESOURCE_DIR + "sub-personne-fr.xml";
    private static final String XPATH_POSITION_XML = RESOURCE_DIR + "xpathposition.xml";
    private static final String DATETIME_ARRAY_XML = RESOURCE_DIR + "dateTimeArray.xml";

    // Names of types to instantiate
    private static final String PACKAGE = "mynamespace";
    private static final String DEF_PACKAGE = "generated";
    private static final String BANK_PACKAGE = "banknamespace";
    private static final String PERSON = "Person";
    private static final String EMPLOYEE = "Employee";
    private static final String INDIVIDUO = "Individuo";
    private static final String CDN_CURRENCY = "CdnCurrency";
    private static final String DATA = "Data";
    private static final String COMPANY = "Company";
    private static final String COMPASS_DIRECTION = "CompassDirection";
    private static final String TIME_ZONE = "Timezone";
    private static final String NORTH_CONSTANT = "NORTH";
    private static final String EST_CONSTANT = "EST";

}
