/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2021 IBM Corporation. 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
//
//     05/28/2008-1.0M8 Andrei Ilitchev
//        - 224964: Provide support for Proxy Authentication through JPA.
//        Added updateConnectionPolicy method to support EXCLUSIVE_CONNECTION property.
//        Some methods, like setSessionEventListener called from deploy still used predeploy properties,
//        that meant it was impossible to set listener through createEMF property in SE case with an agent - fixed that.
//        Also if creating / closing the same emSetupImpl many times (24 in my case) "java.lang.OutOfMemoryError: PermGen space" resulted:
//        partially fixed partially worked around this - see a big comment in predeploy method.
//     12/23/2008-1.1M5 Michael O'Brien
//        - 253701: add persistenceInitializationHelper field used by undeploy() to clear the JavaSECMPInitializer
//     10/14/2009-2.0      Michael O'Brien
//        - 266912: add Metamodel instance field as part of the JPA 2.0 implementation
//     10/21/2009-2.0 Guy Pelletier
//       - 290567: mappedbyid support incomplete
//     cdelahun - Bug 214534: changes to allow JMSPublishingTransportManager configuration through properties
//     05/14/2010-2.1 Guy Pelletier
//       - 253083: Add support for dynamic persistence using ORM.xml/eclipselink-orm.xml
//     04/01/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 2)
//     06/30/2011-2.3.1 Guy Pelletier
//       - 341940: Add disable/enable allowing native queries
//     09/20/2011-2.3.1 Guy Pelletier
//       - 357476: Change caching default to ISOLATED for multitenant's using a shared EMF.
//     08/01/2012-2.5 Chris Delahunt
//       - 371950: Metadata caching
//     12/24/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     01/08/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     01/11/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     01/16/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     01/24/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     02/04/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     02/19/2013-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support
//     08/11/2014-2.5 Rick Curtis
//       - 440594: Tolerate invalid NamedQuery at EntityManager creation.
//     11/20/2014-2.5 Rick Curtis
//       - 452187: Support multiple ClassLoaders to load properties.
//     01/05/2015 Rick Curtis
//       - 455683: Automatically detect target server
//     01/13/2015 - Rick Curtis
//       - 438871 : Add support for writing statement terminator character(s) when generating ddl to script.
//     02/19/2015 - Rick Curtis
//       - 458877 : Add national character support
//     03/04/2015 - Will Dazey
//       - 460862 : Added support for JTA schema generation without JTA-DS
//     03/23/2015 - Rick Curtis
//       - 462888 : SessionCustomizer instance based configuration
//     08/24/2015 - Dalia Abo Sheasha
//       - 475285 : Create a generic application-id property to generate unique session names
//     09/03/2015 - Will Dazey
//       - 456067 : Added support for defining query timeout units
//     09/28/2015 - Will Dazey
//       - 478331 : Added support for defining local or server as the default locale for obtaining timestamps
//     11/05/2015 - Dalia Abo Sheasha
//       - 480787 : Wrap several privileged method calls with a doPrivileged block
//     12/03/2015-2.6 Dalia Abo Sheasha
//       - 483582: Add the jakarta.persistence.sharedCache.mode property
//     09/29/2016-2.7 Tomas Kraus
//       - 426852: @GeneratedValue(strategy=GenerationType.IDENTITY) support in Oracle 12c
//     09/14/2017-2.6 Will Dazey
//       - 522312: Add the eclipselink.sequencing.start-sequence-at-nextval property
//     10/24/2017-3.0 Tomas Kraus
//       - 526419: Modify EclipseLink to reflect changes in JTA 1.1.
//     01/16/2018-2.7 Joe Grassel
//       - 529907: EntityManagerSetupImpl.addBeanValidationListeners() should fall back on old method for finding helperClass
//     12/06/2018 - Will Dazey
//       - 542491: Add new 'eclipselink.jdbc.force-bind-parameters' property to force enable binding
//     09/02/2019-3.0 Alexandre Jacob
//        - 527415: Fix code when locale is tr, az or lt
package org.eclipse.persistence.internal.jpa;

import static org.eclipse.persistence.config.PersistenceUnitProperties.DDL_GENERATION;
import static org.eclipse.persistence.config.PersistenceUnitProperties.NONE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_CREATE_ACTION;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_CREATE_DATABASE_SCHEMAS;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_CREATE_SCRIPT_SOURCE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_CREATE_SOURCE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_DATABASE_ACTION;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_DROP_ACTION;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_DROP_AND_CREATE_ACTION;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_DROP_SCRIPT_SOURCE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_DROP_SOURCE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_METADATA_SOURCE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_METADATA_THEN_SCRIPT_SOURCE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_NONE_ACTION;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_SCRIPTS_ACTION;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_SCRIPTS_CREATE_TARGET;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_SCRIPTS_DROP_TARGET;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_SCRIPT_SOURCE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_SCRIPT_THEN_METADATA_SOURCE;
import static org.eclipse.persistence.config.PersistenceUnitProperties.SCHEMA_GENERATION_SQL_LOAD_SCRIPT_SOURCE;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.generateDefaultTables;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.getConfigProperty;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.getConfigPropertyAsString;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.getConfigPropertyLogDebug;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.hasConfigProperty;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.mergeMaps;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.translateOldProperties;
import static org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.warnOldProperties;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

import jakarta.persistence.OptimisticLockException;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.ValidationMode;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.CollectionAttribute;
import jakarta.persistence.metamodel.ListAttribute;
import jakarta.persistence.metamodel.ManagedType;
import jakarta.persistence.metamodel.MapAttribute;
import jakarta.persistence.metamodel.Metamodel;
import jakarta.persistence.metamodel.SetAttribute;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.spi.ClassTransformer;
import jakarta.persistence.spi.PersistenceUnitInfo;
import jakarta.persistence.spi.PersistenceUnitTransactionType;

import org.eclipse.persistence.annotations.IdValidation;
import org.eclipse.persistence.config.BatchWriting;
import org.eclipse.persistence.config.CacheCoordinationProtocol;
import org.eclipse.persistence.config.CacheIsolationType;
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.config.ExclusiveConnectionMode;
import org.eclipse.persistence.config.LoggerType;
import org.eclipse.persistence.config.ParserType;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.ProfilerType;
import org.eclipse.persistence.config.PropertiesUtils;
import org.eclipse.persistence.config.RemoteProtocol;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.MultitenantPolicy;
import org.eclipse.persistence.descriptors.SchemaPerMultitenantPolicy;
import org.eclipse.persistence.descriptors.TimestampLockingPolicy;
import org.eclipse.persistence.descriptors.partitioning.PartitioningPolicy;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.eis.EISConnectionSpec;
import org.eclipse.persistence.eis.EISLogin;
import org.eclipse.persistence.eis.EISPlatform;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.EntityManagerSetupException;
import org.eclipse.persistence.exceptions.ExceptionHandler;
import org.eclipse.persistence.exceptions.IntegrityException;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.BatchWritingMechanism;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.databaseaccess.Platform;
import org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy;
import org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy.LockOnChange;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.ConcurrencyManager;
import org.eclipse.persistence.internal.helper.ConcurrencyUtil;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.JPAClassLoaderHolder;
import org.eclipse.persistence.internal.helper.JPAConversionManager;
import org.eclipse.persistence.internal.jpa.deployment.BeanValidationInitializationHelper;
import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.internal.jpa.jdbc.DataSourceImpl;
import org.eclipse.persistence.internal.jpa.metadata.MetadataHelper;
import org.eclipse.persistence.internal.jpa.metadata.MetadataLogger;
import org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor;
import org.eclipse.persistence.internal.jpa.metadata.MetadataProject;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAsmFactory;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;
import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappingsReader;
import org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl;
import org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl;
import org.eclipse.persistence.internal.jpa.metamodel.proxy.AttributeProxyImpl;
import org.eclipse.persistence.internal.jpa.metamodel.proxy.CollectionAttributeProxyImpl;
import org.eclipse.persistence.internal.jpa.metamodel.proxy.ListAttributeProxyImpl;
import org.eclipse.persistence.internal.jpa.metamodel.proxy.MapAttributeProxyImpl;
import org.eclipse.persistence.internal.jpa.metamodel.proxy.SetAttributeProxyImpl;
import org.eclipse.persistence.internal.jpa.metamodel.proxy.SingularAttributeProxyImpl;
import org.eclipse.persistence.internal.jpa.weaving.ClassDetails;
import org.eclipse.persistence.internal.jpa.weaving.PersistenceWeaver;
import org.eclipse.persistence.internal.jpa.weaving.TransformerFactory;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.localization.LoggingLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredField;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredFields;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredMethod;
import org.eclipse.persistence.internal.security.PrivilegedGetValueFromField;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.security.SecurableObjectHolder;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.internal.sessions.PropertiesHandler;
import org.eclipse.persistence.internal.sessions.remote.RemoteConnection;
import org.eclipse.persistence.jpa.metadata.FileBasedProjectCache;
import org.eclipse.persistence.jpa.metadata.MetadataSource;
import org.eclipse.persistence.jpa.metadata.ProjectCache;
import org.eclipse.persistence.jpa.metadata.XMLMetadataSource;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.database.converters.StructConverter;
import org.eclipse.persistence.platform.database.events.DatabaseEventListener;
import org.eclipse.persistence.platform.database.partitioning.DataPartitioningCallback;
import org.eclipse.persistence.platform.server.CustomServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatformBase;
import org.eclipse.persistence.platform.server.ServerPlatformUtils;
import org.eclipse.persistence.queries.QueryResultsCachePolicy;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sessions.Connector;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatasourceLogin;
import org.eclipse.persistence.sessions.DefaultConnector;
import org.eclipse.persistence.sessions.ExternalTransactionController;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEventListener;
import org.eclipse.persistence.sessions.SessionProfiler;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.sessions.coordination.MetadataRefreshListener;
import org.eclipse.persistence.sessions.coordination.RemoteCommandManager;
import org.eclipse.persistence.sessions.coordination.TransportManager;
import org.eclipse.persistence.sessions.coordination.jms.JMSPublishingTransportManager;
import org.eclipse.persistence.sessions.coordination.jms.JMSTopicTransportManager;
import org.eclipse.persistence.sessions.coordination.rmi.RMITransportManager;
import org.eclipse.persistence.sessions.factories.SessionManager;
import org.eclipse.persistence.sessions.factories.XMLSessionConfigLoader;
import org.eclipse.persistence.sessions.remote.RemoteSession;
import org.eclipse.persistence.sessions.remote.rmi.RMIConnection;
import org.eclipse.persistence.sessions.remote.rmi.RMIServerSessionManager;
import org.eclipse.persistence.sessions.remote.rmi.RMIServerSessionManagerDispatcher;
import org.eclipse.persistence.sessions.serializers.JavaSerializer;
import org.eclipse.persistence.sessions.serializers.Serializer;
import org.eclipse.persistence.sessions.server.ConnectionPolicy;
import org.eclipse.persistence.sessions.server.ConnectionPool;
import org.eclipse.persistence.sessions.server.ExternalConnectionPool;
import org.eclipse.persistence.sessions.server.ReadConnectionPool;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.tools.profiler.PerformanceMonitor;
import org.eclipse.persistence.tools.profiler.PerformanceProfiler;
import org.eclipse.persistence.tools.profiler.QueryMonitor;
import org.eclipse.persistence.tools.schemaframework.SchemaManager;
import org.eclipse.persistence.tools.tuning.SafeModeTuner;
import org.eclipse.persistence.tools.tuning.SessionTuner;
import org.eclipse.persistence.tools.tuning.StandardTuner;

/**
 * INTERNAL:
 * This class handles deployment of a persistence unit.
 * In predeploy the meta-data is processed and weaver transformer is returned to allow weaving of the persistent classes.
 * In deploy the project and session are initialize and registered.
 */
public class EntityManagerSetupImpl implements MetadataRefreshListener {
    /*
     * Design Pattern in use: Builder pattern
     * EntityManagerSetupImpl, MetadataProcessor and MetadataProject
     * play the role of director, builder and product respectively.
     * See processORMetadata which is the factory method.
     *
     */

    // this name should uniquely identify the persistence unit
    protected String persistenceUnitUniqueName;
    // session name should uniquely identify the session
    protected String sessionName;

    private MetadataProcessor processor = null;
    /** Holds a reference to the weaver class transformer so it can be cleared after login. */
    private PersistenceWeaver weaver = null;
    protected PersistenceUnitInfo persistenceUnitInfo = null;
    // count a number of open factories that use this object.
    protected int factoryCount = 0;
    protected AbstractSession session = null;
    // true if predeploy called by createContainerEntityManagerFactory; false - createEntityManagerFactory
    protected boolean isInContainerMode = false;
    protected boolean isSessionLoadedFromSessionsXML=false;
    //project caching:
    protected ProjectCache projectCacheAccessor = null;
    protected boolean shouldBuildProject = true;
    // indicates whether weaving was used on the first run through predeploy (in STATE_INITIAL)
    protected Boolean enableWeaving = null;
    // indicates that classes have already been woven
    protected boolean isWeavingStatic = false;
    // used by static weaving
    protected StaticWeaveInfo staticWeaveInfo;
    protected SecurableObjectHolder securableObjectHolder = new SecurableObjectHolder();
    // used by deploy method
    protected ConcurrencyManager deployLock = new ConcurrencyManager();

    protected boolean requiresConnection;

    // 266912: Criteria API and Metamodel API (See Ch 5 of the JPA 2.0 Specification)
    /** Reference to the Metamodel for this deployment and session.
     * Please use the accessor and not the instance variable directly*/
    private Metamodel metaModel;

    protected List<StructConverter> structConverters = null;
    // factoryCount==0; session==null
    public static final String STATE_INITIAL        = "Initial";

    // session != null
    public static final String STATE_PREDEPLOYED    = "Predeployed";

    // factoryCount>0; session != null; session stored in SessionManager
    // for compositeMember factoryCount is always 0; session is never stored in SessionBroker
    // the session has not yet connected for the first time or failed to connect for the first time
    public static final String STATE_HALF_DEPLOYED  = "HalfDeployed";

    // factoryCount>0; session != null; session stored in SessionManager
    // for compositeMember factoryCount is always 0; session is never stored in SessionBroker
    // the session has connected for the first time
    public static final String STATE_DEPLOYED       = "Deployed";

    // factoryCount==0; session==null
    public static final String STATE_PREDEPLOY_FAILED="PredeployFailed";

    // factoryCount>0; session != null
    // for compositeMember factoryCount is always 0
    public static final String STATE_DEPLOY_FAILED  = "DeployFailed";

    // factoryCount==0; session==null
    public static final String STATE_UNDEPLOYED     = "Undeployed";

    // factoryCount==0; session==null
    // only composite member persistence unit can be in this state
    public static final String STATE_HALF_PREDEPLOYED_COMPOSITE_MEMBER = "HalfPredeployedCompositeMember";

    /**
     *     Initial -----&gt; HalfPredeployedCompositeMember -----&gt; PredeployFailed
     *                    |        ^                   |
     *                    V-------&gt;|                   V
     *                                                Predeployed
     */
    protected String state = STATE_INITIAL;

    /**
     *     Initial -----------&gt; PredeployFailed ---
     *           |                                |
     *           V                                |
     *         Predeployed ---&gt; DeployFailed --   |
     *           |                            |   |
     *           V                            V   V
     *         HalfDeployed --&gt; Deployed -&gt; Undeployed
     *           |                            ^
     *           V                            |
     *         DeployFailed -------------------
     *
     */


    public static final String ERROR_LOADING_XML_FILE = "error_loading_xml_file";
    public static final String EXCEPTION_LOADING_ENTITY_CLASS = "exception_loading_entity_class";

    /*
     * Properties used to generate sessionName if none is provided.
     */
    public static String[] connectionPropertyNames = {
        PersistenceUnitProperties.TRANSACTION_TYPE,
        PersistenceUnitProperties.JTA_DATASOURCE,
        PersistenceUnitProperties.NON_JTA_DATASOURCE,
        PersistenceUnitProperties.JDBC_URL,
        PersistenceUnitProperties.JDBC_USER,
        PersistenceUnitProperties.NOSQL_CONNECTION_SPEC,
        PersistenceUnitProperties.NOSQL_CONNECTION_FACTORY,
        PersistenceUnitProperties.NOSQL_USER,
        PersistenceUnitProperties.JDBC_CONNECTOR
    };

    /*
     * Composite, not null only if it's a composite member.
     */
    protected EntityManagerSetupImpl compositeEmSetupImpl;

    /*
     * Composite members, not null only if it's a composite.
     */
    protected Set<EntityManagerSetupImpl> compositeMemberEmSetupImpls;

    /*
     * In HalfPredeployedCompositeMember predeploy method called several times,
     * each call uses mode, then updating it before returning.
     * So mode value could be viewed as a substate of HalfPredeployedCompositeMember state.
     * The mode is required for staging of processing OR metadata for composite members:
     * each processing stage should be completed for ALL composite members before
     * any one of then could proceed to the next processing stage.
     */
    PersistenceUnitProcessor.Mode mode;

    boolean throwExceptionOnFail;
    boolean weaveChangeTracking;
    boolean weaveLazy;
    boolean weaveEager;
    boolean weaveFetchGroups;
    boolean weaveInternal;
    boolean weaveRest;
    boolean weaveMappedSuperClass;

    /**
     * Used to indicate that an EntityManagerFactoryImpl based on this
     * EntityManagerSetupImpl has been refreshed.  This means this EntityManagerSetupImpl
     * will no longer be associated with new EntityManagerFactories
     */
    protected boolean isMetadataExpired = false;
    /*
     * Used to distinguish the various DDL options
     */
    protected enum TableCreationType {NONE, CREATE, DROP, DROP_AND_CREATE, EXTEND};

    /*
     * PersistenceException responsible for the invalid state.
     */
    protected PersistenceException persistenceException;

    public EntityManagerSetupImpl(String persistenceUnitUniqueName, String sessionName) {
        this.persistenceUnitUniqueName = persistenceUnitUniqueName;
        this.sessionName = sessionName;
        this.requiresConnection = true;
    }

    public EntityManagerSetupImpl() {
        this("", "");
    }

    protected static String addFileSeperator(String appLocation) {
        int strLength = appLocation.length();
        if (appLocation.substring(strLength -1, strLength).equals(File.separator)) {
            return appLocation;
        } else {
            return appLocation + File.separator;
        }
    }

    /*
     * Return session name if specified.
     * Otherwise build one from the connection properties names and values.
     * Note that specifying value "" in properties causes
     * the property value specified in PersistenceUnitInfo to be ignored.
     * Never returns null.
     */
    public static String getOrBuildSessionName(Map properties, PersistenceUnitInfo puInfo, String persistenceUnitUniqueName) {
        // Weblogic server was found to prefix the file path on Windows platform with a slash, so mandating that for compatibility
        String persistenceUnitName = assertCompatiblePersistenceUnitName(persistenceUnitUniqueName);

        // if SESSION_NAME is specified in either properties or puInfo properties - use it as session name (unless it's an empty String).
        String sessionName = (String)properties.get(PersistenceUnitProperties.SESSION_NAME);
        if (sessionName == null) {
            sessionName = (String)puInfo.getProperties().get(PersistenceUnitProperties.SESSION_NAME);
        }
        // Specifying empty String in properties allows to remove SESSION_NAME specified in puInfo properties.
        if(sessionName != null && sessionName.length() > 0) {
            return sessionName;
        }

        // ELBug 355603 - Prepend the application id if present in properties.
        // This property will be set by the WebLogic Server if the persistence unit
        // is deployed as part of shared library to construct a unique session name
        String applicationId = (String)properties.get("weblogic.application-id");

        // ELBug 475285 - Added a more generic version of the weblogic.application-id property.
        if (applicationId == null) {
            applicationId = (String) properties.get("eclipselink.application-id");
        }

        if (isComposite(puInfo)) {
            // Composite doesn't use connection properties.
            if (applicationId != null) {
                return applicationId + persistenceUnitName;
            }

            return persistenceUnitName;
        } else {
            // In case no SESSION_NAME specified (or empty String) - build one
            // by concatenating persistenceUnitUniqueName and suffix build of connection properties' names and values.
            if (applicationId != null) {
                return applicationId + persistenceUnitName + buildSessionNameSuffixFromConnectionProperties(properties);
            }

            return persistenceUnitName + buildSessionNameSuffixFromConnectionProperties(properties);
        }
    }

    private static String assertCompatiblePersistenceUnitName(String persistenceUnitUniqueName) {
        if(persistenceUnitUniqueName != null && !persistenceUnitUniqueName.startsWith("/")) {
            return '/' + persistenceUnitUniqueName;
        }
        return persistenceUnitUniqueName;
    }

    protected static String buildSessionNameSuffixFromConnectionProperties(Map properties) {
        StringBuilder suffix = new StringBuilder(32);
        for (int i=0; i < connectionPropertyNames.length; i++) {
            String name = connectionPropertyNames[i];
            Object value = properties.get(name);
            if (value != null) {
                String strValue = null;
                if (value instanceof String) {
                    strValue = (String)value;
                } else {
                    if (value instanceof javax.sql.DataSource) {
                        // value of JTA_DATASOURCE / NON_JTA_DATASOURCE may be a DataSource (we would prefer DataSource name)
                        strValue = Integer.toString(System.identityHashCode(value));
                    } else if (value instanceof PersistenceUnitTransactionType) {
                        strValue = value.toString();
                    } else {
                        strValue = Integer.toString(System.identityHashCode(value));
                    }
                }
                // don't set an empty String
                if (strValue.length() > 0) {
                    suffix.append("_").append(Helper.getShortClassName(name)).append("=").append(strValue);
                }
            }
        }
        return suffix.toString();
    }

