@Override
  protected void invoke(@NotNull ActionContext context, @NotNull PsiLoopStatement loop, @NotNull ModPsiUpdater updater) {
    if (!(loop.getParent() instanceof PsiCodeBlock parentBlock)) return;
    List<PsiExpression> expressions = extractExpressions(loop);
    if (expressions.isEmpty()) return;
    Project project = context.project();
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
    CommentTracker ct = new CommentTracker();
    PsiElement anchor = loop;
    for (PsiExpression expression : expressions) {
      PsiLoopStatement copy = (PsiLoopStatement)factory.createStatementFromText(loop.getText(), loop);
      PsiVariable variable = Objects.requireNonNull(getVariable(copy));
      for (PsiReference reference : ReferencesSearch.search(variable, new LocalSearchScope(copy))) {
        final PsiElement referenceElement = reference.getElement();
        if (referenceElement instanceof PsiJavaCodeReferenceElement) {
          ct.markUnchanged(expression);
          CommonJavaInlineUtil.getInstance().inlineVariable(variable, expression, (PsiJavaCodeReferenceElement)referenceElement, null);
        }
      }
      PsiStatement body = copy.getBody();
      assert body != null;
      PsiElement[] children;
      if (body instanceof PsiBlockStatement) {
        PsiCodeBlock block = ((PsiBlockStatement)Objects.requireNonNull(loop.getBody())).getCodeBlock();
        if (canUnwrapBlock(block, parentBlock, expressions)) {
          PsiElement firstBodyElement = block.getFirstBodyElement();
          PsiElement lastBodyElement = block.getLastBodyElement();
          if (firstBodyElement != null && lastBodyElement != null) {
            ct.markRangeUnchanged(firstBodyElement, lastBodyElement);
          }
          children = ((PsiBlockStatement)body).getCodeBlock().getChildren();
          // Skip {braces}
          children = Arrays.copyOfRange(children, 1, children.length-1);
        } else {
          ct.markUnchanged(loop.getBody());
          children = new PsiElement[]{body};
        }
      } else {
        ct.markUnchanged(loop.getBody());
        children = new PsiElement[]{body};
      }
      for(PsiElement child : children) {
        PsiElement added = anchor.getParent().addBefore(child, anchor);
        if (added instanceof PsiIfStatement ifStatement && isLoopBreak((PsiStatement)added)) {
          PsiExpression condition = Objects.requireNonNull(ifStatement.getCondition());
          PsiStatement thenBranch = Objects.requireNonNull(ifStatement.getThenBranch());
          String negated = BoolUtils.getNegatedExpressionText(condition, ct);
          condition.replace(factory.createExpressionFromText(negated, condition));
          PsiBlockStatement block = (PsiBlockStatement)thenBranch.replace(factory.createStatementFromText("{}", added));
          anchor = block.getCodeBlock().getLastChild();
        }
      }
    }
    if (loop instanceof PsiForeachStatement) {
      PsiExpression iteratedValue = ((PsiForeachStatement)loop).getIteratedValue();
      PsiLocalVariable variable = ExpressionUtils.resolveLocalVariable(iteratedValue);
      if (variable != null && PsiTreeUtil.isAncestor(variable, expressions.get(0), true)) ct.delete(variable);
    }
    ct.deleteAndRestoreComments(loop);
  }
@Override
  protected void invoke(@NotNull ActionContext context, @NotNull PsiLoopStatement loop, @NotNull ModPsiUpdater updater)