public Set<InferenceVariable> getDependencies(InferenceSession session) {
    final Set<InferenceVariable> dependencies = new LinkedHashSet<InferenceVariable>();
    for (List<PsiType> boundTypes : myBounds.values()) {
      if (boundTypes != null) {
        for (PsiType bound : boundTypes) {
          session.collectDependencies(bound, dependencies);
        }
      }
    }

    if (!session.hasCapture(this) && dependencies.isEmpty()) {
      return dependencies;
    }

    if (!session.hasCapture(this)) {
      return dependencies;
    }

    for (Iterator<InferenceVariable> iterator = dependencies.iterator(); iterator.hasNext(); ) {
      if (!session.hasCapture(iterator.next())) {
        iterator.remove();
      }
    }
    session.collectCaptureDependencies(this, dependencies);
    return dependencies;
  }
Example #2
0
 @NotNull
 public static PsiElement[] findSuperElements(@NotNull PsiElement element) {
   if (element instanceof PsiClass) {
     PsiClass aClass = (PsiClass) element;
     List<PsiClass> allSupers = new ArrayList<>(Arrays.asList(aClass.getSupers()));
     for (Iterator<PsiClass> iterator = allSupers.iterator(); iterator.hasNext(); ) {
       PsiClass superClass = iterator.next();
       if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName()))
         iterator.remove();
     }
     return allSupers.toArray(new PsiClass[allSupers.size()]);
   }
   if (element instanceof PsiMethod) {
     PsiMethod method = (PsiMethod) element;
     if (method.isConstructor()) {
       PsiMethod constructorInSuper = PsiSuperMethodUtil.findConstructorInSuper(method);
       if (constructorInSuper != null) {
         return new PsiMethod[] {constructorInSuper};
       }
     } else {
       PsiMethod[] superMethods = method.findSuperMethods(false);
       if (superMethods.length == 0) {
         PsiMethod superMethod = getSiblingInheritedViaSubClass(method);
         if (superMethod != null) {
           superMethods = new PsiMethod[] {superMethod};
         }
       }
       return superMethods;
     }
   }
   return PsiElement.EMPTY_ARRAY;
 }
    private void updateFragments(int start, int end, @NotNull String replace) {
      int docStart = psiToDocumentOffset(start);
      int docEnd = psiToDocumentOffset(end);

      TextRange startRange = findFragment(docStart);
      TextRange endRange = findFragment(docEnd);

      myPsiText = myPsiText.delete(start, end).insert(start, replace);

      TextRange newFragment =
          new TextRange(
              startRange != null ? startRange.getStartOffset() : docStart,
              endRange != null ? endRange.getEndOffset() : docEnd);
      CharSequence newReplacement =
          myPsiText.subSequence(
              documentToPsiOffset(newFragment.getStartOffset(), false),
              documentToPsiOffset(newFragment.getEndOffset(), true)
                  + replace.length()
                  - (end - start));

      for (Iterator<TextRange> iterator = myAffectedFragments.keySet().iterator();
          iterator.hasNext(); ) {
        if (iterator.next().intersects(newFragment)) {
          iterator.remove();
        }
      }
      myAffectedFragments.put(newFragment, newReplacement);
    }
Example #4
0
 private static void retainOnlyJarsAndDirectories(List<VirtualFile> woSdk) {
   for (Iterator<VirtualFile> iterator = woSdk.iterator(); iterator.hasNext(); ) {
     VirtualFile file = iterator.next();
     final VirtualFile local = ArchiveVfsUtil.getVirtualFileForJar(file);
     final boolean dir = file.isDirectory();
     final String name = file.getName();
     if (LOG.isDebugEnabled()) {
       LOG.debug(
           "Considering: "
               + file.getPath()
               + "; local="
               + local
               + "; dir="
               + dir
               + "; name="
               + name);
     }
     if (dir || local != null) {
       continue;
     }
     if (name.endsWith(".jar")) {
       continue;
     }
     LOG.debug("Removing");
     iterator.remove();
   }
 }