    /*
     * Should only be called when emSetupImpl created during SE initialization is set into a new EMF.
     * emSetupImpl must be in PREDEPLOYED state.
     */
    public void changeSessionName(String newSessionName) {
        if(!session.getName().equals(newSessionName)) {
            session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "session_name_change", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), newSessionName});
            sessionName = newSessionName;
            session.setName(newSessionName);
        }
    }

    /**
     * This method can be used to ensure the session represented by emSetupImpl
     * is removed from the SessionManager.
     */
    protected void removeSessionFromGlobalSessionManager() {
        if (this.session != null){
            try {
                if (this.session.isDatabaseSession() && this.session.isConnected()) {
                    getDatabaseSession().logout();
                }
            } finally {
                SessionManager manager = SessionManager.getManager();
                manager.getSessions().remove(this.session.getName(), this.session);
                manager.destroy();
            }
        }
    }

    /**
     * Deploy a persistence session and return an EntityManagerFactory.
     *
     * Deployment takes a session that was partially created in the predeploy call and makes it whole.
     *
     * This means doing any configuration that requires the real class definitions for the entities.  In
     * the predeploy phase we were in a stage where we were not let allowed to load the real classes.
     *
     * Deploy could be called several times - but only the first call does the actual deploying -
     * additional calls allow to update session properties (in case the session is not connected).
     *
     * Note that there is no need to synchronize deploy method - it doesn't alter factoryCount
     * and while deploy is executed no other method can alter the current state
     * (predeploy call would just increment factoryCount; undeploy call would not drop factoryCount to 0).
     * However precautions should be taken to handle concurrent calls to deploy, because those may
     * alter the current state or connect the session.
     *
     * @param realClassLoader The class loader that was used to load the entity classes. This loader
     *               will be maintained for the lifespan of the loaded classes.
     * @param additionalProperties added to persistence unit properties for updateServerSession overriding existing properties.
     *              In JSE case it allows to alter properties in main (as opposed to preMain where preDeploy is called).
     * @return An EntityManagerFactory to be used by the Container to obtain EntityManagers
     */
    public AbstractSession deploy(ClassLoader realClassLoader, Map additionalProperties) {
        if (this.state != STATE_PREDEPLOYED && this.state != STATE_DEPLOYED && this.state != STATE_HALF_DEPLOYED) {
            if (mustBeCompositeMember()) {
                throw new PersistenceException(EntityManagerSetupException.compositeMemberCannotBeUsedStandalone(this.persistenceUnitInfo.getPersistenceUnitName()));
            }
            throw new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(this.persistenceUnitInfo.getPersistenceUnitName(), this.state, this.persistenceException));
        }
        // state is PREDEPLOYED or DEPLOYED
        this.session.log(SessionLog.FINEST, SessionLog.JPA, "deploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), this.session.getName(), this.state, this.factoryCount});

        ClassLoader classLoaderToUse = realClassLoader;

        if (additionalProperties.containsKey(PersistenceUnitProperties.CLASSLOADER)) {
            classLoaderToUse = (ClassLoader) additionalProperties.get(PersistenceUnitProperties.CLASSLOADER);
        } else if ((this.processor != null) && (this.processor.getProject() != null) && (this.processor.getProject().hasVirtualClasses()) && (this.state == STATE_PREDEPLOYED) && (!(classLoaderToUse instanceof DynamicClassLoader))) {
            classLoaderToUse = new DynamicClassLoader(classLoaderToUse);
        }

        // indicates whether session has failed to connect, determines whether HALF_DEPLOYED state should be kept in case of exception.
        boolean isLockAcquired = false;
        try {
            Map deployProperties = mergeMaps(additionalProperties, this.persistenceUnitInfo.getProperties());
            updateTunerPreDeploy(deployProperties, classLoaderToUse);
            translateOldProperties(deployProperties, this.session);
            if (isComposite()) {
                updateCompositeMembersProperties(deployProperties);
            }
            if (this.state == STATE_PREDEPLOYED) {
                this.deployLock.acquire();
                isLockAcquired = true;
                if (this.state == STATE_PREDEPLOYED) {
                    if (this.shouldBuildProject && !this.isSessionLoadedFromSessionsXML) {
                        if (isComposite()) {
                            deployCompositeMembers(deployProperties, classLoaderToUse);
                        } else {
                            if (this.processor.getMetadataSource() != null) {
                                Map metadataProperties = this.processor.getMetadataSource().getPropertyOverrides(deployProperties, classLoaderToUse, this.session.getSessionLog());
                                if (metadataProperties != null && !metadataProperties.isEmpty()) {
                                    translateOldProperties(metadataProperties, this.session);
                                    deployProperties = mergeMaps(metadataProperties, deployProperties);
                                }
                            }
                            // listeners and queries require the real classes and are therefore built during deploy using the realClassLoader
                            this.processor.setClassLoader(classLoaderToUse);
                            this.processor.createDynamicClasses();

                            this.processor.addEntityListeners();

                            if (this.projectCacheAccessor != null) {
                                //cache the project:
                                this.projectCacheAccessor.storeProject(this.session.getProject(), deployProperties, this.session.getSessionLog());
                            }

                            // The project is initially created using class names rather than classes.  This call will make the conversion.
                            // If the session was loaded from sessions.xml this will also convert the descriptor classes to the correct class loader.
                            this.session.getProject().convertClassNamesToClasses(classLoaderToUse);

                            if (!isCompositeMember()) {
                                addBeanValidationListeners(deployProperties, classLoaderToUse);
                            }

                            // Process the customizers last.
                            this.processor.processCustomizers();
                        }

                        this.processor = null;
                    } else {
                        // The project is initially created using class names rather than classes.  This call will make the conversion.
                        // If the session was loaded from sessions.xml this will also convert the descriptor classes to the correct class loader.
                        this.session.getProject().convertClassNamesToClasses(classLoaderToUse);
                        if (!this.shouldBuildProject) {
                            //process anything that might not have been serialized/cached in the project correctly:
                            if (!isCompositeMember()) {
                                addBeanValidationListeners(deployProperties, classLoaderToUse);
                            }

                            //process Descriptor customizers:
                            processDescriptorsFromCachedProject(classLoaderToUse);
                        }
                    }
                    finishProcessingDescriptorEvents(classLoaderToUse);
                    this.structConverters = getStructConverters(classLoaderToUse);

                    updateRemote(deployProperties, classLoaderToUse);
                    initSession();

                    if (this.session.getIntegrityChecker().hasErrors()){
                        this.session.handleException(new IntegrityException(session.getIntegrityChecker()));
                    }

                    this.session.getDatasourcePlatform().getConversionManager().setLoader(classLoaderToUse);
                    this.state = STATE_HALF_DEPLOYED;
                    // keep deployLock
                } else {
                    // state is HALF_DEPLOYED or DEPLOY_FAILED
                    this.deployLock.release();
                    isLockAcquired = false;
                    if (this.state == STATE_DEPLOY_FAILED) {
                        // while this thread waited in STATE_PREDEPLOYED another thread attempted to deploy and failed.
                        // Rethrow the cache PersistenceException, which caused STATE_DEPLOYED_FAILED.
                        throw persistenceException;
                    }
                }
            }
            // state is HALF_DEPLOYED or DEPLOYED
            if (!isCompositeMember()) {
                if (this.session.isDatabaseSession() && !((DatabaseSessionImpl)session).isLoggedIn()) {
                    // If it's HALF_DEPLOYED then deployLock has been already acquired.
                    if (!isLockAcquired) {
                        this.deployLock.acquire();
                        isLockAcquired = true;
                    }
                    if (!((DatabaseSessionImpl)this.session).isLoggedIn()) {
                        if (this.state == STATE_DEPLOY_FAILED) {
                            // while this thread waited in STATE_HALF_DEPLOYED another thread attempted to connect the session and failed.
                            // Rethrow the cache PersistenceException, which caused STATE_DEPLOYED_FAILED.
                            throw persistenceException;
                        }
                        this.session.setProperties(deployProperties);
                        updateSession(deployProperties, classLoaderToUse);
                        if (isValidationOnly(deployProperties, false)) {
                            /**
                             * for 324213 we could add a session.loginAndDetectDatasource() call
                             * before calling initializeDescriptors when validation-only is True
                             * to avoid a native sequence exception on a generic DatabasePlatform
                             * by auto-detecting the correct DB platform.
                             * However, this would introduce a DB login when validation is on
                             * - in opposition to the functionality of the property (to only validate)
                             */
                            if (this.state == STATE_HALF_DEPLOYED) {
                                getDatabaseSession().initializeDescriptors();
                                this.state = STATE_DEPLOYED;
                            }
                        } else {
                            try {
                                updateTunerDeploy(deployProperties, classLoaderToUse);
                                updateFreeMemory(deployProperties);
                                if (this.isSessionLoadedFromSessionsXML) {
                                    getDatabaseSession().login();
                                } else {
                                    login(getDatabaseSession(), deployProperties, requiresConnection);
                                }

                                final Platform platform = getDatabaseSession().getDatasourcePlatform();
                                String dbProperties = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.TARGET_DATABASE_PROPERTIES, deployProperties, this.session);
                                PropertiesUtils.set(platform, PersistenceUnitProperties.TARGET_DATABASE_PROPERTIES, dbProperties);

                                // Make JTA integration throw JPA exceptions.
                                if (this.session.hasExternalTransactionController()) {
                                    if (this.session.getExternalTransactionController().getExceptionHandler() == null) {
                                        this.session.getExternalTransactionController().setExceptionHandler(new ExceptionHandler() {

                                            @Override
                                            public Object handleException(RuntimeException exception) {
                                                if (exception instanceof org.eclipse.persistence.exceptions.OptimisticLockException) {
                                                    throw new OptimisticLockException(exception);
                                                } else if (exception instanceof EclipseLinkException) {
                                                    throw new PersistenceException(exception);
                                                } else {
                                                    throw exception;
                                                }
                                            }

                                        });
                                    }
                                }
                                this.state = STATE_DEPLOYED;
                            } catch (Throwable loginException) {
                                if (this.state == STATE_HALF_DEPLOYED) {
                                    if (this.session.isConnected()) {
                                        // session is connected, but postConnect has failed.
                                        // Likely this is caused by failure in initializeDescriptors:
                                        // either descriptor exception or by invalid named jpql query.
                                        // Cannot recover from that - the user has to fix the persistence unit and redeploy it.
                                        try {
                                            getDatabaseSession().logout();
                                        } catch (Throwable logoutException) {
                                            // Ignore
                                        }
                                        this.state = STATE_DEPLOY_FAILED;
                                    }
                                }
                                throw loginException;
                            }
                            if (!this.isSessionLoadedFromSessionsXML) {
                                addStructConverters();
                            }

                            // Generate the DDL using the correct connection.
                            writeDDL(deployProperties, getDatabaseSession(deployProperties), classLoaderToUse);
                        }
                    }
                    // Initialize platform specific identity sequences.
                    session.getDatasourcePlatform().initIdentitySequences(getDatabaseSession(), MetadataProject.DEFAULT_IDENTITY_GENERATOR);
                    updateTunerPostDeploy(deployProperties, classLoaderToUse);
                    this.deployLock.release();
                    isLockAcquired = false;
                }
                // 266912: Initialize the Metamodel, a login should have already occurred.
                try {
                    this.getMetamodel(classLoaderToUse);
                } catch (Exception e) {
                    this.session.log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_init_failed", new Object[]{e.getMessage()});
                }
            }
            // Clear the weaver's reference to meta-data information, as it is held by the class loader and will never gc.
            if (this.weaver != null) {
                this.weaver.clear();
                this.weaver = null;
            }

            return this.session;
        } catch (Throwable exception) {
            // before releasing deployLock switch to the correct state
            if (this.state == STATE_PREDEPLOYED) {
                this.state = STATE_DEPLOY_FAILED;
            }
            PersistenceException persistenceEx;
            if (this.state == STATE_DEPLOY_FAILED) {
                if (exception == persistenceException) {
                    persistenceEx = new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(this.persistenceUnitInfo.getPersistenceUnitName(), this.state, this.persistenceException));
                } else {
                    // before releasing deployLock cache the exception
                    persistenceEx = createDeployFailedPersistenceException(exception);
                }
            } else {
                if (exception instanceof PersistenceException) {
                    persistenceEx = (PersistenceException)exception;
                } else {
                    persistenceEx = new PersistenceException(exception);
                }
            }
            if (isLockAcquired) {
                this.deployLock.release();
            }
            this.session.logThrowable(SessionLog.SEVERE, SessionLog.EJB, exception);
            throw persistenceEx;
        } finally {
            this.session.log(SessionLog.FINEST, SessionLog.JPA, "deploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), this.session.getName(), this.state, this.factoryCount});
        }
    }

    /**
     * INTERNAL:
     * This method is used to resolve Descriptor Customizers that might have been stored in the project
     * for JPA project caching.
     *
     * @param realClassLoader
     * @throws ClassNotFoundException
     * @throws PrivilegedActionException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    private void processDescriptorsFromCachedProject(ClassLoader realClassLoader) throws ClassNotFoundException, PrivilegedActionException, IllegalAccessException, InstantiationException {
        for (ClassDescriptor descriptor: session.getProject().getDescriptors().values()) {
            //process customizers:
            if (descriptor.getDescriptorCustomizerClassName() != null) {
                Class listenerClass = findClass(descriptor.getDescriptorCustomizerClassName(), realClassLoader);
                DescriptorCustomizer customizer = (DescriptorCustomizer) buildObjectForClass(listenerClass, DescriptorCustomizer.class);
                try {
                    customizer.customize(descriptor);
                } catch (Exception e) {
                    session.getSessionLog().logThrowable(SessionLog.FINER, SessionLog.METADATA, e);
                }
            }
        }
    }

    /**
     * INTERNAL:
     * This method is used to resolve Descriptor Events processed earlier into EventHolders that now need to be
     * used to create the DescriptorEventListeners and added to the DescriptorEventManager
     *
     */
    private void finishProcessingDescriptorEvents(ClassLoader realClassLoader) {
        for (ClassDescriptor descriptor: session.getProject().getDescriptors().values()) {
            if (descriptor.hasEventManager()) {
                descriptor.getEventManager().processDescriptorEventHolders(session, realClassLoader);
            }
        }
    }

    protected PersistenceException createDeployFailedPersistenceException(Throwable ex) {
        PersistenceException perEx = new PersistenceException(EntityManagerSetupException.deployFailed(persistenceUnitInfo.getPersistenceUnitName(), ex));
        if (persistenceException == null) {
            persistenceException = perEx;
        }
        return perEx;
    }

    /**
     * Adds descriptors plus sequencing info found on the project to the session.
     */
    protected void addProjectToSession(ServerSession session, Project project) {
        DatasourcePlatform sessionPlatform = (DatasourcePlatform)session.getDatasourceLogin().getDatasourcePlatform();
        DatasourcePlatform projectPlatform = (DatasourcePlatform)project.getDatasourceLogin().getDatasourcePlatform();
        if (!sessionPlatform.hasDefaultSequence() && projectPlatform.hasDefaultSequence()) {
            sessionPlatform.setDefaultSequence(projectPlatform.getDefaultSequence());
        }
        if ((sessionPlatform.getSequences() == null) || sessionPlatform.getSequences().isEmpty()) {
            if ((projectPlatform.getSequences() != null) && !projectPlatform.getSequences().isEmpty()) {
                sessionPlatform.setSequences(projectPlatform.getSequences());
            }
        } else {
            if ((projectPlatform.getSequences() != null) && !projectPlatform.getSequences().isEmpty()) {
                Iterator<Sequence> itProjectSequences = projectPlatform.getSequences().values().iterator();
                while (itProjectSequences.hasNext()) {
                    Sequence sequence = itProjectSequences.next();
                    if (!sessionPlatform.getSequences().containsKey(sequence.getName())) {
                        sessionPlatform.addSequence(sequence);
                    }
                }
            }
        }
        session.addDescriptors(project);
    }

    /**
     * Put the given session into the session manager so it can be looked up later
     */
    protected void addSessionToGlobalSessionManager() {
        SessionManager sm = SessionManager.getManager();
        ConcurrentMap<String,Session> sessions = sm.getSessions();
        AbstractSession oldSession = (AbstractSession) sessions.get(session.getName());
        if(oldSession != null) {
            throw new PersistenceException(EntityManagerSetupException.attemptedRedeployWithoutClose(session.getName()));
        }
        sm.addSession(session);
    }

    /**
     * Add the StructConverters that were specified by annotation on the DatabasePlatform
     * This method must be called after the DatabasePlatform has been detected
     */
    public void addStructConverters(){
        if (this.compositeMemberEmSetupImpls == null) {
            for (StructConverter structConverter : structConverters){
                if (session.getPlatform().getTypeConverters().get(structConverter.getJavaType()) != null){
                    throw ValidationException.twoStructConvertersAddedForSameClass(structConverter.getJavaType().getName());
                }
                session.getPlatform().addStructConverter(structConverter);
            }
        } else {
            // composite
            for(EntityManagerSetupImpl compositeMemberEmSetupImpl : this.compositeMemberEmSetupImpls) {
                if (!compositeMemberEmSetupImpl.structConverters.isEmpty()) {
                    String compositeMemberPuName = compositeMemberEmSetupImpl.getPersistenceUnitInfo().getPersistenceUnitName();
                    // debug output added to make it easier to navigate the log because the method is called outside of composite member deploy
                    compositeMemberEmSetupImpl.session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "composite_member_begin_call", new Object[]{"addStructConverters", compositeMemberPuName, state});
                    compositeMemberEmSetupImpl.addStructConverters();
                    compositeMemberEmSetupImpl.session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "composite_member_end_call", new Object[]{"addStructConverters", compositeMemberPuName, state});
                }
            }
        }
    }

    /**
     * Assign a CMP3Policy to each descriptor, and sets the OptimisticLockingPolicy's LockOnChangeMode if applicable.
     */
    protected void assignCMP3Policy() {
        // all descriptors assigned CMP3Policy
        Project project = session.getProject();
        for (Iterator<ClassDescriptor> iterator = project.getDescriptors().values().iterator(); iterator.hasNext();){
            //bug:4406101  changed class cast to base class, which is used in projects generated from 904 xml
            ClassDescriptor descriptor = iterator.next();

            if(descriptor.getCMPPolicy() == null) {
                descriptor.setCMPPolicy(new CMP3Policy());
            }
            OptimisticLockingPolicy olp = descriptor.getOptimisticLockingPolicy();
            if (olp != null && olp.getLockOnChangeMode() == null){
                olp.setLockOnChangeMode(LockOnChange.OWNING);
            }
        }

        // TODO: Look into setting a CMPPolicy on the MappedSuperclass descriptors.
        // Will require some tweaking however to ensure the primary key fields are
        // set/initialized correctly. Currently rely on the descriptor initialized
        // object builder which is not available to mapped superclass descriptors.
    }

    /**
     * Updates the EclipseLink ServerPlatform class for use with this platform.
     * @return true if the ServerPlatform has changed.
     */
    protected boolean updateServerPlatform(Map m, ClassLoader loader) {
        final String serverPlatformClassNameProperty =
                PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.TARGET_SERVER, m, session);
        final String jtaControllerClassNameProperty =
                PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.JTA_CONTROLLER, m, session);

        final String serverPlatformClassName;
        if (serverPlatformClassNameProperty == null) {
            // property is not specified - try to detect.
            serverPlatformClassName = ServerPlatformUtils.detectServerPlatform(getSession());
            if (serverPlatformClassName == null) {
                // Unable to detect what platform we're running on. Use default/NoServer.
                return false;
            }
        } else {
            serverPlatformClassName = serverPlatformClassNameProperty;
        }

        // originalServerPlatform is always non-null - Session's constructor sets serverPlatform to NoServerPlatform
        final ServerPlatform originalServerPlatform = session.getServerPlatform();
        final String originalServerPlatformClassName = originalServerPlatform.getClass().getName();
        final Class originalServerPlatformTransCtrlClass = originalServerPlatform.getExternalTransactionControllerClass();
        final String originalServerPlatformTransCtrlClassName = originalServerPlatformTransCtrlClass != null
                ? originalServerPlatform.getExternalTransactionControllerClass().getName() : null;

        if (serverPlatformClassName.equals(originalServerPlatformClassName)
                && (serverPlatformClassNameProperty == null || serverPlatformClassNameProperty.equals(originalServerPlatformClassName))
                && (jtaControllerClassNameProperty == null || jtaControllerClassNameProperty.equals(originalServerPlatformTransCtrlClassName))) {
            // nothing to do - use the same value as before
            return false;
        }

        // the new serverPlatform
        ServerPlatform serverPlatform = null;
        // New platform - create the new instance and set it.
        Class cls = findClassForProperty(serverPlatformClassName, PersistenceUnitProperties.TARGET_SERVER, loader);
        boolean isTargetServerTransCtrl = false;
        try {
            Constructor constructor = cls.getConstructor(org.eclipse.persistence.sessions.DatabaseSession.class);
            serverPlatform = (ServerPlatform)constructor.newInstance(new Object[]{session});
        } catch (Exception ex) {
            if(ExternalTransactionController.class.isAssignableFrom(cls)) {
                // the new serverPlatform is CustomServerPlatform, cls is its ExternalTransactionController class
                if(originalServerPlatform.getClass().equals(CustomServerPlatform.class)) {
                    // both originalServerPlatform and the new serverPlatform are Custom,
                    // just set externalTransactionController class (if necessary) into
                    // originalServerPlatform
                    CustomServerPlatform originalCustomServerPlatform = (CustomServerPlatform)originalServerPlatform;
                    if (cls.equals(originalCustomServerPlatform.getExternalTransactionControllerClass())) {
                        // externalTransactionController classes are the same - nothing to do
                    } else {
                        originalCustomServerPlatform.setExternalTransactionControllerClass(cls);
                    }
                } else {
                    // originalServerPlatform is not custom - need a new one.
                    serverPlatform = new CustomServerPlatform(getDatabaseSession());
                    serverPlatform.setExternalTransactionControllerClass(cls);
                }
                isTargetServerTransCtrl = true;
             } else {
                 throw EntityManagerSetupException.failedToInstantiateServerPlatform(serverPlatformClassName, PersistenceUnitProperties.TARGET_SERVER, ex);
             }
         }

        // Override JTA transaction controller class by eclipselink.jta.controller property, but only when
        // eclipselink.target-server does not contain ExternalTransactionController implementing class.
        if (jtaControllerClassNameProperty != null) {
            if (isTargetServerTransCtrl) {
                session.getSessionLog().log(SessionLog.WARNING, "jta_duplicate_ctrl_property");
            } else {
                if (!originalServerPlatform.getClass().equals(CustomServerPlatform.class)) {
                    serverPlatform = new CustomServerPlatform(getDatabaseSession());
                }
                updateJTAControllerInPlatform(serverPlatform != null ? serverPlatform : originalServerPlatform, jtaControllerClassNameProperty, loader);
            }
        }

        if (serverPlatform != null) {
            getDatabaseSession().setServerPlatform(serverPlatform);
            return true;
        }
        return false;
    }

    /**
     * Update JTA transaction controller class of provided {@link ServerPlatform} instance.
     *
     * @param serverPlatform target {@link ServerPlatform} instance
     * @param jtaControllerClassName JTA transaction controller class name
     * @param loader class loader containing JTA transaction controller class
     */
    private static void updateJTAControllerInPlatform(
            final ServerPlatform serverPlatform, final String jtaControllerClassName, final ClassLoader loader) {
        Class jtaCls = findClassForProperty(jtaControllerClassName, PersistenceUnitProperties.JTA_CONTROLLER, loader);
        serverPlatform.setExternalTransactionControllerClass(jtaCls);
    }

    /**
     * Checks for partitioning properties.
     */
    protected void updatePartitioning(Map m, ClassLoader loader) {
        // Partitioning
        String partitioning = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.PARTITIONING, m, this.session);
        if (partitioning != null) {
            PartitioningPolicy partitioningPolicy = this.session.getProject().getPartitioningPolicy(partitioning);
            if (partitioningPolicy == null) {
                throw DescriptorException.missingPartitioningPolicy(partitioning, null, null);
            }
            this.session.setPartitioningPolicy(partitioningPolicy);
        }

        String callbackClassName = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.PARTITIONING_CALLBACK, m, this.session);
        if (callbackClassName != null) {
            Class cls = findClassForProperty(callbackClassName, PersistenceUnitProperties.PARTITIONING_CALLBACK, loader);
            DataPartitioningCallback callback = null;
            try {
                Constructor constructor = cls.getConstructor();
                callback = (DataPartitioningCallback)constructor.newInstance();
            } catch (Exception exception) {
                throw EntityManagerSetupException.failedToInstantiateProperty(callbackClassName, PersistenceUnitProperties.PARTITIONING_CALLBACK, exception);
            }
            this.session.getLogin().setPartitioningCallback(callback);
        }
    }

    /**
     * Checks for partitioning properties.
     */
    protected void updateRemote(Map m, ClassLoader loader) {
        String protocol = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.REMOTE_PROTOCOL, m, this.session);
        String serverName = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.REMOTE_SERVER_NAME, m, this.session);
        if (serverName == null) {
            // Configure as client.
            if (protocol != null) {
                RemoteConnection connection = null;
                if (protocol.equalsIgnoreCase(RemoteProtocol.RMI)) {
                    String url = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.REMOTE_URL, m, this.session);
                    if (url == null) {
                        throw EntityManagerSetupException.missingProperty(PersistenceUnitProperties.REMOTE_URL);
                    }
                    try {
                        connection = new RMIConnection(((RMIServerSessionManager)Naming.lookup(url)).createRemoteSessionController());
                    } catch (Exception exception) {
                        throw ValidationException.invalidValueForProperty(url, PersistenceUnitProperties.REMOTE_URL, exception);
                    }
                } else {
                    Class cls = findClassForProperty(protocol, PersistenceUnitProperties.REMOTE_PROTOCOL, loader);
                    try {
                        Constructor constructor = cls.getConstructor();
                        connection = (RemoteConnection)constructor.newInstance();
                    } catch (Exception exception) {
                        throw ValidationException.invalidValueForProperty(protocol, PersistenceUnitProperties.REMOTE_PROTOCOL, exception);
                    }
                }
                RemoteSession remoteSession = new RemoteSession();
                remoteSession.setIsMetadataRemote(false);
                remoteSession.setProject(this.session.getProject());
                remoteSession.setProfiler(this.session.getProfiler());
                remoteSession.setSessionLog(this.session.getSessionLog());
                remoteSession.setEventManager(this.session.getEventManager());
                remoteSession.setQueries(this.session.getQueries());
                remoteSession.setProperties(this.session.getProperties());
                remoteSession.setName(this.session.getName());
                remoteSession.setRemoteConnection(connection);
                this.session = remoteSession;
            }
        } else {
            // Configure as server.
            if (protocol.equalsIgnoreCase(RemoteProtocol.RMI)) {
                RMIServerSessionManager manager = null;
                // Make sure RMI registry is started.
                try {
                    java.rmi.registry.LocateRegistry.createRegistry(1099);
                } catch (Exception exception) {
                    System.out.println("Security violation " + exception.toString());
                }
                // Create local instance of the factory
                try {
                    manager = new RMIServerSessionManagerDispatcher(session);
                } catch (RemoteException exception) {
                    throw ValidationException.invalidValueForProperty(serverName, PersistenceUnitProperties.REMOTE_SERVER_NAME, exception);
                }
                // Put the local instance into the Registry
                try {
                    Naming.unbind(serverName);
                } catch (Exception exception) {
                    // Ignore.
                }

                // Put the local instance into the Registry
                try {
                    Naming.rebind(serverName, manager);
                } catch (Exception exception) {
                    throw ValidationException.invalidValueForProperty(serverName, PersistenceUnitProperties.REMOTE_SERVER_NAME, exception);
                }
            }
        }
    }

    /**
     * Checks for database events listener properties.
     */
    protected void updateDatabaseEventListener(Map m, ClassLoader loader) {
        String listenerClassName = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.DATABASE_EVENT_LISTENER, m, this.session);
        if (listenerClassName != null) {
            if (listenerClassName.equalsIgnoreCase("DCN") || listenerClassName.equalsIgnoreCase("QCN")) {
                listenerClassName = "org.eclipse.persistence.platform.database.oracle.dcn.OracleChangeNotificationListener";
            }
            Class cls = findClassForProperty(listenerClassName, PersistenceUnitProperties.DATABASE_EVENT_LISTENER, loader);
            DatabaseEventListener listener = null;
            try {
                Constructor constructor = cls.getConstructor();
                listener = (DatabaseEventListener)constructor.newInstance();
            } catch (Exception exception) {
                throw EntityManagerSetupException.failedToInstantiateProperty(listenerClassName, PersistenceUnitProperties.DATABASE_EVENT_LISTENER, exception);
            }
            getDatabaseSession().setDatabaseEventListener(listener);
        }
    }

    /**
     * Update loggers and settings for the singleton logger and the session logger.
     * @param persistenceProperties the properties map
     * @param serverPlatformChanged the boolean that denotes a serverPlatform change in the session.
     */
    protected void updateLoggers(Map persistenceProperties, boolean serverPlatformChanged, ClassLoader loader) {
        // Logger(SessionLog type) can be specified by the logger property or ServerPlatform.getServerLog().
        // The logger property has a higher priority to ServerPlatform.getServerLog().
        String loggerClassName = PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.LOGGING_LOGGER, persistenceProperties, session);

        // The sessionLog instance should be different from the singletonLog because they have
        // different state.
        SessionLog singletonLog = null, sessionLog = null;
        if (loggerClassName != null) {
            SessionLog currentLog = session.getSessionLog();
            if(loggerClassName.equals(LoggerType.ServerLogger)){
                ServerPlatform serverPlatform = session.getServerPlatform();
                singletonLog = serverPlatform.getServerLog();
                sessionLog = serverPlatform.getServerLog();
            } else if (!currentLog.getClass().getName().equals(loggerClassName)) {
                // Logger class was specified and it's not what's already there.
                Class sessionLogClass = findClassForProperty(loggerClassName, PersistenceUnitProperties.LOGGING_LOGGER, loader);
                try {
                    singletonLog = (SessionLog)sessionLogClass.getConstructor().newInstance();
                    sessionLog = (SessionLog)sessionLogClass.getConstructor().newInstance();
                } catch (Exception ex) {
                    throw EntityManagerSetupException.failedToInstantiateLogger(loggerClassName, PersistenceUnitProperties.LOGGING_LOGGER, ex);
                }
            }
        } else if (serverPlatformChanged) {
            ServerPlatform serverPlatform = session.getServerPlatform();
            singletonLog = serverPlatform.getServerLog();
            sessionLog = serverPlatform.getServerLog();
        }

        // Don't change default loggers if the new loggers have not been created.
        if (singletonLog != null && sessionLog != null) {
            AbstractSessionLog.setLog(singletonLog);
            session.setSessionLog(sessionLog);
        }

        // Bug5389828.  Update the logging settings for the singleton logger.
        initOrUpdateLogging(persistenceProperties, AbstractSessionLog.getLog());
        initOrUpdateLogging(persistenceProperties, session.getSessionLog());
        // Set logging file.
        String loggingFileString = (String)persistenceProperties.get(PersistenceUnitProperties.LOGGING_FILE);
        if (loggingFileString != null) {
            if (!loggingFileString.trim().equals("")) {
                try {
                    if (sessionLog!=null){
                        if (sessionLog instanceof AbstractSessionLog) {
                            FileOutputStream fos = new FileOutputStream(loggingFileString);
                           ((AbstractSessionLog)sessionLog).setWriter(fos);
                        } else {
                            FileWriter fw = new FileWriter(loggingFileString);
                            sessionLog.setWriter(fw);
                        }
                    }
                } catch (IOException e) {
                    session.handleException(ValidationException.invalidLoggingFile(loggingFileString,e));
                }
            } else {
                session.handleException(ValidationException.invalidLoggingFile());
            }
        }
    }

    /**
     * Check for the PROFILER persistence or system property and set the Session's profiler.
     * This can also set the QueryMonitor.
     */
    protected void updateProfiler(Map persistenceProperties,ClassLoader loader) {
        // This must use config property as the profiler is not in the PropertiesHandler and requires
        // supporting generic profiler classes.
        String newProfilerClassName = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.PROFILER, persistenceProperties, session);

        if (newProfilerClassName == null) {
            ServerPlatformBase plaftorm = ((ServerPlatformBase)session.getServerPlatform());
            if (plaftorm != null) {
                plaftorm.configureProfiler(session);
            }
        } else {
            if (newProfilerClassName.equals(ProfilerType.NoProfiler)) {
                session.setProfiler(null);
                return;
            }
            if (newProfilerClassName.equals(ProfilerType.QueryMonitor)) {
                session.setProfiler(null);
                QueryMonitor.shouldMonitor=true;
                return;
            }
            if (newProfilerClassName.equals(ProfilerType.PerformanceProfiler)) {
                session.setProfiler(new PerformanceProfiler());
                return;
            }
            if (newProfilerClassName.equals(ProfilerType.PerformanceMonitor)) {
                session.setProfiler(new PerformanceMonitor());
                return;
            }

            if (newProfilerClassName.equals(ProfilerType.DMSProfiler)) {
                newProfilerClassName = ProfilerType.DMSProfilerClassName;
            }

            String originalProfilerClassNamer = null;
            if (session.getProfiler() != null) {
                originalProfilerClassNamer = session.getProfiler().getClass().getName();
                if (originalProfilerClassNamer.equals(newProfilerClassName)) {
                    return;
                }
            }

            // New profiler - create the new instance and set it.
            try {
                Class newProfilerClass = findClassForProperty(newProfilerClassName, PersistenceUnitProperties.PROFILER, loader);

                SessionProfiler sessionProfiler = (SessionProfiler)buildObjectForClass(newProfilerClass, SessionProfiler.class);

                if (sessionProfiler != null) {
                    session.setProfiler(sessionProfiler);
                } else {
                    session.handleException(ValidationException.invalidProfilerClass(newProfilerClassName));
                }
            } catch (IllegalAccessException e) {
                session.handleException(ValidationException.cannotInstantiateProfilerClass(newProfilerClassName,e));
            } catch (PrivilegedActionException e) {
                session.handleException(ValidationException.cannotInstantiateProfilerClass(newProfilerClassName,e));
            } catch (InstantiationException e) {
                session.handleException(ValidationException.cannotInstantiateProfilerClass(newProfilerClassName,e));
            }
        }
    }


    protected static Class findClass(String className, ClassLoader loader) throws ClassNotFoundException, PrivilegedActionException {
        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
            return AccessController.doPrivileged(new PrivilegedClassForName<>(className, true, loader));
        } else {
            return org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(className, true, loader);
        }
    }

    protected static Class findClassForProperty(String className, String propertyName, ClassLoader loader) {
        ClassLoader eclipselinkLoader = EntityManagerSetupImpl.class.getClassLoader();
        boolean multipleLoaders = eclipselinkLoader != loader;
        if (multipleLoaders) {
            return findClassForPropertyInternal(className, propertyName, loader, eclipselinkLoader);
        } else {
            return findClassForPropertyInternal(className, propertyName, loader);
        }
    }

    private static Class findClassForPropertyInternal(String clsName, String propName, ClassLoader... loaders) {
        RuntimeException e = null;
        for (ClassLoader loader : loaders) {
            try {
                return findClass(clsName, loader);
            } catch (PrivilegedActionException exception1) {
                e = EntityManagerSetupException.classNotFoundForProperty(clsName, propName, exception1.getException());
            } catch (ClassNotFoundException exception2) {
                e = EntityManagerSetupException.classNotFoundForProperty(clsName, propName, exception2);
            }
        }

        throw e;
    }

    /**
     * Internal:
     * Returns a list of StructConverter instances from a list of StructConverter names stored within the project.
     *
     * @param realClassLoader
     * @return
     */
    protected List<StructConverter> getStructConverters(ClassLoader realClassLoader) {
        List<StructConverter> structConverters = new ArrayList<StructConverter>();
        if (session.getProject().getStructConverters() != null) {
            for (String converter: session.getProject().getStructConverters()) {
                Class clazz = null;
                try {
                    clazz = findClass(converter, realClassLoader);
                } catch (PrivilegedActionException exception) {
                    throw ValidationException.unableToLoadClass(converter, exception.getException());
                } catch (ClassNotFoundException exception) {
                    throw ValidationException.unableToLoadClass(converter, exception);
                }

                try {
                    structConverters.add((StructConverter) buildObjectForClass(clazz, StructConverter.class));
                } catch (PrivilegedActionException e) {
                    throw ValidationException.errorInstantiatingClass(clazz, e.getException());
                } catch (IllegalAccessException e) {
                    throw ValidationException.errorInstantiatingClass(clazz, e);
                }  catch (InstantiationException e) {
                    throw ValidationException.errorInstantiatingClass(clazz, e);
                }
            }
        }
        return structConverters;
    }

    protected boolean hasSchemaDatabaseGeneration(Map m) {
        if (hasConfigProperty(SCHEMA_GENERATION_DATABASE_ACTION, m)) {
            return getConfigPropertyAsString(SCHEMA_GENERATION_DATABASE_ACTION, m) != null && ! getConfigPropertyAsString(SCHEMA_GENERATION_DATABASE_ACTION, m).equals(SCHEMA_GENERATION_NONE_ACTION);
        }

        return false;
    }

    protected boolean hasSchemaScriptsGeneration(Map m) {
        if (hasConfigProperty(SCHEMA_GENERATION_SCRIPTS_ACTION, m)) {
            return getConfigPropertyAsString(SCHEMA_GENERATION_SCRIPTS_ACTION, m) != null && ! getConfigPropertyAsString(SCHEMA_GENERATION_SCRIPTS_ACTION, m).equals(SCHEMA_GENERATION_NONE_ACTION);
        }

        return false;
    }

    public AbstractSession getSession() {
        return session;
    }

    public DatabaseSessionImpl getDatabaseSession() {
        return (DatabaseSessionImpl)session;
    }

    /**
     * We may be provided a connection via the properties to use. Check for
     * one and build a database session around it. Otherwise return the pu
     * database session.
     */
    public DatabaseSessionImpl getDatabaseSession(Map props) {
        DatabaseSessionImpl databaseSession = getDatabaseSession();
        Object connection = getConfigProperty(PersistenceUnitProperties.SCHEMA_GENERATION_CONNECTION, props);

        if (connection == null) {
            return databaseSession;
        } else {
            // A connection was provided. Build a database session using that
            // connection and use the same log level set on the original
            // database session.
            DatabaseSessionImpl newDatabaseSession = new DatabaseSessionImpl();
            newDatabaseSession.setAccessor(new DatabaseAccessor(connection));
            newDatabaseSession.setLogLevel(databaseSession.getLogLevel());
            newDatabaseSession.setProject(databaseSession.getProject().clone());
            return newDatabaseSession;
        }
    }

    /**
     * This method will be used to validate the specified class and return it's instance.
     */
    protected static Object buildObjectForClass(Class clazz, Class mustBeImplementedInterface) throws IllegalAccessException, PrivilegedActionException,InstantiationException {
        if(clazz!=null && Helper.classImplementsInterface(clazz,mustBeImplementedInterface)){
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                return AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(clazz));
            } else {
                return PrivilegedAccessHelper.newInstanceFromClass(clazz);
            }
        } else {
            return null;
        }
    }

    protected void updateDescriptorCacheSettings(Map m, ClassLoader loader) {
        String queryCache = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.QUERY_CACHE, m, session);
        if ((queryCache != null) && queryCache.equalsIgnoreCase("true")) {
            session.getProject().setDefaultQueryResultsCachePolicy(new QueryResultsCachePolicy());
        }
        String queryCacheForceDeferredLocks = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CACHE_QUERY_FORCE_DEFERRED_LOCKS, m, session);
        if ((queryCacheForceDeferredLocks != null) && queryCacheForceDeferredLocks.equalsIgnoreCase("true")) {
            session.getProject().setQueryCacheForceDeferredLocks(true);
        } else {
            session.getProject().setQueryCacheForceDeferredLocks(false);
        }

        Map typeMap = PropertiesHandler.getPrefixValuesLogDebug(PersistenceUnitProperties.CACHE_TYPE_, m, session);
        Map sizeMap = PropertiesHandler.getPrefixValuesLogDebug(PersistenceUnitProperties.CACHE_SIZE_, m, session);
        Map sharedMap = PropertiesHandler.getPrefixValuesLogDebug(PersistenceUnitProperties.CACHE_SHARED_, m, session);
        if(typeMap.isEmpty() && sizeMap.isEmpty() && sharedMap.isEmpty()) {
            return;
        }

        String defaultTypeName = (String)typeMap.remove(PersistenceUnitProperties.DEFAULT);
        if (defaultTypeName != null) {
            // Always use the EclipseLink class loader, otherwise can have loader/redeployment issues.
            Class defaultType = findClassForProperty(defaultTypeName, PersistenceUnitProperties.CACHE_TYPE_DEFAULT, getClass().getClassLoader());
            session.getProject().setDefaultIdentityMapClass(defaultType);
        }

        String value = null;
        try {
            String defaultSizeString = (String)sizeMap.remove(PersistenceUnitProperties.DEFAULT);
            if (defaultSizeString != null) {
                value = defaultSizeString;
                int defaultSize = Integer.parseInt(defaultSizeString);
                session.getProject().setDefaultIdentityMapSize(defaultSize);
            }

            String defaultSharedString = (String)sharedMap.remove(PersistenceUnitProperties.DEFAULT);
            if (defaultSharedString != null) {
                boolean defaultShared = Boolean.parseBoolean(defaultSharedString);
                session.getProject().setDefaultCacheIsolation(defaultShared
                        ? CacheIsolationType.SHARED : CacheIsolationType.ISOLATED);
            }

            Iterator<ClassDescriptor> it = session.getDescriptors().values().iterator();
            while (it.hasNext() && (!typeMap.isEmpty() || !sizeMap.isEmpty() || !sharedMap.isEmpty())) {
                ClassDescriptor descriptor = it.next();

                if (descriptor.isDescriptorTypeAggregate()) {
                    continue;
                }

                String entityName = descriptor.getAlias();
                String className = descriptor.getJavaClass().getName();
                String name;

                name = entityName;
                String typeName = (String)typeMap.remove(name);
                if( typeName == null) {
                    name = className;
                    typeName = (String)typeMap.remove(name);
                }
                if (typeName != null) {
                    Class type = findClassForProperty(typeName, PersistenceUnitProperties.CACHE_TYPE_ + name, getClass().getClassLoader());
                    descriptor.setIdentityMapClass(type);
                }

                name = entityName;
                String sizeString = (String)sizeMap.remove(name);
                if (sizeString == null) {
                    name = className;
                    sizeString = (String)sizeMap.remove(name);
                }
                if (sizeString != null) {
                    value = sizeString;
                    int size = Integer.parseInt(sizeString);
                    descriptor.setIdentityMapSize(size);
                }

                name = entityName;
                String sharedString = (String)sharedMap.remove(name);
                if (sharedString == null) {
                    name = className;
                    sharedString = (String)sharedMap.remove(name);
                }
                if (sharedString != null) {
                    boolean shared = Boolean.parseBoolean(sharedString);
                    descriptor.setCacheIsolation(shared ? CacheIsolationType.SHARED : CacheIsolationType.ISOLATED);
                }
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(value, PersistenceUnitProperties.CACHE_SIZE_, exception));
        }
    }

    /**
     * Process all properties under "eclipselink.connection-pool.".
     * This allows for named connection pools.
     * It also processes "read", "write", "default"  and "sequence" connection pools.
     */
    protected void updateConnectionSettings(ServerSession serverSession, Map properties) {
        Map<String, Object> connectionsMap = PropertiesHandler.getPrefixValuesLogDebug(PersistenceUnitProperties.CONNECTION_POOL, properties, serverSession);
        if (connectionsMap.isEmpty()) {
            return;
        }
        for (Map.Entry<String, Object> entry : connectionsMap.entrySet()) {
            String poolName = "default";
            String attribute = null;
            try {
                int dotIdx = entry.getKey().indexOf('.');
                if (dotIdx == -1) {
                    attribute = entry.getKey();
                } else {
                    String key = entry.getKey();
                    poolName = key.substring(0, dotIdx);
                    attribute = key.substring(dotIdx + 1);
                }
                ConnectionPool pool = null;
                if (poolName.equals("write")) {
                    poolName = "default";
                }
                if (poolName.equals("read")) {
                    pool = serverSession.getReadConnectionPool();
                    // By default there is no connection pool, so if the default, create a new one.
                    if ((pool == null) || (pool == serverSession.getDefaultConnectionPool())) {
                        if (this.session.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
                            pool = new ExternalConnectionPool(poolName, serverSession.getDatasourceLogin(), serverSession);
                        } else {
                            pool = new ConnectionPool(poolName, serverSession.getDatasourceLogin(), serverSession);
                        }
                        serverSession.setReadConnectionPool(pool);
                    }
                } else if (poolName.equals("sequence")) {
                    pool = getDatabaseSession().getSequencingControl().getConnectionPool();
                    if (pool == null) {
                        if (this.session.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
                            pool = new ExternalConnectionPool(poolName, serverSession.getDatasourceLogin(), serverSession);
                        } else {
                            pool = new ConnectionPool(poolName, serverSession.getDatasourceLogin(), serverSession);
                        }
                        getDatabaseSession().getSequencingControl().setConnectionPool(pool);
                    }
                } else {
                    pool = serverSession.getConnectionPool(poolName);
                    if (pool == null) {
                        if (this.session.getDatasourceLogin().shouldUseExternalConnectionPooling()) {
                            pool = new ExternalConnectionPool(poolName, serverSession.getDatasourceLogin(), serverSession);
                        } else {
                            pool = new ConnectionPool(poolName, serverSession.getDatasourceLogin(), serverSession);
                        }
                        serverSession.addConnectionPool(pool);
                    }
                }
                if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_INITIAL)) {
                    pool.setInitialNumberOfConnections(Integer.parseInt((String)entry.getValue()));
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_MIN)) {
                    pool.setMinNumberOfConnections(Integer.parseInt((String)entry.getValue()));
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_MAX)) {
                    pool.setMaxNumberOfConnections(Integer.parseInt((String)entry.getValue()));
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_URL)) {
                    pool.setLogin(pool.getLogin().clone());
                    ((DatabaseLogin)pool.getLogin()).setURL((String)entry.getValue());
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_NON_JTA_DATA_SOURCE)) {
                    pool.setLogin(pool.getLogin().clone());
                    ((DatabaseLogin)pool.getLogin()).useDataSource((String)entry.getValue());
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_JTA_DATA_SOURCE)) {
                    pool.setLogin(pool.getLogin().clone());
                    ((DatabaseLogin)pool.getLogin()).useDataSource((String)entry.getValue());
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_USER)) {
                    pool.setLogin(pool.getLogin().clone());
                    pool.getLogin().setUserName((String)entry.getValue());
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_PASSWORD)) {
                    pool.setLogin(pool.getLogin().clone());
                    pool.getLogin().setPassword((String)entry.getValue());
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_WAIT)) {
                    pool.setWaitTimeout(Integer.parseInt((String)entry.getValue()));
                } else if (attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_FAILOVER)) {
                    String failoverPools = (String)entry.getValue();
                    if ((failoverPools.indexOf(',') != -1) || (failoverPools.indexOf(' ') != -1)) {
                        StringTokenizer tokenizer = new StringTokenizer(failoverPools, " ,");
                        while (tokenizer.hasMoreTokens()) {
                            pool.addFailoverConnectionPool(tokenizer.nextToken());
                        }
                    } else {
                        pool.addFailoverConnectionPool((String)entry.getValue());
                    }
                } else if (poolName.equals("read") && attribute.equals(PersistenceUnitProperties.CONNECTION_POOL_SHARED)) {
                    boolean shared = Boolean.parseBoolean((String)entry.getValue());
                    if (shared) {
                        ReadConnectionPool readPool = new ReadConnectionPool(poolName, serverSession.getDatasourceLogin(), serverSession);
                        readPool.setInitialNumberOfConnections(pool.getInitialNumberOfConnections());
                        readPool.setMinNumberOfConnections(pool.getMinNumberOfConnections());
                        readPool.setMaxNumberOfConnections(pool.getMaxNumberOfConnections());
                        readPool.setWaitTimeout(pool.getWaitTimeout());
                        readPool.setLogin(pool.getLogin());
                        serverSession.setReadConnectionPool(readPool);
                    }
                }
            } catch (RuntimeException exception) {
                this.session.handleException(ValidationException.invalidValueForProperty(entry.getValue(), entry.getKey(), exception));
            }
        }
    }

    protected void updateConnectionPolicy(ServerSession serverSession, Map m) {
        String isLazyString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.EXCLUSIVE_CONNECTION_IS_LAZY, m, session);
        if(isLazyString != null) {
            serverSession.getDefaultConnectionPolicy().setIsLazy(Boolean.parseBoolean(isLazyString));
        }
        ConnectionPolicy.ExclusiveMode exclusiveMode = getConnectionPolicyExclusiveModeFromProperties(m, session, true);
        if(exclusiveMode != null) {
            serverSession.getDefaultConnectionPolicy().setExclusiveMode(exclusiveMode);
        }
    }

    public static ConnectionPolicy.ExclusiveMode getConnectionPolicyExclusiveModeFromProperties(Map m, AbstractSession abstractSession, boolean useSystemAsDefault) {
        String exclusiveConnectionModeString = PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.EXCLUSIVE_CONNECTION_MODE, m, abstractSession, useSystemAsDefault);
        if(exclusiveConnectionModeString != null) {
            if(exclusiveConnectionModeString == ExclusiveConnectionMode.Isolated) {
                return ConnectionPolicy.ExclusiveMode.Isolated;
            } else if(exclusiveConnectionModeString == ExclusiveConnectionMode.Always) {
                return ConnectionPolicy.ExclusiveMode.Always;
            } else {
                return ConnectionPolicy.ExclusiveMode.Transactional;
            }
        } else {
            return null;
        }
    }

    /**
     * Perform any steps necessary prior to actual deployment.  This includes any steps in the session
     * creation that do not require the real loaded domain classes.
     *
     * The first call to this method caches persistenceUnitInfo which is reused in the following calls.
     *
     * Note that in JSE case factoryCount is NOT incremented on the very first call
     * (by JavaSECMPInitializer.callPredeploy, typically in preMain).
     * That provides 1 to 1 correspondence between factoryCount and the number of open factories.
     *
     * In case factoryCount &gt; 0 the method just increments factoryCount.
     * factory == 0 triggers creation of a new session.
     *
     * This method and undeploy - the only methods altering factoryCount - should be synchronized.
     *
     * @return A transformer (which may be null) that should be plugged into the proper
     *         classloader to allow classes to be transformed as they get loaded.
     * @see #deploy(ClassLoader, Map)
     */
    public synchronized ClassTransformer predeploy(PersistenceUnitInfo info, Map extendedProperties) {
        ClassLoader classLoaderToUse = null;
        // session == null
        if (state == STATE_DEPLOY_FAILED || state == STATE_UNDEPLOYED) {
            throw new PersistenceException(EntityManagerSetupException.cannotPredeploy(persistenceUnitInfo.getPersistenceUnitName(), state, persistenceException));
        }
        // session != null
        if (state == STATE_PREDEPLOYED || state == STATE_DEPLOYED || state == STATE_HALF_DEPLOYED) {
            session.log(SessionLog.FINEST, SessionLog.JPA, "predeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state, factoryCount});
            factoryCount++;
            session.log(SessionLog.FINEST, SessionLog.JPA, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state, factoryCount});
            return null;
        // session == null
        } else if (state == STATE_INITIAL) {
            persistenceUnitInfo = info;
            if (!isCompositeMember()) {
                if (mustBeCompositeMember(persistenceUnitInfo)) {
                    if (this.staticWeaveInfo == null) {
                        return null;
                    } else {
                        // predeploy is used for static weaving
                        throw new PersistenceException(EntityManagerSetupException.compositeMemberCannotBeUsedStandalone(persistenceUnitInfo.getPersistenceUnitName()));
                    }
                }
            }
        }

        // state is INITIAL or PREDEPLOY_FAILED or STATE_HALF_PREDEPLOYED_COMPOSITE_MEMBER, session == null
        try {
            // properties not used in STATE_HALF_PREDEPLOYED_COMPOSITE_MEMBER
            Map predeployProperties = null;
            // composite can't be in STATE_HALF_PREDEPLOYED_COMPOSITE_MEMBER
            boolean isComposite = false;
            if(state != STATE_HALF_PREDEPLOYED_COMPOSITE_MEMBER) {
                //set the claasloader early on and change it if needed
                classLoaderToUse = persistenceUnitInfo.getClassLoader();

                predeployProperties = mergeMaps(extendedProperties, persistenceUnitInfo.getProperties());
                // Translate old properties.
                // This should be done before using properties (i.e. ServerPlatform).
                translateOldProperties(predeployProperties, null);

                String sessionsXMLStr = (String)predeployProperties.get(PersistenceUnitProperties.SESSIONS_XML);
                if (sessionsXMLStr != null) {
                    isSessionLoadedFromSessionsXML = true;
                }

                // Create session (it needs to be done before initializing ServerPlatform and logging).
                // If a sessions-xml is used this will get replaced later, but is required for logging.
                isComposite = isComposite(persistenceUnitInfo);
                if (isComposite) {
                    if (isSessionLoadedFromSessionsXML) {
                        throw EntityManagerSetupException.compositeIncompatibleWithSessionsXml(persistenceUnitInfo.getPersistenceUnitName());
                    }
                    session = new SessionBroker();
                    ((SessionBroker)session).setShouldUseDescriptorAliases(true);
                } else {
                    session = new ServerSession(new Project(new DatabaseLogin()));

                    //set the listener to process RCM metadata refresh commands
                    session.setRefreshMetadataListener(this);
                }
                session.setName(this.sessionName);
                updateTunerPreDeploy(predeployProperties, classLoaderToUse);
                updateTolerateInvalidJPQL(predeployProperties);

                if (this.compositeEmSetupImpl == null) {
                    // session name and ServerPlatform must be set prior to setting the loggers.
                    if (this.staticWeaveInfo == null) {
                        updateServerPlatform(predeployProperties, classLoaderToUse);
                        // Update loggers and settings for the singleton logger and the session logger.
                        updateLoggers(predeployProperties, true, classLoaderToUse);
                        // log the server platform being used by the session
                        if (session.getSessionLog().shouldLog(SessionLog.FINE)) {
                            session.getSessionLog().log(SessionLog.FINE, SessionLog.SERVER,
                                    "configured_server_platform", session.getServerPlatform().getClass().getName()); // NOI18N
                        }
                        // Get the temporary classLoader based on the platform

                        //Update performance profiler
                        updateProfiler(predeployProperties, classLoaderToUse);
                    } else {
                        // predeploy is used for static weaving
                        Writer writer = this.staticWeaveInfo.getLogWriter();
                        if (writer != null) {
                            session.getSessionLog().setWriter(writer);
                        }
                        session.setLogLevel(this.staticWeaveInfo.getLogLevel());
                    }
                } else {
                    // composite member
                    session.setSessionLog(this.compositeEmSetupImpl.session.getSessionLog());
                    session.setProfiler(this.compositeEmSetupImpl.session.getProfiler());
                }

                // Cannot start logging until session and log and initialized, so log start of predeploy here.
                session.log(SessionLog.FINEST, SessionLog.JPA, "predeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state, factoryCount});

                //Project Cache accessor processing
                updateProjectCache(predeployProperties, classLoaderToUse);

                if (projectCacheAccessor!=null) {
                    //get the project from the cache
                    Project project = projectCacheAccessor.retrieveProject(predeployProperties, classLoaderToUse, session.getSessionLog());

                    if (project!=null) {
                        try {
                            DatabaseSessionImpl tempSession = (DatabaseSessionImpl)project.createServerSession();

                            tempSession.setName(this.sessionName);
                            tempSession.setSessionLog(session.getSessionLog());
                            tempSession.getSessionLog().setSession(tempSession);
                            if (this.staticWeaveInfo != null) {
                                tempSession.setLogLevel(this.staticWeaveInfo.getLogLevel());
                            }
                            tempSession.setProfiler(session.getProfiler());
                            tempSession.setRefreshMetadataListener(this);

                            session = tempSession;
                            // reusing the serverPlatform from the existing session would have been preferred,
                            //  but its session is only set through the ServerPlatform constructor.
                            updateServerPlatform(predeployProperties, classLoaderToUse);
                            shouldBuildProject = false;
                        } catch (Exception e) {
                            //need a better exception here
                            throw new PersistenceException(e);
                        }
                    }
                }

                if (isSessionLoadedFromSessionsXML) {
                    if (this.compositeEmSetupImpl == null && this.staticWeaveInfo == null) {
                        JPAClassLoaderHolder privateClassLoaderHolder = session.getServerPlatform().getNewTempClassLoader(persistenceUnitInfo);
                        classLoaderToUse = privateClassLoaderHolder.getClassLoader();
                    } else {
                        classLoaderToUse = persistenceUnitInfo.getNewTempClassLoader();
                    }
                    // Loading session from sessions-xml.
                    String tempSessionName = sessionName;
                    if (isCompositeMember()) {
                        // composite member session name is always the same as puName
                        // need the session name specified in properties to read correct session from sessions.xml
                        tempSessionName = (String)predeployProperties.get(PersistenceUnitProperties.SESSION_NAME);
                    }
                    session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "loading_session_xml", sessionsXMLStr, tempSessionName);
                    if (tempSessionName == null) {
                        throw EntityManagerSetupException.sessionNameNeedBeSpecified(persistenceUnitInfo.getPersistenceUnitName(), sessionsXMLStr);
                    }
                    XMLSessionConfigLoader xmlLoader = new XMLSessionConfigLoader(sessionsXMLStr);
                    // Do not register the session with the SessionManager at this point, create temporary session using a local SessionManager and private class loader.
                    // This allows for the project to be accessed without loading any of the classes to allow weaving.
                    // Note that this method assigns sessionName to session.
                    Session tempSession = new SessionManager().getSession(xmlLoader, tempSessionName, classLoaderToUse, false, false);
                    // Load path of sessions-xml resource before throwing error so user knows which sessions-xml file was found (may be multiple).
                    session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "sessions_xml_path_where_session_load_from", xmlLoader.getSessionName(), xmlLoader.getResourcePath());
                    if (tempSession == null) {
                        throw ValidationException.noSessionFound(sessionName, sessionsXMLStr);
                    }
                    // Currently the session must be either a ServerSession or a SessionBroker, cannot be just a DatabaseSessionImpl.
                    if (tempSession.isServerSession() || tempSession.isSessionBroker()) {
                       session = (DatabaseSessionImpl) tempSession;
                       if (tempSessionName != sessionName) {
                           // set back the original session name
                           session.setName(sessionName);
                       }
                    } else {
                        throw EntityManagerSetupException.sessionLoadedFromSessionsXMLMustBeServerSession(persistenceUnitInfo.getPersistenceUnitName(), (String)predeployProperties.get(PersistenceUnitProperties.SESSIONS_XML), tempSession);
                    }
                    if (this.staticWeaveInfo == null) {
                        // Must now reset logging and server-platform on the loaded session.
                        // ServerPlatform must be set prior to setting the loggers.
                        updateServerPlatform(predeployProperties, classLoaderToUse);
                        // Update loggers and settings for the singleton logger and the session logger.
                        updateLoggers(predeployProperties, true, classLoaderToUse);
                    }
                } else {
                    classLoaderToUse = persistenceUnitInfo.getClassLoader();
                }

                warnOldProperties(predeployProperties, session);
                session.getPlatform().setConversionManager(new JPAConversionManager());

                if (this.staticWeaveInfo == null) {
                    if (!isComposite) {
                        PersistenceUnitTransactionType transactionType=null;
                        //bug 5867753: find and override the transaction type
                        String transTypeString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.TRANSACTION_TYPE, predeployProperties, session);
                        if (transTypeString != null && transTypeString.length() > 0) {
                            transactionType=PersistenceUnitTransactionType.valueOf(transTypeString);
                        } else if (persistenceUnitInfo!=null){
                            transactionType=persistenceUnitInfo.getTransactionType();
                        }

                        if (!isValidationOnly(predeployProperties, false) && persistenceUnitInfo != null && transactionType == PersistenceUnitTransactionType.JTA) {
                            if (predeployProperties.get(PersistenceUnitProperties.JTA_DATASOURCE) == null && persistenceUnitInfo.getJtaDataSource() == null) {
                                if (predeployProperties.get(PersistenceUnitProperties.SCHEMA_DATABASE_PRODUCT_NAME) == null ||
                                        predeployProperties.get(PersistenceUnitProperties.SCHEMA_DATABASE_MAJOR_VERSION) == null ||
                                        predeployProperties.get(PersistenceUnitProperties.SCHEMA_DATABASE_MINOR_VERSION) == null) {
                                    throw EntityManagerSetupException.jtaPersistenceUnitInfoMissingJtaDataSource(persistenceUnitInfo.getPersistenceUnitName());
                                }
                            }
                        }
                    }

                    // this flag is used to disable work done as a result of the LAZY hint on OneToOne and ManyToOne mappings
                    if(state == STATE_INITIAL) {
                        if (compositeEmSetupImpl == null) {
                            if(null == enableWeaving) {
                                enableWeaving = Boolean.TRUE;
                            }
                            isWeavingStatic = false;
                            String weaving = getConfigPropertyAsString(PersistenceUnitProperties.WEAVING, predeployProperties);

                            if (weaving != null && weaving.equalsIgnoreCase("false")) {
                                enableWeaving = Boolean.FALSE;
                            }else if (weaving != null && weaving.equalsIgnoreCase("static")) {
                                isWeavingStatic = true;
                            }
                        } else {
                            // composite member
                            // no weaving for composite forces no weaving for members
                            if (!compositeEmSetupImpl.enableWeaving) {
                                enableWeaving = Boolean.FALSE;
                            } else {
                                if(null == enableWeaving) {
                                    enableWeaving = Boolean.TRUE;
                                }
                                String weaving = getConfigPropertyAsString(PersistenceUnitProperties.WEAVING, predeployProperties);
                                if (weaving != null && weaving.equalsIgnoreCase("false")) {
                                    enableWeaving = Boolean.FALSE;
                                }
                            }
                            // static weaving is dictated by composite
                            isWeavingStatic = compositeEmSetupImpl.isWeavingStatic;
                        }
                    }

                    if (compositeEmSetupImpl == null) {
                        throwExceptionOnFail = "true".equalsIgnoreCase(
                                EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.THROW_EXCEPTIONS, predeployProperties, "true", session));
                    } else {
                        // composite member
                        throwExceptionOnFail = compositeEmSetupImpl.throwExceptionOnFail;
                    }
                } else {
                    // predeploy is used for static weaving
                    enableWeaving = Boolean.TRUE;
                }

                weaveChangeTracking = false;
                weaveLazy = false;
                weaveEager = false;
                weaveFetchGroups = false;
                weaveInternal = false;
                weaveRest = false;
                weaveMappedSuperClass = false;
                if (enableWeaving) {
                    weaveChangeTracking = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.WEAVING_CHANGE_TRACKING, predeployProperties, "true", session));
                    weaveLazy = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.WEAVING_LAZY, predeployProperties, "true", session));
                    weaveEager = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.WEAVING_EAGER, predeployProperties, "false", session));
                    weaveFetchGroups = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.WEAVING_FETCHGROUPS, predeployProperties, "true", session));
                    weaveInternal = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.WEAVING_INTERNAL, predeployProperties, "true", session));
                    weaveRest = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.WEAVING_REST, predeployProperties, shouldWeaveRestByDefault(classLoaderToUse), session));
                    weaveMappedSuperClass = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.WEAVING_MAPPEDSUPERCLASS, predeployProperties, "true", session));
                }

            }
            if (shouldBuildProject && !isSessionLoadedFromSessionsXML ) {
                if (isComposite) {
                    predeployCompositeMembers(predeployProperties, classLoaderToUse);
                } else {
                    MetadataProcessor compositeProcessor = null;
                    if (compositeEmSetupImpl == null) {
                        mode = PersistenceUnitProcessor.Mode.ALL;
                    } else {
                        // composite member
                        if (state != STATE_HALF_PREDEPLOYED_COMPOSITE_MEMBER) {
                            state = STATE_HALF_PREDEPLOYED_COMPOSITE_MEMBER;
                            mode = PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_INITIAL;
                        }
                        compositeProcessor = compositeEmSetupImpl.processor;
                    }

                    if (mode == PersistenceUnitProcessor.Mode.ALL || mode == PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_INITIAL) {
                        boolean usesMultitenantSharedEmf = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.MULTITENANT_SHARED_EMF, predeployProperties, "true", session));
                        boolean usesMultitenantSharedCache = "true".equalsIgnoreCase(EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.MULTITENANT_SHARED_CACHE, predeployProperties, "false", session));

                        // Create an instance of MetadataProcessor for specified persistence unit info
                        processor = new MetadataProcessor(persistenceUnitInfo, session, classLoaderToUse, weaveLazy, weaveEager, weaveFetchGroups, usesMultitenantSharedEmf, usesMultitenantSharedCache, predeployProperties, compositeProcessor);

                        //need to use the real classloader to create the repository class
                        updateMetadataRepository(predeployProperties, classLoaderToUse);

                        //bug:299926 - Case insensitive table / column matching with native SQL queries
                        EntityManagerSetupImpl.updateCaseSensitivitySettings(predeployProperties, processor.getProject(), session);
                    }

                    // Set the shared cache mode to the jakarta.persistence.sharedCache.mode property value.
                    updateSharedCacheMode(predeployProperties);

                    // Process the Object/relational metadata from XML and annotations.
                    // If Java Security is enabled, surround this call with a doPrivileged block.
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                        AccessController.doPrivileged(new PrivilegedAction<Void>() {
                            @Override
                            public Void run() {
                                PersistenceUnitProcessor.processORMetadata(processor, throwExceptionOnFail, mode);
                                return null;
                            }
                        });
                    } else {
                        PersistenceUnitProcessor.processORMetadata(processor, throwExceptionOnFail, mode);
                    }

                    if (mode == PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_INITIAL) {
                        mode = PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_MIDDLE;
                        session.log(SessionLog.FINEST, SessionLog.JPA, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state + " " + mode , factoryCount});
                        return null;
                    } else if (mode == PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_MIDDLE) {
                        mode = PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_FINAL;
                        session.log(SessionLog.FINEST, SessionLog.JPA, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state + " " + mode , factoryCount});
                        return null;
                    }
                    // mode == PersistenceUnitProcessor.Mode.ALL || mode == PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_FINAL
                    // clear mode and proceed
                    mode = null;

                    if (session.getIntegrityChecker().hasErrors()){
                        session.handleException(new IntegrityException(session.getIntegrityChecker()));
                    }

                    // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings.  It will only
                    // be returned if we we are mean to process these mappings
                    if (enableWeaving) {
                        // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use
                        Collection<MetadataClass> entities = PersistenceUnitProcessor.buildEntityList(processor, classLoaderToUse);
                        this.weaver = TransformerFactory.createTransformerAndModifyProject(session, entities, classLoaderToUse, weaveLazy, weaveChangeTracking, weaveFetchGroups, weaveInternal, weaveRest, weaveMappedSuperClass);
                        session.getProject().setClassNamesForWeaving(new ArrayList<>(processor.getProject().getWeavableClassNames()));
                    }

                    //moved from deployment:
                    processor.addNamedQueries();
                    processor.addStructConverterNames();
                }
            } else {
                //This means this session is from sessions.xml or a cached project

                // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings.  It will only
                // be returned if we we are meant to process these mappings.
                if (enableWeaving) {
                    Collection<MetadataClass> persistenceClasses = new ArrayList<>();
                    MetadataAsmFactory factory = new MetadataAsmFactory(new MetadataLogger(session), classLoaderToUse);
                    if (shouldBuildProject) {
                        // If deploying from a sessions-xml it is still desirable to allow the classes to be weaved.
                        // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use
                        for (Iterator<Class<?>> iterator = session.getProject().getDescriptors().keySet().iterator(); iterator.hasNext(); ) {
                            persistenceClasses.add(factory.getMetadataClass(iterator.next().getName()));
                        }
                    } else {
                        // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use
                        for (String className : session.getProject().getClassNamesForWeaving()) {
                            persistenceClasses.add(factory.getMetadataClass(className));
                        }
                    }
                    this.weaver = TransformerFactory.createTransformerAndModifyProject(session, persistenceClasses, classLoaderToUse, weaveLazy, weaveChangeTracking, weaveFetchGroups, weaveInternal, weaveRest, weaveMappedSuperClass);
                }
            }

            // composite member never has a factory - it is predeployed by the composite.
            if (!isCompositeMember()) {
                // factoryCount is not incremented only in case of a first call to preDeploy
                // in non-container mode: this call is not associated with a factory
                // but rather done by JavaSECMPInitializer.callPredeploy (typically in preMain).
                if(state != STATE_INITIAL || this.isInContainerMode()) {
                    factoryCount++;
                }
                preInitializeMetamodel();
            }

            state = STATE_PREDEPLOYED;
            session.log(SessionLog.FINEST, SessionLog.JPA, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state, factoryCount});
            //gf3146: if static weaving is used, we should not return a transformer.  Transformer should still be created though as it modifies descriptors
            if (isWeavingStatic) {
                return null;
            } else {
                return this.weaver;
            }
        } catch (Throwable ex) {
            state = STATE_PREDEPLOY_FAILED;
            // cache this.persistenceException before slow logging
            PersistenceException persistenceEx = createPredeployFailedPersistenceException(ex);
            // If session exists, use it for logging
            if (session != null) {
                session.log(SessionLog.FINEST, SessionLog.JPA, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state, factoryCount});
            // If at least staticWeaveInfo exists, use it for logging
            } else if (staticWeaveInfo != null && staticWeaveInfo.getLogLevel() <= SessionLog.FINEST) {
                Writer logWriter = staticWeaveInfo.getLogWriter();
                if (logWriter != null) {
                    String message = LoggingLocalization.buildMessage("predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), "N/A", state, factoryCount});
                    try {
                        logWriter.write(message);
                        logWriter.write(Helper.cr());
                    } catch (IOException ioex) {
                        // Ignore IOException
                    }
                }
            }
            session = null;
            mode = null;
            throw persistenceEx;
        }
    }

    protected PersistenceException createPredeployFailedPersistenceException(Throwable ex) {
        PersistenceException perEx = new PersistenceException(EntityManagerSetupException.predeployFailed(persistenceUnitInfo.getPersistenceUnitName(), ex));
        if (persistenceException == null) {
            persistenceException = perEx;
        }
        return perEx;
    }

    /**
     * Return the name of the session this SetupImpl is building. The session name is only known at deploy
     * time and if this method is called prior to that, this method will return null.
     */
    public String getDeployedSessionName(){
        return session != null ? session.getName() : null;
    }

    public PersistenceUnitInfo getPersistenceUnitInfo(){
        return persistenceUnitInfo;
    }

    public boolean isValidationOnly(Map m) {
        return isValidationOnly(m, true);
    }

    protected boolean isValidationOnly(Map m, boolean shouldMergeMap) {
        if (shouldMergeMap) {
            m = mergeWithExistingMap(m);
        }
        String validationOnlyString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.VALIDATION_ONLY_PROPERTY, m, session);
        if (validationOnlyString != null) {
            return Boolean.parseBoolean(validationOnlyString);
        } else {
            return false;
        }
    }

    /**
     * Return if the session should be deployed and connected during the creation of the EntityManagerFactory,
     * or if it should be deferred until createEntityManager().
     * The default is to defer, but is only validating, or can be configured to deploy upfront to avoid hanging the
     * application at runtime.
     */
    public boolean shouldGetSessionOnCreateFactory(Map m) {
        m = mergeWithExistingMap(m);
        if (isValidationOnly(m, false)) {
            return true;
        }

        String deployString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.DEPLOY_ON_STARTUP, m, this.session);
        if (deployString != null) {
            return Boolean.parseBoolean(deployString);
        } else {
            // If DDL schame generation is turned on, we need to deploy.
            return hasSchemaDatabaseGeneration(m) || hasSchemaScriptsGeneration(m);
        }
    }

    protected Map mergeWithExistingMap(Map m) {
        if(persistenceUnitInfo != null) {
            return mergeMaps(m, persistenceUnitInfo.getProperties());
        } else {
            return m;
        }
    }

    public boolean isInContainerMode(){
        return isInContainerMode;
    }

    /**
     * Configure cache coordination using properties.
     */
    protected void updateCacheCoordination(Map m, ClassLoader loader) {
        String protocol = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_PROTOCOL, m, this.session);
        String value = "";
        String property = "";
        try {
            if (protocol != null) {
                RemoteCommandManager rcm = new RemoteCommandManager(this.session);
                if (protocol.equalsIgnoreCase(CacheCoordinationProtocol.JGROUPS)) {
                    property = PersistenceUnitProperties.COORDINATION_PROTOCOL;
                    value = "org.eclipse.persistence.sessions.coordination.jgroups.JGroupsTransportManager";
                    // Avoid compile and runtime dependency.
                    Class transportClass = findClassForProperty(value, PersistenceUnitProperties.COORDINATION_PROTOCOL, loader);
                    TransportManager transport = (TransportManager)transportClass.getConstructor().newInstance();
                    rcm.setTransportManager(transport);
                    String config = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_JGROUPS_CONFIG, m, this.session);
                    if (config != null) {
                        transport.setConfig(config);
                    }
                } else if (protocol.equalsIgnoreCase(CacheCoordinationProtocol.JMS) || protocol.equalsIgnoreCase(CacheCoordinationProtocol.JMSPublishing)) {
                    JMSPublishingTransportManager transport = null;
                    if (protocol.equalsIgnoreCase(CacheCoordinationProtocol.JMS)) {
                         transport = new JMSTopicTransportManager(rcm);
                    } else {
                        transport = new JMSPublishingTransportManager(rcm);
                    }
                    rcm.setTransportManager(transport);

                    String host = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_JMS_HOST, m, this.session);
                    if (host != null) {
                        transport.setTopicHostUrl(host);
                    }
                    String topic = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_JMS_TOPIC, m, this.session);
                    if (topic != null) {
                        transport.setTopicName(topic);
                    }
                    String factory = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_JMS_FACTORY, m, this.session);
                    if (factory != null) {
                        transport.setTopicConnectionFactoryName(factory);
                    }

                    String reuse_publisher = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_JMS_REUSE_PUBLISHER, m, this.session);
                    if (reuse_publisher != null) {
                        transport.setShouldReuseJMSTopicPublisher(reuse_publisher.equalsIgnoreCase("true"));
                    }

                } else if (protocol.equalsIgnoreCase(CacheCoordinationProtocol.RMI) || protocol.equalsIgnoreCase(CacheCoordinationProtocol.RMIIIOP)) {
                    if (protocol.equalsIgnoreCase(CacheCoordinationProtocol.RMIIIOP)) {
                        ((RMITransportManager) rcm.getTransportManager()).setIsRMIOverIIOP(true);
                    }
                    // Default protocol.
                    String delay = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_RMI_ANNOUNCEMENT_DELAY, m, this.session);
                    property = PersistenceUnitProperties.COORDINATION_RMI_ANNOUNCEMENT_DELAY;
                    value = delay;
                    if (delay != null) {
                        rcm.getDiscoveryManager().setAnnouncementDelay(Integer.parseInt(delay));
                    }
                    String multicast = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_RMI_MULTICAST_GROUP, m, this.session);
                    if (multicast != null) {
                        rcm.getDiscoveryManager().setMulticastGroupAddress(multicast);
                    }
                    String port = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_RMI_MULTICAST_GROUP_PORT, m, this.session);
                    property = PersistenceUnitProperties.COORDINATION_RMI_MULTICAST_GROUP_PORT;
                    value = port;
                    if (port != null) {
                        rcm.getDiscoveryManager().setMulticastPort(Integer.parseInt(port));
                    }
                    String timeToLive = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_RMI_PACKET_TIME_TO_LIVE, m, this.session);
                    property = PersistenceUnitProperties.COORDINATION_RMI_PACKET_TIME_TO_LIVE;
                    value = timeToLive;
                    if (timeToLive != null) {
                        rcm.getDiscoveryManager().setPacketTimeToLive(Integer.parseInt(timeToLive));
                    }
                    String url = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_RMI_URL, m, this.session);
                    if (url != null) {
                        rcm.setUrl(url);
                    }
                } else {
                    property = PersistenceUnitProperties.COORDINATION_PROTOCOL;
                    value = protocol;
                    Class transportClass = findClassForProperty(protocol, PersistenceUnitProperties.COORDINATION_PROTOCOL, loader);
                    rcm.setTransportManager((TransportManager)transportClass.getConstructor().newInstance());
                }
                String serializer = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_SERIALIZER, m, this.session);
                if (serializer != null) {
                    property = PersistenceUnitProperties.COORDINATION_SERIALIZER;
                    value = serializer;
                    Class transportClass = findClassForProperty(serializer, PersistenceUnitProperties.COORDINATION_SERIALIZER, loader);
                    rcm.setSerializer((Serializer)transportClass.getConstructor().newInstance());
                }

                String naming = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_NAMING_SERVICE, m, this.session);
                if (naming != null) {
                    if (naming.equalsIgnoreCase("jndi")) {
                        rcm.getTransportManager().setNamingServiceType(TransportManager.JNDI_NAMING_SERVICE);
                    } else if (naming.equalsIgnoreCase("rmi")) {
                        rcm.getTransportManager().setNamingServiceType(TransportManager.REGISTRY_NAMING_SERVICE);
                    }
                }
                String user = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_JNDI_USER, m, this.session);
                if (user != null) {
                    rcm.getTransportManager().setUserName(user);
                }
                String password = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_JNDI_PASSWORD, m, this.session);
                if (password != null) {
                    rcm.getTransportManager().setPassword(password);
                }
                String context = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_JNDI_CONTEXT, m, this.session);
                if (context != null) {
                    rcm.getTransportManager().setInitialContextFactoryName(context);
                }
                String removeOnError = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_REMOVE_CONNECTION, m, this.session);
                if (removeOnError != null) {
                    rcm.getTransportManager().setShouldRemoveConnectionOnError(removeOnError.equalsIgnoreCase("true"));
                }
                String asynch = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_ASYNCH, m, this.session);
                if (asynch != null) {
                    rcm.setShouldPropagateAsynchronously(asynch.equalsIgnoreCase("true"));
                }
                String threadPoolSize = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_THREAD_POOL_SIZE, m, this.session);
                property = PersistenceUnitProperties.COORDINATION_THREAD_POOL_SIZE;
                value = threadPoolSize;
                if (threadPoolSize != null) {
                    this.session.getServerPlatform().setThreadPoolSize(Integer.parseInt(threadPoolSize));
                }
                String channel = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.COORDINATION_CHANNEL, m, this.session);
                if (channel != null) {
                    rcm.setChannel(channel);
                }
                this.session.setCommandManager(rcm);
                this.session.setShouldPropagateChanges(true);
            }
        } catch (ReflectiveOperationException | NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(value, property, exception));
        }
    }

    /**
     * Update session serializer.
     */
    protected void updateSerializer(Map m, ClassLoader loader) {
        String serializer = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.SERIALIZER, m, this.session);
        if (serializer != null) {
            if (serializer.length() > 0) {
                try {
                    Class transportClass = findClassForProperty(serializer, PersistenceUnitProperties.SERIALIZER, loader);
                    this.session.setSerializer((Serializer)transportClass.getConstructor().newInstance());
                } catch (Exception exception) {
                    this.session.handleException(ValidationException.invalidValueForProperty(serializer, PersistenceUnitProperties.SERIALIZER, exception));
                }
            } else {
                this.session.setSerializer(JavaSerializer.instance);
            }
        }
    }

    /**
     * Update whether session ShouldOptimizeResultSetAccess.
     */
    protected void updateShouldOptimizeResultSetAccess(Map m) {
       String resultSetAccessOptimization = PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.JDBC_RESULT_SET_ACCESS_OPTIMIZATION, m, this.session);
       if (resultSetAccessOptimization != null) {
          this.session.setShouldOptimizeResultSetAccess(resultSetAccessOptimization.equals("true"));
       }
    }

    /**
     * Update whether session should use externally defined multi tenancy.
     */
    protected void updateTenancy(Map m, ClassLoader loader) {
        String tenantStrategy = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.MULTITENANT_STRATEGY, m, this.session);
        if(tenantStrategy != null) {
            if ("external".equalsIgnoreCase(tenantStrategy)) {
                SchemaPerMultitenantPolicy policy = new SchemaPerMultitenantPolicy();
                String prop = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.MULTITENANT_SHARED_EMF, m, session);
                if (prop != null) {
                    policy.setShouldUseSharedEMF(Boolean.parseBoolean(prop));
                }
                prop = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.MULTITENANT_SHARED_CACHE, m, session);
                if (prop != null) {
                    policy.setShouldUseSharedCache(Boolean.parseBoolean(prop));
                }
                session.getProject().setMultitenantPolicy(policy);
            } else {
                //assume it is a class with default constructor implementing existing interface
                Class cls = findClassForProperty(tenantStrategy, PersistenceUnitProperties.MULTITENANT_STRATEGY, loader);
                MultitenantPolicy policy = null;
                try {
                    Constructor constructor = cls.getConstructor();
                    policy = (MultitenantPolicy) constructor.newInstance();
                } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
                    throw EntityManagerSetupException.failedToInstantiateProperty(tenantStrategy, PersistenceUnitProperties.MULTITENANT_STRATEGY, ex);
                }
                session.getProject().setMultitenantPolicy(policy);
            }
        }
    }

    /**
     * Update whether session should tolerate invalid JPQL at creation time.
     */
    protected void updateTolerateInvalidJPQL(Map m) {
        String config =
            PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.JPQL_TOLERATE, m, this.session);
        // Tolerate invalid JPQL is ignored if running in validation only mode
        if (config != null && isValidationOnly(m) == false) {
            this.session.setTolerateInvalidJPQL(config.equals("true"));
        }
    }

    /**
     * Override the default login creation method.
     * If persistenceInfo is available, use the information from it to setup the login
     * and possibly to set readConnectionPool.
     */
    protected void updateLogins(Map m){
        DatasourceLogin login = (DatasourceLogin)this.session.getDatasourceLogin();

        String eclipselinkPlatform = PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.TARGET_DATABASE, m, this.session);
        if (eclipselinkPlatform != null) {
            login.setPlatformClassName(eclipselinkPlatform, this.persistenceUnitInfo.getClassLoader());
        }
        // Check for EIS platform, need to use an EIS login.
        boolean isEIS = false;
        if (login.getDatasourcePlatform() instanceof EISPlatform) {
            isEIS = true;
            EISLogin newLogin = new EISLogin();
            newLogin.setDatasourcePlatform(login.getDatasourcePlatform());
            this.session.setDatasourceLogin(newLogin);
            if (this.session.isServerSession()) {
               for (ConnectionPool pool : ((ServerSession)this.session).getConnectionPools().values()) {
                   pool.setLogin(newLogin);
               }
            }
            login = newLogin;
        }

        // Check for EIS or custom (JDBC) Connector class.
        Object connectorValue = getConfigPropertyLogDebug(PersistenceUnitProperties.NOSQL_CONNECTION_SPEC, m, this.session);
        String connectorProperty = PersistenceUnitProperties.NOSQL_CONNECTION_SPEC;
        if (connectorValue == null) {
            connectorValue = getConfigPropertyLogDebug(PersistenceUnitProperties.JDBC_CONNECTOR, m, this.session);
            connectorProperty = PersistenceUnitProperties.JDBC_CONNECTOR;
        }
        if (connectorValue instanceof Connector) {
            login.setConnector((Connector)connectorValue);
        } else if (connectorValue instanceof String) {
            Class cls = null;
            // Try both class loaders.
            try {
                cls = findClassForProperty((String)connectorValue, connectorProperty, this.persistenceUnitInfo.getClassLoader());
            } catch (Throwable failed) {
                cls = findClassForProperty((String)connectorValue, connectorProperty, getClass().getClassLoader());
            }
            Connector connector = null;
            try {
                Constructor constructor = cls.getConstructor();
                connector = (Connector)constructor.newInstance();
            } catch (Exception exception) {
                throw EntityManagerSetupException.failedToInstantiateProperty((String)connectorValue, connectorProperty, exception);
            }
            if (connector != null) {
                login.setConnector(connector);
            }
        } else if (connectorValue != null) {
            // Assume JCA connection spec.
            ((EISConnectionSpec)login.getConnector()).setConnectionSpecObject(connectorValue);
        }

        // Check for EIS ConnectionFactory.
        Object factoryValue = getConfigPropertyLogDebug(PersistenceUnitProperties.NOSQL_CONNECTION_FACTORY, m, this.session);
        if (factoryValue instanceof String) {
            // JNDI name.
            ((EISConnectionSpec)login.getConnector()).setName((String)factoryValue);
        } else if (factoryValue != null) {
            ((EISConnectionSpec)login.getConnector()).setConnectionFactoryObject(factoryValue);
        }

        // Process EIS or JDBC connection properties.
        Map propertiesMap = PropertiesHandler.getPrefixValuesLogDebug(PersistenceUnitProperties.NOSQL_PROPERTY, m, session);
        if (propertiesMap.isEmpty()) {
            propertiesMap = PropertiesHandler.getPrefixValuesLogDebug(PersistenceUnitProperties.JDBC_PROPERTY, m, session);
        }
        for (Iterator iterator = propertiesMap.entrySet().iterator(); iterator.hasNext(); ) {
            Map.Entry entry = (Map.Entry)iterator.next();
            String property = (String)entry.getKey();
            Object value = entry.getValue();
            login.setProperty(property, value);
        }

        // Note: This call does not checked the stored persistenceUnitInfo or extended properties because
        // the map passed into this method should represent the full set of properties we expect to process

        String user = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_USER, m, this.session);
        String password = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_PASSWORD, m, this.session);
        if(user != null) {
            login.setUserName(user);
        }
        if (password != null) {
            login.setPassword(this.securableObjectHolder.getSecurableObject().decryptPassword(password));
        }

        PersistenceUnitTransactionType transactionType = this.persistenceUnitInfo.getTransactionType();
        //bug 5867753: find and override the transaction type using properties
        String transTypeString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.TRANSACTION_TYPE, m, this.session);
        if (transTypeString != null && transTypeString.length() > 0) {
            transactionType = PersistenceUnitTransactionType.valueOf(transTypeString);
        }
        //find the jta datasource
        javax.sql.DataSource jtaDatasource = getDatasourceFromProperties(m, PersistenceUnitProperties.JTA_DATASOURCE, this.persistenceUnitInfo.getJtaDataSource());

        //find the non jta datasource
        javax.sql.DataSource nonjtaDatasource = getDatasourceFromProperties(m, PersistenceUnitProperties.NON_JTA_DATASOURCE, this.persistenceUnitInfo.getNonJtaDataSource());

        if (isValidationOnly(m, false) && transactionType == PersistenceUnitTransactionType.JTA && jtaDatasource == null) {
            updateLoginDefaultConnector(login, m);
            return;
        }

        login.setUsesExternalTransactionController(transactionType == PersistenceUnitTransactionType.JTA);

        // Avoid processing data-source if EIS, as container may pass in a default one.
        if (isEIS) {
            return;
        }

        javax.sql.DataSource mainDatasource = null;
        javax.sql.DataSource readDatasource = null;
        if (login.shouldUseExternalTransactionController()) {
            // JtaDataSource is guaranteed to be non null - otherwise exception would've been thrown earlier
            mainDatasource = jtaDatasource;
            // only define readDatasource if there is jta mainDatasource
            readDatasource = nonjtaDatasource;
        } else {
            // JtaDataSource will be ignored because transactionType is RESOURCE_LOCAL
            if (jtaDatasource != null) {
                session.log(SessionLog.WARNING, SessionLog.TRANSACTION, "resource_local_persistence_init_info_ignores_jta_data_source", this.persistenceUnitInfo.getPersistenceUnitName());
            }
            if (nonjtaDatasource != null) {
                mainDatasource = nonjtaDatasource;
            } else {
                updateLoginDefaultConnector(login, m);
                return;
            }
        }

        // mainDatasource is guaranteed to be non null - TODO: No it is not, if they did not set one it is null, should raise error, not null-pointer.
        if (!(login.getConnector() instanceof JNDIConnector)) {
            JNDIConnector jndiConnector;
            if (mainDatasource instanceof DataSourceImpl) {
                //Bug5209363  Pass in the datasource name instead of the dummy datasource
                jndiConnector = new JNDIConnector(((DataSourceImpl)mainDatasource).getName());
            } else {
                jndiConnector = new JNDIConnector(mainDatasource);
            }
            login.setConnector(jndiConnector);
            String useInternalConnectionPool = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONNECTION_POOL_INTERNALLY_POOL_DATASOURCE, m, this.session);
            if (!"true".equalsIgnoreCase(useInternalConnectionPool)){
                login.setUsesExternalConnectionPooling(true);
            }
        }

        if (this.session.isServerSession()) {
            // set readLogin
            if (readDatasource != null) {
                DatasourceLogin readLogin = login.clone();
                readLogin.dontUseExternalTransactionController();
                JNDIConnector jndiConnector;
                if (readDatasource instanceof DataSourceImpl) {
                    //Bug5209363  Pass in the datasource name instead of the dummy datasource
                    jndiConnector = new JNDIConnector(((DataSourceImpl)readDatasource).getName());
                } else {
                    jndiConnector = new JNDIConnector(readDatasource);
                }
                readLogin.setConnector(jndiConnector);
                ((ServerSession)this.session).setReadConnectionPool(readLogin);
            }
        }

    }

    /**
     * This is used to return either the defaultDatasource or, if one exists, a datasource
     * defined under the property from the Map m.  This method will build a DataSourceImpl
     * object to hold the url if the property in Map m defines a string instead of a datasource.
     */
    protected javax.sql.DataSource getDatasourceFromProperties(Map m, String property, javax.sql.DataSource defaultDataSource){
        Object datasource = getConfigPropertyLogDebug(property, m, session);
        if ( datasource == null ){
            return defaultDataSource;
        }
        if ( datasource instanceof String){
            if(((String)datasource).length() > 0) {
                // Create a dummy DataSource that will throw an exception on access
                return new DataSourceImpl((String)datasource, null, null, null);
            } else {
                // allow an empty string data source property passed to createEMF to cancel data source specified in persistence.xml
                return null;
            }
        }
        if ( !(datasource instanceof javax.sql.DataSource) ){
            //A warning should be enough.  Though an error might be better, the properties passed in could contain anything
            session.log(SessionLog.WARNING, SessionLog.PROPERTIES, "invalid_datasource_property_value", property, datasource);
            return defaultDataSource;
        }
        return (javax.sql.DataSource)datasource;
    }

    /**
     * In cases where there is no data source, we will use properties to configure the login for
     * our session.  This method gets those properties and sets them on the login.
     */
    protected void updateLoginDefaultConnector(DatasourceLogin login, Map m){
        //Login info might be already set with sessions.xml and could be overridden by session customizer after this
        //If login has default connector then JDBC properties update(override) the login info
        if ((login.getConnector() instanceof DefaultConnector)) {
            DatabaseLogin dbLogin = (DatabaseLogin)login;
            // Note: This call does not checked the stored persistenceUnitInfo or extended properties because
            // the map passed into this method should represent the full set of properties we expect to process
            String jdbcDriver = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_DRIVER, m, session);
            String connectionString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_URL, m, session);
            if(connectionString != null) {
                dbLogin.setConnectionString(connectionString);
            }
            if(jdbcDriver != null) {
                dbLogin.setDriverClassName(jdbcDriver);
            }
        }
    }

    /**
     * Configure the internal connection pooling parameters.
     * By default if nothing is configured a default shared (exclusive) read/write pool is used with 32 min/max connections and 1 initial.
     */
    @SuppressWarnings("deprecation")
    protected void updatePools(ServerSession serverSession, Map m) {
        String value = null;
        String property = null;
        try {
            // Configure default/write connection pool.
            // Sizes are irrelevant for external connection pool
            if (!serverSession.getDefaultConnectionPool().getLogin().shouldUseExternalConnectionPooling()) {
                // CONNECTION and WRITE_CONNECTION properties both configure the default pool (mean the same thing, but WRITE normally used with READ).
                property = PersistenceUnitProperties.JDBC_CONNECTIONS_MIN;
                value = getConfigPropertyAsStringLogDebug(property, m, serverSession);
                if (value != null) {
                    serverSession.getDefaultConnectionPool().setMinNumberOfConnections(Integer.parseInt(value));
                }
                property = PersistenceUnitProperties.JDBC_CONNECTIONS_MAX;
                value = getConfigPropertyAsStringLogDebug(property, m, serverSession);
                if (value != null) {
                    serverSession.getDefaultConnectionPool().setMaxNumberOfConnections(Integer.parseInt(value));
                }
                property = PersistenceUnitProperties.JDBC_CONNECTIONS_INITIAL;
                value = getConfigPropertyAsStringLogDebug(property, m, serverSession);
                if (value != null) {
                    serverSession.getDefaultConnectionPool().setInitialNumberOfConnections(Integer.parseInt(value));
                }
                property = PersistenceUnitProperties.JDBC_WRITE_CONNECTIONS_MIN;
                value = getConfigPropertyAsStringLogDebug(property, m, serverSession);
                if (value != null) {
                    serverSession.getDefaultConnectionPool().setMinNumberOfConnections(Integer.parseInt(value));
                }
                property = PersistenceUnitProperties.JDBC_WRITE_CONNECTIONS_MAX;
                value = getConfigPropertyAsStringLogDebug(property, m, serverSession);
                if (value != null) {
                    serverSession.getDefaultConnectionPool().setMaxNumberOfConnections(Integer.parseInt(value));
                }
                property = PersistenceUnitProperties.JDBC_WRITE_CONNECTIONS_INITIAL;
                value = getConfigPropertyAsStringLogDebug(property, m, serverSession);
                if (value != null) {
                    serverSession.getDefaultConnectionPool().setInitialNumberOfConnections(Integer.parseInt(value));
                }
            }

            // Configure read connection pool if set.
            // Sizes and shared option are irrelevant for external connection pool
            if (!serverSession.getReadConnectionPool().getLogin().shouldUseExternalConnectionPooling()) {
                String shared = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_READ_CONNECTIONS_SHARED, m, serverSession);
                boolean isShared = false;
                if (shared != null) {
                    isShared = Boolean.parseBoolean(shared);
                }
                ConnectionPool pool = null;
                if (isShared) {
                    pool = new ReadConnectionPool("read", serverSession.getReadConnectionPool().getLogin(), serverSession);
                } else {
                    pool = new ConnectionPool("read", serverSession.getReadConnectionPool().getLogin(), serverSession);
                }
                String min = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_READ_CONNECTIONS_MIN, m, serverSession);
                if (min != null) {
                    value = min;
                    property = PersistenceUnitProperties.JDBC_READ_CONNECTIONS_MIN;
                    pool.setMinNumberOfConnections(Integer.parseInt(min));
                }
                String max = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_READ_CONNECTIONS_MAX, m, serverSession);
                if (max != null) {
                    value = max;
                    property = PersistenceUnitProperties.JDBC_READ_CONNECTIONS_MAX;
                    pool.setMaxNumberOfConnections(Integer.parseInt(max));
                }
                String initial = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_READ_CONNECTIONS_INITIAL, m, serverSession);
                if (initial != null) {
                    value = initial;
                    property = PersistenceUnitProperties.JDBC_READ_CONNECTIONS_INITIAL;
                    pool.setInitialNumberOfConnections(Integer.parseInt(initial));
                }
                // Only set the read pool if they configured it, otherwise use default shared read/write.
                if (isShared || (min != null) || (max != null) || (initial != null)) {
                    serverSession.setReadConnectionPool(pool);
                }
                String wait = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_CONNECTIONS_WAIT, m, serverSession);
                if (wait != null) {
                    value = wait;
                    property = PersistenceUnitProperties.JDBC_CONNECTIONS_WAIT;
                    serverSession.getDefaultConnectionPool().setWaitTimeout(Integer.parseInt(wait));
                    pool.setWaitTimeout(Integer.parseInt(wait));
                }
            }

            // Configure sequence connection pool if set.
            String sequence = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_SEQUENCE_CONNECTION_POOL, m, serverSession);
            if (sequence != null) {
                serverSession.getSequencingControl().setShouldUseSeparateConnection(Boolean.parseBoolean(sequence));
            }
            String sequenceDataSource = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_SEQUENCE_CONNECTION_POOL_DATASOURCE, m, serverSession);
            if (sequenceDataSource != null) {
                DatasourceLogin login = this.session.getLogin().clone();
                login.dontUseExternalTransactionController();
                JNDIConnector jndiConnector = new JNDIConnector(sequenceDataSource);
                login.setConnector(jndiConnector);
                serverSession.getSequencingControl().setLogin(login);
            }
            // Sizes and shared option are irrelevant for external connection pool
            if (!serverSession.getReadConnectionPool().getLogin().shouldUseExternalConnectionPooling()) {
                value = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_SEQUENCE_CONNECTION_POOL_MIN, m, serverSession);
                if (value != null) {
                    property = PersistenceUnitProperties.JDBC_SEQUENCE_CONNECTION_POOL_MIN;
                    serverSession.getSequencingControl().setMinPoolSize(Integer.parseInt(value));
                }
                value = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_SEQUENCE_CONNECTION_POOL_MAX, m, serverSession);
                if (value != null) {
                    property = PersistenceUnitProperties.JDBC_SEQUENCE_CONNECTION_POOL_MAX;
                    serverSession.getSequencingControl().setMaxPoolSize(Integer.parseInt(value));
                }
                value = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_SEQUENCE_CONNECTION_POOL_INITIAL, m, serverSession);
                if (value != null) {
                    property = PersistenceUnitProperties.JDBC_SEQUENCE_CONNECTION_POOL_INITIAL;
                    serverSession.getSequencingControl().setInitialPoolSize(Integer.parseInt(value));
                }
            }
        } catch (NumberFormatException exception) {
            serverSession.handleException(ValidationException.invalidValueForProperty(value, property, exception));
        }
    }

    /**
     * Normally when a property is missing nothing should be applied to the session.
     * However there are several session attributes that defaulted in EJB3 to the values
     * different from EclipseLink defaults.
     * This function applies defaults for such properties and registers the session.
     * All other session-related properties are applied in updateServerSession.
     * Note that updateSession may be called several times on the same session
     * (before login), but initSession is called just once - before the first call
     * to updateSession.
     */
    protected void initSession() {
        assignCMP3Policy();

        if(!isCompositeMember()) {
            // Register session that has been created earlier.
            addSessionToGlobalSessionManager();
        }
    }

    /**
     * Make any changes to our ServerSession that can be made after it is created.
     */
    protected void updateSession(Map m, ClassLoader loader) {
        if (session == null || (session.isDatabaseSession() && ((DatabaseSessionImpl)session).isLoggedIn())) {
            return;
        }

        // In deploy ServerPlatform could've changed which will affect the loggers.
        boolean serverPlatformChanged = updateServerPlatform(m, loader);
        updateJPQLParser(m);

        if (!session.hasBroker()) {
            updateLoggers(m, serverPlatformChanged, loader);
            updateProfiler(m,loader);
        }

        // log the server platform being used by the session if it has been changed
        if (serverPlatformChanged && session.getSessionLog().shouldLog(SessionLog.FINE)) {
            session.getSessionLog().log(SessionLog.FINE, SessionLog.SERVER,
                    "configured_server_platform", session.getServerPlatform().getClass().getName()); // NOI18N
        }

        if(session.isBroker()) {
            PersistenceUnitTransactionType transactionType = persistenceUnitInfo.getTransactionType();
            //bug 5867753: find and override the transaction type using properties
            String transTypeString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.TRANSACTION_TYPE, m, session);
            if (transTypeString != null) {
                transactionType = PersistenceUnitTransactionType.valueOf(transTypeString);
            }
            ((DatasourceLogin)session.getDatasourceLogin()).setUsesExternalTransactionController(transactionType == PersistenceUnitTransactionType.JTA);
        } else {
            String shouldBindString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_BIND_PARAMETERS, m, session);
            if (shouldBindString != null) {
                session.getPlatform().setShouldBindAllParameters(Boolean.parseBoolean(shouldBindString));
            }

            String shouldForceBindString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JDBC_FORCE_BIND_PARAMETERS, m, session);
            if(shouldForceBindString != null) {
                session.getPlatform().setShouldForceBindAllParameters(Boolean.parseBoolean(shouldForceBindString));
            }

            updateLogins(m);
        }
        if (!session.getDatasourceLogin().shouldUseExternalTransactionController()) {
            session.getServerPlatform().disableJTA();
        }

        if(session.isServerSession()) {
            updatePools((ServerSession)session, m);
            updateConnectionSettings((ServerSession)session, m);
            if (!isSessionLoadedFromSessionsXML) {
                updateDescriptorCacheSettings(m, loader);
            }
            updateConnectionPolicy((ServerSession)session, m);
        }

        if(session.isBroker()) {
            if (this.compositeMemberEmSetupImpls != null) {
                // composite
                Map compositeMemberMapOfProperties = (Map)getConfigProperty(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, m);
                for(EntityManagerSetupImpl compositeMemberEmSetupImpl : this.compositeMemberEmSetupImpls) {
                    // the properties guaranteed to be non-null after updateCompositeMemberProperties call
                    String compositeMemberPuName = compositeMemberEmSetupImpl.getPersistenceUnitInfo().getPersistenceUnitName();
                    Map compositeMemberProperties = (Map)compositeMemberMapOfProperties.get(compositeMemberPuName);
                    // debug output added to make it easier to navigate the log because the method is called outside of composite member deploy
                    compositeMemberEmSetupImpl.session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "composite_member_begin_call", new Object[]{"updateSession", compositeMemberPuName, state});
                    compositeMemberEmSetupImpl.updateSession(compositeMemberProperties, loader);
                    compositeMemberEmSetupImpl.session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "composite_member_end_call", new Object[]{"updateSession", compositeMemberPuName, state});
                }
            }
            setSessionEventListener(m, loader);
            setExceptionHandler(m, loader);

            updateAllowZeroIdSetting(m);
            updateCacheCoordination(m, loader);
            processSessionCustomizer(m, loader);
        } else {
            setSessionEventListener(m, loader);
            setExceptionHandler(m, loader);

            updateBatchWritingSetting(m, loader);

            updateNativeSQLSetting(m);
            updateSequencing(m);
            updateSequencingStart(m);
            updateAllowNativeSQLQueriesSetting(m);
            updateSQLCastSetting(m);
            updateUppercaseSetting(m);
            updateCacheStatementSettings(m);
            updateAllowExtendedCacheLogging(m);
            updateAllowExtendedThreadLogging(m);
            updateAllowExtendedThreadLoggingThreadDump(m);
            updateTemporalMutableSetting(m);
            updateTableCreationSettings(m);
            updateIndexForeignKeys(m);
            if (!session.hasBroker()) {
                updateAllowZeroIdSetting(m);
            }
            updateIdValidation(m);
            updatePessimisticLockTimeout(m);
            updatePessimisticLockTimeoutUnit(m);
            updateQueryTimeout(m);
            updateQueryTimeoutUnit(m);
            updateLockingTimestampDefault(m);
            updateSQLCallDeferralDefault(m);
            updateNamingIntoIndexed(m);
            if (!session.hasBroker()) {
                updateCacheCoordination(m, loader);
            }
            updatePartitioning(m, loader);
            updateDatabaseEventListener(m, loader);
            updateSerializer(m, loader);
            updateShouldOptimizeResultSetAccess(m);
            updateTolerateInvalidJPQL(m);
            updateTenancy(m, loader);
            // ConcurrencyManager properties
            updateConcurrencyManagerWaitTime(m);
            updateConcurrencyManagerBuildObjectCompleteWaitTime(m);
            updateConcurrencyManagerMaxAllowedSleepTime(m);
            updateConcurrencyManagerMaxAllowedFrequencyToProduceTinyDumpLogMessage(m);
            updateConcurrencyManagerMaxAllowedFrequencyToProduceMassiveDumpLogMessage(m);
            updateConcurrencyManagerAllowInterruptedExceptionFired(m);
            updateConcurrencyManagerAllowConcurrencyExceptionToBeFiredUp(m);
            updateConcurrencyManagerAllowTakingStackTraceDuringReadLockAcquisition(m);
            updateConcurrencyManagerUseObjectBuildingSemaphore(m);
            updateConcurrencyManagerUseWriteLockManagerSemaphore(m);
            updateConcurrencyManagerNoOfThreadsAllowedToObjectBuildInParallel(m);
            updateConcurrencyManagerNoOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel(m);
            updateConcurrencySemaphoreMaxTimePermit(m);
            updateConcurrencySemaphoreLogTimeout(m);
            // Customizers should be processed last
            processDescriptorCustomizers(m, loader);
            processSessionCustomizer(m, loader);

            setDescriptorNamedQueries(m);
        }
    }

    /**
     * This sets the isInContainerMode flag.
     * "true" indicates container case, "false" - SE.
     */
    public void setIsInContainerMode(boolean isInContainerMode) {
        this.isInContainerMode = isInContainerMode;
    }

    /**
     * Used to indicate that an EntityManagerFactoryImpl based on this
     * EntityManagerSetupImpl has been refreshed.  This means this EntityManagerSetupImpl
     * will no longer be associated with new EntityManagerFactories
     */
    public void setIsMetadataExpired(boolean hasExpiredMetadata) {
        this.isMetadataExpired = hasExpiredMetadata;
    }

    protected void processSessionCustomizer(Map m, ClassLoader loader) {
        SessionCustomizer sessionCustomizer;
        Object customizer = getConfigPropertyLogDebug(PersistenceUnitProperties.SESSION_CUSTOMIZER, m, session);
        if (customizer == null) {
            return;
        }
        if (customizer instanceof String) {
            Class sessionCustomizerClass = findClassForProperty((String) customizer, PersistenceUnitProperties.SESSION_CUSTOMIZER, loader);
            try {
                sessionCustomizer = (SessionCustomizer) sessionCustomizerClass.getConstructor().newInstance();
            } catch (Exception ex) {
                throw EntityManagerSetupException.failedWhileProcessingProperty(PersistenceUnitProperties.SESSION_CUSTOMIZER, (String) customizer, ex);
            }
        } else {
            sessionCustomizer = (SessionCustomizer) customizer;
        }
        try {
            sessionCustomizer.customize(session);
        } catch (Exception ex) {
            throw EntityManagerSetupException.failedWhileProcessingProperty(PersistenceUnitProperties.SESSION_CUSTOMIZER, customizer.toString(), ex);
        }
    }

    protected void initOrUpdateLogging(Map m, SessionLog log) {
        String logLevelString = PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.LOGGING_LEVEL, m, session);
        if (logLevelString != null) {
            log.setLevel(AbstractSessionLog.translateStringToLoggingLevel(logLevelString));
        }
        // category-specific logging level
        Map categoryLogLevelMap = PropertiesHandler.getPrefixValuesLogDebug(PersistenceUnitProperties.CATEGORY_LOGGING_LEVEL_, m, session);
        if(!categoryLogLevelMap.isEmpty()) {
            Iterator it = categoryLogLevelMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry)it.next();
                String category = (String)entry.getKey();
                String value = (String)entry.getValue();
                log.setLevel(AbstractSessionLog.translateStringToLoggingLevel(value), category);
            }
        }

        String tsString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGGING_TIMESTAMP, m, session);
        if (tsString != null) {
            log.setShouldPrintDate(Boolean.parseBoolean(tsString));
        }
        String threadString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGGING_THREAD, m, session);
        if (threadString != null) {
            log.setShouldPrintThread(Boolean.parseBoolean(threadString));
        }
        String sessionString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGGING_SESSION, m, session);
        if (sessionString != null) {
            log.setShouldPrintSession(Boolean.parseBoolean(sessionString));
        }
        String connectionString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGGING_CONNECTION, m, session);
        if (connectionString != null) {
            log.setShouldPrintConnection(Boolean.parseBoolean(connectionString));
        }
        String exString = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGGING_EXCEPTIONS, m, session);
        if (exString != null) {
            log.setShouldLogExceptionStackTrace(Boolean.parseBoolean(exString));
        }
        String shouldDisplayData = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.LOGGING_PARAMETERS, m, session);
        if (shouldDisplayData != null) {
            log.setShouldDisplayData(Boolean.parseBoolean(shouldDisplayData));
        }
    }

    protected void processDescriptorCustomizers(Map m, ClassLoader loader) {
        Map customizerMap = PropertiesHandler.getPrefixValuesLogDebug(PersistenceUnitProperties.DESCRIPTOR_CUSTOMIZER_, m, session);
        if (customizerMap.isEmpty()) {
            return;
        }

        Iterator it = customizerMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String name = (String)entry.getKey();
            String customizerClassName = (String)entry.getValue();

            ClassDescriptor descriptor = session.getDescriptorForAlias(name);
            if (descriptor == null) {
                try {
                    Class javaClass = findClass(name, loader);
                    descriptor = session.getDescriptor(javaClass);
                } catch (Exception ex) {
                    throw EntityManagerSetupException.failedWhileProcessingProperty(PersistenceUnitProperties.DESCRIPTOR_CUSTOMIZER_ + name, customizerClassName, ex);
                }
            }
            if (descriptor != null) {
                Class customizerClass = findClassForProperty(customizerClassName, PersistenceUnitProperties.DESCRIPTOR_CUSTOMIZER_ + name, loader);
                try {
                    DescriptorCustomizer customizer = (DescriptorCustomizer)customizerClass.getConstructor().newInstance();
                    customizer.customize(descriptor);
                } catch (Exception ex) {
                    throw EntityManagerSetupException.failedWhileProcessingProperty(PersistenceUnitProperties.DESCRIPTOR_CUSTOMIZER_ + name, customizerClassName, ex);
                }
            } else {
                // TODO throw a better error, missing descriptor for property.
                throw EntityManagerSetupException.failedWhileProcessingProperty(PersistenceUnitProperties.DESCRIPTOR_CUSTOMIZER_ + name, customizerClassName, null);
            }
        }
    }

    public boolean isInitial() {
        return state == STATE_INITIAL;
    }

    /**
     * Used to indicate that an EntityManagerFactoryImpl based on this
     * EntityManagerSetupImpl has been refreshed.  This means this EntityManagerSetupImpl
     * will no longer be associated with new EntityManagerFactories
     */
    public boolean isMetadataExpired() {
        return isMetadataExpired;
    }

    public boolean isPredeployed() {
        return state == STATE_PREDEPLOYED;
    }

    public boolean isDeployed() {
        return state == STATE_DEPLOYED;
    }

    public boolean isHalfDeployed() {
        return state == STATE_HALF_DEPLOYED;
    }

    public boolean isUndeployed() {
        return state == STATE_UNDEPLOYED;
    }

    public boolean isPredeployFailed() {
        return state == STATE_PREDEPLOY_FAILED;
    }

    public boolean isDeployFailed() {
        return state == STATE_DEPLOY_FAILED;
    }

    public boolean isHalfPredeployedCompositeMember() {
        return state == STATE_HALF_PREDEPLOYED_COMPOSITE_MEMBER;
    }

    public String getPersistenceUnitUniqueName() {
        return this.persistenceUnitUniqueName;
    }

    public int getFactoryCount() {
        return factoryCount;
    }

    public String getSessionName() {
        return this.sessionName;
    }

    public boolean shouldRedeploy() {
        return state == STATE_UNDEPLOYED || state == STATE_PREDEPLOY_FAILED;
    }

    /**
     * Return if MetadataSource refresh commands should be sent when refresh is called
     * Checks the PersistenceUnitProperties.METADATA_SOURCE_RCM_COMMAND property and defaults to true.
     */
    public boolean shouldSendMetadataRefreshCommand(Map m) {
        String sendCommand = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.METADATA_SOURCE_RCM_COMMAND, m, this.session);
        if (sendCommand != null) {
            return Boolean.parseBoolean(sendCommand);
        } else {
            return true;
        }
    }

    /**
     * Undeploy may be called several times, but only the call that decreases
     * factoryCount to 0 disconnects the session and removes it from the session manager.
     * This method and predeploy - the only methods altering factoryCount - should be synchronized.
     * After undeploy call that turns factoryCount to 0:
     *   session==null;
     *   PREDEPLOYED, DEPLOYED and DEPLOYED_FAILED states change to UNDEPLOYED state.
     */
    public synchronized void undeploy() {
        if (state == STATE_INITIAL || state == STATE_PREDEPLOY_FAILED || state == STATE_UNDEPLOYED) {
            // must already have factoryCount==0 and session==null
            return;
        }
        // state is PREDEPLOYED, DEPLOYED or DEPLOY_FAILED
        session.log(SessionLog.FINEST, SessionLog.JPA, "undeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state, factoryCount});
        try {
            factoryCount--;
            if(factoryCount > 0) {
                return;
            }
            synchronized (EntityManagerFactoryProvider.emSetupImpls) {
                state = STATE_UNDEPLOYED;
                removeSessionFromGlobalSessionManager();
                // remove undeployed emSetupImpl from the map
                EntityManagerSetupImpl emSetupImpl = EntityManagerFactoryProvider.emSetupImpls.get(sessionName);
                if ((emSetupImpl != null) && (emSetupImpl.equals(this))) {
                    EntityManagerFactoryProvider.emSetupImpls.remove(sessionName);
                }
            }
        } finally {
            session.log(SessionLog.FINEST, SessionLog.JPA, "undeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), session.getName(), state, factoryCount});
            if(state == STATE_UNDEPLOYED) {
                session = null;
            }
        }
    }

    /**
     * INTERNAL:
     * By default we require a connection to the database. However, when
     * generating schema to scripts only, this is not required.
     */
    public void setRequiresConnection(boolean requiresConnection) {
        this.requiresConnection = requiresConnection;
    }

    /**
     * Allow customized session event listener to be added into session.
     * The method needs to be called in deploy stage.
     */
    protected void setSessionEventListener(Map m, ClassLoader loader){
        //Set event listener if it has been specified.
        String sessionEventListenerClassName = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.SESSION_EVENT_LISTENER_CLASS, m, session);
        if(sessionEventListenerClassName!=null){
            Class sessionEventListenerClass = findClassForProperty(sessionEventListenerClassName,PersistenceUnitProperties.SESSION_EVENT_LISTENER_CLASS, loader);
            try {
                SessionEventListener sessionEventListener = (SessionEventListener)buildObjectForClass(sessionEventListenerClass, SessionEventListener.class);
                if(sessionEventListener!=null){
                    session.getEventManager().addListener(sessionEventListener);
                } else {
                    session.handleException(ValidationException.invalidSessionEventListenerClass(sessionEventListenerClassName));
                }
            } catch (IllegalAccessException e) {
                session.handleException(ValidationException.cannotInstantiateSessionEventListenerClass(sessionEventListenerClassName,e));
            } catch (PrivilegedActionException e) {
                session.handleException(ValidationException.cannotInstantiateSessionEventListenerClass(sessionEventListenerClassName,e));
            } catch (InstantiationException e) {
                session.handleException(ValidationException.cannotInstantiateSessionEventListenerClass(sessionEventListenerClassName,e));
            }
        }
    }

    /**
     * Allow customized exception handler to be added into session.
     * The method needs to be called in deploy and pre-deploy stage.
     */
    protected void setExceptionHandler(Map m, ClassLoader loader){
        //Set exception handler if it was specified.
        String exceptionHandlerClassName = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.EXCEPTION_HANDLER_CLASS, m, session);
        if(exceptionHandlerClassName!=null){
            Class exceptionHandlerClass = findClassForProperty(exceptionHandlerClassName,PersistenceUnitProperties.EXCEPTION_HANDLER_CLASS, loader);
            try {
                ExceptionHandler exceptionHandler = (ExceptionHandler)buildObjectForClass(exceptionHandlerClass, ExceptionHandler.class);
                if (exceptionHandler!=null){
                    session.setExceptionHandler(exceptionHandler);
                } else {
                    session.handleException(ValidationException.invalidExceptionHandlerClass(exceptionHandlerClassName));
                }
            } catch (IllegalAccessException e) {
                session.handleException(ValidationException.cannotInstantiateExceptionHandlerClass(exceptionHandlerClassName,e));
            } catch (PrivilegedActionException e) {
                session.handleException(ValidationException.cannotInstantiateExceptionHandlerClass(exceptionHandlerClassName,e));
            } catch (InstantiationException e) {
                session.handleException(ValidationException.cannotInstantiateExceptionHandlerClass(exceptionHandlerClassName,e));
            }
        }
    }

    /**
     * Update batch writing setting.
     * The method needs to be called in deploy stage.
     */
    protected void updateBatchWritingSetting(Map persistenceProperties, ClassLoader loader) {
        String batchWritingSettingString = PropertiesHandler.getPropertyValueLogDebug(PersistenceUnitProperties.BATCH_WRITING, persistenceProperties, this.session);
        if (batchWritingSettingString != null) {
             this.session.getPlatform().setUsesBatchWriting(batchWritingSettingString != BatchWriting.None);
             if (batchWritingSettingString == BatchWriting.JDBC) {
                 this.session.getPlatform().setUsesJDBCBatchWriting(true);
                 this.session.getPlatform().setUsesNativeBatchWriting(false);
             } else if (batchWritingSettingString == BatchWriting.Buffered) {
                 this.session.getPlatform().setUsesJDBCBatchWriting(false);
                 this.session.getPlatform().setUsesNativeBatchWriting(false);
             } else if (batchWritingSettingString == BatchWriting.OracleJDBC) {
                 this.session.getPlatform().setUsesNativeBatchWriting(true);
                 this.session.getPlatform().setUsesJDBCBatchWriting(true);
             } else if (batchWritingSettingString == BatchWriting.None) {
                 // Nothing required.
             } else {
                 if (batchWritingSettingString.equalsIgnoreCase("ExaLogic")) {
                     batchWritingSettingString = "oracle.toplink.exalogic.batch.DynamicParameterizedBatchWritingMechanism";
                 }
                 Class cls = findClassForProperty(batchWritingSettingString, PersistenceUnitProperties.BATCH_WRITING, loader);
                 BatchWritingMechanism mechanism = null;
                 try {
                     Constructor constructor = cls.getConstructor();
                     mechanism = (BatchWritingMechanism)constructor.newInstance();
                 } catch (Exception exception) {
                     if (batchWritingSettingString.indexOf('.') == -1) {
                         throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-illegal-property-value", new Object[]{PersistenceUnitProperties.BATCH_WRITING, batchWritingSettingString}));
                     } else {
                         throw EntityManagerSetupException.failedToInstantiateProperty(batchWritingSettingString, PersistenceUnitProperties.BATCH_WRITING, exception);
                     }
                 }
                 this.session.getPlatform().setBatchWritingMechanism(mechanism);
             }
        }
        // Set batch size.
        String sizeString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.BATCH_WRITING_SIZE, persistenceProperties, this.session);
        if (sizeString != null) {
            try {
                this.session.getPlatform().setMaxBatchWritingSize(Integer.parseInt(sizeString));
            } catch (NumberFormatException invalid) {
                session.handleException(ValidationException.invalidValueForProperty(sizeString, PersistenceUnitProperties.BATCH_WRITING_SIZE, invalid));
            }
        }
    }

    /**
     * Load the Metadata Repository for Extensibility
     */
    protected void updateMetadataRepository(Map m, ClassLoader loader){
        Object metadataSource = EntityManagerFactoryProvider.getConfigPropertyLogDebug(PersistenceUnitProperties.METADATA_SOURCE, m, session);
        if (metadataSource != null && metadataSource instanceof MetadataSource){
            processor.setMetadataSource((MetadataSource)metadataSource);
        } else {
            if (metadataSource!=null) {
                String repository = (String)metadataSource;
                if (repository.equalsIgnoreCase("XML")) {
                    processor.setMetadataSource(new XMLMetadataSource());
                } else {
                    Class transportClass = findClassForProperty(repository, PersistenceUnitProperties.METADATA_SOURCE, loader);
                    try {
                        processor.setMetadataSource((MetadataSource)transportClass.getConstructor().newInstance());
                    } catch (Exception invalid) {
                        session.handleException(EntityManagerSetupException.failedToInstantiateProperty(repository, PersistenceUnitProperties.METADATA_SOURCE,invalid));
                    }
                }
            }
        }
    }

    /**
     * Check for a tuning property and run the tuner preDeploy.
     */
    protected void updateTunerPreDeploy(Map m, ClassLoader loader) {
        String tuning = (String)EntityManagerFactoryProvider.getConfigPropertyLogDebug(PersistenceUnitProperties.TUNING, m, this.session);
        if (tuning != null) {
            SessionTuner tuner = null;
            if (tuning.equalsIgnoreCase("Safe")) {
                tuner = new SafeModeTuner();
            } else if (tuning.equalsIgnoreCase("Standard")) {
                tuner = new StandardTuner();
            } else {
                if (tuning.equalsIgnoreCase("ExaLogic")) {
                    tuning = "oracle.toplink.exalogic.tuning.ExaLogicTuner";
                }
                Class tunerClass = findClassForProperty(tuning, PersistenceUnitProperties.TUNING, loader);
                try {
                    tuner = (SessionTuner)tunerClass.getConstructor().newInstance();
                } catch (Exception invalid) {
                    this.session.handleException(EntityManagerSetupException.failedToInstantiateProperty(tuning, PersistenceUnitProperties.TUNING, invalid));
                }
            }
            getDatabaseSession().setTuner(tuner);
            if (tuner != null) {
                tuner.tunePreDeploy(m);
            }
        }
    }

    /**
     * Check for a tuning property and run the tuner deploy.
     */
    protected void updateTunerDeploy(Map m, ClassLoader loader) {
        if (getDatabaseSession().getTuner() != null) {
            getDatabaseSession().getTuner().tuneDeploy(getDatabaseSession());
        }
    }

    /**
     * Check for a tuning property and run the tuner deploy.
     */
    protected void updateTunerPostDeploy(Map m, ClassLoader loader) {
        if (getDatabaseSession().getTuner() != null) {
            getDatabaseSession().getTuner().tunePostDeploy(getDatabaseSession());
        }
    }

    /**
     * Allow the deployment metadata to be freed post-deploy to conserve memory.
     */
    protected void updateFreeMemory(Map m) {
        String freeMemory = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.FREE_METADATA, m, session);
        if (freeMemory != null) {
           if (freeMemory.equalsIgnoreCase("true")) {
               XMLEntityMappingsReader.clear();
           } else if (freeMemory.equalsIgnoreCase("false")) {
               // default.
           } else {
               session.handleException(ValidationException.invalidBooleanValueForProperty(freeMemory, PersistenceUnitProperties.FREE_METADATA));
           }
        }
    }

    /**
     * Enable or disable the capability of Native SQL function.
     * The method needs to be called in deploy stage.
     */
    protected void updateNativeSQLSetting(Map m){
        //Set Native SQL flag if it was specified.
        String nativeSQLString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.NATIVE_SQL, m, session);
        if(nativeSQLString!=null){
           if(nativeSQLString.equalsIgnoreCase("true") ){
                 session.getProject().getLogin().useNativeSQL();
           }else if (nativeSQLString.equalsIgnoreCase("false")){
                 session.getProject().getLogin().dontUseNativeSQL();
           }else{
                 session.handleException(ValidationException.invalidBooleanValueForSettingNativeSQL(nativeSQLString));
           }
        }
    }

    /**
     * Configure sequencing settings.
     */
    protected void updateSequencing(Map m){
        String useTable = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.SEQUENCING_SEQUENCE_DEFAULT, m, session);
        if (useTable != null) {
           if (useTable.equalsIgnoreCase("true")) {
               this.session.getPlatform().setDefaultNativeSequenceToTable(true);
           } else if (useTable.equalsIgnoreCase("false")) {
               this.session.getPlatform().setDefaultNativeSequenceToTable(false);
           } else {
               this.session.handleException(ValidationException.invalidBooleanValueForProperty(useTable, PersistenceUnitProperties.SEQUENCING_SEQUENCE_DEFAULT));
           }
        }
    }

    protected void updateSequencingStart(Map m) {
        String local = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.SEQUENCING_START_AT_NEXTVAL, m, session);
        try {
            if (local != null) {
                this.session.getPlatform().setDefaultSeqenceAtNextValue(Boolean.parseBoolean(local));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(local, PersistenceUnitProperties.USE_LOCAL_TIMESTAMP, exception));
        }
    }

    /**
     * Load the projectCacheAccessor for JPA project caching
     */
    protected void updateProjectCache(Map m, ClassLoader loader){
        Object accessor = EntityManagerFactoryProvider.getConfigPropertyLogDebug(PersistenceUnitProperties.PROJECT_CACHE, m, session);
        if (accessor != null ) {
            if (accessor instanceof ProjectCache) {
                projectCacheAccessor = (ProjectCache)accessor;
            } else {
                String accessorType = (String)accessor;
                if (accessorType.equalsIgnoreCase("java-serialization")) {
                    projectCacheAccessor = new FileBasedProjectCache();
                } else {
                    Class transportClass = findClassForProperty(accessorType, PersistenceUnitProperties.PROJECT_CACHE, loader);
                    try {
                        projectCacheAccessor = (ProjectCache)transportClass.getConstructor().newInstance();
                    } catch (Exception invalid) {
                        session.handleException(EntityManagerSetupException.failedToInstantiateProperty(accessorType, PersistenceUnitProperties.METADATA_SOURCE,invalid));
                    }
                }
            }
        }
    }

    /**
     * Enable or disable the capability of Native SQL function.
     * The method needs to be called in deploy stage.
     */
    protected void updateJPQLParser(Map m) {
        // Set JPQL parser if it was specified.
        String parser = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JPQL_PARSER, m, this.session);
        if (parser != null) {
            if (parser.equalsIgnoreCase(ParserType.Hermes)) {
                parser = "org.eclipse.persistence.internal.jpa.jpql.HermesParser";
            } else if (parser.equalsIgnoreCase(ParserType.ANTLR)) {
                parser = "org.eclipse.persistence.queries.ANTLRQueryBuilder";
            }
            this.session.setProperty(PersistenceUnitProperties.JPQL_PARSER, parser);
        }
        // Set JPQL parser validation mode if it was specified.
        String validation = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.JPQL_VALIDATION, m, this.session);
        if (validation != null) {
            this.session.setProperty(PersistenceUnitProperties.JPQL_VALIDATION, validation);
        }
    }

    /**
     * Enable or disable the capability of Native SQL function.
     * The method needs to be called in deploy stage.
     */
    protected void updateAllowNativeSQLQueriesSetting(Map m){
        // Set allow native SQL queries flag if it was specified.
        String allowNativeSQLQueriesString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.ALLOW_NATIVE_SQL_QUERIES, m, session);

        if (allowNativeSQLQueriesString != null) {
           if (allowNativeSQLQueriesString.equalsIgnoreCase("true")) {
               session.getProject().setAllowNativeSQLQueries(true);
           } else if (allowNativeSQLQueriesString.equalsIgnoreCase("false")) {
               session.getProject().setAllowNativeSQLQueries(false);
           } else {
               session.handleException(ValidationException.invalidBooleanValueForSettingAllowNativeSQLQueries(allowNativeSQLQueriesString));
           }
        }
    }

    /**
     * Enable or disable SQL casting.
     */
    protected void updateSQLCastSetting(Map m) {
        //Set Native SQL flag if it was specified.
        String sqlCastString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.SQL_CAST, m, session);
        if (sqlCastString != null) {
           if (sqlCastString.equalsIgnoreCase("true")) {
                 session.getProject().getLogin().getPlatform().setIsCastRequired(true);
           } else if (sqlCastString.equalsIgnoreCase("false")) {
               session.getProject().getLogin().getPlatform().setIsCastRequired(false);
           } else {
                 session.handleException(ValidationException.invalidBooleanValueForProperty(sqlCastString, PersistenceUnitProperties.SQL_CAST));
           }
        }
    }

    /**
     * Enable or disable forcing field names to uppercase.
     * The method needs to be called in deploy stage.
     */
    protected void updateUppercaseSetting(Map m){
        //Set Native SQL flag if it was specified.
        String uppercaseString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.NATIVE_QUERY_UPPERCASE_COLUMNS, m, session);
        if (uppercaseString != null) {
           if (uppercaseString.equalsIgnoreCase("true") ){
               this.session.getProject().getLogin().setShouldForceFieldNamesToUpperCase(true);
           } else if (uppercaseString.equalsIgnoreCase("false")) {
               this.session.getProject().getLogin().setShouldForceFieldNamesToUpperCase(false);
           } else {
               this.session.handleException(ValidationException.invalidBooleanValueForProperty(uppercaseString, PersistenceUnitProperties.NATIVE_QUERY_UPPERCASE_COLUMNS));
           }
        }
    }

    /**

    /**
     * Enable or disable forcing field names to be case insensitive.  Implementation of case insensitive column handling relies on setting
     * both sides to uppercase (the column names from annotations/xml as well as what is returned from the JDBC/statement)
     * The method needs to be called in deploy stage.
     */
    public static void updateCaseSensitivitySettings(Map m, MetadataProject project, AbstractSession session){
        //Set Native SQL flag if it was specified.
        String insensitiveString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.UPPERCASE_COLUMN_NAMES, m, session);
        if (insensitiveString == null || insensitiveString.equalsIgnoreCase("true")) {
            // Set or default to case in-sensitive.
           project.setShouldForceFieldNamesToUpperCase(true);
           session.getProject().getLogin().setShouldForceFieldNamesToUpperCase(true);
        } else if (insensitiveString.equalsIgnoreCase("false")) {
            project.setShouldForceFieldNamesToUpperCase(false);
            session.getProject().getLogin().setShouldForceFieldNamesToUpperCase(false);
        } else {
            session.handleException(ValidationException.invalidBooleanValueForProperty(insensitiveString, PersistenceUnitProperties.UPPERCASE_COLUMN_NAMES));
        }
    }

    /**
     * Update the default pessimistic lock timeout value.
     * @param persistenceProperties the properties map
     */
    protected void updatePessimisticLockTimeout(Map persistenceProperties) {
        String pessimisticLockTimeout = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.PESSIMISTIC_LOCK_TIMEOUT, persistenceProperties, session);

        if (pessimisticLockTimeout != null) {
            try {
                session.setPessimisticLockTimeoutDefault(Integer.parseInt(pessimisticLockTimeout));
            } catch (NumberFormatException invalid) {
                session.handleException(ValidationException.invalidValueForProperty(pessimisticLockTimeout, PersistenceUnitProperties.PESSIMISTIC_LOCK_TIMEOUT, invalid));
            }
        }
    }

    /**
     * Update the default pessimistic lock timeout unit value.
     * @param persistenceProperties the properties map
     */
    protected void updatePessimisticLockTimeoutUnit(Map persistenceProperties) {
        String pessimisticLockTimeoutUnit = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.PESSIMISTIC_LOCK_TIMEOUT_UNIT, persistenceProperties, session);

        if (pessimisticLockTimeoutUnit != null) {
            try {
                TimeUnit unit = TimeUnit.valueOf(pessimisticLockTimeoutUnit);
                session.setPessimisticLockTimeoutUnitDefault(unit);
            } catch (NumberFormatException invalid) {
                session.handleException(ValidationException.invalidValueForProperty(pessimisticLockTimeoutUnit, PersistenceUnitProperties.PESSIMISTIC_LOCK_TIMEOUT_UNIT, invalid));
            }
        }
    }

    /**
     * Enable or disable statements cached, update statements cache size.
     * The method needs to be called in deploy stage.
     */
    protected void updateCacheStatementSettings(Map m){
        // Cache statements if flag was specified.
        String statmentsNeedBeCached = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CACHE_STATEMENTS, m, session);
        if (statmentsNeedBeCached!=null) {
            if (statmentsNeedBeCached.equalsIgnoreCase("true")) {
                if (session.isServerSession() && ((ServerSession)session).getConnectionPools().isEmpty()){
                    session.log(SessionLog.WARNING, SessionLog.PROPERTIES, "persistence_unit_ignores_statments_cache_setting", new Object[]{null});
                 } else {
                     session.getProject().getLogin().setShouldCacheAllStatements(true);
                 }
            } else if (statmentsNeedBeCached.equalsIgnoreCase("false")) {
                session.getProject().getLogin().setShouldCacheAllStatements(false);
            } else {
                session.handleException(ValidationException.invalidBooleanValueForEnableStatmentsCached(statmentsNeedBeCached));
            }
        }

        // Set statement cache size if specified.
        String cacheStatementsSize = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CACHE_STATEMENTS_SIZE, m, session);
        if (cacheStatementsSize!=null) {
            try {
                session.getProject().getLogin().setStatementCacheSize(Integer.parseInt(cacheStatementsSize));
            } catch (NumberFormatException e) {
                session.handleException(ValidationException.invalidCacheStatementsSize(cacheStatementsSize,e.getMessage()));
            }
        }
    }

    /**
     * Enable or disable default allowing 0 as an id.
     */
    @SuppressWarnings("deprecation")
    protected void updateAllowZeroIdSetting(Map m) {
        String allowZero = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.ALLOW_ZERO_ID, m, this.session);
        if (allowZero != null) {
            if (allowZero.equalsIgnoreCase("true")) {
               Helper.isZeroValidPrimaryKey = true;
            } else if (allowZero.equalsIgnoreCase("false")) {
                Helper.isZeroValidPrimaryKey = false;
            } else {
                session.handleException(ValidationException.invalidBooleanValueForProperty(allowZero, PersistenceUnitProperties.ALLOW_ZERO_ID));
            }
        }
    }

    /**
     * Enable or disable default allowing 0 as an id.
     */
    protected void updateIdValidation(Map m) {
        String idValidationString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.ID_VALIDATION, m, session);
        if (idValidationString != null) {
            session.getProject().setDefaultIdValidation(IdValidation.valueOf(idValidationString));
        }
    }


    /**
     * Sets the SharedCacheMode with values from the jakarta.persistence.sharedCache.mode property. If
     * user enters an invalid caching type, valueOf will throw an illegal argument exception, e.g.
     * java.lang.IllegalArgumentException: No enum const class
     * jakarta.persistence.SharedCacheMode.ALLBOGUS
     */
    protected void updateSharedCacheMode(Map m) {
        String sharedCacheMode = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.SHARED_CACHE_MODE, m, session);
        if (sharedCacheMode != null) {
            processor.getProject().setSharedCacheMode(SharedCacheMode.valueOf(sharedCacheMode));
        }
    }

    /**
     * sets the TABLE_CREATION_SUFFIX property on the session's project to be applied to all table creation statements (DDL)
     */
    protected void updateTableCreationSettings(Map m) {
        String tableCreationSuffix = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.TABLE_CREATION_SUFFIX, m, session);
        if (tableCreationSuffix != null && tableCreationSuffix.length()>0) {
            session.getPlatform().setTableCreationSuffix(tableCreationSuffix);
        }
    }

    /**
     * Sets shouldCreateIndicesOnForeignKeys DDL generation option.
     */
    protected void updateIndexForeignKeys(Map m) {
        String indexForeignKeys = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.DDL_GENERATION_INDEX_FOREIGN_KEYS, m, this.session);
        if (indexForeignKeys != null && (indexForeignKeys.length() > 0)) {
            if (indexForeignKeys.equalsIgnoreCase("true") ){
                this.session.getProject().getLogin().setShouldCreateIndicesOnForeignKeys(true);
            } else if (indexForeignKeys.equalsIgnoreCase("false")){
                this.session.getProject().getLogin().setShouldCreateIndicesOnForeignKeys(false);
            } else {
                this.session.handleException(ValidationException.invalidBooleanValueForProperty(indexForeignKeys, PersistenceUnitProperties.DDL_GENERATION_INDEX_FOREIGN_KEYS));
            }
        }
    }

    /**
     * Enable or disable default temporal mutable setting.
     * The method needs to be called in deploy stage.
     */
    protected void updateTemporalMutableSetting(Map m) {
        // Cache statements if flag was specified.
        String temporalMutable = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.TEMPORAL_MUTABLE, m, session);
        if (temporalMutable != null) {
            if (temporalMutable.equalsIgnoreCase("true")) {
               session.getProject().setDefaultTemporalMutable(true);
            } else if (temporalMutable.equalsIgnoreCase("false")) {
               session.getProject().setDefaultTemporalMutable(false);
            } else {
                session.handleException(ValidationException.invalidBooleanValueForProperty(temporalMutable, PersistenceUnitProperties.TEMPORAL_MUTABLE));
            }
        }
    }

    /**
     * Copy named queries defined in EclipseLink descriptor into the session if it was indicated to do so.
     */
    protected void setDescriptorNamedQueries(Map m) {
        // Copy named queries to session if the flag has been specified.
        String addNamedQueriesString  = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.INCLUDE_DESCRIPTOR_QUERIES, m, session);
        if (addNamedQueriesString!=null) {
            if (addNamedQueriesString.equalsIgnoreCase("true")) {
                session.copyDescriptorNamedQueries(false);
            } else {
                if (!addNamedQueriesString.equalsIgnoreCase("false")) {
                   session.handleException(ValidationException.invalidBooleanValueForAddingNamedQueries(addNamedQueriesString));
                }
            }
        }
    }

    private void updateQueryTimeout(Map persistenceProperties) {
        String timeout = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.QUERY_TIMEOUT, persistenceProperties, session);
        try {
            if (timeout != null) {
                session.setQueryTimeoutDefault(Integer.parseInt(timeout));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(timeout, PersistenceUnitProperties.QUERY_TIMEOUT, exception));
        }
    }

    //Bug #456067: Added persistence unit support for timeout units
    private void updateQueryTimeoutUnit(Map persistenceProperties) {
        String timeoutUnit = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.QUERY_TIMEOUT_UNIT, persistenceProperties, session);
        try {
            if (timeoutUnit != null) {
                TimeUnit unit = TimeUnit.valueOf(timeoutUnit);
                session.setQueryTimeoutUnitDefault(unit);
            }
        } catch (IllegalArgumentException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(timeoutUnit, PersistenceUnitProperties.QUERY_TIMEOUT_UNIT, exception));
        }
    }

    private void updateLockingTimestampDefault(Map persistenceProperties) {
        String local = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.USE_LOCAL_TIMESTAMP, persistenceProperties, session);
        try {
            if (local != null) {
                for (ClassDescriptor descriptor: session.getProject().getDescriptors().values()) {
                    OptimisticLockingPolicy policy = descriptor.getOptimisticLockingPolicy();
                    if (policy instanceof TimestampLockingPolicy) {
                        ((TimestampLockingPolicy)policy).setUsesServerTime(!Boolean.parseBoolean(local));
                    }
                }
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(local, PersistenceUnitProperties.USE_LOCAL_TIMESTAMP, exception));
        }
    }

    //Bug #333100: Added support for turning off SQL deferral default behavior
    private void updateSQLCallDeferralDefault(Map persistenceProperties) {
        String defer = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.SQL_CALL_DEFERRAL, persistenceProperties, this.session);
        if (defer != null) {
            if (defer.equalsIgnoreCase("true")) {
                this.session.getProject().setAllowSQLDeferral(true);
            } else if (defer.equalsIgnoreCase("false")) {
                this.session.getProject().setAllowSQLDeferral(false);
            } else {
                this.session.handleException(ValidationException.invalidBooleanValueForProperty(defer, PersistenceUnitProperties.SQL_CALL_DEFERRAL));
            }
        }
    }

    private void updateNamingIntoIndexed(Map persistenceProperties) {
        String namingIntoIndexed = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.NAMING_INTO_INDEXED, persistenceProperties, this.session);
        if (namingIntoIndexed != null) {
            if (namingIntoIndexed.equalsIgnoreCase("true")) {
                this.session.getProject().setNamingIntoIndexed(true);
            } else if (namingIntoIndexed.equalsIgnoreCase("false")) {
                this.session.getProject().setNamingIntoIndexed(false);
            } else {
                this.session.handleException(ValidationException.invalidBooleanValueForProperty(namingIntoIndexed, PersistenceUnitProperties.NAMING_INTO_INDEXED));
            }
        }
    }

    private void updateConcurrencyManagerWaitTime(Map persistenceProperties) {
        String acquireWaitTime = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME, persistenceProperties, session);
        try {
            if (acquireWaitTime != null) {
                ConcurrencyUtil.SINGLETON.setAcquireWaitTime(Long.parseLong(acquireWaitTime));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(acquireWaitTime, PersistenceUnitProperties.CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME, exception));
        }
    }

    private void updateConcurrencyManagerBuildObjectCompleteWaitTime(Map persistenceProperties) {
        String buildObjectCompleteWaitTime = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_BUILD_OBJECT_COMPLETE_WAIT_TIME, persistenceProperties, session);
        try {
            if (buildObjectCompleteWaitTime != null) {
                ConcurrencyUtil.SINGLETON.setBuildObjectCompleteWaitTime(Long.parseLong(buildObjectCompleteWaitTime));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(buildObjectCompleteWaitTime, PersistenceUnitProperties.CONCURRENCY_MANAGER_BUILD_OBJECT_COMPLETE_WAIT_TIME, exception));
        }
    }

    private void updateConcurrencyManagerMaxAllowedSleepTime(Map persistenceProperties) {
        String maxAllowedSleepTime = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_MAX_SLEEP_TIME, persistenceProperties, session);
        try {
            if (maxAllowedSleepTime != null) {
                ConcurrencyUtil.SINGLETON.setMaxAllowedSleepTime(Long.parseLong(maxAllowedSleepTime));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(maxAllowedSleepTime, PersistenceUnitProperties.CONCURRENCY_MANAGER_MAX_SLEEP_TIME, exception));
        }
    }

    private void updateConcurrencyManagerMaxAllowedFrequencyToProduceTinyDumpLogMessage(Map persistenceProperties) {
        String maxAllowedSleepTime = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_TINY_MESSAGE, persistenceProperties, session);
        try {
            if (maxAllowedSleepTime != null) {
                ConcurrencyUtil.SINGLETON.setMaxAllowedFrequencyToProduceTinyDumpLogMessage(Long.parseLong(maxAllowedSleepTime));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(maxAllowedSleepTime, PersistenceUnitProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_TINY_MESSAGE, exception));
        }
    }

    private void updateConcurrencyManagerMaxAllowedFrequencyToProduceMassiveDumpLogMessage(Map persistenceProperties) {
        String maxAllowedSleepTime = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_MASSIVE_MESSAGE, persistenceProperties, session);
        try {
            if (maxAllowedSleepTime != null) {
                ConcurrencyUtil.SINGLETON.setMaxAllowedFrequencyToProduceMassiveDumpLogMessage(Long.parseLong(maxAllowedSleepTime));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(maxAllowedSleepTime, PersistenceUnitProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_MASSIVE_MESSAGE, exception));
        }
    }

    private void updateConcurrencyManagerAllowInterruptedExceptionFired(Map persistenceProperties) {
        String allowInterruptedExceptionFired = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION, persistenceProperties, session);
        try {
            if (allowInterruptedExceptionFired != null) {
                ConcurrencyUtil.SINGLETON.setAllowInterruptedExceptionFired(Boolean.parseBoolean(allowInterruptedExceptionFired));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(allowInterruptedExceptionFired, PersistenceUnitProperties.CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION, exception));
        }
    }

    private void updateConcurrencyManagerAllowConcurrencyExceptionToBeFiredUp(Map persistenceProperties) {
        String allowConcurrencyExceptionToBeFiredUp = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_ALLOW_CONCURRENCY_EXCEPTION, persistenceProperties, session);
        try {
            if (allowConcurrencyExceptionToBeFiredUp != null) {
                ConcurrencyUtil.SINGLETON.setAllowConcurrencyExceptionToBeFiredUp(Boolean.parseBoolean(allowConcurrencyExceptionToBeFiredUp));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(allowConcurrencyExceptionToBeFiredUp, PersistenceUnitProperties.CONCURRENCY_MANAGER_ALLOW_CONCURRENCY_EXCEPTION, exception));
        }
    }

    private void updateConcurrencyManagerAllowTakingStackTraceDuringReadLockAcquisition(Map persistenceProperties) {
        String allowTakingStackTraceDuringReadLockAcquisition = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK, persistenceProperties, session);
        try {
            if (allowTakingStackTraceDuringReadLockAcquisition != null) {
                ConcurrencyUtil.SINGLETON.setAllowTakingStackTraceDuringReadLockAcquisition(Boolean.parseBoolean(allowTakingStackTraceDuringReadLockAcquisition));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(allowTakingStackTraceDuringReadLockAcquisition, PersistenceUnitProperties.CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK, exception));
        }
    }

    private void updateConcurrencyManagerUseObjectBuildingSemaphore(Map persistenceProperties) {
        String useObjectBuildingSemaphore = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_OBJECT_BUILDING, persistenceProperties, session);
        try {
            if (useObjectBuildingSemaphore != null) {
                ConcurrencyUtil.SINGLETON.setUseSemaphoreInObjectBuilder(Boolean.parseBoolean(useObjectBuildingSemaphore));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(useObjectBuildingSemaphore, PersistenceUnitProperties.CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_OBJECT_BUILDING, exception));
        }
    }

    private void updateConcurrencyManagerUseWriteLockManagerSemaphore(Map persistenceProperties) {
        String useWriteLockManagerSemaphore = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS, persistenceProperties, session);
        try {
            if (useWriteLockManagerSemaphore != null) {
                ConcurrencyUtil.SINGLETON.setUseSemaphoreToLimitConcurrencyOnWriteLockManagerAcquireRequiredLocks(Boolean.parseBoolean(useWriteLockManagerSemaphore));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(useWriteLockManagerSemaphore, PersistenceUnitProperties.CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS, exception));
        }
    }

    private void updateConcurrencyManagerNoOfThreadsAllowedToObjectBuildInParallel(Map persistenceProperties) {
        String noOfThreadsAllowedToObjectBuildInParallel = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS, persistenceProperties, session);
        try {
            if (noOfThreadsAllowedToObjectBuildInParallel != null) {
                ConcurrencyUtil.SINGLETON.setNoOfThreadsAllowedToObjectBuildInParallel(Integer.parseInt(noOfThreadsAllowedToObjectBuildInParallel));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(noOfThreadsAllowedToObjectBuildInParallel, PersistenceUnitProperties.CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS, exception));
        }
    }

    private void updateConcurrencyManagerNoOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel(Map persistenceProperties) {
        String noOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS, persistenceProperties, session);
        try {
            if (noOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel != null) {
                ConcurrencyUtil.SINGLETON.setNoOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel(Integer.parseInt(noOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(noOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel, PersistenceUnitProperties.CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS, exception));
        }
    }

    private void updateConcurrencySemaphoreMaxTimePermit(Map persistenceProperties) {
        String concurrencySemaphoreMaxTimePermit = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_SEMAPHORE_MAX_TIME_PERMIT, persistenceProperties, session);
        try {
            if (concurrencySemaphoreMaxTimePermit != null) {
                ConcurrencyUtil.SINGLETON.setConcurrencySemaphoreMaxTimePermit(Long.parseLong(concurrencySemaphoreMaxTimePermit));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(concurrencySemaphoreMaxTimePermit, PersistenceUnitProperties.CONCURRENCY_SEMAPHORE_MAX_TIME_PERMIT, exception));
        }
    }

    private void updateConcurrencySemaphoreLogTimeout(Map persistenceProperties) {
        String concurrencySemaphoreLogTimeout = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONCURRENCY_SEMAPHORE_LOG_TIMEOUT, persistenceProperties, session);
        try {
            if (concurrencySemaphoreLogTimeout != null) {
                ConcurrencyUtil.SINGLETON.setConcurrencySemaphoreLogTimeout(Long.parseLong(concurrencySemaphoreLogTimeout));
            }
        } catch (NumberFormatException exception) {
            this.session.handleException(ValidationException.invalidValueForProperty(concurrencySemaphoreLogTimeout, PersistenceUnitProperties.CONCURRENCY_SEMAPHORE_LOG_TIMEOUT, exception));
        }
    }

    /**
     * Enable or disable extended logging of JPA L2 cache usage.
     * The method needs to be called in deploy stage.
     */
    protected void updateAllowExtendedCacheLogging(Map m){
        String allowExtendedCacheLogging = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CACHE_EXTENDED_LOGGING, m, session);

        if (allowExtendedCacheLogging != null) {
            if (allowExtendedCacheLogging.equalsIgnoreCase("true")) {
                session.getProject().setAllowExtendedCacheLogging(true);
            } else if (allowExtendedCacheLogging.equalsIgnoreCase("false")) {
                session.getProject().setAllowExtendedCacheLogging(false);
            } else {
                session.handleException(ValidationException.invalidBooleanValueForProperty(allowExtendedCacheLogging, PersistenceUnitProperties.CACHE_EXTENDED_LOGGING));
            }
        }
    }

    /**
     * Enable or disable extended thread logging.
     * The method needs to be called in deploy stage.
     */
    protected void updateAllowExtendedThreadLogging(Map m){
        String allowExtendedThreadLogging = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.THREAD_EXTENDED_LOGGING, m, session);

        if (allowExtendedThreadLogging != null) {
            if (allowExtendedThreadLogging.equalsIgnoreCase("true")) {
                session.getProject().setAllowExtendedThreadLogging(true);
            } else if (allowExtendedThreadLogging.equalsIgnoreCase("false")) {
                session.getProject().setAllowExtendedThreadLogging(false);
            } else {
                session.handleException(ValidationException.invalidBooleanValueForProperty(allowExtendedThreadLogging, PersistenceUnitProperties.THREAD_EXTENDED_LOGGING));
            }
        }
    }

    /**
     * Enable or disable thread dump addition to extended thread logging.
     * The method needs to be called in deploy stage.
     */
    protected void updateAllowExtendedThreadLoggingThreadDump(Map m){
        String allowExtendedThreadLoggingThreadDump = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.THREAD_EXTENDED_LOGGING_THREADDUMP, m, session);

        if (allowExtendedThreadLoggingThreadDump != null) {
            if (allowExtendedThreadLoggingThreadDump.equalsIgnoreCase("true")) {
                session.getProject().setAllowExtendedThreadLoggingThreadDump(true);
            } else if (allowExtendedThreadLoggingThreadDump.equalsIgnoreCase("false")) {
                session.getProject().setAllowExtendedThreadLoggingThreadDump(false);
            } else {
                session.handleException(ValidationException.invalidBooleanValueForProperty(allowExtendedThreadLoggingThreadDump, PersistenceUnitProperties.THREAD_EXTENDED_LOGGING_THREADDUMP));
            }
        }
    }

    /**
     * If Bean Validation is enabled, bootstraps Bean Validation on descriptors.
     * @param puProperties merged properties for this persistence unit
     */
    private void addBeanValidationListeners(Map puProperties, ClassLoader appClassLoader) {
        ValidationMode validationMode = getValidationMode(persistenceUnitInfo, puProperties);
        if (validationMode == ValidationMode.AUTO || validationMode == ValidationMode.CALLBACK) {
            // BeanValidationInitializationHelper contains static reference to jakarta.validation.* classes. We need to support
            // environment where these classes are not available.
            // To guard against some vms that eagerly resolve, reflectively load class to prevent any static reference to it
            String helperClassName = "org.eclipse.persistence.internal.jpa.deployment.BeanValidationInitializationHelper$BeanValidationInitializationHelperImpl";
            Class helperClass;
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                    try {
                        helperClass = AccessController.doPrivileged(
                                new PrivilegedClassForName<>(helperClassName, true, appClassLoader));
                    } catch (Throwable t) {
                        // Try the ClassLoader that loaded Eclipselink classes
                        ClassLoader eclipseLinkClassLoader = EntityManagerSetupImpl.class.getClassLoader();
                        helperClass = AccessController.doPrivileged(new PrivilegedClassForName<>(helperClassName, true, eclipseLinkClassLoader));
                    }
                } else {
                    try {
                        helperClass = PrivilegedAccessHelper.getClassForName(helperClassName, true, appClassLoader);
                    } catch (Throwable t) {
                        // Try the ClassLoader that loaded Eclipselink classes
                        ClassLoader eclipseLinkClassLoader = EntityManagerSetupImpl.class.getClassLoader();
                        helperClass = PrivilegedAccessHelper.getClassForName(helperClassName, true, eclipseLinkClassLoader);
                    }
                }
                BeanValidationInitializationHelper beanValidationInitializationHelper = (BeanValidationInitializationHelper)helperClass.getConstructor().newInstance();
                beanValidationInitializationHelper.bootstrapBeanValidation(puProperties, session, appClassLoader);
            } catch (Throwable e) {  //Catching Throwable to catch any linkage errors on vms that resolve eagerly
                if (validationMode == ValidationMode.CALLBACK) {
                    throw PersistenceUnitLoadingException.exceptionObtainingRequiredBeanValidatorFactory(e);
                } // else validationMode == ValidationMode.AUTO. Log a message, Ignore the exception
                this.session.log(SessionLog.FINEST, SessionLog.JPA, "validation_factory_not_initialized", new Object[]{ e.getMessage() });
            }
        }
    }

    /**
     * Validation mode from information in persistence.xml and properties specified at EMF creation
     * @param persitenceUnitInfo PersitenceUnitInfo instance for this persistence unit
     * @param puProperties merged properties for this persistence unit
     * @return validation mode
     */
    private static ValidationMode getValidationMode(PersistenceUnitInfo persitenceUnitInfo, Map puProperties) {
        //Check if overridden at emf creation
        String validationModeAtEMFCreation = (String) puProperties.get(PersistenceUnitProperties.VALIDATION_MODE);
        if(validationModeAtEMFCreation != null) {
            // User will receive IllegalArgumentException if an invalid mode has been specified
            return ValidationMode.valueOf(validationModeAtEMFCreation.toUpperCase(Locale.ROOT));
        }

        //otherwise:
        ValidationMode validationMode = null;
        // Initialize with value in persitence.xml
        // Using reflection to call getValidationMode to prevent blowing up while we are running in JPA 1.0 environment
        // (This would be all JavaEE5 appservers) where PersistenceUnitInfo does not implement method getValidationMode().
        try {
            Method method = null;
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                method = AccessController.doPrivileged(new PrivilegedGetDeclaredMethod(PersistenceUnitInfo.class, "getValidationMode", null));
                validationMode = (ValidationMode) AccessController.doPrivileged(new PrivilegedMethodInvoker(method, persitenceUnitInfo));
            } else {
                method = PrivilegedAccessHelper.getDeclaredMethod(PersistenceUnitInfo.class, "getValidationMode", null);
                validationMode = PrivilegedAccessHelper.invokeMethod(method, persitenceUnitInfo, null);
            }
        } catch (Throwable exception) {
            // We are running in JavaEE5 environment. Catch and swallow any exceptions and return null.
        }

        if(validationMode == null) {
            // Default to AUTO as specified in JPA spec.
            validationMode = ValidationMode.AUTO;
        }
        return validationMode;
    }

    /**
     * INTERNAL:
     * Return an instance of Metamodel interface for access to the
     * metamodel of the persistence unit.
     * This method will complete any initialization done in the predeploy phase
     * of deployment.
     * @return Metamodel instance
     * @since Java Persistence 2.0
     */
    public Metamodel getMetamodel(ClassLoader classLoader) {
        preInitializeMetamodel();
        if (!((MetamodelImpl)metaModel).isInitialized()){
            ((MetamodelImpl)metaModel).initialize(classLoader);
            // If the canonical metamodel classes exist, initialize them
            initializeCanonicalMetamodel(metaModel);
        }
        return metaModel;
    }

    /**
     * INTERNAL:
     * Initialize the Canonical Metamodel classes generated by EclipseLink
     * @since Java Persistence 2.0
     */
    protected void initializeCanonicalMetamodel(Metamodel model) {
        // 338837: verify that the collection is not empty - this would mean entities did not make it into the search path
        if(null == model.getManagedTypes() || model.getManagedTypes().isEmpty()) {
            getSession().log(SessionLog.FINER, SessionLog.METAMODEL, "metamodel_type_collection_empty");
        }
        for (ManagedType manType : model.getManagedTypes()) {
            boolean classInitialized = false;
            String className = MetadataHelper.getQualifiedCanonicalName(manType.getJavaType().getName(), getSession());
            try {
                Class clazz = this.getSession().getDatasourcePlatform().convertObject(className, ClassConstants.CLASS);
                classInitialized=true;
                this.getSession().log(SessionLog.FINER, SessionLog.METAMODEL, "metamodel_canonical_model_class_found", className);
                String fieldName = "";
                for(Object attribute : manType.getDeclaredAttributes()) {
                    try {
                        fieldName = ((Attribute)attribute).getName();
                        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                            AccessController.doPrivileged(new PrivilegedGetDeclaredField(clazz, fieldName, false)).set(clazz, attribute);
                        } else {
                            PrivilegedAccessHelper.getDeclaredField(clazz, fieldName, false).set(clazz, attribute);
                        }
                    } catch (NoSuchFieldException nsfe) {
                        // Ignore fields missing in canonical model (dclarke bug 346106)
                    } catch (Exception e) {
                       ValidationException v = ValidationException.invalidFieldForClass(fieldName, clazz);
                       v.setInternalException(e);
                       throw v;
                    }
                }
            } catch (ConversionException exception){
            }
            if (!classInitialized) {
                getSession().log(SessionLog.FINER, SessionLog.METAMODEL, "metamodel_canonical_model_class_not_found", className);
            }
        }
    }

    /**
     * INTERNAL:
     * Convenience function to allow us to reset the Metamodel
     * in the possible case that we want to regenerate it.
     * This function is outside of the JPA 2.0 specification.
     * @param aMetamodel
     * @since Java Persistence 2.0
     */
    public void setMetamodel(Metamodel aMetamodel) {
        this.metaModel = aMetamodel;
    }

    public boolean mustBeCompositeMember() {
        return mustBeCompositeMember(this.persistenceUnitInfo);
    }

    public boolean isCompositeMember() {
        return this.compositeEmSetupImpl != null;
    }

    public boolean isComposite() {
        return this.compositeMemberEmSetupImpls != null;
    }

    public static boolean mustBeCompositeMember(PersistenceUnitInfo puInfo) {
        String mustBeCompositeMemberStr = PropertiesHandler.getPropertyValue(PersistenceUnitProperties.COMPOSITE_UNIT_MEMBER, puInfo.getProperties(), false);
        if(mustBeCompositeMemberStr != null) {
            return mustBeCompositeMemberStr.equals("true");
        } else {
            return false;
        }
    }
    public static boolean isComposite(PersistenceUnitInfo puInfo) {
        String isCompositeString = PropertiesHandler.getPropertyValue(PersistenceUnitProperties.COMPOSITE_UNIT, puInfo.getProperties(), false);
        if(isCompositeString != null) {
            return isCompositeString.equals("true");
        } else {
            return false;
        }
    }

    public void setCompositeEmSetupImpl(EntityManagerSetupImpl compositeEmSetupImpl) {
        this.compositeEmSetupImpl = compositeEmSetupImpl;
    }

    public EntityManagerSetupImpl getCompositeEmSetupImpl() {
        return this.compositeEmSetupImpl;
    }

    // predeploy method will be used for static weaving
    public void setStaticWeaveInfo(StaticWeaveInfo staticWeaveInfo) {
        this.staticWeaveInfo = staticWeaveInfo;
    }

    protected void predeployCompositeMembers(Map predeployProperties, ClassLoader tempClassLoader) {
        // get all puInfos found in jar-files specified in composite's persistence.xml
        // all these puInfos are not composite because composites are recursively "taken apart", too.
        Set<SEPersistenceUnitInfo> compositeMemberPuInfos = getCompositeMemberPuInfoSet(persistenceUnitInfo, predeployProperties);
        // makes sure each member has a non-null property, overrides where required properties with composite's predeploy properties.
        updateCompositeMembersProperties(compositeMemberPuInfos, predeployProperties);
        // Don't log these properties - may contain passwords. The properties will be logged by contained persistence units.
        Map compositeMemberMapOfProperties = (Map)getConfigProperty(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, predeployProperties);
        this.compositeMemberEmSetupImpls = new HashSet<>(compositeMemberPuInfos.size());
        this.processor = new MetadataProcessor();
        if (enableWeaving) {
            this.weaver = new PersistenceWeaver(new HashMap<String, ClassDetails>());
        }

        // create containedEmSetupImpls and predeploy them for the first time.
        // predeploy divided in three stages (modes):
        // all composite members should complete a stage before any of them can move to the next one.
        for (SEPersistenceUnitInfo compositeMemberPuInfo : compositeMemberPuInfos) {
            // set composite's temporary classloader
            compositeMemberPuInfo.setNewTempClassLoader(tempClassLoader);
            String containedPuName = compositeMemberPuInfo.getPersistenceUnitName();
            EntityManagerSetupImpl containedEmSetupImpl = new EntityManagerSetupImpl(containedPuName, containedPuName);
            // set composite
            containedEmSetupImpl.setCompositeEmSetupImpl(this);
            // non-null only in case predeploy is used for static weaving
            containedEmSetupImpl.setStaticWeaveInfo(this.staticWeaveInfo);
            // the properties guaranteed to be non-null after updateCompositeMemberProperties call
            Map compositeMemberProperties = (Map)compositeMemberMapOfProperties.get(containedPuName);
            containedEmSetupImpl.predeploy(compositeMemberPuInfo, compositeMemberProperties);
            // reset temporary classloader back to the original
            compositeMemberPuInfo.setNewTempClassLoader(compositeMemberPuInfo.getClassLoader());
            this.compositeMemberEmSetupImpls.add(containedEmSetupImpl);
        }

        // after the first loop containedEmSetupImpls are in HalfPredeployed state,
        // mode = COMPOSITE_MEMBER_MIDDLE mode
        for(EntityManagerSetupImpl containedEmSetupImpl : this.compositeMemberEmSetupImpls) {
            // properties not used, puInfo already set
            containedEmSetupImpl.predeploy(null, null);
        }

        // after the second loop containedEmSetupImpls are still in HalfPredeployed state,
        // mode = COMPOSITE_MEMBER_FINAL mode
        for(EntityManagerSetupImpl containedEmSetupImpl : this.compositeMemberEmSetupImpls) {
            // properties not used, puInfo already set
            PersistenceWeaver containedWeaver = (PersistenceWeaver)containedEmSetupImpl.predeploy(null, null);
            // containedEmSetupImpl is finally in Predeployed state.
            // if both composite and composite member weavings enabled copy class details from member's weaver to composite's one.
            if(enableWeaving && containedWeaver != null) {
                this.weaver.getClassDetailsMap().putAll(containedWeaver.getClassDetailsMap());
            }
        }

        if(enableWeaving && this.weaver.getClassDetailsMap().isEmpty()) {
            this.weaver = null;
        }
    }

    protected void deployCompositeMembers(Map deployProperties, ClassLoader realClassLoader) {
        // Don't log these properties - may contain passwords. The properties will be logged by contained persistence units.
        Map compositeMemberMapOfProperties = (Map)getConfigProperty(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, deployProperties);
        for(EntityManagerSetupImpl compositeMemberEmSetupImpl : this.compositeMemberEmSetupImpls) {
            // the properties guaranteed to be non-null after updateCompositeMemberProperties call
            Map compositeMemberProperties = (Map)compositeMemberMapOfProperties.get(compositeMemberEmSetupImpl.getPersistenceUnitInfo().getPersistenceUnitName());
            compositeMemberEmSetupImpl.deploy(realClassLoader, compositeMemberProperties);
            AbstractSession containedSession = compositeMemberEmSetupImpl.getSession();
            ((SessionBroker)session).registerSession(containedSession.getName(), containedSession);
        }
    }

    /**
     * INTERNAL:
     * Cause the first phase of metamodel initialization.  This phase involves detecting the classes involved
     * and build metamodel instances for them.
     */
    public void preInitializeMetamodel(){
        // perform lazy initialisation
        Metamodel tempMetaModel = null;
        if (null == metaModel){
            // 338837: verify that the collection is not empty - this would mean entities did not make it into the search path
            tempMetaModel = new MetamodelImpl(this);
            // set variable after init has executed without exception
            metaModel = tempMetaModel;
        }
    }

    /**
     * INTERNAL:
     * First phase of canonical metamodel initialization.  For each class the metamodel is aware of, check
     * for a canonical metamodel class and initialize each attribute in it with a proxy that can cause the
     * rest of the metamodel population.  Attributes are found reflectively rather than through the metamodel
     * to avoid having to further initialize the metamodel.
     * @param factory
     */
    public void preInitializeCanonicalMetamodel(EntityManagerFactoryImpl factory){
        // 338837: verify that the collection is not empty - this would mean entities did not make it into the search path
        if(null == metaModel.getManagedTypes() || metaModel.getManagedTypes().isEmpty()) {
            getSession().log(SessionLog.FINER, SessionLog.METAMODEL, "metamodel_type_collection_empty");
        }
        for (ManagedType manType : metaModel.getManagedTypes()) {
            boolean classInitialized = false;
            String className = MetadataHelper.getQualifiedCanonicalName(((ManagedTypeImpl)manType).getJavaTypeName(), getSession());
            try {
                Class clazz = this.getSession().getDatasourcePlatform().convertObject(className, ClassConstants.CLASS);
                classInitialized=true;
                this.getSession().log(SessionLog.FINER, SessionLog.METAMODEL, "metamodel_canonical_model_class_found", className);
                Field[] fields = null;
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    fields = AccessController.doPrivileged(new PrivilegedGetDeclaredFields(clazz));
                } else {
                    fields = PrivilegedAccessHelper.getDeclaredFields(clazz);
                }
                for(Field attribute : fields) {
                    if (Attribute.class.isAssignableFrom(attribute.getType())){
                        Object assignedAttribute = null;
                        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                            assignedAttribute = AccessController.doPrivileged(new PrivilegedGetValueFromField(attribute, null));
                        } else {
                            assignedAttribute =PrivilegedAccessHelper.getValueFromField(attribute, null);
                        }
                        AttributeProxyImpl proxy = null;
                        if (assignedAttribute == null){
                            if (SingularAttribute.class.isAssignableFrom(attribute.getType())){
                                proxy = new SingularAttributeProxyImpl();
                            } else if (MapAttribute.class.isAssignableFrom(attribute.getType())){
                                proxy = new MapAttributeProxyImpl();
                            } else if (SetAttribute.class.isAssignableFrom(attribute.getType())){
                                proxy = new SetAttributeProxyImpl();
                            } else if (ListAttribute.class.isAssignableFrom(attribute.getType())){
                                proxy = new ListAttributeProxyImpl();
                            } else if (CollectionAttribute.class.isAssignableFrom(attribute.getType())){
                                proxy = new CollectionAttributeProxyImpl();
                            }
                            if (proxy != null){
                                attribute.setAccessible(true);
                                attribute.set(null, proxy);
                            }
                        } else if (assignedAttribute instanceof AttributeProxyImpl){
                            proxy = (AttributeProxyImpl)assignedAttribute;
                        }
                        if (proxy != null){
                            proxy.addFactory(factory);
                        }
                    }
                }
            } catch (PrivilegedActionException pae){
                getSession().logThrowable(SessionLog.FINEST,  SessionLog.METAMODEL, pae);
            } catch (IllegalAccessException iae){
                getSession().logThrowable(SessionLog.FINEST,  SessionLog.METAMODEL, iae);
            } catch (ConversionException ce){
            }
            if (!classInitialized) {
                getSession().log(SessionLog.FINER, SessionLog.METAMODEL, "metamodel_canonical_model_class_not_found", className);
            }
        }
    }

    /*
     * Overide composite member properties' map with a new one, which
     * has (possibly empty but non-null) properties for each composite member,
     * for required properties overrides values with those from composite properties.
     */
    protected void updateCompositeMembersProperties(Map compositeProperties) {
        Set<SEPersistenceUnitInfo> compositePuInfos = new HashSet<>(compositeMemberEmSetupImpls.size());
        for (EntityManagerSetupImpl compositeMemberEmSetupImpl : compositeMemberEmSetupImpls) {
            compositePuInfos.add((SEPersistenceUnitInfo)compositeMemberEmSetupImpl.persistenceUnitInfo);
        }
        updateCompositeMembersProperties(compositePuInfos, compositeProperties);
    }

    /*
     * Overide composite member properties' map with a new one, which
     * has (possibly empty but non-null) properties for each composite member,
     * for required properties overrides values with those from composite properties.
     * Parameter compositePuInfo indicates whether compositeMemberPreoperties should be merged (overriding) with its puInfo properties
     * (false for predeploy, true for deploy).
     */
    protected void updateCompositeMembersProperties(Set<SEPersistenceUnitInfo> compositePuInfos, Map compositeProperties) {
        // Don't log these properties - may contain passwords. The properties will be logged by contained persistence units.
        Map compositeMemberMapOfProperties = (Map)getConfigProperty(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, compositeProperties);
        Map newCompositeMemberMapOfProperties;
        if (compositeMemberMapOfProperties == null) {
            newCompositeMemberMapOfProperties = new HashMap<>(compositePuInfos.size());
        } else {
            // Don't alter user-supplied properties' map - create a copy instead
            newCompositeMemberMapOfProperties = new HashMap<>(compositeMemberMapOfProperties);
        }

        for (SEPersistenceUnitInfo compositePuInfo : compositePuInfos) {
            String compositeMemberPuName = compositePuInfo.getPersistenceUnitName();
            Map compositeMemberProperties = (Map)newCompositeMemberMapOfProperties.get(compositeMemberPuName);
            Map newCompositeMemberProperties;
            if (compositeMemberProperties == null) {
                newCompositeMemberProperties = new HashMap<>();
            } else {
                // Don't alter user-supplied properties - create a copy instead
                newCompositeMemberProperties = new HashMap<>(compositeMemberProperties);
            }
            overrideMemberProperties(newCompositeMemberProperties, compositeProperties);
            newCompositeMemberProperties = mergeMaps(newCompositeMemberProperties, compositePuInfo.getProperties());
            translateOldProperties(newCompositeMemberProperties, session);
            newCompositeMemberMapOfProperties.put(compositeMemberPuName, newCompositeMemberProperties);
        }

        // set the new COMPOSITE_PROPERTIES into compositeProperties
        compositeProperties.put(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, newCompositeMemberMapOfProperties);
    }

    /*
     * For required properties overrides values with those from composite properties.
     */
    protected static void overrideMemberProperties(Map memberProperties, Map compositeProperties) {
        String transactionTypeProp =  (String)compositeProperties.get(PersistenceUnitProperties.TRANSACTION_TYPE);
        if (transactionTypeProp != null) {
            memberProperties.put(PersistenceUnitProperties.TRANSACTION_TYPE, transactionTypeProp);
        } else {
            memberProperties.remove(PersistenceUnitProperties.TRANSACTION_TYPE);
        }

        String serverPlatformProp =  (String)compositeProperties.get(PersistenceUnitProperties.TARGET_SERVER);
        if (serverPlatformProp != null) {
            memberProperties.put(PersistenceUnitProperties.TARGET_SERVER, serverPlatformProp);
        } else {
            memberProperties.remove(PersistenceUnitProperties.TARGET_SERVER);
        }

        Boolean isValidationOnly =  (Boolean)compositeProperties.get(PersistenceUnitProperties.VALIDATION_ONLY_PROPERTY);
        if (isValidationOnly != null) {
            memberProperties.put(PersistenceUnitProperties.VALIDATION_ONLY_PROPERTY, isValidationOnly);
        } else {
            memberProperties.remove(PersistenceUnitProperties.VALIDATION_ONLY_PROPERTY);
        }
    }

    /*
     * If a member is composite then add its members instead.
     * All members' puNames must be unique.
     * Return a Map of composite member SEPersistenceUnitInfo keyed by persistence unit name.
     */
    protected static Map<String, SEPersistenceUnitInfo> getCompositeMemberPuInfoMap(PersistenceUnitInfo puInfo, Map predeployProperties) {
        Set<SEPersistenceUnitInfo> memeberPuInfoSet = PersistenceUnitProcessor.getPersistenceUnits(puInfo.getClassLoader(), predeployProperties, puInfo.getJarFileUrls());
        HashMap<String, SEPersistenceUnitInfo> memberPuInfoMap = new HashMap<>(memeberPuInfoSet.size());
        for (SEPersistenceUnitInfo memberPuInfo : memeberPuInfoSet) {
            // override transaction type with composite's transaction type
            memberPuInfo.setTransactionType(puInfo.getTransactionType());
            // override properties that should be overridden by composit's properties
            overrideMemberProperties(memberPuInfo.getProperties(), puInfo.getProperties());
            if (isComposite(memberPuInfo)) {
                Map<String, SEPersistenceUnitInfo> containedMemberPuInfoMap = getCompositeMemberPuInfoMap(memberPuInfo, memberPuInfo.getProperties());
                Iterator<Map.Entry<String, SEPersistenceUnitInfo>> it = containedMemberPuInfoMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<String, SEPersistenceUnitInfo> entry = it.next();
                    String containedMemberPuName = entry.getKey();
                    SEPersistenceUnitInfo containedMemberPuInfo = entry.getValue();
                    SEPersistenceUnitInfo anotherMemeberPuInfo = memberPuInfoMap.get(containedMemberPuName);
                    if (anotherMemeberPuInfo == null) {
                        memberPuInfoMap.put(containedMemberPuName, containedMemberPuInfo);
                    } else {
                        throwPersistenceUnitNameAlreadyInUseException(containedMemberPuName, containedMemberPuInfo, anotherMemeberPuInfo);
                    }
                }
            } else {
                String memberPuName = memberPuInfo.getPersistenceUnitName();
                SEPersistenceUnitInfo anotherMemeberPuInfo = memberPuInfoMap.get(memberPuName);
                if (anotherMemeberPuInfo == null) {
                    memberPuInfoMap.put(memberPuName, memberPuInfo);
                } else {
                    throwPersistenceUnitNameAlreadyInUseException(memberPuName, memberPuInfo, anotherMemeberPuInfo);
                }
            }
        }
        return memberPuInfoMap;
    }

    /*
     * If a member is composite then add its members instead.
     * All members' puNames must be unique.
     * Return a Set of composite member SEPersistenceUnitInfo.
     */
    protected static Set<SEPersistenceUnitInfo> getCompositeMemberPuInfoSet(PersistenceUnitInfo puInfo, Map predeployProperties) {
        return new HashSet<>(getCompositeMemberPuInfoMap(puInfo, predeployProperties).values());
    }

    public static void throwPersistenceUnitNameAlreadyInUseException(String puName, PersistenceUnitInfo newPuInfo, PersistenceUnitInfo exsitingPuInfo) {
        String puUrl;
        String anotherPuUrl;
        try {
            puUrl = URLDecoder.decode(newPuInfo.getPersistenceUnitRootUrl().toString(), "UTF8");
            anotherPuUrl = URLDecoder.decode(exsitingPuInfo.getPersistenceUnitRootUrl().toString(), "UTF8");
        } catch (UnsupportedEncodingException e) {
            puUrl = newPuInfo.getPersistenceUnitRootUrl().toString();
            anotherPuUrl = exsitingPuInfo.getPersistenceUnitRootUrl().toString();
        }
        throw PersistenceUnitLoadingException.persistenceUnitNameAlreadyInUse(puName, puUrl, anotherPuUrl);
    }

    /**
     * Create a new version of this EntityManagerSetupImpl and cache it.  Prepare "this" EntityManagerSetupImpl
     * for garbage collection.
     *
     * This call will mean any users of this EntityManagerSetupImpl will get the new version the next time
     * they look it up (for instance and EntityManager creation time)
     * @param properties
     * @return
     */
    public EntityManagerSetupImpl refreshMetadata(Map properties){
        String sessionName = getSessionName();
        String uniqueName = getPersistenceUnitUniqueName();
        EntityManagerSetupImpl newSetupImpl = new EntityManagerSetupImpl(uniqueName, sessionName);
        newSetupImpl.setIsInContainerMode(isInContainerMode);
        newSetupImpl.enableWeaving = enableWeaving;
        Map<Object, Object> refreshProperties = new HashMap<>();
        refreshProperties.putAll(getSession().getProperties());
        if (properties != null){
            refreshProperties.putAll(properties);
        }
        newSetupImpl.predeploy(getPersistenceUnitInfo(), refreshProperties);
        // newSetupImpl has been already predeployed, predeploy will just increment factoryCount.
        if (!isInContainerMode) {
            newSetupImpl.predeploy(getPersistenceUnitInfo(), refreshProperties);
        }
        synchronized (EntityManagerFactoryProvider.emSetupImpls) {
            SessionManager.getManager().getSessions().remove(sessionName, getSession());
            if (EntityManagerFactoryProvider.emSetupImpls.get(sessionName).equals(this)){
                EntityManagerFactoryProvider.emSetupImpls.remove(sessionName);
            }
            setIsMetadataExpired(true);
            //stop this EntityManagerSetupImpl's session from processing refresh commands. The new session should listen instead.
            getSession().setRefreshMetadataListener(null);

            EntityManagerFactoryProvider.addEntityManagerSetupImpl(sessionName, newSetupImpl);
        }
        return newSetupImpl;
    }

    /**
     * This method is just a wrapper on refreshMetadata so that core does not need a dependency on JPA
     * due to the EntityManagerSetupImpl return value.  This method satisfies the MetedataRefreshListener implementation
     * and is called by incoming RCM refresh commands
     *
     * @see refreshMetadata
     */
    @Override
    public void triggerMetadataRefresh(Map properties){
        refreshMetadata(properties);
    }

    /**
     * INTERNAL:
     * Generate the DDL per the properties specified.
     */
    public void writeDDL(Map props, DatabaseSessionImpl session, ClassLoader classLoader) {
        if (this.compositeMemberEmSetupImpls == null) {
            // Generate the DDL if we find either EclipseLink or JPA DDL generation properties.
            // Note, we do one or the other, that is, we do not mix the properties by default
            // but we may use some with both, e.g. APP_LOCATION. EclipseLink properties
            // override JPA properties.

            if (hasConfigProperty(DDL_GENERATION, props)) {
                // We have EclipseLink DDL generation properties.
                String ddlGeneration = getConfigPropertyAsString(DDL_GENERATION, props).toLowerCase(Locale.ROOT);

                if (! ddlGeneration.equals(NONE)) {
                    writeDDL(ddlGeneration, props, session, classLoader);
                }
            } else {
                // Look for JPA schema generation properties.

                // Schema generation for the database.
                if (hasConfigProperty(SCHEMA_GENERATION_DATABASE_ACTION, props)) {
                    String databaseGenerationAction = getConfigPropertyAsString(SCHEMA_GENERATION_DATABASE_ACTION, props).toLowerCase(Locale.ROOT);

                    if (! databaseGenerationAction.equals(SCHEMA_GENERATION_NONE_ACTION)) {
                        if (databaseGenerationAction.equals(SCHEMA_GENERATION_CREATE_ACTION)) {
                            writeDDL(SCHEMA_GENERATION_CREATE_SOURCE, SCHEMA_GENERATION_CREATE_SCRIPT_SOURCE, TableCreationType.CREATE, props, session, classLoader);
                        } else if (databaseGenerationAction.equals(PersistenceUnitProperties.CREATE_OR_EXTEND)) {
                            writeDDL(SCHEMA_GENERATION_CREATE_SOURCE, SCHEMA_GENERATION_CREATE_SCRIPT_SOURCE, TableCreationType.EXTEND, props, session, classLoader);
                        } else if (databaseGenerationAction.equals(SCHEMA_GENERATION_DROP_ACTION)) {
                            writeDDL(SCHEMA_GENERATION_DROP_SOURCE, SCHEMA_GENERATION_DROP_SCRIPT_SOURCE, TableCreationType.DROP, props, session, classLoader);
                        } else if (databaseGenerationAction.equals(SCHEMA_GENERATION_DROP_AND_CREATE_ACTION)) {
                            writeDDL(SCHEMA_GENERATION_DROP_SOURCE, SCHEMA_GENERATION_DROP_SCRIPT_SOURCE, TableCreationType.DROP, props, session, classLoader);
                            writeDDL(SCHEMA_GENERATION_CREATE_SOURCE, SCHEMA_GENERATION_CREATE_SCRIPT_SOURCE, TableCreationType.CREATE, props, session, classLoader);
                        } else {
                            String validOptions = SCHEMA_GENERATION_CREATE_ACTION + ", " + SCHEMA_GENERATION_DROP_ACTION + ", " +  SCHEMA_GENERATION_DROP_AND_CREATE_ACTION + ", " + PersistenceUnitProperties.CREATE_OR_EXTEND;
                            session.log(SessionLog.WARNING, SessionLog.PROPERTIES, "ddl_generation_unknown_property_value", new Object[] {SCHEMA_GENERATION_DATABASE_ACTION, databaseGenerationAction, persistenceUnitInfo.getPersistenceUnitName(), validOptions});
                        }
                    }
                }

                // Schema generation for target scripts.
                if (hasConfigProperty(SCHEMA_GENERATION_SCRIPTS_ACTION, props)) {
                    String scriptsGenerationAction = getConfigPropertyAsString(SCHEMA_GENERATION_SCRIPTS_ACTION, props).toLowerCase(Locale.ROOT);

                    if (! scriptsGenerationAction.equals(SCHEMA_GENERATION_NONE_ACTION)) {
                        if (scriptsGenerationAction.equals(SCHEMA_GENERATION_CREATE_ACTION)) {
                            writeMetadataDDLToScript(TableCreationType.CREATE, props, session, classLoader);
                        } else if (scriptsGenerationAction.equals(PersistenceUnitProperties.CREATE_OR_EXTEND)) {
                            writeMetadataDDLToScript(TableCreationType.EXTEND, props, session, classLoader);
                        } else if (scriptsGenerationAction.equals(SCHEMA_GENERATION_DROP_ACTION)) {
                            writeMetadataDDLToScript(TableCreationType.DROP, props, session, classLoader);
                        } else if (scriptsGenerationAction.equals(SCHEMA_GENERATION_DROP_AND_CREATE_ACTION)) {
                            writeMetadataDDLToScript(TableCreationType.DROP_AND_CREATE, props, session, classLoader);
                        } else {
                            String validOptions = SCHEMA_GENERATION_CREATE_ACTION + ", " + SCHEMA_GENERATION_DROP_ACTION + ", " +  SCHEMA_GENERATION_DROP_AND_CREATE_ACTION;
                            session.log(SessionLog.WARNING, SessionLog.PROPERTIES, "ddl_generation_unknown_property_value", new Object[] {SCHEMA_GENERATION_SCRIPTS_ACTION, scriptsGenerationAction, persistenceUnitInfo.getPersistenceUnitName(), validOptions});
                        }
                    }
                }

                // Once we've generated any and all DDL, check for load scripts.
                writeSourceScriptToDatabase(getConfigProperty(SCHEMA_GENERATION_SQL_LOAD_SCRIPT_SOURCE, props), session, classLoader);
            }
        } else {
            // composite
            Map compositeMemberMapOfProperties = (Map)getConfigProperty(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, props);
            for(EntityManagerSetupImpl compositeMemberEmSetupImpl : this.compositeMemberEmSetupImpls) {
                // the properties guaranteed to be non-null after updateCompositeMemberProperties call
                Map compositeMemberProperties = (Map)compositeMemberMapOfProperties.get(compositeMemberEmSetupImpl.getPersistenceUnitInfo().getPersistenceUnitName());
                compositeMemberEmSetupImpl.writeDDL(compositeMemberProperties, session, classLoader);
            }
        }
    }

    /**
     * INTERNAL:
     * Generate the DDL from the persistence unit metadata. This DDL generation
     * utilizes the EclipseLink DDL properties.
     */
    protected void writeDDL(String ddlGeneration, Map props, DatabaseSessionImpl session, ClassLoader classLoader) {
        // By default the table creation type will be 'none'.
        TableCreationType ddlType = TableCreationType.NONE;

        if (ddlGeneration.equals(PersistenceUnitProperties.CREATE_ONLY)) {
            ddlType = TableCreationType.CREATE;
        } else if (ddlGeneration.equals(PersistenceUnitProperties.DROP_ONLY)) {
            ddlType = TableCreationType.DROP;
        } else if (ddlGeneration.equals(PersistenceUnitProperties.DROP_AND_CREATE)) {
            ddlType = TableCreationType.DROP_AND_CREATE;
        } else if (ddlGeneration.equals(PersistenceUnitProperties.CREATE_OR_EXTEND)) {
            ddlType = TableCreationType.EXTEND;
        } else {
            // Log a warning if we have an unknown ddl generation.
            String validOptions = PersistenceUnitProperties.NONE + ", " +
                                  PersistenceUnitProperties.CREATE_ONLY + ", " +
                                  PersistenceUnitProperties.DROP_ONLY + ", " +
                                  PersistenceUnitProperties.DROP_AND_CREATE + ", " +
                                  PersistenceUnitProperties.CREATE_OR_EXTEND;
            session.log(SessionLog.WARNING, SessionLog.PROPERTIES, "ddl_generation_unknown_property_value", new Object[] {PersistenceUnitProperties.DDL_GENERATION, ddlGeneration, persistenceUnitInfo.getPersistenceUnitName(), validOptions});
        }

        if (ddlType != TableCreationType.NONE) {
            String ddlGenerationMode = getConfigPropertyAsString(PersistenceUnitProperties.DDL_GENERATION_MODE, props, PersistenceUnitProperties.DEFAULT_DDL_GENERATION_MODE);

            // Optimize for cases where the value is explicitly set to NONE
            if (! ddlGenerationMode.equals(NONE)) {
                if (isCompositeMember()) {
                    // debug output added to make it easier to navigate the log because the method is called outside of composite member deploy
                    session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "composite_member_begin_call", new Object[]{"generateDDL", persistenceUnitInfo.getPersistenceUnitName(), state});
                }

                SchemaManager mgr = new SchemaManager(session);

                if (ddlGenerationMode.equals(PersistenceUnitProperties.DDL_DATABASE_GENERATION) || ddlGenerationMode.equals(PersistenceUnitProperties.DDL_BOTH_GENERATION)) {
                    writeDDLToDatabase(mgr, ddlType);
                }

                if (ddlGenerationMode.equals(PersistenceUnitProperties.DDL_SQL_SCRIPT_GENERATION)|| ddlGenerationMode.equals(PersistenceUnitProperties.DDL_BOTH_GENERATION)) {
                    String appLocation = getConfigPropertyAsString(PersistenceUnitProperties.APP_LOCATION, props, PersistenceUnitProperties.DEFAULT_APP_LOCATION);

                    // These could be a string (file name urls) or actual writers.
                    Object createDDLJdbc = getConfigProperty(PersistenceUnitProperties.CREATE_JDBC_DDL_FILE, props, PersistenceUnitProperties.DEFAULT_CREATE_JDBC_FILE_NAME);
                    Object dropDDLJdbc = getConfigProperty(PersistenceUnitProperties.DROP_JDBC_DDL_FILE, props, PersistenceUnitProperties.DEFAULT_DROP_JDBC_FILE_NAME);
                    writeDDLToFiles(mgr, appLocation,  createDDLJdbc,  dropDDLJdbc, ddlType, props);
                }

                // Log a warning if we have an unknown ddl generation mode.
                if ( (! ddlGenerationMode.equals(PersistenceUnitProperties.DDL_DATABASE_GENERATION)) && (! ddlGenerationMode.equals(PersistenceUnitProperties.DDL_SQL_SCRIPT_GENERATION)) && (! ddlGenerationMode.equals(PersistenceUnitProperties.DDL_BOTH_GENERATION))) {
                    String validOptions = PersistenceUnitProperties.DDL_DATABASE_GENERATION + ", " +
                                          PersistenceUnitProperties.DDL_SQL_SCRIPT_GENERATION + ", " +
                                          PersistenceUnitProperties.DDL_BOTH_GENERATION;
                    session.log(SessionLog.WARNING, SessionLog.PROPERTIES, "ddl_generation_unknown_property_value", new Object[] {PersistenceUnitProperties.DDL_GENERATION_MODE, ddlGenerationMode, persistenceUnitInfo.getPersistenceUnitName(), validOptions});
                }

                if (isCompositeMember()) {
                    // debug output added to make it easier to navigate the log because the method is called outside of composite member deploy
                    session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "composite_member_end_call", new Object[]{"generateDDL", persistenceUnitInfo.getPersistenceUnitName(), state});
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Generate the DDL per the properties given.
     */
    protected void writeDDL(String generationSourceProperty, String scriptGenerationSourceProperty, TableCreationType tableCreationType, Map props, DatabaseSessionImpl session, ClassLoader loader) {
        String generationSource = getConfigPropertyAsString(generationSourceProperty, props);
        Object scriptGenerationSource = getConfigProperty(scriptGenerationSourceProperty, props);

        if (generationSource == null) {
            if (scriptGenerationSource == null) {
                writeMetadataDDLToDatabase(tableCreationType, props, session, loader);
            } else {
                writeSourceScriptToDatabase(scriptGenerationSource, session, loader);
            }
        } else if (generationSource.equals(SCHEMA_GENERATION_METADATA_SOURCE)) {
            writeMetadataDDLToDatabase(tableCreationType, props, session, loader);
        } else if (generationSource.equals(SCHEMA_GENERATION_SCRIPT_SOURCE)) {
            writeSourceScriptToDatabase(scriptGenerationSource, session, loader);
        } else if (generationSource.equals(SCHEMA_GENERATION_METADATA_THEN_SCRIPT_SOURCE)) {
            writeMetadataDDLToDatabase(tableCreationType, props, session, loader);
            writeSourceScriptToDatabase(scriptGenerationSource, session, loader);
        } else if (generationSource.equals(SCHEMA_GENERATION_SCRIPT_THEN_METADATA_SOURCE)) {
            writeSourceScriptToDatabase(scriptGenerationSource, session, loader);
            writeMetadataDDLToDatabase(tableCreationType, props, session, loader);
        } else {
            String validOptions = SCHEMA_GENERATION_METADATA_SOURCE + ", " +
                                  SCHEMA_GENERATION_SCRIPT_SOURCE + ", " +
                                  SCHEMA_GENERATION_METADATA_THEN_SCRIPT_SOURCE + ", " +
                                  SCHEMA_GENERATION_SCRIPT_THEN_METADATA_SOURCE;
            session.log(SessionLog.WARNING, SessionLog.PROPERTIES, "ddl_generation_unknown_property_value", new Object[] {generationSourceProperty, generationSource, persistenceUnitInfo.getPersistenceUnitName(), validOptions});
        }
    }

    /**
     * INTERNAL:
     * Generate and write DDL from the persistence unit metadata to the database.
     */
    protected void writeDDLToDatabase(SchemaManager mgr, TableCreationType ddlType) {
        String str = getConfigPropertyAsString(PersistenceUnitProperties.JAVASE_DB_INTERACTION, null ,"true");
        boolean interactWithDB = Boolean.parseBoolean(str.toLowerCase());
        if (!interactWithDB){
            return;
        }

        generateDefaultTables(mgr, ddlType);
    }

    /**
     * @deprecated Extenders should now use
     *             {@link #writeDDLToFiles(SchemaManager, String, Object, Object, TableCreationType, Map)}
     */
    @Deprecated
    protected void writeDDLToFiles(SchemaManager mgr, String appLocation, Object createDDLJdbc, Object dropDDLJdbc,
            TableCreationType ddlType) {
        writeDDLToFiles(mgr, appLocation, createDDLJdbc, dropDDLJdbc, ddlType, Collections.EMPTY_MAP);
    }

    /**
     * Write the DDL to the files provided.
     */
    protected void writeDDLToFiles(SchemaManager mgr, String appLocation, Object createDDLJdbc, Object dropDDLJdbc, TableCreationType ddlType, Map props) {
        // Ensure that the appLocation string ends with File.separator if
        // specified. In JPA there is no default for app location, however, if
        // the user did specify one, we'll use it.
        String appLocationPrefix = (appLocation == null) ? "" : addFileSeperator(appLocation);

        if (ddlType.equals(TableCreationType.CREATE) || ddlType.equals(TableCreationType.DROP_AND_CREATE) || ddlType.equals(TableCreationType.EXTEND)) {
            if (createDDLJdbc == null) {
                // Using EclipseLink properties, the create script has a default.
                // Using JPA properties, the user must specify the target else an exception must be thrown.
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa21-ddl-create-script-target-not-specified"));
            } else if (createDDLJdbc instanceof Writer) {
                mgr.outputCreateDDLToWriter((Writer) createDDLJdbc);
            } else {
                // Assume it is a String file name.
                mgr.outputCreateDDLToFile(appLocationPrefix + createDDLJdbc);
            }
        }

        if (ddlType.equals(TableCreationType.DROP) || ddlType.equals(TableCreationType.DROP_AND_CREATE)) {
            if (dropDDLJdbc == null) {
                // Using EclipseLink properties, the drop script has a default.
                // Using JPA properties, the user must specify the target else an exception must be thrown.
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa21-ddl-drop-script-target-not-specified"));
            } else if (dropDDLJdbc instanceof Writer) {
                mgr.outputDropDDLToWriter((Writer) dropDDLJdbc);
            } else if (dropDDLJdbc instanceof String) {
                mgr.outputDropDDLToFile(appLocationPrefix + dropDDLJdbc);
            } else {
                throw new PersistenceException(ExceptionLocalization.buildMessage("jpa21-ddl-invalid-target-script-type", new Object[]{ dropDDLJdbc , dropDDLJdbc.getClass()}));
            }
        }

        String propString = getConfigPropertyAsString(PersistenceUnitProperties.SCHEMA_GENERATION_SCRIPT_TERMINATE_STATEMENTS, props);
        boolean terminator = Boolean.parseBoolean(propString);
        mgr.setCreateSQLFiles(terminator);
        generateDefaultTables(mgr, ddlType);
        mgr.closeDDLWriter();
    }

    /**
     * INTERNAL:
     * Generate and write DDL from the persistence unit metadata to the database.
     */
    protected void writeMetadataDDLToDatabase(TableCreationType tableCreationType, Map props, DatabaseSessionImpl session, ClassLoader classLoader) {
        SchemaManager mgr = new SchemaManager(session);

        // Set the create database schemas flag on the schema manager.
        String createSchemas = getConfigPropertyAsString(SCHEMA_GENERATION_CREATE_DATABASE_SCHEMAS, props);
        mgr.setCreateDatabaseSchemas(createSchemas != null && createSchemas.equalsIgnoreCase("true"));

        writeDDLToDatabase(mgr, tableCreationType);
    }

    /**
     * INTERNAL:
     * Generate and write DDL from the persistence unit metadata to scripts.
     */
    protected void writeMetadataDDLToScript(TableCreationType tableCreationType, Map props, DatabaseSessionImpl session, ClassLoader classLoader) {
        SchemaManager mgr = new SchemaManager(session);

        // Set the create database schemas flag on the schema manager.
        String createSchemas = getConfigPropertyAsString(SCHEMA_GENERATION_CREATE_DATABASE_SCHEMAS, props);
        mgr.setCreateDatabaseSchemas(createSchemas != null && createSchemas.equalsIgnoreCase("true"));

        writeDDLToFiles(mgr, getConfigPropertyAsString(PersistenceUnitProperties.APP_LOCATION, props),  getConfigProperty(SCHEMA_GENERATION_SCRIPTS_CREATE_TARGET, props),  getConfigProperty(SCHEMA_GENERATION_SCRIPTS_DROP_TARGET, props), tableCreationType, props);
    }

    /**
     * This method will read SQL from a reader or URL and send it through
     * to the database. This could open up the database to SQL injection if
     * not careful.
     */
    protected void writeSourceScriptToDatabase(Object source, DatabaseSessionImpl session, ClassLoader loader) {
        if (source != null) {
            Reader reader = null;

            try {
                if (source instanceof Reader) {
                    reader = (Reader) source;
                } else if (source instanceof String) {
                    // Try to load the resource first, if not assume it as a well formed URL. If not, throw an exception.
                    URL sourceURL = loader.getResource((String) source);

                    if (sourceURL == null) {
                        try {
                            sourceURL = new URL((String) source);
                        }  catch (MalformedURLException e) {
                            throw new PersistenceException(ExceptionLocalization.buildMessage("jpa21-ddl-source-script-not-found", new Object[]{ source }), e);
                        }
                    }

                    URLConnection connection = sourceURL.openConnection();
                    // Set to false to prevent locking of jar files on Windows. EclipseLink issue 249664
                    connection.setUseCaches(false);
                    reader = new InputStreamReader(connection.getInputStream(), "UTF-8");
                } else {
                    throw new PersistenceException(ExceptionLocalization.buildMessage("jpa21-ddl-invalid-source-script-type", new Object[]{ source , source.getClass()}));
                }

                if (reader != null) {
                    StringBuffer sqlBuffer;
                    int data = reader.read();

                    // While there is still data to read, read line by line.
                    while (data != -1) {
                        sqlBuffer = new StringBuffer();
                        char aChar = (char) data;

                        // Read till the end of the line or maybe even file.
                        while (aChar != '\n' && data != -1) {
                            sqlBuffer.append(aChar);

                            // Read next character.
                            data = reader.read();
                            aChar = (char) data;
                        }

                        // Remove trailing and leading white space characters.
                        String sqlString = sqlBuffer.toString().trim();

                        // If the string isn't empty, then fire it.
                        if ((! sqlString.equals("")) && (! sqlString.startsWith("#"))) {
                            try {
                                session.executeNonSelectingSQL(sqlString);
                            } catch (DatabaseException e) {
                                // Swallow any database exceptions as these could
                                // be drop failures of a table that doesn't exist etc.
                                // SQLExceptions will be thrown to the user.
                            }
                        }

                        data = reader.read();
                    }

                    reader.close();
                }
            } catch (IOException e) {
                throw new PersistenceException(ExceptionLocalization.buildMessage("jpa21-ddl-source-script-io-exception", new Object[]{source}), e);
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        // ignore.
                    }
                }
            }
        }
    }

    //JPA-RS feature may be provided by a jar on the path or missing
    private static String shouldWeaveRestByDefault(ClassLoader cl) {
        try {
            cl.loadClass("org.eclipse.persistence.internal.jpa.rs.weaving.PersistenceWeavedRest");
            return "true";
        } catch (Throwable t) {
            //ignore
        }
        return "false";
    }
}

