/*
 * Copyright (c) 1998, 2019 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
    *
    * @exception org.eclipse.persistence.oxm.exceptions.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 = (String) ((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 = (String) ((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 (String) ((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 xpathString element and index to create (in the form 'element[index]')
    * @param namespaceResolover namespaceResolover of the element being created
    * @param parent Parent element
    * @param schemaType schemaType for the new node
    * @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
    *
    * @exception org.eclipse.persistence.oxm.exceptions.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 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 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 element 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 namespace namespace of element to create
    * @param parent Parent element
    * @param schemaType schemaType of element to create
    * @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 elementName 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 simpleTypeTranslator SimpleTypeTranslator to perform lookup in
    * @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 elementName 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 attributeName 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 = (String)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((String) 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);

    }
}
