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

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.jaxb.compiler;

import java.awt.Image;
import java.beans.Introspector;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableSet;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeSet;

import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlMixed;
import jakarta.xml.bind.annotation.XmlTransient;
import jakarta.xml.bind.annotation.XmlValue;
import jakarta.xml.bind.annotation.adapters.CollapsedStringAdapter;
import jakarta.xml.bind.annotation.adapters.NormalizedStringAdapter;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.core.descriptors.CoreDescriptor;
import org.eclipse.persistence.core.mappings.CoreMapping;
import org.eclipse.persistence.core.mappings.converters.CoreConverter;
import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.core.sessions.CoreProject;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.JAXBException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.InstantiationPolicy;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.descriptors.VirtualAttributeAccessor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.jaxb.AccessorFactoryWrapper;
import org.eclipse.persistence.internal.jaxb.CustomAccessorAttributeAccessor;
import org.eclipse.persistence.internal.jaxb.DefaultElementConverter;
import org.eclipse.persistence.internal.jaxb.DomHandlerConverter;
import org.eclipse.persistence.internal.jaxb.JAXBElementConverter;
import org.eclipse.persistence.internal.jaxb.JAXBElementRootConverter;
import org.eclipse.persistence.internal.jaxb.JAXBSetMethodAttributeAccessor;
import org.eclipse.persistence.internal.jaxb.JaxbClassLoader;
import org.eclipse.persistence.internal.jaxb.MultiArgInstantiationPolicy;
import org.eclipse.persistence.internal.jaxb.WrappedValue;
import org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter;
import org.eclipse.persistence.internal.jaxb.many.JAXBArrayAttributeAccessor;
import org.eclipse.persistence.internal.jaxb.many.ManyValue;
import org.eclipse.persistence.internal.jaxb.many.MapValue;
import org.eclipse.persistence.internal.jaxb.many.MapValueAttributeAccessor;
import org.eclipse.persistence.internal.libraries.asm.EclipseLinkASMClassWriter;
import org.eclipse.persistence.internal.libraries.asm.MethodVisitor;
import org.eclipse.persistence.internal.libraries.asm.Opcodes;
import org.eclipse.persistence.internal.libraries.asm.Type;
import org.eclipse.persistence.internal.localization.JAXBLocalization;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
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.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.mappings.XMLContainerMapping;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.eclipse.persistence.internal.oxm.record.XMLTransformationRecord;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jaxb.JAXBEnumTypeConverter;
import org.eclipse.persistence.jaxb.TypeMappingInfo;
import org.eclipse.persistence.jaxb.javamodel.Helper;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaField;
import org.eclipse.persistence.jaxb.javamodel.JavaMethod;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAbstractNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper;
import org.eclipse.persistence.jaxb.xmlmodel.XmlIsSetNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes.XmlJoinNode;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNamedAttributeNode;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNamedObjectGraph;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNamedSubgraph;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation;
import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation.XmlReadTransformer;
import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation.XmlWriteTransformer;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.mappings.FixedMimeTypePolicy;
import org.eclipse.persistence.oxm.mappings.MimeTypePolicy;
import org.eclipse.persistence.oxm.mappings.UnmarshalKeepAsElementPolicy;
import org.eclipse.persistence.oxm.mappings.XMLAnyAttributeMapping;
import org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLCollectionReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLMapping;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLTransformationMapping;
import org.eclipse.persistence.oxm.mappings.XMLVariableXPathCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLVariableXPathObjectMapping;
import org.eclipse.persistence.oxm.mappings.converters.XMLConverter;
import org.eclipse.persistence.oxm.mappings.converters.XMLListConverter;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.IsSetNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.NullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.oxm.schema.XMLSchemaClassPathReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;

/**
 * INTERNAL:
 * <p><b>Purpose:</b>To generate a TopLink OXM Project based on Java Class and TypeInfo information
 * <p><b>Responsibilities:</b><ul>
 * <li>Generate a XMLDescriptor for each TypeInfo object</li>
 * <li>Generate a mapping for each TypeProperty object</li>
 * <li>Determine the correct mapping type based on the type of each property</li>
 * <li>Set up Converters on mappings for XmlAdapters or JDK 1.5 Enumeration types.</li>
 * </ul>
 * <p>This class is invoked by a Generator in order to create a TopLink Project.
 * This is generally used by JAXBContextFactory to create the runtime project. A Descriptor will
 * be generated for each TypeInfo and Mappings generated for each Property. In the case that a
 * non-transient property's type is a user defined class, a Descriptor and Mappings will be generated
 * for that class as well.
 * @see org.eclipse.persistence.jaxb.compiler.Generator
 * @see org.eclipse.persistence.jaxb.compiler.TypeInfo
 * @see org.eclipse.persistence.jaxb.compiler.Property
 * @author mmacivor
 * @since Oracle TopLink 11.1.1.0.0
 *
 */
public class MappingsGenerator {
    private static final String ATT = "@";
    private static final String TXT = "/text()";
    private static String OBJECT_CLASS_NAME = "java.lang.Object";
    public static final QName RESERVED_QNAME = new QName("urn:ECLIPSELINK_RESERVEDURI", "RESERVEDNAME");

    String outputDir = ".";
    private Map<String, QName> userDefinedSchemaTypes;
    private Helper helper;
    private JavaClass jotArrayList;
    private JavaClass jotHashSet;
    private JavaClass jotHashMap;
    private JavaClass jotLinkedList;
    private JavaClass jotTreeSet;
    private Map<String, PackageInfo> packageToPackageInfoMappings;
    private Map<String, TypeInfo> typeInfo;
    private Map<QName, Class> qNamesToGeneratedClasses;
    private Map<String, Class> classToGeneratedClasses;
    private Map<QName, Class> qNamesToDeclaredClasses;
    private Map<QName, ElementDeclaration> globalElements;
    private List<ElementDeclaration> localElements;
    private Map<TypeMappingInfo, Class> typeMappingInfoToGeneratedClasses;
    private Map<MapEntryGeneratedKey, Class> generatedMapEntryClasses;
    private CoreProject project;
    private org.eclipse.persistence.oxm.NamespaceResolver globalNamespaceResolver;
    private boolean isDefaultNamespaceAllowed;
    private Map<TypeMappingInfo, Class>typeMappingInfoToAdapterClasses;

    public MappingsGenerator(Helper helper) {
        this.helper = helper;
        jotArrayList = helper.getJavaClass(ArrayList.class);
        jotHashSet = helper.getJavaClass(HashSet.class);
        jotHashMap = helper.getJavaClass(HashMap.class);
        jotLinkedList = helper.getJavaClass(LinkedList.class);
        jotTreeSet = helper.getJavaClass(TreeSet.class);
        qNamesToGeneratedClasses = new HashMap<>();
        qNamesToDeclaredClasses = new HashMap<>();
        classToGeneratedClasses = new HashMap<>();
        globalNamespaceResolver = new org.eclipse.persistence.oxm.NamespaceResolver();
        isDefaultNamespaceAllowed = true;
    }

    public CoreProject generateProject(List<JavaClass> typeInfoClasses, Map<String, TypeInfo> typeInfo, Map<String, QName> userDefinedSchemaTypes, Map<String, PackageInfo> packageToPackageInfoMappings, Map<QName, ElementDeclaration> globalElements, List<ElementDeclaration> localElements, Map<TypeMappingInfo, Class> typeMappingInfoToGeneratedClass, Map<TypeMappingInfo, Class> typeMappingInfoToAdapterClasses,  boolean isDefaultNamespaceAllowed) throws Exception {
        this.typeInfo = typeInfo;
        this.userDefinedSchemaTypes = userDefinedSchemaTypes;
        this.packageToPackageInfoMappings = packageToPackageInfoMappings;
        this.isDefaultNamespaceAllowed = isDefaultNamespaceAllowed;
        this.globalElements = globalElements;
        this.localElements = localElements;
        this.typeMappingInfoToGeneratedClasses = typeMappingInfoToGeneratedClass;
        this.typeMappingInfoToAdapterClasses = typeMappingInfoToAdapterClasses;
        project = new Project();

        processDefaultNamespacePreferences(packageToPackageInfoMappings.values());

        // Generate descriptors
        for (JavaClass next : typeInfoClasses) {
            if (!next.isEnum()) {
                generateDescriptor(next, project);
            }
        }
        // Setup inheritance
        for (JavaClass next : typeInfoClasses) {
            if (!next.isEnum()) {
                setupInheritance(next);
            }
        }

        // Now create mappings
        generateMappings();

        // Setup AttributeGroups
        for(JavaClass next : typeInfoClasses) {
            setupAttributeGroups(next);
        }

        // apply customizers if necessary
        Set<Entry<String, TypeInfo>> entrySet = this.typeInfo.entrySet();
        for (Entry<String, TypeInfo> entry : entrySet) {
            TypeInfo tInfo = entry.getValue();
            if (tInfo.getXmlCustomizer() != null) {
                String customizerClassName = tInfo.getXmlCustomizer();
                try {
                    Class<Object> customizerClass = PrivilegedAccessHelper.getClassForName(customizerClassName, true, helper.getClassLoader());
                    DescriptorCustomizer descriptorCustomizer = (DescriptorCustomizer) PrivilegedAccessHelper.newInstanceFromClass(customizerClass);
                    descriptorCustomizer.customize((XMLDescriptor)tInfo.getDescriptor());
                } catch (IllegalAccessException iae) {
                    throw JAXBException.couldNotCreateCustomizerInstance(iae, customizerClassName);
                } catch (InstantiationException ie) {
                    throw JAXBException.couldNotCreateCustomizerInstance(ie, customizerClassName);
                } catch (ClassCastException cce) {
                    throw JAXBException.invalidCustomizerClass(cce, customizerClassName);
                } catch (ClassNotFoundException cnfe) {
                    throw JAXBException.couldNotCreateCustomizerInstance(cnfe, customizerClassName);
                }
            }
        }

        processGlobalElements(project);
        return project;
    }

