/**
  * Substitutes element to be renamed and initiate rename procedure. Should be used in order to
  * prevent modal dialogs to appear during inplace rename
  *
  * @param element the element on which refactoring was invoked
  * @param editor the editor in which inplace refactoring was invoked
  * @param renameCallback rename procedure which should be called on the chosen substitution
  */
 public void substituteElementToRename(
     @NotNull final PsiElement element,
     @NotNull Editor editor,
     @NotNull Pass<PsiElement> renameCallback) {
   final PsiElement psiElement = substituteElementToRename(element, editor);
   if (psiElement == null) return;
   if (!PsiElementRenameHandler.canRename(psiElement.getProject(), editor, psiElement)) return;
   renameCallback.pass(psiElement);
 }
  private void updateErrorMessage(
      Pass<String> updateErrorMessage, ProjectFileIndex fileIndex, Object selectedItem) {
    updateErrorMessage.pass(null);
    if (myInitialTargetDirectory != null
        && selectedItem instanceof DirectoryChooser.ItemWrapper
        && selectedItem != NULL_WRAPPER) {
      final PsiDirectory directory = ((DirectoryChooser.ItemWrapper) selectedItem).getDirectory();
      final boolean isSelectionInTestSourceContent =
          fileIndex.isInTestSourceContent(directory.getVirtualFile());
      final boolean inTestSourceContent =
          fileIndex.isInTestSourceContent(myInitialTargetDirectory.getVirtualFile());
      if (isSelectionInTestSourceContent != inTestSourceContent) {
        if (inTestSourceContent && reportBaseInTestSelectionInSource()) {
          updateErrorMessage.pass("Source root is selected while the test root is expected");
        }

        if (isSelectionInTestSourceContent && reportBaseInSourceSelectionInTest()) {
          updateErrorMessage.pass("Test root is selected while the source root is expected");
        }
      }
    }
  }
  public static void processElementToWorkOn(
      final Editor editor,
      final PsiFile file,
      final String refactoringName,
      final String helpId,
      final Project project,
      final Pass<ElementToWorkOn> processor) {
    PsiLocalVariable localVar = null;
    PsiExpression expr = null;

    if (!editor.getSelectionModel().hasSelection()) {
      PsiElement element =
          TargetElementUtilBase.findTargetElement(
              editor,
              TargetElementUtilBase.ELEMENT_NAME_ACCEPTED
                  | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED
                  | TargetElementUtilBase.LOOKUP_ITEM_ACCEPTED);
      if (element instanceof PsiLocalVariable) {
        localVar = (PsiLocalVariable) element;
        final PsiElement elementAt = file.findElementAt(editor.getCaretModel().getOffset());
        if (elementAt instanceof PsiIdentifier
            && elementAt.getParent() instanceof PsiReferenceExpression) {
          expr = (PsiExpression) elementAt.getParent();
        }
      } else {
        final PsiLocalVariable variable =
            PsiTreeUtil.getParentOfType(
                file.findElementAt(editor.getCaretModel().getOffset()), PsiLocalVariable.class);

        final int offset = editor.getCaretModel().getOffset();
        final PsiElement[] statementsInRange =
            IntroduceVariableBase.findStatementsAtOffset(editor, file, offset);

        if (statementsInRange.length == 1
            && (PsiUtil.hasErrorElementChild(statementsInRange[0])
                || !PsiUtil.isStatement(statementsInRange[0]))) {
          editor.getSelectionModel().selectLineAtCaret();
          final ElementToWorkOn elementToWorkOn =
              getElementToWorkOn(editor, file, refactoringName, helpId, project, localVar, expr);
          if (elementToWorkOn == null
              || elementToWorkOn.getLocalVariable() == null
                  && elementToWorkOn.getExpression() == null) {
            editor.getSelectionModel().removeSelection();
          }
        }

        if (!editor.getSelectionModel().hasSelection()) {
          final List<PsiExpression> expressions =
              IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange);
          if (expressions.isEmpty()) {
            editor.getSelectionModel().selectLineAtCaret();
          } else if (expressions.size() == 1) {
            expr = expressions.get(0);
          } else {
            IntroduceTargetChooser.showChooser(
                editor,
                expressions,
                new Pass<PsiExpression>() {
                  @Override
                  public void pass(final PsiExpression selectedValue) {
                    PsiLocalVariable var =
                        null; // replace var if selected expression == var initializer
                    if (variable != null && variable.getInitializer() == selectedValue) {
                      var = variable;
                    }
                    processor.pass(
                        getElementToWorkOn(
                            editor, file, refactoringName, helpId, project, var, selectedValue));
                  }
                },
                new PsiExpressionTrimRenderer.RenderFunction());
            return;
          }
        }
      }
    }

    processor.pass(
        getElementToWorkOn(editor, file, refactoringName, helpId, project, localVar, expr));
  }