public static void showOutput(final @NotNull Project myProject,
                                final @NotNull ProcessOutput output,
                                final @NotNull @NlsContexts.TabTitle String tabDisplayName,
                                final @Nullable VirtualFile file,
                                final boolean activateWindow) {
    final String stdout = output.getStdout();
    final String stderr = output.getStderr();
    if (ApplicationManager.getApplication().isUnitTestMode() && !(stdout.isEmpty() || stderr.isEmpty())) {
      throw new RuntimeException("STDOUT:\n" + stdout + "\nSTDERR:\n" + stderr);
    }

    ApplicationManager.getApplication().invokeLater(() -> {
      if (myProject.isDisposed()) return;

      final String stdOutTitle = "[Stdout]:";
      final String stderrTitle = "[Stderr]:";
      final ErrorViewPanel errorTreeView = new ErrorViewPanel(myProject);
      try {
        openMessagesView(errorTreeView, myProject, tabDisplayName);
      }
      catch (NullPointerException e) {
        Messages.showErrorDialog(stdOutTitle + "\n" + stdout + "\n" + stderrTitle + "\n" + stderr,
                                 ExecutionBundle.message("process.output"));
        return;
      }

      if (!StringUtil.isEmpty(stdout)) {
        final String[] stdoutLines = StringUtil.splitByLines(stdout);
        if (stdoutLines.length > 0) {
          if (StringUtil.isEmpty(stderr)) {
            // Only stdout available
            errorTreeView.addMessage(MessageCategory.SIMPLE, stdoutLines, file, -1, -1, null);
          }
          else {
            // both stdout and stderr available, show as groups
            if (file == null) {
              errorTreeView.addMessage(MessageCategory.SIMPLE, stdoutLines, stdOutTitle, NonNavigatable.INSTANCE, null, null, null);
            }
            else {
              errorTreeView.addMessage(MessageCategory.SIMPLE, new String[]{stdOutTitle}, file, -1, -1, null);
              errorTreeView.addMessage(MessageCategory.SIMPLE, new String[]{""}, file, -1, -1, null);
              errorTreeView.addMessage(MessageCategory.SIMPLE, stdoutLines, file, -1, -1, null);
            }
          }
        }
      }
      if (!StringUtil.isEmpty(stderr)) {
        final String[] stderrLines = StringUtil.splitByLines(stderr);
        if (stderrLines.length > 0) {
          if (file == null) {
            errorTreeView.addMessage(MessageCategory.SIMPLE, stderrLines, stderrTitle, NonNavigatable.INSTANCE, null, null, null);
          }
          else {
            errorTreeView.addMessage(MessageCategory.SIMPLE, new String[]{stderrTitle}, file, -1, -1, null);
            errorTreeView.addMessage(MessageCategory.SIMPLE, ArrayUtilRt.EMPTY_STRING_ARRAY, file, -1, -1, null);
            errorTreeView.addMessage(MessageCategory.SIMPLE, stderrLines, file, -1, -1, null);
          }
        }
      }
      errorTreeView
        .addMessage(MessageCategory.SIMPLE, new String[]{"Process finished with exit code " + output.getExitCode()}, null, -1, -1, null);

      if (activateWindow) {
        final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW);
        if (toolWindow != null) {
          toolWindow.activate(null);
        }
      }
    });
  }
public static void showOutput(final @NotNull Project myProject,
                                final @NotNull ProcessOutput output,
                                final @NotNull @NlsContexts.TabTitle String tabDisplayName,
                                final @Nullable VirtualFile file,
                                final boolean activateWindow)