@Override
  public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
    String varName = myReferenceExpression.getReferenceName();
    if (CreateFromUsageUtils.isValidReference(myReferenceExpression, false) || varName == null) return;

    if (file.isPhysical()) {
      IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
    }

    PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);

    PsiType[] expectedTypes = CreateFromUsageUtils.guessType(myReferenceExpression, false);
    final SmartTypePointer defaultType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(expectedTypes[0]);
    final PsiType preferredType = TypeSelectorManagerImpl.getPreferredType(expectedTypes, expectedTypes[0]);
    PsiType type = preferredType != null ? preferredType : expectedTypes[0];
    if (LambdaUtil.notInferredType(type)) {
      type = PsiType.getJavaLangObject(myReferenceExpression.getManager(), file.getResolveScope());
    }

    PsiExpression initializer = null;
    boolean isInline = false;
    PsiExpression[] expressions = CreateFromUsageUtils.collectExpressions(myReferenceExpression, PsiMember.class, PsiFile.class);
    PsiStatement anchor = getAnchor(expressions);
    if (anchor == null) {
      expressions = new PsiExpression[]{myReferenceExpression};
      anchor = getAnchor(expressions);
      if (anchor == null) return;
    }
    if (anchor instanceof PsiExpressionStatement expressionStatement &&
        expressionStatement.getExpression() instanceof PsiAssignmentExpression assignment &&
        assignment.getLExpression().textMatches(myReferenceExpression)) {
      initializer = assignment.getRExpression();
      isInline = true;
    }

    PsiDeclarationStatement decl = factory.createVariableDeclarationStatement(varName, type, initializer);

    TypeExpression expression = new TypeExpression(project, expectedTypes);

    if (isInline) {
      CommentTracker tracker = new CommentTracker();
      tracker.markUnchanged(initializer);
      decl = (PsiDeclarationStatement)tracker.replaceAndRestoreComments(anchor, decl);
    }
    else {
      decl = (PsiDeclarationStatement)anchor.getParent().addBefore(decl, anchor);
    }

    PsiVariable var = (PsiVariable)decl.getDeclaredElements()[0];
    boolean isFinal =
      JavaCodeStyleSettings.getInstance(file).GENERATE_FINAL_LOCALS &&
      !CreateFromUsageUtils.isAccessedForWriting(expressions);
    PsiUtil.setModifierProperty(var, PsiModifier.FINAL, isFinal);

    var = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(var);
    if (var == null || !file.isPhysical()) return;
    TemplateBuilderImpl builder = new TemplateBuilderImpl(var);
    final PsiTypeElement typeElement = var.getTypeElement();
    LOG.assertTrue(typeElement != null);
    builder.replaceElement(typeElement,
                           IntroduceVariableUtil.createExpression(expression, typeElement.getText()));
    builder.setEndVariableAfter(var.getNameIdentifier());
    Template template = builder.buildTemplate();

    final Editor newEditor = CodeInsightUtil.positionCursor(project, file, var);
    if (newEditor == null) return;
    TextRange range = var.getTextRange();
    newEditor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());

    startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
      @Override
      public void templateFinished(@NotNull Template template, boolean brokenOff) {
        PsiDocumentManager.getInstance(project).commitDocument(newEditor.getDocument());
        final int offset = newEditor.getCaretModel().getOffset();
        final PsiLocalVariable localVariable = PsiTreeUtil.findElementOfClassAtOffset(file, offset, PsiLocalVariable.class, false);
        if (localVariable != null) {
          TypeSelectorManagerImpl.typeSelected(localVariable.getType(), defaultType.getType());

          ApplicationManager.getApplication().runWriteAction(() -> {
            CodeStyleManager.getInstance(project).reformat(localVariable);
          });
        }
      }
    });
  }
@Override
  public void invoke(@NotNull Project project, Editor editor, PsiFile file)