Example #5
0
 @Nullable
 public static CreateClassOrPackageFix createFix(
     @NotNull final String qualifiedName,
     @NotNull final GlobalSearchScope scope,
     @NotNull final PsiElement context,
     @Nullable final PsiPackage basePackage,
     @Nullable ClassKind kind,
     @Nullable String superClass,
     @Nullable String templateName) {
   final List<PsiDirectory> directories =
       getWritableDirectoryListDefault(basePackage, scope, context.getManager());
   if (directories.isEmpty()) {
     return null;
   }
   final String redPart =
       basePackage == null
           ? qualifiedName
           : qualifiedName.substring(basePackage.getQualifiedName().length() + 1);
   final int dot = redPart.indexOf('.');
   final boolean fixPath = dot >= 0;
   final String firstRedName = fixPath ? redPart.substring(0, dot) : redPart;
   for (Iterator<PsiDirectory> i = directories.iterator(); i.hasNext(); ) {
     if (!checkCreateClassOrPackage(kind != null && !fixPath, i.next(), firstRedName)) {
       i.remove();
     }
   }
   return new CreateClassOrPackageFix(
       directories,
       context,
       fixPath ? qualifiedName : redPart,
       redPart,
       kind,
       superClass,
       templateName);
 }
 @Nullable
 private InstructionImpl findInstruction(PsiElement element) {
   final Iterator<InstructionImpl> iterator = myProcessingStack.descendingIterator();
   while (iterator.hasNext()) {
     final InstructionImpl instruction = iterator.next();
     if (element.equals(instruction.getElement())) return instruction;
   }
   return null;
 }
Example #7
0
 private void processInterface(PsiClass inheritor, PsiClass anInterface) {
   for (Iterator<PsiMethod> methodIterator = myRemainingMethods.iterator();
       methodIterator.hasNext(); ) {
     PsiMethod method = methodIterator.next();
     SiblingInfo info = findSibling(inheritor, anInterface, method);
     if (info != null) {
       myResult.put(method, info);
       methodIterator.remove();
     }
   }
 }
 public static ClassFilter[] readFilters(List children) throws InvalidDataException {
   if (children == null || children.size() == 0) {
     return ClassFilter.EMPTY_ARRAY;
   }
   List<ClassFilter> classFiltersList = new ArrayList<ClassFilter>(children.size());
   for (Iterator i = children.iterator(); i.hasNext(); ) {
     final ClassFilter classFilter = new ClassFilter();
     classFilter.readExternal((Element) i.next());
     classFiltersList.add(classFilter);
   }
   return classFiltersList.toArray(new ClassFilter[classFiltersList.size()]);
 }
 @Nullable
 public static List<UnresolvableCollisionUsageInfo> removeConflictUsages(Set<UsageInfo> usages) {
   final List<UnresolvableCollisionUsageInfo> result =
       new ArrayList<UnresolvableCollisionUsageInfo>();
   for (Iterator<UsageInfo> iterator = usages.iterator(); iterator.hasNext(); ) {
     UsageInfo usageInfo = iterator.next();
     if (usageInfo instanceof UnresolvableCollisionUsageInfo) {
       result.add((UnresolvableCollisionUsageInfo) usageInfo);
       iterator.remove();
     }
   }
   return result.isEmpty() ? null : result;
 }
Example #10
0
 @Override
 public void preprocessCovariantOverriders(final List<UsageInfo> covariantOverriderInfos) {
   for (Iterator<UsageInfo> usageInfoIterator = covariantOverriderInfos.iterator();
       usageInfoIterator.hasNext(); ) {
     final UsageInfo info = usageInfoIterator.next();
     if (info instanceof OverriderUsageInfo) {
       final OverriderUsageInfo overrideUsage = (OverriderUsageInfo) info;
       if (myAffectedMethods.contains(overrideUsage.getOverridingMethod())) {
         usageInfoIterator.remove();
       }
     }
   }
 }
 private void addToResult(Map<PsiExpression, PsiType> map) {
   if (myResult == null) {
     myResult = new THashMap<>(map, ExpressionTypeMemoryState.EXPRESSION_HASHING_STRATEGY);
   } else {
     final Iterator<PsiExpression> iterator = myResult.keySet().iterator();
     while (iterator.hasNext()) {
       PsiExpression psiExpression = iterator.next();
       if (!myResult.get(psiExpression).equals(map.get(psiExpression))) {
         iterator.remove();
       }
     }
   }
 }
