@Override
  public int compare(InspectionTreeNode node1, InspectionTreeNode node2) {
    if (node1 == node2) return 0;
    if (node1 instanceof InspectionSeverityGroupNode groupNode1 && node2 instanceof InspectionSeverityGroupNode groupNode2) {
      return -groupNode1.getSeverityRegistrar().compare(groupNode1.getSeverityLevel().getSeverity(), groupNode2.getSeverityLevel().getSeverity());
    }
    if (node1 instanceof InspectionSeverityGroupNode) return -1;
    if (node2 instanceof InspectionSeverityGroupNode) return 1;

    if (node1 instanceof InspectionGroupNode && node2 instanceof InspectionGroupNode) {
      return ((InspectionGroupNode)node1).getSubGroup().compareTo(((InspectionGroupNode)node2).getSubGroup());
    }
    if (node1 instanceof InspectionGroupNode) return -1;
    if (node2 instanceof InspectionGroupNode) return 1;

    if (node1 instanceof InspectionNode && node2 instanceof InspectionNode)
      return InspectionsConfigTreeComparator.getDisplayTextToSort(node1.toString())
        .compareToIgnoreCase(InspectionsConfigTreeComparator.getDisplayTextToSort(node2.toString()));
    if (node1 instanceof InspectionNode) return -1;
    if (node2 instanceof InspectionNode) return 1;

    if (node1 instanceof InspectionModuleNode && node2 instanceof InspectionModuleNode) {
      return Comparing.compare(node1.toString(), node2.toString());
    }
    if (node1 instanceof InspectionModuleNode) return -1;
    if (node2 instanceof InspectionModuleNode) return 1;

    if (node1 instanceof InspectionPackageNode && node2 instanceof InspectionPackageNode) {
      return ((InspectionPackageNode)node1).getPackageName().compareToIgnoreCase(((InspectionPackageNode)node2).getPackageName());
    }
    if (node1 instanceof InspectionPackageNode) return -1;
    if (node2 instanceof InspectionPackageNode) return 1;

    if (node1 instanceof RefElementNode && node2 instanceof RefElementNode){   //sort by filename and inside file by start offset
      return compareEntities(((RefElementNode)node1).getElement(), ((RefElementNode)node2).getElement());
    }
    if (node1 instanceof ProblemDescriptionNode && node2 instanceof ProblemDescriptionNode) {
      final CommonProblemDescriptor descriptor1 = ((ProblemDescriptionNode)node1).getDescriptor();
      final CommonProblemDescriptor descriptor2 = ((ProblemDescriptionNode)node2).getDescriptor();
      if (descriptor1 instanceof ProblemDescriptor && descriptor2 instanceof ProblemDescriptor) {
        int diff = ((ProblemDescriptor)descriptor1).getLineNumber() - ((ProblemDescriptor)descriptor2).getLineNumber();
        if (diff != 0) {
          return diff;
        }
        diff = ((ProblemDescriptor)descriptor1).getHighlightType().compareTo(((ProblemDescriptor)descriptor2).getHighlightType());
        if (diff != 0) {
          return diff;
        }
        diff = PsiUtilCore.compareElementsByPosition(((ProblemDescriptor)descriptor1).getStartElement(),
                                                     ((ProblemDescriptor)descriptor2).getStartElement());
        if (diff != 0) {
          return diff;
        }
        diff = PsiUtilCore.compareElementsByPosition(((ProblemDescriptor)descriptor2).getEndElement(),
                                                     ((ProblemDescriptor)descriptor1).getEndElement());
        if (diff != 0) return diff;

        final TextRange range1 = ((ProblemDescriptor)descriptor1).getTextRangeInElement();
        final TextRange range2 = ((ProblemDescriptor)descriptor2).getTextRangeInElement();
        if (range1 != null && range2 != null) {
          diff = range1.getStartOffset() - range2.getStartOffset();
          if (diff != 0) return diff;
          diff = range1.getEndOffset() - range2.getEndOffset();
          if (diff != 0) return diff;
        }
      }
      if (descriptor1 != null && descriptor2 != null) {
        return descriptor1.getDescriptionTemplate().compareToIgnoreCase(descriptor2.getDescriptionTemplate());
      }
      if (descriptor1 == null) return descriptor2 == null ? 0 : -1;
      return 1;
    }

    if (node1 instanceof RefElementNode && node2 instanceof ProblemDescriptionNode) {
      return 1;
    }
    if (node2 instanceof RefElementNode && node1 instanceof ProblemDescriptionNode) {
      return -1;
    }
    if (node1 instanceof InspectionRootNode && node2 instanceof InspectionRootNode) {
      //TODO Dmitry Batkovich: optimization, because only one root node is existed
      return 0;
    }

    LOG.error("node1: " + node1 + ", node2: " + node2);
    return 0;
  }
@Override
  public int compare(InspectionTreeNode node1, InspectionTreeNode node2)