    private void setupAttributeGroups(JavaClass javaClass) {
        TypeInfo info = this.typeInfo.get(javaClass.getQualifiedName());
        XMLDescriptor descriptor = (XMLDescriptor)info.getDescriptor();

        if(!info.getObjectGraphs().isEmpty()) {
            for(XmlNamedObjectGraph next:info.getObjectGraphs()) {
                AttributeGroup group = descriptor.getAttributeGroup(next.getName());
                Map<String, List<CoreAttributeGroup>> subgraphs = processSubgraphs(next.getXmlNamedSubgraph());
                for(XmlNamedAttributeNode nextAttributeNode:next.getXmlNamedAttributeNode()) {
                    if(nextAttributeNode.getSubgraph() == null || nextAttributeNode.getSubgraph().length() == 0) {
                        group.addAttribute(nextAttributeNode.getName());
                    } else {
                        List<CoreAttributeGroup> nestedGroups = subgraphs.get(nextAttributeNode.getSubgraph());
                        if(nestedGroups == null || nestedGroups.isEmpty()) {
                            Property property = info.getProperties().get(nextAttributeNode.getName());
                            if(property == null) {
                                //if there's no property associated with the attributeNode, just ignore it
                                continue;
                            }
                            JavaClass cls = property.getActualType();
                            TypeInfo referenceType = typeInfo.get(cls.getQualifiedName());
                            if(referenceType != null) {
                                AttributeGroup targetGroup = (AttributeGroup)referenceType.getDescriptor().getAttributeGroup(nextAttributeNode.getSubgraph());
                                group.addAttribute(nextAttributeNode.getName(), targetGroup);
                            } else {
                                //TODO: Exception
                            }
                        } else {
                            if(nestedGroups.size() == 1) {
                                group.addAttribute(nextAttributeNode.getName(), nestedGroups.get(0));
                            } else {
                                group.addAttribute(nextAttributeNode.getName(), nestedGroups);
                            }
                        }
                    }
                }


                for(XmlNamedSubgraph nextSubclass:next.getXmlNamedSubclassGraph()) {
                    AttributeGroup subclassGroup = new AttributeGroup(next.getName(), nextSubclass.getType(), true);
                    group.getSubClassGroups().put(nextSubclass.getType(), subclassGroup);
                    for(XmlNamedAttributeNode nextAttributeNode:nextSubclass.getXmlNamedAttributeNode()) {
                        if(nextAttributeNode.getSubgraph() == null || nextAttributeNode.getSubgraph().length() == 0) {
                            subclassGroup.addAttribute(nextAttributeNode.getName());
                        } else {
                            List<CoreAttributeGroup> nestedGroups = subgraphs.get(nextAttributeNode.getSubgraph());
                            if(nestedGroups == null || nestedGroups.isEmpty()) {
                                Property property = info.getProperties().get(nextAttributeNode.getName());
                                JavaClass cls = property.getActualType();
                                TypeInfo referenceType = typeInfo.get(cls.getQualifiedName());
                                if(referenceType != null) {
                                    AttributeGroup targetGroup = (AttributeGroup)referenceType.getDescriptor().getAttributeGroup(nextAttributeNode.getSubgraph());
                                    subclassGroup.addAttribute(nextAttributeNode.getName(), targetGroup);
                                } else {
                                    //TODO: Exception
                                }
                            } else {
                                if(nestedGroups.size() == 1) {
                                    subclassGroup.addAttribute(nextAttributeNode.getName(), nestedGroups.get(0));
                                } else {
                                    subclassGroup.addAttribute(nextAttributeNode.getName(), nestedGroups);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private Map<String, List<CoreAttributeGroup>> processSubgraphs(List<XmlNamedSubgraph> subgraphs) {
        Map<String, List<CoreAttributeGroup>> subgroups = new HashMap<>();
        //Iterate through once and create all the AttributeGroups
        for(XmlNamedSubgraph next: subgraphs) {
            String type = next.getType();
            if(type == null) {
                type = "java.lang.Object";
            }
            AttributeGroup group = new AttributeGroup(next.getName(), type, false);
            if(subgroups.containsKey(group.getName())) {
                List<CoreAttributeGroup> groups = subgroups.get(group.getName());
                groups.add(group);
            } else {
                List<CoreAttributeGroup> groups = new ArrayList<>(1);
                groups.add(group);
                subgroups.put(group.getName(), groups);
            }
        }

        //Iterate through a second time to populate the groups and set up links.
        for(XmlNamedSubgraph next:subgraphs) {
            List<XmlNamedAttributeNode> attributeNodes = next.getXmlNamedAttributeNode();
            List<CoreAttributeGroup> attributeGroups = subgroups.get(next.getName());
            if(attributeGroups != null) {
                for(CoreAttributeGroup group:attributeGroups) {
                    String typeName = next.getType();
                    if(typeName == null) {
                        typeName = "java.lang.Object";
                    }
                    if(group.getTypeName().equals(typeName)) {
                        for(XmlNamedAttributeNode attributeNode:attributeNodes) {
                            if(attributeNode.getSubgraph() == null || attributeNode.getSubgraph().length() == 0) {
                                group.addAttribute(attributeNode.getName());
                            } else {
                                List<CoreAttributeGroup> nestedGroups = subgroups.get(attributeNode.getSubgraph());
                                if(nestedGroups == null || nestedGroups.size() == 0) {
                                    //TODO: Exception or check for root level ones on target class
                                } else {
                                    group.addAttribute(attributeNode.getName(), nestedGroups.get(0));
                                }

                            }
                        }
                    }
                }
            }
        }
        return subgroups;
    }

    public void generateDescriptor(JavaClass javaClass, CoreProject project) {
        String jClassName = javaClass.getQualifiedName();
        TypeInfo info = typeInfo.get(jClassName);
        if (info.isTransient()){
            return;
        }
        NamespaceInfo namespaceInfo = this.packageToPackageInfoMappings.get(javaClass.getPackageName()).getNamespaceInfo();
        String packageNamespace = namespaceInfo.getNamespace();
        String elementName;
        String namespace;

        if (javaClass.getSuperclass() != null && javaClass.getSuperclass().getName().equals("jakarta.xml.bind.JAXBElement")) {
            generateDescriptorForJAXBElementSubclass(javaClass, project, getNamespaceResolverForDescriptor(namespaceInfo));
            return;
        }

        Descriptor descriptor = new XMLDescriptor();
        org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement rootElem = info.getXmlRootElement();
        if (rootElem == null) {
             try{
                 elementName = info.getXmlNameTransformer().transformRootElementName(javaClass.getName());
             }catch (Exception ex){
                  throw org.eclipse.persistence.exceptions.JAXBException.exceptionDuringNameTransformation(javaClass.getName(), info.getXmlNameTransformer().getClass().getName(), ex);
             }

            namespace = packageNamespace;
        } else {
            elementName = rootElem.getName();
            if (elementName.equals(XMLProcessor.DEFAULT)) {
                try{
                    elementName = info.getXmlNameTransformer().transformRootElementName(javaClass.getName());
                }catch (Exception ex){
                     throw org.eclipse.persistence.exceptions.JAXBException.exceptionDuringNameTransformation(javaClass.getName(), info.getXmlNameTransformer().getClass().getName(), ex);
                }
            }
            namespace = rootElem.getNamespace();
        }

        descriptor.setJavaClassName(jClassName);

        if (info.getFactoryMethodName() != null) {
            descriptor.getInstantiationPolicy().useFactoryInstantiationPolicy(info.getObjectFactoryClassName(), info.getFactoryMethodName());
        }

        if (namespace.equals(XMLProcessor.DEFAULT)) {
            namespace = namespaceInfo.getNamespace();
        }

        NamespaceResolver resolverForDescriptor = getNamespaceResolverForDescriptor(namespaceInfo);
        JavaClass manyValueJavaClass = helper.getJavaClass(ManyValue.class);
        if (!manyValueJavaClass.isAssignableFrom(javaClass)){
            if(isDefaultNamespaceAllowed
                    && namespace.length() != 0
                    && globalNamespaceResolver.getDefaultNamespaceURI() == null
                    && !resolverForDescriptor.getPrefixesToNamespaces().containsValue(namespace)) {
                globalNamespaceResolver.setDefaultNamespaceURI(namespace);
                resolverForDescriptor.setDefaultNamespaceURI(namespace);
            }
            if (rootElem == null) {
                descriptor.setDefaultRootElement("");
            } else {
                if (namespace.length() == 0) {
                    descriptor.setDefaultRootElement(elementName);
                } else {
                    descriptor.setDefaultRootElement(getQualifiedString(getPrefixForNamespace(namespace, resolverForDescriptor), elementName));
                }
            }
        }

        descriptor.setNamespaceResolver(resolverForDescriptor);

        setSchemaContext(descriptor, info);
        // set the ClassExtractor class name if necessary
        if (info.isSetClassExtractorName()) {
            descriptor.getInheritancePolicy().setClassExtractorName(info.getClassExtractorName());
        }
        // set any user-defined properties
        if (info.getUserProperties() != null) {
            descriptor.setProperties(info.getUserProperties());
        }

        if (info.isLocationAware()) {
            Property locProp = null;
            Iterator<Property> i = info.getPropertyList().iterator();
            while (i.hasNext()) {
                Property p = i.next();
                if (p.getType().getName().equals(Constants.LOCATOR_CLASS_NAME)) {
                    locProp = p;
                }
            }
            if (locProp != null && locProp.isTransient()) {
                // build accessor
                // don't make a mapping
                if (locProp.isMethodProperty()) {
                    MethodAttributeAccessor aa = new MethodAttributeAccessor();
                    aa.setAttributeName(locProp.getPropertyName());
                    aa.setSetMethodName(locProp.getSetMethodName());
                    aa.setGetMethodName(locProp.getGetMethodName());
                    descriptor.setLocationAccessor(aa);
                } else {
                    // instance variable property
                    InstanceVariableAttributeAccessor aa = new InstanceVariableAttributeAccessor();
                    aa.setAttributeName(locProp.getPropertyName());
                    descriptor.setLocationAccessor(aa);
                }
            }
        }

        if(!info.getObjectGraphs().isEmpty()) {
            //create attribute groups for each object graph.
            //these will be populated later to allow for linking
            for(XmlNamedObjectGraph next:info.getObjectGraphs()) {
                AttributeGroup attributeGroup = new AttributeGroup(next.getName(), info.getJavaClassName(), false);
                ((XMLDescriptor)descriptor).addAttributeGroup(attributeGroup);

                //process subclass graphs for inheritance
                //for(NamedSubgraph nextSubclass:next.getNamedSubclassGraph()) {
                    //attributeGroup.insertSubClass(new AttributeGroup(next.getName(), nextSubclass.getType()));
                //}
            }
        }

        project.addDescriptor((CoreDescriptor)descriptor);
        info.setDescriptor(descriptor);
    }

    public void generateDescriptorForJAXBElementSubclass(JavaClass javaClass, CoreProject project, NamespaceResolver nsr) {
        String jClassName = javaClass.getQualifiedName();
        TypeInfo info = typeInfo.get(jClassName);

        Descriptor xmlDescriptor = new XMLDescriptor();
        xmlDescriptor.setJavaClassName(jClassName);

        String[] factoryMethodParamTypes = info.getFactoryMethodParamTypes();

        MultiArgInstantiationPolicy policy = new MultiArgInstantiationPolicy();
        policy.useFactoryInstantiationPolicy(info.getObjectFactoryClassName(), info.getFactoryMethodName());
        policy.setParameterTypeNames(factoryMethodParamTypes);
        policy.setDefaultValues(new String[]{null});

        xmlDescriptor.setInstantiationPolicy(policy);
        JavaClass paramClass = helper.getJavaClass(factoryMethodParamTypes[0]);
        boolean isObject = paramClass.getName().equals("java.lang.Object");
        if(helper.isBuiltInJavaType(paramClass) && !isObject ){
            if(isBinaryData(paramClass)){
                BinaryDataMapping mapping = new XMLBinaryDataMapping();
                mapping.setAttributeName("value");
                mapping.setXPath(".");
                ((Field)mapping.getField()).setSchemaType(Constants.BASE_64_BINARY_QNAME);
                mapping.setSetMethodName("setValue");
                mapping.setGetMethodName("getValue");

                Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(factoryMethodParamTypes[0], helper.getClassLoader());
                mapping.setAttributeClassification(attributeClassification);
                mapping.getNullPolicy().setNullRepresentedByEmptyNode(false);

                mapping.setShouldInlineBinaryData(false);
                if(mapping.getMimeType() == null) {
                    if(areEquals(paramClass, javax.xml.transform.Source.class)) {
                        mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/xml"));
                    } else {
                        mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/octet-stream"));
                    }
                }
                xmlDescriptor.addMapping((CoreMapping)mapping);
            } else {
                DirectMapping mapping = new XMLDirectMapping();
                mapping.setNullValueMarshalled(true);
                mapping.setAttributeName("value");
                mapping.setGetMethodName("getValue");
                mapping.setSetMethodName("setValue");
                mapping.setXPath("text()");
                Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(factoryMethodParamTypes[0], helper.getClassLoader());
                mapping.setAttributeClassification(attributeClassification);
                xmlDescriptor.addMapping((CoreMapping)mapping);
            }
        }else if(paramClass.isEnum()){
             EnumTypeInfo enumInfo = (EnumTypeInfo)typeInfo.get(paramClass.getQualifiedName());

             DirectMapping mapping = new XMLDirectMapping();
             mapping.setConverter(buildJAXBEnumTypeConverter(mapping, enumInfo));
             mapping.setNullValueMarshalled(true);
             mapping.setAttributeName("value");
             mapping.setGetMethodName("getValue");
             mapping.setSetMethodName("setValue");
             mapping.setXPath("text()");
             Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(factoryMethodParamTypes[0], helper.getClassLoader());
             mapping.setAttributeClassification(attributeClassification);
             xmlDescriptor.addMapping((CoreMapping)mapping);

        }else{

            CompositeObjectMapping mapping = new XMLCompositeObjectMapping();
            mapping.setAttributeName("value");
            mapping.setGetMethodName("getValue");
            mapping.setSetMethodName("setValue");
            mapping.setXPath(".");
            if(isObject){
                mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
            }else{
                mapping.setReferenceClassName(factoryMethodParamTypes[0]);
            }
            xmlDescriptor.addMapping((CoreMapping)mapping);
        }
        xmlDescriptor.setNamespaceResolver(nsr);
        setSchemaContext(xmlDescriptor, info);
        project.addDescriptor((CoreDescriptor)xmlDescriptor);
        info.setDescriptor(xmlDescriptor);
    }

    private void setSchemaContext(Descriptor desc, TypeInfo info) {
        XMLSchemaClassPathReference schemaRef = new XMLSchemaClassPathReference();
        if (info.getClassNamespace() == null || info.getClassNamespace().equals("")) {
            schemaRef.setSchemaContext("/" + info.getSchemaTypeName());
            schemaRef.setSchemaContextAsQName(new QName(info.getSchemaTypeName()));
        } else {
            String prefix = desc.getNonNullNamespaceResolver().resolveNamespaceURI(info.getClassNamespace());
            if (prefix != null && !prefix.equals("")) {
                schemaRef.setSchemaContext("/" + prefix + ":" + info.getSchemaTypeName());
                schemaRef.setSchemaContextAsQName(new QName(info.getClassNamespace(), info.getSchemaTypeName(), prefix));
            } else {
                String generatedPrefix =getPrefixForNamespace(info.getClassNamespace(), desc.getNonNullNamespaceResolver(), false);
                schemaRef.setSchemaContext("/" + getQualifiedString(generatedPrefix, info.getSchemaTypeName()));
                if(generatedPrefix == null || generatedPrefix.equals(Constants.EMPTY_STRING)){
                    schemaRef.setSchemaContextAsQName(new QName(info.getClassNamespace(), info.getSchemaTypeName()));
                }else{
                    schemaRef.setSchemaContextAsQName(new QName(info.getClassNamespace(), info.getSchemaTypeName(), generatedPrefix));
                }
            }
        }
        // the default type is complex; need to check for simple type case
        if (info.isEnumerationType() || (info.getPropertyNames().size() == 1 && helper.isAnnotationPresent(info.getProperties().get(info.getPropertyNames().get(0)).getElement(), XmlValue.class))) {
            schemaRef.setType(XMLSchemaReference.SIMPLE_TYPE);
        }
        desc.setSchemaReference(schemaRef);

    }

    /**
     * Generate a mapping for a given Property.
     *
     * @param property
     * @param descriptor
     * @param namespaceInfo
     * @return newly created mapping
     */
    public Mapping generateMapping(Property property, Descriptor descriptor, JavaClass descriptorJavaClass, NamespaceInfo namespaceInfo) {
        if (property.isSetXmlJavaTypeAdapter()) {
            // if we are dealing with a reference, generate mapping and return
            if (property.isReference()) {
                return generateMappingForReferenceProperty(property, descriptor, namespaceInfo);
            }

            XmlJavaTypeAdapter xja = property.getXmlJavaTypeAdapter();
            JavaClass adapterClass = helper.getJavaClass(xja.getValue());

            JavaClass valueType = null;
            String sValType = xja.getValueType();
            if (sValType.equals("jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT")) {
                valueType = property.getActualType();
            } else {
                valueType = helper.getJavaClass(xja.getValueType());
            }

            Mapping mapping;
            boolean isArray = property.getType().isArray() && !property.getType().getRawName().equals("byte[]");

            // if the value type is something we have a descriptor for, create
            // a composite mapping
            if(property.isChoice()) {
                if(helper.isCollectionType(property.getType()) || property.getType().isArray()) {
                    mapping = generateChoiceCollectionMapping(property, descriptor, namespaceInfo);
                    ((ChoiceCollectionMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                } else {
                    mapping = generateChoiceMapping(property, descriptor, namespaceInfo);
                    ((ChoiceObjectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                }
            } else if (typeInfo.containsKey(valueType.getQualifiedName())) {
                TypeInfo reference = typeInfo.get(valueType.getQualifiedName());
                if (helper.isCollectionType(property.getType())) {
                    if (reference.isEnumerationType()) {
                        mapping = generateEnumCollectionMapping(property, descriptor, namespaceInfo, (EnumTypeInfo) reference);
                        XMLJavaTypeConverter converter = new XMLJavaTypeConverter(adapterClass.getQualifiedName());
                        converter.setNestedConverter(((DirectCollectionMapping)mapping).getValueConverter());
                        ((DirectCollectionMapping)mapping).setValueConverter(converter);
                    } else {
                        if(property.getVariableAttributeName() !=null){
                            mapping = generateVariableXPathCollectionMapping(property, descriptor, namespaceInfo, valueType);
                            ((VariableXPathCollectionMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                        }else{
                            mapping = generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, valueType.getQualifiedName());
                            ((CompositeCollectionMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                        }
                    }
                } else {
                    if (reference.isEnumerationType()) {
                        mapping = generateDirectEnumerationMapping(property, descriptor, namespaceInfo, (EnumTypeInfo) reference);
                        XMLJavaTypeConverter converter = new XMLJavaTypeConverter(adapterClass.getQualifiedName());
                        converter.setNestedConverter(((DirectMapping)mapping).getConverter());
                        ((DirectMapping)mapping).setConverter(converter);
                    } else if (property.isInverseReference()) {
                        mapping = generateInverseReferenceMapping(property, descriptor, namespaceInfo);
                    } else {
                        if(property.getVariableAttributeName() !=null){
                            mapping = generateVariableXPathObjectMapping(property, descriptor, namespaceInfo, valueType);
                            ((VariableXPathObjectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                        }else{
                            mapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, valueType.getQualifiedName());
                            ((CompositeObjectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                        }
                    }
                }
            } else {
                // no descriptor for value type
                if (property.isAny()) {
                    if (helper.isCollectionType(property.getType())){
                        mapping = generateAnyCollectionMapping(property, descriptor, namespaceInfo, property.isMixedContent());
                        ((AnyCollectionMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                    } else {
                        mapping = generateAnyObjectMapping(property, descriptor, namespaceInfo);
                        ((AnyObjectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                    }
                } else if (helper.isCollectionType(property.getType()) || isArray) {
                    if (property.isSwaAttachmentRef() || property.isMtomAttachment()) {
                        mapping = generateBinaryDataCollectionMapping(property, descriptor, namespaceInfo);
                        ((BinaryDataCollectionMapping) mapping).setValueConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                    } else{
                        mapping = generateDirectCollectionMapping(property, descriptor, namespaceInfo);
                        if(adapterClass.getQualifiedName().equals(CollapsedStringAdapter.class.getName())) {
                            ((DirectCollectionMapping)mapping).setCollapsingStringValues(true);
                        } else if(adapterClass.getQualifiedName().equals(NormalizedStringAdapter.class.getName())) {
                            ((DirectCollectionMapping)mapping).setNormalizingStringValues(true);
                        } else {
                            ((DirectCollectionMapping) mapping).setValueConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                        }
                    }
                } else if (property.isSwaAttachmentRef() || property.isMtomAttachment()) {
                    mapping = generateBinaryMapping(property, descriptor, namespaceInfo);
                    ((BinaryDataMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                } else {
                    if (!property.isAttribute() && areEquals(valueType, Object.class) || property.isTyped()){
                        mapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, null);
                        ((CompositeObjectMapping)mapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
                        ((CompositeObjectMapping)mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                        return mapping;
                    }
                    mapping = generateDirectMapping(property, descriptor, namespaceInfo);
                    if(adapterClass.getQualifiedName().equals(CollapsedStringAdapter.class.getName())) {
                        ((DirectMapping)mapping).setCollapsingStringValues(true);
                    } else if(adapterClass.getQualifiedName().equals(NormalizedStringAdapter.class.getName())) {
                        ((DirectMapping)mapping).setNormalizingStringValues(true);
                    } else {
                        ((DirectMapping) mapping).setConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
                    }
                }
            }
            return mapping;
        }
        if (property.getVariableAttributeName() != null){
            if (helper.isCollectionType(property.getType()) || property.getType().isArray() || property.isMap()){
                return generateVariableXPathCollectionMapping(property, descriptor, namespaceInfo, property.getActualType());
            }else{
                return generateVariableXPathObjectMapping(property, descriptor, namespaceInfo, property.getActualType());
            }
        }
        if (property.isSetXmlJoinNodes()) {
            if (helper.isCollectionType(property.getType())) {
                return generateXMLCollectionReferenceMapping(property, descriptor, namespaceInfo, property.getActualType());
            }
            return generateXMLObjectReferenceMapping(property, descriptor, namespaceInfo, property.getType());
        }
        if (property.isXmlTransformation()) {
            return generateTransformationMapping(property, descriptor, namespaceInfo);
        }
        if (property.isChoice()) {
            if (helper.isCollectionType(property.getType()) || property.getType().isArray()) {
                return generateChoiceCollectionMapping(property, descriptor, namespaceInfo);
            }
            return generateChoiceMapping(property, descriptor, namespaceInfo);
        }
        if (property.isInverseReference()) {
            return generateInverseReferenceMapping(property, descriptor, namespaceInfo);
        }
        if (property.isReference()) {
            return generateMappingForReferenceProperty(property, descriptor, namespaceInfo);
        }
        if (property.isAny()) {
            if (helper.isCollectionType(property.getType()) || property.getType().isArray()){
                return generateAnyCollectionMapping(property, descriptor, namespaceInfo, property.isMixedContent());
            }
            return generateAnyObjectMapping(property, descriptor, namespaceInfo);
        }

        if (property.isMap()){
            if (property.isAnyAttribute()) {
                return generateAnyAttributeMapping(property, descriptor, namespaceInfo);
            }
            return generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, null);
        }
        if (helper.isCollectionType(property.getType())) {
            return generateCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo);
        }

        JavaClass referenceClass = property.getType();
        String referenceClassName = referenceClass.getRawName();
        if (referenceClass.isArray()  && !referenceClassName.equals("byte[]")){
            JavaClass componentType = referenceClass.getComponentType();
            TypeInfo reference = typeInfo.get(componentType.getName());

            if (reference != null && reference.isEnumerationType()) {
                return generateEnumCollectionMapping(property,  descriptor, namespaceInfo,(EnumTypeInfo) reference);
            }
            if (areEquals(componentType, Object.class)){
                CompositeCollectionMapping mapping = generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, null);
                mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
                return mapping;
            }

            if (reference != null ||  componentType.isArray()){
                  if (property.isXmlIdRef() || property.isSetXmlJoinNodes()) {
                      return generateXMLCollectionReferenceMapping(property, descriptor, namespaceInfo, componentType);
                  }

                return generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, componentType.getQualifiedName());
            }
            return generateDirectCollectionMapping(property, descriptor, namespaceInfo);
        }
        if (property.isXmlIdRef()) {
            return generateXMLObjectReferenceMapping(property, descriptor, namespaceInfo, referenceClass);
        }
        TypeInfo reference = typeInfo.get(referenceClass.getQualifiedName());
        if (reference != null) {
            if (reference.isEnumerationType()) {
                return generateDirectEnumerationMapping(property, descriptor, namespaceInfo, (EnumTypeInfo) reference);
            }
            if (property.isXmlLocation()) {
                CompositeObjectMapping locationMapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, referenceClass.getQualifiedName());
                reference.getDescriptor().setInstantiationPolicy(new NullInstantiationPolicy());
                descriptor.setLocationAccessor(locationMapping.getAttributeAccessor());
                return locationMapping;
            } else {
                return generateCompositeObjectMapping(property, descriptor, namespaceInfo, referenceClass.getQualifiedName());
            }
        }
        if (property.isSwaAttachmentRef() || property.isMtomAttachment()) {
            return generateBinaryMapping(property, descriptor, namespaceInfo);
        }
        if (referenceClass.getQualifiedName().equals(OBJECT_CLASS_NAME) && !property.isAttribute() || property.isTyped() ) {
            CompositeObjectMapping coMapping = generateCompositeObjectMapping(property, descriptor, namespaceInfo, null);
            coMapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
            return coMapping;
        }
        if (property.isXmlLocation()) {
            return null;
        }
        return generateDirectMapping(property, descriptor, namespaceInfo);
    }

    private Mapping generateVariableXPathCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass actualType) {
        XMLVariableXPathCollectionMapping mapping = new XMLVariableXPathCollectionMapping();
        mapping.setAttributeName(property.getPropertyName());

        if(property.isMap()){
            actualType = property.getValueType();
        }

        initializeXMLContainerMapping(mapping, property.getType().isArray());
        initializeXMLMapping(mapping, property);
        initializeVariableXPathMapping(mapping, property, actualType);

        if (property.getXmlPath() != null) {
            mapping.setField(new XMLField(property.getXmlPath()));
        } else {
            if (property.isSetXmlElementWrapper()) {
                mapping.setField((XMLField)getXPathForField(property, namespaceInfo, false, true));
            }
        }

        if (property.isSetXmlElementWrapper()) {
            mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property));
        }
        JavaClass collectionType = property.getType();
        if (collectionType.isArray()){
            JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader());
            JavaClass componentType = collectionType.getComponentType();
            if(componentType.isArray()) {
                JavaClass baseComponentType = getBaseComponentType(componentType);
                if (baseComponentType.isPrimitive()){
                    Class<Object> primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName());
                    accessor.setComponentClass(primitiveClass);
                } else {
                    accessor.setComponentClassName(baseComponentType.getQualifiedName());
                }
            } else {
                accessor.setComponentClassName(componentType.getQualifiedName());
            }
            mapping.setAttributeAccessor(accessor);
        }



        if(property.isMap()){
            JavaClass mapType = property.getType();
            if(mapType.isInterface()){
                mapping.useMapClass("java.util.HashMap");
            }else{
                mapping.useMapClass(property.getType().getName());
            }

        }else{
            collectionType = containerClassImpl(collectionType);
            mapping.useCollectionClass(helper.getClassForJavaClass(collectionType));
        }


        return mapping;
    }

    private Mapping generateVariableXPathObjectMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass actualType) {
        XMLVariableXPathObjectMapping mapping = new XMLVariableXPathObjectMapping();
        initializeXMLMapping(mapping, property);
        initializeVariableXPathMapping(mapping, property, actualType);

        // handle null policy set via xml metadata
        if (property.isSetNullPolicy()) {
            mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo)));
        } else {
            NullPolicy nullPolicy = (NullPolicy) mapping.getNullPolicy();
            nullPolicy.setSetPerformedForAbsentNode(false);
            if(property.isNillable()) {
                nullPolicy.setNullRepresentedByXsiNil(true);
                nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
            }
        }

        if (property.getXmlPath() != null) {
            mapping.setField(new XMLField(property.getXmlPath()));
        } else {
            if (property.isSetXmlElementWrapper()) {
                mapping.setField((XMLField)getXPathForField(property, namespaceInfo, false, true));
            }
        }

        return mapping;
    }

    private void initializeVariableXPathMapping(VariableXPathObjectMapping mapping, Property property, JavaClass actualType){
        String variableAttributeName = property.getVariableAttributeName();

        TypeInfo refInfo = typeInfo.get(actualType.getName());

        if(refInfo == null){
            throw JAXBException.unknownTypeForVariableNode(actualType.getName());
        }

        Property refProperty = refInfo.getProperties().get(variableAttributeName);


        while(refProperty == null){
             JavaClass superClass = CompilerHelper.getNextMappedSuperClass(actualType, typeInfo, helper);
            if (superClass != null){
                refInfo = typeInfo.get(superClass.getName());
                refProperty = refInfo.getProperties().get(variableAttributeName);
            }else{
                break;
            }
        }


        if(refProperty == null){
            throw JAXBException.unknownPropertyForVariableNode(variableAttributeName, actualType.getName());
        }

        String refPropertyType = refProperty.getActualType().getQualifiedName();

        if(!(refPropertyType.equals("java.lang.String") || refPropertyType.equals("javax.xml.namespace.QName"))){
            throw JAXBException.invalidTypeForVariableNode(variableAttributeName, refPropertyType, actualType.getName());
        }
        if (refProperty.isMethodProperty()) {
            if (refProperty.getGetMethodName() == null) {
                // handle case of set with no get method
                String paramTypeAsString = refProperty.getType().getName();
                JAXBSetMethodAttributeAccessor accessor = new JAXBSetMethodAttributeAccessor(paramTypeAsString, helper.getClassLoader());
                accessor.setIsReadOnly(true);
                accessor.setSetMethodName(refProperty.getSetMethodName());
                mapping.setIsReadOnly(true);
                accessor.setAttributeName("thingBLAH");
                mapping.setVariableAttributeAccessor(accessor);
            } else if (refProperty.getSetMethodName() == null) {
                mapping.setVariableGetMethodName(refProperty.getGetMethodName());
            } else {
                mapping.setVariableGetMethodName(refProperty.getGetMethodName());
                mapping.setVariableSetMethodName(refProperty.getSetMethodName());
            }
        }else{
            mapping.setVariableAttributeName(property.getVariableAttributeName());
        }


        if(property.getVariableClassName() != null){
            mapping.setReferenceClassName(property.getVariableClassName());
        }else{
            mapping.setReferenceClassName(actualType.getQualifiedName());
        }

        mapping.setAttribute(property.isVariableNodeAttribute());

    }

    private InverseReferenceMapping generateInverseReferenceMapping(Property property, Descriptor descriptor, NamespaceInfo namespace) {
        InverseReferenceMapping<AbstractSession, AttributeAccessor, ContainerPolicy, ClassDescriptor, DatabaseField, DatabaseMapping, org.eclipse.persistence.internal.oxm.record.XMLRecord> invMapping = new XMLInverseReferenceMapping();
        boolean isCollection = helper.isCollectionType(property.getType());

        if (isCollection) {
            invMapping.setReferenceClassName(property.getGenericType().getQualifiedName());
        } else {
            invMapping.setReferenceClassName(property.getType().getQualifiedName());
        }

        invMapping.setAttributeName(property.getPropertyName());

        String setMethodName = property.getInverseReferencePropertySetMethodName();
        String getMethodName = property.getInverseReferencePropertyGetMethodName();

        if (setMethodName != null && !setMethodName.equals(Constants.EMPTY_STRING)) {
            invMapping.setSetMethodName(setMethodName);
        }
        if (getMethodName != null && !getMethodName.equals(Constants.EMPTY_STRING)) {
            invMapping.setGetMethodName(getMethodName);
        }
        invMapping.setMappedBy(property.getInverseReferencePropertyName());

        if (isCollection) {
            JavaClass collectionType = property.getType();
            collectionType = containerClassImpl(collectionType);
            invMapping.useCollectionClass(org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(collectionType.getQualifiedName(), helper.getClassLoader()));
        }

        if(property.isWriteableInverseReference()){
               if(isCollection){
                   JavaClass descriptorClass = helper.getJavaClass(descriptor.getJavaClassName());
                   invMapping.setInlineMapping((XMLCompositeCollectionMapping)generateCompositeCollectionMapping(property, descriptor, descriptorClass, namespace, invMapping.getReferenceClassName()));
               }else{
                   invMapping.setInlineMapping((XMLCompositeObjectMapping)generateCompositeObjectMapping(property, descriptor, namespace, invMapping.getReferenceClassName()));
               }
        }

        return invMapping;
    }

    /**
     * Generate an XMLTransformationMapping based on a given Property.
     *
     * @param property
     * @param descriptor
     * @param namespace
     * @return
     */
    public TransformationMapping generateTransformationMapping(Property property, Descriptor descriptor, NamespaceInfo namespace) {
        TransformationMapping<AbstractSession, AttributeAccessor, ContainerPolicy, ClassDescriptor, DatabaseField, XMLTransformationRecord, XMLRecord> mapping = new XMLTransformationMapping();
        if (property.isMethodProperty()) {
            if (property.getGetMethodName() == null) {
                // handle case of set with no get method
                String paramTypeAsString = property.getType().getName();
                mapping.setAttributeAccessor(new JAXBSetMethodAttributeAccessor(paramTypeAsString, helper.getClassLoader()));
                mapping.setSetMethodName(property.getSetMethodName());
            } else if (property.getSetMethodName() == null) {
                mapping.setGetMethodName(property.getGetMethodName());
            } else {
                mapping.setSetMethodName(property.getSetMethodName());
                mapping.setGetMethodName(property.getGetMethodName());
            }
        }
        // handle transformation
        if (property.isSetXmlTransformation()) {
            XmlTransformation xmlTransformation = property.getXmlTransformation();
            mapping.setIsOptional(xmlTransformation.isOptional());
            // handle transformer(s)
            if (xmlTransformation.isSetXmlReadTransformer()) {
                // handle read transformer
                mapping.setAttributeName(property.getPropertyName());
                XmlReadTransformer readTransformer = xmlTransformation.getXmlReadTransformer();
                if (readTransformer.isSetTransformerClass()) {
                    mapping.setAttributeTransformerClassName(xmlTransformation.getXmlReadTransformer().getTransformerClass());
                } else {
                    mapping.setAttributeTransformation(xmlTransformation.getXmlReadTransformer().getMethod());
                }
            }
            if (xmlTransformation.isSetXmlWriteTransformers()) {
                // handle write transformer(s)
                for (XmlWriteTransformer writeTransformer : xmlTransformation.getXmlWriteTransformer()) {
                    if (writeTransformer.isSetTransformerClass()) {
                        mapping.addFieldTransformerClassName(writeTransformer.getXmlPath(), writeTransformer.getTransformerClass());
                    } else {
                        mapping.addFieldTransformation(writeTransformer.getXmlPath(), writeTransformer.getMethod());
                    }
                }
            }
        }
        return mapping;
    }

    public ChoiceObjectMapping generateChoiceMapping(Property property, Descriptor descriptor, NamespaceInfo namespace) {
        XMLChoiceObjectMapping mapping = new XMLChoiceObjectMapping();
        initializeXMLMapping(mapping, property);

        boolean isIdRef = property.isXmlIdRef();
        Iterator<Property> choiceProperties = property.getChoiceProperties().iterator();
        while (choiceProperties.hasNext()) {
            Property next = choiceProperties.next();
            JavaClass type = next.getType();
            JavaClass originalType = next.getType();
            Converter converter = null;
            TypeInfo info = typeInfo.get(type.getName());
            if(info != null){
                XmlJavaTypeAdapter adapter = info.getXmlJavaTypeAdapter();
                if(adapter != null){
                    String adapterValue = adapter.getValue();
                    JavaClass adapterClass = helper.getJavaClass(adapterValue);
                    JavaClass theClass = CompilerHelper.getTypeFromAdapterClass(adapterClass, helper);
                    type = theClass;
                    converter = new XMLJavaTypeConverter(adapterClass.getQualifiedName());
                }
            }
            if (next.getXmlJoinNodes() != null) {
                // handle XmlJoinNodes
                List<XMLField> srcFlds = new ArrayList<>();
                List<XMLField> tgtFlds = new ArrayList<>();
                for (XmlJoinNode xmlJoinNode: next.getXmlJoinNodes().getXmlJoinNode()) {
                    srcFlds.add(new XMLField(xmlJoinNode.getXmlPath()));
                    tgtFlds.add(new XMLField(xmlJoinNode.getReferencedXmlPath()));
                }
                mapping.addChoiceElement(srcFlds, type.getQualifiedName(), tgtFlds);
            } else if (isIdRef) {
                // handle IDREF
                String tgtXPath = null;
                TypeInfo referenceType = typeInfo.get(type.getQualifiedName());
                if (null != referenceType && referenceType.isIDSet()) {
                    Property prop = referenceType.getIDProperty();
                    tgtXPath = getXPathForField(prop, namespace, !prop.isAttribute(), false).getXPath();
                }
                // if the XPath is set (via xml-path) use it, otherwise figure it out
                Field srcXPath;
                if (next.getXmlPath() != null) {
                    srcXPath = new XMLField(next.getXmlPath());
                } else {
                    srcXPath = getXPathForField(next, namespace, true, false);
                }
                mapping.addChoiceElement(srcXPath.getXPath(), type.getQualifiedName(), tgtXPath);
            } else {
                XMLField xpath;
                if (next.getXmlPath() != null) {
                    xpath = new XMLField(next.getXmlPath());
                } else {
                    xpath = (XMLField) getXPathForField(next, namespace, (!(this.typeInfo.containsKey(type.getQualifiedName()))) || next.isMtomAttachment() || type.isEnum(), false);
                }
                mapping.addChoiceElement(xpath, type.getQualifiedName());
                if(!originalType.getQualifiedName().equals(type.getQualifiedName())) {
                    if(mapping.getClassNameToFieldMappings().get(originalType.getQualifiedName()) == null) {
                        mapping.getClassNameToFieldMappings().put(originalType.getQualifiedName(), xpath);
                    }
                    mapping.addConverter(xpath, converter);
                }
                XMLMapping nestedMapping = mapping.getChoiceElementMappings().get(xpath);
                if(nestedMapping instanceof BinaryDataMapping){
                    ((BinaryDataMapping)nestedMapping).getNullPolicy().setNullRepresentedByEmptyNode(false);
                }
                if (type.isEnum()) {
                    if(nestedMapping.isAbstractDirectMapping()) {
                        ((DirectMapping)nestedMapping).setConverter(buildJAXBEnumTypeConverter(nestedMapping, (EnumTypeInfo)info));
                    }
                }
            }
        }
        return mapping;
    }

    public ChoiceCollectionMapping generateChoiceCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespace) {
        ChoiceCollectionMapping mapping = new XMLChoiceCollectionMapping();
        initializeXMLContainerMapping(mapping, property.getType().isArray());
        initializeXMLMapping((XMLChoiceCollectionMapping)mapping, property);

        JavaClass collectionType = property.getType();
        if (collectionType.isArray()){
            JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader());
            JavaClass componentType = collectionType.getComponentType();
            if(componentType.isArray()) {
                JavaClass baseComponentType = getBaseComponentType(componentType);
                if (baseComponentType.isPrimitive()){
                    Class<?> primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName());
                    accessor.setComponentClass(primitiveClass);
                } else {
                    accessor.setComponentClassName(baseComponentType.getQualifiedName());
                }
            } else {
                accessor.setComponentClassName(componentType.getQualifiedName());
            }

            mapping.setAttributeAccessor(accessor);
        }


        collectionType = containerClassImpl(collectionType);
        mapping.useCollectionClassName(collectionType.getRawName());

        if (property.isSetXmlElementWrapper()) {
            mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property));
        }

        boolean isIdRef = property.isXmlIdRef();
        Iterator<Property> choiceProperties = property.getChoiceProperties().iterator();
        while (choiceProperties.hasNext()) {
            Property next = choiceProperties.next();
            JavaClass type = next.getType();
            JavaClass originalType = next.getType();
            Converter converter = null;
            Field xmlField = null;
            TypeInfo info = typeInfo.get(type.getName());
            if(info != null){
                XmlJavaTypeAdapter adapter = info.getXmlJavaTypeAdapter();
                if(adapter != null){
                    String adapterValue = adapter.getValue();
                    JavaClass adapterClass = helper.getJavaClass(adapterValue);
                    JavaClass theClass = CompilerHelper.getTypeFromAdapterClass(adapterClass, helper);
                    type = theClass;
                    converter = new XMLJavaTypeConverter(adapterClass.getQualifiedName());
                }
            }

            if (next.getXmlJoinNodes() != null) {
                // handle XmlJoinNodes
                List<Field> srcFlds = new ArrayList<>();
                List<Field> tgtFlds = new ArrayList<>();
                for (XmlJoinNode xmlJoinNode: next.getXmlJoinNodes().getXmlJoinNode()) {
                    srcFlds.add(new XMLField(xmlJoinNode.getXmlPath()));
                    tgtFlds.add(new XMLField(xmlJoinNode.getReferencedXmlPath()));
                }
                mapping.addChoiceElement(srcFlds, type.getQualifiedName(), tgtFlds);
            } else if (isIdRef) {
                // handle IDREF
                String tgtXPath = null;
                TypeInfo referenceType = typeInfo.get(type.getQualifiedName());
                if (null != referenceType && referenceType.isIDSet()) {
                    Property prop = referenceType.getIDProperty();
                    tgtXPath = getXPathForField(prop, namespace, !prop.isAttribute(), false).getXPath();
                }
                // if the XPath is set (via xml-path) use it, otherwise figure it out
                Field srcXPath;
                if (next.getXmlPath() != null) {
                    srcXPath = new XMLField(next.getXmlPath());
                } else {
                    srcXPath = getXPathForField(next, namespace, true, false);
                }
                mapping.addChoiceElement(srcXPath.getXPath(), type.getQualifiedName(), tgtXPath);
            } else {
                Field xpath;
                if (next.getXmlPath() != null) {
                    xpath = new XMLField(next.getXmlPath());
                } else {
                    xpath = getXPathForField(next, namespace, (!(this.typeInfo.containsKey(type.getQualifiedName()))) || type.isEnum(), false);
                }
                xmlField = xpath;
                mapping.addChoiceElement(xpath.getName(), type.getQualifiedName());
                if(!originalType.getQualifiedName().equals(type.getQualifiedName())) {
                    if(mapping.getClassNameToFieldMappings().get(originalType.getQualifiedName()) == null) {
                        mapping.getClassNameToFieldMappings().put(originalType.getQualifiedName(), xpath);
                    }
                    mapping.addConverter(xpath, converter);
                }

            }

            if(xmlField !=null){
                Mapping nestedMapping = (Mapping) mapping.getChoiceElementMappings().get(xmlField);
                if(nestedMapping.isAbstractCompositeCollectionMapping()){
                   //handle null policy set via xml metadata
                   if (property.isSetNullPolicy()) {
                       ((CompositeCollectionMapping)nestedMapping).setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespace)));
                   } else if (next.isNillable() && property.isNillable()){
                       ((CompositeCollectionMapping)nestedMapping).getNullPolicy().setNullRepresentedByXsiNil(true);
                       ((CompositeCollectionMapping)nestedMapping).getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
                   }
                } else if(nestedMapping.isAbstractCompositeDirectCollectionMapping()){
                     if (next.isSetNullPolicy()) {
                         ((DirectCollectionMapping)nestedMapping).setNullPolicy(getNullPolicyFromProperty(next, getNamespaceResolverForDescriptor(namespace)));
                     } else if (next.isNillable() && property.isNillable()){
                         ((DirectCollectionMapping)nestedMapping).getNullPolicy().setNullRepresentedByXsiNil(true);
                         ((DirectCollectionMapping)nestedMapping).getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
                     }
                     ((DirectCollectionMapping)nestedMapping).getNullPolicy().setNullRepresentedByEmptyNode(false);

                     if (type.isEnum()) {
                         ((DirectCollectionMapping)nestedMapping).setValueConverter(buildJAXBEnumTypeConverter(nestedMapping, (EnumTypeInfo)info));
                     }
                } else if(nestedMapping instanceof BinaryDataCollectionMapping){
                       if (next.isSetNullPolicy()) {
                        ((BinaryDataCollectionMapping)nestedMapping).setNullPolicy(getNullPolicyFromProperty(next, getNamespaceResolverForDescriptor(namespace)));
                    } else if (next.isNillable() && property.isNillable()){
                        ((BinaryDataCollectionMapping)nestedMapping).getNullPolicy().setNullRepresentedByXsiNil(true);
                        ((BinaryDataCollectionMapping)nestedMapping).getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
                    }
                }
            }
        }
        return mapping;
    }

    public Mapping generateMappingForReferenceProperty(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo)  {
        boolean isCollection = helper.isCollectionType(property.getType()) || property.getType().isArray();

        Mapping mapping;
        if (isCollection) {
            mapping = new XMLChoiceCollectionMapping();
            initializeXMLContainerMapping((ChoiceCollectionMapping) mapping, property.getType().isArray());
            JavaClass collectionType = property.getType();
            collectionType = containerClassImpl(collectionType);
            ((ChoiceCollectionMapping) mapping).useCollectionClassName(collectionType.getRawName());
            JAXBElementRootConverter jaxbERConverter = new JAXBElementRootConverter(Object.class);
            if (property.isSetXmlJavaTypeAdapter()) {
                JavaClass adapterClass = helper.getJavaClass(property.getXmlJavaTypeAdapter().getValue());
                jaxbERConverter.setNestedConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
            }
            ((ChoiceCollectionMapping) mapping).setConverter(jaxbERConverter);
            if (property.isSetWriteOnly()) {
                ((ChoiceCollectionMapping) mapping).setIsWriteOnly(property.isWriteOnly());
            }
            if (property.isSetXmlElementWrapper()) {
                ((ChoiceCollectionMapping) mapping).setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property));
            }
        } else {
            mapping = new XMLChoiceObjectMapping();
            JAXBElementRootConverter jaxbERConverter = new JAXBElementRootConverter(Object.class);
            if (property.isSetXmlJavaTypeAdapter()) {
                JavaClass adapterClass = helper.getJavaClass(property.getXmlJavaTypeAdapter().getValue());
                jaxbERConverter.setNestedConverter(new XMLJavaTypeConverter(adapterClass.getQualifiedName()));
            }
            ((ChoiceObjectMapping) mapping).setConverter(jaxbERConverter);
            if (property.isSetWriteOnly()) {
                ((ChoiceObjectMapping) mapping).setIsWriteOnly(property.isWriteOnly());
            }
        }

        initializeXMLMapping((XMLMapping)mapping, property);

        List<ElementDeclaration> referencedElements = property.getReferencedElements();
        JavaClass propertyType = property.getType();
        if (propertyType.isArray()) {
            JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader());
            accessor.setComponentClassName(property.getType().getComponentType().getQualifiedName());
            JavaClass componentType = propertyType.getComponentType();
            if(componentType.isArray()) {
                Class adaptedClass = classToGeneratedClasses.get(componentType.getQualifiedName());
                accessor.setAdaptedClassName(adaptedClass.getName());
            }
            mapping.setAttributeAccessor(accessor);
        }
        String wrapperXPath = "";
        // handle XmlElementWrapper
        if (property.isSetXmlElementWrapper()) {
            XmlElementWrapper wrapper = property.getXmlElementWrapper();
            String namespace = wrapper.getNamespace();
            if (namespace.equals(XMLProcessor.DEFAULT)) {
                if (namespaceInfo.isElementFormQualified()) {
                    namespace = namespaceInfo.getNamespace();
                } else {
                    namespace = "";
                }
            }
            if (namespace.equals("")) {
                wrapperXPath += (wrapper.getName() + "/");
            } else {
                String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(namespaceInfo));
                wrapperXPath += getQualifiedString(prefix, wrapper.getName() + "/");
            }
        }
        if(property.isMixedContent() && isCollection) {
            if(wrapperXPath.length() == 0) {
                ((ChoiceCollectionMapping)mapping).setMixedContent(true);
            } else {
                ((ChoiceCollectionMapping)mapping).setMixedContent(wrapperXPath.substring(0, wrapperXPath.length() - 1));
            }
        }
        for (ElementDeclaration element:referencedElements) {
            QName elementName = element.getElementName();
            JavaClass    pType = element.getJavaType();
            String    pTypeName = element.getJavaTypeName();
            boolean isBinaryType = (areEquals(pType, AnnotationsProcessor.JAVAX_ACTIVATION_DATAHANDLER) || areEquals(pType, byte[].class) || areEquals(pType, Image.class) || areEquals(pType, Source.class) || areEquals(pType, AnnotationsProcessor.JAVAX_MAIL_INTERNET_MIMEMULTIPART));
            boolean isText = pType.isEnum() || (!isBinaryType && !(this.typeInfo.containsKey(element.getJavaTypeName())) && !(element.getJavaTypeName().equals(OBJECT_CLASS_NAME)));
            String xPath = wrapperXPath;

            Field xmlField = this.getXPathForElement(xPath, elementName, namespaceInfo, isText);
            //ensure byte[] goes to base64 instead of the default hex.
            if(helper.getXMLToJavaTypeMap().get(pType.getRawName()) == Constants.BASE_64_BINARY_QNAME) {
                xmlField.setSchemaType(Constants.BASE_64_BINARY_QNAME);
            }
            if(areEquals(pType, Object.class)) {
                setTypedTextField(xmlField);
            }
            Mapping nestedMapping;
            AbstractNullPolicy nullPolicy = null;
            if(isCollection){
                ChoiceCollectionMapping xmlChoiceCollectionMapping = (ChoiceCollectionMapping) mapping;
                xmlChoiceCollectionMapping.addChoiceElement(xmlField, pTypeName);
                nestedMapping = (Mapping) xmlChoiceCollectionMapping.getChoiceElementMappings().get(xmlField);
                if(nestedMapping.isAbstractCompositeCollectionMapping()){
                    ((CompositeCollectionMapping)nestedMapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
                    nullPolicy = ((CompositeCollectionMapping)nestedMapping).getNullPolicy();
                }

                if (nestedMapping.isAbstractCompositeDirectCollectionMapping()) {
                    DirectCollectionMapping nestedCompositeDirectCollectionMapping = (DirectCollectionMapping) nestedMapping;
                    nullPolicy = nestedCompositeDirectCollectionMapping.getNullPolicy();
                    if(pType.isEnum()) {
                        TypeInfo enumTypeInfo = typeInfo.get(pType.getQualifiedName());
                        nestedCompositeDirectCollectionMapping.setValueConverter(buildJAXBEnumTypeConverter(nestedCompositeDirectCollectionMapping, (EnumTypeInfo) enumTypeInfo));
                    }
                    if(element.isList()){
                        XMLListConverter listConverter = new XMLListConverter();
                        listConverter.setObjectClassName(pType.getQualifiedName());
                        ((DirectCollectionMapping)nestedMapping).setValueConverter(listConverter);
                    }
                }else if(nestedMapping instanceof BinaryDataCollectionMapping){
                    nullPolicy =  ((BinaryDataCollectionMapping)nestedMapping).getNullPolicy();
                    if(element.isList()){
                        ((XMLField) nestedMapping.getField()).setUsesSingleNode(true);
                    }
                }


            } else {
                ChoiceObjectMapping xmlChoiceObjectMapping = (ChoiceObjectMapping) mapping;
                xmlChoiceObjectMapping.addChoiceElement(xmlField, pTypeName);
                nestedMapping = (Mapping) xmlChoiceObjectMapping.getChoiceElementMappings().get(xmlField);
                if(pType.isEnum()) {
                    TypeInfo enumTypeInfo = typeInfo.get(pType.getQualifiedName());
                    ((DirectMapping)nestedMapping).setConverter(buildJAXBEnumTypeConverter(nestedMapping, (EnumTypeInfo) enumTypeInfo));
                }
                if(nestedMapping.isAbstractCompositeObjectMapping()){
                    ((CompositeObjectMapping)nestedMapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
                    nullPolicy = ((CompositeObjectMapping)nestedMapping).getNullPolicy();

                }else if(nestedMapping instanceof BinaryDataMapping){
                    nullPolicy = ((BinaryDataMapping)nestedMapping).getNullPolicy();
                }else if(nestedMapping instanceof DirectMapping){
                    nullPolicy = ((DirectMapping)nestedMapping).getNullPolicy();
                }

            }
            if(nullPolicy != null){
                nullPolicy.setNullRepresentedByEmptyNode(false);
                nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
                nullPolicy.setNullRepresentedByXsiNil(true);
                nullPolicy.setIgnoreAttributesForNil(false);
            }
            if (!element.isXmlRootElement()) {
                Class scopeClass = element.getScopeClass();
                if (scopeClass == jakarta.xml.bind.annotation.XmlElementDecl.GLOBAL.class){
                    scopeClass = JAXBElement.GlobalScope.class;
                }

                Class declaredType = null;
                if(element.getAdaptedJavaType() != null){
                    declaredType =  org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(element.getAdaptedJavaType().getQualifiedName(), helper.getClassLoader());
                }else{
                    declaredType =  org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(pType.getQualifiedName(), helper.getClassLoader());
                }

                JAXBElementConverter converter = new JAXBElementConverter(xmlField, declaredType, scopeClass);
                if (isCollection){
                    ChoiceCollectionMapping xmlChoiceCollectionMapping = (ChoiceCollectionMapping) mapping;
                    if(element.getJavaTypeAdapterClass() != null){
                        converter.setNestedConverter(new XMLJavaTypeConverter(element.getJavaTypeAdapterClass().getName()));
                    }else{
                        CoreConverter originalConverter = xmlChoiceCollectionMapping.getConverter(xmlField);
                        converter.setNestedConverter(originalConverter);
                    }
                    xmlChoiceCollectionMapping.addConverter(xmlField, converter);
                } else {
                    ChoiceObjectMapping xmlChoiceObjectMapping = (ChoiceObjectMapping) mapping;
                    if(element.getJavaTypeAdapterClass() != null){
                        converter.setNestedConverter(new XMLJavaTypeConverter(element.getJavaTypeAdapterClass().getName()));
                    }else{
                        CoreConverter originalConverter = xmlChoiceObjectMapping.getConverter(xmlField);
                        converter.setNestedConverter(originalConverter);
                    }
                    xmlChoiceObjectMapping.addConverter(xmlField, converter);
                }
            }
        }
        if(property.isAny()){
            if(isCollection){
                XMLChoiceCollectionMapping xmlChoiceCollectionMapping = (XMLChoiceCollectionMapping) mapping;
                xmlChoiceCollectionMapping.setIsAny(true);
            }
        }

        return mapping;
    }

    private void setTypedTextField(Field field){

        field.setIsTypedTextField(true);
        if(field.getSchemaType() == null){
            field.setSchemaType(Constants.ANY_TYPE_QNAME);
        }
         ((XMLField)field).addXMLConversion(Constants.DATE_TIME_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR);
        ((XMLField)field).addXMLConversion(Constants.DATE_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR);
        ((XMLField)field).addXMLConversion(Constants.TIME_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR);
        ((XMLField)field).addJavaConversion(CoreClassConstants.APBYTE, Constants.BASE_64_BINARY_QNAME);
        ((XMLField)field).addJavaConversion(CoreClassConstants.ABYTE, Constants.BASE_64_BINARY_QNAME);

    }

    public AnyCollectionMapping generateAnyCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, boolean isMixed) {
        AnyCollectionMapping  mapping = new XMLAnyCollectionMapping();
        initializeXMLContainerMapping(mapping, property.getType().isArray());
        initializeXMLMapping((XMLMapping)mapping, property);

        // if the XPath is set (via xml-path) use it
        if (property.getXmlPath() != null) {
            mapping.setField(new XMLField(property.getXmlPath()));
        } else {
            if (property.isSetXmlElementWrapper()) {
                mapping.setField(getXPathForField(property, namespaceInfo, false, true));
            }
        }

        if (property.isSetXmlElementWrapper()) {
            mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property));
        }

        Class declaredType = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(property.getActualType().getQualifiedName(), helper.getClassLoader());
        JAXBElementRootConverter jaxbElementRootConverter = new JAXBElementRootConverter(declaredType);
        mapping.setConverter(jaxbElementRootConverter);
        if (property.getDomHandlerClassName() != null) {
            jaxbElementRootConverter.setNestedConverter(new DomHandlerConverter(property.getDomHandlerClassName()));
        }

        if (property.isLax() || property.isReference()) {
            mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
        } else {
            if (property.isAny()) {
                mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT);
            } else {
                mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_NONE_AS_ELEMENT);
            }
        }

        mapping.setMixedContent(isMixed);
        if (isMixed) {
            mapping.setPreserveWhitespaceForMixedContent(true);
        }
        if (property.isAny()) {
            mapping.setUseXMLRoot(true);
        }

        JavaClass collectionType = property.getType();
        if (collectionType.isArray()){
            JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader());
            JavaClass componentType = collectionType.getComponentType();
            if(componentType.isArray()) {
                JavaClass baseComponentType = getBaseComponentType(componentType);
                if (baseComponentType.isPrimitive()){
                    Class<Object> primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName());
                    accessor.setComponentClass(primitiveClass);
                } else {
                    accessor.setComponentClassName(baseComponentType.getQualifiedName());
                }
            } else {
                accessor.setComponentClassName(componentType.getQualifiedName());
            }
            mapping.setAttributeAccessor(accessor);
        }
        collectionType = containerClassImpl(collectionType);
        mapping.useCollectionClass(helper.getClassForJavaClass(collectionType));

        return mapping;
    }

    public CompositeObjectMapping generateCompositeObjectMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, String referenceClassName) {
        CompositeObjectMapping mapping = new XMLCompositeObjectMapping();

        initializeXMLMapping((XMLMapping)mapping, property);

        // if the XPath is set (via xml-path) use it; otherwise figure it out
        mapping.setField(getXPathForField(property, namespaceInfo, false, false));
        // handle null policy set via xml metadata
        if (property.isSetNullPolicy()) {
            mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo)));
        } else {
            NullPolicy nullPolicy = (NullPolicy) mapping.getNullPolicy();
            nullPolicy.setSetPerformedForAbsentNode(false);
            if(property.isNillable()) {
                nullPolicy.setNullRepresentedByXsiNil(true);
                nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
            }
        }

        if (referenceClassName == null){
            setTypedTextField((Field)mapping.getField());
            String defaultValue = property.getDefaultValue();
            if (null != defaultValue) {
                mapping.setConverter(new DefaultElementConverter(defaultValue));
            }
        } else {
            mapping.setReferenceClassName(referenceClassName);
        }
            if(property.isTransientType()){
                mapping.setReferenceClassName(Constants.UNKNOWN_OR_TRANSIENT_CLASS);
            }

        if (property.isRequired()) {
            ((Field) mapping.getField()).setRequired(true);
        }
        return mapping;

    }

    public DirectMapping generateDirectMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) {
        DirectMapping mapping = new XMLDirectMapping();
        mapping.setNullValueMarshalled(true);

        String fixedValue = property.getFixedValue();
        if (fixedValue != null) {
            mapping.setIsWriteOnly(true);
        }
        initializeXMLMapping((XMLMapping)mapping, property);

        // if the XPath is set (via xml-path) use it; otherwise figure it out
        Field xmlField = getXPathForField(property, namespaceInfo, true, false);
        mapping.setField(xmlField);

        if (property.getDefaultValue() != null) {
            mapping.setNullValue(property.getDefaultValue());
        }

        if (property.isXmlId()) {
            mapping.setCollapsingStringValues(true);
        }

        // handle null policy set via xml metadata
        if (property.isSetNullPolicy()) {
            mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo)));
        } else {
            if (property.isNillable()){
                mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
                mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
            }
            mapping.getNullPolicy().setNullRepresentedByEmptyNode(false);

            if (!mapping.getXPath().equals("text()")) {
                ((NullPolicy) mapping.getNullPolicy()).setSetPerformedForAbsentNode(false);
            }
        }

        if (property.isRequired()) {
            ((Field) mapping.getField()).setRequired(true);
        }

        if (property.getType() != null) {
            String theClass = null;
            String targetClass = null;
            if (property.isSetXmlJavaTypeAdapter()) {
                theClass = property.getOriginalType().getQualifiedName();
                targetClass = property.getType().getQualifiedName();
            } else {
                theClass = property.getType().getQualifiedName();

            }
            // Try to get the actual Class
            try {
                JavaClass actualJavaClass = helper.getJavaClass(theClass);
                Class actualClass =  org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(actualJavaClass.getQualifiedName(), helper.getClassLoader());
                mapping.setAttributeClassification(actualClass);
                if(targetClass != null) {
                    Class fieldClass = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(targetClass, helper.getClassLoader());
                    mapping.getField().setType(fieldClass);
                }

            } catch (Exception e) {
                // Couldn't find Class (Dynamic?), so set class name instead.
                mapping.setAttributeClassificationName(theClass);
            }
        }

        if (Constants.QNAME_QNAME.equals(property.getSchemaType())){
            ((Field) mapping.getField()).setSchemaType(Constants.QNAME_QNAME);
        }
        // handle cdata set via metadata
        if (property.isSetCdata()) {
            mapping.setIsCDATA(property.isCdata());
        }
        return mapping;
    }

    public BinaryDataMapping generateBinaryMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) {
        BinaryDataMapping mapping = new XMLBinaryDataMapping();

        initializeXMLMapping((XMLMapping)mapping, property);

        // if the XPath is set (via xml-path) use it
        mapping.setField(getXPathForField(property, namespaceInfo, false, false));
        if (property.isSwaAttachmentRef()) {
            ((Field) mapping.getField()).setSchemaType(Constants.SWA_REF_QNAME);
            mapping.setSwaRef(true);
        } else if (property.isMtomAttachment()) {
            Field f = ((Field) mapping.getField());
            if (!f.getSchemaType().equals(Constants.HEX_BINARY_QNAME)) {
                f.setSchemaType(Constants.BASE_64_BINARY_QNAME);
            }
        }

        if (property.isInlineBinaryData()) {
            mapping.setShouldInlineBinaryData(true);
        }
        // use a non-dynamic implementation of MimeTypePolicy to wrap the MIME string
        if (property.getMimeType() != null) {
            mapping.setMimeTypePolicy(new FixedMimeTypePolicy(property.getMimeType(),(DatabaseMapping) mapping));
        } else {
            if(areEquals(property.getType(), javax.xml.transform.Source.class)) {
                mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/xml", (DatabaseMapping)mapping));
            } else if(areEquals(property.getType(), java.awt.Image.class)) {
                mapping.setMimeTypePolicy(new FixedMimeTypePolicy("image/png", (DatabaseMapping)mapping));
            } else {
                mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/octet-stream", (DatabaseMapping)mapping));
            }
        }
        if (property.isSetNullPolicy()) {
            mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo)));
        } else {
            if (property.isNillable()){
                mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
                mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
            }
            mapping.getNullPolicy().setNullRepresentedByEmptyNode(false);

            if (!mapping.getXPath().equals("text()")) {
                ((NullPolicy) mapping.getNullPolicy()).setSetPerformedForAbsentNode(false);
            }
        }
        mapping.setAttributeClassificationName(property.getActualType().getQualifiedName());
        return mapping;
    }

    public BinaryDataCollectionMapping generateBinaryDataCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) {
        BinaryDataCollectionMapping mapping = new XMLBinaryDataCollectionMapping();
        initializeXMLMapping((XMLMapping)mapping, property);

        initializeXMLContainerMapping(mapping, property.getType().isArray());

        if (property.isSetXmlElementWrapper()) {
            mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property));
        }

        // handle null policy set via xml metadata
        if (property.isSetNullPolicy()) {
            mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo)));
        } else if (property.isNillable()){
            mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
            mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
        }

        // if the XPath is set (via xml-path) use it
        mapping.setField(getXPathForField(property, namespaceInfo, false, false));
        if (property.isSwaAttachmentRef()) {
            ((Field) mapping.getField()).setSchemaType(Constants.SWA_REF_QNAME);
            mapping.setSwaRef(true);
        } else if (property.isMtomAttachment()) {
            Field f = (Field) mapping.getField();
            if (!f.getSchemaType().equals(Constants.HEX_BINARY_QNAME)) {
                f.setSchemaType(Constants.BASE_64_BINARY_QNAME);
            }
        }
        if (property.isInlineBinaryData()) {
            mapping.setShouldInlineBinaryData(true);
        }
        // use a non-dynamic implementation of MimeTypePolicy to wrap the MIME string
        if (property.getMimeType() != null) {
            mapping.setMimeTypePolicy(new FixedMimeTypePolicy(property.getMimeType()));
        } else {
            if(areEquals(property.getType(), javax.xml.transform.Source.class)) {
                mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/xml"));
            } else {
                mapping.setMimeTypePolicy(new FixedMimeTypePolicy("application/octet-stream"));
            }
        }

        JavaClass collectionType = property.getType();
        JavaClass itemType = property.getActualType();
        if(collectionType != null && helper.isCollectionType(collectionType)){
            try{
                Class<Object> declaredClass = PrivilegedAccessHelper.getClassForName(itemType.getQualifiedName(), false, helper.getClassLoader());
                mapping.setAttributeElementClass(declaredClass);
            }catch (Exception e) {
            }
        }
        collectionType = containerClassImpl(collectionType);
        mapping.useCollectionClassName(collectionType.getRawName());
        return mapping;
    }

    public DirectMapping generateDirectEnumerationMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, EnumTypeInfo enumInfo) {
        DirectMapping mapping = new XMLDirectMapping();
        initializeXMLMapping((XMLMapping)mapping, property);
        mapping.setNullValueMarshalled(true);
        mapping.setConverter(buildJAXBEnumTypeConverter(mapping, enumInfo));
        // handle null policy set via xml metadata
        if (property.isSetNullPolicy()) {
            mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo)));
        } else if (property.isNillable()){
            mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
            mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
        }
        mapping.setField(getXPathForField(property, namespaceInfo, true, false));
        if (!mapping.getXPath().equals("text()")) {
            ((NullPolicy) mapping.getNullPolicy()).setSetPerformedForAbsentNode(false);
        }
        return mapping;
    }

    private JAXBEnumTypeConverter buildJAXBEnumTypeConverter(Mapping mapping, EnumTypeInfo enumInfo){
        JAXBEnumTypeConverter converter = new JAXBEnumTypeConverter(mapping, enumInfo.getClassName(), false);
        List<String> fieldNames = enumInfo.getFieldNames();
        List<Object> xmlEnumValues = enumInfo.getXmlEnumValues();
        for (int i=0; i< fieldNames.size(); i++) {
            converter.addConversionValue(xmlEnumValues.get(i), fieldNames.get(i));
        }
        return converter;
    }

    public Mapping generateCollectionMapping(Property property, Descriptor descriptor, JavaClass descriptorJavaClass, NamespaceInfo namespaceInfo) {
        // check to see if this should be a composite or direct mapping
        JavaClass javaClass = property.getActualType();

        if (property.isMixedContent()) {
            return generateAnyCollectionMapping(property, descriptor, namespaceInfo, true);
        }
        if (property.isXmlIdRef() || property.isSetXmlJoinNodes()) {
            return generateXMLCollectionReferenceMapping(property, descriptor, namespaceInfo, javaClass);
        }

        if (javaClass != null && typeInfo.get(javaClass.getQualifiedName()) != null) {
            TypeInfo referenceInfo = typeInfo.get(javaClass.getQualifiedName());
            if (referenceInfo.isEnumerationType()) {
                return generateEnumCollectionMapping(property,  descriptor, namespaceInfo,(EnumTypeInfo) referenceInfo);
            }
            return generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, javaClass.getQualifiedName());
        }
        if (!property.isAttribute() && javaClass != null && javaClass.getQualifiedName().equals(OBJECT_CLASS_NAME)){
            CompositeCollectionMapping ccMapping = generateCompositeCollectionMapping(property, descriptor, descriptorJavaClass, namespaceInfo, null);
            ccMapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
            return ccMapping;
        }
        if(isBinaryData(javaClass)){
            return generateBinaryDataCollectionMapping(property, descriptor, namespaceInfo);
        }
        return generateDirectCollectionMapping(property, descriptor, namespaceInfo);
    }

    public DirectCollectionMapping generateEnumCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, EnumTypeInfo info) {

        DirectCollectionMapping mapping = generateDirectCollectionMapping(property, descriptor, namespaceInfo);
        mapping.setValueConverter(buildJAXBEnumTypeConverter(mapping, info));
        return mapping;
    }
    public AnyAttributeMapping generateAnyAttributeMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) {
        XMLAnyAttributeMapping mapping = new XMLAnyAttributeMapping();
        initializeXMLMapping(mapping, property);
        initializeXMLContainerMapping(mapping, property.getType().isArray());

        // if the XPath is set (via xml-path) use it
        if (property.getXmlPath() != null) {
            mapping.setField(new XMLField(property.getXmlPath()));
        }
        mapping.setSchemaInstanceIncluded(false);
        mapping.setNamespaceDeclarationIncluded(false);

        JavaClass mapType = property.getType();
        if (areEquals(mapType, Map.class)) {
            mapType = jotHashMap;
        }
        mapping.useMapClassName(mapType.getRawName());

        return mapping;
    }

    public AnyObjectMapping generateAnyObjectMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo)  {
        AnyObjectMapping<AbstractSession, AttributeAccessor, ContainerPolicy, XMLConverter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, UnmarshalKeepAsElementPolicy, XMLUnmarshaller, XMLRecord> mapping = new XMLAnyObjectMapping();
        initializeXMLMapping((XMLMapping)mapping, property);

        // if the XPath is set (via xml-path) use it
        if (property.getXmlPath() != null) {
            mapping.setField(new XMLField(property.getXmlPath()));
        }

        Class declaredType = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(property.getActualType().getQualifiedName(), helper.getClassLoader());
        JAXBElementRootConverter jaxbElementRootConverter = new JAXBElementRootConverter(declaredType);
        mapping.setConverter(jaxbElementRootConverter);
        if (property.getDomHandlerClassName() != null) {
            jaxbElementRootConverter.setNestedConverter(new DomHandlerConverter(property.getDomHandlerClassName()));
        }

        if (property.isLax()) {
            mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
        } else {
            mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT);
        }

        if (property.isMixedContent()) {
            mapping.setMixedContent(true);
        } else {
            mapping.setUseXMLRoot(true);
        }

        return mapping;
    }

    protected boolean areEquals(JavaClass src, Class tgt) {
        if (src == null || tgt == null) {
            return false;
        }
        return src.getRawName().equals(tgt.getCanonicalName());
    }

    /**
     * Compares a JavaModel JavaClass to a Class.  Equality is based on
     * the raw name of the JavaClass compared to the canonical
     * name of the Class.
     *
     * @param src
     * @param tgtCanonicalName
     * @return
     */
    protected boolean areEquals(JavaClass src, String tgtCanonicalName) {
        if (src == null || tgtCanonicalName == null) {
            return false;
        }
        return src.getRawName().equals(tgtCanonicalName);
    }


    private Class generateMapEntryClassAndDescriptor(Property property, NamespaceResolver nr){
        JavaClass keyType = property.getKeyType();
        JavaClass valueType = property.getValueType();
        if(keyType == null){
            keyType = helper.getJavaClass("java.lang.Object");
        }
        if(valueType == null){
            valueType = helper.getJavaClass("java.lang.Object");
        }

        String mapEntryClassName = getJaxbClassLoader().nextAvailableGeneratedClassName();

        MapEntryGeneratedKey mapKey = new MapEntryGeneratedKey(keyType.getQualifiedName(),valueType.getQualifiedName());
        Class generatedClass = getGeneratedMapEntryClasses().get(mapKey);

        if(generatedClass == null){
            generatedClass = generateMapEntryClass(mapEntryClassName, keyType.getQualifiedName(), valueType.getQualifiedName());
            getGeneratedMapEntryClasses().put(mapKey, generatedClass);
            Descriptor desc = new XMLDescriptor();
            desc.setJavaClass(generatedClass);

            desc.addMapping((CoreMapping)generateMappingForType(keyType, Property.DEFAULT_KEY_NAME));
            desc.addMapping((CoreMapping)generateMappingForType(valueType, Property.DEFAULT_VALUE_NAME));
            desc.setNamespaceResolver(nr);
            project.addDescriptor((CoreDescriptor)desc);
        }
        return generatedClass;
    }

    private Class generateMapEntryClass(String className, String keyType, String valueType){

        EclipseLinkASMClassWriter cw = new EclipseLinkASMClassWriter();

        String qualifiedInternalClassName = className.replace('.', '/');
        String qualifiedInternalKeyClassName = keyType.replace('.', '/');
        String qualifiedInternalValueClassName = valueType.replace('.', '/');

        String valuePrefix = "L"; // non-array type
        if (qualifiedInternalValueClassName.startsWith("[L") && qualifiedInternalValueClassName.endsWith(";")) {
            valuePrefix = "[L"; // array type
            qualifiedInternalValueClassName = qualifiedInternalValueClassName.substring(2, qualifiedInternalValueClassName.length() - 1);
        }

        String sig = "Ljava/lang/Object;Lorg/eclipse/persistence/internal/jaxb/many/MapEntry<L"+qualifiedInternalKeyClassName+";" + valuePrefix + qualifiedInternalValueClassName+";>;";
        cw.visit(Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, qualifiedInternalClassName, sig, "java/lang/Object", new String[] { "org/eclipse/persistence/internal/jaxb/many/MapEntry" });

        cw.visitField(Opcodes.ACC_PRIVATE, "key", "L"+qualifiedInternalKeyClassName+";", null, null);

        cw.visitField(Opcodes.ACC_PRIVATE, "value", valuePrefix + qualifiedInternalValueClassName+";", null, null);

        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();

        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getKey", "()L"+qualifiedInternalKeyClassName+";", null, null);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, qualifiedInternalClassName, "key", "L"+qualifiedInternalKeyClassName+";");
        mv.visitInsn(Opcodes.ARETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();

        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setKey", "(L"+qualifiedInternalKeyClassName+";)V", null, null);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitFieldInsn(Opcodes.PUTFIELD, qualifiedInternalClassName, "key", "L"+qualifiedInternalKeyClassName+";");
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();

        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getValue", "()" + valuePrefix + qualifiedInternalValueClassName+";", null, null);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, qualifiedInternalClassName, "value", valuePrefix + qualifiedInternalValueClassName+";");
        mv.visitInsn(Opcodes.ARETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();

        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setValue", "(" + valuePrefix + qualifiedInternalValueClassName+";)V", null, null);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitFieldInsn(Opcodes.PUTFIELD, qualifiedInternalClassName, "value", valuePrefix + qualifiedInternalValueClassName+";");
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();

        if(!qualifiedInternalValueClassName.equals("java/lang/Object")){
            mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "getValue", "()Ljava/lang/Object;", null, null);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, qualifiedInternalClassName, "getValue", "()" + valuePrefix + qualifiedInternalValueClassName+";", false);
            mv.visitInsn(Opcodes.ARETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();

            mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "setValue", "(Ljava/lang/Object;)V", null, null);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            // CHECKCAST is slightly different for array types
            if (valuePrefix.equals("[L")) {
                mv.visitTypeInsn(Opcodes.CHECKCAST, valuePrefix + qualifiedInternalValueClassName + ";");
            } else {
                mv.visitTypeInsn(Opcodes.CHECKCAST, qualifiedInternalValueClassName);
            }
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, qualifiedInternalClassName, "setValue", "(" + valuePrefix + qualifiedInternalValueClassName+";)V", false);
            mv.visitInsn(Opcodes.RETURN);
            mv.visitMaxs(2, 2);
            mv.visitEnd();
        }

        if(!qualifiedInternalKeyClassName.equals("java/lang/Object")){
            mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "getKey", "()Ljava/lang/Object;", null, null);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,qualifiedInternalClassName, "getKey", "()L"+qualifiedInternalKeyClassName+";", false);
            mv.visitInsn(Opcodes.ARETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();

            mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, "setKey", "(Ljava/lang/Object;)V", null, null);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            mv.visitTypeInsn(Opcodes.CHECKCAST, qualifiedInternalKeyClassName);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, qualifiedInternalClassName, "setKey", "(L"+qualifiedInternalKeyClassName+";)V", false);
            mv.visitInsn(Opcodes.RETURN);
            mv.visitMaxs(2, 2);
            mv.visitEnd();
        }

        cw.visitEnd();

        byte[] classBytes =cw.toByteArray();
        Class generatedClass = getJaxbClassLoader().generateClass(className, classBytes);
        return generatedClass;
    }

    private Mapping generateMappingForType(JavaClass theType, String attributeName){
        Mapping mapping;
        boolean typeIsObject =  theType.getRawName().equals(OBJECT_CLASS_NAME);
        TypeInfo info = typeInfo.get(theType.getQualifiedName());
        if ((info != null && !(info.isEnumerationType())) || typeIsObject) {
            mapping = new XMLCompositeObjectMapping();
            mapping.setAttributeName(attributeName);
            ((CompositeObjectMapping)mapping).setXPath(attributeName);
            if(typeIsObject){
                ((CompositeObjectMapping)mapping).setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
                setTypedTextField((Field) mapping.getField());
            }else{
                ((CompositeObjectMapping)mapping).setReferenceClassName(theType.getQualifiedName());
            }
        } else if (theType.isArray() || helper.isCollectionType(theType)) {
            DirectCollectionMapping directCollectionMapping;
            mapping = directCollectionMapping = new XMLCompositeDirectCollectionMapping();
            initializeXMLContainerMapping(directCollectionMapping, theType.isArray());
            directCollectionMapping.setAttributeName(attributeName);
            if (theType.isArray()) {
                JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(directCollectionMapping.getAttributeAccessor(),
                        directCollectionMapping.getContainerPolicy(), helper.getClassLoader());
                String componentClassName = theType.getComponentType().getQualifiedName();
                if (theType.getComponentType().isPrimitive()){
                    Class<Object> primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(componentClassName);
                    accessor.setComponentClass(primitiveClass);
                    directCollectionMapping.setAttributeAccessor(accessor);

                    Class<Object> declaredClass = XMLConversionManager.getObjectClass(primitiveClass);
                    directCollectionMapping.setAttributeElementClass(declaredClass);
                } else {
                    accessor.setComponentClassName(componentClassName);
                    directCollectionMapping.setAttributeAccessor(accessor);

                    JavaClass componentType = theType.getComponentType();
                    try {
                        Class declaredClass;
                        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                                try {
                                    declaredClass = AccessController.doPrivileged(new PrivilegedClassForName<>(componentType.getRawName(), false, helper.getClassLoader()));
                                } catch (PrivilegedActionException exception) {
                                    throw JAXBException.classNotFoundException(componentType.getRawName());
                                }
                        } else {
                            declaredClass = PrivilegedAccessHelper.getClassForName(componentType.getRawName(), false, helper.getClassLoader());
                        }
                        directCollectionMapping.setAttributeElementClass(declaredClass);
                    } catch (ClassNotFoundException e) {
                        throw JAXBException.classNotFoundException(componentType.getRawName());
                    }
                }
            } else if (helper.isCollectionType(theType)) {
                Collection args = theType.getActualTypeArguments();
                if (args.size() > 0) {
                    JavaClass itemType = (JavaClass)args.iterator().next();
                    try {
                        Class declaredClass;
                        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                                try {
                                    declaredClass = AccessController.doPrivileged(new PrivilegedClassForName<>(itemType.getRawName(), false, helper.getClassLoader()));
                                } catch (PrivilegedActionException exception) {
                                    throw JAXBException.classNotFoundException(itemType.getRawName());
                                }
                        } else {
                            declaredClass = PrivilegedAccessHelper.getClassForName(itemType.getRawName(), false, helper.getClassLoader());
                        }
                        if(declaredClass != String.class){
                            directCollectionMapping.setAttributeElementClass(declaredClass);
                        }
                    } catch (ClassNotFoundException e) {
                        throw JAXBException.classNotFoundException(itemType.getRawName());
                    }
                }
            }
            theType = containerClassImpl(theType);
            directCollectionMapping.useCollectionClassName(theType.getRawName());
            directCollectionMapping.setXPath(attributeName + TXT);
        } else {
            mapping = new XMLDirectMapping();
            mapping.setAttributeName(attributeName);
            ((DirectMapping)mapping).setNullValueMarshalled(true);
            ((DirectMapping)mapping).setXPath(attributeName + TXT);

            QName schemaType = userDefinedSchemaTypes.get(theType.getQualifiedName());

            if (schemaType == null) {
                schemaType = (QName) helper.getXMLToJavaTypeMap().get(theType);
            }
            ((Field) mapping.getField()).setSchemaType(schemaType);
            if(info != null && info.isEnumerationType()) {
                ((DirectMapping)mapping).setConverter(buildJAXBEnumTypeConverter(mapping, (EnumTypeInfo)info));
            }
        }
        return mapping;
    }

    public CompositeCollectionMapping generateCompositeCollectionMapping(Property property, Descriptor descriptor, JavaClass javaClass, NamespaceInfo namespaceInfo, String referenceClassName) {
        boolean nestedArray = false;
        CompositeCollectionMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, UnmarshalKeepAsElementPolicy, XMLUnmarshaller, XMLRecord> mapping = new XMLCompositeCollectionMapping();
        initializeXMLMapping((XMLMapping)mapping, property);
        initializeXMLContainerMapping(mapping, property.getType().isArray());

        JavaClass manyValueJavaClass = helper.getJavaClass(ManyValue.class);
        if (manyValueJavaClass.isAssignableFrom(javaClass)){
            mapping.setReuseContainer(false);
        }

        // handle null policy set via xml metadata
        if (property.isSetNullPolicy()) {
            mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo)));
        } else if (property.isNillable()){
            mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
            mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
        }

        if (property.isSetXmlElementWrapper()) {
            mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property));
        }

        JavaClass collectionType = property.getType();

        if (collectionType.isArray()){
            JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader());
            JavaClass componentType = collectionType.getComponentType();
            if(componentType.isArray()) {
                Class adaptedClass = classToGeneratedClasses.get(componentType.getName());
                referenceClassName = adaptedClass.getName();
                accessor.setAdaptedClassName(referenceClassName);
                JavaClass baseComponentType = getBaseComponentType(componentType);
                if (baseComponentType.isPrimitive()){
                    Class<Object> primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName());
                    accessor.setComponentClass(primitiveClass);
                } else {
                    accessor.setComponentClassName(baseComponentType.getQualifiedName());
                }
            } else {
                accessor.setComponentClassName(componentType.getQualifiedName());
            }
            mapping.setAttributeAccessor(accessor);
        }else if (helper.isMapType(property.getType())){
            Class generatedClass = generateMapEntryClassAndDescriptor(property, descriptor.getNonNullNamespaceResolver());
            referenceClassName = generatedClass.getName();
            String mapClassName = property.getType().getRawName();
            mapping.setAttributeAccessor(new MapValueAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), generatedClass, mapClassName, helper.getClassLoader()));
        }
        //Nested array check (used in JSON marshalling)
        if (collectionType.getComponentType() == null) {
            if ((collectionType.isArray() || helper.isCollectionType(collectionType)) && (referenceClassName != null && referenceClassName.contains(AnnotationsProcessor.ARRAY_PACKAGE_NAME))) {
                nestedArray = true;
            }
        } else if ((collectionType.isArray() || helper.isCollectionType(collectionType)) && (collectionType.getComponentType().isArray() || helper.isCollectionType(collectionType.getComponentType()))) {
            nestedArray = true;
        }
        collectionType = containerClassImpl(collectionType);
        mapping.useCollectionClassName(collectionType.getRawName());

        // if the XPath is set (via xml-path) use it; otherwise figure it out
        Field xmlField = getXPathForField(property, namespaceInfo, false, false);
        if(helper.isMapType(property.getType())){
            JavaClass mapValueClass = helper.getJavaClass(MapValue.class);
            if(mapValueClass.isAssignableFrom(javaClass)){
                mapping.setXPath("entry");
            }else{
                mapping.setXPath(xmlField.getXPath() + "/entry");
            }
        }else{
            mapping.setXPath(xmlField.getXPath());
        }

        if (referenceClassName == null){
            setTypedTextField((Field)mapping.getField());
        } else {
            mapping.setReferenceClassName(referenceClassName);
        }
        if(property.isTransientType()){
            mapping.setReferenceClassName(Constants.UNKNOWN_OR_TRANSIENT_CLASS);
        }

        if (property.isRequired()) {
            ((Field) mapping.getField()).setRequired(true);
        }

        ((Field) mapping.getField()).setNestedArray(nestedArray);
        return mapping;
    }

    public DirectCollectionMapping generateDirectCollectionMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo) {
        DirectCollectionMapping mapping = new XMLCompositeDirectCollectionMapping();
        initializeXMLMapping((XMLMapping)mapping, property);

        initializeXMLContainerMapping(mapping, property.getType().isArray());

        JavaClass collectionType = property.getType();

        if (collectionType.isArray()){
            JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader());
            String componentClassName = collectionType.getComponentType().getQualifiedName();
            if (collectionType.getComponentType().isPrimitive()){
                Class<?> primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(componentClassName);
                accessor.setComponentClass(primitiveClass);
                mapping.setAttributeAccessor(accessor);

                Class<?> declaredClass = XMLConversionManager.getObjectClass(primitiveClass);
                mapping.setAttributeElementClass(declaredClass);
            } else {
                accessor.setComponentClassName(componentClassName);
                mapping.setAttributeAccessor(accessor);

                JavaClass componentType = collectionType.getComponentType();
                try{
                    Class<?> declaredClass = PrivilegedAccessHelper.getClassForName(componentType.getRawName(), false, helper.getClassLoader());
                    mapping.setAttributeElementClass(declaredClass);
                }catch (Exception e) {}
            }
        } else if (helper.isCollectionType(collectionType)){
            Collection args = collectionType.getActualTypeArguments();
            if (args.size() >0){
                JavaClass itemType = (JavaClass)args.iterator().next();
                try {
                    Class<?> declaredClass = PrivilegedAccessHelper.getClassForName(itemType.getRawName(), false, helper.getClassLoader());
                    if(declaredClass != String.class){
                        mapping.setAttributeElementClass(declaredClass);
                    }
                } catch (Exception e) {}
            }
        }
        collectionType = containerClassImpl(collectionType);
        mapping.useCollectionClassName(collectionType.getRawName());

        if (property.getDefaultValue() != null) {
            mapping.setNullValue(property.getDefaultValue());
        }

        // if the XPath is set (via xml-path) use it; otherwise figure it out
        Field xmlField = getXPathForField(property, namespaceInfo, true, false);
        mapping.setField(xmlField);

        if (helper.isAnnotationPresent(property.getElement(), XmlMixed.class)) {
            xmlField.setXPath("text()");
        }

        if (Constants.QNAME_QNAME.equals(property.getSchemaType())){
            ((Field) mapping.getField()).setSchemaType(Constants.QNAME_QNAME);
        }

        // handle null policy set via xml metadata
        if (property.isSetNullPolicy()) {
            mapping.setNullPolicy(getNullPolicyFromProperty(property, getNamespaceResolverForDescriptor(namespaceInfo)));
        } else if (property.isNillable()){
            mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
            mapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
        }
        mapping.getNullPolicy().setNullRepresentedByEmptyNode(false);

        if (property.isSetXmlElementWrapper()) {
            mapping.setWrapperNullPolicy(getWrapperNullPolicyFromProperty(property));
        }

        if (property.isRequired()) {
            ((Field) mapping.getField()).setRequired(true);
        }

        if (property.isXmlElementType() && property.getGenericType()!=null ){
            Class theClass = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(property.getGenericType().getQualifiedName(), helper.getClassLoader());
            mapping.setAttributeElementClass(theClass);
        }

        if (xmlField.getXPathFragment().isAttribute() || property.isXmlList() || xmlField.getXPathFragment().nameIsText()){
            mapping.setUsesSingleNode(true);
        }
        // handle cdata set via metadata
        if (property.isSetCdata()) {
            mapping.setIsCDATA(property.isCdata());
        }
        return mapping;
    }


    public String getPrefixForNamespace(String URI, NamespaceResolver namespaceResolver) {
        return getPrefixForNamespace(URI, namespaceResolver, true);
    }

    public String getPrefixForNamespace(String URI, NamespaceResolver namespaceResolver, boolean addPrefixToNR) {
        String defaultNS = namespaceResolver.getDefaultNamespaceURI();
        if(defaultNS != null && URI.equals(defaultNS)){
            return null;
        }
        String prefix = namespaceResolver.resolveNamespaceURI(URI);
        if (prefix != null) {
            return prefix;
        }
        prefix = globalNamespaceResolver.resolveNamespaceURI(URI);
        if(prefix == null){
            if(URI.equals(globalNamespaceResolver.getDefaultNamespaceURI())) {
                namespaceResolver.setDefaultNamespaceURI(URI);
                return null;
            } else {
                //Bug 400536 before generating a new one check other resolvers
                String suggestedPrefix = null;
                NamespaceInfo refInfo = getNamespaceInfoForURI(URI);
                if(refInfo != null && refInfo.getNamespaceResolver() !=null){
                    suggestedPrefix = refInfo.getNamespaceResolver().resolveNamespaceURI(URI);
                }
                if(suggestedPrefix != null){
                    prefix = globalNamespaceResolver.generatePrefix(suggestedPrefix);
                } else{
                    prefix = globalNamespaceResolver.generatePrefix();
                }
            }
        }

        String nrUri = namespaceResolver.resolveNamespacePrefix(prefix);
        while(null != nrUri && !URI.equals(nrUri)){
            prefix = globalNamespaceResolver.generatePrefix();
            nrUri = namespaceResolver.resolveNamespacePrefix(prefix);
        }
        if(addPrefixToNR){
            namespaceResolver.put(prefix, URI);
        }
        globalNamespaceResolver.put(prefix, URI);
        return prefix;
    }

    /**
     * Setup inheritance for abstract superclass.
     *
     * NOTE: We currently only handle one level of inheritance in this case.
     * For multiple levels the code will need to be modified. The logic in
     * generateMappings() that determines when to copy down inherited
     * methods from the parent class will need to be changed as well.
     *
     * @param jClass
     */
    private void setupInheritance(JavaClass jClass) {
        TypeInfo tInfo = typeInfo.get(jClass.getName());
        Descriptor descriptor = tInfo.getDescriptor();
        if (descriptor == null) {
            return;
        }

        JavaClass superClass = CompilerHelper.getNextMappedSuperClass(jClass, typeInfo, helper);
        if (superClass == null){
            return;
        }

        TypeInfo superTypeInfo =  typeInfo.get(superClass.getName());
        if (superTypeInfo == null){
            return;
        }
        Descriptor superDescriptor = superTypeInfo.getDescriptor();
        if (superDescriptor != null) {
            XMLSchemaReference sRef = descriptor.getSchemaReference();
            if (sRef == null || sRef.getSchemaContext() == null) {
                return;
            }

            JavaClass rootMappedSuperClass = getRootMappedSuperClass(superClass);
            TypeInfo rootTypeInfo =  typeInfo.get(rootMappedSuperClass.getName());
            Descriptor rootDescriptor = rootTypeInfo.getDescriptor();
            if (rootDescriptor.getNamespaceResolver() == null) {
                rootDescriptor.setNamespaceResolver(new org.eclipse.persistence.oxm.NamespaceResolver());
            }

            if (rootDescriptor.getInheritancePolicy().getClassIndicatorField() == null) {
                Field classIndicatorField;
                if (rootTypeInfo.isSetXmlDiscriminatorNode()) {
                    classIndicatorField = new XMLField(rootTypeInfo.getXmlDiscriminatorNode());
                } else {
                    classIndicatorField = XMLConstants.DEFAULT_XML_TYPE_ATTRIBUTE;
                    classIndicatorField.getXPathFragment().setNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                }
                rootDescriptor.getInheritancePolicy().setClassIndicatorField(classIndicatorField);
            }

            Object sCtx = null;
            //TypeInfo tInfo = typeInfo.get(jClass.getName());
            if (tInfo.isSetXmlDiscriminatorValue()) {
                sCtx = tInfo.getXmlDiscriminatorValue();
            } else if(!tInfo.isAnonymousComplexType()){
                sCtx = sRef.getSchemaContextAsQName();
            }
            if(sCtx != null) {
                descriptor.getInheritancePolicy().setParentClassName(superClass.getName());
                rootDescriptor.getInheritancePolicy().addClassNameIndicator(jClass.getName(), sCtx);
            }
            Object value = rootDescriptor.getInheritancePolicy().getClassNameIndicatorMapping().get(rootDescriptor.getJavaClassName());
            if (value == null){
                if (rootTypeInfo.isSetXmlDiscriminatorValue()) {
                    rootDescriptor.getInheritancePolicy().addClassNameIndicator(rootDescriptor.getJavaClassName(), rootTypeInfo.getXmlDiscriminatorValue());
                } else {
                    XMLSchemaReference rootSRef = rootDescriptor.getSchemaReference();
                    if (rootSRef != null && rootSRef.getSchemaContext() != null) {
                        QName rootSCtx = rootSRef.getSchemaContextAsQName();
                        rootDescriptor.getInheritancePolicy().addClassNameIndicator(rootDescriptor.getJavaClassName(), rootSCtx);
                    }
                }
            }
            rootDescriptor.getInheritancePolicy().setShouldReadSubclasses(true);
            //Check for attributeGroups
            Map<String, AttributeGroup> childGroups = ((XMLDescriptor)descriptor).getAttributeGroups();
            Map<String, AttributeGroup> parentGroups = ((XMLDescriptor)rootDescriptor).getAttributeGroups();
            if(childGroups != null && !(childGroups.isEmpty()) && parentGroups != null && !(parentGroups.isEmpty())) {
                for(String nextKey:childGroups.keySet()) {
                    AttributeGroup parentGroup = parentGroups.get(nextKey);
                    if(parentGroup != null) {
                        AttributeGroup childGroup = childGroups.get(nextKey);
                        parentGroup.getSubClassGroups().put(descriptor.getJavaClassName(), childGroup);
                    }
                }
            }
        }
    }

    private JavaClass getRootMappedSuperClass(JavaClass javaClass){
        JavaClass rootMappedSuperClass = javaClass;

        JavaClass nextMappedSuperClass = rootMappedSuperClass;
        while(nextMappedSuperClass != null){
            nextMappedSuperClass = CompilerHelper.getNextMappedSuperClass(nextMappedSuperClass, this.typeInfo, helper);
            if(nextMappedSuperClass == null){
                return rootMappedSuperClass;
            }
            rootMappedSuperClass = nextMappedSuperClass;
        }

        return rootMappedSuperClass;
    }

    public void generateMappings() {
        Iterator<String> javaClasses = this.typeInfo.keySet().iterator();
        while (javaClasses.hasNext()) {
            String next = javaClasses.next();
            JavaClass javaClass = helper.getJavaClass(next);
            TypeInfo info = this.typeInfo.get(next);
            if (info.isEnumerationType()) {
                continue;
            }
            NamespaceInfo namespaceInfo = this.packageToPackageInfoMappings.get(javaClass.getPackageName()).getNamespaceInfo();

            Descriptor descriptor = info.getDescriptor();
            if (descriptor != null) {
                generateMappings(info, descriptor, javaClass, namespaceInfo);
                // set primary key fields (if necessary)
                CoreMapping mapping;
                // handle XmlID
                if (info.isIDSet()) {
                    mapping = descriptor.getMappingForAttributeName(info.getIDProperty().getPropertyName());
                    if (mapping != null) {
                        descriptor.addPrimaryKeyField(mapping.getField());
                    }
                }
                // handle XmlKey
                if (info.hasXmlKeyProperties()) {
                    for (Property keyProp : info.getXmlKeyProperties()) {
                        mapping = descriptor.getMappingForAttributeName(keyProp.getPropertyName());
                        if (mapping != null) {
                            descriptor.addPrimaryKeyField(mapping.getField());
                        }
                    }
                }
            }
            info.postInitialize();
            if (descriptor != null) {
                logMappingGeneration(descriptor);
            }
        }
    }

    /**
     * Generate mappings for a given TypeInfo.
     *
     * @param info
     * @param descriptor
     * @param namespaceInfo
     */
    public void generateMappings(TypeInfo info, Descriptor descriptor, JavaClass descriptorJavaClass, NamespaceInfo namespaceInfo) {
        if(info.isAnonymousComplexType()) {
            //may need to generate inherited mappings
            generateInheritedMappingsForAnonymousType(info, descriptor, descriptorJavaClass, namespaceInfo);
        }
        List<Property> propertiesInOrder = info.getNonTransientPropertiesInPropOrder();
        for (int i = 0; i < propertiesInOrder.size(); i++) {
            Property next = propertiesInOrder.get(i);
            if (next != null && (!next.isTransient() || (next.isTransient() && next.isXmlLocation()))) {
                Mapping mapping = generateMapping(next, descriptor, descriptorJavaClass, namespaceInfo);
                if (next.isVirtual()) {
                    VirtualAttributeAccessor accessor = new VirtualAttributeAccessor();
                    accessor.setAttributeName(mapping.getAttributeName());

                    String getMethod = info.getXmlVirtualAccessMethods().getGetMethod();
                    String setMethod = info.getXmlVirtualAccessMethods().getSetMethod();

                    // Check to see if get/set were overridden in the mapping
                    if (mapping.getAttributeAccessor().isMethodAttributeAccessor()) {
                        getMethod = ((MethodAttributeAccessor) mapping.getAttributeAccessor()).getGetMethodName();
                        setMethod = ((MethodAttributeAccessor) mapping.getAttributeAccessor()).getSetMethodName();
                        accessor.setValueType(mapping.getAttributeClassification());
                    }

                    accessor.setGetMethodName(getMethod);
                    accessor.setSetMethodName(setMethod);

                    if (mapping.getAttributeAccessor() instanceof JAXBArrayAttributeAccessor) {
                        JAXBArrayAttributeAccessor jaa = (JAXBArrayAttributeAccessor) mapping.getAttributeAccessor();
                        jaa.setNestedAccessor(accessor);
                    } else {
                        mapping.setAttributeAccessor(accessor);
                    }
                }
                if (mapping != null) {
                    descriptor.addMapping((CoreMapping)mapping);
                }
                // set user-defined properties if necessary
                if (next.isSetUserProperties()) {
                    mapping.setProperties(next.getUserProperties());
                }
                //get package info
                AccessorFactoryWrapper accessorFactory = info.getXmlAccessorFactory();
                if(accessorFactory == null) {
                    accessorFactory = info.getPackageLevelXmlAccessorFactory();
                }
                if(accessorFactory != null) {
                    try {
                        Object accessor = CompilerHelper.createAccessorFor(descriptorJavaClass, next, helper, accessorFactory);

                        if(accessor != null) {
                            CustomAccessorAttributeAccessor attributeAccessor = new CustomAccessorAttributeAccessor(accessor);
                            mapping.setAttributeAccessor(attributeAccessor);
                        }
                    } catch(Exception ex) {}
                }
            }
            next.postInitialize();
        }
    }

    private void generateInheritedMappingsForAnonymousType(TypeInfo info, Descriptor descriptor, JavaClass descriptorJavaClass, NamespaceInfo namespaceInfo) {
        List<TypeInfo> mappedParents = new ArrayList<>();
        JavaClass next = CompilerHelper.getNextMappedSuperClass(descriptorJavaClass, typeInfo, helper);
        while(next != null) {
            TypeInfo nextInfo = this.typeInfo.get(next.getName());
            mappedParents.add(0, nextInfo);
            next = CompilerHelper.getNextMappedSuperClass(helper.getJavaClass(nextInfo.getJavaClassName()), typeInfo, helper);
        }
        for(TypeInfo nextInfo:mappedParents) {
            List<Property> propertiesInOrder = nextInfo.getNonTransientPropertiesInPropOrder();
            for (int i = 0; i < propertiesInOrder.size(); i++) {
                Property nextProp = propertiesInOrder.get(i);
                if (nextProp != null){
                    Mapping mapping = generateMapping(nextProp, descriptor, descriptorJavaClass, namespaceInfo);
                    descriptor.addMapping((CoreMapping)mapping);
                    // set user-defined properties if necessary
                    if (nextProp.isSetUserProperties()) {
                        mapping.setProperties(nextProp.getUserProperties());
                    }
                }
            }
        }

    }

    /**
     * Create an XMLCollectionReferenceMapping and add it to the descriptor.
     *
     * @param property
     * @param descriptor
     * @param namespaceInfo
     * @param referenceClass
     */
    public CollectionReferenceMapping generateXMLCollectionReferenceMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass referenceClass) {
        CollectionReferenceMapping<AbstractSession, AttributeAccessor, ContainerPolicy, ClassDescriptor, DatabaseField, UnmarshalRecord, XMLField, XMLRecord> mapping = new XMLCollectionReferenceMapping();
        initializeXMLMapping((XMLMapping)mapping, property);

        initializeXMLContainerMapping(mapping, property.getType().isArray());
        mapping.setUsesSingleNode(property.isXmlList() || (property.isAttribute() && (property.getXmlPath() == null || !property.getXmlPath().contains("/"))));

        String referenceClassName = referenceClass.getQualifiedName();
        JavaClass collectionType = property.getType();

        if (collectionType.isArray()){
            JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader());
            JavaClass componentType = collectionType.getComponentType();
            if(componentType.isArray()) {
                Class adaptedClass = classToGeneratedClasses.get(componentType.getName());
                referenceClassName = adaptedClass.getName();
                accessor.setAdaptedClassName(referenceClassName);
                JavaClass baseComponentType = getBaseComponentType(componentType);
                if (baseComponentType.isPrimitive()){
                    Class<Object> primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName());
                    accessor.setComponentClass(primitiveClass);
                } else {
                    accessor.setComponentClassName(baseComponentType.getQualifiedName());
                }
            } else {
                accessor.setComponentClassName(componentType.getQualifiedName());
            }
            mapping.setAttributeAccessor(accessor);
        }
        collectionType = containerClassImpl(collectionType);
        mapping.useCollectionClassName(collectionType.getRawName());
        mapping.setReferenceClassName(referenceClassName);

        // here we need to setup source/target key field associations
        if (property.isSetXmlJoinNodes()) {
            for (XmlJoinNode xmlJoinNode: property.getXmlJoinNodes().getXmlJoinNode()) {
               validateJoinNode(descriptor.getJavaClassName(), property, xmlJoinNode.getReferencedXmlPath(), referenceClass);
               mapping.addSourceToTargetKeyFieldAssociation(xmlJoinNode.getXmlPath(), xmlJoinNode.getReferencedXmlPath());
            }
        } else {
            // here we need to setup source/target key field associations
            TypeInfo referenceType = typeInfo.get(referenceClass.getQualifiedName());
            String tgtXPath = null;
            if (null != referenceType && referenceType.isIDSet()) {
                Property prop = referenceType.getIDProperty();
                tgtXPath = getXPathForField(prop, namespaceInfo, !prop.isAttribute(), false).getXPath();
            }
            // if the XPath is set (via xml-path) use it
            Field srcXPath;
            if (property.getXmlPath() != null) {
                srcXPath = new XMLField(property.getXmlPath());
            } else {
                srcXPath = getXPathForField(property, namespaceInfo, true, false);
            }
            mapping.addSourceToTargetKeyFieldAssociation(srcXPath.getXPath(), tgtXPath);
        }
        if (property.getInverseReferencePropertyName() != null) {
            mapping.getInverseReferenceMapping().setAttributeName(property.getInverseReferencePropertyName());
            JavaClass backPointerPropertyType = null;
            if (property.getInverseReferencePropertyGetMethodName() != null && property.getInverseReferencePropertySetMethodName() != null && !property.getInverseReferencePropertyGetMethodName().equals("") && !property.getInverseReferencePropertySetMethodName().equals("")) {
                mapping.getInverseReferenceMapping().setGetMethodName(property.getInverseReferencePropertySetMethodName());
                mapping.getInverseReferenceMapping().setSetMethodName(property.getInverseReferencePropertySetMethodName());
                JavaMethod getMethod = referenceClass.getDeclaredMethod(mapping.getInverseReferenceMapping().getGetMethodName(), new JavaClass[]{});
                if (getMethod != null) {
                    backPointerPropertyType = getMethod.getReturnType();
                }
            } else {
                JavaField backpointerField = referenceClass.getDeclaredField(property.getInverseReferencePropertyName());
                if (backpointerField != null) {
                    backPointerPropertyType = backpointerField.getResolvedType();
                }
            }
            if (helper.isCollectionType(backPointerPropertyType)) {
                mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
            }
        }
        return mapping;
    }
    /**
     * Create an XMLObjectReferenceMapping and add it to the descriptor.
     *
     * @param property
     * @param descriptor
     * @param namespaceInfo
     * @param referenceClass
     */
    public ObjectReferenceMapping generateXMLObjectReferenceMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass referenceClass) {
        ObjectReferenceMapping<AbstractSession, AttributeAccessor, ContainerPolicy, ClassDescriptor, DatabaseField, UnmarshalRecord, XMLField, XMLRecord> mapping = new XMLObjectReferenceMapping();
        initializeXMLMapping((XMLMapping)mapping, property);
        mapping.setReferenceClassName(referenceClass.getQualifiedName());

        // here we need to setup source/target key field associations
        if (property.isSetXmlJoinNodes()) {
            for (XmlJoinNode xmlJoinNode: property.getXmlJoinNodes().getXmlJoinNode()) {
                validateJoinNode(descriptor.getJavaClassName(), property, xmlJoinNode.getReferencedXmlPath(), referenceClass);
                mapping.addSourceToTargetKeyFieldAssociation(xmlJoinNode.getXmlPath(), xmlJoinNode.getReferencedXmlPath());
            }
        } else {
            String tgtXPath = null;
            TypeInfo referenceType = typeInfo.get(referenceClass.getQualifiedName());
            if (null != referenceType && referenceType.isIDSet()) {
                Property prop = referenceType.getIDProperty();
                tgtXPath = getXPathForField(prop, namespaceInfo, !prop.isAttribute(), false).getXPath();
            }
            // if the XPath is set (via xml-path) use it, otherwise figure it out
            Field srcXPath;
            if (property.getXmlPath() != null) {
                srcXPath = new XMLField(property.getXmlPath());
            } else {
                srcXPath = getXPathForField(property, namespaceInfo, true, false);
            }
            mapping.addSourceToTargetKeyFieldAssociation(srcXPath.getXPath(), tgtXPath);
        }
        if (property.getInverseReferencePropertyName() != null) {
            mapping.getInverseReferenceMapping().setAttributeName(property.getInverseReferencePropertyName());
            JavaClass backPointerPropertyType = null;
            if (property.getInverseReferencePropertyGetMethodName() != null && property.getInverseReferencePropertySetMethodName() != null && !property.getInverseReferencePropertyGetMethodName().equals("") && !property.getInverseReferencePropertySetMethodName().equals("")) {
                mapping.getInverseReferenceMapping().setGetMethodName(property.getInverseReferencePropertySetMethodName());
                mapping.getInverseReferenceMapping().setSetMethodName(property.getInverseReferencePropertySetMethodName());
                JavaMethod getMethod = referenceClass.getDeclaredMethod(mapping.getInverseReferenceMapping().getGetMethodName(), new JavaClass[]{});
                if (getMethod != null) {
                    backPointerPropertyType = getMethod.getReturnType();
                }
            } else {
                JavaField backpointerField = referenceClass.getDeclaredField(property.getInverseReferencePropertyName());
                if (backpointerField != null) {
                    backPointerPropertyType = backpointerField.getResolvedType();
                }
            }
            if (helper.isCollectionType(backPointerPropertyType)) {
                mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
            }
        }
        return mapping;
    }

    private void validateJoinNode(String className, Property property, String referencedXmlPath, JavaClass referenceClass) {
        TypeInfo targetInfo = this.typeInfo.get(referenceClass.getQualifiedName());
        NamespaceInfo namespaceInfo = this.packageToPackageInfoMappings.get(referenceClass.getPackageName()).getNamespaceInfo();
        Property idProp = targetInfo.getIDProperty();
        if(idProp != null) {
            String idXpath = idProp.getXmlPath();
            if(idXpath == null) {
                idXpath = this.getXPathForField(idProp, namespaceInfo, !idProp.isAttribute(), false).getXPath();
            }
            if (referencedXmlPath.equals(idXpath)) {
                return;
            }
        }
        boolean matched = false;
        if (targetInfo.getXmlKeyProperties() != null) {
            for (Property xmlkeyProperty : targetInfo.getXmlKeyProperties()) {
                String keyXpath = xmlkeyProperty.getXmlPath();
                if(keyXpath == null) {
                    keyXpath = this.getXPathForField(xmlkeyProperty, namespaceInfo, !xmlkeyProperty.isAttribute(), false).getXPath();
                }
                if (referencedXmlPath.equals(keyXpath)) {
                    matched = true;
                    break;
                }
            }
        }
        if (!matched) {
            throw JAXBException.invalidReferencedXmlPathOnJoin(className, property.getPropertyName(), referenceClass.getQualifiedName(), referencedXmlPath);
        }
    }


    private String prefixCustomXPath(String unprefixedXPath, Property property, NamespaceInfo nsInfo) {
        StringBuilder newXPath = new StringBuilder(32);
        QName schemaName = property.getSchemaName();
        String namespace = schemaName.getNamespaceURI();

        if (null == namespace || namespace.equals(Constants.EMPTY_STRING)) {
            return unprefixedXPath;
        }

        String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(nsInfo));
        if (null == prefix) {
            return unprefixedXPath;
        }

        StringTokenizer st = new StringTokenizer(unprefixedXPath, Constants.XPATH_SEPARATOR);
        while (st.hasMoreTokens()) {
            String nextToken = st.nextToken();

            if (st.hasMoreTokens()) {
                if (nextToken.lastIndexOf(Constants.COLON) != -1) {
                    // Token already has a user-supplied prefix
                    newXPath.append(nextToken);
                } else {
                    newXPath.append(prefix).append(Constants.COLON).append(nextToken);
                }
                newXPath.append(Constants.XPATH_SEPARATOR);
            } else {
                // Last token is text()
                newXPath.append(nextToken);
            }

        }
        return newXPath.toString();
    }

    public Field getXPathForField(Property property, NamespaceInfo namespaceInfo, boolean isTextMapping, boolean isAny) {
        Field xmlField = null;
        String xPath = property.getXmlPath();
        if (null != xPath) {
            String newXPath = prefixCustomXPath(xPath, property, namespaceInfo);
            xmlField = new XMLField(newXPath);
        } else {
            StringBuilder xPathBuilder = new StringBuilder();
            if (property.isSetXmlElementWrapper()) {
                XmlElementWrapper wrapper = property.getXmlElementWrapper();
                String namespace = wrapper.getNamespace();
                if (namespace.equals(XMLProcessor.DEFAULT)) {
                    if (namespaceInfo.isElementFormQualified()) {
                        namespace = namespaceInfo.getNamespace();
                    } else {
                        namespace = "";
                    }
                }

                if (namespace.equals("")) {
                    xPathBuilder.append(wrapper.getName()).append("/");
                } else {
            String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(namespaceInfo));
            xPathBuilder.append(getQualifiedString(prefix, wrapper.getName() + "/"));
                }

                if (isAny || property.isMap()) {
                    xmlField = new XMLField(xPathBuilder.toString());
                    return xmlField;
                }

            }
            if (property.isAttribute()) {
                if (property.isSetXmlPath()) {
                    xPathBuilder.append(property.getXmlPath());
                } else {
                    QName name = property.getSchemaName();
                    String namespace = name.getNamespaceURI();
                    if (namespace.equals("")) {
                        xPathBuilder.append(ATT).append(name.getLocalPart());
                    } else {
                        String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(namespaceInfo));
                        xPathBuilder.append(ATT).append(getQualifiedString(prefix, name.getLocalPart()));
                    }
                }
                xmlField = new XMLField(xPathBuilder.toString());
            } else if (property.isXmlValue()) {
        if(isBinaryData(property.getActualType())){
            xmlField = new XMLField(".");
                }else{
                    xmlField = new XMLField("text()");
        }
            } else {
                QName elementName = property.getSchemaName();
                xmlField = getXPathForElement(xPathBuilder.toString(), elementName, namespaceInfo, isTextMapping);
            }
        }

        QName schemaType = userDefinedSchemaTypes.get(property.getActualType().getQualifiedName());
        if (property.getSchemaType() != null) {
            schemaType = property.getSchemaType();
        }
        if (schemaType == null) {
            String propertyActualTypeRawName = property.getActualType().getRawName();
            if(QName.class.getCanonicalName().equals(propertyActualTypeRawName)) {
                 schemaType = (QName) helper.getXMLToJavaTypeMap().get(propertyActualTypeRawName);
            }
        }
        if(schemaType !=null && !schemaType.equals (Constants.NORMALIZEDSTRING_QNAME)){
            xmlField.setSchemaType(schemaType);
        }

        return xmlField;
    }

    public Field getXPathForElement(String path, QName elementName, NamespaceInfo namespaceInfo, boolean isText) {
        String namespace = "";
        if (!elementName.getNamespaceURI().equals(Constants.EMPTY_STRING)) {
            namespace = elementName.getNamespaceURI();
        }
        if (namespace.equals(Constants.EMPTY_STRING)) {
            path += elementName.getLocalPart();
            if (isText) {
                path += TXT;
            }
        } else {
            String prefix = getPrefixForNamespace(namespace, getNamespaceResolverForDescriptor(namespaceInfo));
            path += getQualifiedString(prefix, elementName.getLocalPart());
            if (isText) {
                path += TXT;
            }
        }
        return new XMLField(path);
    }

    public Property getXmlValueFieldForSimpleContent(ArrayList<Property> properties) {
        boolean foundValue = false;
        boolean foundNonAttribute = false;
        Property valueField = null;

        for (Property prop : properties) {
            if (helper.isAnnotationPresent(prop.getElement(), XmlValue.class)) {
                foundValue = true;
                valueField = prop;
            } else if (!helper.isAnnotationPresent(prop.getElement(), XmlAttribute.class) && !helper.isAnnotationPresent(prop.getElement(), XmlTransient.class) && !prop.isAnyAttribute()) {
                foundNonAttribute = true;
            }
        }
        if (foundValue && !foundNonAttribute) {
            return valueField;
        }
        return null;
    }

    public String getSchemaTypeNameForClassName(String className) {
        String typeName = Introspector.decapitalize(className.substring(className.lastIndexOf('.') + 1));
        return typeName;
    }

    public void processGlobalElements(CoreProject project) {
        //Find any global elements for classes we've generated descriptors for, and add them as possible
        //root elements.
        if(this.globalElements == null && this.localElements == null) {
            return;
        }
        List<ElementDeclaration> elements = new ArrayList<>();
        elements.addAll(this.localElements);
        elements.addAll(this.globalElements.values());
        for(ElementDeclaration nextElement:elements) {
            QName next = nextElement.getElementName();
            String nextClassName = nextElement.getJavaTypeName();
            TypeInfo type = this.typeInfo.get(nextClassName);

            if(helper.isBuiltInJavaType(nextElement.getJavaType()) || (type !=null && type.isEnumerationType())){

                //generate a class/descriptor for this element
                String attributeTypeName = nextClassName;
                if(nextElement.getJavaType().isPrimitive()) {
                    attributeTypeName = helper.getClassForJavaClass(nextElement.getJavaType()).getName();
                }
                if (nextElement.getAdaptedJavaTypeName() != null) {
                    attributeTypeName = nextElement.getAdaptedJavaTypeName();
                }

                if(next == null){
                    if(isBinaryData(nextElement.getJavaType())){
                        Class generatedClass = addByteArrayWrapperAndDescriptor(type, nextElement.getJavaType().getRawName(), nextElement,nextClassName, attributeTypeName);
                         this.qNamesToGeneratedClasses.put(next, generatedClass);
                         if(nextElement.getTypeMappingInfo() != null) {
                             typeMappingInfoToGeneratedClasses.put(nextElement.getTypeMappingInfo(), generatedClass);
                         }
                         try{
                             Class<Object> declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader());
                             this.qNamesToDeclaredClasses.put(next, declaredClass);
                         }catch(Exception e){
                         }
                    }
                    if(nextElement.getJavaType().isEnum()) {
                        if(!(helper.getClassLoader() instanceof DynamicClassLoader)) {
                            //  Only generate enum wrappers in non-dynamic case.
                            Class generatedClass = addEnumerationWrapperAndDescriptor(type, nextElement.getJavaType().getRawName(), nextElement, nextClassName, attributeTypeName);
                            this.qNamesToGeneratedClasses.put(next, generatedClass);
                            if(nextElement.getTypeMappingInfo() != null) {
                                typeMappingInfoToGeneratedClasses.put(nextElement.getTypeMappingInfo(), generatedClass);
                            }
                            try{
                                Class<Object> declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader());
                                this.qNamesToDeclaredClasses.put(next, declaredClass);
                            }catch(Exception ex) {

                            }
                        }

                    }
                    continue;
                }
                Class generatedClass = generateWrapperClassAndDescriptor(type, next, nextElement, nextClassName, attributeTypeName);

                this.qNamesToGeneratedClasses.put(next, generatedClass);
                if(type != null && type.isEnumerationType() && nextElement.isXmlRootElement()) {
                    this.classToGeneratedClasses.put(type.getJavaClassName(), generatedClass);
                }
                try{
                    Class<Object> declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader());
                    this.qNamesToDeclaredClasses.put(next, declaredClass);
                }catch(Exception e){

                }
            }else if(type != null && !type.isTransient()){
                if(next.getNamespaceURI() == null || next.getNamespaceURI().equals("")) {
                    type.getDescriptor().addRootElement(next.getLocalPart());
                } else {
                    Descriptor descriptor = type.getDescriptor();
                    String uri = next.getNamespaceURI();
                    String prefix = getPrefixForNamespace(uri, descriptor.getNamespaceResolver());
                    descriptor.addRootElement(getQualifiedString(prefix, next.getLocalPart()));
                }
            }
        }
    }

    private Class addByteArrayWrapperAndDescriptor(TypeInfo type , String javaClassName,  ElementDeclaration nextElement, String nextClassName, String attributeTypeName){
        Class generatedClass = classToGeneratedClasses.get(javaClassName);
        if(generatedClass == null){
            generatedClass = generateWrapperClassAndDescriptor(type, null, nextElement, nextClassName, attributeTypeName);
            classToGeneratedClasses.put(javaClassName, generatedClass);
        }
        return generatedClass;
    }

    private Class addEnumerationWrapperAndDescriptor(TypeInfo type, String javaClassName, ElementDeclaration nextElement, String nextClassName, String attributeTypeName) {
        Class generatedClass = classToGeneratedClasses.get(javaClassName);
        if(generatedClass == null){
            generatedClass = generateWrapperClassAndDescriptor(type, nextElement.getElementName(), nextElement, nextClassName, attributeTypeName);
            classToGeneratedClasses.put(javaClassName, generatedClass);
        }
        return generatedClass;
    }

     private Class generateWrapperClassAndDescriptor(TypeInfo type, QName next, ElementDeclaration nextElement, String nextClassName, String attributeTypeName){
        String namespaceUri = null;
          if(next!= null){
              //generate a class/descriptor for this element
              namespaceUri = next.getNamespaceURI();
              if (namespaceUri == null || namespaceUri.equals(XMLProcessor.DEFAULT)) {
                  namespaceUri = "";
              }
          }

          TypeMappingInfo tmi = nextElement.getTypeMappingInfo();
          Class generatedClass = null;

        JaxbClassLoader loader = getJaxbClassLoader();

          if(tmi != null){
            generatedClass = CompilerHelper.getExisitingGeneratedClass(tmi, typeMappingInfoToGeneratedClasses, typeMappingInfoToAdapterClasses, helper.getClassLoader());
            if(generatedClass == null){
                generatedClass = this.generateWrapperClass(loader.nextAvailableGeneratedClassName(), attributeTypeName, nextElement.isList(), next);
            }

            typeMappingInfoToGeneratedClasses.put(tmi, generatedClass);
          }else{
              generatedClass = this.generateWrapperClass(loader.nextAvailableGeneratedClassName(), attributeTypeName, nextElement.isList(), next);
          }

          this.qNamesToGeneratedClasses.put(next, generatedClass);
          try{
              Class<Object> declaredClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader());
              this.qNamesToDeclaredClasses.put(next, declaredClass);
          }catch(Exception e){

          }

          Descriptor desc = (Descriptor)project.getDescriptor(generatedClass);

          if(desc == null){
              desc = new XMLDescriptor();
              desc.setJavaClass(generatedClass);


              if(nextElement.isList()){
                  DirectCollectionMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, XMLUnmarshaller, XMLRecord> mapping = new XMLCompositeDirectCollectionMapping();
                  mapping.setAttributeName("value");
                  mapping.setXPath("text()");
                  mapping.setUsesSingleNode(true);
                  mapping.setReuseContainer(true);

                  if(type != null && type.isEnumerationType()){
                      mapping.setValueConverter(buildJAXBEnumTypeConverter(mapping, (EnumTypeInfo)type));
                  }else{
                      try{
                          Class<Object> fieldElementClass = PrivilegedAccessHelper.getClassForName(nextClassName, false, helper.getClassLoader());
                          mapping.setFieldElementClass(fieldElementClass);
                      }catch(ClassNotFoundException e){
                      }
                  }

                  if(nextClassName.equals("[B") || nextClassName.equals("[Ljava.lang.Byte;")) {
                     ((Field)mapping.getField()).setSchemaType(Constants.BASE_64_BINARY_QNAME);
                  }
                  else if(nextClassName.equals("javax.xml.namespace.QName")){
                      ((Field)mapping.getField()).setSchemaType(Constants.QNAME_QNAME);
                  }
                  desc.addMapping((CoreMapping)mapping);
              } else{
                  if(nextElement.getJavaTypeName().equals(OBJECT_CLASS_NAME)){
                      CompositeObjectMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, UnmarshalKeepAsElementPolicy, XMLUnmarshaller, XMLRecord> mapping = new XMLCompositeObjectMapping();
                      mapping.setAttributeName("value");
                      mapping.setSetMethodName("setValue");
                      mapping.setGetMethodName("getValue");
                      mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT);
                      mapping.setXPath(".");
                        setTypedTextField((Field)mapping.getField());

                      desc.addMapping((CoreMapping)mapping);
                  }else if(isBinaryData(nextElement.getJavaType())){
                        BinaryDataMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, MimeTypePolicy, Session, XMLUnmarshaller, XMLRecord> mapping = new XMLBinaryDataMapping();
                        mapping.setAttributeName("value");
                        mapping.setXPath(".");
                      ((Field)mapping.getField()).setSchemaType(Constants.BASE_64_BINARY_QNAME);
                      mapping.setSetMethodName("setValue");
                      mapping.setGetMethodName("getValue");
                      mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
                      mapping.getNullPolicy().setNullRepresentedByEmptyNode(false);

                      Class attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(attributeTypeName, helper.getClassLoader());
                      mapping.setAttributeClassification(attributeClassification);

                        mapping.setShouldInlineBinaryData(false);
                        //if(nextElement.getTypeMappingInfo() != null) {
                            mapping.setSwaRef(nextElement.isXmlAttachmentRef());
                            mapping.setMimeType(nextElement.getXmlMimeType());
                        //}
                      desc.addMapping((CoreMapping)mapping);

                  }else{
                      DirectMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, XMLUnmarshaller, XMLRecord> mapping = new XMLDirectMapping();
                      mapping.setNullValueMarshalled(true);
                      mapping.setAttributeName("value");
                      mapping.setXPath("text()");
                      mapping.setSetMethodName("setValue");
                      mapping.setGetMethodName("getValue");
                      if(nextElement.getDefaultValue() != null) {
                          mapping.setNullValue(nextElement.getDefaultValue());
                          mapping.getNullPolicy().setNullRepresentedByXsiNil(true);
                      }


                      if(helper.isBuiltInJavaType(nextElement.getJavaType())){
                          Class attributeClassification = null;
                          if(nextElement.getJavaType().isPrimitive()) {
                              attributeClassification = XMLConversionManager.getDefaultManager().convertClassNameToClass(attributeTypeName);
                          } else {
                              attributeClassification = org.eclipse.persistence.internal.helper.Helper.getClassFromClasseName(attributeTypeName, helper.getClassLoader());
                          }
                          mapping.setAttributeClassification(attributeClassification);
                      }

                      IsSetNullPolicy nullPolicy = new IsSetNullPolicy("isSetValue", false, true, XMLNullRepresentationType.ABSENT_NODE);
                      //nullPolicy.setNullRepresentedByEmptyNode(true);
                      mapping.setNullPolicy(nullPolicy);

                      if(type != null && type.isEnumerationType()){
                          mapping.setConverter(buildJAXBEnumTypeConverter(mapping, (EnumTypeInfo)type));
                      }
                      if(nextClassName.equals("[B") || nextClassName.equals("[Ljava.lang.Byte;")) {
                          ((Field)mapping.getField()).setSchemaType(Constants.BASE_64_BINARY_QNAME);
                      }
                      else if(nextClassName.equals("javax.xml.namespace.QName")){
                          ((Field)mapping.getField()).setSchemaType(Constants.QNAME_QNAME);
                      }

                      if (nextElement.getJavaTypeAdapterClass() != null) {
                          mapping.setConverter(new XMLJavaTypeConverter(nextElement.getJavaTypeAdapterClass()));
                      }

                      desc.addMapping((CoreMapping)mapping);
                  }
              }
              if(next != null){
                  NamespaceInfo info = getNamespaceInfoForURI(namespaceUri);

                  if(info != null) {
                      NamespaceResolver resolver = getNamespaceResolverForDescriptor(info);

                      String prefix = null;
                      if(namespaceUri != Constants.EMPTY_STRING){
                          prefix = resolver.resolveNamespaceURI(namespaceUri);
                          if(prefix == null){
                              prefix = getPrefixForNamespace(namespaceUri, resolver);
                          }
                      }
                      desc.setNamespaceResolver(resolver);
                      if(nextElement.isXmlRootElement()) {
                          desc.setDefaultRootElement(getQualifiedString(prefix, next.getLocalPart()));
                      } else {
                          desc.setDefaultRootElement("");
                          desc.addRootElement(getQualifiedString(prefix, next.getLocalPart()));
                          desc.setResultAlwaysXMLRoot(true);
                      }
                  } else {
                      if(namespaceUri.equals("")) {
                          desc.setDefaultRootElement(next.getLocalPart());
                      } else {
                          NamespaceResolver resolver = new org.eclipse.persistence.oxm.NamespaceResolver();
                          String prefix = getPrefixForNamespace(namespaceUri, resolver);

                          desc.setNamespaceResolver(resolver);
                          if(nextElement.isXmlRootElement()) {
                              desc.setDefaultRootElement(getQualifiedString(prefix, next.getLocalPart()));
                          } else {
                              desc.setDefaultRootElement("");
                              desc.addRootElement(getQualifiedString(prefix, next.getLocalPart()));
                              desc.setResultAlwaysXMLRoot(true);
                          }
                      }
                  }
              }
              project.addDescriptor((CoreDescriptor)desc);
          }
          return generatedClass;
    }

    private String getQualifiedString(String prefix, String localPart){
        if(prefix == null){
            return localPart;
        }
        return prefix + Constants.COLON + localPart;
    }

    private NamespaceInfo getNamespaceInfoForURI(String namespaceUri) {
        Iterator<PackageInfo> namespaces = this.packageToPackageInfoMappings.values().iterator();
        while(namespaces.hasNext()) {
            NamespaceInfo next = namespaces.next().getNamespaceInfo();
            if(next.getNamespace().equals(namespaceUri)) {
                return next;
            }
        }
        return null;
    }

    @SuppressWarnings("unused")
    private String getPackageNameForURI(String namespaceUri) {
        for(String next:this.packageToPackageInfoMappings.keySet()) {
            if(packageToPackageInfoMappings.get(next).getNamespace().equals(namespaceUri)) {
                return next;
            }
        }
        return null;
    }

    public Class generateWrapperClass(String className, String attributeType, boolean isList, QName theQName) {
        EclipseLinkASMClassWriter cw = new EclipseLinkASMClassWriter();

        String sig = null;
        cw.visit(Opcodes.ACC_PUBLIC, className.replace(".", "/"), sig, Type.getType(WrappedValue.class).getInternalName(), null);

        String fieldType = null;
        if(isList){
            fieldType ="Ljava/util/List;";
        }else{
            fieldType = attributeType.replace(".", "/");
            if(!(fieldType.startsWith("["))) {
                fieldType = "L" + fieldType + ";";
            }
        }

            if(theQName == null){
                theQName = RESERVED_QNAME;
            }

            MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);

            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
            mv.visitInsn(Opcodes.DUP);
            mv.visitLdcInsn(theQName.getNamespaceURI());
            mv.visitLdcInsn(theQName.getLocalPart());
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName", "<init>", "(Ljava/lang/String;Ljava/lang/String;)V", false);
            mv.visitLdcInsn(Type.getType(fieldType));
            mv.visitInsn(Opcodes.ACONST_NULL);

            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "org/eclipse/persistence/internal/jaxb/WrappedValue", "<init>", "(Ljavax/xml/namespace/QName;Ljava/lang/Class;Ljava/lang/Object;)V", false);
            mv.visitInsn(Opcodes.RETURN);
            mv.visitMaxs(5, 1);
            mv.visitEnd();


        cw.visitEnd();

        byte[] classBytes = cw.toByteArray();
        //byte[] classBytes = new byte[]{};

        Module moxyModule = MappingsGenerator.class.getModule();
        if (moxyModule.isNamed() && !moxyModule.isExported(WrappedValue.class.getPackageName(), getJaxbClassLoader().getUnnamedModule())) {
            // our generated classes live in unnamed module, therefore we need to export our private class
            // to the unnamed module as we don't want to export internal package from eclipselink.jar
            moxyModule.addExports(WrappedValue.class.getPackageName(), getJaxbClassLoader().getUnnamedModule());
        }
        Class generatedClass = getJaxbClassLoader().generateClass(className, classBytes);
        return generatedClass;
    }

    public Map<QName, Class> getQNamesToGeneratedClasses() {
        return qNamesToGeneratedClasses;
    }

    public Map<String, Class> getClassToGeneratedClasses() {
        return classToGeneratedClasses;
    }
    public Map<QName, Class> getQNamesToDeclaredClasses() {
        return qNamesToDeclaredClasses;
    }

    private Map<MapEntryGeneratedKey, Class> getGeneratedMapEntryClasses() {
        if(generatedMapEntryClasses == null){
            generatedMapEntryClasses = new HashMap<>();
        }
        return generatedMapEntryClasses;
    }

    // Made static final for performance reasons.
    private static final class MapEntryGeneratedKey {
    @SuppressWarnings("unused")
        String keyClassName;
        @SuppressWarnings("unused")
        String valueClassName;

        public MapEntryGeneratedKey(String keyClass, String valueClass){
            keyClassName = keyClass;
            valueClassName = valueClass;
        }
    }

    private AbstractNullPolicy getWrapperNullPolicyFromProperty(Property property) {
        NullPolicy nullPolicy = null;

        if (property.isSetXmlElementWrapper()) {
            nullPolicy = new NullPolicy();
            nullPolicy.setNullRepresentedByEmptyNode(false);
            nullPolicy.setSetPerformedForAbsentNode(false);

            if (property.getXmlElementWrapper().isNillable()) {
                nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
                nullPolicy.setNullRepresentedByXsiNil(true);
            } else {
                nullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.ABSENT_NODE);
                nullPolicy.setNullRepresentedByXsiNil(false);
            }
        }

        return nullPolicy;
    }

    /**
     * Convenience method which returns an AbstractNullPolicy built from an XmlAbstractNullPolicy.
     *
     * @param property
     * @param nsr if 'NullRepresentedByXsiNil' is true, this is the resolver
     *            that we will add the schema instance prefix/uri pair to
     * @return
     * @see org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy
     * @see org.eclipse.persistence.jaxb.xmlmodel.XmlAbstractNullPolicy
     */
    private AbstractNullPolicy getNullPolicyFromProperty(Property property, NamespaceResolver nsr) {
        AbstractNullPolicy absNullPolicy = null;
        XmlAbstractNullPolicy xmlAbsNullPolicy = property.getNullPolicy();

        // policy is assumed to be one of XmlNullPolicy or XmlIsSetNullPolicy
        if (xmlAbsNullPolicy instanceof XmlNullPolicy) {
            XmlNullPolicy xmlNullPolicy = (XmlNullPolicy) xmlAbsNullPolicy;
            NullPolicy nullPolicy = new NullPolicy();
            nullPolicy.setSetPerformedForAbsentNode(xmlNullPolicy.isIsSetPerformedForAbsentNode());
            absNullPolicy = nullPolicy;
        } else {
            XmlIsSetNullPolicy xmlIsSetNullPolicy = (XmlIsSetNullPolicy) xmlAbsNullPolicy;
            IsSetNullPolicy isSetNullPolicy = new IsSetNullPolicy();
            isSetNullPolicy.setIsSetMethodName(xmlIsSetNullPolicy.getIsSetMethodName());
            // handle isSetParams
            ArrayList<Object> parameters = new ArrayList<>();
            ArrayList<Class> parameterTypes = new ArrayList<>();
            List<XmlIsSetNullPolicy.IsSetParameter> params = xmlIsSetNullPolicy.getIsSetParameter();
            for (XmlIsSetNullPolicy.IsSetParameter param : params) {
                String valueStr = param.getValue();
                String typeStr = param.getType();
                // create a conversion manager instance with the helper's loader
                XMLConversionManager mgr = new XMLConversionManager();
                mgr.setLoader(helper.getClassLoader());
                // handle parameter type
                Class<Object> typeClass = mgr.convertClassNameToClass(typeStr);
                // handle parameter value
                Object parameterValue = mgr.convertObject(valueStr, typeClass);
                parameters.add(parameterValue);
                parameterTypes.add(typeClass);
            }
            isSetNullPolicy.setIsSetParameters(parameters.toArray());
            isSetNullPolicy.setIsSetParameterTypes(parameterTypes.toArray(new Class[parameterTypes.size()]));
            absNullPolicy = isSetNullPolicy;
        }
        // handle commmon settings
        absNullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.valueOf(xmlAbsNullPolicy.getNullRepresentationForXml().name()));
        absNullPolicy.setNullRepresentedByEmptyNode(xmlAbsNullPolicy.isEmptyNodeRepresentsNull());
        boolean xsiRepresentsNull = xmlAbsNullPolicy.isXsiNilRepresentsNull();
        if (xsiRepresentsNull) {
            absNullPolicy.setNullRepresentedByXsiNil(true);
        }

        return absNullPolicy;
    }

    /**
     * Return the base component type for a class.  For example, the base
     * component type for Integer, Integer[], and Integer[][] are all Integer.
     */
    private JavaClass getBaseComponentType(JavaClass javaClass) {
        JavaClass componentType = javaClass.getComponentType();
        if(null == componentType) {
            return javaClass;
        }
        if(!componentType.isArray()) {
            return componentType;
        }
        return getBaseComponentType(componentType);
    }

    public JaxbClassLoader getJaxbClassLoader() {
        if (helper.getClassLoader() instanceof DynamicClassLoader) {
            return (JaxbClassLoader) helper.getClassLoader().getParent();
        } else {
            return (JaxbClassLoader) helper.getClassLoader();
        }
    }

    private boolean isBinaryData(JavaClass type){
        return areEquals(type, CoreClassConstants.APBYTE) ||areEquals(type, "jakarta.activation.DataHandler") || areEquals(type, "java.awt.Image") || areEquals(type, "javax.xml.transform.Source") || areEquals(type, "jakarta.mail.internet.MimeMultipart");
    }

    // Made static final for performance reasons.
    /**
     * <p>An InstantiationPolicy that does not construct any objects (and therefore
     * will not throw validation errors caused by a lack of a no-arg constructor).</p>
     *
     * <p>This is used by @XmlLocation, where we want to have a real mapping created
     * (so we can later set its value through the mapping), but where we will never
     * instantiate a Locator from XML (the Locator will be built internally during parsing).</p>
     *
     * @see org.eclipse.persistence.internal.descriptors.InstantiationPolicy
     * @see org.xml.sax.Locator
     */
    private static final class NullInstantiationPolicy extends InstantiationPolicy {

        /**
         * Returns a new instance of this InstantiationPolicy's Descriptor's class.
         *
         * In this case, do nothing and return null.
         */
        @Override
        public Object buildNewInstance() throws DescriptorException {
            return null;
        }

    }

    private void initializeXMLContainerMapping(XMLContainerMapping xmlContainerMapping, boolean isArray) {
        xmlContainerMapping.setReuseContainer(!isArray);
        xmlContainerMapping.setDefaultEmptyContainer(false);
    }

    private void initializeXMLMapping(XMLMapping mapping, Property property){
        mapping.setAttributeName(property.getPropertyName());

         // handle read-only set via metadata
        if (property.isSetReadOnly()) {
            mapping.setIsReadOnly(property.isReadOnly());
        }
        // handle write-only set via metadata
        if (property.isSetWriteOnly()) {
            mapping.setIsWriteOnly(property.isWriteOnly());
        }

        if (property.isMethodProperty()) {
            if (property.getGetMethodName() == null) {
                // handle case of set with no get method
                String paramTypeAsString = property.getType().getName();
                mapping.setAttributeAccessor(new JAXBSetMethodAttributeAccessor(paramTypeAsString, helper.getClassLoader()));
                mapping.setIsReadOnly(true);
                mapping.setSetMethodName(property.getSetMethodName());
            } else if (property.getSetMethodName() == null) {
                mapping.setGetMethodName(property.getGetMethodName());
                mapping.setIsWriteOnly(true);
            } else {
                mapping.setSetMethodName(property.getSetMethodName());
                mapping.setGetMethodName(property.getGetMethodName());
            }
        }
    }

    private JavaClass containerClassImpl(JavaClass collectionType) {
        if (areEquals(collectionType, List.class) || areEquals(collectionType, Collection.class) || collectionType.isArray() || helper.isMapType(collectionType) ) {
            return jotArrayList;
        } else if (areEquals(collectionType, Set.class)) {
            return jotHashSet;
        } else if (areEquals(collectionType, Deque.class) || areEquals(collectionType, Queue.class)) {
            return jotLinkedList;
        } else if (areEquals(collectionType, NavigableSet.class) || areEquals(collectionType, SortedSet.class)) {
            return jotTreeSet;
        } else {
            return collectionType;
        }
    }

    private void processDefaultNamespacePreferences(Collection<PackageInfo> packageInfos) {
        if (isDefaultNamespaceAllowed && globalNamespaceResolver.getDefaultNamespaceURI() == null) {
            for (PackageInfo packageInfo : packageInfos) {
                NamespaceResolver resolver = packageInfo.getNamespaceInfo().getNamespaceResolver();
                String defaultNS = resolver.getDefaultNamespaceURI();
                if (defaultNS != null) {
                    globalNamespaceResolver.setDefaultNamespaceURI(defaultNS);
                    break;
                }
            }
        }
    }

    private NamespaceResolver getNamespaceResolverForDescriptor(NamespaceInfo info) {
        return info.getNamespaceResolverForDescriptor(globalNamespaceResolver, isDefaultNamespaceAllowed);
    }

    private void logMappingGeneration(Descriptor xmlDescriptor) {
        String i18nmsg = JAXBLocalization.buildMessage("create_mappings", new Object[] { xmlDescriptor.getJavaClassName() });
        AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.MOXY, i18nmsg, new Object[0], false);
        Iterator mappingIterator = xmlDescriptor.getMappings().iterator();
        Mapping xmlMapping;
        while (mappingIterator.hasNext()) {
            xmlMapping = (Mapping) mappingIterator.next();
            AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.MOXY, xmlMapping.toString(), new Object[0], false);
        }
    }
}
