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

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     cdelahun - Bug 214534: changes for JMSPublishingTransportManager configuration via session.xml
package org.eclipse.persistence.internal.sessions.factories;

import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.eis.EISConnectionSpec;
import org.eclipse.persistence.eis.EISLogin;
import org.eclipse.persistence.exceptions.ExceptionHandler;
import org.eclipse.persistence.exceptions.SessionLoaderException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.databaseaccess.Platform;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.internal.sessions.factories.model.SessionConfigs;
import org.eclipse.persistence.internal.sessions.factories.model.event.SessionEventManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.log.DefaultSessionLogConfig;
import org.eclipse.persistence.internal.sessions.factories.model.log.JavaLogConfig;
import org.eclipse.persistence.internal.sessions.factories.model.log.LogConfig;
import org.eclipse.persistence.internal.sessions.factories.model.log.ServerLogConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.DatabaseLoginConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.EISLoginConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.LoginConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.StructConverterConfig;
import org.eclipse.persistence.internal.sessions.factories.model.login.XMLLoginConfig;
import org.eclipse.persistence.internal.sessions.factories.model.platform.CustomServerPlatformConfig;
import org.eclipse.persistence.internal.sessions.factories.model.platform.ServerPlatformConfig;
import org.eclipse.persistence.internal.sessions.factories.model.pool.ConnectionPolicyConfig;
import org.eclipse.persistence.internal.sessions.factories.model.pool.ConnectionPoolConfig;
import org.eclipse.persistence.internal.sessions.factories.model.pool.PoolsConfig;
import org.eclipse.persistence.internal.sessions.factories.model.pool.ReadConnectionPoolConfig;
import org.eclipse.persistence.internal.sessions.factories.model.project.ProjectConfig;
import org.eclipse.persistence.internal.sessions.factories.model.property.PropertyConfig;
import org.eclipse.persistence.internal.sessions.factories.model.rcm.RemoteCommandManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.rcm.command.CommandsConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.DefaultSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.NativeSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.SequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.TableSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.UnaryTableSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.sequencing.XMLFileSequenceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.session.DatabaseSessionConfig;
import org.eclipse.persistence.internal.sessions.factories.model.session.ServerSessionConfig;
import org.eclipse.persistence.internal.sessions.factories.model.session.SessionBrokerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.session.SessionConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.JMSPublishingTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.JMSTopicTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.Oc4jJGroupsTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.RMIIIOPTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.RMITransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.SunCORBATransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.TransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.UserDefinedTransportManagerConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.discovery.DiscoveryConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.naming.JNDINamingServiceConfig;
import org.eclipse.persistence.internal.sessions.factories.model.transport.naming.RMIRegistryNamingServiceConfig;
import org.eclipse.persistence.logging.DefaultSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.platform.database.converters.StructConverter;
import org.eclipse.persistence.platform.server.NoServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatformUtils;
import org.eclipse.persistence.sequencing.DefaultSequence;
import org.eclipse.persistence.sequencing.NativeSequence;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sequencing.TableSequence;
import org.eclipse.persistence.sequencing.UnaryTableSequence;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatasourceLogin;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Login;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEventListener;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.sessions.coordination.DiscoveryManager;
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.XMLProjectReader;
import org.eclipse.persistence.sessions.factories.XMLSessionConfigLoader;
import org.eclipse.persistence.sessions.server.ConnectionPolicy;
import org.eclipse.persistence.sessions.server.ConnectionPool;
import org.eclipse.persistence.sessions.server.ReadConnectionPool;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.tools.profiler.PerformanceProfiler;

/**
 * INTERNAL:
 * Builds EclipseLink Sessions from the XML Session Config model.
 * Model classes that are not built, are processed only.
 *
 * @author Guy Pelletier
 * @version 1.0
 */
public class SessionsFactory {
    protected Map<String, Session> m_sessions;
    protected Map<String, Integer> m_logLevels;
    protected ClassLoader m_classLoader;

    /**
     * INTERNAL:
     */
    public SessionsFactory() {
        m_logLevels = new HashMap<>();
        m_logLevels.put("off", SessionLog.OFF);
        m_logLevels.put("severe", SessionLog.SEVERE);
        m_logLevels.put("warning", SessionLog.WARNING);
        m_logLevels.put("info", SessionLog.INFO);
        m_logLevels.put("config", SessionLog.CONFIG);
        m_logLevels.put("fine", SessionLog.FINE);
        m_logLevels.put("finer", SessionLog.FINER);
        m_logLevels.put("finest", SessionLog.FINEST);
        m_logLevels.put("all", SessionLog.ALL);
    }

    /**
     * INTERNAL:
     * To build EclipseLink sessions, users must call this method with a
     * SessionConfigs object returned from an OX read in the
     * {@link XMLSessionConfigLoader}.
     *
     * @param eclipseLinkSessions object returned from an OX read in the XMLSessionConfigLoader
     * @param classLoader class loader used in the XMLSessionConfigLoader
     * @return EclipseLink sessions
     */
    public Map<String, Session> buildSessionConfigs(SessionConfigs eclipseLinkSessions, ClassLoader classLoader) {
        m_sessions = new HashMap<>();
        m_classLoader = classLoader;
        List<SessionBrokerConfig> sessionBrokerConfigs = new ArrayList<>();
        Enumeration<SessionConfig> e = eclipseLinkSessions.getSessionConfigs().elements();

        while (e.hasMoreElements()) {
            SessionConfig sessionConfig = e.nextElement();

            if (sessionConfig instanceof SessionBrokerConfig) {
                // Hold all the session brokers till all the sessions have been built
                sessionBrokerConfigs.add((SessionBrokerConfig) sessionConfig);
            } else {
                AbstractSession session = buildSession(sessionConfig);
                session.getDatasourcePlatform().getConversionManager().setLoader(classLoader);
                processSessionCustomizer(sessionConfig, session);
                m_sessions.put(session.getName(), session);
            }
        }

        // All the sessions have been built now so we can process the Session Brokers
        for (SessionBrokerConfig sessionBrokerConfig : sessionBrokerConfigs) {
            SessionBroker sessionBroker = buildSessionBrokerConfig(sessionBrokerConfig);
            sessionBroker.getDatasourcePlatform().getConversionManager().setLoader(classLoader);
            processSessionCustomizer(sessionBrokerConfig, sessionBroker);
            m_sessions.put(sessionBroker.getName(), sessionBroker);
        }

        return m_sessions;
    }

