void (boolean closedByUser, boolean keepManagerThread, Consumer<@Nullable VirtualMachineData> callback) { DebuggerManagerThreadImpl.assertIsManagerThread(); if (myState.compareAndSet(State.INITIAL, State.DETACHING) || myState.compareAndSet(State.ATTACHED, State.DETACHING)) { try { if (!keepManagerThread) { getManagerThread().close(); } } finally { if (!(myConnection instanceof RemoteConnectionStub)) { VirtualMachineData vmData = new VirtualMachineData(myVirtualMachineProxy, myConnection, myDebuggerManagerThread); myVirtualMachineProxy = null; myPositionManager = CompoundPositionManager.EMPTY; myReturnValueWatcher = null; myNodeRenderersMap.clear(); myRenderers.clear(); DebuggerUtils.cleanupAfterProcessFinish(this); myState.compareAndSet(State.DETACHING, State.DETACHED); try { myDebugProcessDispatcher.getMulticaster().processDetached(this, closedByUser); } finally { callback.accept(vmData); } } } } }