/*
 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.corba.se.impl.orb;

import java.applet.Applet;

import java.io.IOException;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.InvocationTargetException;

import java.util.Set;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Map;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Collection;
import java.util.Collections;
import java.util.StringTokenizer;
import java.util.Enumeration;
import java.util.WeakHashMap;

import java.net.InetAddress;

import java.security.PrivilegedAction;
import java.security.AccessController;

import javax.rmi.CORBA.Util;
import javax.rmi.CORBA.ValueHandler;

import org.omg.CORBA.Context;
import org.omg.CORBA.ContextList;
import org.omg.CORBA.Environment;
import org.omg.CORBA.ExceptionList;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CORBA.NVList;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.NamedValue;
import org.omg.CORBA.Request;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.Any;
import org.omg.CORBA.StructMember;
import org.omg.CORBA.UnionMember;
import org.omg.CORBA.ValueMember;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.MARSHAL;

import org.omg.CORBA.portable.ValueFactory;

import org.omg.CORBA.ORBPackage.InvalidName;

import com.sun.org.omg.SendingContext.CodeBase;

import com.sun.corba.se.pept.broker.Broker;
import com.sun.corba.se.pept.protocol.ClientInvocationInfo;
import com.sun.corba.se.pept.transport.ContactInfo;
import com.sun.corba.se.pept.transport.ConnectionCache;
import com.sun.corba.se.pept.transport.TransportManager;

import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.spi.ior.IdentifiableFactoryFinder;
import com.sun.corba.se.spi.ior.TaggedComponentFactoryFinder;
import com.sun.corba.se.spi.ior.IORFactories;
import com.sun.corba.se.spi.ior.ObjectKey;
import com.sun.corba.se.spi.ior.ObjectKeyFactory;
import com.sun.corba.se.spi.ior.iiop.IIOPFactories;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.spi.oa.OAInvocationInfo;
import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
import com.sun.corba.se.spi.orb.DataCollector;
import com.sun.corba.se.spi.orb.Operation;
import com.sun.corba.se.spi.orb.ORBData;
import com.sun.corba.se.spi.orb.ORBConfigurator;
import com.sun.corba.se.spi.orb.ParserImplBase;
import com.sun.corba.se.spi.orb.PropertyParser;
import com.sun.corba.se.spi.orb.OperationFactory;
import com.sun.corba.se.spi.orb.ORBVersion;
import com.sun.corba.se.spi.orb.ORBVersionFactory;
import com.sun.corba.se.spi.orbutil.closure.ClosureFactory;
import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolManager;
import com.sun.corba.se.spi.protocol.ClientDelegateFactory;
import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;
import com.sun.corba.se.spi.protocol.RequestDispatcherDefault;
import com.sun.corba.se.spi.protocol.PIHandler;
import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
import com.sun.corba.se.spi.protocol.ForwardException;
import com.sun.corba.se.spi.resolver.Resolver;
import com.sun.corba.se.spi.resolver.LocalResolver;
import com.sun.corba.se.spi.orb.StringPair;
import com.sun.corba.se.spi.orb.StringPair;
import com.sun.corba.se.spi.transport.CorbaContactInfoListFactory;
import com.sun.corba.se.spi.transport.CorbaTransportManager;
import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketManager;
import com.sun.corba.se.spi.copyobject.CopierManager;
import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults;
import com.sun.corba.se.spi.presentation.rmi.PresentationManager;
import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
import com.sun.corba.se.spi.servicecontext.ServiceContextRegistry;

import com.sun.corba.se.impl.corba.TypeCodeFactory;
import com.sun.corba.se.impl.corba.TypeCodeImpl;
import com.sun.corba.se.impl.corba.NVListImpl;
import com.sun.corba.se.impl.corba.ExceptionListImpl;
import com.sun.corba.se.impl.corba.ContextListImpl;
import com.sun.corba.se.impl.corba.NamedValueImpl;
import com.sun.corba.se.impl.corba.EnvironmentImpl;
import com.sun.corba.se.impl.corba.AsynchInvoke;
import com.sun.corba.se.impl.corba.AnyImpl;
import com.sun.corba.se.impl.corba.RequestImpl;
import com.sun.corba.se.impl.dynamicany.DynAnyFactoryImpl;
import com.sun.corba.se.impl.encoding.EncapsOutputStream;
import com.sun.corba.se.impl.encoding.CachedCodeBase;
import com.sun.corba.se.impl.interceptors.PIHandlerImpl;
import com.sun.corba.se.impl.interceptors.PINoOpHandlerImpl;
import com.sun.corba.se.impl.ior.TaggedComponentFactoryFinderImpl;
import com.sun.corba.se.impl.ior.TaggedProfileFactoryFinderImpl;
import com.sun.corba.se.impl.ior.TaggedProfileTemplateFactoryFinderImpl;
import com.sun.corba.se.impl.oa.toa.TOAFactory;
import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
import com.sun.corba.se.impl.oa.poa.DelegateImpl;
import com.sun.corba.se.impl.oa.poa.POAFactory;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.StackImpl;
import com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl;
import com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolManagerImpl;
import com.sun.corba.se.impl.protocol.RequestDispatcherRegistryImpl;
import com.sun.corba.se.impl.protocol.CorbaInvocationInfo;
import com.sun.corba.se.impl.transport.CorbaTransportManagerImpl;
import com.sun.corba.se.impl.legacy.connection.LegacyServerSocketManagerImpl;
import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.logging.ORBUtilSystemException;
import com.sun.corba.se.impl.copyobject.CopierManagerImpl;
import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl;

/**
 * The JavaIDL ORB implementation.
 */
public class ORBImpl extends com.sun.corba.se.spi.orb.ORB
{
    protected TransportManager transportManager;
    protected LegacyServerSocketManager legacyServerSocketManager;

    private ThreadLocal OAInvocationInfoStack ;

    private ThreadLocal clientInvocationInfoStack ;

    // pure java orb, caching the servant IOR per ORB
    private static IOR codeBaseIOR ;

    // Vector holding deferred Requests
    private Vector            dynamicRequests ;
    private SynchVariable     svResponseReceived ;

    private java.lang.Object runObj = new java.lang.Object();
    private java.lang.Object shutdownObj = new java.lang.Object();
    private java.lang.Object waitForCompletionObj = new java.lang.Object();
    private static final byte STATUS_OPERATING = 1;
    private static final byte STATUS_SHUTTING_DOWN = 2;
    private static final byte STATUS_SHUTDOWN = 3;
    private static final byte STATUS_DESTROYED = 4;
    private byte status = STATUS_OPERATING;

    // XXX Should we move invocation tracking to the first level server dispatcher?
    private java.lang.Object invocationObj = new java.lang.Object();
    private int numInvocations = 0;

    // thread local variable to store a boolean to detect deadlock in
    // ORB.shutdown(true).
    private ThreadLocal isProcessingInvocation = new ThreadLocal () {
        protected java.lang.Object initialValue() {
            return Boolean.FALSE;
        }
    };

    // This map is caching TypeCodes created for a certain class (key)
    // and is used in Util.writeAny()
    private Map typeCodeForClassMap ;

