/*
 * Copyright (c) 2013, 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:
//     Blaise Doughan - 2.5 - initial implementation
package org.eclipse.persistence.internal.oxm;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.descriptors.CoreDescriptor;
import org.eclipse.persistence.core.mappings.CoreMapping;
import org.eclipse.persistence.core.mappings.transformers.CoreFieldTransformer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.descriptors.CoreObjectBuilder;
import org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractRecord;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.oxm.mappings.AnyAttributeMapping;
import org.eclipse.persistence.internal.oxm.mappings.AnyCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.AnyObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataMapping;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.CollectionReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.DirectCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.DirectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.FragmentCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.FragmentMapping;
import org.eclipse.persistence.internal.oxm.mappings.InverseReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.TransformationMapping;
import org.eclipse.persistence.internal.oxm.mappings.VariableXPathCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.VariableXPathObjectMapping;
import org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecord;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext;
import org.eclipse.persistence.internal.oxm.record.SequencedMarshalContext;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl;
import org.eclipse.persistence.internal.oxm.record.XMLRecord;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.mappings.UnmarshalKeepAsElementPolicy;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.sequenced.SequencedObject;
import org.eclipse.persistence.sessions.Session;

public class XPathObjectBuilder extends CoreObjectBuilder<CoreAbstractRecord, CoreAbstractSession, CoreField, CoreMapping> implements ObjectBuilder {

    public static final String CYCLE_RECOVERABLE = "org.glassfish.jaxb.runtime.CycleRecoverable";
    public static final String CYCLE_RECOVERABLE_CONTEXT = "org.glassfish.jaxb.runtime.CycleRecoverable$Context";
    private static final String CYCLE_RECOVERABLE_OLD = "com.sun.xml.bind.CycleRecoverable";
    private static final String CYCLE_RECOVERABLE_CONTEXT_OLD = "com.sun.xml.bind.CycleRecoverable$Context";
    public static final String ON_CYCLE_DETECTED = "onCycleDetected";

    private List<ContainerValue> containerValues;
    private int counter = 0;
    private Class cycleRecoverableClass = null;
    private Class cycleRecoverableContextClass = null;
    private List<ContainerValue> defaultEmptyContainerValues; //a list of container values that have isDefaultEmptyContainer() set to true
    private CoreDescriptor descriptor;
    private volatile boolean initialized = false;
    private List<NullCapableValue> nullCapableValues;
    private XPathNode rootXPathNode;
    private List<TransformationMapping> transformationMappings;
    private boolean xsiTypeIndicatorField;

    public XPathObjectBuilder(CoreDescriptor descriptor) {
        this.descriptor = descriptor;
        this.rootXPathNode = new XPathNode();
    }

    private XPathNode addChild(XPathFragment xPathFragment, NodeValue nodeValue, NamespaceResolver namespaceResolver) {
        return rootXPathNode.addChild(xPathFragment, nodeValue, namespaceResolver);
    }

    @Override
    public boolean addClassIndicatorFieldToRow(AbstractMarshalRecord abstractMarshalRecord) {
        if (descriptor.hasInheritance() && !xsiTypeIndicatorField) {
            descriptor.getInheritancePolicy().addClassIndicatorFieldToRow((CoreAbstractRecord) abstractMarshalRecord);
            return true;
        }
        return false;
    }

    private void addContainerValue(ContainerValue containerValue) {
        if (null == this.containerValues) {
            this.containerValues = new ArrayList();
        }
        containerValue.setIndex(counter++);
        this.containerValues.add(containerValue);

        if(containerValue.isDefaultEmptyContainer()){
            addDefaultEmptyContainerValue(containerValue);
        }
    }

    private void addDefaultEmptyContainerValue(ContainerValue containerValue){
        if (null == this.defaultEmptyContainerValues) {
            this.defaultEmptyContainerValues = new ArrayList();
        }
        this.defaultEmptyContainerValues.add(containerValue);
    }

    @Override
    public List<Namespace> addExtraNamespacesToNamespaceResolver(Descriptor desc, AbstractMarshalRecord marshalRecord, CoreAbstractSession session, boolean allowOverride, boolean ignoreEqualResolvers) {
        if (rootXPathNode.getNonAttributeChildren() == null) {
            return null;
        } else {
            return marshalRecord.addExtraNamespacesToNamespaceResolver(desc, session, allowOverride, ignoreEqualResolvers);
        }
    }

    private void addNullCapableValue(NullCapableValue nullCapableValue) {
        if (null == this.nullCapableValues) {
            this.nullCapableValues = new ArrayList();
        }
        this.nullCapableValues.add(nullCapableValue);
    }

    public void addTransformationMapping(TransformationMapping transformationMapping) {
        if (null == this.transformationMappings) {
            this.transformationMappings = new ArrayList();
        }
        transformationMappings.add(transformationMapping);
    }

    /**
     * Return a new instance of the receiver's javaClass.
     */
    @Override
    public Object buildNewInstance() {
        return this.descriptor.getInstantiationPolicy().buildNewInstance();
    }

    @Override
    public XMLRecord buildRow(XMLRecord record, Object object,
            CoreAbstractSession session, Marshaller marshaller,
            XPathFragment rootFragment) {
        lazyInitialize();
        XPathNode textNode = rootXPathNode.getTextNode();
        List<XPathNode> nonAttributeChildren = rootXPathNode.getNonAttributeChildren();
        if (null == textNode && null == nonAttributeChildren) {
            return record;
        }

        Descriptor xmlDescriptor = (Descriptor) descriptor;
        XPathNode node = rootXPathNode;
        MarshalRecord marshalRecord = (MarshalRecord) record;
        QName schemaType = null;

        if (marshalRecord.getCycleDetectionStack().contains(object, marshaller.isEqualUsingIdenity())) {
            if (cycleRecoverableClass == null) {
                initCycleRecoverableClasses();
            }
            if (cycleRecoverableClass != null && cycleRecoverableClass.isAssignableFrom(object.getClass())) {
                try {
                    Object jaxbMarshaller = marshaller.getProperty(Constants.JAXB_MARSHALLER);
                    // Create a proxy instance of CycleRecoverable$Context, a parameter to
                    // the onCycleDetected method
                    Object contextProxy = CycleRecoverableContextProxy.getProxy(cycleRecoverableContextClass, jaxbMarshaller);
                    // Invoke onCycleDetected method, passing in proxy, and reset
                    // 'object' to the returned value
                    Method onCycleDetectedMethod = object.getClass().getMethod(ON_CYCLE_DETECTED, new Class[] { cycleRecoverableContextClass });
                    object = PrivilegedAccessHelper.invokeMethod(onCycleDetectedMethod, object, new Object[] { contextProxy });
                } catch (Exception e) {
                    throw XMLMarshalException.marshalException(e);
                }

                // Returned object might have a different descriptor
                xmlDescriptor = (Descriptor) session.getDescriptor(object.getClass());
                if (xmlDescriptor != null) {
                    node = ((ObjectBuilder) xmlDescriptor.getObjectBuilder()).getRootXPathNode();
                } else {
                    node = null;
                }

                // Push new object
                marshalRecord.getCycleDetectionStack().push(object);

                // Write xsi:type if onCycleDetected returned an object of a type different than the one mapped
                if (xmlDescriptor != descriptor) {
                    if (xmlDescriptor == null) {
                        schemaType = record.getConversionManager().schemaType(object.getClass());
                    } else {
                        schemaType = xmlDescriptor.getSchemaReference().getSchemaContextAsQName();
                    }
                    marshalRecord.writeXsiTypeAttribute(xmlDescriptor, schemaType.getNamespaceURI(), schemaType.getLocalPart(), schemaType.getPrefix(), false);
                }
            } else {
                // Push the duplicate object anyway, so that we can get the complete cycle string
                marshalRecord.getCycleDetectionStack().push(object);
                throw XMLMarshalException.objectCycleDetected(marshalRecord.getCycleDetectionStack().getCycleString());
            }
        } else {
            marshalRecord.getCycleDetectionStack().push(object);
        }

        NamespaceResolver namespaceResolver = null;
        if (xmlDescriptor != null) {
            namespaceResolver = xmlDescriptor.getNamespaceResolver();
        }
        MarshalContext marshalContext = null;
        if (xmlDescriptor != null && xmlDescriptor.isSequencedObject()) {
            SequencedObject sequencedObject = (SequencedObject) object;
            marshalContext = new SequencedMarshalContext(sequencedObject.getSettings());
        } else {
            marshalContext = ObjectMarshalContext.getInstance();
        }
        if (null == nonAttributeChildren) {
            textNode.marshal((MarshalRecord) record, object, session, namespaceResolver, marshaller, marshalContext, rootFragment);
        } else {
            if (node == null) {
                // No descriptor for this object, so manually create a MappingNodeValue and marshal it
                XPathNode n = new XPathNode();
                CompositeObjectMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, UnmarshalKeepAsElementPolicy, XMLUnmarshaller, org.eclipse.persistence.oxm.record.XMLRecord> m = new XMLCompositeObjectMapping();
                m.setXPath(".");
                XMLCompositeObjectMappingNodeValue nv = new XMLCompositeObjectMappingNodeValue(m);
                n.setMarshalNodeValue(nv);
                nv.marshalSingleValue(new XPathFragment("."), marshalRecord, null, object, session, namespaceResolver, marshalContext);
            } else {
                for (int x = 0, size = marshalContext.getNonAttributeChildrenSize(node); x < size; x++) {
                    XPathNode xPathNode = (XPathNode) marshalContext.getNonAttributeChild(x, node);
                    xPathNode.marshal((MarshalRecord) record, object, session, namespaceResolver, marshaller, marshalContext.getMarshalContext(x), rootFragment);
                }
            }
        }
        marshalRecord.getCycleDetectionStack().pop();
        return record;
    }

    @Override
    public Class classFromRow(UnmarshalRecord record, CoreAbstractSession session) {
        return descriptor.getInheritancePolicy().classFromRow((CoreAbstractRecord) record, session);
    }

    /**
     * Create a new row/record for the object builder.
     * This allows subclasses to define different record types.
     */
    @Override
    public CoreAbstractRecord createRecord(CoreAbstractSession session) {
        UnmarshalRecordImpl record = new UnmarshalRecordImpl(this);
        record.setSession(session);
        return record;
    }

    @Override
    public Object extractPrimaryKeyFromObject(Object object, CoreAbstractSession session) {
        throw new UnsupportedOperationException();
    }

    @Override
    public List<ContainerValue> getContainerValues() {
        return this.containerValues;
    }

    @Override
    public List<ContainerValue> getDefaultEmptyContainerValues() {
        return this.defaultEmptyContainerValues;
    }

    @Override
    public CoreDescriptor getDescriptor() {
        return descriptor;
    }

    @Override
    public CoreMapping getMappingForField(CoreField field) {
        throw new UnsupportedOperationException();
    }

    @Override
    public List<NullCapableValue> getNullCapableValues() {
        return this.nullCapableValues;
    }

    @Override
    public XPathNode getRootXPathNode() {
        lazyInitialize();
        return this.rootXPathNode;
    }

    @Override
    public List<TransformationMapping> getTransformationMappings() {
        return this.transformationMappings;
    }

    private void initCycleRecoverableClasses() {
        try {
            this.cycleRecoverableClass = PrivilegedAccessHelper.getClassForName(CYCLE_RECOVERABLE);
            this.cycleRecoverableContextClass = PrivilegedAccessHelper.getClassForName(CYCLE_RECOVERABLE_CONTEXT);
        } catch (Throwable e) {
            //try old one
            try {
                this.cycleRecoverableClass = PrivilegedAccessHelper.getClassForName(CYCLE_RECOVERABLE_OLD);
                this.cycleRecoverableContextClass = PrivilegedAccessHelper.getClassForName(CYCLE_RECOVERABLE_CONTEXT_OLD);
            } catch (Throwable e2) {
                //ignore
            }
        }
    }

    @Override
    public boolean isXsiTypeIndicatorField() {
        return xsiTypeIndicatorField;
    }

    void lazyInitialize() {
        if(initialized) {
            return;
        }
        synchronized(this) {
            if(initialized) {
                return;
            }
            Descriptor xmlDescriptor = (Descriptor) descriptor;

            // MAPPINGS
            Iterator mappingIterator = xmlDescriptor.getMappings().iterator();
            Iterator fieldTransformerIterator;
            Mapping xmlMapping;

            // Transformation Mapping
            TransformationMapping transformationMapping;
            FieldTransformerNodeValue fieldTransformerNodeValue;
            Object[] nextFieldToTransformer;

            // Simple Type Translator
            TypeNodeValue typeNodeValue;

            NodeValue mappingNodeValue = null;
            Field xmlField;
            while (mappingIterator.hasNext()) {
                xmlMapping = (Mapping)mappingIterator.next();

                xmlField = (Field)xmlMapping.getField();
                if (xmlMapping.isTransformationMapping()) {
                    transformationMapping = (TransformationMapping)xmlMapping;
                    addTransformationMapping(transformationMapping);
                    fieldTransformerIterator = transformationMapping.getFieldToTransformers().iterator();
                    while (fieldTransformerIterator.hasNext()) {
                        fieldTransformerNodeValue = new FieldTransformerNodeValue(transformationMapping);
                        nextFieldToTransformer = (Object[])fieldTransformerIterator.next();
                        xmlField = (Field)nextFieldToTransformer[0];
                        fieldTransformerNodeValue.setXMLField(xmlField);
                        fieldTransformerNodeValue.setFieldTransformer((CoreFieldTransformer)nextFieldToTransformer[1]);
                        addChild(xmlField.getXPathFragment(), fieldTransformerNodeValue, xmlDescriptor.getNamespaceResolver());
                    }
                } else {
                    if (xmlMapping.isAbstractDirectMapping()) {
                        mappingNodeValue = new XMLDirectMappingNodeValue((DirectMapping)xmlMapping);
                    } else if (xmlMapping.isAbstractCompositeObjectMapping()) {
                        mappingNodeValue = new XMLCompositeObjectMappingNodeValue((CompositeObjectMapping)xmlMapping);
                    } else if (xmlMapping.isAbstractCompositeCollectionMapping()) {
                        CompositeCollectionMapping collectionMapping = (CompositeCollectionMapping) xmlMapping;
                        mappingNodeValue = new XMLCompositeCollectionMappingNodeValue(collectionMapping);
                        if (collectionMapping.getWrapperNullPolicy() != null) {
                            addChild(xmlField.getXPathFragment(), new CollectionGroupingElementNodeValue((ContainerValue) mappingNodeValue), xmlDescriptor.getNamespaceResolver());
                        }
                    } else if (xmlMapping.isAbstractCompositeDirectCollectionMapping()) {
                        DirectCollectionMapping collectionMapping = (DirectCollectionMapping) xmlMapping;
                        mappingNodeValue = new XMLCompositeDirectCollectionMappingNodeValue(collectionMapping);
                        if (collectionMapping.getWrapperNullPolicy() != null) {
                            addChild(xmlField.getXPathFragment(), new CollectionGroupingElementNodeValue((ContainerValue) mappingNodeValue), xmlDescriptor.getNamespaceResolver());
                        }
                    } else if (xmlMapping instanceof InverseReferenceMapping) {
                        xmlMapping = (Mapping)((InverseReferenceMapping)xmlMapping).getInlineMapping();
                        if(xmlMapping == null){
                            continue;
                        }
                        xmlField = (Field)xmlMapping.getField();
                        if(xmlMapping.isAbstractCompositeCollectionMapping()){
                            mappingNodeValue=new XMLCompositeCollectionMappingNodeValue((CompositeCollectionMapping)xmlMapping, true);
                        }
                        if(xmlMapping.isAbstractCompositeObjectMapping()){
                            mappingNodeValue=new XMLCompositeObjectMappingNodeValue((CompositeObjectMapping)xmlMapping, true);
                        }

                    } else if (xmlMapping instanceof VariableXPathCollectionMapping) {
                        mappingNodeValue = new XMLVariableXPathCollectionMappingNodeValue((VariableXPathCollectionMapping)xmlMapping);
                    } else if (xmlMapping instanceof VariableXPathObjectMapping){
                        mappingNodeValue = new XMLVariableXPathObjectMappingNodeValue((VariableXPathObjectMapping)xmlMapping);
                    } else if (xmlMapping instanceof AnyObjectMapping) {
                        mappingNodeValue = new XMLAnyObjectMappingNodeValue((AnyObjectMapping)xmlMapping);
                    } else if (xmlMapping instanceof AnyCollectionMapping) {
                        mappingNodeValue = new XMLAnyCollectionMappingNodeValue((AnyCollectionMapping)xmlMapping);
                    } else if (xmlMapping instanceof AnyAttributeMapping) {
                        mappingNodeValue = new XMLAnyAttributeMappingNodeValue((AnyAttributeMapping)xmlMapping);
                    } else if (xmlMapping instanceof BinaryDataMapping) {
                        mappingNodeValue = new XMLBinaryDataMappingNodeValue((BinaryDataMapping)xmlMapping);
                    } else if (xmlMapping instanceof BinaryDataCollectionMapping) {
                        mappingNodeValue = new XMLBinaryDataCollectionMappingNodeValue((BinaryDataCollectionMapping)xmlMapping);
                    } else if (xmlMapping instanceof FragmentMapping) {
                        mappingNodeValue = new XMLFragmentMappingNodeValue((FragmentMapping)xmlMapping);
                    } else if (xmlMapping instanceof FragmentCollectionMapping) {
                        mappingNodeValue = new XMLFragmentCollectionMappingNodeValue((FragmentCollectionMapping)xmlMapping);
                    } else if (xmlMapping instanceof CollectionReferenceMapping) {
                        CollectionReferenceMapping xmlColMapping = (CollectionReferenceMapping)xmlMapping;

                        List fields = xmlColMapping.getFields();
                        Field xmlColMappingField = (Field) xmlColMapping.getField();
                        XPathNode branchNode;
                        if(null == xmlColMappingField) {
                            if(fields.size() > 1 && !xmlColMapping.usesSingleNode()) {
                                addChild(XPathFragment.SELF_FRAGMENT, new XMLCollectionReferenceMappingMarshalNodeValue(xmlColMapping), xmlDescriptor.getNamespaceResolver());
                            }
                            branchNode = rootXPathNode;
                        } else {
                            branchNode = addChild(((Field) xmlColMapping.getField()).getXPathFragment(), new XMLCollectionReferenceMappingMarshalNodeValue(xmlColMapping), xmlDescriptor.getNamespaceResolver());
                        }

                        int containerIndex = -1;
                        for (int i = 0, size = fields.size(); i < size; i++) {
                            Field xmlFld = (Field)fields.get(i);
                            mappingNodeValue = new XMLCollectionReferenceMappingNodeValue(xmlColMapping, xmlFld);
                            if(i == 0){
                                addContainerValue((ContainerValue)mappingNodeValue);
                                containerIndex = ((ContainerValue)mappingNodeValue).getIndex();
                            }else{
                                ((ContainerValue)mappingNodeValue).setIndex(containerIndex);
                            }
                            branchNode.addChild(xmlFld.getXPathFragment(), mappingNodeValue, xmlDescriptor.getNamespaceResolver());
                        }
                        continue;
                    } else if (xmlMapping instanceof ObjectReferenceMapping) {
                        ObjectReferenceMapping xmlORMapping = (ObjectReferenceMapping)xmlMapping;
                        Iterator fieldIt = xmlORMapping.getFields().iterator();
                        while (fieldIt.hasNext()) {
                            Field xmlFld = (Field)fieldIt.next();
                            mappingNodeValue = new XMLObjectReferenceMappingNodeValue(xmlORMapping, xmlFld);
                            addChild(xmlFld.getXPathFragment(), mappingNodeValue, xmlDescriptor.getNamespaceResolver());
                        }
                        continue;
                    } else if (xmlMapping instanceof ChoiceObjectMapping) {
                        ChoiceObjectMapping xmlChoiceMapping = (ChoiceObjectMapping)xmlMapping;
                        Iterator fields = xmlChoiceMapping.getChoiceElementMappings().keySet().iterator();
                        Field firstField = (Field)fields.next();
                        XMLChoiceObjectMappingNodeValue firstNodeValue = new XMLChoiceObjectMappingNodeValue(xmlChoiceMapping, firstField);
                        firstNodeValue.setNullCapableNodeValue(firstNodeValue);
                        addChild(firstField.getXPathFragment(), firstNodeValue, xmlDescriptor.getNamespaceResolver());
                        while(fields.hasNext()) {
                            Field next = (Field)fields.next();
                            XMLChoiceObjectMappingNodeValue nodeValue = new XMLChoiceObjectMappingNodeValue(xmlChoiceMapping, next);
                            nodeValue.setNullCapableNodeValue(firstNodeValue);
                            addChild(next.getXPathFragment(), nodeValue, xmlDescriptor.getNamespaceResolver());
                        }
                        continue;
                    } else if(xmlMapping instanceof ChoiceCollectionMapping) {
                        ChoiceCollectionMapping xmlChoiceMapping = (ChoiceCollectionMapping)xmlMapping;

                        Iterator<Entry<Field, Mapping>> fields = xmlChoiceMapping.getChoiceElementMappings().entrySet().iterator();
                        Entry<Field, Mapping> firstEntry = fields.next();
                        Field firstField = firstEntry.getKey();

                        XMLChoiceCollectionMappingUnmarshalNodeValue unmarshalValue = new XMLChoiceCollectionMappingUnmarshalNodeValue(xmlChoiceMapping, firstField);
                        XMLChoiceCollectionMappingMarshalNodeValue marshalValue = new XMLChoiceCollectionMappingMarshalNodeValue(xmlChoiceMapping, firstField);

                        //The reason behind LinkedHashMap is the order of items when for-cycling HashMap.getEntrySet() or HashMap.getKeySet().
                        //This change fixes non-determinism (implementation in JDK8 has changed so the order is different (sometimes) than in JDK6 and JDK7).
                        HashMap<Field, NodeValue> fieldToNodeValues = new LinkedHashMap<>();
                        unmarshalValue.setContainerNodeValue(unmarshalValue);
                        unmarshalValue.setFieldToNodeValues(fieldToNodeValues);
                        if(xmlChoiceMapping.isMixedContent() && (xmlChoiceMapping.getMixedContentMapping() == firstEntry.getValue())) {
                            unmarshalValue.setIsMixedNodeValue(true);
                            marshalValue.setIsMixedNodeValue(true);
                        }
                        this.addContainerValue(unmarshalValue);
                        ((ContainerValue)unmarshalValue.getChoiceElementNodeValue()).setIndex(unmarshalValue.getIndex());
                        fieldToNodeValues.put(firstField, unmarshalValue);
                        addChild(firstField.getXPathFragment(), unmarshalValue, xmlDescriptor.getNamespaceResolver());
                        addChild(firstField.getXPathFragment(), marshalValue, xmlDescriptor.getNamespaceResolver());
                        while(fields.hasNext()) {
                            Entry<Field, Mapping> nextEntry = fields.next();
                            Field nextField = nextEntry.getKey();
                            XMLChoiceCollectionMappingUnmarshalNodeValue nodeValue = new XMLChoiceCollectionMappingUnmarshalNodeValue(xmlChoiceMapping, nextField);
                            nodeValue.setContainerNodeValue(unmarshalValue);
                            nodeValue.setIndex(unmarshalValue.getIndex());
                            ((ContainerValue)nodeValue.getChoiceElementNodeValue()).setIndex(unmarshalValue.getIndex());
                            addChild(nextField.getXPathFragment(), nodeValue, xmlDescriptor.getNamespaceResolver());
                            fieldToNodeValues.put(nextField, nodeValue);
                            if(xmlChoiceMapping.isMixedContent() && (xmlChoiceMapping.getMixedContentMapping() == nextEntry.getValue())) {
                                nodeValue.setIsMixedNodeValue(true);
                            }
                        }
                        if(xmlChoiceMapping.isAny()) {
                            XMLChoiceCollectionMappingUnmarshalNodeValue nodeValue = new XMLChoiceCollectionMappingUnmarshalNodeValue(xmlChoiceMapping, null, xmlChoiceMapping.getAnyMapping());
                             nodeValue.setContainerNodeValue(unmarshalValue);
                             nodeValue.setIndex(unmarshalValue.getIndex());
                             ((ContainerValue)nodeValue.getChoiceElementNodeValue()).setIndex(unmarshalValue.getIndex());
                             addChild(null, nodeValue, xmlDescriptor.getNamespaceResolver());
                             fieldToNodeValues.put(null, nodeValue);
                             if(xmlChoiceMapping.isMixedContent()) {
                                 nodeValue.setIsMixedNodeValue(true);
                             }
                        }
                        marshalValue.setFieldToNodeValues(fieldToNodeValues);
                        continue;
                    }
                    if (mappingNodeValue.isContainerValue()) {
                        addContainerValue((ContainerValue)mappingNodeValue);
                    }
                    if (mappingNodeValue.isNullCapableValue()) {
                        addNullCapableValue((NullCapableValue)mappingNodeValue);
                    }
                    if (xmlField != null) {
                        addChild(xmlField.getXPathFragment(), mappingNodeValue, xmlDescriptor.getNamespaceResolver());
                    } else {
                        addChild(null, mappingNodeValue, xmlDescriptor.getNamespaceResolver());
                    }
                }
            }

            if (descriptor.hasInheritance()) {
                Field indicatorField = (Field) descriptor
                        .getInheritancePolicy().getClassIndicatorField();
                if (indicatorField != null) {
                    if (indicatorField.getLastXPathFragment().getNamespaceURI() != null
                            && indicatorField
                                    .getLastXPathFragment()
                                    .getNamespaceURI()
                                    .equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI)
                            && indicatorField.getLastXPathFragment()
                                    .getLocalName()
                                    .equals(Constants.SCHEMA_TYPE_ATTRIBUTE)) {
                        xsiTypeIndicatorField = true;
                    }

                }
            }

            initialized = true;
        }
    }

    @Override
    public boolean marshalAttributes(MarshalRecord marshalRecord, Object object, CoreAbstractSession session) {
        lazyInitialize();
        boolean hasValue = false;
        NamespaceResolver namespaceResolver = ((Descriptor)descriptor).getNamespaceResolver();

        List<XPathNode> attributeChildren = rootXPathNode.getAttributeChildren();
        if (null != attributeChildren) {
            ObjectMarshalContext objectMarshalContext = ObjectMarshalContext.getInstance();
            for (XPathNode anAttributeChildren : attributeChildren) {
                hasValue = anAttributeChildren.marshal(marshalRecord, object, session, namespaceResolver, null, objectMarshalContext, null) || hasValue;
            }
        }

        if (rootXPathNode.getAnyAttributeNode() != null) {
            hasValue = rootXPathNode.getAnyAttributeNode().marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance(), null) || hasValue;
        }

        List<XPathNode> selfChildren = rootXPathNode.getSelfChildren();
        if (null != selfChildren) {
            for (XPathNode selfXPathNode : selfChildren) {
                NodeValue marshalNodeValue = selfXPathNode.getMarshalNodeValue();
                if(marshalNodeValue instanceof MappingNodeValue) {
                    Mapping selfMapping = ((MappingNodeValue) marshalNodeValue).getMapping();
                    Object value = selfMapping.getAttributeValueFromObject(object);
                    Descriptor referenceDescriptor = (Descriptor)selfMapping.getReferenceDescriptor();
                    Descriptor valueDescriptor;
                    if(value != null && (referenceDescriptor == null || referenceDescriptor.hasInheritance())){
                        valueDescriptor = (Descriptor)session.getDescriptor(value.getClass());
                    } else {
                        valueDescriptor = referenceDescriptor;
                    }
                    if(null != valueDescriptor) {
                       marshalRecord.addXsiTypeAndClassIndicatorIfRequired(valueDescriptor, referenceDescriptor, (Field) selfMapping.getField(), false);
                    }
                }
                selfXPathNode.marshalSelfAttributes(marshalRecord, object, session, namespaceResolver, marshalRecord.getMarshaller());
            }
        }

        return hasValue;
    }

    @Override
    public CoreAbstractRecord createRecordFromXMLContext(XMLContext context) {
        return createRecord((AbstractSession)context.getSession());
    }

}
