void (@NotNull EdtReplacementThread thread, @NotNull ModalityState modalityState, @NotNull Runnable r) { switch (thread) { case EDT: if (!SwingUtilities.isEventDispatchThread() && ApplicationManager.getApplication().isWriteIntentLockAcquired()) { Logger.getInstance(ApplicationUtil.class).error("Can't invokeAndWait from WT to EDT: probably leads to deadlock"); } EdtInvocationManager.invokeAndWaitIfNeeded(r); break; case WT: if (ApplicationManager.getApplication().isWriteIntentLockAcquired()) { r.run(); } else if (SwingUtilities.isEventDispatchThread()) { Logger.getInstance(ApplicationUtil.class).error("Can't invokeAndWait from EDT to WT"); } else { Semaphore s = new Semaphore(1); AtomicReference<Throwable> throwable = new AtomicReference<>(); ApplicationManager.getApplication().invokeLaterOnWriteThread(() -> { try { r.run(); } catch (Throwable t) { throwable.set(t); } finally { s.up(); } }, modalityState); s.waitFor(); if (throwable.get() != null) { ExceptionUtil.rethrow(throwable.get()); } } break; case EDT_WITH_IW: if (!SwingUtilities.isEventDispatchThread() && ApplicationManager.getApplication().isWriteIntentLockAcquired()) { Logger.getInstance(ApplicationUtil.class).error("Can't invokeAndWait from WT to EDT: probably leads to deadlock"); } ApplicationManager.getApplication().invokeAndWait(r, modalityState); break; } }