@NotNull
  public List<Pair<TaskInfo, ProgressIndicator>> getBackgroundProcesses() {
    synchronized (myOriginals) {
      if (myOriginals.isEmpty()) return Collections.emptyList();

      List<Pair<TaskInfo, ProgressIndicator>> result =
          new ArrayList<Pair<TaskInfo, ProgressIndicator>>(myOriginals.size());
      for (int i = 0; i < myOriginals.size(); i++) {
        result.add(Pair.<TaskInfo, ProgressIndicator>create(myInfos.get(i), myOriginals.get(i)));
      }

      return Collections.unmodifiableList(result);
    }
  }
    @NotNull
    private static Pair<EditorTextField, EditorEx> createEditor(
        Project project, @Nullable FileType fileType, boolean inheritFontFromLaF) {
      EditorTextField field =
          new EditorTextField(new MyDocument(), project, fileType, false, false);
      field.setSupplementary(true);
      field.setFontInheritedFromLAF(inheritFontFromLaF);
      field.addNotify(); // creates editor

      EditorEx editor = (EditorEx) ObjectUtils.assertNotNull(field.getEditor());
      editor.setRendererMode(true);

      editor.setColorsScheme(editor.createBoundColorSchemeDelegate(null));
      editor.getSettings().setCaretRowShown(false);

      editor.getScrollPane().setBorder(null);

      return Pair.create(field, editor);
    }
 public void registerFix(
     @Nullable IntentionAction action,
     @Nullable List<IntentionAction> options,
     @Nullable String displayName,
     @Nullable TextRange fixRange,
     @Nullable HighlightDisplayKey key) {
   if (action == null) return;
   if (fixRange == null) fixRange = new TextRange(startOffset, endOffset);
   if (quickFixActionRanges == null) {
     quickFixActionRanges = ContainerUtil.createLockFreeCopyOnWriteList();
   }
   IntentionActionDescriptor desc =
       new IntentionActionDescriptor(action, options, displayName, null, key, getProblemGroup());
   quickFixActionRanges.add(Pair.create(desc, fixRange));
   fixStartOffset = Math.min(fixStartOffset, fixRange.getStartOffset());
   fixEndOffset = Math.max(fixEndOffset, fixRange.getEndOffset());
   if (action instanceof HintAction) {
     setHint(true);
   }
 }
  public static Pair<JPanel, JBList> createActionGroupPanel(
      ActionGroup action, final JComponent parent, final Runnable backAction) {
    JPanel actionsListPanel = new JPanel(new BorderLayout());
    actionsListPanel.setBackground(getProjectsBackground());
    final JBList list = new JBList(action.getChildren(null));
    list.setBackground(getProjectsBackground());
    list.installCellRenderer(
        new NotNullFunction<AnAction, JComponent>() {
          final JLabel label = new JLabel();

          {
            label.setBorder(JBUI.Borders.empty(3, 7));
          }

          @NotNull
          @Override
          public JComponent fun(AnAction action) {
            label.setText(action.getTemplatePresentation().getText());
            Icon icon = action.getTemplatePresentation().getIcon();
            label.setIcon(icon);
            return label;
          }
        });
    JScrollPane pane = ScrollPaneFactory.createScrollPane(list, true);
    pane.setBackground(getProjectsBackground());
    actionsListPanel.add(pane, BorderLayout.CENTER);
    if (backAction != null) {
      final JLabel back = new JLabel(AllIcons.Actions.Back);
      back.setBorder(JBUI.Borders.empty(3, 7, 10, 7));
      back.setHorizontalAlignment(SwingConstants.LEFT);
      new ClickListener() {
        @Override
        public boolean onClick(@NotNull MouseEvent event, int clickCount) {
          backAction.run();
          return true;
        }
      }.installOn(back);
      actionsListPanel.add(back, BorderLayout.SOUTH);
    }
    final Ref<Component> selected = Ref.create();
    final JPanel main = new JPanel(new BorderLayout());
    main.add(actionsListPanel, BorderLayout.WEST);

    ListSelectionListener selectionListener =
        new ListSelectionListener() {
          @Override
          public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting()) {
              // Update when a change has been finalized.
              // For instance, selecting an element with mouse fires two consecutive
              // ListSelectionEvent events.
              return;
            }
            if (!selected.isNull()) {
              main.remove(selected.get());
            }
            Object value = list.getSelectedValue();
            if (value instanceof AbstractActionWithPanel) {
              JPanel panel = ((AbstractActionWithPanel) value).createPanel();
              panel.setBorder(JBUI.Borders.empty(7, 10));
              selected.set(panel);
              main.add(selected.get());

              for (JButton button : UIUtil.findComponentsOfType(main, JButton.class)) {
                if (button.getClientProperty(DialogWrapper.DEFAULT_ACTION) == Boolean.TRUE) {
                  parent.getRootPane().setDefaultButton(button);
                  break;
                }
              }

              main.revalidate();
              main.repaint();
            }
          }
        };
    list.addListSelectionListener(selectionListener);
    if (backAction != null) {
      new AnAction() {
        @Override
        public void actionPerformed(@NotNull AnActionEvent e) {
          backAction.run();
        }
      }.registerCustomShortcutSet(KeyEvent.VK_ESCAPE, 0, main);
    }
    return Pair.create(main, list);
  }
  private static void addPatchedInfos(
      @NotNull HighlightInfo info,
      @NotNull PsiFile injectedPsi,
      @NotNull DocumentWindow documentWindow,
      @NotNull InjectedLanguageManager injectedLanguageManager,
      @Nullable TextRange fixedTextRange,
      @NotNull Collection<HighlightInfo> out) {
    ProperTextRange textRange = new ProperTextRange(info.startOffset, info.endOffset);
    List<TextRange> editables =
        injectedLanguageManager.intersectWithAllEditableFragments(injectedPsi, textRange);
    for (TextRange editable : editables) {
      TextRange hostRange =
          fixedTextRange == null ? documentWindow.injectedToHost(editable) : fixedTextRange;

      boolean isAfterEndOfLine = info.isAfterEndOfLine;
      if (isAfterEndOfLine) {
        // convert injected afterEndOfLine to either host' afterEndOfLine or not-afterEndOfLine
        // highlight of the injected fragment boundary
        int hostEndOffset = hostRange.getEndOffset();
        int lineNumber = documentWindow.getDelegate().getLineNumber(hostEndOffset);
        int hostLineEndOffset = documentWindow.getDelegate().getLineEndOffset(lineNumber);
        if (hostEndOffset < hostLineEndOffset) {
          // convert to non-afterEndOfLine
          isAfterEndOfLine = false;
          hostRange = new ProperTextRange(hostRange.getStartOffset(), hostEndOffset + 1);
        }
      }

      HighlightInfo patched =
          new HighlightInfo(
              info.forcedTextAttributes,
              info.forcedTextAttributesKey,
              info.type,
              hostRange.getStartOffset(),
              hostRange.getEndOffset(),
              info.description,
              info.toolTip,
              info.type.getSeverity(null),
              isAfterEndOfLine,
              null,
              false);
      patched.setHint(info.hasHint());
      patched.setGutterIconRenderer(info.getGutterIconRenderer());

      if (info.quickFixActionRanges != null) {
        for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair :
            info.quickFixActionRanges) {
          TextRange quickfixTextRange = pair.getSecond();
          List<TextRange> editableQF =
              injectedLanguageManager.intersectWithAllEditableFragments(
                  injectedPsi, quickfixTextRange);
          for (TextRange editableRange : editableQF) {
            HighlightInfo.IntentionActionDescriptor descriptor = pair.getFirst();
            if (patched.quickFixActionRanges == null)
              patched.quickFixActionRanges =
                  new ArrayList<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>>();
            TextRange hostEditableRange = documentWindow.injectedToHost(editableRange);
            patched.quickFixActionRanges.add(Pair.create(descriptor, hostEditableRange));
          }
        }
      }
      patched.fromInjection = true;
      out.add(patched);
    }
  }
  public static String composeText(
      final Map<String, ExpectedHighlightingSet> types,
      Collection<HighlightInfo> infos,
      String text) {
    // filter highlighting data and map each highlighting to a tag name
    List<Pair<String, HighlightInfo>> list =
        ContainerUtil.mapNotNull(
            infos,
            (NullableFunction<HighlightInfo, Pair<String, HighlightInfo>>)
                info -> {
                  for (Map.Entry<String, ExpectedHighlightingSet> entry : types.entrySet()) {
                    final ExpectedHighlightingSet set = entry.getValue();
                    if (set.enabled
                        && set.severity == info.getSeverity()
                        && set.endOfLine == info.isAfterEndOfLine()) {
                      return Pair.create(entry.getKey(), info);
                    }
                  }
                  return null;
                });

    boolean showAttributesKeys = false;
    for (ExpectedHighlightingSet eachSet : types.values()) {
      for (HighlightInfo eachInfo : eachSet.infos) {
        if (eachInfo.forcedTextAttributesKey != null) {
          showAttributesKeys = true;
          break;
        }
      }
    }

    // sort filtered highlighting data by end offset in descending order
    Collections.sort(
        list,
        (o1, o2) -> {
          HighlightInfo i1 = o1.second;
          HighlightInfo i2 = o2.second;

          int byEnds = i2.endOffset - i1.endOffset;
          if (byEnds != 0) return byEnds;

          if (!i1.isAfterEndOfLine() && !i2.isAfterEndOfLine()) {
            int byStarts = i1.startOffset - i2.startOffset;
            if (byStarts != 0) return byStarts;
          } else {
            int byEOL = Comparing.compare(i2.isAfterEndOfLine(), i1.isAfterEndOfLine());
            if (byEOL != 0) return byEOL;
          }

          int bySeverity = i2.getSeverity().compareTo(i1.getSeverity());
          if (bySeverity != 0) return bySeverity;

          return Comparing.compare(i1.getDescription(), i2.getDescription());
        });

    // combine highlighting data with original text
    StringBuilder sb = new StringBuilder();
    Couple<Integer> result = composeText(sb, list, 0, text, text.length(), 0, showAttributesKeys);
    sb.insert(0, text.substring(0, result.second));
    return sb.toString();
  }
 @Override
 @NotNull
 public Pair<FileEditor[], FileEditorProvider[]> openFileWithProviders(
     @NotNull VirtualFile file, boolean focusEditor, boolean searchForSplitter) {
   return Pair.create(new FileEditor[0], new FileEditorProvider[0]);
 }