Example #12
0
  protected void defineScopeEquivalence(Class scopeClass, Class equivClass) {
    final Iterator<CompletionVariant> iter = myCompletionVariants.iterator();
    if (isScopeFinal(scopeClass)) {
      declareFinalScope(equivClass);
    }

    while (iter.hasNext()) {
      final CompletionVariant variant = iter.next();
      if (variant.isScopeClassAcceptable(scopeClass)) {
        variant.includeScopeClass(equivClass, variant.isScopeClassFinal(scopeClass));
      }
    }
  }
 @Nullable
 private ExceptionInfo findCatch(PsiType thrownType) {
   final Iterator<ExceptionInfo> iterator = myCaughtExceptionInfos.descendingIterator();
   while (iterator.hasNext()) {
     final ExceptionInfo info = iterator.next();
     final GrCatchClause clause = info.myClause;
     final GrParameter parameter = clause.getParameter();
     if (parameter != null) {
       final PsiType type = parameter.getType();
       if (type.isAssignableFrom(thrownType)) return info;
     }
   }
   return null;
 }
Example #14
0
 @Nullable
 public static PsiMethod findPropertyGetterWithType(
     String propertyName, boolean isStatic, PsiType type, Iterator<PsiMethod> methods) {
   while (methods.hasNext()) {
     PsiMethod method = methods.next();
     if (method.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue;
     if (isSimplePropertyGetter(method)) {
       if (getPropertyNameByGetter(method).equals(propertyName)) {
         if (type.equals(method.getReturnType())) return method;
       }
     }
   }
   return null;
 }
  protected void refreshElements(PsiElement[] elements) {
    LOG.assertTrue(elements.length > 0);
    if (myPrimaryElement != null) {
      myPrimaryElement = elements[0];
    }

    final Iterator<String> newNames = myAllRenames.values().iterator();
    LinkedHashMap<PsiElement, String> newAllRenames = new LinkedHashMap<PsiElement, String>();
    for (PsiElement resolved : elements) {
      newAllRenames.put(resolved, newNames.next());
    }
    myAllRenames.clear();
    myAllRenames.putAll(newAllRenames);
  }
Example #16
0
  private static boolean elementListsEqual(List<Element> l1, List<Element> l2) {
    if (l1 == null) return l2 == null;
    if (l2 == null) return false;

    if (l1.size() != l2.size()) return false;

    Iterator<Element> i1 = l1.iterator();

    for (Element aL2 : l2) {
      Element elem1 = i1.next();

      if (!elementsEqual(elem1, aL2)) return false;
    }
    return true;
  }
 private static void test(MethodEntry current, List<MethodEntry> set) {
   Iterator<MethodEntry> it = current.myCalledMethods.iterator();
   while (it.hasNext()) {
     MethodEntry callee = it.next();
     if (set.contains(callee)) {
       callee.myCalledByMethods.remove(current);
       if (callee.myCalledByMethods.size() == 0) {
         callee.myRelatedMethod = false;
       }
       it.remove();
     } else {
       set.add(callee);
       test(callee, set);
     }
   }
 }
  private static boolean elementListsEqual(List<Element> l1, List<Element> l2) {
    if (l1 == null) return l2 == null;
    if (l2 == null) return false;

    if (l1.size() != l2.size()) return false;

    Iterator<Element> i1 = l1.iterator();
    Iterator<Element> i2 = l2.iterator();

    while (i2.hasNext()) {
      Element elem1 = i1.next();
      Element elem2 = i2.next();

      if (!elementsEqual(elem1, elem2)) return false;
    }
    return true;
  }
  private static void filterOutBindings(@NotNull List<GroovyResolveResult> candidates) {
    boolean hasNonBinding = false;
    for (GroovyResolveResult candidate : candidates) {
      if (!(candidate.getElement() instanceof GrBindingVariable)) {
        hasNonBinding = true;
      }
    }

    if (hasNonBinding) {
      for (Iterator<GroovyResolveResult> iterator = candidates.iterator(); iterator.hasNext(); ) {
        GroovyResolveResult candidate = iterator.next();
        if (candidate.getElement() instanceof GrBindingVariable) {
          iterator.remove();
        }
      }
    }
  }
Example #20
0
  @Nullable
  public static PsiField findPropertyFieldWithType(
      Project project,
      String propertyName,
      boolean isStatic,
      PsiType type,
      Iterator<PsiField> fields) {
    while (fields.hasNext()) {
      PsiField field = fields.next();
      if (field.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue;
      if (propertyName.equals(suggestPropertyName(project, field))) {
        if (type.equals(field.getType())) return field;
      }
    }

    return null;
  }
Example #21
0
  private static boolean attributeListsEqual(List<Attribute> l1, List<Attribute> l2) {
    if (l1 == null) return l2 == null;
    if (l2 == null) return false;

    if (l1.size() != l2.size()) return false;

    Iterator<Attribute> i1 = l1.iterator();

    for (Attribute aL2 : l2) {
      Attribute attr1 = i1.next();

      if (!Comparing.equal(attr1.getName(), aL2.getName())
          || !Comparing.equal(attr1.getValue(), aL2.getValue())) {
        return false;
      }
    }
    return true;
  }
 private void removeParametersUsedInExitsOnly(
     PsiElement codeFragment, List<PsiVariable> inputVariables) {
   LocalSearchScope scope = new LocalSearchScope(codeFragment);
   Variables:
   for (Iterator<PsiVariable> iterator = inputVariables.iterator(); iterator.hasNext(); ) {
     PsiVariable variable = iterator.next();
     for (PsiReference ref : ReferencesSearch.search(variable, scope)) {
       PsiElement element = ref.getElement();
       int elementOffset = myControlFlow.getStartOffset(element);
       if (elementOffset == -1) {
         continue Variables;
       }
       if (elementOffset >= myFlowStart && elementOffset <= myFlowEnd) {
         if (!isInExitStatements(element, myExitStatements)) continue Variables;
       }
     }
     iterator.remove();
   }
 }
  @Override
  public void removeEntryPoint(@NotNull RefElement anEntryPoint) {
    myTemporaryEntryPoints.remove(anEntryPoint);

    Set<Map.Entry<String, SmartRefElementPointer>> set = myPersistentEntryPoints.entrySet();
    String key = null;
    for (Map.Entry<String, SmartRefElementPointer> entry : set) {
      SmartRefElementPointer value = entry.getValue();
      if (value.getRefElement() == anEntryPoint) {
        key = entry.getKey();
        break;
      }
    }

    if (key != null) {
      myPersistentEntryPoints.remove(key);
    }
    ((RefElementImpl) anEntryPoint).setEntry(false);

    if (anEntryPoint.isPermanentEntry() && anEntryPoint.isValid()) {
      final Project project = anEntryPoint.getElement().getProject();
      final EntryPointsManager entryPointsManager = getInstance(project);
      if (this != entryPointsManager) {
        entryPointsManager.removeEntryPoint(anEntryPoint);
      }
    }

    if (anEntryPoint instanceof RefMethod && ((RefMethod) anEntryPoint).isConstructor()
        || anEntryPoint instanceof RefClass) {
      final RefClass aClass =
          anEntryPoint instanceof RefClass
              ? (RefClass) anEntryPoint
              : ((RefMethod) anEntryPoint).getOwnerClass();
      final String qualifiedName = aClass.getQualifiedName();
      for (Iterator<ClassPattern> iterator = getPatterns().iterator(); iterator.hasNext(); ) {
        if (Comparing.equal(iterator.next().pattern, qualifiedName)) {
          // todo if inheritance or pattern?
          iterator.remove();
        }
      }
    }
  }
  private List<TypeParameterDescriptor> modifyTypeParametersAccordingToSuperMethods(
      List<TypeParameterDescriptor> autoTypeParameters) {
    List<TypeParameterDescriptor> result = Lists.newArrayList();

    for (TypeParameterDescriptor autoParameter : autoTypeParameters) {
      int index = autoParameter.getIndex();
      TypeParameterDescriptorImpl modifiedTypeParameter =
          autoTypeParameterToModified.get(autoParameter);

      List<Iterator<JetType>> upperBoundFromSuperFunctionsIterators = Lists.newArrayList();
      for (FunctionDescriptor superFunction : superFunctions) {
        upperBoundFromSuperFunctionsIterators.add(
            superFunction.getTypeParameters().get(index).getUpperBounds().iterator());
      }

      for (JetType autoUpperBound : autoParameter.getUpperBounds()) {
        List<TypeAndVariance> upperBoundsFromSuperFunctions = Lists.newArrayList();

        for (Iterator<JetType> iterator : upperBoundFromSuperFunctionsIterators) {
          assert iterator.hasNext();
          upperBoundsFromSuperFunctions.add(new TypeAndVariance(iterator.next(), INVARIANT));
        }

        JetType modifiedUpperBound =
            modifyTypeAccordingToSuperMethods(
                autoUpperBound, upperBoundsFromSuperFunctions, UPPER_BOUND);
        modifiedTypeParameter.addUpperBound(modifiedUpperBound);
      }

      for (Iterator<JetType> iterator : upperBoundFromSuperFunctionsIterators) {
        assert !iterator.hasNext();
      }

      modifiedTypeParameter.setInitialized();
      result.add(modifiedTypeParameter);
    }

    return result;
  }
  private void validateEntryPoints() {
    long count = PsiManager.getInstance(myProject).getModificationTracker().getModificationCount();
    if (count != myLastModificationCount) {
      myLastModificationCount = count;
      Collection<SmartRefElementPointer> collection = myPersistentEntryPoints.values();
      SmartRefElementPointer[] entries =
          collection.toArray(new SmartRefElementPointer[collection.size()]);
      for (SmartRefElementPointer entry : entries) {
        RefElement refElement = (RefElement) entry.getRefElement();
        if (refElement != null && !refElement.isValid()) {
          myPersistentEntryPoints.remove(entry.getFQName());
        }
      }

      final Iterator<RefElement> it = myTemporaryEntryPoints.iterator();
      while (it.hasNext()) {
        RefElement refElement = it.next();
        if (!refElement.isValid()) {
          it.remove();
        }
      }
    }
  }
    private void addInaccessibilityDescriptions(
        Set<UsageInfo> usages, MultiMap<PsiElement, String> conflictDescriptions)
        throws IncorrectOperationException {
      PsiMethod method = myChangeInfo.getMethod();
      PsiModifierList modifierList = (PsiModifierList) method.getModifierList().copy();
      VisibilityUtil.setVisibility(modifierList, myChangeInfo.getNewVisibility());

      for (Iterator<UsageInfo> iterator = usages.iterator(); iterator.hasNext(); ) {
        UsageInfo usageInfo = iterator.next();
        PsiElement element = usageInfo.getElement();
        if (element != null) {
          if (element instanceof PsiQualifiedReference) {
            PsiClass accessObjectClass = null;
            PsiElement qualifier = ((PsiQualifiedReference) element).getQualifier();
            if (qualifier instanceof PsiExpression) {
              accessObjectClass =
                  (PsiClass) PsiUtil.getAccessObjectClass((PsiExpression) qualifier).getElement();
            }

            if (!JavaPsiFacade.getInstance(element.getProject())
                .getResolveHelper()
                .isAccessible(method, modifierList, element, accessObjectClass, null)) {
              String message =
                  RefactoringBundle.message(
                      "0.with.1.visibility.is.not.accessible.from.2",
                      RefactoringUIUtil.getDescription(method, true),
                      myChangeInfo.getNewVisibility(),
                      RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true));
              conflictDescriptions.putValue(method, message);
              if (!needToChangeCalls()) {
                iterator.remove();
              }
            }
          }
        }
      }
    }
 public List<PsiVariable> getInputVariables(
     final PsiElement codeFragment, PsiElement[] elements, PsiVariable[] outputVariables) {
   final List<PsiVariable> inputVariables =
       ControlFlowUtil.getInputVariables(myControlFlow, myFlowStart, myFlowEnd);
   List<PsiVariable> myInputVariables;
   if (skipVariablesFromExitStatements(outputVariables)) {
     List<PsiVariable> inputVariableList = new ArrayList<>(inputVariables);
     removeParametersUsedInExitsOnly(codeFragment, inputVariableList);
     myInputVariables = inputVariableList;
   } else {
     List<PsiVariable> inputVariableList = new ArrayList<>(inputVariables);
     for (Iterator<PsiVariable> iterator = inputVariableList.iterator(); iterator.hasNext(); ) {
       PsiVariable variable = iterator.next();
       for (PsiElement element : elements) {
         if (PsiTreeUtil.isAncestor(element, variable, false)) {
           iterator.remove();
           break;
         }
       }
     }
     myInputVariables = inputVariableList;
   }
   // varargs variables go last, otherwise order is induced by original ordering
   Collections.sort(
       myInputVariables,
       (v1, v2) -> {
         if (v1.getType() instanceof PsiEllipsisType) {
           return 1;
         }
         if (v2.getType() instanceof PsiEllipsisType) {
           return -1;
         }
         return v1.getTextOffset() - v2.getTextOffset();
       });
   return myInputVariables;
 }
Example #28
0
 private void removeInvalidRefs() {
   synchronized (myLocalRefsMap) {
     for (Iterator<PsiReference> iterator = myLocalRefsMap.keySet().iterator();
         iterator.hasNext(); ) {
       PsiReference ref = iterator.next();
       if (!ref.getElement().isValid()) {
         PsiElement value = myLocalRefsMap.get(ref);
         iterator.remove();
         List<PsiReference> array = myLocalRefsMap.getKeysByValue(value);
         LOG.assertTrue(array != null);
         array.remove(ref);
       }
     }
   }
   for (Iterator<PsiReference> iterator = myImportStatements.keySet().iterator();
       iterator.hasNext(); ) {
     PsiReference ref = iterator.next();
     if (!ref.getElement().isValid()) {
       iterator.remove();
     }
   }
   removeInvalidFrom(myDclsUsedMap.keySet());
 }
  public static ReferenceType getSuperClass(
      final String baseQualifiedName, ReferenceType checkedType) {
    if (baseQualifiedName.equals(checkedType.name())) {
      return checkedType;
    }

    if (checkedType instanceof ClassType) {
      ClassType classType = (ClassType) checkedType;
      ClassType superClassType = classType.superclass();
      if (superClassType != null) {
        ReferenceType superClass = getSuperClass(baseQualifiedName, superClassType);
        if (superClass != null) {
          return superClass;
        }
      }
      List<InterfaceType> ifaces = classType.allInterfaces();
      for (Iterator<InterfaceType> it = ifaces.iterator(); it.hasNext(); ) {
        InterfaceType iface = it.next();
        ReferenceType superClass = getSuperClass(baseQualifiedName, iface);
        if (superClass != null) {
          return superClass;
        }
      }
    }

    if (checkedType instanceof InterfaceType) {
      List<InterfaceType> list = ((InterfaceType) checkedType).superinterfaces();
      for (Iterator<InterfaceType> it = list.iterator(); it.hasNext(); ) {
        InterfaceType superInterface = it.next();
        ReferenceType superClass = getSuperClass(baseQualifiedName, superInterface);
        if (superClass != null) {
          return superClass;
        }
      }
    }
    return null;
  }
  private List<PostponedAction> normalizeAndReorderPostponedActions(
      final TreeSet<PostprocessFormattingTask> rangesToProcess, Document document) {
    final List<PostprocessFormattingTask> freeFormatingActions =
        new ArrayList<PostprocessFormattingTask>();
    final List<ReindentTask> indentActions = new ArrayList<ReindentTask>();

    PostprocessFormattingTask accumulatedTask = null;
    Iterator<PostprocessFormattingTask> iterator = rangesToProcess.iterator();
    while (iterator.hasNext()) {
      final PostprocessFormattingTask currentTask = iterator.next();
      if (accumulatedTask == null) {
        accumulatedTask = currentTask;
        iterator.remove();
      } else if (accumulatedTask.getStartOffset() > currentTask.getEndOffset()
          || accumulatedTask.getStartOffset() == currentTask.getEndOffset()
              && !canStickActionsTogether(accumulatedTask, currentTask)) {
        // action can be pushed
        if (accumulatedTask instanceof ReindentTask) {
          indentActions.add((ReindentTask) accumulatedTask);
        } else {
          freeFormatingActions.add(accumulatedTask);
        }

        accumulatedTask = currentTask;
        iterator.remove();
      } else if (accumulatedTask instanceof ReformatTask && currentTask instanceof ReindentTask) {
        // split accumulated reformat range into two
        if (accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
          final RangeMarker endOfRange =
              document.createRangeMarker(
                  accumulatedTask.getStartOffset(), currentTask.getStartOffset());
          // add heading reformat part
          rangesToProcess.add(new ReformatTask(endOfRange));
          // and manage heading whitespace because formatter does not edit it in previous action
          iterator = rangesToProcess.iterator();
          //noinspection StatementWithEmptyBody
          while (iterator.next().getRange() != currentTask.getRange()) ;
        }
        final RangeMarker rangeToProcess =
            document.createRangeMarker(currentTask.getEndOffset(), accumulatedTask.getEndOffset());
        freeFormatingActions.add(new ReformatWithHeadingWhitespaceTask(rangeToProcess));
        accumulatedTask = currentTask;
        iterator.remove();
      } else {
        if (!(accumulatedTask instanceof ReindentTask)) {
          iterator.remove();

          boolean withLeadingWhitespace =
              accumulatedTask instanceof ReformatWithHeadingWhitespaceTask;
          if (accumulatedTask instanceof ReformatTask
              && currentTask instanceof ReformatWithHeadingWhitespaceTask
              && accumulatedTask.getStartOffset() == currentTask.getStartOffset()) {
            withLeadingWhitespace = true;
          } else if (accumulatedTask instanceof ReformatWithHeadingWhitespaceTask
              && currentTask instanceof ReformatTask
              && accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
            withLeadingWhitespace = false;
          }
          int newStart = Math.min(accumulatedTask.getStartOffset(), currentTask.getStartOffset());
          int newEnd = Math.max(accumulatedTask.getEndOffset(), currentTask.getEndOffset());
          RangeMarker rangeMarker;

          if (accumulatedTask.getStartOffset() == newStart
              && accumulatedTask.getEndOffset() == newEnd) {
            rangeMarker = accumulatedTask.getRange();
          } else if (currentTask.getStartOffset() == newStart
              && currentTask.getEndOffset() == newEnd) {
            rangeMarker = currentTask.getRange();
          } else {
            rangeMarker = document.createRangeMarker(newStart, newEnd);
          }

          if (withLeadingWhitespace) {
            accumulatedTask = new ReformatWithHeadingWhitespaceTask(rangeMarker);
          } else {
            accumulatedTask = new ReformatTask(rangeMarker);
          }
        } else if (currentTask instanceof ReindentTask) {
          iterator.remove();
        } // TODO[ik]: need to be fixed to correctly process indent inside indent
      }
    }
    if (accumulatedTask != null) {
      if (accumulatedTask instanceof ReindentTask) {
        indentActions.add((ReindentTask) accumulatedTask);
      } else {
        freeFormatingActions.add(accumulatedTask);
      }
    }

    final List<PostponedAction> result = new ArrayList<PostponedAction>();
    Collections.reverse(freeFormatingActions);
    Collections.reverse(indentActions);

    if (!freeFormatingActions.isEmpty()) {
      FormatTextRanges ranges = new FormatTextRanges();
      for (PostprocessFormattingTask action : freeFormatingActions) {
        TextRange range = TextRange.create(action);
        ranges.add(range, action instanceof ReformatWithHeadingWhitespaceTask);
      }
      result.add(new ReformatRangesAction(ranges));
    }

    if (!indentActions.isEmpty()) {
      ReindentRangesAction reindentRangesAction = new ReindentRangesAction();
      for (ReindentTask action : indentActions) {
        reindentRangesAction.add(action.getRange(), action.getOldIndent());
      }
      result.add(reindentRangesAction);
    }

    return result;
  }