public static boolean isValidName(
      final Project project, final PsiElement psiElement, final String newName) {
    if (newName == null || newName.length() == 0) {
      return false;
    }
    final Condition<String> inputValidator =
        RenameInputValidatorRegistry.getInputValidator(psiElement);
    if (inputValidator != null) {
      return inputValidator.value(newName);
    }
    if (psiElement instanceof PsiFile || psiElement instanceof PsiDirectory) {
      return newName.indexOf('\\') < 0 && newName.indexOf('/') < 0;
    }
    if (psiElement instanceof PomTargetPsiElement) {
      return !StringUtil.isEmptyOrSpaces(newName);
    }

    final PsiFile file = psiElement.getContainingFile();
    final Language elementLanguage = psiElement.getLanguage();

    final Language fileLanguage = file == null ? null : file.getLanguage();
    Language language =
        fileLanguage == null
            ? elementLanguage
            : fileLanguage.isKindOf(elementLanguage) ? fileLanguage : elementLanguage;

    return LanguageNamesValidation.INSTANCE
        .forLanguage(language)
        .isIdentifier(newName.trim(), project);
  }
  @Override
  public void invoke(
      @NotNull final Project project, @NotNull Editor editor, @NotNull PsiFile file) {
    PsiDocumentManager.getInstance(project).commitAllDocuments();

    DumbService.getInstance(project).setAlternativeResolveEnabled(true);
    try {
      int offset = editor.getCaretModel().getOffset();
      PsiElement[] elements =
          underModalProgress(
              project,
              "Resolving Reference...",
              () -> findAllTargetElements(project, editor, offset));
      FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.declaration");

      if (elements.length != 1) {
        if (elements.length == 0
            && suggestCandidates(TargetElementUtil.findReference(editor, offset)).isEmpty()) {
          PsiElement element =
              findElementToShowUsagesOf(editor, editor.getCaretModel().getOffset());
          if (startFindUsages(editor, element)) {
            return;
          }

          // disable 'no declaration found' notification for keywords
          final PsiElement elementAtCaret = file.findElementAt(offset);
          if (elementAtCaret != null) {
            final NamesValidator namesValidator =
                LanguageNamesValidation.INSTANCE.forLanguage(elementAtCaret.getLanguage());
            if (namesValidator != null
                && namesValidator.isKeyword(elementAtCaret.getText(), project)) {
              return;
            }
          }
        }
        chooseAmbiguousTarget(editor, offset, elements, file);
        return;
      }

      PsiElement element = elements[0];
      if (element == findElementToShowUsagesOf(editor, editor.getCaretModel().getOffset())
          && startFindUsages(editor, element)) {
        return;
      }

      PsiElement navElement = element.getNavigationElement();
      navElement = TargetElementUtil.getInstance().getGotoDeclarationTarget(element, navElement);
      if (navElement != null) {
        gotoTargetElement(navElement, editor, file);
      }
    } catch (IndexNotReadyException e) {
      DumbService.getInstance(project)
          .showDumbModeNotification("Navigation is not available here during index update");
    } finally {
      DumbService.getInstance(project).setAlternativeResolveEnabled(false);
    }
  }
/** @author Ilya.Kazakevich */
class PyExtractSuperclassPresenterImpl
    extends MembersBasedPresenterNoPreviewImpl<
        PyExtractSuperclassView, MemberInfoModel<PyElement, PyMemberInfo<PyElement>>>
    implements PyExtractSuperclassPresenter {
  private final NamesValidator myNamesValidator =
      LanguageNamesValidation.INSTANCE.forLanguage(PythonLanguage.getInstance());

  PyExtractSuperclassPresenterImpl(
      @NotNull final PyExtractSuperclassView view,
      @NotNull final PyClass classUnderRefactoring,
      @NotNull final PyMemberInfoStorage infoStorage) {
    super(
        view,
        classUnderRefactoring,
        infoStorage,
        new PyExtractSuperclassInfoModel(classUnderRefactoring));
  }

  @Override
  protected void validateView() throws BadDataException {
    super.validateView();
    final Project project = myClassUnderRefactoring.getProject();
    if (!myNamesValidator.isIdentifier(myView.getSuperClassName(), project)) {
      throw new BadDataException(
          PyBundle.message(
              "refactoring.extract.super.name.0.must.be.ident", myView.getSuperClassName()));
    }
    boolean rootFound = false;
    final File moduleFile = new File(myView.getModuleFile());
    try {
      final String targetDir = FileUtil.toSystemIndependentName(moduleFile.getCanonicalPath());
      for (final VirtualFile file : ProjectRootManager.getInstance(project).getContentRoots()) {
        if (StringUtil.startsWithIgnoreCase(targetDir, file.getPath())) {
          rootFound = true;
          break;
        }
      }
    } catch (final IOException ignore) {
    }
    if (!rootFound) {
      throw new BadDataException(
          PyBundle.message("refactoring.extract.super.target.path.outside.roots"));
    }

    // TODO: Cover with test. It can't be done for now, because testFixture reports root path
    // incorrectly
    // PY-12173
    myView.getModuleFile();
    final VirtualFile moduleVirtualFile =
        LocalFileSystem.getInstance().findFileByIoFile(moduleFile);
    if (moduleVirtualFile != null) {
      final PsiFile psiFile = PsiManager.getInstance(project).findFile(moduleVirtualFile);
      if (psiFile instanceof PyFile) {
        if (((PyFile) psiFile).findTopLevelClass(myView.getSuperClassName()) != null) {
          throw new BadDataException(
              PyBundle.message(
                  "refactoring.extract.super.target.class.already.exists",
                  myView.getSuperClassName()));
        }
      }
    }
  }

  @Override
  public void launch() {
    final String defaultFilePath =
        FileUtil.toSystemDependentName(
            myClassUnderRefactoring.getContainingFile().getVirtualFile().getPath());
    final VirtualFile[] roots =
        ProjectRootManager.getInstance(myClassUnderRefactoring.getProject()).getContentRoots();
    final Collection<PyMemberInfo<PyElement>> pyMemberInfos =
        PyUtil.filterOutObject(myStorage.getClassMemberInfos(myClassUnderRefactoring));
    myView.configure(
        new PyExtractSuperclassInitializationInfo(myModel, pyMemberInfos, defaultFilePath, roots));
    myView.initAndShow();
  }

  @NotNull
  @Override
  protected String getCommandName() {
    return RefactoringBundle.message(
        "extract.superclass.command.name",
        myView.getSuperClassName(),
        myClassUnderRefactoring.getName());
  }

  @Override
  protected void refactorNoPreview() {
    PyExtractSuperclassHelper.extractSuperclass(
        myClassUnderRefactoring,
        myView.getSelectedMemberInfos(),
        myView.getSuperClassName(),
        myView.getModuleFile());
  }

  @NotNull
  @Override
  protected Iterable<? extends PyClass> getDestClassesToCheckConflicts() {
    return Collections.emptyList(); // No conflict can take place in newly created classes
  }
}