// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.impl.source.codeStyle;

import com.intellij.formatting.FormattingRangesExtender;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.ChangedRangesInfo;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;

import java.util.List;

class ChangedRangesUtil {

  private ChangedRangesUtil() {
  }

  static List<TextRange> processChangedRanges(@NotNull PsiFile file,
                                              @NotNull ChangedRangesInfo changedRangesInfo) {
    Document document = file.getViewProvider().getDocument();
    List<TextRange> changedRanges = optimizedChangedRanges(changedRangesInfo.allChangedRanges);
    if (document != null) {
      FormattingRangesExtender extender = new FormattingRangesExtenderImpl(document, file);
      changedRanges = extender.getExtendedRanges(changedRanges);
    }
    return changedRanges;
  }

  private static List<TextRange> optimizedChangedRanges(@NotNull List<TextRange> allChangedRanges) {
    if (allChangedRanges.isEmpty()) return allChangedRanges;
    List<TextRange> sorted = ContainerUtil.sorted(allChangedRanges, Segment.BY_START_OFFSET_THEN_END_OFFSET);

    List<TextRange> result = ContainerUtil.newSmartList();

    TextRange prev = sorted.get(0);
    for (TextRange next : sorted) {
      if (next.getStartOffset() <= prev.getEndOffset() + 5) {
        int newEndOffset = Math.max(prev.getEndOffset(), next.getEndOffset());
        prev = new TextRange(prev.getStartOffset(), newEndOffset);
      }
      else {
        result.add(prev);
        prev = next;
      }
    }
    result.add(prev);

    return result;
  }
}

@@ -551,16 +551,74 @@
 tNull;%0A%0A
+import java.util.ArrayList;%0Aimport java.util.Collections;%0A
 import j
@@ -946,81 +946,33 @@
 ge%3E 
-changedRanges = optimizedChangedRanges(changedRangesInfo.allChangedRanges
+result = new ArrayList%3C%3E(
 );%0A 
@@ -1100,52 +1100,266 @@
     
-changedRanges = extender.getExtendedRanges(c
+for (TextRange range : changedRangesInfo.allChangedRanges) %7B%0A        List%3CTextRange%3E extended = extender.getExtendedRanges(Collections.singletonList(range));%0A        result.addAll(extended);%0A      %7D%0A    %7D%0A    else %7B%0A      result.addAll(changedRangesInfo.allC
 hang
@@ -1386,17 +1386,26 @@
  return 
-c
+optimizedC
 hangedRa
@@ -1404,24 +1404,32 @@
 hangedRanges
+(result)
 ;%0A  %7D%0A%0A  pri
@@ -1886,12 +1886,8 @@
 et()
- + 5
 ) %7B%0A

Extend each changed range independently