    // Cache to hold ValueFactories (Helper classes) keyed on repository ids
    private Hashtable valueFactoryCache = new Hashtable();

    // thread local variable to store the current ORB version.
    // default ORB version is the version of ORB with correct Rep-id
    // changes
    private ThreadLocal orbVersionThreadLocal ;

    private RequestDispatcherRegistry requestDispatcherRegistry ;

    private CopierManager copierManager ;

    private int transientServerId ;

    private ServiceContextRegistry serviceContextRegistry ;

    // Needed here to implement connect/disconnect
    private TOAFactory toaFactory ;

    // Needed here for set_delegate
    private POAFactory poaFactory ;

    // The interceptor handler, which provides portable interceptor services for
    // subcontracts and object adapters.
    private PIHandler pihandler ;

    private ORBData configData ;

    private BadServerIdHandler badServerIdHandler ;

    private ClientDelegateFactory clientDelegateFactory ;

    private CorbaContactInfoListFactory corbaContactInfoListFactory ;

    // All access to resolver, localResolver, and urlOperation must be protected using
    // resolverLock.  Do not hold the ORBImpl lock while accessing
    // resolver, or deadlocks may occur.
    // Note that we now have separate locks for each resolver type.  This is due
    // to bug 6980681 and 6238477, which was caused by a deadlock while resolving a
    // corbaname: URL that contained a reference to the same ORB as the
    // ORB making the call to string_to_object.  This caused a deadlock between the
    // client thread holding the single lock for access to the urlOperation,
    // and the server thread handling the client is_a request waiting on the
    // same lock to access the localResolver.


    // Used for resolver_initial_references and list_initial_services
    private Resolver resolver ;

    // Used for register_initial_references
    private LocalResolver localResolver ;

    // Converts strings to object references for resolvers and string_to_object
    private Operation urlOperation ;
    private final Object urlOperationLock = new java.lang.Object() ;

    private CorbaServerRequestDispatcher insNamingDelegate ;

    // resolverLock must be used for all access to either resolver or
    // localResolver, since it is possible for the resolver to indirectly
    // refer to the localResolver.  Also used to protect access to
    // insNamingDelegate.
    private final Object resolverLock = new Object() ;

    private TaggedComponentFactoryFinder taggedComponentFactoryFinder ;

    private IdentifiableFactoryFinder taggedProfileFactoryFinder ;

    private IdentifiableFactoryFinder taggedProfileTemplateFactoryFinder ;

    private ObjectKeyFactory objectKeyFactory ;

    private boolean orbOwnsThreadPoolManager = false ;

    private ThreadPoolManager threadpoolMgr;

    private void dprint( String msg )
    {
        ORBUtility.dprint( this, msg ) ;
    }

    ////////////////////////////////////////////////////
    //
    // NOTE:
    //
    // Methods that are synchronized MUST stay synchronized.
    //
    // Methods that are NOT synchronized must stay that way to avoid deadlock.
    //
    //
    // REVISIT:
    //
    // checkShutDownState - lock on different object - and normalize usage.
    // starting/FinishDispatch and Shutdown
    //

    public ORBData getORBData()
    {
        return configData ;
    }

    public PIHandler getPIHandler()
    {
        return pihandler ;
    }

    /**
     * Create a new ORB. Should be followed by the appropriate
     * set_parameters() call.
     */
    public ORBImpl()
    {
        // All initialization is done through set_parameters().
    }

    public ORBVersion getORBVersion()
    {
        synchronized (this) {
                checkShutdownState();
        }
        return (ORBVersion)(orbVersionThreadLocal.get()) ;
    }

    public void setORBVersion(ORBVersion verObj)
    {
        synchronized (this) {
                checkShutdownState();
        }
        orbVersionThreadLocal.set(verObj);
    }

/****************************************************************************
 * The following methods are ORB initialization
 ****************************************************************************/

    // preInit initializes all non-pluggable ORB data that is independent
    // of the property parsing.
    private void preInit( String[] params, Properties props )
    {
        // Before ORBConfiguration we need to set a PINoOpHandlerImpl,
        // because PersisentServer Initialization inside configurator will
        // invoke orb.resolve_initial_references( ) which will result in a
        // check on piHandler to invoke Interceptors. We do not want any
        // Interceptors to be invoked before the complete ORB initialization.
        // piHandler will be replaced by a real PIHandler implementation at the
        // end of this method.
        pihandler = new PINoOpHandlerImpl( );

        // This is the unique id of this server (JVM). Multiple incarnations
        // of this server will get different ids.
        // Compute transientServerId = milliseconds since Jan 1, 1970
        // Note: transientServerId will wrap in about 2^32 / 86400000 = 49.7 days.
        // If two ORBS are started at the same time then there is a possibility
        // of having the same transientServerId. This may result in collision
        // and may be a problem in ior.isLocal() check to see if the object
        // belongs to the current ORB. This problem is taken care of by checking
        // to see if the IOR port matches ORB server port in legacyIsLocalServerPort()
        // method.
        //
        // XXX need to move server ID to a string for CORBA 3.0.  At that point,
        // make this more unique (possibly use java.rmi.server.UID).
        transientServerId = (int)System.currentTimeMillis();

        orbVersionThreadLocal  = new ThreadLocal () {
            protected java.lang.Object initialValue() {
                // set default to version of the ORB with correct Rep-ids
                return ORBVersionFactory.getORBVersion() ;
            }
        };


        requestDispatcherRegistry = new RequestDispatcherRegistryImpl(
            this, ORBConstants.DEFAULT_SCID);
        copierManager = new CopierManagerImpl( this ) ;

        taggedComponentFactoryFinder =
            new TaggedComponentFactoryFinderImpl(this) ;
        taggedProfileFactoryFinder =
            new TaggedProfileFactoryFinderImpl(this) ;
        taggedProfileTemplateFactoryFinder =
            new TaggedProfileTemplateFactoryFinderImpl(this) ;

        dynamicRequests = new Vector();
        svResponseReceived = new SynchVariable();

        OAInvocationInfoStack =
            new ThreadLocal () {
                protected java.lang.Object initialValue()
                {
                    return new StackImpl();
                }
            };

        clientInvocationInfoStack =
            new ThreadLocal() {
                protected java.lang.Object initialValue() {
                    return new StackImpl();
                }
            };

        serviceContextRegistry = new ServiceContextRegistry( this ) ;
    }

    protected void setDebugFlags( String[] args )
    {
        for (int ctr=0; ctr<args.length; ctr++ ) {
            String token = args[ctr] ;

            // If there is a public boolean data member in this class
            // named token + "DebugFlag", set it to true.
            try {
                Field fld = this.getClass().getField( token + "DebugFlag" ) ;
                int mod = fld.getModifiers() ;
                if (Modifier.isPublic( mod ) && !Modifier.isStatic( mod ))
                    if (fld.getType() == boolean.class)
                        fld.setBoolean( this, true ) ;
            } catch (Exception exc) {
                // ignore it XXX log this as info
            }
        }
    }

