@TestOnly
  void validateState() {
    Document document = myEditor.getDocument();
    if (document.isInBulkUpdate()) return;

    FoldRegion[] allFoldRegions = getAllFoldRegions();
    boolean[] invisibleRegions = new boolean[allFoldRegions.length];
    for (int i = 0; i < allFoldRegions.length; i++) {
      FoldRegion r1 = allFoldRegions[i];
      int r1s = r1.getStartOffset();
      int r1e = r1.getEndOffset();
      boolean r1c = r1 instanceof CustomFoldRegion;
      LOG.assertTrue(r1.isValid() &&
                     !DocumentUtil.isInsideCharacterPair(document, r1s) &&
                     !DocumentUtil.isInsideCharacterPair(document, r1e),
                     "Invalid region");
      if (r1c) {
        LOG.assertTrue(!r1.isExpanded(), "Expanded custom region");
        LOG.assertTrue(r1s == DocumentUtil.getLineStartOffset(r1s, document) && r1e == DocumentUtil.getLineEndOffset(r1e, document),
                       "Wrong custom region position");
      }
      for (int j = i + 1; j < allFoldRegions.length; j++) {
        FoldRegion r2 = allFoldRegions[j];
        int r2s = r2.getStartOffset();
        int r2e = r2.getEndOffset();
        boolean r2c = r2 instanceof CustomFoldRegion;
        LOG.assertTrue(r1c == r2c &&
                       (r1s < r2s && (r1e <= r2s || r1e >= r2e) ||
                       r1s == r2s && r1e != r2e ||
                       r1s > r2s && r1s < r2e && r1e <= r2e ||
                       r1s >= r2e)
                       || r1c && !r2c && (r1s > r2e || r1e < r2s || r1s > r2s && r1e < r2e || r1s <= r2s && r1e >= r2e)
                       || !r1c && r2c && (r1s > r2e || r1e < r2s || r2s > r1s && r2e < r1e || r2s <= r1s && r2e >= r1e),
                       "Disallowed relative position of regions");
        if (!r1.isExpanded() && r1s <= r2s && r1e >= r2e && (r1s != r2s || r1e != r2e || r1c)) invisibleRegions[j] = true;
        if (!r2.isExpanded() && r2s <= r1s && r2e >= r1e && (r1s != r2s || r1e != r2e || r2c)) invisibleRegions[i] = true;
      }
    }
    Set<FoldRegion> visibleRegions = CollectionFactory.createCustomHashingStrategySet(OFFSET_BASED_HASHING_STRATEGY);
    List<FoldRegion> topLevelRegions = new ArrayList<>();
    for (int i = 0; i < allFoldRegions.length; i++) {
      if (!invisibleRegions[i]) {
        FoldRegion region = allFoldRegions[i];
        LOG.assertTrue(visibleRegions.add(region), "Duplicate visible regions");
        if (!region.isExpanded()) {
          topLevelRegions.add(region);
        }
      }
    }
    topLevelRegions.sort(Comparator.comparingInt(r -> r.getStartOffset()));

    FoldRegion[] actualVisibles = fetchVisible();
    if (actualVisibles != null) {
      for (FoldRegion r : actualVisibles) {
        LOG.assertTrue(visibleRegions.remove(r), "Unexpected visible region");
      }
      LOG.assertTrue(visibleRegions.isEmpty(), "Missing visible region");
    }

    FoldRegion[] actualTopLevels = fetchTopLevel();
    if (actualTopLevels != null) {
      LOG.assertTrue(actualTopLevels.length == topLevelRegions.size(), "Wrong number of top-level regions");
      for (int i = 0; i < actualTopLevels.length; i++) {
        LOG.assertTrue(OFFSET_BASED_HASHING_STRATEGY.equals(actualTopLevels[i], topLevelRegions.get(i)),
                       "Unexpected top-level region");
      }
    }
  }
@TestOnly
  void validateState()