/* (non-Javadoc)
   * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext)
   */
  public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context)
      throws CoreException, OperationCanceledException {
    pm.beginTask("", 1); // $NON-NLS-1$
    try {
      RefactoringStatus result = new RefactoringStatus();

      for (int i = 0; i < fResources.length; i++) {
        IResource resource = fResources[i];
        if (!resource.isSynchronized(IResource.DEPTH_INFINITE)) {
          if (resource instanceof IFile) {
            result.addInfo(
                Messages.format(
                    RefactoringCoreMessages.DeleteResourcesProcessor_warning_out_of_sync_file,
                    BasicElementLabels.getPathLabel(resource.getFullPath(), false)));
          } else {
            result.addInfo(
                Messages.format(
                    RefactoringCoreMessages.DeleteResourcesProcessor_warning_out_of_sync_container,
                    BasicElementLabels.getPathLabel(resource.getFullPath(), false)));
          }
        }
      }

      checkDirtyResources(result);

      ResourceChangeChecker checker =
          (ResourceChangeChecker) context.getChecker(ResourceChangeChecker.class);
      IResourceChangeDescriptionFactory deltaFactory = checker.getDeltaFactory();
      for (int i = 0; i < fResources.length; i++) {
        if (fResources[i].isPhantom()) {
          result.addFatalError(
              Messages.format(
                  RefactoringCoreMessages.DeleteResourcesProcessor_delete_error_phantom,
                  BasicElementLabels.getPathLabel(fResources[i].getFullPath(), false)));
        } else if (fDeleteContents && Resources.isReadOnly(fResources[i])) {
          result.addFatalError(
              Messages.format(
                  RefactoringCoreMessages.DeleteResourcesProcessor_delete_error_read_only,
                  BasicElementLabels.getPathLabel(fResources[i].getFullPath(), false)));
        } else {
          deltaFactory.delete(fResources[i]);
        }
      }
      return result;
    } finally {
      pm.done();
    }
  }
  @SuppressWarnings({"unchecked"})
  @Override
  public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
      throws CoreException, OperationCanceledException {
    RefactoringStatus result = new RefactoringStatus();
    fChangeManager.clear();
    pm.beginTask("", 12);
    pm.setTaskName("Convert to AtomicInteger checking preconditions");
    pm.worked(1);
    if (result.hasFatalError()) return result;
    pm.setTaskName("ConvertToAtomicInteger searching for cunits");
    final SubProgressMonitor subPm = new SubProgressMonitor(pm, 5);
    ICompilationUnit[] affectedCUs =
        RefactoringSearchEngine.findAffectedCompilationUnits(
            SearchPattern.createPattern(targetClass, IJavaSearchConstants.ALL_OCCURRENCES),
            RefactoringScopeFactory.create(targetClass, true),
            subPm,
            result,
            true);

    if (result.hasFatalError()) return result;

    pm.setTaskName("Analyzing the field");
    IProgressMonitor sub = new SubProgressMonitor(pm, 5);
    sub.beginTask("", affectedCUs.length);

    List ownerDescriptions = new ArrayList();
    ICompilationUnit owner = targetClass.getCompilationUnit();

    for (int i = 0; i < affectedCUs.length; i++) {
      ICompilationUnit unit = affectedCUs[i];
      sub.subTask(unit.getElementName());
      CompilationUnit root = null;
      ASTRewrite rewriter = null;
      List descriptions;
      if (owner.equals(unit)) {
        root = fRoot;
        rewriter = fRewriter;
        descriptions = ownerDescriptions;
      } else {
        root = new RefactoringASTParser(AST.JLS3).parse(unit, true);
        rewriter = ASTRewrite.create(root.getAST());
        descriptions = new ArrayList();
      }
      checkCompileErrors(result, root, unit);

      // We will perform a different set of analysis and rewrites for the compilation unit
      // containing the
      // target class and other compilation units
      if (owner.equals(unit)) {

        // Analysis passes
        ClassMutatorAnalysis mutatorAnalysis = new ClassMutatorAnalysis(targetClass, pm);
        mutatorAnalysis.findMutators();

        ClassConstructorAnalysis constructorAnalysis =
            new ClassConstructorAnalysis(targetClassDeclaration);
        targetClassDeclaration.accept(constructorAnalysis);

        // Rewrite pass
        MakeClassImmutableRewriter immutableRewriter =
            new MakeClassImmutableRewriter(this, unit, rewriter);
        immutableRewriter.rewrite(targetClassDeclaration, mutatorAnalysis, constructorAnalysis);

        result.merge(immutableRewriter.getStatus());
        if (result.hasFatalError()) {
          fChangeManager.clear();
          return result;
        }
      } else {

        // descriptions.addAll(immutableRewriter.getGroupDescriptions());
        createEdits(unit, rewriter, descriptions);
      }

      sub.worked(1);
      if (pm.isCanceled()) throw new OperationCanceledException();
    }

    createEdits(owner, fRewriter, ownerDescriptions);

    sub.done();
    IFile[] filesToBeModified = ResourceUtil.getFiles(fChangeManager.getAllCompilationUnits());
    result.merge(Checks.validateModifiesFiles(filesToBeModified, getValidationContext()));
    if (result.hasFatalError()) return result;
    ResourceChangeChecker.checkFilesToBeChanged(filesToBeModified, new SubProgressMonitor(pm, 1));
    return result;
  }
  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;
  }