    // Class that defines a parser that gets the name of the
    // ORBConfigurator class.
    private static class ConfigParser extends ParserImplBase {
        // The default here is the ORBConfiguratorImpl that we define,
        // but this can be replaced.
        public Class configurator = ORBConfiguratorImpl.class ;

        public PropertyParser makeParser()
        {
            PropertyParser parser = new PropertyParser() ;
            parser.add( ORBConstants.SUN_PREFIX + "ORBConfigurator",
                OperationFactory.classAction(), "configurator" ) ;
            return parser ;
        }
    }

    private void postInit( String[] params, DataCollector dataCollector )
    {
        // First, create the standard ORB config data.
        // This must be initialized before the ORBConfigurator
        // is executed.
        configData = new ORBDataParserImpl( this, dataCollector) ;

        // Set the debug flags early so they can be used by other
        // parts of the initialization.
        setDebugFlags( configData.getORBDebugFlags() ) ;

        // REVISIT: this should go away after more transport init cleanup
        // and going to ORT based ORBD.
        getTransportManager();
        getLegacyServerSocketManager();

        // Create a parser to get the configured ORBConfigurator.
        ConfigParser parser = new ConfigParser() ;
        parser.init( dataCollector ) ;

        ORBConfigurator configurator =  null ;
        try {
            configurator =
                (ORBConfigurator)(parser.configurator.newInstance()) ;
        } catch (Exception iexc) {
            throw wrapper.badOrbConfigurator( iexc, parser.configurator.getName() ) ;
        }

        // Finally, run the configurator.  Note that the default implementation allows
        // other configurators with their own parsers to run,
        // using the same DataCollector.
        try {
            configurator.configure( dataCollector, this ) ;
        } catch (Exception exc) {
            throw wrapper.orbConfiguratorError( exc ) ;
        }

        // Last of all, create the PIHandler and run the ORB initializers.
        pihandler = new PIHandlerImpl( this, params) ;
        pihandler.initialize() ;

        // Initialize the thread manager pool and byte buffer pool
        // so they may be initialized & accessed without synchronization
        getThreadPoolManager();

        super.getByteBufferPool();
    }

    private synchronized POAFactory getPOAFactory()
    {
        if (poaFactory == null) {
            poaFactory = (POAFactory)requestDispatcherRegistry.getObjectAdapterFactory(
                ORBConstants.TRANSIENT_SCID ) ;
        }

        return poaFactory ;
    }

    private synchronized TOAFactory getTOAFactory()
    {
        if (toaFactory == null) {
            toaFactory = (TOAFactory)requestDispatcherRegistry.getObjectAdapterFactory(
                ORBConstants.TOA_SCID ) ;
        }

        return toaFactory ;
    }

    public void set_parameters( Properties props )
    {
        synchronized (this) {
                checkShutdownState();
        }
        preInit( null, props ) ;
        DataCollector dataCollector =
            DataCollectorFactory.create( props, getLocalHostName() ) ;
        postInit( null, dataCollector ) ;
    }

    protected void set_parameters(Applet app, Properties props)
    {
        preInit( null, props ) ;
        DataCollector dataCollector =
            DataCollectorFactory.create( app, props, getLocalHostName() ) ;
        postInit( null, dataCollector ) ;
    }

    protected void set_parameters (String[] params, Properties props)
    {
        preInit( params, props ) ;
        DataCollector dataCollector =
            DataCollectorFactory.create( params, props, getLocalHostName() ) ;
        postInit( params, dataCollector ) ;
    }

/****************************************************************************
 * The following methods are standard public CORBA ORB APIs
 ****************************************************************************/

    public synchronized org.omg.CORBA.portable.OutputStream create_output_stream()
    {
        checkShutdownState();
        return sun.corba.OutputStreamFactory.newEncapsOutputStream(this);
    }

    /**
     * Get a Current pseudo-object.
     * The Current interface is used to manage thread-specific
     * information for use by the transactions, security and other
     * services. This method is deprecated,
     * and replaced by ORB.resolve_initial_references("NameOfCurrentObject");
     *
     * @return          a Current pseudo-object.
     * @deprecated
     */
    public synchronized org.omg.CORBA.Current get_current()
    {
        checkShutdownState();

        /* _REVISIT_
           The implementation of get_current is not clear. How would
           ORB know whether the caller wants a Current for transactions
           or security ?? Or is it assumed that there is just one
           implementation for both ? If Current is thread-specific,
           then it should not be instantiated; so where does the
           ORB get a Current ?

           This should probably be deprecated. */

        throw wrapper.genericNoImpl() ;
    }

    /**
     * Create an NVList
     *
     * @param count     size of list to create
     * @result          NVList created
     *
     * @see NVList
     */
    public synchronized NVList create_list(int count)
    {
        checkShutdownState();
        return new NVListImpl(this, count);
    }

    /**
     * Create an NVList corresponding to an OperationDef
     *
     * @param oper      operation def to use to create list
     * @result          NVList created
     *
     * @see NVList
     */
    public synchronized NVList create_operation_list(org.omg.CORBA.Object oper)
    {
        checkShutdownState();
        throw wrapper.genericNoImpl() ;
    }

    /**
     * Create a NamedValue
     *
     * @result          NamedValue created
     */
    public synchronized NamedValue create_named_value(String s, Any any, int flags)
    {
        checkShutdownState();
        return new NamedValueImpl(this, s, any, flags);
    }

    /**
     * Create an ExceptionList
     *
     * @result          ExceptionList created
     */
    public synchronized org.omg.CORBA.ExceptionList create_exception_list()
    {
        checkShutdownState();
        return new ExceptionListImpl();
    }

    /**
     * Create a ContextList
     *
     * @result          ContextList created
     */
    public synchronized org.omg.CORBA.ContextList create_context_list()
    {
        checkShutdownState();
        return new ContextListImpl(this);
    }

    /**
     * Get the default Context object
     *
     * @result          the default Context object
     */
    public synchronized org.omg.CORBA.Context get_default_context()
    {
        checkShutdownState();
        throw wrapper.genericNoImpl() ;
    }

    /**
     * Create an Environment
     *
     * @result          Environment created
     */
    public synchronized org.omg.CORBA.Environment create_environment()
    {
        checkShutdownState();
        return new EnvironmentImpl();
    }

    public synchronized void send_multiple_requests_oneway(Request[] req)
    {
        checkShutdownState();

        // Invoke the send_oneway on each new Request
        for (int i = 0; i < req.length; i++) {
            req[i].send_oneway();
        }
    }

    /**
     * Send multiple dynamic requests asynchronously.
     *
     * @param req         an array of request objects.
     */
    public synchronized void send_multiple_requests_deferred(Request[] req)
    {
        checkShutdownState();

        // add the new Requests to pending dynamic Requests
        for (int i = 0; i < req.length; i++) {
            dynamicRequests.addElement(req[i]);
        }

        // Invoke the send_deferred on each new Request
        for (int i = 0; i < req.length; i++) {
            AsynchInvoke invokeObject = new AsynchInvoke( this,
                (com.sun.corba.se.impl.corba.RequestImpl)req[i], true);
            new Thread(invokeObject).start();
        }
    }

