public synchronized boolean switchConnection(Connection newCon) throws InterruptedException {
    Connection oldCon = null;
    synchronized (this) {
      if (shouldDestroy()) return false;

      if (this.active && !shouldDestroy()) {
        this.waitingToSwitch = true;
        try {
          while (this.active && !shouldDestroy()) {
            wait();
          }
        } finally {
          this.waitingToSwitch = false;
          notifyAll();
        }
      }
      if (shouldDestroy()) return false;
      assert !this.active;
      final long now = System.nanoTime();
      oldCon = this.connection;
      this.connection = newCon;
      this.endpoint = newCon.getEndpoint();
      this.birthDate = now;
    }
    if (oldCon != null) {
      try {
        // do this outside of sync
        oldCon.close(false);
      } catch (Exception e) {
        // ignore
      }
    }
    return true;
  }
 public void internalClose(boolean keepAlive) throws Exception {
   try {
     Connection con = this.connection;
     if (con != null) {
       con.close(keepAlive);
     }
   } finally {
     internalDestroy();
   }
 }