/**
  * Creates a compilation unit change based on the events recorded by this compilation unit
  * rewrite.
  *
  * @param name the name of the change to create
  * @param generateGroups <code>true</code> to generate text edit groups, <code>false</code>
  *     otherwise
  * @param monitor the progress monitor or <code>null</code>
  * @return a {@link CompilationUnitChange}, or <code>null</code> for an empty change
  * @throws CoreException when text buffer acquisition or import rewrite text edit creation fails
  * @throws IllegalArgumentException when the AST rewrite encounters problems
  */
 public CompilationUnitChange createChange(String name, boolean generateGroups)
     throws CoreException {
   CompilationUnitChange cuChange = new CompilationUnitChange(name, document);
   MultiTextEdit multiEdit = new MultiTextEdit();
   cuChange.setEdit(multiEdit);
   return attachChange(cuChange, generateGroups);
 }
  /**
   * Attaches the changes of this compilation unit rewrite to the given CU Change. The given change
   * <b>must</b> either have no root edit, or a MultiTextEdit as a root edit. The edits in the given
   * change <b>must not</b> overlap with the changes of this compilation unit.
   *
   * @param cuChange existing CompilationUnitChange with a MultiTextEdit root or no root at all.
   * @param generateGroups <code>true</code> to generate text edit groups, <code>false</code>
   *     otherwise
   * @param monitor the progress monitor or <code>null</code>
   * @return a change combining the changes of this rewrite and the given rewrite, or <code>null
   *     </code> for an empty change
   * @throws CoreException when text buffer acquisition or import rewrite text edit creation fails
   */
  public CompilationUnitChange attachChange(CompilationUnitChange cuChange, boolean generateGroups)
      throws CoreException {
    boolean needsAstRewrite =
        fRewrite != null; // TODO: do we need something like ASTRewrite#hasChanges() here?
    boolean needsImportRemoval = fImportRemover != null && fImportRemover.hasRemovedNodes();
    boolean needsImportRewrite =
        fImportRewrite != null && fImportRewrite.hasRecordedChanges() || needsImportRemoval;
    if (!needsAstRewrite && !needsImportRemoval && !needsImportRewrite) return null;

    MultiTextEdit multiEdit = (MultiTextEdit) cuChange.getEdit();
    if (multiEdit == null) {
      multiEdit = new MultiTextEdit();
      cuChange.setEdit(multiEdit);
    }

    if (needsAstRewrite) {
      TextEdit rewriteEdit;
      if (fRememberContent != null) {
        rewriteEdit =
            fRewrite.rewriteAST(fRememberContent, WorkerMessageHandler.get().getOptions());
      } else {
        rewriteEdit = fRewrite.rewriteAST(document, WorkerMessageHandler.get().getOptions());
      }
      if (!isEmptyEdit(rewriteEdit)) {
        multiEdit.addChild(rewriteEdit);
        if (generateGroups) {
          for (Iterator<TextEditGroup> iter = fTextEditGroups.iterator(); iter.hasNext(); ) {
            TextEditGroup group = iter.next();
            cuChange.addTextEditGroup(group);
          }
        }
      }
    }
    if (needsImportRemoval) {
      fImportRemover.applyRemoves(getImportRewrite());
    }
    if (needsImportRewrite) {
      TextEdit importsEdit = fImportRewrite.rewriteImports();
      if (!isEmptyEdit(importsEdit)) {
        multiEdit.addChild(importsEdit);
        String importUpdateName = RefactoringCoreMessages.INSTANCE.ASTData_update_imports();
        cuChange.addTextEditGroup(new TextEditGroup(importUpdateName, importsEdit));
      }
    } else {

    }
    if (isEmptyEdit(multiEdit)) return null;
    return cuChange;
  }