    /**
     * Find out if any of the deferred invocations have a response yet.
     */
    public synchronized boolean poll_next_response()
    {
        checkShutdownState();

        Request currRequest;

        // poll on each pending request
        Enumeration ve = dynamicRequests.elements();
        while (ve.hasMoreElements() == true) {
            currRequest = (Request)ve.nextElement();
            if (currRequest.poll_response() == true) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get the next request that has gotten a response.
     *
     * @result            the next request ready with a response.
     */
    public org.omg.CORBA.Request get_next_response()
        throws org.omg.CORBA.WrongTransaction
    {
        synchronized( this ) {
            checkShutdownState();
        }

        while (true) {
            // check if there already is a response
            synchronized ( dynamicRequests ) {
                Enumeration elems = dynamicRequests.elements();
                while ( elems.hasMoreElements() ) {
                    Request currRequest = (Request)elems.nextElement();
                    if ( currRequest.poll_response() ) {
                        // get the response for this successfully polled Request
                        currRequest.get_response();
                        dynamicRequests.removeElement(currRequest);
                        return currRequest;
                    }
                }
            }

            // wait for a response
            synchronized(this.svResponseReceived) {
                while (!this.svResponseReceived.value()) {
                    try {
                        this.svResponseReceived.wait();
                    } catch(java.lang.InterruptedException ex) {
                        // NO-OP
                    }
                }
                // reinitialize the response flag
                this.svResponseReceived.reset();
            }
        }
    }

    /**
     * Notify response to ORB for get_next_response
     */
    public void notifyORB()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (this.svResponseReceived) {
            this.svResponseReceived.set();
            this.svResponseReceived.notify();
        }
    }

    /**
     * Convert an object ref to a string.
     * @param obj The object to stringify.
     * @return A stringified object reference.
     */
    public synchronized String object_to_string(org.omg.CORBA.Object obj)
    {
        checkShutdownState();

        // Handle the null objref case
        if (obj == null) {
            IOR nullIOR = IORFactories.makeIOR( this ) ;
            return nullIOR.stringify();
        }

        IOR ior = null ;

        try {
            ior = ORBUtility.connectAndGetIOR( this, obj ) ;
        } catch (BAD_PARAM bp) {
            // Throw MARSHAL instead if this is a LOCAL_OBJECT_NOT_ALLOWED error.
            if (bp.minor == ORBUtilSystemException.LOCAL_OBJECT_NOT_ALLOWED) {
                throw omgWrapper.notAnObjectImpl( bp ) ;
            } else
                // Not a local object problem: just rethrow the exception.
                // Do not wrap and log this, since it was already logged at its
                // point of origin.
                throw bp ;
        }

        return ior.stringify() ;
    }

    /**
     * Convert a stringified object reference to the object it represents.
     * @param str The stringified object reference.
     * @return The unstringified object reference.
     */
    public org.omg.CORBA.Object string_to_object(String str)
    {
        Operation op ;

        synchronized (this) {
            checkShutdownState();
            op = urlOperation ;
        }

        if (str == null)
            throw wrapper.nullParam() ;

        synchronized (urlOperationLock) {
            org.omg.CORBA.Object obj = (org.omg.CORBA.Object)op.operate( str ) ;
            return obj ;
        }
    }

    // pure java orb support, moved this method from FVDCodeBaseImpl.
    // Note that we connect this if we have not already done so.
    public synchronized IOR getFVDCodeBaseIOR()
    {
        checkShutdownState();

        if (codeBaseIOR != null) // i.e. We are already connected to it
            return codeBaseIOR;

        // backward compatability 4365188
        CodeBase cb;

        ValueHandler vh = ORBUtility.createValueHandler();

        cb = (CodeBase)vh.getRunTimeCodeBase();
        return ORBUtility.connectAndGetIOR( this, cb ) ;
    }

    /**
     * Get the TypeCode for a primitive type.
     *
     * @param tcKind    the integer kind for the primitive type
     * @return          the requested TypeCode
     */
    public synchronized TypeCode get_primitive_tc(TCKind tcKind)
    {
        checkShutdownState();
        return get_primitive_tc( tcKind.value() ) ;
    }

    /**
     * Create a TypeCode for a structure.
     *
     * @param id                the logical id for the typecode.
     * @param name      the name for the typecode.
     * @param members   an array describing the members of the TypeCode.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_struct_tc(String id,
                                     String name,
                                     StructMember[] members)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_struct, id, name, members);
    }

    /**
     * Create a TypeCode for a union.
     *
     * @param id                the logical id for the typecode.
     * @param name      the name for the typecode.
     * @param discriminator_type
     *                  the type of the union discriminator.
     * @param members   an array describing the members of the TypeCode.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_union_tc(String id,
                                    String name,
                                    TypeCode discriminator_type,
                                    UnionMember[] members)
    {
        checkShutdownState();
        return new TypeCodeImpl(this,
                                TCKind._tk_union,
                                id,
                                name,
                                discriminator_type,
                                members);
    }

    /**
     * Create a TypeCode for an enum.
     *
     * @param id                the logical id for the typecode.
     * @param name      the name for the typecode.
     * @param members   an array describing the members of the TypeCode.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_enum_tc(String id,
                                   String name,
                                   String[] members)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_enum, id, name, members);
    }

    /**
     * Create a TypeCode for an alias.
     *
     * @param id                the logical id for the typecode.
     * @param name      the name for the typecode.
     * @param original_type
     *                  the type this is an alias for.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_alias_tc(String id,
                                    String name,
                                    TypeCode original_type)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_alias, id, name, original_type);
    }

    /**
     * Create a TypeCode for an exception.
     *
     * @param id                the logical id for the typecode.
     * @param name      the name for the typecode.
     * @param members   an array describing the members of the TypeCode.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_exception_tc(String id,
                                        String name,
                                        StructMember[] members)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_except, id, name, members);
    }

    /**
     * Create a TypeCode for an interface.
     *
     * @param id                the logical id for the typecode.
     * @param name      the name for the typecode.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_interface_tc(String id,
                                        String name)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_objref, id, name);
    }

    /**
     * Create a TypeCode for a string.
     *
     * @param bound     the bound for the string.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_string_tc(int bound)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_string, bound);
    }

    /**
     * Create a TypeCode for a wide string.
     *
     * @param bound     the bound for the string.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_wstring_tc(int bound)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_wstring, bound);
    }

    /**
     * Create a TypeCode for a sequence.
     *
     * @param bound     the bound for the sequence.
     * @param element_type
     *                  the type of elements of the sequence.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_sequence_tc(int bound,
                                       TypeCode element_type)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_sequence, bound, element_type);
    }


    /**
     * Create a recursive TypeCode in a sequence.
     *
     * @param bound     the bound for the sequence.
     * @param offset    the index to the enclosing TypeCode that is
     *                  being referenced.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_recursive_sequence_tc(int bound,
                                                 int offset)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_sequence, bound, offset);
    }


    /**
     * Create a TypeCode for an array.
     *
     * @param length    the length of the array.
     * @param element_type
     *                  the type of elements of the array.
     * @return          the requested TypeCode.
     */
    public synchronized TypeCode create_array_tc(int length,
                                    TypeCode element_type)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_array, length, element_type);
    }


    public synchronized org.omg.CORBA.TypeCode create_native_tc(String id,
                                                   String name)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_native, id, name);
    }

    public synchronized org.omg.CORBA.TypeCode create_abstract_interface_tc(
                                                               String id,
                                                               String name)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_abstract_interface, id, name);
    }

    public synchronized org.omg.CORBA.TypeCode create_fixed_tc(short digits, short scale)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_fixed, digits, scale);
    }

    public synchronized org.omg.CORBA.TypeCode create_value_tc(String id,
                                                  String name,
                                                  short type_modifier,
                                                  TypeCode concrete_base,
                                                  ValueMember[] members)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_value, id, name,
                                type_modifier, concrete_base, members);
    }

    public synchronized org.omg.CORBA.TypeCode create_recursive_tc(String id) {
        checkShutdownState();
        return new TypeCodeImpl(this, id);
    }

    public synchronized org.omg.CORBA.TypeCode create_value_box_tc(String id,
                                                      String name,
                                                      TypeCode boxed_type)
    {
        checkShutdownState();
        return new TypeCodeImpl(this, TCKind._tk_value_box, id, name,
            boxed_type);
    }

    /**
     * Create a new Any
     *
     * @return          the new Any created.
     */
    public synchronized Any create_any()
    {
        checkShutdownState();
        return new AnyImpl(this);
    }

    // TypeCodeFactory interface methods.
    // Keeping track of type codes by repository id.

    // Keeping a cache of TypeCodes associated with the class
    // they got created from in Util.writeAny().

    public synchronized void setTypeCodeForClass(Class c, TypeCodeImpl tci)
    {
        checkShutdownState();

        if (typeCodeForClassMap == null)
            typeCodeForClassMap = Collections.synchronizedMap(
                new WeakHashMap(64));
        // Store only one TypeCode per class.
        if ( ! typeCodeForClassMap.containsKey(c))
            typeCodeForClassMap.put(c, tci);
    }

    public synchronized TypeCodeImpl getTypeCodeForClass(Class c)
    {
        checkShutdownState();

        if (typeCodeForClassMap == null)
            return null;
        return (TypeCodeImpl)typeCodeForClassMap.get(c);
    }

