@@ -0,0 +1,2908 @@
+package org.jetbrains.debugger.connection;%0A%0Aimport com.intellij.ide.browsers.WebBrowser;%0Aimport com.intellij.openapi.application.ApplicationManager;%0Aimport com.intellij.openapi.util.ActionCallback;%0Aimport com.intellij.openapi.util.AsyncResult;%0Aimport com.intellij.util.Consumer;%0Aimport com.intellij.util.io.socketConnection.ConnectionStatus;%0Aimport org.jetbrains.annotations.NotNull;%0Aimport org.jetbrains.annotations.Nullable;%0Aimport org.jetbrains.debugger.Vm;%0A%0Aimport java.net.InetSocketAddress;%0Aimport java.util.concurrent.Future;%0Aimport java.util.concurrent.atomic.AtomicReference;%0A%0Apublic abstract class ProcessBackedVmConnection extends VmConnection%3CVm%3E %7B%0A  private final AtomicReference%3CRunnable%3E connectCancelHandler = new AtomicReference%3CRunnable%3E();%0A%0A  @Nullable%0A  @Override%0A  public WebBrowser getBrowser() %7B%0A    return null;%0A  %7D%0A%0A  public abstract void createVmAndConnect(@NotNull InetSocketAddress address, @NotNull AsyncResult%3CVm%3E result);%0A%0A  public void open(@NotNull final InetSocketAddress address) %7B%0A    setState(ConnectionStatus.WAITING_FOR_CONNECTION, %22Connecting to %22 + address.getHostName() + %22:%22 + address.getPort());%0A    final Future%3C?%3E future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() %7B%0A      @Override%0A      public void run() %7B%0A        if (Thread.interrupted()) %7B%0A          return;%0A        %7D%0A%0A        final AsyncResult%3CVm%3E result = new AsyncResult%3CVm%3E();%0A        connectCancelHandler.set(new Runnable() %7B%0A          @Override%0A          public void run() %7B%0A            result.reject(%22Closed explicitly%22);%0A          %7D%0A        %7D);%0A%0A        createVmAndConnect(address, result);%0A        result.doWhenDone(new Consumer%3CVm%3E() %7B%0A          @Override%0A          public void consume(Vm vm) %7B%0A            ProcessBackedVmConnection.this.vm = vm;%0A            setState(ConnectionStatus.CONNECTED, %22Connected to %22 + address.getHostName() + %22:%22 + address.getPort());%0A            startProcessing();%0A          %7D%0A        %7D).doWhenRejected(new Consumer%3CString%3E() %7B%0A          @Override%0A          public void consume(String error) %7B%0A            if (getState().getStatus() == ConnectionStatus.WAITING_FOR_CONNECTION) %7B%0A              setState(ConnectionStatus.CONNECTION_FAILED, error == null ? %22Internal error%22 : error);%0A            %7D%0A          %7D%0A        %7D).doWhenProcessed(new Runnable() %7B%0A          @Override%0A          public void run() %7B%0A            connectCancelHandler.set(null);%0A          %7D%0A        %7D);%0A      %7D%0A    %7D);%0A    connectCancelHandler.set(new Runnable() %7B%0A      @Override%0A      public void run() %7B%0A        future.cancel(true);%0A      %7D%0A    %7D);%0A  %7D%0A%0A  @Override%0A  public ActionCallback detachAndClose() %7B%0A    ActionCallback callback;%0A    try %7B%0A      Runnable runnable = connectCancelHandler.getAndSet(null);%0A      if (runnable != null) %7B%0A        runnable.run();%0A      %7D%0A    %7D%0A    finally %7B%0A      callback = super.detachAndClose();%0A    %7D%0A    return callback;%0A  %7D%0A%7D

move generic ProcessBackedVmConnection impl to shared module