/** Renames the main type in <code>cu</code>. */
 private void updateTypeName(
     ICompilationUnit cu,
     CompilationUnit astCU,
     String oldName,
     String newName,
     ASTRewrite rewriter)
     throws JavaModelException {
   if (newName != null) {
     String oldTypeName = Util.getNameWithoutJavaLikeExtension(oldName);
     String newTypeName = Util.getNameWithoutJavaLikeExtension(newName);
     AST ast = astCU.getAST();
     // update main type name
     IType[] types = cu.getTypes();
     for (int i = 0, max = types.length; i < max; i++) {
       IType currentType = types[i];
       if (currentType.getElementName().equals(oldTypeName)) {
         AbstractTypeDeclaration typeNode =
             (AbstractTypeDeclaration) ((JavaElement) currentType).findNode(astCU);
         if (typeNode != null) {
           // rename type
           rewriter.replace(typeNode.getName(), ast.newSimpleName(newTypeName), null);
           // rename constructors
           Iterator bodyDeclarations = typeNode.bodyDeclarations().iterator();
           while (bodyDeclarations.hasNext()) {
             Object bodyDeclaration = bodyDeclarations.next();
             if (bodyDeclaration instanceof MethodDeclaration) {
               MethodDeclaration methodDeclaration = (MethodDeclaration) bodyDeclaration;
               if (methodDeclaration.isConstructor()) {
                 SimpleName methodName = methodDeclaration.getName();
                 if (methodName.getIdentifier().equals(oldTypeName)) {
                   rewriter.replace(methodName, ast.newSimpleName(newTypeName), null);
                 }
               }
             }
           }
         }
       }
     }
   }
 }
  /**
   * Copies/moves a compilation unit with the name <code>newCUName</code> to the destination
   * package.<br>
   * The package statement in the compilation unit is updated if necessary. The main type of the
   * compilation unit is renamed if necessary.
   *
   * @exception JavaModelException if the operation is unable to complete
   */
  private void processCompilationUnitResource(ICompilationUnit source, PackageFragment dest)
      throws JavaModelException {
    String newCUName = getNewNameFor(source);
    String destName = (newCUName != null) ? newCUName : source.getElementName();
    TextEdit edit = updateContent(source, dest, newCUName); // null if unchanged

    // TODO (frederic) remove when bug 67606 will be fixed (bug 67823)
    // store encoding (fix bug 66898)
    IFile sourceResource = (IFile) source.getResource();
    String sourceEncoding = null;
    try {
      sourceEncoding = sourceResource.getCharset(false);
    } catch (CoreException ce) {
      // no problem, use default encoding
    }
    // end todo
    // copy resource
    IContainer destFolder = (IContainer) dest.getResource(); // can be an IFolder or an IProject
    IFile destFile = destFolder.getFile(new Path(destName));
    org.eclipse.jdt.internal.core.CompilationUnit destCU =
        new org.eclipse.jdt.internal.core.CompilationUnit(
            dest, destName, DefaultWorkingCopyOwner.PRIMARY);
    if (!destFile.equals(sourceResource)) {
      try {
        if (!destCU.isWorkingCopy()) {
          if (destFile.exists()) {
            if (this.force) {
              // we can remove it
              deleteResource(destFile, IResource.KEEP_HISTORY);
              destCU.close(); // ensure the in-memory buffer for the dest CU is closed
            } else {
              // abort
              throw new JavaModelException(
                  new JavaModelStatus(
                      IJavaModelStatusConstants.NAME_COLLISION,
                      Messages.bind(
                          Messages.status_nameCollision, destFile.getFullPath().toString())));
            }
          }
          int flags = this.force ? IResource.FORCE : IResource.NONE;
          if (isMove()) {
            flags |= IResource.KEEP_HISTORY;
            sourceResource.move(destFile.getFullPath(), flags, getSubProgressMonitor(1));
          } else {
            if (edit != null) flags |= IResource.KEEP_HISTORY;
            sourceResource.copy(destFile.getFullPath(), flags, getSubProgressMonitor(1));
          }
          setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
        } else {
          destCU.getBuffer().setContents(source.getBuffer().getContents());
        }
      } catch (JavaModelException e) {
        throw e;
      } catch (CoreException e) {
        throw new JavaModelException(e);
      }

      // update new resource content
      if (edit != null) {
        boolean wasReadOnly = destFile.isReadOnly();
        try {
          saveContent(dest, destName, edit, sourceEncoding, destFile);
        } catch (CoreException e) {
          if (e instanceof JavaModelException) throw (JavaModelException) e;
          throw new JavaModelException(e);
        } finally {
          Util.setReadOnly(destFile, wasReadOnly);
        }
      }

      // register the correct change deltas
      prepareDeltas(source, destCU, isMove());
      if (newCUName != null) {
        // the main type has been renamed
        String oldName = Util.getNameWithoutJavaLikeExtension(source.getElementName());
        String newName = Util.getNameWithoutJavaLikeExtension(newCUName);
        prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove());
      }
    } else {
      if (!this.force) {
        throw new JavaModelException(
            new JavaModelStatus(
                IJavaModelStatusConstants.NAME_COLLISION,
                Messages.bind(Messages.status_nameCollision, destFile.getFullPath().toString())));
      }
      // update new resource content
      // in case we do a saveas on the same resource we have to simply update the contents
      // see http://dev.eclipse.org/bugs/show_bug.cgi?id=9351
      if (edit != null) {
        saveContent(dest, destName, edit, sourceEncoding, destFile);
      }
    }
  }