/****************************************************************************
 * The following methods deal with listing and resolving the initial
 * (bootstrap) object references such as "NameService".
 ****************************************************************************/

    /**
     * Get a list of the initially available CORBA services.
     * This does not work unless an ORBInitialHost is specified during
     * initialization (or unless there is an ORB running on the AppletHost)
     * since the localhostname
     * is inaccessible to applets. If a service properties URL was specified,
     * then it is used, otherwise the bootstrapping protocol is used.
     * @return A list of the initial services available.
     */
    public String[] list_initial_services()
    {
        Resolver res ;

        synchronized( this ) {
            checkShutdownState();
            res = resolver ;
        }

        synchronized (resolverLock) {
            java.util.Set keys = res.list() ;
            return (String[])keys.toArray( new String[keys.size()] ) ;
        }
    }

    /**
     * Resolve the stringified reference of one of the initially
     * available CORBA services.
     * @param identifier The stringified object reference of the
     * desired service.
     * @return An object reference for the desired service.
     * @exception InvalidName The supplied identifier is not associated
     * with a known service.
     * @exception SystemException One of a fixed set of Corba system exceptions.
     */
    public org.omg.CORBA.Object resolve_initial_references(
        String identifier) throws InvalidName
    {
        Resolver res ;

        synchronized( this ) {
            checkShutdownState();
            res = resolver ;
        }

        synchronized (resolverLock) {
            org.omg.CORBA.Object result = res.resolve( identifier ) ;

            if (result == null)
                throw new InvalidName() ;
            else
                return result ;
        }
    }

    /**
     * If this operation is called with an id, <code>"Y"</code>, and an
     * object, <code>YY</code>, then a subsequent call to
     * <code>ORB.resolve_initial_references( "Y" )</code> will
     * return object <code>YY</code>.
     *
     * @param id The ID by which the initial reference will be known.
     * @param obj The initial reference itself.
     * @throws InvalidName if this operation is called with an empty string id
     *     or this operation is called with an id that is already registered,
     *     including the default names defined by OMG.
     * @throws BAD_PARAM if the obj parameter is null.
     */
    public void register_initial_reference(
        String id, org.omg.CORBA.Object obj ) throws InvalidName
    {
        CorbaServerRequestDispatcher insnd ;

        synchronized (this) {
            checkShutdownState();
        }

        if ((id == null) || (id.length() == 0))
            throw new InvalidName() ;

        synchronized (this) {
            checkShutdownState();
        }

        synchronized (resolverLock) {
            insnd = insNamingDelegate ;

            java.lang.Object obj2 = localResolver.resolve( id ) ;
            if (obj2 != null)
                throw new InvalidName(id + " already registered") ;

            localResolver.register( id, ClosureFactory.makeConstant( obj )) ;
        }

        synchronized (this) {
            if (StubAdapter.isStub(obj))
                // Make all remote object references available for INS.
                requestDispatcherRegistry.registerServerRequestDispatcher(
                    insnd, id ) ;
        }
    }

