Collection<CustomRegionTreeElement> (@NotNull PsiElement rootElement, @NotNull Set<? extends TextRange> ranges) { TextRange rootRange = getTextRange(rootElement); Iterator<PsiElement> iterator = SyntaxTraverser.psiTraverser(rootElement) .filter(element -> isCustomRegionCommentCandidate(element) && rootRange.contains(element.getTextRange()) && !isInsideRanges(element, ranges)) .iterator(); List<CustomRegionTreeElement> customRegions = new SmartList<>(); CustomRegionTreeElement currRegionElement = null; CustomFoldingProvider provider = null; while (iterator.hasNext()) { ProgressManager.checkCanceled(); PsiElement child = iterator.next(); if (provider == null) provider = getProvider(child); if (provider != null) { String commentText = child.getText(); if (provider.isCustomRegionStart(commentText)) { if (currRegionElement == null) { currRegionElement = new CustomRegionTreeElement(child, provider); customRegions.add(currRegionElement); } else { currRegionElement = currRegionElement.createNestedRegion(child); } } else if (provider.isCustomRegionEnd(commentText) && currRegionElement != null) { currRegionElement = currRegionElement.endRegion(child); } } } return customRegions; }