/*
 * Copyright (c) 1998, 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.oxm;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.xml.namespace.QName;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.documentpreservation.NoDocumentPreservationPolicy;
import org.eclipse.persistence.internal.oxm.documentpreservation.XMLBinderPolicy;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.UnionField;
import org.eclipse.persistence.internal.oxm.record.XMLRecord;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.documentpreservation.DocumentPreservationPolicy;
import org.eclipse.persistence.oxm.record.XMLEntry;
import org.eclipse.persistence.platform.xml.XMLNodeList;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * INTERNAL:
 * <p><b>Purpose</b>: Utility class for creating and removing XML nodes using
 * XPath expressions.</p>
 * @author    Rick Barkhouse - rick.barkhouse@oracle.com
 * @since    OracleAS TopLink 10<i>g</i> (10.0.3), 03/11/2003 10:21:42
 */
public class XPathEngine <
   XML_FIELD extends Field
>{
    private static XPathEngine instance = null;
    private UnmarshalXPathEngine unmarshalXPathEngine;
    private DocumentPreservationPolicy noDocPresPolicy = new NoDocumentPreservationPolicy();//handles xpath engine calls without a policy
    private DocumentPreservationPolicy xmlBinderPolicy = new XMLBinderPolicy();//used for adding new elements to a collection.

    /**
    * Return the <code>XPathEngine</code> singleton.
    */
    public static XPathEngine getInstance() {
        if (instance == null) {
            instance = new XPathEngine();
        }
        return instance;
    }

    private XPathEngine() {
        super();
        unmarshalXPathEngine = new UnmarshalXPathEngine();
    }

    /**
    * Create the node path specified by <code>xpathString</code> under <code>element</code>.
    * This method also supports creating attributes and indexed elements using the appropriate
    * XPath syntax ('<code>@</code>' and '<code>[ ]</code>' respectively).
    *
    * @param xmlField XMLField containing xpath expression representing the node path to create
    * @param element Root element under which to create path
    *
    * @return The last <code>XMLNode</code> in the path
    *
    * @exception XMLMarshalException Thrown if passed an invalid XPath string
    */
    public Node create(Field xmlField, Node element, CoreAbstractSession session) throws XMLMarshalException {
        return create(xmlField, element, this, session);
    }

    public Node create(Field xmlField, Node element, Object value, CoreAbstractSession session) {
        return create(xmlField, element, value, null, noDocPresPolicy, session);
    }

    /**
    * Create the node path specified by <code>xpathString</code> under <code>element</code>
    * and initialize the leaf node with <code>value</code>.
    * This method also supports creating attributes and integer-indexed elements using the
    * appropriate XPath syntax ('<code>@</code>' and '<code>[ ]</code>' respectively).
    *
    * @param xmlField XMLField containing xpath expression representing the node path to create
    * @param element Root element under which to create path
    * @param value Initial value for the leaf node (should not be a list)
    *
    * @return The last <code>XMLNode</code> in the path
    *
    * @exception XMLMarshalException Thrown if passed an invalid XPath string
    */
    public Node create(Field xmlField, Node element, Object value, Field lastUpdated, DocumentPreservationPolicy docPresPolicy, CoreAbstractSession session) throws XMLMarshalException {
        if (null == value) {
            return null;
        }
        if (docPresPolicy == null) {
            //EIS case and others
            docPresPolicy = this.noDocPresPolicy;
        }
        XPathFragment fragment = xmlField.getXPathFragment();
        if (fragment.getNextFragment() == null) {
            if (fragment.nameIsText()) {
                Object textValue = getValueToWrite(value, xmlField, session);
                if (textValue instanceof String) {
                    if (xmlField.isTypedTextField()) {
                        XMLNodeList createdElements = new XMLNodeList();
                        createdElements.add(element);
                        addTypeAttributes(createdElements, xmlField, value, resolveNamespacePrefixForURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, getNamespaceResolverForField(xmlField)), session);
                    }
                    return addText(xmlField, element, (String)textValue);
                }
                return null;
            }
        }
        NodeList created = createCollection(xmlField, element, value, lastUpdated, docPresPolicy, session);

        if ((created == null) || (created.getLength() == 0)) {
            return null;
        }

        return created.item(0);
    }

    public void create(List<Field> xmlFields, Node contextNode, List<XMLEntry> values, Field lastUpdatedField, DocumentPreservationPolicy docPresPolicy, CoreAbstractSession session) {
        List itemsToWrite = new ArrayList();
        for(int i = 0, size = values.size(); i < size; i++) {
            XMLEntry nextEntry = values.get(i);
            itemsToWrite.add(nextEntry.getValue());
            if(i == (values.size() -1) || values.get(i+1).getXMLField() != nextEntry.getXMLField()) {
                create(nextEntry.getXMLField(), contextNode, itemsToWrite, lastUpdatedField, docPresPolicy, session);
                itemsToWrite = new ArrayList();
                lastUpdatedField = nextEntry.getXMLField();
            }
        }
    }



    /**
    * Create the node path specified by <code>xpathString</code> under <code>element</code>
    * and initialize the leaf node with <code>value</code>.
    * This method also supports creating attributes and integer-indexed elements using the
    * appropriate XPath syntax ('<code>@</code>' and '<code>[ ]</code>' respectively).
    *
    * @param xmlField XMLField containing xpath expression representing the node path to create
    * @param element Root element under which to create path
    * @param value Initial value for the leaf node (this can be a value or a collection of values)
    *
    * @return The last <code>XMLNode</code> in the path
    *
    * @throws XMLMarshalException Thrown if passed an invalid XPath string
    */
    private NodeList createCollection(Field xmlField, Node element, Object value, Field lastUpdated, DocumentPreservationPolicy docPresPolicy, CoreAbstractSession session) throws XMLMarshalException {
        XMLNodeList createdElements = new XMLNodeList();

        //CR:### If the value is null, then the node(s) must not be created.
        if ((value == null) || (value instanceof Collection && (((Collection)value).size() == 0))) {
            return createdElements;
        }
        Node nextElement = element;
        Element sibling = null;
        XPathFragment siblingFragment = null;
        if(lastUpdated != null) {
            siblingFragment = lastUpdated.getXPathFragment();
        }
        if ((lastUpdated != null) && !siblingFragment.isAttribute() && !siblingFragment.nameIsText()) {
            //find the sibling element.
            NodeList nodes = unmarshalXPathEngine.selectElementNodes(element, siblingFragment, getNamespaceResolverForField(lastUpdated));
            if (nodes.getLength() > 0) {
                sibling = (Element)nodes.item(nodes.getLength() - 1);
            }
        }
        NodeList elements;
        XPathFragment next = xmlField.getXPathFragment();
        while (next != null) {
            if (next.isAttribute()) {
                addAttribute(next, xmlField, nextElement, value, session);
            } else if (next.containsIndex()) {
                // If we are creating multiple nodes from this XPath, assume the value is for the last node.
                boolean hasMore = !(next.getHasText() || (next.getNextFragment() == null));

                if (hasMore) {
                    nextElement = addIndexedElement(next, xmlField, nextElement, this, !hasMore, session);
                } else {
                    Object valueToWrite = getValueToWrite(value, xmlField, session);
                    nextElement = addIndexedElement(next, xmlField, nextElement, valueToWrite, !hasMore, session);
                    createdElements.add(nextElement);
                }
            } else {
                boolean hasMore = !(next.getHasText() || (next.getNextFragment() == null));

                if (hasMore) {
                    elements = addElements(next, xmlField, nextElement, this, !hasMore, sibling, docPresPolicy, session);
                } else {
                    XPathFragment nextFragment = next.getNextFragment();
                    if ((nextFragment != null) && nextFragment.isAttribute() && !(value instanceof List)) {
                        elements = addElements(next, xmlField, nextElement, this, hasMore, sibling, docPresPolicy, session);
                    } else {
                        Object valueToWrite = getValueToWrite(value, xmlField, session);
                        elements = addElements(next, xmlField, nextElement, valueToWrite, !hasMore, sibling, docPresPolicy, session);
                        createdElements.addAll(elements);
                    }
                }

                nextElement = elements.item(elements.getLength() - 1);
            }
            if(siblingFragment != null && sibling != null && siblingFragment.equals(next)) {
                //if the sibling shares a grouping element, update the sibling
                siblingFragment = siblingFragment.getNextFragment();
                if ((siblingFragment != null) && !siblingFragment.isAttribute() && !siblingFragment.nameIsText()) {
                    //find the sibling element.
                    NodeList nodes = unmarshalXPathEngine.selectElementNodes(nextElement, siblingFragment, getNamespaceResolverForField(lastUpdated));
                    if (nodes.getLength() > 0) {
                        sibling = (Element)nodes.item(nodes.getLength() - 1);
                    } else {
                        sibling = null;
                    }
                } else {
                    sibling = null;
                }
            } else {
                sibling = null;
            }

            next = next.getNextFragment();
            if ((next != null) && next.nameIsText()) {
                next = null;
            }
        }

        if (xmlField.isTypedTextField()) {
            addTypeAttributes(createdElements, xmlField, value, resolveNamespacePrefixForURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, getNamespaceResolverForField(xmlField)), session);
        }

        return createdElements;
    }

    private Object getNonNodeValueToWrite(Object value, Field xmlField, CoreAbstractSession session) {
        if (this == value) {
            return this;
        }

        QName schemaType = null;
        if(xmlField.getLeafElementType() != null){
            schemaType = xmlField.getLeafElementType();
        }else if (xmlField.isUnionField()) {
            return getValueToWriteForUnion((UnionField)xmlField, value, session);
        }else if (xmlField.isTypedTextField()) {
            ConversionManager conversionManager = (ConversionManager) session.getDatasourcePlatform().getConversionManager();
            schemaType = xmlField.getXMLType(value.getClass(), conversionManager);
        }else if (xmlField.getSchemaType() != null) {
            schemaType = xmlField.getSchemaType();
        }

        if (value instanceof List) {
            if (xmlField.usesSingleNode()) {
                StringBuilder returnStringBuilder = new StringBuilder();
                for (int i = 0; i < ((List)value).size(); i++) {
                    Object nextItem = ((List)value).get(i);

                    String nextConvertedItem = null;
                    if(schemaType != null && schemaType.equals(Constants.QNAME_QNAME)){
                        nextConvertedItem = getStringForQName((QName)nextItem, getNamespaceResolverForField(xmlField));
                    }else{
                        nextConvertedItem = ((ConversionManager)session.getDatasourcePlatform().getConversionManager()).convertObject(nextItem, CoreClassConstants.STRING, schemaType);
                    }
                    returnStringBuilder.append(nextConvertedItem);
                    if (i < (((List)value).size() - 1)) {
                        returnStringBuilder.append(' ');
                    }
                }
                return returnStringBuilder.toString();
            } else {
                ArrayList items = new ArrayList(((List)value).size());
                for (int index = 0; index < ((List)value).size(); index++) {
                    Object nextItem = ((List)value).get(index);
                    if (nextItem instanceof Node || nextItem == XMLRecord.NIL) {
                        items.add(nextItem);
                    } else {
                        if(schemaType != null && schemaType.equals(Constants.QNAME_QNAME)){
                            String nextConvertedItem = getStringForQName((QName)nextItem, getNamespaceResolverForField(xmlField));
                            items.add(nextConvertedItem);
                        }else{
                            String nextConvertedItem = ((ConversionManager)session.getDatasourcePlatform().getConversionManager()).convertObject(nextItem, CoreClassConstants.STRING, schemaType);
                            items.add(nextConvertedItem);
                        }
                    }
                }
                return items;
            }
        } else {
            if(schemaType != null && schemaType.equals(Constants.QNAME_QNAME)){
                return getStringForQName((QName)value, getNamespaceResolverForField(xmlField));
            }
            return ((ConversionManager)session.getDatasourcePlatform().getConversionManager()).convertObject(value, CoreClassConstants.STRING, schemaType);
        }
    }

    private Object getValueToWrite(Object value, Field xmlField, CoreAbstractSession session) {
        if (value instanceof Node || value == XMLRecord.NIL) {
            return value;
        }

        return getNonNodeValueToWrite(value, xmlField, session);
    }

    private String getSingleValueToWriteForUnion(UnionField xmlField, Object value, CoreAbstractSession session) {
        List schemaTypes = xmlField.getSchemaTypes();
        QName schemaType = null;
        for (int i = 0; i < schemaTypes.size(); i++) {
            QName nextQName = (QName)(xmlField).getSchemaTypes().get(i);
            try {
                if (nextQName != null) {
                    ConversionManager conversionManager = (ConversionManager)session.getDatasourcePlatform().getConversionManager();
                    Class javaClass = xmlField.getJavaClass(nextQName, conversionManager);
                    value = conversionManager.convertObject(value, javaClass, nextQName);
                    schemaType = nextQName;
                    break;
                }
            } catch (ConversionException ce) {
                if (i == (schemaTypes.size() - 1)) {
                    schemaType = nextQName;
                }
            }
        }
        return ((ConversionManager)session.getDatasourcePlatform().getConversionManager()).convertObject(value, CoreClassConstants.STRING, schemaType);
    }

    private Object getValueToWriteForUnion(UnionField xmlField, Object value, CoreAbstractSession session) {
        if (value instanceof List) {
            if (xmlField.usesSingleNode()) {
                StringBuilder returnStringBuilder = new StringBuilder();
                Object next = null;
                for (int i = 0; i < ((List)value).size(); i++) {
                    next = ((List)value).get(i);
                    returnStringBuilder.append(getSingleValueToWriteForUnion(xmlField, next, session));
                    if (i < (((List)value).size() - 1)) {
                        returnStringBuilder.append(' ');
                    }
                }
                return returnStringBuilder.toString();
            } else {
                ArrayList items = new ArrayList(((List)value).size());
                Object next = null;
                for (int i = 0; i < ((List)value).size(); i++) {
                    next = ((List)value).get(i);
                    items.add(getSingleValueToWriteForUnion(xmlField, next, session));
                }
                return items;
            }
        } else {
            return getSingleValueToWriteForUnion(xmlField, value, session);
        }
    }

    /**
    * Add a new indexed <code>element</code> to the <code>parent</code> element.
    * Will overwrite if an element already exists at that position.  Currently only supports
    * integer indices.
    *
    * @param fragment element and index to create (in the form 'element[index]')
    * @param parent Parent element
    * @param value Value for the new node
    * @param forceCreate If true, create a new element even if one with the same name currently exists
    *
    * @return The <code>XMLElement</code> that was created/found
    *
    * @throws XMLMarshalException Thrown if passed an invalid XPath string
    */
    private Node addIndexedElement(XPathFragment fragment, Field xmlField, Node parent, Object value, boolean forceCreate, CoreAbstractSession session) throws XMLMarshalException {
        String element = fragment.getShortName();

        int index = fragment.getIndexValue();
        if (index < 0) {
            throw XMLMarshalException.invalidXPathIndexString(fragment.getXPath());
        }

        Node existingElement;
        NamespaceResolver namespaceResolver = getNamespaceResolverForField(xmlField);
        for (int i = 1; i < index; i++) {
            Field<XMLConversionManager, NamespaceResolver> field = new XMLField(element + "[" + i + "]");
            field.setNamespaceResolver(namespaceResolver);
            existingElement = (Node)unmarshalXPathEngine.selectSingleNode(parent, field, namespaceResolver);
            if (existingElement == null) {
                addElement(new XPathFragment(element), xmlField, parent, this, true, session);
            }
        }
        Field<XMLConversionManager, NamespaceResolver> field = new XMLField(fragment.getXPath());
        field.setNamespaceResolver(namespaceResolver);
        existingElement = (Node)unmarshalXPathEngine.selectSingleNode(parent, field, namespaceResolver);
        if (existingElement == null) {
            return addElement(new XPathFragment(element), field, parent, value, true, session);
        }

        if (!forceCreate) {
            return existingElement;
        }

        String namespace = resolveNamespacePrefix(fragment, namespaceResolver);
        Element elementToReturn = parent.getOwnerDocument().createElementNS(namespace, element);

        if ((value != this) && (value != null)) {
            if (value instanceof String) {
                addText(xmlField, elementToReturn, (String)value);
            }
        }
        parent.replaceChild(elementToReturn, existingElement);
        return elementToReturn;
    }

    /**
    * Add a new <code>element</code> to the <code>parent</code> element.  If an element with
    * this name already exists, return it (unless <code>forceCreate</code> is <code>true</code>).
    *
    * @param fragment Name of element to create
    * @param parent Parent element
    * @param value Value for the new node
    * @param forceCreate If true, create a new element even if one with the same name currently exists
    *
    * @return The <code>XMLElement</code> that was created/found
    */
    private Node addElement(XPathFragment fragment, Field xmlField, Node parent, Object value, boolean forceCreate, CoreAbstractSession session) {
        return addElement(fragment, xmlField, parent, null, value, forceCreate, session);
    }

    private Node addElement(XPathFragment fragment, Field xmlField, Node parent, QName schemaType, Object value, boolean forceCreate, CoreAbstractSession session) {
        NodeList list = addElements(fragment, xmlField, parent, value, forceCreate, null, noDocPresPolicy, session);
        if (list.getLength() > 0) {
            return list.item(0);
        }
        return null;
    }

    /**
    * Add a new <code>element</code> to the <code>parent</code> element.  If an element with
    * this name already exists, return it (unless <code>forceCreate</code> is <code>true</code>).
    *
    * @param fragment Name of element to create
    * @param parent Parent element
    * @param value Value for the new node
    * @param forceCreate If true, create a new element even if one with the same name currently exists

    * @return The <code>NodeList</code> that was created/found
    */
    private NodeList addElements(XPathFragment fragment, Field xmlField, Node parent, Object value, boolean forceCreate, Element sibling, DocumentPreservationPolicy docPresPolicy, CoreAbstractSession session) {
        if (!forceCreate) {
            NodeList nodes = unmarshalXPathEngine.selectElementNodes(parent, fragment, getNamespaceResolverForField(xmlField));
            if (nodes.getLength() > 0) {
                return nodes;
            }
        }

        XMLNodeList elementsToReturn = new XMLNodeList();

        if (value == this) {
            String namespace = resolveNamespacePrefix(fragment, getNamespaceResolverForField(xmlField));
            Element newElement = parent.getOwnerDocument().createElementNS(namespace, fragment.getShortName());
            XPathPredicate predicate = fragment.getPredicate();
            if(predicate != null) {
                XPathFragment predicateFragment = predicate.getXPathFragment();
                if(predicateFragment.isAttribute()) {
                    if(predicateFragment.getNamespaceURI() == null || predicateFragment.getNamespaceURI().length() == 0) {
                        newElement.setAttribute(predicateFragment.getLocalName(), fragment.getPredicate().getValue());
                    } else {
                        String name = predicateFragment.getLocalName();
                        if(predicateFragment.getPrefix() != null && predicateFragment.getPrefix().length() != 0) {
                            name = predicateFragment.getPrefix() + Constants.COLON + name;
                        }
                        newElement.setAttributeNS(predicateFragment.getNamespaceURI(), name, fragment.getPredicate().getValue());
                    }
                }
            }
            elementsToReturn.add(newElement);
            docPresPolicy.getNodeOrderingPolicy().appendNode(parent, newElement, sibling);

        } else if (value == null) {
            elementsToReturn.add(parent);
        } else {
            // Value may be a direct value, node, or list of values.
            if (value instanceof List) {
                List values = (List)value;
                for (int index = 0; index < values.size(); index++) {
                    Element newElement = null;

                    if (values.get(index) != XMLRecord.NIL) {
                        newElement = (Element) createElement(parent, fragment, xmlField, values.get(index), session);
                    } else {
                        newElement = (Element) createElement(parent, fragment, xmlField, Constants.EMPTY_STRING, session);
                        addXsiNilToElement(newElement, xmlField);
                    }
                    XPathPredicate predicate = fragment.getPredicate();
                    if(predicate != null) {
                        XPathFragment predicateFragment = predicate.getXPathFragment();
                        if(predicateFragment.isAttribute()) {
                            if(predicateFragment.getNamespaceURI() == null || predicateFragment.getNamespaceURI().length() == 0) {
                                newElement.setAttribute(predicateFragment.getLocalName(), fragment.getPredicate().getValue());
                            } else {
                                String name = predicateFragment.getLocalName();
                                if(predicateFragment.getPrefix() != null && predicateFragment.getPrefix().length() != 0) {
                                    name = predicateFragment.getPrefix() + Constants.COLON + name;
                                }
                                newElement.setAttributeNS(predicateFragment.getNamespaceURI(), name, fragment.getPredicate().getValue());
                            }
                        }
                    }
                    docPresPolicy.getNodeOrderingPolicy().appendNode(parent, newElement, sibling);
                    elementsToReturn.add(newElement);
                    sibling = newElement;
                }
            } else {
                Element newElement = null;
                if (value != XMLRecord.NIL) {
                    newElement = (Element)createElement(parent, fragment, xmlField, value, session);
                } else {
                    newElement = (Element) createElement(parent, fragment, xmlField, Constants.EMPTY_STRING, session);
                    addXsiNilToElement(newElement, xmlField);
                }
                XPathPredicate predicate = fragment.getPredicate();
                if(predicate != null) {
                    XPathFragment predicateFragment = predicate.getXPathFragment();
                    if(predicateFragment.isAttribute()) {
                        if(predicateFragment.getNamespaceURI() == null || predicateFragment.getNamespaceURI().length() == 0) {
                            newElement.setAttribute(predicateFragment.getLocalName(), fragment.getPredicate().getValue());
                        } else {
                            String name = predicateFragment.getLocalName();
                            if(predicateFragment.getPrefix() != null && predicateFragment.getPrefix().length() != 0) {
                                name = predicateFragment.getPrefix() + Constants.COLON + name;
                            }
                            newElement.setAttributeNS(predicateFragment.getNamespaceURI(), name, fragment.getPredicate().getValue());
                        }
                    }
                }

                docPresPolicy.getNodeOrderingPolicy().appendNode(parent, newElement, sibling);
                elementsToReturn.add(newElement);
            }
        }
        return elementsToReturn;
    }

    /**
    * Creates a new Element and appends a value to an element.
    *
    * @param parent Element which will own the newly created element
    * @param fragment tag name for the new element
    * @param value Object to add
    */
    private Node createElement(Node parent, XPathFragment fragment, Field xmlField, Object value, CoreAbstractSession session) {
        if (value == null) {
            return parent;
        }
        if (value instanceof Node) {
            return createElement(parent, fragment, getNamespaceResolverForField(xmlField), (Node)value);
        }
        Element element = null;
        if (parent.getOwnerDocument() == null) {
            element = ((Document)parent).getDocumentElement();
        } else {
            String namespace = resolveNamespacePrefix(fragment, getNamespaceResolverForField(xmlField));
            NamespaceResolver domResolver = new NamespaceResolver();
            domResolver.setDOM(parent);
            String existingPrefix = domResolver.resolveNamespaceURI(namespace);
            String elementName = fragment.getShortName();
            if(existingPrefix != null) {
                if(existingPrefix.length() > 0) {
                    elementName = existingPrefix + Constants.COLON + fragment.getLocalName();
                } else {
                    elementName = fragment.getLocalName();
                }
            }
            element = parent.getOwnerDocument().createElementNS(namespace, elementName);
            if (fragment.isGeneratedPrefix() && existingPrefix == null) {
                element.setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + fragment.getPrefix(), fragment.getNamespaceURI());
            }
            XPathPredicate predicate = fragment.getPredicate();
            if(predicate != null) {
                XPathFragment predicateFragment = predicate.getXPathFragment();
                if(predicateFragment.isAttribute()) {
                    element.setAttributeNS(predicateFragment.getNamespaceURI(), predicateFragment.getLocalName(), fragment.getPredicate().getValue());
                }
            }
        }

        XPathFragment nextFragment = fragment.getNextFragment();
        if ((nextFragment != null) && nextFragment.isAttribute()) {
            addAttribute(nextFragment, xmlField, element, value, session);
        } else if (value instanceof String && ((String)value).length() > 0) {
            addText(xmlField, element, (String)value);
        } else if (value == XMLRecord.NIL) {
            addXsiNilToElement(element, xmlField);
        }
        return element;
    }

    public Element createUnownedElement(Node parent, Field xmlField) {
        XPathFragment lastFragment = xmlField.getXPathFragment();
        while (lastFragment.getNextFragment() != null) {
            lastFragment = lastFragment.getNextFragment();
        }
        String nodeName = lastFragment.getShortName();
        String namespace = resolveNamespacePrefix(lastFragment, getNamespaceResolverForField(xmlField));

        NamespaceResolver domResolver = new NamespaceResolver();
        domResolver.setDOM(parent);
        String existingPrefix = domResolver.resolveNamespaceURI(namespace);
        String elementName = nodeName;
        if(existingPrefix != null) {
            if(existingPrefix.length() > 0) {
                elementName = existingPrefix + Constants.COLON + lastFragment.getLocalName();
            } else {
                elementName = lastFragment.getLocalName();
            }
        }

        Element elem = parent.getOwnerDocument().createElementNS(namespace, elementName);
        if (lastFragment.isGeneratedPrefix() && existingPrefix == null) {
            elem.setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + lastFragment.getPrefix(), lastFragment.getNamespaceURI());
        }

        return elem;
    }

    /**
    * Adds a type attribute on an element, the value of the attribute is determined
    * by performing a lookup in the SimpleTypeTranslator to find the Schema type
    * for the value.
    *
    * @param elements NodeList which will have a type attribute added to them
    * @param value Object to base the lookup on
    * @param schemaInstancePrefix the prefix representing the schema instance namespace
    */
    private void addTypeAttributes(NodeList elements, Field field, Object value, String schemaInstancePrefix, CoreAbstractSession session) {
        NamespaceResolver namespaceResolver = getNamespaceResolverForField(field);
        if (!field.isTypedTextField()) {
            return;
        }

        List values;
        if (value instanceof List) {
            values = (List)value;
        } else {
            values = new ArrayList();
            values.add(value);
        }

        int size = elements.getLength();
        int valuesSize = values.size();

        if (size != valuesSize) {
            return;
        }

        Node next = null;
        for (int i = 0; i < size; i++) {
            next = elements.item(i);
            if (next.getNodeType() == Node.ELEMENT_NODE) {
                Class<?> valueClass = values.get(i).getClass();
                if(valueClass != CoreClassConstants.STRING){
                    ConversionManager conversionManager = (ConversionManager) session.getDatasourcePlatform().getConversionManager();
                    QName qname = field.getXMLType(valueClass, conversionManager);
                    if (qname != null) {
                        if (null == schemaInstancePrefix) {
                            schemaInstancePrefix = namespaceResolver.generatePrefix(Constants.SCHEMA_INSTANCE_PREFIX);
                            ((Element)next).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + schemaInstancePrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                        }

                        String type;
                        String prefix = this.resolveNamespacePrefixForURI(qname.getNamespaceURI(), namespaceResolver);
                        if (prefix == null || prefix.length() == 0) {
                            if(qname.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)){
                                prefix = namespaceResolver.generatePrefix(Constants.SCHEMA_PREFIX);
                            }else{
                                prefix = namespaceResolver.generatePrefix();
                            }
                            ((Element)next).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + prefix, qname.getNamespaceURI());
                        }
                        type = prefix + Constants.COLON + qname.getLocalPart();
                        ((Element)next).setAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, schemaInstancePrefix + Constants.COLON + Constants.SCHEMA_TYPE_ATTRIBUTE, type);
                    }
                }
            }
        }
    }

    /**
    * Creates a new Element and appends a value to an element.
    *
    * @param parent Element which will own the newly created element
    * @param fragment tag name for the new element
    * @param value Node to add
    *
    */
    private Node createElement(Node parent, XPathFragment fragment, NamespaceResolver namespaceResolver, Node value) {
        // The case of the parent being the document (element is the root) needs to be handled.
        // Document have no owner document, but are the document.
        Document document = parent.getOwnerDocument();
        if ((document == null) && (parent.getNodeType() == Node.DOCUMENT_NODE)) {
            document = (Document)parent;
        }

        String nodeUri = value.getNamespaceURI();
        String nodeName = value.getLocalName();

        //String fragUri = resolveNamespacePrefix(fragment, namespaceResolver);
        String fragUri = fragment.getNamespaceURI();
        String fragName = fragment.getLocalName();

        if ((nodeName != null) && nodeName.equals(fragName) && (((nodeUri != null) && nodeUri.equals(fragUri)) || ((nodeUri == null) && (fragUri == null)))) {
            if (document != value.getOwnerDocument()) {
                return document.importNode(value, true);
            }
            return value;
        } else {
            // Need to reset the node name.
            String namespace = resolveNamespacePrefix(fragment, namespaceResolver);
            Element clone = document.createElementNS(namespace, fragName);
            NamedNodeMap attributes = value.getAttributes();
            int attributesLength = attributes.getLength();

            for (int index = 0; index < attributesLength; index++) {
                Node attribute = document.importNode(attributes.item(index), true);
                clone.setAttributeNode((Attr)attribute);
            }

            NodeList elements = value.getChildNodes();
            int elementsLength = elements.getLength();
            for (int index = 0; index < elementsLength; index++) {
                Node attribute = document.importNode(elements.item(index), true);
                clone.appendChild(attribute);
            }
            return clone;
        }
    }

    /**
    * Add a new attribute to an element.  If the attribute already exists, return the element.
    *
    * @param attributeFragment Name of the attribute to add
    * @param parent Element to create the attribute on
    * @param value Value for the new attribute
    *
    * @return The <code>XMLElement</code> that the attribute was added to (same as the <code>parent</code> parameter).
    */
    private Node addAttribute(XPathFragment attributeFragment, Field xmlField, Node parent, Object value, CoreAbstractSession session) {
        Object valueToWrite = null;

        if (!(parent instanceof Element)) {
            return parent;
        }
        Element parentElement = (Element)parent;
        if (value instanceof Node) {
            if (((Node)value).getNodeType() == Node.ATTRIBUTE_NODE) {
                Attr attr = (Attr)value;
                if (parent.getAttributes().getNamedItemNS(attr.getNamespaceURI(), attr.getLocalName()) == null) {
                    String pfx = null;
                    if (xmlField.getNamespaceResolver() != null) {
                        pfx = getNamespaceResolverForField(xmlField).resolveNamespaceURI(attr.getNamespaceURI());
                    }
                    if (pfx != null) {
                        // If the namespace resolver has a prefix for the node's URI, use it
                        parentElement.setAttributeNS(attr.getNamespaceURI(), pfx + Constants.COLON + attr.getLocalName(), attr.getNodeValue());
                    } else {
                        // No entry for the node's URI in the resolver, so use the node's
                        // prefix/uri pair and define the URI locally
                        parentElement.setAttributeNS(attr.getNamespaceURI(), attr.getName(), attr.getNodeValue());
                    }
                }
                return parent;
            }
            valueToWrite = value;
        } else {
            valueToWrite = getNonNodeValueToWrite(value, xmlField, session);
        }

        String attributeName = attributeFragment.getLocalName();
        String attributeNamespace = resolveNamespacePrefix(attributeFragment, getNamespaceResolverForField(xmlField));
        if ((valueToWrite != null) && (parent.getAttributes().getNamedItemNS(attributeNamespace, attributeName) == null)) {
            if (valueToWrite == this) {
                parentElement.setAttributeNS(attributeNamespace, attributeFragment.getShortName(), Constants.EMPTY_STRING);
            } else if (valueToWrite instanceof String) {
                parentElement.setAttributeNS(attributeNamespace, attributeFragment.getShortName(), (String)valueToWrite);
            }
            if (attributeFragment.isGeneratedPrefix()) {
                parentElement.setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + attributeFragment.getPrefix(), attributeFragment.getNamespaceURI());
            }
        }
        return parent;
    }

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

    /**
    * Remove a node.  If <code>xpathString</code> points to an indexed element, the element will not be removed,
    * but will instead be reinitialzed (to maintain the index of the collection).
    *
    * @param xmlField Field containing XPath query string
    * @param element Root element at which to begin search
    *
    * @return <code>NodeList</code> containing the nodes that were removed.
    *
    * @exception XMLMarshalException Thrown if passed an invalid XPath string
    */
    public NodeList remove(Field xmlField, Node element) throws XMLMarshalException {
        return remove(xmlField, element, false);
    }

    /**
    * Remove a node.
    *
    * @param xmlField Field containing XPath query string
    * @param element Root element at which to begin search
    * @param forceRemove If <code>true</code>, then indexed elements will be truly deleted, otherwise they will be reinitialized
    *
    * @return <code>NodeList</code> containing the nodes that were removed.
    *
    * @exception XMLMarshalException Thrown if passed an invalid XPath string
    */
    public NodeList remove(Field xmlField, Node element, boolean forceRemove) throws XMLMarshalException {
        String xpathString = xmlField.getXPath();
        NodeList nodes = unmarshalXPathEngine.selectNodes(element, xmlField, getNamespaceResolverForField(xmlField));
        int numberOfNodes = nodes.getLength();

        boolean shouldNullOutNode = containsIndex(xpathString) && !forceRemove;

        // Remove the element or attribute, for positional element null-out instead of remove.
        for (int i = 0; i < numberOfNodes; i++) {
            Node node = nodes.item(i);
            if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
                ((Attr)node).getOwnerElement().removeAttribute(node.getNodeName());
            } else {
                if (shouldNullOutNode) {
                    Node blankNode = node.getParentNode().getOwnerDocument().createElementNS(node.getNamespaceURI(), node.getNodeName());
                    node.getParentNode().replaceChild(blankNode, node);
                } else {
                    node.getParentNode().removeChild(node);
                }
            }
        }

        return nodes;
    }

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

    /**
    * Replace the value of the nodes matching <code>xpathString</code> with <code>value</code>.
    * This method handles elements, indexed elements, and attributes.
    *
    * @param xmlField Field containing XPath query string
    * @param parent Parent element
    * @param value New value for the node
    *
    * @return <code>NodeList</code> containing the nodes that were replaced.
    */
    public NodeList replaceValue(Field xmlField, Node parent, Object value, CoreAbstractSession session) throws XMLMarshalException {
        NodeList nodes = unmarshalXPathEngine.selectNodes(parent, xmlField, getNamespaceResolverForField(xmlField), null, false, false);
        int numberOfNodes = nodes.getLength();
        if(numberOfNodes == 0 && xmlField.getLastXPathFragment().nameIsText()) {
            nodes = unmarshalXPathEngine.selectNodes(parent, xmlField, getNamespaceResolverForField(xmlField), null, true);
            XMLNodeList textNodes = new XMLNodeList();
            for(int i = 0; i < nodes.getLength(); i++) {
                Element nextNode = (Element)nodes.item(i);
                Text text = nextNode.getOwnerDocument().createTextNode("");
                nextNode.appendChild(text);
                textNodes.add(text);
            }
            numberOfNodes = textNodes.getLength();
            nodes = textNodes;
        }
        XMLNodeList createdElements = new XMLNodeList();
        for (int i = 0; i < numberOfNodes; i++) {
            Node node = nodes.item(i);

            // Handle Attributes and Text
            if (node.getNodeType() != Node.ELEMENT_NODE) {
                if (((node.getNodeType() == Node.TEXT_NODE) || (node.getNodeType() == Node.CDATA_SECTION_NODE)) && (value == null)) {
                    //if parent has only text children, remove parent. If parent has non-text children,
                    //remove all text children.
                    Node parentNode = node.getParentNode();
                    if(parentNode != null) {
                        Node grandParentNode = parentNode.getParentNode();
                        NodeList childNodes = parentNode.getChildNodes();
                        if(childNodes.getLength() == numberOfNodes) {
                            grandParentNode.removeChild(parentNode);
                        } else {
                            for(int x = 0; x < childNodes.getLength(); x++) {
                                Node next = childNodes.item(x);
                                if(next.getNodeType() == Node.TEXT_NODE || next.getNodeType() == Node.CDATA_SECTION_NODE) {
                                    parentNode.removeChild(next);
                                }
                            }
                        }
                    }
                } else {
                    if(value == null) {
                        ((Attr)node).getOwnerElement().removeAttributeNode((Attr)node);
                    } else {
                        if(value == XMLRecord.NIL && ((node.getNodeType() == Node.TEXT_NODE) || (node.getNodeType() == Node.CDATA_SECTION_NODE))) {
                            Element parentElement = (Element)node.getParentNode();
                            addXsiNilToElement(parentElement, xmlField);
                            parentElement.removeChild(node);
                        } else {
                            String stringValue = session.getDatasourcePlatform().getConversionManager().convertObject(value, CoreClassConstants.STRING);
                            Element parentElement = (Element)node.getParentNode();
                            if(parentElement == null && parent.getNodeType() == Node.ELEMENT_NODE) {
                                parentElement = (Element)parent;
                            }
                            if(stringValue.length() == 0 && ((node.getNodeType() == Node.TEXT_NODE) || (node.getNodeType() == Node.CDATA_SECTION_NODE)) && parentElement != null) {
                                parentElement.removeChild(node);
                            } else {
                                node.setNodeValue(stringValue);
                                if(((node.getNodeType() == Node.TEXT_NODE) || (node.getNodeType() == Node.CDATA_SECTION_NODE)) && parentElement != null) {
                                    Attr nil = parentElement.getAttributeNodeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_NIL_ATTRIBUTE);
                                    if(nil != null) {
                                        parentElement.removeAttributeNode(nil);
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                Element element = (Element)node;
                Node parentNode = element.getParentNode();
                if (value == null) {
                    parentNode.removeChild(element);
                } else {
                    String elementName = element.getTagName();

                    Element newElement = null;

                    Object valueToWrite = getValueToWrite(value, xmlField, session);
                    XPathFragment childFrag = new XPathFragment(elementName);
                    childFrag.setNamespaceURI(element.getNamespaceURI());
                    newElement = (Element)createElement(parentNode, childFrag, xmlField, valueToWrite, session);

                    createdElements.add(newElement);


                    if (newElement != element) {
                        parentNode.replaceChild(newElement, element);
                    }
                }
            }
        }
        if (xmlField.isTypedTextField()) {

            addTypeAttributes(createdElements, xmlField, value, resolveNamespacePrefixForURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, getNamespaceResolverForField(xmlField)), session);
        }
        return nodes;
    }

    public List<XMLEntry> replaceCollection(List<Field> xmlFields, List<XMLEntry> values, Node contextNode, DocumentPreservationPolicy docPresPolicy, Field lastUpdatedField, CoreAbstractSession session) {
        List<XMLEntry> oldNodes = unmarshalXPathEngine.selectNodes(contextNode, xmlFields, getNamespaceResolverForField(xmlFields.get(0)));
        if(oldNodes == null || oldNodes.size() == 0) {
            return oldNodes;
        }

        Iterator<XMLEntry> oldValues = oldNodes.iterator();
        //Remove all the old values, and then call create to add them back in.
        while(oldValues.hasNext()) {
            XMLEntry entry = oldValues.next();
            Node nextNode = (Node)entry.getValue();
            Node parent = nextNode.getParentNode();
            parent.removeChild(nextNode);
            while(parent != contextNode) {
                if(parent.getChildNodes().getLength() == 0) {
                    nextNode = parent;
                    parent = nextNode.getParentNode();
                    parent.removeChild(nextNode);
                } else {
                    break;
                }
            }
        }

        create(xmlFields, contextNode, values, lastUpdatedField, xmlBinderPolicy, session);

        return oldNodes;
    }
    public NodeList replaceCollection(Field xmlField, Node parent, Collection values, CoreAbstractSession session) throws XMLMarshalException {
        NodeList nodes = null;
        if (xmlField != null) {
            nodes = unmarshalXPathEngine.selectNodes(parent, xmlField, getNamespaceResolverForField(xmlField));
        } else {
            nodes = parent.getChildNodes();
        }
        if (nodes.getLength() == 0) {
            return nodes;
        }
        Iterator collectionValues = values.iterator();
        int i = 0;

        int nodesLength = nodes.getLength();
        Vector newNodes = new Vector();

        // Iterate over both collections until one runs out, creating a collection of correct nodes
        // while removing the old ones.
        boolean performedReplace = true;
        Object value = null;
        while ((i < nodesLength) && collectionValues.hasNext()) {
            //Keep track of which nodes have been replaced
            Node oldChild = nodes.item(i);
            Element newChild = null;
            if (performedReplace) {
                value = collectionValues.next();
            }
            Node parentNode = oldChild.getParentNode();

            // Handle Attributes and Text
            if (oldChild.getNodeType() != Node.ELEMENT_NODE) {
                if (((oldChild.getNodeType() == Node.TEXT_NODE) || (oldChild.getNodeType() == Node.CDATA_SECTION_NODE)) && (value == null)) {
                    Node grandParentNode = parentNode.getParentNode();
                    grandParentNode.removeChild(parentNode);
                } else {
                    oldChild.setNodeValue(session.getDatasourcePlatform().getConversionManager().convertObject(value, CoreClassConstants.STRING));
                }
            } else {
                Element element = (Element)oldChild;
                String elementName = element.getTagName();
                Object valueToWrite = getValueToWrite(value, xmlField, session);
                XPathFragment childFragment = new XPathFragment(elementName);
                childFragment.setNamespaceURI(element.getNamespaceURI());
                newChild = (Element)createElement(parentNode, childFragment, xmlField, valueToWrite, session);
                if (!newNodes.contains(oldChild)) {
                    if (newChild != oldChild) {
                        parentNode.replaceChild(newChild, oldChild);
                    }
                    newNodes.addElement(newChild);
                    performedReplace = true;
                } else {
                    performedReplace = false;
                }
            }
            i++;
        }

        // This means collection was ran out first. Remove left-overs.
        while (i < nodesLength) {
            Node toRemove = nodes.item(i);
            Node removedParent = toRemove.getParentNode();
            if ((removedParent != null) && !newNodes.contains(toRemove)) {
                //only remove it, if it's not already been added back in
                removedParent.removeChild(toRemove);
            }
            i++;
        }

        //Now add the nodes back in, in the correct order
        //for (Iterator newNodesIter = newNodes.iterator(); newNodesIter.hasNext();) {
        // Element newNode = (Element)newNodesIter.next();
        //this.create(xmlField, parent, newNode);
        //}
        if ((value != null) && !performedReplace) {
            //If we didn't add in the last element we tried then add it now
            if ((xmlField.getXPathFragment().getNextFragment() == null) || xmlField.getXPathFragment().getHasText()) {
                //if there's no grouping element, ensure that new collection elements
                //are added inline with the others
                create(xmlField, parent, value, xmlField, xmlBinderPolicy, session);
            } else {
                create(xmlField, parent, value, session);
            }
        }

        // Now add in any others that are left in the iterator
        while (collectionValues.hasNext()) {
            value = collectionValues.next();
            //If there's a grouping element, then just do the normal create
            if ((xmlField.getXPathFragment().getNextFragment() == null) || xmlField.getXPathFragment().getHasText()) {
                //if there's no grouping element, ensure that new collection elements
                //are added inline with the others
                create(xmlField, parent, value, xmlField, xmlBinderPolicy, session);
            } else {
                create(xmlField, parent, value, session);
            }
        }

        return nodes;
    }

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

    /**
    * Determine if <code>xpathString</code> contains an index (e.g. 'element[index]').
    *
    * @param xpathString XPath expression to test
    *
    * @return <code>true</code> if <code>xpathString</code> contains an index, otherwise <code>false</code>.
    */
    private boolean containsIndex(String xpathString) {
        return (xpathString.lastIndexOf('[') != -1) && (xpathString.lastIndexOf(']') != -1);
    }

    private String resolveNamespacePrefix(XPathFragment fragment, NamespaceResolver namespaceResolver) {
        try {
            if (fragment.getNamespaceURI() != null) {
                return fragment.getNamespaceURI();
            }
            if(fragment.getPrefix() == null && fragment.isAttribute()) {
                return null;
            }
            return namespaceResolver.resolveNamespacePrefix(fragment.getPrefix());
        } catch (Exception e) {
            return null;
        }
    }

    private String resolveNamespacePrefixForURI(String namespaceURI, NamespaceResolver namespaceResolver) {
        if (null == namespaceResolver) {
            return null;
        }
       return  namespaceResolver.resolveNamespaceURI(namespaceURI);
    }

    private Node addText(Field xmlField, Node element, String textValue) {
        if (xmlField.isCDATA()) {
            CDATASection cdata = element.getOwnerDocument().createCDATASection(textValue);
            element.appendChild(cdata);
            return cdata;
        } else {
            Text text = element.getOwnerDocument().createTextNode(textValue);
            element.appendChild(text);
            return text;
        }
    }
    private String getStringForQName(QName qName, NamespaceResolver namespaceResolver){
        if(null == qName) {
            return null;
        }

        if(null == qName.getNamespaceURI()) {
            return qName.getLocalPart();
        } else {
            String namespaceURI = qName.getNamespaceURI();
            if(namespaceResolver == null){
                throw XMLMarshalException.namespaceResolverNotSpecified(namespaceURI);
            }
            String prefix = namespaceResolver.resolveNamespaceURI(namespaceURI);
            if(null == prefix) {
                return qName.getLocalPart();
            } else {
                return prefix + Constants.COLON + qName.getLocalPart();
            }
        }

    }

    private NamespaceResolver getNamespaceResolverForField(Field field){
        NamespaceResolver nr = (org.eclipse.persistence.oxm.NamespaceResolver) field.getNamespaceResolver();
        if(nr == null){
            field.setNamespaceResolver(new NamespaceResolver());
        }
        return (org.eclipse.persistence.oxm.NamespaceResolver) field.getNamespaceResolver();
    }

    private void addXsiNilToElement(Element element, Field xmlField) {
        NamespaceResolver nsr = new NamespaceResolver();
        nsr.setDOM(element);

        String  schemaInstancePrefix = resolveNamespacePrefixForURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, nsr);
        Node parentNode = element.getParentNode();
        while(schemaInstancePrefix == null && parentNode != null && parentNode.getNodeType() == Node.ELEMENT_NODE){
            nsr.setDOM(element);
            schemaInstancePrefix = resolveNamespacePrefixForURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, nsr);
            parentNode = parentNode.getParentNode();
        }
        if(schemaInstancePrefix == null && element.getOwnerDocument() != null){
            nsr.setDOM(element.getOwnerDocument().getDocumentElement());
            schemaInstancePrefix = resolveNamespacePrefixForURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, nsr);
        }

        if(schemaInstancePrefix == null) {
            //Not decalred in the doc
            nsr = getNamespaceResolverForField(xmlField);
            schemaInstancePrefix = nsr.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
            if(schemaInstancePrefix == null) {
                schemaInstancePrefix = nsr.generatePrefix(Constants.SCHEMA_INSTANCE_PREFIX);
            }
            element.setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + schemaInstancePrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
        }
        element.setAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_INSTANCE_PREFIX + Constants.COLON + Constants.SCHEMA_NIL_ATTRIBUTE, Constants.BOOLEAN_STRING_TRUE);

    }
}
