@@ -0,0 +1,3414 @@
+package org.jetbrains.debugger.connection;%0A%0Aimport com.intellij.openapi.Disposable;%0Aimport com.intellij.openapi.util.ActionCallback;%0Aimport com.intellij.openapi.util.Disposer;%0Aimport com.intellij.util.EventDispatcher;%0Aimport com.intellij.util.io.socketConnection.ConnectionState;%0Aimport com.intellij.util.io.socketConnection.ConnectionStatus;%0Aimport com.intellij.util.io.socketConnection.SocketConnectionListener;%0Aimport org.jetbrains.annotations.NotNull;%0Aimport org.jetbrains.annotations.Nullable;%0Aimport org.jetbrains.debugger.DebugEventAdapter;%0Aimport org.jetbrains.debugger.DebugEventListener;%0Aimport org.jetbrains.debugger.Vm;%0A%0Aimport javax.swing.event.HyperlinkListener;%0Aimport java.util.concurrent.atomic.AtomicBoolean;%0Aimport java.util.concurrent.atomic.AtomicReference;%0A%0Apublic abstract class VmConnection%3CT extends Vm%3E implements Disposable, BrowserConnection %7B%0A  private final AtomicReference%3CConnectionState%3E state = new AtomicReference%3CConnectionState%3E(new ConnectionState(ConnectionStatus.NOT_CONNECTED));%0A  private final EventDispatcher%3CDebugEventListener%3E dispatcher = EventDispatcher.create(DebugEventListener.class);%0A  private final EventDispatcher%3CSocketConnectionListener%3E connectionDispatcher = EventDispatcher.create(SocketConnectionListener.class);%0A%0A  protected volatile T vm;%0A%0A  private final ActionCallback started = new ActionCallback();%0A%0A  private final AtomicBoolean closed = new AtomicBoolean();%0A%0A  public final Vm getVm() %7B%0A    return vm;%0A  %7D%0A%0A  @NotNull%0A  @Override%0A  public ConnectionState getState() %7B%0A    return state.get();%0A  %7D%0A%0A  public void addDebugListener(@NotNull DebugEventAdapter listener, @NotNull Disposable parentDisposable) %7B%0A    dispatcher.addListener(listener, parentDisposable);%0A  %7D%0A%0A  @Override%0A  public void executeOnStart(@NotNull Runnable runnable) %7B%0A    started.doWhenDone(runnable);%0A  %7D%0A%0A  protected void setState(@NotNull ConnectionStatus status, @Nullable String message) %7B%0A    setState(status, message, null);%0A  %7D%0A%0A  protected void setState(@NotNull ConnectionStatus status, @Nullable String message, @Nullable HyperlinkListener messageLinkListener) %7B%0A    ConnectionState oldState = state.getAndSet(new ConnectionState(status, message, messageLinkListener));%0A    if (oldState == null %7C%7C oldState.getStatus() != status) %7B%0A      connectionDispatcher.getMulticaster().statusChanged(status);%0A    %7D%0A  %7D%0A%0A  @Override%0A  public void addListener(@NotNull SocketConnectionListener listener, @NotNull Disposable parentDisposable) %7B%0A    connectionDispatcher.addListener(listener, parentDisposable);%0A  %7D%0A%0A  public DebugEventListener getDebugEventListener() %7B%0A    return dispatcher.getMulticaster();%0A  %7D%0A%0A  protected void startProcessing() %7B%0A    started.setDone();%0A  %7D%0A%0A  public final void close(@Nullable String message) %7B%0A    if (!closed.compareAndSet(false, true)) %7B%0A      return;%0A    %7D%0A%0A    vm = null;%0A    if (!started.isProcessed()) %7B%0A      started.setRejected();%0A    %7D%0A    setState(ConnectionStatus.DISCONNECTED, message);%0A    Disposer.dispose(this, false);%0A  %7D%0A%0A  @Override%0A  public void dispose() %7B%0A  %7D%0A%0A  public ActionCallback detachAndClose() %7B%0A    if (!started.isProcessed()) %7B%0A      started.setRejected();%0A    %7D%0A%0A    Vm currentVm = vm;%0A    ActionCallback callback;%0A    if (currentVm == null) %7B%0A      callback = new ActionCallback.Done();%0A    %7D%0A    else %7B%0A      vm = null;%0A      callback = currentVm.detach();%0A    %7D%0A    close(null);%0A    return callback;%0A  %7D%0A%7D

move generic connection impl to shared module