/*
 * 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.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.VirtualAttributeAccessor;
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.queries.ContainerPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
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.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.mappings.FixedMimeTypePolicy;
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.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.schema.XMLSchemaClassPathReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.sessions.Project;

/**
 * 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 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 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 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 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) {
        ChoiceObjectMapping mapping = new XMLChoiceObjectMapping();
        initializeXMLMapping((XMLChoiceObjectMapping)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<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()))) || 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);
                }
                Mapping nestedMapping = (Mapping) 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 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 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) {
        AnyAttributeMapping mapping = new XMLAnyAttributeMapping();
        initializeXMLMapping((XMLAnyAttributeMapping)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 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 primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(componentClassName);
                    accessor.setComponentClass(primitiveClass);
                    directCollectionMapping.setAttributeAccessor(accessor);

                    Class 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 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 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 javaClasses = this.typeInfo.keySet().iterator();
        while (javaClasses.hasNext()) {
            String next = (String)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 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 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 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 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 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 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 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 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 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 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 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 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 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);
        }
    }
}
