public void collapseFoldRegion(FoldRegion region) {
    assertIsDispatchThreadForEditor();
    if (!region.isExpanded()) return;

    if (!myIsBatchFoldingProcessing) {
      LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only.");
    }

    List<Caret> carets = myEditor.getCaretModel().getAllCarets();
    for (Caret caret : carets) {
      LogicalPosition caretPosition = caret.getLogicalPosition();
      int caretOffset = myEditor.logicalPositionToOffset(caretPosition);

      if (FoldRegionsTree.contains(region, caretOffset)) {
        if (myDoNotCollapseCaret) return;
      }
    }
    for (Caret caret : carets) {
      LogicalPosition caretPosition = caret.getLogicalPosition();
      int caretOffset = myEditor.logicalPositionToOffset(caretPosition);

      if (FoldRegionsTree.contains(region, caretOffset)) {
        if (caret.getUserData(SAVED_CARET_POSITION) == null) {
          caret.putUserData(SAVED_CARET_POSITION, caretPosition.withoutVisualPositionInfo());
        }
      }
    }

    myFoldRegionsProcessed = true;
    ((FoldRegionImpl) region).setExpandedInternal(false);
    notifyListenersOnFoldRegionStateChange(region);
  }
  public void collapseFoldRegion(FoldRegion region) {
    assertIsDispatchThread();
    if (!region.isExpanded()) return;

    if (!myIsBatchFoldingProcessing) {
      LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only.");
    }

    LogicalPosition caretPosition = myEditor.getCaretModel().getLogicalPosition();

    int caretOffset = myEditor.logicalPositionToOffset(caretPosition);

    if (FoldRegionsTree.contains(region, caretOffset)) {
      if (myDoNotCollapseCaret) return;

      if (!myCaretPositionSaved) {
        mySavedCaretX = caretPosition.column;
        mySavedCaretY = caretPosition.line;
        myCaretPositionSaved = true;
      }
    }

    int selectionStart = myEditor.getSelectionModel().getSelectionStart();
    int selectionEnd = myEditor.getSelectionModel().getSelectionEnd();

    if (FoldRegionsTree.contains(region, selectionStart - 1)
        || FoldRegionsTree.contains(region, selectionEnd))
      myEditor.getSelectionModel().removeSelection();

    myFoldRegionsProcessed = true;
    ((FoldRegionImpl) region).setExpandedInternal(false);
    notifyListenersOnFoldRegionStateChange(region);
  }