    /**
     * INTERNAL:
     * Process the user inputed session customizer class. Will be run at the
     * end of the session build process
     */
    protected void processSessionCustomizer(SessionConfig sessionConfig, AbstractSession session) {
        // Session customizer - MUST BE THE LAST THING TO PROCESS
        String sessionCustomizerClassName = sessionConfig.getSessionCustomizerClass();
        if (sessionCustomizerClassName != null) {
            try {
                Class sessionCustomizerClass = m_classLoader.loadClass(sessionCustomizerClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    ((SessionCustomizer)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(sessionCustomizerClass))).customize(session);
                }else{
                    ((SessionCustomizer)PrivilegedAccessHelper.newInstanceFromClass(sessionCustomizerClass)).customize(session);
                }
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("session-customizer-class", sessionCustomizerClassName, exception);
            }
        }
    }

    /**
     * INTERNAL:
     * Build the correct session based on the session config type
     */
    protected AbstractSession buildSession(SessionConfig sessionConfig) {
        if (sessionConfig instanceof ServerSessionConfig) {
            return buildServerSessionConfig((ServerSessionConfig)sessionConfig);
        } else {// if (sessionConfig instanceof DatabaseSessionConfig) {
            return buildDatabaseSessionConfig((DatabaseSessionConfig)sessionConfig);
        }
    }

    /**
     * INTERNAL:
     * Wrapped by the getSession() call, therefore, config can't be null at this
     * point.
     */
    protected AbstractSession buildDatabaseSessionConfig(DatabaseSessionConfig databaseSessionConfig) {
        // Create a new database session (null means use login from deployment xml if there is one)
        DatabaseSessionImpl databaseSession = createSession(databaseSessionConfig, null);

        // Login - may overwrite the previous login (expected behavior)
        Login login = buildLogin(databaseSessionConfig.getLoginConfig());
        if (login != null) {
            databaseSession.setLogin(login);
        }

        // Common processing since ServerSessions inherit from DatabaseSession
        processDatabaseSessionConfig(databaseSessionConfig, databaseSession);

        // Process the common elements in SessionConfig
        processSessionConfig(databaseSessionConfig, databaseSession);

        return databaseSession;
    }

    /**
     * INTERNAL
     * Process a DatabaseSessionConfig object.
     */
    protected void processDatabaseSessionConfig(DatabaseSessionConfig sessionConfig, AbstractSession session) {
    }

    /**
     * INTERNAL:
     * Builds a server server from the given ServerSessionConfig.
     */
    protected AbstractSession buildServerSessionConfig(ServerSessionConfig serverSessionConfig) {
        // For server sessions we should build the login first, that way we can
        // initialize the server session with the login (if there is one)
        Login login = buildLogin(serverSessionConfig.getLoginConfig());

        // Create a new server session
        ServerSession serverSession = (ServerSession)createSession(serverSessionConfig, login);

        // Common processing since ServerSessions inherit from DatabaseSession
        processDatabaseSessionConfig(serverSessionConfig, serverSession);

        // Process pools config
        processPoolsConfig(serverSessionConfig.getPoolsConfig(), serverSession);

        // Process connection policy config
        processConnectionPolicyConfig(serverSessionConfig.getConnectionPolicyConfig(), serverSession);

        // Process the common elements in SessionConfig
        processSessionConfig(serverSessionConfig, serverSession);

        return serverSession;
    }

    /**
     * INTERNAL:
     * Return a DatabaseSession object from it's config object using either
     * the project classes or project XML files.
     */
    protected DatabaseSessionImpl createSession(DatabaseSessionConfig sessionConfig, Login login) {
        Project primaryProject;

        if (sessionConfig.getPrimaryProject() != null) {
            primaryProject = loadProjectConfig(sessionConfig.getPrimaryProject());
        } else {
            primaryProject = new Project();// Build a session from an empty project
        }

        prepareProjectLogin(primaryProject, login);
        DatabaseSessionImpl sessionToReturn = getSession(sessionConfig, primaryProject);

        // Append descriptors from all subsequent project.xml and project classes
        // to the mainProject
        if (sessionConfig.getAdditionalProjects() != null) {
            Enumeration<ProjectConfig> additionalProjects = sessionConfig.getAdditionalProjects().elements();

            while (additionalProjects.hasMoreElements()) {
                Project subProject = loadProjectConfig(additionalProjects.nextElement());
                primaryProject.addDescriptors(subProject, sessionToReturn);
            }
        }

        return sessionToReturn;
    }

    /**
     * INTERNAL:
     * Return the correct session type from the sessionConfig
     */
    protected void prepareProjectLogin(Project project, Login login) {
        if (login != null) {
            project.setLogin(login);
        } else if (project.getDatasourceLogin() == null) {
            // dummy login that needs to be set, otherwise session creation will fail
            project.setLogin(new DatabaseLogin());
        } else {
            // we read a login from the deployment xml of java, don't overwrite
        }
    }

    /**
     * INTERNAL:
     * Return the correct session type from the sessionConfig
     */
    protected DatabaseSessionImpl getSession(SessionConfig sessionConfig, Project project) {
        if (sessionConfig instanceof ServerSessionConfig) {
            return (ServerSession)project.createServerSession();
        } else {
            return (DatabaseSessionImpl)project.createDatabaseSession();
        }
    }

    /**
     * INTERNAL:
     * Load a projectConfig from the session.xml file. This method will determine
     * the proper loading scheme, that is, for a class or xml project.
     */
    protected Project loadProjectConfig(ProjectConfig projectConfig) {
        Project project = null;
        String projectString = projectConfig.getProjectString().trim();

        if (projectConfig.isProjectClassConfig()) {
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    project = (Project) AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(m_classLoader.loadClass(projectString)));
                }else{
                    project = (Project) PrivilegedAccessHelper.newInstanceFromClass(m_classLoader.loadClass(projectString));
                }
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadProjectClass(projectString, exception);
            }
        } else {
            try {
                project = XMLProjectReader.read(projectString, m_classLoader);
            } catch (ValidationException validationException) {
                if (validationException.getErrorCode() == ValidationException.PROJECT_XML_NOT_FOUND) {
                    try {
                        project = XMLProjectReader.read(projectString);
                    } catch (Exception e) {
                        throw SessionLoaderException.failedToLoadProjectXml(projectString, validationException);
                    }
                } else {
                    throw SessionLoaderException.failedToLoadProjectXml(projectString, validationException);
                }
            }
        }

        return project;
    }

    /**
     * INTERNAL:
     * Build the correct login based on the login config type
     */
    protected Login buildLogin(LoginConfig loginConfig) {
        if (loginConfig instanceof EISLoginConfig) {
            return buildEISLoginConfig((EISLoginConfig)loginConfig);
        } else if (loginConfig instanceof XMLLoginConfig) {
            return buildXMLLoginConfig((XMLLoginConfig)loginConfig);
        } else if (loginConfig instanceof DatabaseLoginConfig) {
            return buildDatabaseLoginConfig((DatabaseLoginConfig)loginConfig);
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     * Wrapped by the getLogin() call, therefore, config can't be null at this
     * point.
     */
    protected Login buildEISLoginConfig(EISLoginConfig eisLoginConfig) {
        EISLogin eisLogin = new EISLogin();

        // Connection Spec
        String specClassName = eisLoginConfig.getConnectionSpecClass();
        if (specClassName != null) {
            try {
                Class specClass = m_classLoader.loadClass(specClassName);
                EISConnectionSpec spec = null;
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    spec = (EISConnectionSpec)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(specClass));
                }else{
                    spec = (EISConnectionSpec)PrivilegedAccessHelper.newInstanceFromClass(specClass);
                }
                eisLogin.setConnectionSpec(spec);
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("connection-spec-class", specClassName, exception);
            }
        }

        // Connection Factory URL, setConnectionFactoryURL checks for null
        eisLogin.setConnectionFactoryURL(eisLoginConfig.getConnectionFactoryURL());

        // Process the common elements in LoginConfig
        processLoginConfig(eisLoginConfig, eisLogin);

        // Finally, return the newly created EISLogin
        return eisLogin;
    }

    /**
      * INTERNAL:
      * Wrapped by the getLogin() call, therefore, config can't be null at this
      * point.
      */
    protected Login buildXMLLoginConfig(XMLLoginConfig xmlLoginConfig) {
        XMLLogin xmlLogin = new XMLLogin();

        // Process the common elements in LoginConfig
        processLoginConfig(xmlLoginConfig, xmlLogin);

        // Finally, return the newly created XMLLogin
        return xmlLogin;
    }

    /**
     * INTERNAL:
     * Build a DatabaseLogin for the given Session
     * Wrapped by the getLogin() call, therefore, config can't be null at this
     * point.
     */
    protected Login buildDatabaseLoginConfig(DatabaseLoginConfig databaseLoginConfig) {
        DatabaseLogin databaseLogin = new DatabaseLogin();

        // Driver class
        String driverClassName = databaseLoginConfig.getDriverClass();
        if (driverClassName != null) {
            try {
                Class driverClass = m_classLoader.loadClass(driverClassName);
                databaseLogin.setDriverClass(driverClass);
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("driver-class", driverClassName, exception);
            }
        }

        // Connection URL
        String connectionString = databaseLoginConfig.getConnectionURL();
        if (connectionString != null) {
            databaseLogin.setConnectionString(connectionString);
        }

        // Datasource
        String datasourceName = databaseLoginConfig.getDatasource();
        if (datasourceName != null) {
            try {
                JNDIConnector jndiConnector = new JNDIConnector(new javax.naming.InitialContext(), datasourceName);
                jndiConnector.setLookupType(databaseLoginConfig.getLookupType());
                databaseLogin.setConnector(jndiConnector);
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("datasource", datasourceName, exception);
            }
        }

        // Bind all parameters - XML Schema default is false
        databaseLogin.setShouldBindAllParameters(databaseLoginConfig.getBindAllParameters());

        // Cache all statements - XML Schema default is false
        databaseLogin.setShouldCacheAllStatements(databaseLoginConfig.getCacheAllStatements());

        // Byte array binding - XML Schema default is true
        databaseLogin.setUsesByteArrayBinding(databaseLoginConfig.getByteArrayBinding());

        // String binding - XML Schema default is false
        databaseLogin.setUsesStringBinding(databaseLoginConfig.getStringBinding());

        // Stream binding - XML Schema default is false
        databaseLogin.setUsesStreamsForBinding(databaseLoginConfig.getStreamsForBinding());

        // Force field to uppper case - XML Schema default is false
        databaseLogin.setShouldForceFieldNamesToUpperCase(databaseLoginConfig.getForceFieldNamesToUppercase());

        // Optimize data conversion - XML Schema default is true
        databaseLogin.setShouldOptimizeDataConversion(databaseLoginConfig.getOptimizeDataConversion());

        // Trim strings - XML Schema default is true
        databaseLogin.setShouldTrimStrings(databaseLoginConfig.getTrimStrings());

        // Batch writing - XML Schema default is false
        databaseLogin.setUsesBatchWriting(databaseLoginConfig.getBatchWriting());

        // JDBC 2.0 batch writing - XML Schema default is true
        databaseLogin.setUsesJDBCBatchWriting(databaseLoginConfig.getJdbcBatchWriting());

        // Max batch writing size - XML Schema default is 32000
        Integer maxBatchWritingSize = databaseLoginConfig.getMaxBatchWritingSize();
        if (maxBatchWritingSize != null) {
            databaseLogin.setMaxBatchWritingSize(maxBatchWritingSize);
        }

        // Native SQL - XML Schema default is false
        databaseLogin.setUsesNativeSQL(databaseLoginConfig.getNativeSQL());

        // Process the common elements in LoginConfig
        processLoginConfig(databaseLoginConfig, databaseLogin);

        processStructConverterConfig(databaseLoginConfig.getStructConverterConfig(), databaseLogin);

        if (databaseLoginConfig.isConnectionHealthValidatedOnError() != null){
            databaseLogin.setConnectionHealthValidatedOnError(databaseLoginConfig.isConnectionHealthValidatedOnError());
        }
        if (databaseLoginConfig.getQueryRetryAttemptCount() != null){
            databaseLogin.setQueryRetryAttemptCount(databaseLoginConfig.getQueryRetryAttemptCount());
        }
        if (databaseLoginConfig.getDelayBetweenConnectionAttempts() != null){
            databaseLogin.setDelayBetweenConnectionAttempts(databaseLoginConfig.getDelayBetweenConnectionAttempts());
        }
        if (databaseLoginConfig.getPingSQL() != null){
            databaseLogin.setPingSQL(databaseLoginConfig.getPingSQL());
        }

        // Finally, return the newly created DatabaseLogin
        return databaseLogin;
    }

    /**
     * INTERNAL:
     */
    protected void processStructConverterConfig(StructConverterConfig converterClassConfig, DatabaseLogin login) {
        if (converterClassConfig != null) {
            Platform platform = login.getDatasourcePlatform();
            if (platform instanceof DatabasePlatform){
                Iterator i = converterClassConfig.getStructConverterClasses().iterator();

                while (i.hasNext()) {
                    String converterClassName = (String)i.next();
                    try {
                        Class converterClass = m_classLoader.loadClass(converterClassName);
                        StructConverter converter = null;
                        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                            try{
                                converter = (StructConverter)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(converterClass));
                            }catch (PrivilegedActionException ex){
                                throw (Exception)ex.getCause();
                            }
                        }else{
                            converter = (StructConverter)PrivilegedAccessHelper.newInstanceFromClass(converterClass);
                        }
                        ((DatabasePlatform)platform).addStructConverter(converter);
                    } catch (Exception exception) {
                        throw SessionLoaderException.failedToLoadTag("struct-converter", converterClassName, exception);
                    }
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Process the common elements of a Login.
     */
    protected void processLoginConfig(LoginConfig loginConfig, DatasourceLogin login) {
        // Platform class
        String platformClassName = loginConfig.getPlatformClass();
        if (platformClassName != null) {
            try {
                Class platformClass = m_classLoader.loadClass(platformClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    login.usePlatform((DatasourcePlatform)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(platformClass)));
                }else{
                    login.usePlatform((DatasourcePlatform)PrivilegedAccessHelper.newInstanceFromClass(platformClass));
                }
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("platform-class", platformClassName, exception);
            }
        }

        // Table qualifier
        String tableQualifier = loginConfig.getTableQualifier();
        if (tableQualifier != null) {
            login.setTableQualifier(tableQualifier);
        }

        // Username - setUserName checks for null
        login.setUserName(loginConfig.getUsername());

        // Encryption class (must be set before the password)
        // XML Schema default is org.eclipse.persistence.internal.security.JCEEncryptor
        login.setEncryptionClassName(loginConfig.getEncryptionClass());

        // Password is encrypted on the model - setEncryptedPassword checks for null
        login.setEncryptedPassword(loginConfig.getEncryptedPassword());

        // External connection pool - XML Schema default is false
        login.setUsesExternalConnectionPooling(loginConfig.getExternalConnectionPooling());

        // External transaction controller - XML Schema default is false
        login.setUsesExternalTransactionController(loginConfig.getExternalTransactionController());

        // Sequencing - XML Schema default is null
        if (loginConfig.getSequencingConfig() != null) {
            if (loginConfig.getSequencingConfig().getDefaultSequenceConfig() != null) {
                Sequence sequence = buildSequence(loginConfig.getSequencingConfig().getDefaultSequenceConfig());
                login.setDefaultSequence(sequence);
            }

            if ((loginConfig.getSequencingConfig().getSequenceConfigs() != null) && !loginConfig.getSequencingConfig().getSequenceConfigs().isEmpty()) {
                Enumeration eSequenceConfigs = loginConfig.getSequencingConfig().getSequenceConfigs().elements();

                while (eSequenceConfigs.hasMoreElements()) {
                    Sequence sequence = buildSequence((SequenceConfig)eSequenceConfigs.nextElement());
                    login.addSequence(sequence);
                }
            }
        }

        // Properties (assumes they are all valid)
        if (loginConfig.getPropertyConfigs() != null) {
            Enumeration e = loginConfig.getPropertyConfigs().elements();

            while (e.hasMoreElements()) {
                PropertyConfig propertyConfig = (PropertyConfig)e.nextElement();
                login.getProperties().put(propertyConfig.getName(), propertyConfig.getValue());
            }
        }
    }

    /**
     * INTERNAL:
     * Process the PoolsConfig object.
     */
    protected void processPoolsConfig(PoolsConfig poolsConfig, ServerSession serverSession) {
        if (poolsConfig != null) {
            // Read connection pool
            ReadConnectionPoolConfig readConnectionPoolConfig = poolsConfig.getReadConnectionPoolConfig();
            if (readConnectionPoolConfig != null) {
                serverSession.setReadConnectionPool(buildReadConnectionPoolConfig(readConnectionPoolConfig, serverSession));
            }

            // Write connection pool
            ConnectionPoolConfig writeConnectionPoolConfig = poolsConfig.getWriteConnectionPoolConfig();
            if (writeConnectionPoolConfig != null) {
                serverSession.addConnectionPool(buildConnectionPoolConfig(writeConnectionPoolConfig, serverSession));
            }

            // Sequence connection pool
            ConnectionPoolConfig sequenceConnectionPoolConfig = poolsConfig.getSequenceConnectionPoolConfig();
            if (sequenceConnectionPoolConfig != null) {
                processSequenceConnectionPoolConfig(sequenceConnectionPoolConfig, serverSession);
            }

            // Connection pools
            Enumeration e = poolsConfig.getConnectionPoolConfigs().elements();
            while (e.hasMoreElements()) {
                ConnectionPoolConfig connectionPoolConfig = (ConnectionPoolConfig)e.nextElement();
                serverSession.addConnectionPool(buildConnectionPoolConfig(connectionPoolConfig, serverSession));
            }
        }
    }

    /**
     * INTERNAL:
     * Process a SequenceConnectionPoolConfig object.
     */
    protected void processSequenceConnectionPoolConfig(ConnectionPoolConfig poolConfig, ServerSession serverSession) {
        // Set the Sequence connection pool flag to true
        serverSession.getSequencingControl().setShouldUseSeparateConnection(true);

        // Max connections
        Integer maxConnections = poolConfig.getMaxConnections();
        if (maxConnections != null) {
            serverSession.getSequencingControl().setMaxPoolSize(maxConnections);
        }

        // Min connections
        Integer minConnections = poolConfig.getMinConnections();
        if (minConnections != null) {
            serverSession.getSequencingControl().setMinPoolSize(minConnections);
        }

        // Name - no need to process
    }

    /**
     * INTERNAL:
     * Process a ServerPlatformConfig object.
     */
    protected void processServerPlatformConfig(ServerPlatformConfig platformConfig, ServerPlatform platform) {
        // Enable runtime services - XML schema default is true
        if (!platformConfig.getEnableRuntimeServices()) {
            platform.disableRuntimeServices();
        }

        // Enable JTA - XML schema default is true
        if (!platformConfig.getEnableJTA()) {
            platform.disableJTA();
        }
    }

    /**
     * INTERNAL:
     * Build a connection pool from the config to store on the server session.
     */
    protected ConnectionPool buildConnectionPoolConfig(ConnectionPoolConfig poolConfig, ServerSession serverSession) {
        ConnectionPool connectionPool = new ConnectionPool();

        // Process the common elements in ConnectionPool
        processConnectionPoolConfig(poolConfig, connectionPool, serverSession);

        return connectionPool;
    }

    /**
     * INTERNAL:
     */
    protected ServerPlatform buildCustomServerPlatformConfig(CustomServerPlatformConfig platformConfig, DatabaseSessionImpl session) {
        ServerPlatform platform;

        // Server class - XML schema default is org.eclipse.persistence.platform.server.CustomServerPlatform
        String serverClassName = platformConfig.getServerClassName();
        try {
            Class serverClass = m_classLoader.loadClass(serverClassName);
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                Constructor constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor(serverClass, new Class[] { org.eclipse.persistence.sessions.DatabaseSession.class }, false));
                platform = (ServerPlatform)AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, new Object[] { session }));
            }else{
                Constructor constructor = PrivilegedAccessHelper.getConstructorFor(serverClass, new Class[] { org.eclipse.persistence.sessions.DatabaseSession.class }, false);
                platform = (ServerPlatform)PrivilegedAccessHelper.invokeConstructor(constructor, new Object[] { session });
            }
        } catch (Exception e) {
            throw SessionLoaderException.failedToLoadTag("server-class", serverClassName, e);
        }

        // External transaction controller class
        String externalTransactionControllerClass = platformConfig.getExternalTransactionControllerClass();
        if (externalTransactionControllerClass != null) {
            try {
                platform.setExternalTransactionControllerClass(m_classLoader.loadClass(externalTransactionControllerClass));
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("external-transaction-controller-class", externalTransactionControllerClass, exception);
            }
        }

        return platform;
    }

    /**
     * INTERNAL:
     * Build a read connection pool from the config to store on the server session.
     */
    protected ConnectionPool buildReadConnectionPoolConfig(ReadConnectionPoolConfig poolConfig, ServerSession serverSession) {
        // Exclusive tag - XML Schema default is false
        ConnectionPool connectionPool = (poolConfig.getExclusive()) ? new ConnectionPool() : new ReadConnectionPool();

        // Process the common elements in ConnectionPool
        processConnectionPoolConfig(poolConfig, connectionPool, serverSession);

        return connectionPool;
    }

    /**
     * INTERNAL:
     * Process the common elements from a ConnectionPoolConfig
     */
    protected void processConnectionPolicyConfig(ConnectionPolicyConfig connectionPolicyConfig, ServerSession serverSession) {
        if (connectionPolicyConfig != null) {
            ConnectionPolicy connectionPolicy = serverSession.getDefaultConnectionPolicy();
            if(connectionPolicyConfig.getUseExclusiveConnection()) {
                connectionPolicy.setExclusiveMode(ConnectionPolicy.ExclusiveMode.Isolated);
            } else {
                connectionPolicy.setExclusiveMode(ConnectionPolicy.ExclusiveMode.Transactional);
            }
            connectionPolicy.setIsLazy(connectionPolicyConfig.getLazy());
        }
    }

    /**
     * INTERNAL:
     * Process the common elements from a ConnectionPoolConfig
     */
    protected void processConnectionPoolConfig(ConnectionPoolConfig poolConfig, ConnectionPool connectionPool, AbstractSession session) {
        // Login - if null, set it to the same as the session login
        Login login = buildLogin(poolConfig.getLoginConfig());
        if (login != null) {
            connectionPool.setLogin(login);
        } else {
            connectionPool.setLogin(session.getDatasourceLogin());
        }

        // Name
        connectionPool.setName(poolConfig.getName());

        // Max connections
        Integer maxConnections = poolConfig.getMaxConnections();
        if (maxConnections != null) {
            connectionPool.setMaxNumberOfConnections(maxConnections);
        }

        // Min connections
        Integer minConnections = poolConfig.getMinConnections();
        if (minConnections != null) {
            connectionPool.setMinNumberOfConnections(minConnections);
        }
    }

    /**
     * INTERNAL:
     * Process the common elements from a SessionConfig.
     */
    protected void processSessionConfig(SessionConfig sessionConfig, AbstractSession session) {
        // Name
        session.setName(sessionConfig.getName().trim());

        // Session Event Manager
        processSessionEventManagerConfig(sessionConfig.getSessionEventManagerConfig(), session);

        //server platform
        ((DatabaseSessionImpl)session).setServerPlatform(buildServerPlatformConfig(sessionConfig.getServerPlatformConfig(), (DatabaseSessionImpl)session));

        // Session Log - BUG# 3442865, don't set the log if it is null
        SessionLog log = buildSessionLog(sessionConfig.getLogConfig(), session);
        if (log != null) {
            session.setSessionLog(log);
        }

        // Remote command manager
        buildRemoteCommandManagerConfig(sessionConfig.getRemoteCommandManagerConfig(), session);

        // Profiler - XML Schema default is null
        if (sessionConfig.getProfiler() != null) {
            if (sessionConfig.getProfiler().equals("eclipselink")) {
                session.setProfiler(new PerformanceProfiler());
            }
        }

        // Exception handler
        String exceptionHandlerClassName = sessionConfig.getExceptionHandlerClass();
        if (exceptionHandlerClassName != null) {
            try {
                Class exceptionHandlerClass = m_classLoader.loadClass(exceptionHandlerClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    session.setExceptionHandler((ExceptionHandler)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(exceptionHandlerClass)));
                }else{
                    session.setExceptionHandler((ExceptionHandler)PrivilegedAccessHelper.newInstanceFromClass(exceptionHandlerClass));
                }
            } catch (Exception e) {
                throw SessionLoaderException.failedToLoadTag("exception-handler-class", exceptionHandlerClassName, e);
            }
        }

        // Session customizer will be processed in the buildSessions method.
        // Ensures it is run last.
    }

    /**
     * INTERNAL: Build the appropriate server platform
     */
    protected ServerPlatform buildServerPlatformConfig(ServerPlatformConfig platformConfig, DatabaseSessionImpl session) {
        if (platformConfig == null) {
            return new NoServerPlatform(session);
        }

        // Build the server platform, the config model knows which to build.
        ServerPlatform platform;

        if (platformConfig instanceof CustomServerPlatformConfig) {
            platform = buildCustomServerPlatformConfig((CustomServerPlatformConfig)platformConfig, session);
        } else {
            // A supported platform so instantiate an object of its type.
            String serverClassName = platformConfig.getServerClassName();
            if (platformConfig.isSupported()) {
                platform = ServerPlatformUtils.createServerPlatform(session, serverClassName, m_classLoader);
            } else {
                throw SessionLoaderException.serverPlatformNoLongerSupported(serverClassName);
            }
        }

        // Process the common elements in ServerPlatformConfig
        processServerPlatformConfig(platformConfig, platform);
        return platform;
    }

    /**
     * INTERNAL:
     */
    protected void buildRemoteCommandManagerConfig(RemoteCommandManagerConfig rcmConfig, AbstractSession session) {
        if (rcmConfig != null) {
            RemoteCommandManager rcm = new RemoteCommandManager(session);

            // Commands
            processCommandsConfig(rcmConfig.getCommandsConfig(), rcm);

            // Transport Manager - will set the built TransportManager on the given
            // Remote command manager that is passed in
            buildTransportManager(rcmConfig.getTransportManagerConfig(), rcm);

            // Channel - XML Schema default is TopLinkCommandChannel
            rcm.setChannel(rcmConfig.getChannel());
        }
    }

    /**
     * INTERNAL:
     */
    protected void buildTransportManager(TransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        if (tmConfig instanceof RMITransportManagerConfig) {
            buildRMITransportManagerConfig((RMITransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof RMIIIOPTransportManagerConfig) {
            buildRMIIIOPTransportManagerConfig((RMIIIOPTransportManagerConfig)tmConfig, rcm);
        }  else if (tmConfig instanceof JMSTopicTransportManagerConfig) {
            buildJMSTopicTransportManagerConfig((JMSTopicTransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof JMSPublishingTransportManagerConfig) {
            buildJMSPublishingTransportManagerConfig((JMSPublishingTransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof Oc4jJGroupsTransportManagerConfig) {
            buildOc4jJGroupsTransportManagerConfig((Oc4jJGroupsTransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof SunCORBATransportManagerConfig) {
            buildSunCORBATransportManagerConfig((SunCORBATransportManagerConfig)tmConfig, rcm);
        } else if (tmConfig instanceof UserDefinedTransportManagerConfig) {
            buildUserDefinedTransportManagerConfig((UserDefinedTransportManagerConfig)tmConfig, rcm);
        }
    }

    /**
     * INTERNAL:
     */
    protected void buildRMITransportManagerConfig(RMITransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        RMITransportManager tm = new RMITransportManager(rcm);

        // Set the transport manager. This will initialize the DiscoveryManager
        // This needs to be done before we process the DiscoveryConfig.
        rcm.setTransportManager(tm);

        // Discovery
        DiscoveryConfig discoveryConfig = tmConfig.getDiscoveryConfig();
        if (discoveryConfig != null) {
            processDiscoveryConfig(discoveryConfig, rcm.getDiscoveryManager());
        }

        if (tmConfig.getJNDINamingServiceConfig() != null) {
            // JNDI naming service
            tm.setNamingServiceType(TransportManager.JNDI_NAMING_SERVICE);
            processJNDINamingServiceConfig(tmConfig.getJNDINamingServiceConfig(), tm);
        } else if (tmConfig.getRMIRegistryNamingServiceConfig() != null) {
            // RMI registry naming service
            tm.setNamingServiceType(TransportManager.REGISTRY_NAMING_SERVICE);
            processRMIRegistryNamingServiceConfig(tmConfig.getRMIRegistryNamingServiceConfig(), tm);
        }

        tm.setIsRMIOverIIOP(tmConfig instanceof RMIIIOPTransportManagerConfig);

        // Send mode - Can only be Asynchronous (true) or Synchronous (false), validated by the schema
        // XML Schema default is Asynchronous
        rcm.setShouldPropagateAsynchronously(tmConfig.getSendMode().equals("Asynchronous"));

        // Process the common elements in TransportManagerConfig
        processTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     * Builds a Sequence from the given SequenceConfig.
     */
    protected Sequence buildSequence(SequenceConfig sequenceConfig) {
        if (sequenceConfig == null) {
            return null;
        }

        String name = sequenceConfig.getName();
        int size = sequenceConfig.getPreallocationSize();

        if (sequenceConfig instanceof DefaultSequenceConfig) {
            return new DefaultSequence(name, size);
        } else if (sequenceConfig instanceof NativeSequenceConfig) {
            return new NativeSequence(name, size);
        } else if (sequenceConfig instanceof TableSequenceConfig) {
            TableSequenceConfig tsc = (TableSequenceConfig)sequenceConfig;
            return new TableSequence(name, size, tsc.getTable(), tsc.getNameField(), tsc.getCounterField());
        } else if (sequenceConfig instanceof UnaryTableSequenceConfig) {
            UnaryTableSequenceConfig utsc = (UnaryTableSequenceConfig)sequenceConfig;
            return new UnaryTableSequence(name, size, utsc.getCounterField());
        } else if (sequenceConfig instanceof XMLFileSequenceConfig) {
            try {
                // Can no longer reference class directly as in a different project.
                Class xmlClass = Class.forName("org.eclipse.persistence.eis.adapters.xmlfile.XMLFileSequence");
                Sequence sequence = (Sequence)xmlClass.getConstructor().newInstance();
                sequence.setName(name);
                sequence.setInitialValue(size);
                return sequence;
            } catch (Exception missing) {
                return null;
            }
        } else {
            // Unknown SequenceConfig subclass - should never happen
            return null;
        }
    }

    /**
     * INTERNAL:
     * Left this in for now since in the future we may add more IIOP specific
     * configurations?
     */
    protected void buildRMIIIOPTransportManagerConfig(RMIIIOPTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        buildRMITransportManagerConfig(tmConfig, rcm);
    }

    /**
     * INTERNAL:
     */
    protected void buildJMSTopicTransportManagerConfig(JMSTopicTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        JMSTopicTransportManager tm = new JMSTopicTransportManager(rcm);

        // Set the transport manager. This will initialize the DiscoveryManager
        rcm.setTransportManager(tm);

        processJMSTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     */
    protected void buildJMSPublishingTransportManagerConfig(JMSPublishingTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        JMSPublishingTransportManager tm = new JMSPublishingTransportManager(rcm);

        // Set the transport manager. This will initialize the DiscoveryManager
        rcm.setTransportManager(tm);
        processJMSTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     * Common JMS configuration
     */
    protected void processJMSTransportManagerConfig(JMSPublishingTransportManagerConfig tmConfig, JMSPublishingTransportManager tm ){
        // JNDI naming service
        if (tmConfig.getJNDINamingServiceConfig() != null) {
            tm.setNamingServiceType(TransportManager.JNDI_NAMING_SERVICE);
            processJNDINamingServiceConfig(tmConfig.getJNDINamingServiceConfig(), tm);
        }

        // Topic host URL
        String topicHostURL = tmConfig.getTopicHostURL();
        if (topicHostURL != null) {
            tm.setTopicHostUrl(topicHostURL);
        }

        // Topic connection factory name - XML Schema default is jms/TopLinkTopicConnectionFactory
        tm.setTopicConnectionFactoryName(tmConfig.getTopicConnectionFactoryName());

        // Topic name - XML Schema default is jms/TopLinkTopic
        tm.setTopicName(tmConfig.getTopicName());

        // Process the common elements in TransportManagerConfig
        processTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     */
    protected void buildOc4jJGroupsTransportManagerConfig(Oc4jJGroupsTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        TransportManager tm = null;
        try {
            Class tmClass = m_classLoader.loadClass(tmConfig.getTransportManagerClassName());
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                Constructor constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor(tmClass, new Class[] { RemoteCommandManager.class, boolean.class, String.class }, false));
                tm = (TransportManager)AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, new Object[] { rcm, tmConfig.useSingleThreadedNotification(), tmConfig.getTopicName() }));
            }else{
                Constructor constructor = PrivilegedAccessHelper.getConstructorFor(tmClass, new Class[] { RemoteCommandManager.class, boolean.class, String.class }, false);
                tm = (TransportManager)PrivilegedAccessHelper.invokeConstructor(constructor, new Object[] { rcm, tmConfig.useSingleThreadedNotification(), tmConfig.getTopicName() });
            }
        } catch (Exception e) {
            throw SessionLoaderException.failedToParseXML("Oc4jJGroupsTransportManager class is invalid: " + tmConfig.getTransportManagerClassName(), e);
        }

        // Set the transport manager. This will initialize the DiscoveryManager
        rcm.setTransportManager(tm);

        // Process the common elements in TransportManagerConfig
        processTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     */
    protected void buildUserDefinedTransportManagerConfig(UserDefinedTransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        TransportManager tm = null;

        // Transport class
        String transportManagerClassName = tmConfig.getTransportClass();
        if (transportManagerClassName != null) {
            try {
                Class transportManagerClass = m_classLoader.loadClass(transportManagerClassName);
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    tm = (TransportManager)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(transportManagerClass));
                }else{
                    tm = (TransportManager)PrivilegedAccessHelper.newInstanceFromClass(transportManagerClass);
                }
            } catch (Exception exception) {
                throw SessionLoaderException.failedToLoadTag("transport-class", transportManagerClassName, exception);
            }

            // Set the transport manager. This will initialize the DiscoveryManager
            rcm.setTransportManager(tm);

            // Process the common elements in TransportManagerConfig
            processTransportManagerConfig(tmConfig, tm);
        }
    }

    /**
     * INTERNAL:
     */
    protected void processJNDINamingServiceConfig(JNDINamingServiceConfig namingConfig, TransportManager tm) {
        // URL
        String url = namingConfig.getURL();
        if (url != null) {
            tm.getRemoteCommandManager().setUrl(url);
        }

        // Username - XML Schema default is admin
        tm.setUserName(namingConfig.getUsername());

        // Encryption class - XML Schema default is org.eclipse.persistence.internal.security.JCEEncryptor
        tm.setEncryptionClassName(namingConfig.getEncryptionClass());

        // Password - XML Schema default is password
        tm.setEncryptedPassword(namingConfig.getEncryptedPassword());

        // Initial context factory name - XML Schema is weblogic.jndi.WLInitialContextFactory
        tm.setInitialContextFactoryName(namingConfig.getInitialContextFactoryName());

        // Properties (assumes they are all valid)
        Enumeration e = namingConfig.getPropertyConfigs().elements();

        while (e.hasMoreElements()) {
            PropertyConfig propertyConfig = (PropertyConfig)e.nextElement();
            tm.getRemoteContextProperties().put(propertyConfig.getName(), propertyConfig.getValue());
        }
    }

    /**
     * INTERNAL:
     */
    protected void processRMIRegistryNamingServiceConfig(RMIRegistryNamingServiceConfig namingConfig, TransportManager tm) {
        // URL
        tm.getRemoteCommandManager().setUrl(namingConfig.getURL());
    }

    /**
     * INTERNAL:
     */
    protected void processDiscoveryConfig(DiscoveryConfig discoveryConfig, DiscoveryManager discoveryManager) {
        // Multicast group address - XML Schema default is 226.10.12.64
        discoveryManager.setMulticastGroupAddress(discoveryConfig.getMulticastGroupAddress());

        // Mutlicast port - XML Schema default is 3121
        discoveryManager.setMulticastPort(discoveryConfig.getMulticastPort());

        // Announcement delay - XML Schema default is 1000
        discoveryManager.setAnnouncementDelay(discoveryConfig.getAnnouncementDelay());

        //Packet time-to-live - XML Schema default is 2
        discoveryManager.setPacketTimeToLive(discoveryConfig.getPacketTimeToLive());
    }

    /**
     * INTERNAL:
     */
    protected void processTransportManagerConfig(TransportManagerConfig tmConfig, TransportManager tm) {
        // On connection error - Can only be DiscardConnection (true) or
        // KeepConnection (false), validated by the schema
        // XML Schema default is DiscardConnection
        tm.setShouldRemoveConnectionOnError(tmConfig.getOnConnectionError().equals("DiscardConnection"));
    }

    /**
     * INTERNAL:
     */
    protected void processSessionEventManagerConfig(SessionEventManagerConfig sessionEventManagerConfig, AbstractSession session) {
        if (sessionEventManagerConfig != null) {
            Enumeration e = sessionEventManagerConfig.getSessionEventListeners().elements();

            while (e.hasMoreElements()) {
                String listenerClassName = (String)e.nextElement();

                try {
                    Class listenerClass = m_classLoader.loadClass(listenerClassName);
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                        session.getEventManager().addListener((SessionEventListener)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(listenerClass)));
                    }else{

                    }
                    session.getEventManager().addListener((SessionEventListener)PrivilegedAccessHelper.newInstanceFromClass(listenerClass));
                } catch (Exception exception) {
                    throw SessionLoaderException.failedToLoadTag("event-listener-class", listenerClassName, exception);
                }
            }
        }
    }

    /**
     * INTERNAL:
     */
    protected SessionLog buildSessionLog(LogConfig logConfig, AbstractSession session) {
        if (logConfig instanceof JavaLogConfig) {
            return buildJavaLogConfig((JavaLogConfig)logConfig, session);
        } else if (logConfig instanceof DefaultSessionLogConfig) {
            return buildDefaultSessionLogConfig((DefaultSessionLogConfig)logConfig);
        } else if (logConfig instanceof ServerLogConfig) {
            return buildServerLogConfig((ServerLogConfig)logConfig, session);
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     */
    protected SessionLog buildJavaLogConfig(JavaLogConfig javaLogConfig, AbstractSession session) {
        SessionLog javaLog = null;
        try {
            // use ConversionManager to avoid loading the JDK 1.4 class unless it is needed.
            ConversionManager conversionManager = new ConversionManager();
            conversionManager.setLoader(getClass().getClassLoader());
            javaLog = (SessionLog)((Class)conversionManager.convertObject("org.eclipse.persistence.logging.JavaLog", Class.class)).getConstructor().newInstance();
            javaLog.setSession(session);
        } catch (Exception exception) {
            throw ValidationException.unableToLoadClass("org.eclipse.persistence.logging.JavaLog", exception);
        }

        // Process the common elements from LogConfig
        processLogConfig(javaLogConfig, javaLog);

        return javaLog;
    }

    /**
     * INTERNAL:
     * Wrapped by the getSessionLog() call, therefore, config can't be null at
     * this point.
     */
    protected SessionLog buildDefaultSessionLogConfig(DefaultSessionLogConfig defaultSessionLogConfig) {
        DefaultSessionLog defaultSessionLog = new DefaultSessionLog();

        // Log level - XML Schema default is info
        defaultSessionLog.setLevel(m_logLevels.get(defaultSessionLogConfig.getLogLevel()));

        // Filename - setWriter will handle nulls
        defaultSessionLog.setWriter(defaultSessionLogConfig.getFilename());

        // Process the common elements from LogConfig
        processLogConfig(defaultSessionLogConfig, defaultSessionLog);

        return defaultSessionLog;
    }

    /**
     * INTERNAL:
     */
    protected SessionLog buildServerLogConfig(ServerLogConfig serverLogConfig, AbstractSession session) {
        SessionLog serverLog = session.getServerPlatform().getServerLog();

        return serverLog;
    }

    /**
     * INTERNAL:
     */
    protected void processLogConfig(LogConfig logConfig, SessionLog log) {
        if (logConfig.getLoggingOptions() != null) {
            if (logConfig.getLoggingOptions().getShouldLogExceptionStackTrace() != null) {
                log.setShouldLogExceptionStackTrace(logConfig.getLoggingOptions().getShouldLogExceptionStackTrace());
            }
            if (logConfig.getLoggingOptions().getShouldPrintConnection() != null) {
                log.setShouldPrintConnection(logConfig.getLoggingOptions().getShouldPrintConnection());
            }
            if (logConfig.getLoggingOptions().getShouldPrintDate() != null) {
                log.setShouldPrintDate(logConfig.getLoggingOptions().getShouldPrintDate());
            }
            if (logConfig.getLoggingOptions().getShouldPrintSession() != null) {
                log.setShouldPrintSession(logConfig.getLoggingOptions().getShouldPrintSession());
            }
            if (logConfig.getLoggingOptions().getShouldPrintThread() != null) {
                log.setShouldPrintThread(logConfig.getLoggingOptions().getShouldPrintThread());
            }
        }
    }

    /**
     * INTERNAL:
     * Builds a Sun CORBA transport manager with the given remote command manager
     */
    protected void buildSunCORBATransportManagerConfig(SunCORBATransportManagerConfig tmConfig, RemoteCommandManager rcm) {
        TransportManager tm = TransportManager.newSunCORBATransportManager(rcm);

        // Set the transport manager. This will initialize the DiscoveryManager
        rcm.setTransportManager(tm);

        // Process the common elements in TransportManagerConfig
        processTransportManagerConfig(tmConfig, tm);
    }

    /**
     * INTERNAL:
     */
    protected void processCommandsConfig(CommandsConfig commandsConfig, RemoteCommandManager rcm) {
        if (commandsConfig != null) {
            // cache-sync - XML Schema default is false
            ((AbstractSession)rcm.getCommandProcessor()).setShouldPropagateChanges(commandsConfig.getCacheSync());
        }
    }

    /**
     * INTERNAL:
     * Builds a session broker from the given SessionBrokerConfig.
     */
    protected SessionBroker buildSessionBrokerConfig(SessionBrokerConfig sessionBrokerConfig) {
        SessionBroker sessionBroker = new SessionBroker();

        // Session names
        Enumeration<String> sessionNames = sessionBrokerConfig.getSessionNames().elements();

        while (sessionNames.hasMoreElements()) {
            // Register the sessions
            String sessionName = sessionNames.nextElement();
            sessionBroker.registerSession(sessionName, (AbstractSession)m_sessions.get(sessionName));
        }

        // Process the common elements in SessionConfig
        processSessionConfig(sessionBrokerConfig, sessionBroker);

        return sessionBroker;
    }
}
