/** @see java.lang.Thread#run() */
    public void run() {
      // Wait for registration. Put it into a thread so this
      // can occur while other stuff goes on. It locks the fConnectionPool
      // until done so that the first request for a connection by anyone
      // else will wait until this thread is finished.

      synchronized (fConnectionPool) {
        synchronized (REMProxyFactoryRegistry.this) {
          // Notify the main thread that we have the
          // connection pool locked.
          REMProxyFactoryRegistry.this.notifyAll();
        }
        synchronized (this) {
          // sync on self so that it can be notified when finally receive the registration
          long stopTime = System.currentTimeMillis() + 60000;
          while (waitRegistrationThread != null
              && (fNoTimeouts || System.currentTimeMillis() < stopTime)) {
            try {
              Thread.currentThread().wait(60000);
            } catch (InterruptedException e) {
            }
          }
        }
      }

      waitRegistrationThread = null; // No longer exists.			
    }
 /**
  * Get a free connection
  *
  * @return
  * @throws IllegalStateException - Thrown if a connection cannot be created.
  * @since 1.0.0
  */
 public IREMConnection getFreeConnection() throws IllegalStateException {
   Thread thread = Thread.currentThread();
   if (thread instanceof REMCallbackThread) {
     // The current thread is a call back thread, so just reuse the connection.
     // But this thread could actually be trying to access another registry.
     // So if this thread is for this registry, use it, if not for this registry, create a new
     // connection.
     // But if for this registry AND is already in a transaction, we need a fresh connection.
     REMCallbackThread callbackThread = (REMCallbackThread) thread;
     if (callbackThread.registry == this && !callbackThread.inTransaction()) {
       // This way any calls out to the remote vm will be on same thread as callback caller
       // on remote vm because that thread is waiting on this connection for commands.
       IREMConnection c = (callbackThread).getConnection();
       if (c.isConnected()) return c;
       else
         throw new IllegalStateException(
             ProxyRemoteMessages.REMProxyFactoryRegistry_CallbackConnectionNotWorking_EXC_);
     }
   }
   synchronized (fConnectionPool) {
     if (!fConnectionPool.isEmpty()) return (IREMConnection) fConnectionPool.pop();
     // else we need to allocate one.
     return createConnection();
   }
 }
 /** Free the connection */
 public void returnConnection(IREMConnection connection) {
   if (connection.isConnected()) {
     Thread thread = Thread.currentThread();
     if (!(thread instanceof REMCallbackThread)
         || ((REMCallbackThread) thread).getConnection() != connection) {
       // We are not a callback thread, or we are but the connection is not for the thread, then
       // the connection
       // can be returned.
       synchronized (fConnectionPool) {
         if (fConnectionPool.size() < NUMBER_FREE_CONNECTIONS) fConnectionPool.push(connection);
         else connection.close(); // We don't need to maintain more than five free connections.
       }
     }
   }
 }
 /* (non-Javadoc)
  * @see java.lang.Thread#run()
  */
 public IStatus run(IProgressMonitor mon) {
   try {
     // There is no join on a process available, so we will have to
     // busy wait. Give it 10 seconds in 1/10 second intervals.
     for (int i = 0; !process.isTerminated() && i < 100; i++) {
       try {
         Thread.sleep(100);
       } catch (InterruptedException e) {
       }
     }
     if (!process.isTerminated()) {
       process.terminate();
     }
   } catch (DebugException e) {
   }
   return Status.OK_STATUS;
 }
  /**
   * Make a new connection.
   *
   * @return
   * @throws IllegalStateException - Thrown if connection cannot be created.
   * @since 1.0.0
   */
  protected IREMConnection createConnection() throws IllegalStateException {
    // If we have a server port, then the server is probably open. If we don't then there is no
    // server.
    if (fServerPort != 0) {
      // We are putting it off into a thread because there are no timeout capabilities on getting a
      // socket.
      // So we need to allow for that.
      final Socket[] scArray = new Socket[1];
      final boolean[] waiting = new boolean[] {true};
      Thread doIt =
          new Thread(
              new Runnable() {
                public void run() {
                  try {
                    Socket sc = new Socket("localhost", fServerPort); // $NON-NLS-1$
                    synchronized (this) {
                      if (waiting[0]) scArray[0] = sc;
                      else
                        sc
                            .close(); // We are no longer waiting on this thread so close the socket
                                      // since no one will use it.
                    }
                  } catch (IOException e) {
                    ProxyPlugin.getPlugin()
                        .getLogger()
                        .log(
                            new Status(
                                IStatus.WARNING,
                                ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
                                0,
                                "",
                                e)); //$NON-NLS-1$
                  }
                }
              });

      doIt.start();
      while (true) {
        try {
          doIt.join(!fNoTimeouts ? 60000 : 0);
          synchronized (doIt) {
            waiting[0] = false; // To let it know we are no longer waiting
          }
          break;
        } catch (InterruptedException e) {
        }
      }

      if (scArray[0] == null) {
        // Log where we are at so we can know where it was we down.
        ProxyPlugin.getPlugin()
            .getLogger()
            .log(
                new Status(
                    IStatus.WARNING,
                    ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
                    0,
                    "",
                    new IllegalStateException(
                        ProxyRemoteMessages
                            .REMProxyFactoryRegistry_ConnectionCreationFailed_INFO_))); //$NON-NLS-1$
        throw new IllegalStateException(
            ProxyRemoteMessages
                .REMProxyFactoryRegistry_CouldNotCreateSocketConnectionToRemoteVM_EXC_); // Couldn't
                                                                                         // get one,
                                                                                         // probably
                                                                                         // server
                                                                                         // is down.
                                                                                         // //$NON-NLS-1$
      }

      REMConnection connection = new REMConnection(scArray[0], fNoTimeouts);
      if (connection.isConnected()) return connection;

      // Failed, close the socket.
      try {
        scArray[0].close();
      } catch (IOException e) {
      }
    } else
      ProxyPlugin.getPlugin()
          .getLogger()
          .log(
              new Status(
                  IStatus.WARNING,
                  ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
                  0,
                  "No Server to retrieve a connection.",
                  null)); ///$NON-NLS-1$

    throw new IllegalStateException(
        ProxyRemoteMessages.REMProxyFactoryRegistry_CouldNotCreateSocketConnectionToRemoteVM_EXC_);
  }