@Override
  public void invoke(@NotNull final Project project, final PsiElement @NotNull [] elements, DataContext dataContext) {
    if (elements.length == 0) {
      return;
    }
    PsiElement containingClass = elements[0];
    if (containingClass instanceof PsiField field) {
      containingClass = field.getContainingClass();
    }
    if (!(containingClass instanceof PsiClass)) {
      return;
    }
    PsiElement finalContainingClass = containingClass;

    List<SmartPsiElementPointer<PsiElement>> smartElements = new ArrayList<>();
    SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project);
    for (PsiElement psiElement : elements) {
      if (psiElement == null) {
        continue;
      }
      smartElements.add(smartPointerManager.createSmartPsiElementPointer(psiElement));
    }
    ReadAction.nonBlocking(() -> {
        PsiClass aClass = null;
        Runnable callback;
        final HashSet<PsiField> preselectedFields = new HashSet<>();
        if (smartElements.size() == 1) {
          PsiElement element = smartElements.get(0).getElement();
          if (element == null) {
            return null;
          }
          if (element instanceof PsiClass) {
            aClass = (PsiClass)elements[0];
          }
          else if (element instanceof PsiField field) {
            aClass = field.getContainingClass();
            preselectedFields.add(field);
          }
          else {
            return null;
          }
        }
        else {
          for (SmartPsiElementPointer<PsiElement> smartElement : smartElements) {
            PsiElement element = smartElement.getElement();
            if (element == null) {
              return null;
            }
            if (!(element instanceof PsiField field)) {
              return null;
            }
            if (aClass == null) {
              aClass = field.getContainingClass();
              preselectedFields.add(field);
            }
            else {
              if (aClass.equals(field.getContainingClass())) {
                preselectedFields.add(field);
              }
              else {
                callback = () ->
                {
                  String message = RefactoringBundle.getCannotRefactorMessage(
                    JavaRefactoringBundle.message("fields.to.be.refactored.should.belong.to.the.same.class"));
                  Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
                  CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
                };
                return callback;
              }
            }
          }
        }

        LOG.assertTrue(aClass != null);
        final List<PsiField> fields = ContainerUtil.filter(aClass.getFields(), field -> !(field instanceof PsiEnumConstant));
        if (fields.isEmpty()) {
          callback = () -> {
            CommonRefactoringUtil.showErrorHint(project, CommonDataKeys.EDITOR.getData(dataContext),
                                                JavaRefactoringBundle.message("encapsulate.fields.nothing.todo.warning.message"),
                                                getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
          };
          return callback;
        }

        if (aClass.isInterface()) {
          callback = () -> {
            String message = RefactoringBundle.getCannotRefactorMessage(
              JavaRefactoringBundle.message("encapsulate.fields.refactoring.cannot.be.applied.to.interface"));
            Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
            CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
          };
          return callback;
        }
        EncapsulateFieldsDialog.EncapsulateFieldsContainer container = prepare(aClass, preselectedFields);
        PsiClass finalAClass = aClass;
        callback = () -> {
          EncapsulateFieldsDialog dialog = getDialog(project, container);
          if (!CommonRefactoringUtil.checkReadOnlyStatus(project, finalAClass)) return;
          dialog.show();
        };
        return callback;
      })
      .finishOnUiThread(ModalityState.defaultModalityState(), callback -> {
        if (callback != null) {
          callback.run();
        }
      })
      .expireWhen(() -> !finalContainingClass.isValid())
      .submit(AppExecutorUtil.getAppExecutorService());
  }
@Override
  public void invoke(@NotNull final Project project, final PsiElement @NotNull [] elements, DataContext dataContext)