@Override
  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
    int offset = editor.getCaretModel().getOffset();
    int startOffset = offset;
    if (editor.getSelectionModel().hasSelection()) {
      final int selStart = editor.getSelectionModel().getSelectionStart();
      final int selEnd = editor.getSelectionModel().getSelectionEnd();
      startOffset = (offset == selStart) ? selEnd : selStart;
    }
    PsiElement element = file.findElementAt(startOffset);
    while (element instanceof PsiWhiteSpace) {
      element = element.getPrevSibling();
    }
    PsiStatement psiStatement = PsiTreeUtil.getParentOfType(element, PsiStatement.class, false);
    if (myExpression == null && psiStatement instanceof PsiExpressionStatement &&
        startOffset == offset && startOffset == psiStatement.getTextRange().getEndOffset() &&
        psiStatement.getLastChild() instanceof PsiErrorElement) {
      // At this position, we provide a quick-fix for error
      return false;
    }
    if (psiStatement != null) {
      startOffset = psiStatement.getTextRange().getStartOffset();
    }
    PsiExpression expression = getIterableExpression(editor, file);
    if (expression == null) return false;
    if (ConstructionUtils.isEmptyCollectionInitializer(expression)) {
      // Empty collection: iterating doesn't make much sense
      return false;
    }
    if (expression instanceof PsiNewExpression && ((PsiNewExpression)expression).getArrayDimensions().length > 0) {
      // new array without initializers: all elements are 0/null/false, so iterating doesn't make much sense
      return false;
    }

    TemplateImpl template = file instanceof PsiJavaFile ? getTemplate() : null;
    if (template == null || template.isDeactivated()) return false;

    // we are checking Template applicability later, because it requires initialization of all (for all languages) template context types
    if (!TemplateManagerImpl.isApplicable(file, offset, template) &&
        !TemplateManagerImpl.isApplicable(file, startOffset, template)) {
      return false;
    }

    myText = JavaBundle.message("intention.name.iterate.over", Objects.requireNonNull(expression.getType()).getPresentableText());
    return true;
  }
@Override
  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file)