private static TextChange addTextEditFromRewrite(
     TextChangeManager manager, ICompilationUnit cu, ASTRewrite rewrite) throws CoreException {
   try {
     ITextFileBuffer buffer = RefactoringFileBuffers.acquire(cu);
     TextEdit resultingEdits =
         rewrite.rewriteAST(buffer.getDocument(), cu.getJavaProject().getOptions(true));
     TextChange textChange = manager.get(cu);
     if (textChange instanceof TextFileChange) {
       TextFileChange tfc = (TextFileChange) textChange;
       tfc.setSaveMode(TextFileChange.KEEP_SAVE_STATE);
     }
     String message = RefactoringCoreMessages.DeleteChangeCreator_1;
     TextChangeCompatibility.addTextEdit(textChange, message, resultingEdits);
     return textChange;
   } finally {
     RefactoringFileBuffers.release(cu);
   }
 }
 public Change createChange(IProgressMonitor pm) throws CoreException {
   if (fDeleteSource && fCurrentMode == Mode.INLINE_ALL) {
     TextChange change = fChangeManager.get((ICompilationUnit) fSourceProvider.getTypeRoot());
     TextEdit delete = fSourceProvider.getDeleteEdit();
     TextEditGroup description =
         new TextEditGroup(
             RefactoringCoreMessages.InlineMethodRefactoring_edit_delete, new TextEdit[] {delete});
     TextEdit root = change.getEdit();
     if (root != null) {
       // TODO instead of finding the right insert position the call inliner should
       // reuse the AST & rewriter of the source provide and we should rewrite the
       // whole AST at the end. However, since recursive calls aren't allowed there
       // shouldn't be a text edit overlap.
       // root.addChild(delete);
       TextChangeCompatibility.insert(root, delete);
     } else {
       change.setEdit(delete);
     }
     change.addTextEditGroup(description);
   }
   final Map arguments = new HashMap();
   String project = null;
   IJavaProject javaProject = fInitialTypeRoot.getJavaProject();
   if (javaProject != null) project = javaProject.getElementName();
   int flags =
       RefactoringDescriptor.STRUCTURAL_CHANGE
           | JavaRefactoringDescriptor.JAR_REFACTORING
           | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
   final IMethodBinding binding = fSourceProvider.getDeclaration().resolveBinding();
   final ITypeBinding declaring = binding.getDeclaringClass();
   if (!Modifier.isPrivate(binding.getModifiers())) flags |= RefactoringDescriptor.MULTI_CHANGE;
   final String description =
       Messages.format(
           RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description_short,
           BasicElementLabels.getJavaElementName(binding.getName()));
   final String header =
       Messages.format(
           RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description,
           new String[] {
             BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED),
             BindingLabelProvider.getBindingLabel(declaring, JavaElementLabels.ALL_FULLY_QUALIFIED)
           });
   final JDTRefactoringDescriptorComment comment =
       new JDTRefactoringDescriptorComment(project, this, header);
   comment.addSetting(
       Messages.format(
           RefactoringCoreMessages.InlineMethodRefactoring_original_pattern,
           BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED)));
   if (fDeleteSource)
     comment.addSetting(RefactoringCoreMessages.InlineMethodRefactoring_remove_method);
   if (fCurrentMode == Mode.INLINE_ALL)
     comment.addSetting(RefactoringCoreMessages.InlineMethodRefactoring_replace_references);
   final InlineMethodDescriptor descriptor =
       RefactoringSignatureDescriptorFactory.createInlineMethodDescriptor(
           project, description, comment.asString(), arguments, flags);
   arguments.put(
       JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT,
       JavaRefactoringDescriptorUtil.elementToHandle(project, fInitialTypeRoot));
   arguments.put(
       JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION,
       new Integer(fSelectionStart).toString()
           + " "
           + new Integer(fSelectionLength).toString()); // $NON-NLS-1$
   arguments.put(ATTRIBUTE_DELETE, Boolean.valueOf(fDeleteSource).toString());
   arguments.put(ATTRIBUTE_MODE, new Integer(fCurrentMode == Mode.INLINE_ALL ? 1 : 0).toString());
   return new DynamicValidationRefactoringChange(
       descriptor,
       RefactoringCoreMessages.InlineMethodRefactoring_edit_inlineCall,
       fChangeManager.getAllChanges());
 }
  public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
    pm.beginTask("", 20); // $NON-NLS-1$
    fChangeManager = new TextChangeManager();
    RefactoringStatus result = new RefactoringStatus();
    fSourceProvider.initialize();
    fTargetProvider.initialize();

    pm.setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_searching);
    RefactoringStatus searchStatus = new RefactoringStatus();
    String binaryRefsDescription =
        Messages.format(
            RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description,
            BasicElementLabels.getJavaElementName(fSourceProvider.getMethodName()));
    ReferencesInBinaryContext binaryRefs = new ReferencesInBinaryContext(binaryRefsDescription);
    ICompilationUnit[] units =
        fTargetProvider.getAffectedCompilationUnits(
            searchStatus, binaryRefs, new SubProgressMonitor(pm, 1));
    binaryRefs.addErrorIfNecessary(searchStatus);
    if (searchStatus.hasFatalError()) {
      result.merge(searchStatus);
      return result;
    }

    IFile[] filesToBeModified = getFilesToBeModified(units);
    result.merge(Checks.validateModifiesFiles(filesToBeModified, getValidationContext()));
    if (result.hasFatalError()) return result;
    result.merge(
        ResourceChangeChecker.checkFilesToBeChanged(
            filesToBeModified, new SubProgressMonitor(pm, 1)));
    checkOverridden(result, new SubProgressMonitor(pm, 4));
    IProgressMonitor sub = new SubProgressMonitor(pm, 15);
    sub.beginTask("", units.length * 3); // $NON-NLS-1$
    for (int c = 0; c < units.length; c++) {
      ICompilationUnit unit = units[c];
      sub.subTask(
          Messages.format(
              RefactoringCoreMessages.InlineMethodRefactoring_processing,
              BasicElementLabels.getFileName(unit)));
      CallInliner inliner = null;
      try {
        boolean added = false;
        MultiTextEdit root = new MultiTextEdit();
        CompilationUnitChange change = (CompilationUnitChange) fChangeManager.get(unit);
        change.setEdit(root);
        BodyDeclaration[] bodies =
            fTargetProvider.getAffectedBodyDeclarations(unit, new SubProgressMonitor(pm, 1));
        if (bodies.length == 0) continue;
        inliner = new CallInliner(unit, (CompilationUnit) bodies[0].getRoot(), fSourceProvider);
        for (int b = 0; b < bodies.length; b++) {
          BodyDeclaration body = bodies[b];
          inliner.initialize(body);
          RefactoringStatus nestedInvocations = new RefactoringStatus();
          ASTNode[] invocations =
              removeNestedCalls(
                  nestedInvocations,
                  unit,
                  fTargetProvider.getInvocations(body, new SubProgressMonitor(sub, 2)));
          for (int i = 0; i < invocations.length; i++) {
            ASTNode invocation = invocations[i];
            result.merge(inliner.initialize(invocation, fTargetProvider.getStatusSeverity()));
            if (result.hasFatalError()) break;
            if (result.getSeverity() < fTargetProvider.getStatusSeverity()) {
              added = true;
              TextEditGroup group =
                  new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_inline);
              change.addTextEditGroup(group);
              result.merge(inliner.perform(group));
            } else {
              fDeleteSource = false;
            }
          }
          // do this after we have inlined the method calls. We still want
          // to generate the modifications.
          if (!nestedInvocations.isOK()) {
            result.merge(nestedInvocations);
            fDeleteSource = false;
          }
        }
        if (!added) {
          fChangeManager.remove(unit);
        } else {
          root.addChild(inliner.getModifications());
          ImportRewrite rewrite = inliner.getImportEdit();
          if (rewrite.hasRecordedChanges()) {
            TextEdit edit = rewrite.rewriteImports(null);
            if (edit instanceof MultiTextEdit
                ? ((MultiTextEdit) edit).getChildrenSize() > 0
                : true) {
              root.addChild(edit);
              change.addTextEditGroup(
                  new TextEditGroup(
                      RefactoringCoreMessages.InlineMethodRefactoring_edit_import,
                      new TextEdit[] {edit}));
            }
          }
        }
      } finally {
        if (inliner != null) inliner.dispose();
      }
      sub.worked(1);
      if (sub.isCanceled()) throw new OperationCanceledException();
    }
    result.merge(searchStatus);
    sub.done();
    pm.done();
    return result;
  }