private void generateScopeBasedChoices(PsiExpression expr,
                                           LinkedHashMap<JavaReplaceChoice, List<PsiExpression>> occurrencesMap) {
      // This comparator can correctly compare only elements that represent a single ancestor chain
      // i.e. for two compared elements a and b either a is ancestor of b or vice versa
      Comparator<PsiElement> treeOrder = (e1, e2) -> {
        if (PsiTreeUtil.isAncestor(e1, e2, true)) return 1;
        if (PsiTreeUtil.isAncestor(e2, e1, true)) return -1;
        return 0;
      };
      PsiElement physical = getPhysicalElement(expr);
      TreeMap<PsiElement, List<PsiExpression>> groupByBlock =
        StreamEx.of(myOccurrences)
          .map(place -> (PsiExpression)getPhysicalElement(place))
          .groupingBy(e -> PsiTreeUtil.findCommonParent(e, physical),
                      () -> new TreeMap<>(treeOrder), Collectors.toList());
      IntroduceVariableUtil.LOG.assertTrue(!groupByBlock.isEmpty());
      List<PsiExpression> currentOccurrences = new ArrayList<>();
      Map<String, Integer> counts = new HashMap<>();
      groupByBlock.forEach((parent, occurrences) -> {
        PsiElement nextParent = groupByBlock.higherKey(parent);
        if (nextParent == null) return;
        currentOccurrences.addAll(occurrences);
        if (currentOccurrences.size() == 1) return;
        PsiElement current = parent.getParent();
        @NonNls String keyword = null;
        while (current != nextParent) {
          if (current instanceof PsiIfStatement || current instanceof PsiWhileStatement || current instanceof PsiForStatement ||
              current instanceof PsiTryStatement) {
            keyword = current.getFirstChild().getText();
          }
          else if (current instanceof PsiDoWhileStatement) {
            keyword = "do-while";
          }
          else if (current instanceof PsiForeachStatement) {
            keyword = "for-each";
          }
          else if (current instanceof PsiLambdaExpression) {
            keyword = "lambda";
          }
          if (keyword != null) {
            break;
          }
          current = current.getParent();
        }
        if (keyword == null && nextParent instanceof PsiIfStatement) {
          PsiStatement thenBranch = ((PsiIfStatement)nextParent).getThenBranch();
          PsiStatement elseBranch = ((PsiIfStatement)nextParent).getElseBranch();
          if (PsiTreeUtil.isAncestor(thenBranch, parent, false)) {
            keyword = "if-then";
          } else if (PsiTreeUtil.isAncestor(elseBranch, parent, false)) {
            keyword = "else";
          }
        }
        if (keyword != null) {
          int sameKeywordCount = counts.merge(keyword, 1, Integer::sum);
          if (sameKeywordCount <= 2) {
            JavaReplaceChoice choice = JavaReplaceChoice.allOccurrencesInside(parent, sameKeywordCount, keyword);
            occurrencesMap.put(choice, new ArrayList<>(currentOccurrences));
          }
        }
      });
    }
private void generateScopeBasedChoices(PsiExpression expr,
                                           LinkedHashMap<JavaReplaceChoice, List<PsiExpression>> occurrencesMap)