@Override
    public void navigate(MouseEvent mouseEvent, PsiElement element) {
      PsiElement parent = element.getParent();
      if (!(parent instanceof DotNetVirtualImplementOwner)
          || !OverrideUtil.isAllowForOverride(parent)) {
        return;
      }

      Collection<DotNetVirtualImplementOwner> members =
          OverrideUtil.collectOverridenMembers(((DotNetVirtualImplementOwner) parent));

      if (members.isEmpty()) {
        return;
      }

      if (members.size() == 1) {
        DotNetVirtualImplementOwner firstItem = ContainerUtil.getFirstItem(members);
        if (firstItem instanceof Navigatable) {
          ((Navigatable) firstItem).navigate(true);
        }
      } else {
        PsiElement[] elements = members.toArray(new PsiElement[members.size()]);

        JBPopup popup =
            NavigationUtil.getPsiElementPopup(
                elements,
                new ElementGutterRender(),
                "Open elements (" + elements.length + " " + "items)" + "");
        popup.show(new RelativePoint(mouseEvent));
      }
    }
  public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) {
    boolean tempIsStatic = myIsConstant;
    PsiElement parent = local.getParent();
    List<PsiClass> classes = new ArrayList<>();

    if ("gr".equalsIgnoreCase(local.getContainingFile().getVirtualFile().getExtension())) {
      // this is special ij GW studio check for rule files
      CommonRefactoringUtil.showErrorHint(
          myProject,
          editor,
          "Introduce field is not supported for rule files",
          REFACTORING_NAME,
          HelpID.LOCAL_TO_FIELD);
      return false;
    }

    while (parent != null && parent.getContainingFile() != null) {
      if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) {
        classes.add((PsiClass) parent);
      }
      if (parent instanceof PsiFile && JspPsiUtil.isInJspFile(parent)) {
        String message = RefactoringBundle.message("error.not.supported.for.jsp", REFACTORING_NAME);
        CommonRefactoringUtil.showErrorHint(
            myProject, editor, message, REFACTORING_NAME, HelpID.LOCAL_TO_FIELD);
        return false;
      }
      if (parent instanceof PsiModifierListOwner
          && ((PsiModifierListOwner) parent).hasModifierProperty(PsiModifier.STATIC)) {
        tempIsStatic = true;
      }
      parent = parent.getParent();
    }

    if (classes.isEmpty()) {
      return false;
    }
    if (classes.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) {
      if (convertLocalToField(
          local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic)) {
        return false;
      }
    } else {
      final boolean isStatic = tempIsStatic;
      NavigationUtil.getPsiElementPopup(
              classes.toArray(new PsiClass[classes.size()]),
              new PsiClassListCellRenderer(),
              "Choose class to introduce " + (myIsConstant ? "constant" : "field"),
              new PsiElementProcessor<PsiClass>() {
                @Override
                public boolean execute(@NotNull PsiClass aClass) {
                  convertLocalToField(local, aClass, editor, isStatic);
                  return false;
                }
              })
          .showInBestPositionFor(editor);
    }

    return true;
  }
 private static void createValueResource(
     @NotNull PsiFile file,
     @NotNull AndroidFacet facet,
     @NotNull PsiDirectory dir,
     @NotNull final String resName,
     @NotNull final String value,
     @NotNull final ResourceType type,
     @NotNull final String oldTagText) {
   final String filename = file.getName();
   final List<String> dirNames = Collections.singletonList(dir.getName());
   final Module module = facet.getModule();
   final AtomicReference<PsiElement> openAfter = new AtomicReference<PsiElement>();
   final WriteCommandAction<Void> action =
       new WriteCommandAction<Void>(
           facet.getModule().getProject(), "Override Resource " + resName, file) {
         @Override
         protected void run(@NotNull Result<Void> result) {
           List<ResourceElement> elements = Lists.newArrayListWithExpectedSize(1);
           // AndroidResourceUtil.createValueResource will create a new resource value in the given
           // resource
           // folder (and record the corresponding tags added in the elements list passed into it).
           // However, it only creates a new element and sets the name attribute on it; it does not
           // transfer attributes, child content etc. Therefore, we use this utility method first
           // to
           // create the corresponding tag, and then *afterwards* we will replace the tag with a
           // text copy
           // from the resource tag we are overriding. We do this all under a single write lock
           // such
           // that it becomes a single atomic operation.
           AndroidResourceUtil.createValueResource(
               module, resName, type, filename, dirNames, value, elements);
           if (elements.size() == 1) {
             final XmlTag tag = elements.get(0).getXmlTag();
             if (tag != null && tag.isValid()) {
               try {
                 XmlTag tagFromText =
                     XmlElementFactory.getInstance(tag.getProject()).createTagFromText(oldTagText);
                 PsiElement replaced = tag.replace(tagFromText);
                 openAfter.set(replaced);
               } catch (IncorrectOperationException e) {
                 // The user tried to override an invalid XML fragment: don't attempt to do a
                 // replacement in that case
                 openAfter.set(tag);
               }
             }
           }
         }
       };
   action.execute();
   PsiElement tag = openAfter.get();
   if (tag != null) {
     NavigationUtil.openFileWithPsiElement(tag, true, true);
   }
 }
  // returns true if processor is run or is going to be run after showing popup
  public static boolean chooseAmbiguousTarget(
      @NotNull Editor editor,
      int offset,
      @NotNull PsiElementProcessor<PsiElement> processor,
      @NotNull String titlePattern,
      @Nullable PsiElement[] elements) {
    if (TargetElementUtil.inVirtualSpace(editor, offset)) {
      return false;
    }

    final PsiReference reference = TargetElementUtil.findReference(editor, offset);

    if (elements == null || elements.length == 0) {
      elements =
          reference == null
              ? PsiElement.EMPTY_ARRAY
              : PsiUtilCore.toPsiElementArray(
                  underModalProgress(
                      reference.getElement().getProject(),
                      "Resolving Reference...",
                      () -> suggestCandidates(reference)));
    }

    if (elements.length == 1) {
      PsiElement element = elements[0];
      LOG.assertTrue(element != null);
      processor.execute(element);
      return true;
    }
    if (elements.length > 1) {
      String title;

      if (reference == null) {
        title = titlePattern;
      } else {
        final TextRange range = reference.getRangeInElement();
        final String elementText = reference.getElement().getText();
        LOG.assertTrue(
            range.getStartOffset() >= 0 && range.getEndOffset() <= elementText.length(),
            Arrays.toString(elements) + ";" + reference);
        final String refText = range.substring(elementText);
        title = MessageFormat.format(titlePattern, refText);
      }

      NavigationUtil.getPsiElementPopup(
              elements, new DefaultPsiElementCellRenderer(), title, processor)
          .showInBestPositionFor(editor);
      return true;
    }
    return false;
  }
  public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) {
    boolean tempIsStatic = myIsConstant;
    PsiElement parent = local.getParent();
    List<PsiClass> classes = new ArrayList<PsiClass>();
    while (parent != null && parent.getContainingFile() != null) {
      if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) {
        classes.add((PsiClass) parent);
      }
      if (parent instanceof PsiFile && FileTypeUtils.isInServerPageFile(parent)) {
        String message = RefactoringBundle.message("error.not.supported.for.jsp", REFACTORING_NAME);
        CommonRefactoringUtil.showErrorHint(
            myProject, editor, message, REFACTORING_NAME, HelpID.LOCAL_TO_FIELD);
        return false;
      }
      if (parent instanceof PsiModifierListOwner
          && ((PsiModifierListOwner) parent).hasModifierProperty(PsiModifier.STATIC)) {
        tempIsStatic = true;
      }
      parent = parent.getParent();
    }

    if (classes.isEmpty()) return false;
    final AbstractInplaceIntroducer activeIntroducer =
        AbstractInplaceIntroducer.getActiveIntroducer(editor);
    final boolean shouldSuggestDialog =
        activeIntroducer instanceof InplaceIntroduceConstantPopup
            && activeIntroducer.startsOnTheSameElement(null, local);
    if (classes.size() == 1
        || ApplicationManager.getApplication().isUnitTestMode()
        || shouldSuggestDialog) {
      if (convertLocalToField(
          local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic)) return false;
    } else {
      final boolean isStatic = tempIsStatic;
      NavigationUtil.getPsiElementPopup(
              classes.toArray(new PsiClass[classes.size()]),
              new PsiClassListCellRenderer(),
              "Choose class to introduce " + (myIsConstant ? "constant" : "field"),
              new PsiElementProcessor<PsiClass>() {
                @Override
                public boolean execute(@NotNull PsiClass aClass) {
                  convertLocalToField(local, aClass, editor, isStatic);
                  return false;
                }
              })
          .showInBestPositionFor(editor);
    }

    return true;
  }
  public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) {
    final Collection<JSQualifiedNamedElement> candidates = getCandidates(editor, file);

    if (candidates.isEmpty() || myUnambiguousTheFlyMode && candidates.size() != 1) {
      return;
    }

    if (candidates.size() > 1) {
      NavigationUtil.getPsiElementPopup(
              candidates.toArray(new JSQualifiedNamedElement[candidates.size()]),
              new JSQualifiedNamedElementRenderer(),
              JSBundle.message("choose.class.to.import.title"),
              new PsiElementProcessor<JSQualifiedNamedElement>() {
                public boolean execute(@NotNull final JSQualifiedNamedElement element) {
                  CommandProcessor.getInstance()
                      .executeCommand(
                          project,
                          () -> doImport(element.getQualifiedName()),
                          "Import " + element.getQualifiedName(),
                          this);

                  return false;
                }
              })
          .showInBestPositionFor(editor);
    } else {
      final JSQualifiedNamedElement element = candidates.iterator().next();
      if (myUnambiguousTheFlyMode) {
        CommandProcessor.getInstance()
            .runUndoTransparentAction(() -> doImport(element.getQualifiedName()));
      } else {
        CommandProcessor.getInstance()
            .executeCommand(
                project,
                () -> doImport(element.getQualifiedName()),
                "Import " + element.getQualifiedName(),
                this);
      }
    }
  }