@Override
  public void doCollectInformation(@NotNull ProgressIndicator progress) {
    if (ApplicationManager.getApplication().isUnitTestMode()) {
      return;
    }

    if (!WebEditorOptions.getInstance().isTagTreeHighlightingEnabled()) {
      return;
    }

    final PsiElement[] elements =
        BreadcrumbsXmlWrapper.getLinePsiElements(
            myEditor.getCaretModel().getOffset(),
            myFile.getVirtualFile(),
            myProject,
            myInfoProvider);

    if (elements == null || elements.length == 0) {
      return;
    }

    if (!XmlTagTreeHighlightingUtil.containsTagsWithSameName(elements)) {
      return;
    }

    for (int i = elements.length - 1; i >= 0; i--) {
      if (elements[i] instanceof XmlTag) {
        myPairsToHighlight.add(getTagRanges((XmlTag) elements[i]));
      }
    }
  }
  public List<HighlightInfo> getHighlights() {
    clearLineMarkers(myEditor);

    final int count = myPairsToHighlight.size();
    final List<HighlightInfo> highlightInfos = new ArrayList<HighlightInfo>(count * 2);
    final MarkupModel markupModel = myEditor.getMarkupModel();

    final Color[] baseColors = XmlTagTreeHighlightingUtil.getBaseColors();
    final Color[] colorsForEditor =
        count > 1
            ? toColorsForEditor(baseColors)
            : new Color[] {
              myEditor
                  .getColorsScheme()
                  .getAttributes(CodeInsightColors.MATCHED_BRACE_ATTRIBUTES)
                  .getBackgroundColor()
            };
    final Color[] colorsForLineMarkers = toColorsForLineMarkers(baseColors);

    final List<RangeHighlighter> newHighlighters = new ArrayList<RangeHighlighter>();

    assert colorsForEditor.length > 0;

    for (int i = 0; i < count && i < baseColors.length; i++) {
      Pair<TextRange, TextRange> pair = myPairsToHighlight.get(i);

      if (pair.first == null && pair.second == null) {
        continue;
      }

      Color color = colorsForEditor[i];

      if (color == null) {
        continue;
      }

      if (pair.first != null && !pair.first.isEmpty()) {
        highlightInfos.add(createHighlightInfo(color, pair.first));
      }

      if (pair.second != null && !pair.second.isEmpty()) {
        highlightInfos.add(createHighlightInfo(color, pair.second));
      }

      final int start =
          pair.first != null ? pair.first.getStartOffset() : pair.second.getStartOffset();
      final int end = pair.second != null ? pair.second.getEndOffset() : pair.first.getEndOffset();

      final Color lineMarkerColor = colorsForLineMarkers[i];
      if (count > 1 && lineMarkerColor != null && start != end) {
        final RangeHighlighter highlighter =
            createHighlighter(markupModel, new TextRange(start, end), lineMarkerColor);
        newHighlighters.add(highlighter);
      }
    }

    myEditor.putUserData(TAG_TREE_HIGHLIGHTERS_IN_EDITOR_KEY, newHighlighters);

    return highlightInfos;
  }
  @Override
  public void doCollectInformation(@NotNull ProgressIndicator progress) {
    if (ApplicationManager.getApplication().isUnitTestMode()) {
      return;
    }

    if (!WebEditorOptions.getInstance().isTagTreeHighlightingEnabled()) {
      return;
    }

    final int offset = myEditor.getCaretModel().getOffset();
    PsiElement[] elements =
        BreadcrumbsXmlWrapper.getLinePsiElements(
            offset, myFile.getVirtualFile(), myProject, myInfoProvider);

    if (elements == null
        || elements.length == 0
        || !XmlTagTreeHighlightingUtil.containsTagsWithSameName(elements)) {
      elements = PsiElement.EMPTY_ARRAY;
      final FileViewProvider provider = myFile.getViewProvider();
      for (Language language : provider.getLanguages()) {
        PsiElement element = provider.findElementAt(offset, language);
        if (!isTagStartOrEnd(element)) {
          element = null;
        }
        if (element == null && offset > 0) {
          element = provider.findElementAt(offset - 1, language);
          if (!isTagStartOrEnd(element)) element = null;
        }

        final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
        if (tag != null) {
          elements = new PsiElement[] {tag};
        }
      }
    }

    for (int i = elements.length - 1; i >= 0; i--) {
      if (elements[i] instanceof XmlTag) {
        myPairsToHighlight.add(getTagRanges((XmlTag) elements[i]));
      }
    }
  }
  private Color[] toColorsForEditor(Color[] baseColors) {
    final Color tagBackground = myEditor.getBackgroundColor();

    if (tagBackground == null) {
      return baseColors;
    }

    final Color[] resultColors = new Color[baseColors.length];
    // todo: make configurable
    final double transparency =
        WebEditorOptions.getInstance().getTagTreeHighlightingOpacity() * 0.01;

    for (int i = 0; i < resultColors.length; i++) {
      final Color color = baseColors[i];

      final Color color1 =
          color != null
              ? XmlTagTreeHighlightingUtil.makeTransparent(color, tagBackground, transparency)
              : null;
      resultColors[i] = color1;
    }

    return resultColors;
  }