class HostProxyProvider {

    public HostProxy getHostProxy( ServiceServerNode node )
        throws HmsException
    {
        if ( node != null )
        {
            HostIdentifier hostIdentifier = new HostIdentifier( node.getNodeID(), node.getIbIpAddress(),
                                                                node.getOsUserName(), node.getOsPassword() );

            synchronized ( this )
            {
                // If HostProxy is NOT available, then create Object for that node, so that later in this method, it can
                // be used as Lock.
                if ( !hostProxyMap.containsKey( hostIdentifier ) )
                {
                    if ( !locksMap.containsKey( node.getNodeID() ) )
                    {
                        locksMap.put( node.getNodeID(), new Object() );
                    }
                }
            }

            // Host proxy is NOT there or NOT valid.
            // Try to create HostProxy in Synchronous way, but will be synchronized only for same node.
            // If call comes for another Host, it creating HostProxy for that should NOT get blocked.
            Object lockObj = locksMap.get( node.getNodeID() );

            synchronized ( lockObj )
            {
                if ( hostProxyMap.containsKey( hostIdentifier ) )
                {
                    HostProxy cachedHostProxy = hostProxyMap.get( hostIdentifier );

                    if ( isHostProxyValid( cachedHostProxy ) )
                    {
                        return cachedHostProxy;
                    }
                }
                else
                {
                    removeStaleProxy( hostIdentifier );
                }

                HostProxy hostProxy = createHostProxy( node );
                hostProxyMap.put( hostIdentifier, hostProxy );
                return hostProxy;
            }
        }
        else
        {
            String err = "Cannot get HostProxy for Null Node: " + node;
            logger.error( err );
            throw new HmsException( err );
        }
    }

    private  HostProxyProvider();

}