/****************************************************************************
 * The following methods (introduced in POA / CORBA2.1) deal with
 * shutdown / single threading.
 ****************************************************************************/

    public void run()
    {
        synchronized (this) {
            checkShutdownState();
        }

        synchronized (runObj) {
            try {
                runObj.wait();
            } catch ( InterruptedException ex ) {}
        }
    }

    public void shutdown(boolean wait_for_completion) {
        boolean wait = false;

        synchronized (this) {
            checkShutdownState();

            // This is to avoid deadlock: don't allow a thread that is
            // processing a request to call shutdown( true ), because
            // the shutdown would block waiting for the request to complete,
            // while the request would block waiting for shutdown to complete.
            if (wait_for_completion &&
                isProcessingInvocation.get() == Boolean.TRUE) {
                throw omgWrapper.shutdownWaitForCompletionDeadlock();
            }

            if (status == STATUS_SHUTTING_DOWN) {
                if (wait_for_completion) {
                    wait = true;
                } else {
                    return;
                }
            }

            status = STATUS_SHUTTING_DOWN;
        }

        // Avoid more than one thread performing shutdown at a time.
        synchronized (shutdownObj) {
            // At this point, the ORB status is certainly STATUS_SHUTTING_DOWN.
            // If wait is true, another thread already called shutdown( true ),
            // and so we wait for completion
            if (wait) {
                while (true) {
                    synchronized (this) {
                        if (status == STATUS_SHUTDOWN)
                            break;
                    }

                    try {
                        shutdownObj.wait();
                    } catch (InterruptedException exc) {
                        // NOP: just loop and wait until state is changed
                    }
                }
            } else {
                // perform the actual shutdown
                shutdownServants(wait_for_completion);

                if (wait_for_completion) {
                    synchronized ( waitForCompletionObj ) {
                        while (numInvocations > 0) {
                            try {
                                waitForCompletionObj.wait();
                            } catch (InterruptedException ex) {}
                        }
                    }
                }

                synchronized (runObj) {
                    runObj.notifyAll();
                }

                status = STATUS_SHUTDOWN;

                shutdownObj.notifyAll();
            }
        }
    }

    // Cause all ObjectAdapaterFactories to clean up all of their internal state, which
    // may include activated objects that have associated state and callbacks that must
    // complete in order to shutdown.  This will cause new request to be rejected.
    protected void shutdownServants(boolean wait_for_completion) {
        Set<ObjectAdapterFactory> oaset;
        synchronized (this) {
            oaset = new HashSet<>(requestDispatcherRegistry.getObjectAdapterFactories());
        }

        for (ObjectAdapterFactory oaf : oaset)
            oaf.shutdown(wait_for_completion);
    }

    // Note that the caller must hold the ORBImpl lock.
    public void checkShutdownState()
    {
        if (status == STATUS_DESTROYED) {
            throw wrapper.orbDestroyed() ;
        }

        if (status == STATUS_SHUTDOWN) {
            throw omgWrapper.badOperationAfterShutdown() ;
        }
    }

    public boolean isDuringDispatch()
    {
        synchronized (this) {
                checkShutdownState();
        }
        Boolean value = (Boolean)(isProcessingInvocation.get()) ;
        return value.booleanValue() ;
    }

    public void startingDispatch()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (invocationObj) {
            isProcessingInvocation.set(Boolean.TRUE);
            numInvocations++;
        }
    }

    public void finishedDispatch()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (invocationObj) {
            numInvocations--;
            isProcessingInvocation.set(false);
            if (numInvocations == 0) {
                synchronized (waitForCompletionObj) {
                    waitForCompletionObj.notifyAll();
                }
            } else if (numInvocations < 0) {
                throw wrapper.numInvocationsAlreadyZero(
                    CompletionStatus.COMPLETED_YES);
            }
        }
    }

    /**
     *  formal/99-10-07 p 159: "If destroy is called on an ORB that has
     *  not been shut down, it will start the shutdown process and block until
     *  the ORB has shut down before it destroys the ORB."
     */
    public void destroy()
    {
        boolean shutdownFirst = false;

        synchronized (this) {
            shutdownFirst = (status == STATUS_OPERATING);
        }

        if (shutdownFirst) {
            shutdown(true);
        }

        synchronized (this) {
            if (status < STATUS_DESTROYED) {
                getCorbaTransportManager().close();
                getPIHandler().destroyInterceptors();
                status = STATUS_DESTROYED;
            }
        }
        synchronized (threadPoolManagerAccessLock) {
            if (orbOwnsThreadPoolManager) {
                try {
                    threadpoolMgr.close();
                    threadpoolMgr = null;
                } catch (IOException exc) {
                    wrapper.ioExceptionOnClose(exc);
                }
            }
        }

        try {
            monitoringManager.close();
            monitoringManager = null;
        } catch (IOException exc) {
            wrapper.ioExceptionOnClose(exc);
        }

        CachedCodeBase.cleanCache(this);
        try {
            pihandler.close();
        } catch (IOException exc) {
            wrapper.ioExceptionOnClose(exc);
        }

        super.destroy();

        badServerIdHandlerAccessLock = null;
        clientDelegateFactoryAccessorLock = null;
        corbaContactInfoListFactoryAccessLock = null;

        objectKeyFactoryAccessLock = null;
        legacyServerSocketManagerAccessLock = null;
        threadPoolManagerAccessLock = null;
        transportManager = null;
        legacyServerSocketManager = null;
        OAInvocationInfoStack  = null;
        clientInvocationInfoStack  = null;
        codeBaseIOR = null;
        dynamicRequests  = null;
        svResponseReceived  = null;
        runObj = null;
        shutdownObj = null;
        waitForCompletionObj = null;
        invocationObj = null;
        isProcessingInvocation = null;
        typeCodeForClassMap  = null;
        valueFactoryCache = null;
        orbVersionThreadLocal = null;
        requestDispatcherRegistry = null;
        copierManager = null;
        toaFactory = null;
        poaFactory = null;
        pihandler = null;
        configData = null;
        badServerIdHandler = null;
        clientDelegateFactory = null;
        corbaContactInfoListFactory = null;
        resolver = null;
        localResolver = null;
        insNamingDelegate = null;
        urlOperation = null;
        taggedComponentFactoryFinder = null;
        taggedProfileFactoryFinder = null;
        taggedProfileTemplateFactoryFinder = null;
        objectKeyFactory = null;
    }

    /**
     * Registers a value factory for a particular repository ID.
     *
     * @param repositoryID the repository ID.
     * @param factory the factory.
     * @return the previously registered factory for the given repository ID,
     * or null if no such factory was previously registered.
     * @exception org.omg.CORBA.BAD_PARAM if the registration fails.
     **/
    public synchronized ValueFactory register_value_factory(String repositoryID,
        ValueFactory factory)
    {
        checkShutdownState();

        if ((repositoryID == null) || (factory == null))
            throw omgWrapper.unableRegisterValueFactory() ;

        return (ValueFactory)valueFactoryCache.put(repositoryID, factory);
    }

    /**
     * Unregisters a value factory for a particular repository ID.
     *
     * @param repositoryID the repository ID.
     **/
    public synchronized void unregister_value_factory(String repositoryID)
    {
        checkShutdownState();

        if (valueFactoryCache.remove(repositoryID) == null)
            throw wrapper.nullParam() ;
    }

    /**
     * Finds and returns a value factory for the given repository ID.
     * The value factory returned was previously registered by a call to
     * {@link #register_value_factory} or is the default factory.
     *
     * @param repositoryID the repository ID.
     * @return the value factory.
     * @exception org.omg.CORBA.BAD_PARAM if unable to locate a factory.
     **/
    public synchronized ValueFactory lookup_value_factory(String repositoryID)
    {
        checkShutdownState();

        ValueFactory factory =
            (ValueFactory)valueFactoryCache.get(repositoryID);

        if (factory == null) {
            try {
                factory = Utility.getFactory(null, null, null, repositoryID);
            } catch(org.omg.CORBA.MARSHAL ex) {
                throw wrapper.unableFindValueFactory( ex ) ;
            }
        }

        return factory ;
    }

    public OAInvocationInfo peekInvocationInfo()
    {
        synchronized (this) {
                checkShutdownState();
        }
        StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
        return (OAInvocationInfo)(stack.peek()) ;
    }

    public void pushInvocationInfo( OAInvocationInfo info )
    {
        synchronized (this) {
                checkShutdownState();
        }
        StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
        stack.push( info ) ;
    }

    public OAInvocationInfo popInvocationInfo()
    {
        synchronized (this) {
                checkShutdownState();
        }
        StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
        return (OAInvocationInfo)(stack.pop()) ;
    }

    /**
     * The bad server id handler is used by the Locator to
     * send back the location of a persistant server to the client.
     */

    private Object badServerIdHandlerAccessLock = new Object();

    public void initBadServerIdHandler()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (badServerIdHandlerAccessLock) {
            Class cls = configData.getBadServerIdHandler() ;
            if (cls != null) {
                try {
                    Class[] params = new Class[] { org.omg.CORBA.ORB.class };
                    java.lang.Object[] args = new java.lang.Object[]{this};
                    Constructor cons = cls.getConstructor(params);
                    badServerIdHandler =
                        (BadServerIdHandler) cons.newInstance(args);
                } catch (Exception e) {
                    throw wrapper.errorInitBadserveridhandler( e ) ;
                }
            }
        }
    }

    public void setBadServerIdHandler( BadServerIdHandler handler )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (badServerIdHandlerAccessLock) {
            badServerIdHandler = handler;
        }
    }

    public void handleBadServerId( ObjectKey okey )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (badServerIdHandlerAccessLock) {
            if (badServerIdHandler == null)
                throw wrapper.badServerId() ;
            else
                badServerIdHandler.handle( okey ) ;
        }
    }

    public synchronized org.omg.CORBA.Policy create_policy( int type,
        org.omg.CORBA.Any val ) throws org.omg.CORBA.PolicyError
    {
        checkShutdownState() ;

        return pihandler.create_policy( type, val ) ;
    }

    /** This is the implementation of the public API used to connect
     *  a servant-skeleton to the ORB.
     */
    public synchronized void connect(org.omg.CORBA.Object servant)
    {
        checkShutdownState();
        if (getTOAFactory() == null)
            throw wrapper.noToa() ;

        try {
            String codebase = javax.rmi.CORBA.Util.getCodebase( servant.getClass() ) ;
            getTOAFactory().getTOA( codebase ).connect( servant ) ;
        } catch ( Exception ex ) {
            throw wrapper.orbConnectError( ex ) ;
        }
    }

    public synchronized void disconnect(org.omg.CORBA.Object obj)
    {
        checkShutdownState();
        if (getTOAFactory() == null)
            throw wrapper.noToa() ;

        try {
            getTOAFactory().getTOA().disconnect( obj ) ;
        } catch ( Exception ex ) {
            throw wrapper.orbConnectError( ex ) ;
        }
    }

    public int getTransientServerId()
    {
        synchronized (this) {
                checkShutdownState();
        }
        if( configData.getORBServerIdPropertySpecified( ) ) {
            // ORBServerId is specified then use that value
            return configData.getPersistentServerId( );
        }
        return transientServerId;
    }

    public RequestDispatcherRegistry getRequestDispatcherRegistry()
    {
        synchronized (this) {
                checkShutdownState();
        }
        return requestDispatcherRegistry;
    }

    public ServiceContextRegistry getServiceContextRegistry()
    {
        synchronized (this) {
                checkShutdownState();
        }
        return serviceContextRegistry ;
    }

    // XXX All of the isLocalXXX checking needs to be revisited.
    // First of all, all three of these methods are called from
    // only one place in impl.ior.IORImpl.  Second, we have problems
    // both with multi-homed hosts and with multi-profile IORs.
    // A possible strategy: like the LocalClientRequestDispatcher, we need
    // to determine this more abstractly at the ContactInfo level.
    // This level should probably just get the CorbaContactInfoList from
    // the IOR, then iterator over ContactInfo.  If any ContactInfo is
    // local, the IOR is local, and we can pick one to create the
    // LocalClientRequestDispatcher as well.  Bottom line: this code needs to move.

    // XXX What about multi-homed host?
    public boolean isLocalHost( String hostName )
    {
        synchronized (this) {
                checkShutdownState();
        }
        return hostName.equals( configData.getORBServerHost() ) ||
            hostName.equals( getLocalHostName() ) ;
    }

    public boolean isLocalServerId( int subcontractId, int serverId )
    {
        synchronized (this) {
                checkShutdownState();
        }
        if ((subcontractId < ORBConstants.FIRST_POA_SCID) ||
            (subcontractId > ORBConstants.MAX_POA_SCID))
            return serverId == getTransientServerId( ) ;

        // XXX isTransient info should be stored in subcontract registry
        if (ORBConstants.isTransient( subcontractId ))
            return (serverId == getTransientServerId()) ;
        else if (configData.getPersistentServerIdInitialized())
            return (serverId == configData.getPersistentServerId()) ;
        else
            return false ;
    }

    /*************************************************************************
     *  The following public methods are for ORB shutdown.
     *************************************************************************/

    private String getHostName(String host)
        throws java.net.UnknownHostException
    {
        return InetAddress.getByName( host ).getHostAddress();
    }

    /* keeping a copy of the getLocalHostName so that it can only be called
     * internally and the unauthorized clients cannot have access to the
     * localHost information, originally, the above code was calling
     * getLocalHostName from Connection.java.  If the hostname is cached in
     * Connection.java, then
     * it is a security hole, since any unauthorized client has access to
     * the host information.  With this change it is used internally so the
     * security problem is resolved.  Also in Connection.java, the
     * getLocalHost() implementation has changed to always call the
     * InetAddress.getLocalHost().getHostAddress()
     * The above mentioned method has been removed from the connection class
     */

    private static String localHostString = null;

    private synchronized String getLocalHostName()
    {
        if (localHostString == null) {
            try {
                localHostString = InetAddress.getLocalHost().getHostAddress();
            } catch (Exception ex) {
                throw wrapper.getLocalHostFailed( ex ) ;
            }
        }
        return localHostString ;
    }

 /******************************************************************************
 *  The following public methods are for ORB shutdown.
 *
 ******************************************************************************/

    /** This method always returns false because the ORB never needs the
     *  main thread to do work.
     */
    public synchronized boolean work_pending()
    {
        checkShutdownState();
        throw wrapper.genericNoImpl() ;
    }

    /** This method does nothing. It is not required by the spec to do anything!
     */
    public synchronized void perform_work()
    {
        checkShutdownState();
        throw wrapper.genericNoImpl() ;
    }

    public synchronized void set_delegate(java.lang.Object servant){
        checkShutdownState();

        POAFactory poaFactory = getPOAFactory() ;
        if (poaFactory != null)
            ((org.omg.PortableServer.Servant)servant)
                ._set_delegate( poaFactory.getDelegateImpl() ) ;
        else
            throw wrapper.noPoa() ;
    }

    ////////////////////////////////////////////////////
    //
    // pept.broker.Broker
    //

    public ClientInvocationInfo createOrIncrementInvocationInfo()
    {
        synchronized (this) {
                checkShutdownState();
        }
        StackImpl invocationInfoStack =
            (StackImpl) clientInvocationInfoStack.get();
        ClientInvocationInfo clientInvocationInfo = null;
        if (!invocationInfoStack.empty()) {
            clientInvocationInfo =
                (ClientInvocationInfo) invocationInfoStack.peek();
        }
        if ((clientInvocationInfo == null) ||
            (!clientInvocationInfo.isRetryInvocation()))
        {
            // This is a new call - not a retry.
            clientInvocationInfo = new CorbaInvocationInfo(this);
            startingDispatch();
            invocationInfoStack.push(clientInvocationInfo);
        }
        // Reset retry so recursive calls will get a new info object.
        clientInvocationInfo.setIsRetryInvocation(false);
        clientInvocationInfo.incrementEntryCount();
        return clientInvocationInfo;
    }

    public void releaseOrDecrementInvocationInfo()
    {
        synchronized (this) {
                checkShutdownState();
        }
        int entryCount = -1;
        ClientInvocationInfo clientInvocationInfo = null;
        StackImpl invocationInfoStack =
            (StackImpl)clientInvocationInfoStack.get();
        if (!invocationInfoStack.empty()) {
            clientInvocationInfo =
                (ClientInvocationInfo)invocationInfoStack.peek();
        } else {
            throw wrapper.invocationInfoStackEmpty() ;
        }
        clientInvocationInfo.decrementEntryCount();
        entryCount = clientInvocationInfo.getEntryCount();
        if (clientInvocationInfo.getEntryCount() == 0) {
            // 6763340: don't pop if this is a retry!
            if (!clientInvocationInfo.isRetryInvocation()) {
                invocationInfoStack.pop();
            }
            finishedDispatch();
        }
    }

    public ClientInvocationInfo getInvocationInfo()
    {
        synchronized (this) {
                checkShutdownState();
        }
        StackImpl invocationInfoStack =
            (StackImpl) clientInvocationInfoStack.get();
        return (ClientInvocationInfo) invocationInfoStack.peek();
    }

    ////////////////////////////////////////////////////
    //
    //
    //

    private Object clientDelegateFactoryAccessorLock = new Object();

    public void setClientDelegateFactory( ClientDelegateFactory factory )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (clientDelegateFactoryAccessorLock) {
            clientDelegateFactory = factory ;
        }
    }

    public ClientDelegateFactory getClientDelegateFactory()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (clientDelegateFactoryAccessorLock) {
            return clientDelegateFactory ;
        }
    }

    private Object corbaContactInfoListFactoryAccessLock = new Object();

    public void setCorbaContactInfoListFactory( CorbaContactInfoListFactory factory )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (corbaContactInfoListFactoryAccessLock) {
            corbaContactInfoListFactory = factory ;
        }
    }

    public synchronized CorbaContactInfoListFactory getCorbaContactInfoListFactory()
    {
        checkShutdownState();
        return corbaContactInfoListFactory ;
    }

    /** Set the resolver used in this ORB.  This resolver will be used for list_initial_services
     * and resolve_initial_references.
     */
    public void setResolver( Resolver resolver )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (resolverLock) {
            this.resolver = resolver ;
        }
    }

    /** Get the resolver used in this ORB.  This resolver will be used for list_initial_services
     * and resolve_initial_references.
     */
    public Resolver getResolver()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (resolverLock) {
            return resolver ;
        }
    }

    /** Set the LocalResolver used in this ORB.  This LocalResolver is used for
     * register_initial_reference only.
     */
    public void setLocalResolver( LocalResolver resolver )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (resolverLock) {
            this.localResolver = resolver ;
        }
    }

    /** Get the LocalResolver used in this ORB.  This LocalResolver is used for
     * register_initial_reference only.
     */
    public LocalResolver getLocalResolver()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (resolverLock) {
            return localResolver ;
        }
    }

    /** Set the operation used in string_to_object calls.  The Operation must expect a
     * String and return an org.omg.CORBA.Object.
     */
    public void setURLOperation( Operation stringToObject )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (urlOperationLock) {
            urlOperation = stringToObject ;
        }
    }

    /** Get the operation used in string_to_object calls.  The Operation must expect a
     * String and return an org.omg.CORBA.Object.
     */
    public Operation getURLOperation()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (urlOperationLock) {
            return urlOperation ;
        }
    }

    public void setINSDelegate( CorbaServerRequestDispatcher sdel )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (resolverLock) {
            insNamingDelegate = sdel ;
        }
    }

    public TaggedComponentFactoryFinder getTaggedComponentFactoryFinder()
    {
        synchronized (this) {
                checkShutdownState();
        }
        return taggedComponentFactoryFinder ;
    }

    public IdentifiableFactoryFinder getTaggedProfileFactoryFinder()
    {
        synchronized (this) {
                checkShutdownState();
        }
        return taggedProfileFactoryFinder ;
    }

    public IdentifiableFactoryFinder getTaggedProfileTemplateFactoryFinder()
    {
        synchronized (this) {
                checkShutdownState();
        }
        return taggedProfileTemplateFactoryFinder ;
    }

    private Object objectKeyFactoryAccessLock = new Object();

    public ObjectKeyFactory getObjectKeyFactory()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (objectKeyFactoryAccessLock) {
            return objectKeyFactory ;
        }
    }

    public void setObjectKeyFactory( ObjectKeyFactory factory )
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (objectKeyFactoryAccessLock) {
            objectKeyFactory = factory ;
        }
    }

    private Object transportManagerAccessorLock = new Object();

    public TransportManager getTransportManager()
    {
        synchronized (transportManagerAccessorLock) {
            if (transportManager == null) {
                transportManager = new CorbaTransportManagerImpl(this);
            }
            return transportManager;
        }
    }

    public CorbaTransportManager getCorbaTransportManager()
    {
        return (CorbaTransportManager) getTransportManager();
    }

    private Object legacyServerSocketManagerAccessLock = new Object();

    public LegacyServerSocketManager getLegacyServerSocketManager()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (legacyServerSocketManagerAccessLock) {
            if (legacyServerSocketManager == null) {
                legacyServerSocketManager = new LegacyServerSocketManagerImpl(this);
            }
            return legacyServerSocketManager;
        }
    }

    private Object threadPoolManagerAccessLock = new Object();

    public void setThreadPoolManager(ThreadPoolManager mgr)
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (threadPoolManagerAccessLock) {
            threadpoolMgr = mgr;
        }
    }

    public ThreadPoolManager getThreadPoolManager()
    {
        synchronized (this) {
                checkShutdownState();
        }
        synchronized (threadPoolManagerAccessLock) {
            if (threadpoolMgr == null) {
                threadpoolMgr = new ThreadPoolManagerImpl();
                orbOwnsThreadPoolManager = true;
            }
            return threadpoolMgr;
        }
    }

    public CopierManager getCopierManager()
    {
        synchronized (this) {
                checkShutdownState();
        }
        return copierManager ;
    }
} // Class ORBImpl

////////////////////////////////////////////////////////////////////////
/// Helper class for a Synchronization Variable
////////////////////////////////////////////////////////////////////////

class SynchVariable
{
    // Synchronization Variable
    public boolean _flag;

    // Constructor
    SynchVariable()
    {
        _flag = false;
    }

    // set Flag to true
    public void set()
    {
        _flag = true;
    }

        // get value
    public boolean value()
    {
        return _flag;
    }

    // reset Flag to true
    public void reset()
    {
        _flag = false;
    }
}

// End of file.
