/**
   * Creates a new search scope with all compilation units possibly referencing <code>javaElement
   * </code>.
   *
   * @param javaElement the java element
   * @param considerVisibility consider visibility of javaElement iff <code>true</code>
   * @param sourceReferencesOnly consider references in source only (no references in binary)
   * @return the search scope
   * @throws JavaModelException if an error occurs
   */
  public static IJavaSearchScope create(
      IJavaElement javaElement, boolean considerVisibility, boolean sourceReferencesOnly)
      throws JavaModelException {
    if (considerVisibility & javaElement instanceof IMember) {
      IMember member = (IMember) javaElement;
      if (JdtFlags.isPrivate(member)) {
        if (member.getCompilationUnit() != null)
          return SearchEngine.createJavaSearchScope(
              new IJavaElement[] {member.getCompilationUnit()});
        else return SearchEngine.createJavaSearchScope(new IJavaElement[] {member});
      }
      // Removed code that does some optimizations regarding package visible members. The problem is
      // that
      // there can be a package fragment with the same name in a different source folder or project.
      // So we
      // have to treat package visible members like public or protected members.
    }

    IJavaProject javaProject = javaElement.getJavaProject();
    return SearchEngine.createJavaSearchScope(
        getAllScopeElements(javaProject, sourceReferencesOnly), false);
  }
 @Override
 public void run(IStructuredSelection selection) {
   try {
     IMember member = getMember(selection);
     if (member == null || !ActionUtil.isEditable(getShell(), member)) return;
     ISourceRange range = member.getNameRange();
     RefactoringExecutionStarter.startChangeTypeRefactoring(
         member.getCompilationUnit(), getShell(), range.getOffset(), range.getLength());
   } catch (CoreException e) {
     ExceptionHandler.handle(
         e,
         RefactoringMessages.ChangeTypeAction_dialog_title,
         RefactoringMessages.ChangeTypeAction_exception);
   }
 }
  public void run(ISelection selection) {

    String errorTitle = CompareMessages.AddFromHistory_title;
    String errorMessage = CompareMessages.AddFromHistory_internalErrorMessage;
    Shell shell = getShell();

    ICompilationUnit cu = null;
    IParent parent = null;
    IMember input = null;

    // analyze selection
    if (selection.isEmpty()) {
      // no selection: we try to use the editor's input
      JavaEditor editor = getEditor();
      if (editor != null) {
        IEditorInput editorInput = editor.getEditorInput();
        IWorkingCopyManager manager = JavaPlugin.getDefault().getWorkingCopyManager();
        if (manager != null) {
          cu = manager.getWorkingCopy(editorInput);
          parent = cu;
        }
      }
    } else {
      input = getEditionElement(selection);
      if (input != null) {
        cu = input.getCompilationUnit();
        parent = input;
        input = null;

      } else {
        if (selection instanceof IStructuredSelection) {
          Object o = ((IStructuredSelection) selection).getFirstElement();
          if (o instanceof ICompilationUnit) {
            cu = (ICompilationUnit) o;
            parent = cu;
          }
        }
      }
    }

    if (parent == null || cu == null) {
      String invalidSelectionMessage = CompareMessages.AddFromHistory_invalidSelectionMessage;
      MessageDialog.openInformation(shell, errorTitle, invalidSelectionMessage);
      return;
    }

    IFile file = getFile(parent);
    if (file == null) {
      MessageDialog.openError(shell, errorTitle, errorMessage);
      return;
    }

    boolean inEditor = beingEdited(file);

    IStatus status = Resources.makeCommittable(file, shell);
    if (!status.isOK()) {
      return;
    }

    // get the document where to insert the text
    IPath path = file.getFullPath();
    ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager();
    ITextFileBuffer textFileBuffer = null;
    try {
      bufferManager.connect(path, LocationKind.IFILE, null);
      textFileBuffer = bufferManager.getTextFileBuffer(path, LocationKind.IFILE);
      IDocument document = textFileBuffer.getDocument();

      // configure EditionSelectionDialog and let user select an edition
      ITypedElement target = new JavaTextBufferNode(file, document, inEditor);
      ITypedElement[] editions = buildEditions(target, file);

      ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME);
      EditionSelectionDialog d = new EditionSelectionDialog(shell, bundle);
      d.setAddMode(true);
      d.setHelpContextId(IJavaHelpContextIds.ADD_ELEMENT_FROM_HISTORY_DIALOG);
      ITypedElement selected = d.selectEdition(target, editions, parent);
      if (selected == null) return; // user cancel

      ICompilationUnit cu2 = cu;
      if (parent instanceof IMember) cu2 = ((IMember) parent).getCompilationUnit();

      CompilationUnit root = parsePartialCompilationUnit(cu2);
      ASTRewrite rewriter = ASTRewrite.create(root.getAST());

      ITypedElement[] results = d.getSelection();
      for (int i = 0; i < results.length; i++) {

        // create an AST node
        ASTNode newNode =
            createASTNode(
                rewriter,
                results[i],
                TextUtilities.getDefaultLineDelimiter(document),
                cu.getJavaProject());
        if (newNode == null) {
          MessageDialog.openError(shell, errorTitle, errorMessage);
          return;
        }

        // now determine where to put the new node
        if (newNode instanceof PackageDeclaration) {
          rewriter.set(root, CompilationUnit.PACKAGE_PROPERTY, newNode, null);

        } else if (newNode instanceof ImportDeclaration) {
          ListRewrite lw = rewriter.getListRewrite(root, CompilationUnit.IMPORTS_PROPERTY);
          lw.insertFirst(newNode, null);

        } else { // class, interface, enum, annotation, method, field

          if (parent instanceof ICompilationUnit) { // top level
            ListRewrite lw = rewriter.getListRewrite(root, CompilationUnit.TYPES_PROPERTY);
            int index = ASTNodes.getInsertionIndex((BodyDeclaration) newNode, root.types());
            lw.insertAt(newNode, index, null);

          } else if (parent instanceof IType) {
            ASTNode declaration = getBodyContainer(root, (IType) parent);
            if (declaration instanceof TypeDeclaration
                || declaration instanceof AnnotationTypeDeclaration) {
              List container = ASTNodes.getBodyDeclarations(declaration);
              int index = ASTNodes.getInsertionIndex((BodyDeclaration) newNode, container);
              ListRewrite lw =
                  rewriter.getListRewrite(
                      declaration, ASTNodes.getBodyDeclarationsProperty(declaration));
              lw.insertAt(newNode, index, null);
            } else if (declaration instanceof EnumDeclaration) {
              List container = ((EnumDeclaration) declaration).enumConstants();
              int index = ASTNodes.getInsertionIndex((FieldDeclaration) newNode, container);
              ListRewrite lw =
                  rewriter.getListRewrite(declaration, EnumDeclaration.ENUM_CONSTANTS_PROPERTY);
              lw.insertAt(newNode, index, null);
            }
          } else {
            JavaPlugin.logErrorMessage(
                "JavaAddElementFromHistoryImpl: unknown container " + parent); // $NON-NLS-1$
          }
        }
      }

      Map options = null;
      IJavaProject javaProject = cu2.getJavaProject();
      if (javaProject != null) options = javaProject.getOptions(true);
      applyChanges(rewriter, document, textFileBuffer, shell, inEditor, options);

    } catch (InvocationTargetException ex) {
      ExceptionHandler.handle(ex, shell, errorTitle, errorMessage);

    } catch (InterruptedException ex) {
      // shouldn't be called because is not cancelable
      Assert.isTrue(false);

    } catch (CoreException ex) {
      ExceptionHandler.handle(ex, shell, errorTitle, errorMessage);

    } finally {
      try {
        if (textFileBuffer != null) bufferManager.disconnect(path, LocationKind.IFILE, null);
      } catch (CoreException e) {
        JavaPlugin.log(e);
      }
    }
  }