@Override
 public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
   CompositeChange change = new CompositeChange(getName());
   ArrayList<IModule> tmpList;
   IServer[] allServers = ServerCore.getServers();
   for (int i = 0; i < allServers.length; i++) {
     IModule[] serversMods = allServers[i].getModules();
     tmpList = new ArrayList<IModule>();
     for (int j = 0; j < serversMods.length; j++) {
       if (serversMods[j].getProject() != null
           && serversMods[j].getProject().equals(projectToDelete)) {
         tmpList.add(serversMods[j]);
       }
     }
     IModule[] modsToRemove = tmpList.toArray(new IModule[tmpList.size()]);
     // If modsToRemove is empty, that means that the server does not have the affected project
     // deployed, or
     // the affected project is not a top-level module (for example, and EAR, or stand-alone WAR),
     // but we
     // need to check if the affected project is a child of a top-level module.
     if (modsToRemove.length > 0)
       change.add(new RemoveProjectFromServersChange(modsToRemove, allServers[i]));
     else if (hasParentInServer(projectToDelete, allServers[i], pm)) {
       change.add(new RefreshServerChange(allServers[i]));
     }
   }
   return change;
 }
  private static Change createPackageFragmentRootDeleteChange(IPackageFragmentRoot root)
      throws JavaModelException {
    IResource resource = root.getResource();
    if (resource != null && resource.isLinked()) {
      // XXX using this code is a workaround for jcore bug 31998
      // jcore cannot handle linked stuff
      // normally, we should always create DeletePackageFragmentRootChange
      CompositeChange composite =
          new DynamicValidationStateChange(
              RefactoringCoreMessages.DeleteRefactoring_delete_package_fragment_root);

      ClasspathChange change =
          ClasspathChange.removeEntryChange(root.getJavaProject(), root.getRawClasspathEntry());
      if (change != null) {
        composite.add(change);
      }
      Assert.isTrue(!Checks.isClasspathDelete(root)); // checked in preconditions
      composite.add(createDeleteChange(resource));

      return composite;
    } else {
      Assert.isTrue(!root.isExternal());
      // TODO remove the query argument
      return new DeletePackageFragmentRootChange(root, true, null);
    }
  }
  /* (non-Javadoc)
   * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#createChange(org.eclipse.core.runtime.IProgressMonitor)
   */
  public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    CompositeChange change = new CompositeChange(new String());
    change.markAsSynthetic();
    change.add(new ConnectionProfileRenameChange(mProfile, mArguments));

    return change;
  }
 public static void refactorProjectImportsAndDocLinks(
     Tree.Declaration node,
     IFile originalFile,
     IFile targetFile,
     CompositeChange change,
     String originalPackage,
     String targetPackage) {
   if (!originalPackage.equals(targetPackage)) {
     for (PhasedUnit pu : getAllUnits(originalFile.getProject())) {
       //                if (!node.getUnit().equals(pu.getUnit())) {
       IFile file = ((IFileVirtualFile) pu.getUnitFile()).getFile();
       if (!file.equals(originalFile) && !file.equals(targetFile)) {
         TextFileChange tfc = new TextFileChange("Fix Import", file);
         tfc.setEdit(new MultiTextEdit());
         CompilationUnit rootNode = pu.getCompilationUnit();
         refactorImports(node, originalPackage, targetPackage, rootNode, tfc);
         refactorDocLinks(node, targetPackage, rootNode, tfc);
         if (tfc.getEdit().hasChildren()) {
           change.add(tfc);
         }
       }
       //                }
     }
   }
 }
Exemple #5
0
  @Override
  public Change createChange(final IProgressMonitor pm)
      throws CoreException, OperationCanceledException {
    pm.beginTask("Creating changes", changedFiles.size() + 1);
    final CompositeChange change = new CompositeChange(getName());
    pm.internalWorked(1);

    try {
      Change c;
      for (final ChangedFile e : changedFiles) {
        c = e.createChanges();
        if (c != null) {
          change.add(c);
          pm.internalWorked(1);
        }
      }
    } catch (final IOException e) {
      final Status s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage());

      throw new CoreException(s);
    } finally {
      pm.done();
    }

    return change;
  }
Exemple #6
0
  private void createBuildPathChange(IResource[] sourceResources, CompositeChange rootChange)
      throws ModelException {
    IResource[] uniqueSourceResources = removeDuplicateResources(sourceResources);
    for (IResource element : uniqueSourceResources) {
      // only container need handle build/include path.
      if (element instanceof IContainer) {
        IProject project = element.getProject();

        // if moving to another project
        if (RefactoringUtility.getResource(fMainDestinationPath).getProject() != project) {
          removeBuildPath(element, project);
          IPath path = element.getFullPath().removeLastSegments(1);
          RenameBuildAndIcludePathChange biChange =
              new RenameBuildAndIcludePathChange(
                  path,
                  path,
                  element.getName(),
                  "",
                  oldBuildEntries, //$NON-NLS-1$
                  newBuildEntries,
                  oldIncludePath,
                  newIncludePathEntries);

          if (newBuildEntries.size() > 0 || newIncludePathEntries.size() > 0) {
            rootChange.add(biChange);
          }

        } else {
          updateBuildPath(element, project);
          RenameBuildAndIcludePathChange biChange =
              new RenameBuildAndIcludePathChange(
                  element.getFullPath().removeLastSegments(1),
                  fMainDestinationPath,
                  element.getName(),
                  element.getName(),
                  oldBuildEntries,
                  newBuildEntries,
                  oldIncludePath,
                  newIncludePathEntries);
          if (newBuildEntries.size() > 0 || newIncludePathEntries.size() > 0) {
            rootChange.add(biChange);
          }
        }
      }
    }
  }
Exemple #7
0
 /**
  * Add move changes for each for the selected resources
  *
  * @param sourceResources
  * @param rootChange
  */
 private void createMoveChange(IResource[] sourceResources, CompositeChange rootChange) {
   IResource[] uniqueSourceResources = removeDuplicateResources(sourceResources);
   for (IResource element : uniqueSourceResources) {
     MoveResourceChange moveResource =
         new MoveResourceChange(element, fProcessor.getDestination());
     rootChange.add(moveResource);
   }
 }
 /**
  * Merges the children of the given composite change into this change. This means the changes are
  * removed from the given composite change and added to this change.
  *
  * @param change the change to merge
  */
 public void merge(CompositeChange change) {
   Change[] others = change.getChildren();
   for (int i = 0; i < others.length; i++) {
     Change other = others[i];
     change.remove(other);
     add(other);
   }
 }
Exemple #9
0
  @Override
  public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    CompositeChange ret = createNewCompositeChange();
    try {
      addChanges(affectedIdentifiers, ret, pm);
      // Adds the change for renaming the file which contains the definition.
      RenameResourceChange resourceChange =
          new RenameResourceChange(declaringFile.getFullPath(), newFileName);
      ret.add(resourceChange);

    } catch (Exception e) {
      ret.add(
          new NullChange(
              "Exception Occured during change creation! See project log for more information."));
      getProjectUtil().log("Exception Occured during change creation.", e);
    }
    return ret;
  }
 private void renameSourceFile(CompositeChange change) {
   String unitPath = declaration.getUnit().getFullPath();
   IPath oldPath = project.getFullPath().append(unitPath);
   String newFileName = getNewName() + ".ceylon";
   IPath newPath = oldPath.removeFirstSegments(1).removeLastSegments(1).append(newFileName);
   if (!project.getFile(newPath).exists()) {
     change.add(new RenameResourceChange(oldPath, newFileName));
   }
 }
 @Override
 public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
   CompositeChange changes = new CompositeChange("更新.respath文件");
   for (IARESProject aresProj : ARESModelManager.getManager().getModel().getARESProjects()) {
     if (hasReference(aresProj, this.container))
       changes.add(new UpdateRespathOnContainerRenameChange(aresProj, container, newPath));
   }
   return changes;
 }
  public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    CompositeChange change = new CompositeChange(new String());
    change.markAsSynthetic();

    for (Iterator it = mProfilesToMove.iterator(); it.hasNext(); ) {
      change.add(new ConnectionProfileMoveChange((IConnectionProfile) it.next(), mArguments));
    }

    return change;
  }
Exemple #13
0
 public void generateChange(IASTNode rootNode, ASTVisitor pathProvider)
     throws ProblemRuntimeException {
   change = new CompositeChange(ChangeGeneratorMessages.ChangeGenerator_compositeChange);
   classifyModifications();
   rootNode.accept(pathProvider);
   for (IFile currentFile : changes.keySet()) {
     MultiTextEdit edit = changes.get(currentFile);
     edit =
         formatChangedCode(
             edit, rootNode.getTranslationUnit().getRawSignature(), currentFile.getProject());
     TextFileChange subchange = ASTRewriteAnalyzer.createCTextFileChange(currentFile);
     subchange.setEdit(edit);
     change.add(subchange);
   }
 }
Exemple #14
0
  private void createRunConfigurationChange(
      IResource[] sourceResources, CompositeChange rootChange) {

    IResource[] uniqueSourceResources = removeDuplicateResources(sourceResources);
    for (IResource element : uniqueSourceResources) {
      RenameConfigurationChange configPointchanges =
          new RenameConfigurationChange(
              element.getFullPath().removeLastSegments(1),
              fMainDestinationPath,
              element.getName(),
              element.getName());

      rootChange.add(configPointchanges);
    }
  }
Exemple #15
0
  private void createRenameLibraryFolderChange(
      IResource[] sourceResources, CompositeChange rootChange) {
    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
    LibraryFolderManager lfm = LibraryFolderManager.getInstance();

    for (IResource resource : sourceResources) {
      if (resource.getType() == IResource.FOLDER && lfm.isInLibraryFolder(resource)) {
        IPath newPath = fMainDestinationPath.append(resource.getName());
        IFolder newFolder = root.getFolder(newPath);

        RenameLibraryFolderChange change =
            new RenameLibraryFolderChange((IFolder) resource, newFolder);
        rootChange.add(change);
      }
    }
  }
  private boolean addXmlFileChanges(IFile file, CompositeChange changes, boolean isManifest) {
    IModelManager modelManager = StructuredModelManager.getModelManager();
    IStructuredModel model = null;
    try {
      model = modelManager.getExistingModelForRead(file);
      if (model == null) {
        model = modelManager.getModelForRead(file);
      }
      if (model != null) {
        IStructuredDocument document = model.getStructuredDocument();
        if (model instanceof IDOMModel) {
          IDOMModel domModel = (IDOMModel) model;
          Element root = domModel.getDocument().getDocumentElement();
          if (root != null) {
            List<TextEdit> edits = new ArrayList<TextEdit>();
            if (isManifest) {
              addManifestReplacements(edits, root, document);
            } else {
              addLayoutReplacements(edits, root, document);
            }
            if (!edits.isEmpty()) {
              MultiTextEdit rootEdit = new MultiTextEdit();
              rootEdit.addChildren(edits.toArray(new TextEdit[edits.size()]));
              TextFileChange change = new TextFileChange(file.getName(), file);
              change.setTextType(EXT_XML);
              change.setEdit(rootEdit);
              changes.add(change);
            }
          }
        } else {
          return false;
        }
      }

      return true;
    } catch (IOException e) {
      AdtPlugin.log(e, null);
    } catch (CoreException e) {
      AdtPlugin.log(e, null);
    } finally {
      if (model != null) {
        model.releaseFromRead();
      }
    }

    return false;
  }
 private TextChange canonicalChange(
     CompositeChange composite, Map<IResource, TextChange> changes, SearchMatch match) {
   IResource resource = match.getResource();
   if (resource instanceof IFile) {
     TextChange change = changes.get(resource);
     if (change == null) {
       IFile file = (IFile) resource;
       change = new TextFileChange("Rename", file);
       change.setEdit(new MultiTextEdit());
       changes.put(resource, change);
       composite.add(change);
     }
     return change;
   } else {
     return null;
   }
 }
Exemple #18
0
 @Override
 void createChange(final IProgressMonitor pm, final CompositeChange rootChange) {
   try {
     pm.beginTask(UITexts.mkPointFreeDelegate_collectingChanges, 100);
     if (change == null) {
       throw new IllegalStateException();
     }
     // do not have the intermediate step
     for (Change c : change.getChildren()) {
       change.remove(c);
       rootChange.add(c);
     }
     // rootChange.add( change );
   } finally {
     pm.done();
   }
 }
 /* (non-Javadoc)
  * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#createChange(org.eclipse.core.runtime.IProgressMonitor)
  */
 public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
   pm.beginTask(RefactoringCoreMessages.DeleteResourcesProcessor_create_task, fResources.length);
   try {
     RefactoringChangeDescriptor descriptor = new RefactoringChangeDescriptor(createDescriptor());
     CompositeChange change =
         new CompositeChange(RefactoringCoreMessages.DeleteResourcesProcessor_change_name);
     change.markAsSynthetic();
     for (int i = 0; i < fResources.length; i++) {
       pm.worked(1);
       DeleteResourceChange dc =
           new DeleteResourceChange(fResources[i].getFullPath(), true, fDeleteContents);
       dc.setDescriptor(descriptor);
       change.add(dc);
     }
     return change;
   } finally {
     pm.done();
   }
 }
Exemple #20
0
  private void createBreakPointChange(IResource[] sourceResources, CompositeChange rootChange)
      throws CoreException {
    IResource[] uniqueSourceResources = removeDuplicateResources(sourceResources);
    for (IResource element : uniqueSourceResources) {
      collectBrakePoint(element);

      RenameBreackpointChange breakePointchanges =
          new RenameBreackpointChange(
              element.getFullPath().removeLastSegments(1),
              fMainDestinationPath,
              element.getName(),
              element.getName(),
              fBreakpoints,
              fBreakpointAttributes);

      if (fBreakpoints.getKeys().size() > 0) {
        rootChange.add(breakePointchanges);
      }
    }
  }
 @Override
 protected void refactorInFile(
     TextChange tfc, CompositeChange cc, Tree.CompilationUnit root, List<CommonToken> tokens) {
   tfc.setEdit(new MultiTextEdit());
   if (declaration != null) {
     for (Node node : getNodesToRename(root)) {
       renameNode(tfc, node, root);
     }
     for (Region region : getStringsToReplace(root)) {
       renameRegion(tfc, region, root);
     }
     if (renameValuesAndFunctions) {
       for (Tree.Identifier id : getIdentifiersToRename(root)) {
         renameIdentifier(tfc, id, root);
       }
     }
   }
   if (tfc.getEdit().hasChildren()) {
     cc.add(tfc);
   }
 }
 /**
  * Adds all changes in the given array to the list of children.
  *
  * @param changes the changes to add
  */
 public void addAll(Change[] changes) {
   for (int i = 0; i < changes.length; i++) {
     add(changes[i]);
   }
 }
Exemple #23
0
  /**
   * Creates the text changes for all the affected files. Updates all the include statements in the
   * current file and all the includes in the "including " files. In case of folders, creates the
   * changes recursively
   *
   * @param pm - progress monitor
   * @param rootChange - the root change that the new changes are added to
   * @param sourceResources
   * @return the root change after the additions
   * @throws CoreException
   */
  private Change createTextChanges(
      IProgressMonitor pm,
      CompositeChange rootChange,
      Set<IFile> phpFiles,
      IResource[] sourceResources)
      throws CoreException {
    List<ProgramFileChange> changes = new ArrayList<ProgramFileChange>();
    try {
      pm.beginTask(PhpRefactoringCoreMessages.getString("MoveDelegate.1"), 100); // $NON-NLS-1$

      // creat text changes:
      // for each file that will be moved, update its includes
      // and update all the files that include it,

      IResource[] uniqueSourceResources = removeDuplicateResources(sourceResources);

      for (Iterator<IFile> it = phpFiles.iterator(); it.hasNext(); ) {
        IFile currentMovedResource = it.next();

        Map<IFile, Program> participantFiles = collectReferencingFiles(currentMovedResource, pm);

        for (Entry<IFile, Program> entry : participantFiles.entrySet()) {
          final IFile file = entry.getKey();
          if (phpFiles.contains(file)) {
            continue;
          }
          final Program program = entry.getValue();

          final ChangeIncludePath rename =
              new ChangeIncludePath(
                  currentMovedResource, file, fMainDestinationPath, false, uniqueSourceResources);
          // aggregate the changes identifiers
          program.accept(rename);

          if (pm.isCanceled()) throw new OperationCanceledException();

          pm.worked(1);

          if (rename.hasChanges()) {
            ProgramFileChange change = new ProgramFileChange(file.getName(), file, program);
            change.setEdit(new MultiTextEdit());
            change.setTextType("php"); // $NON-NLS-1$

            changes.add(change);
            rename.updateChange(change);
          }
        }

        ISourceModule sourceModule = DLTKCore.createSourceModuleFrom(currentMovedResource);

        if (sourceModule instanceof ISourceModule) {

          Program program = null;
          try {
            program = ASTUtils.createProgramFromSource(sourceModule);
          } catch (Exception e) {
          }

          if (program != null) {
            final ChangeIncludePath rename =
                new ChangeIncludePath(
                    currentMovedResource,
                    currentMovedResource,
                    fMainDestinationPath,
                    true,
                    uniqueSourceResources);

            // aggregate the changes identifiers
            program.accept(rename);

            if (pm.isCanceled()) throw new OperationCanceledException();

            pm.worked(1);

            if (rename.hasChanges()) {
              ProgramFileChange change =
                  new ProgramFileChange(
                      currentMovedResource.getName(), currentMovedResource, program);
              change.setEdit(new MultiTextEdit());
              change.setTextType("php"); // $NON-NLS-1$

              changes.add(change);
              rename.updateChange(change);
            }
          }
        }
      }
      pm.worked(70);

    } finally {
      pm.done();
    } // getChildren()

    Map<IFile, List<TextEdit>> changeMap = new HashMap<IFile, List<TextEdit>>();
    Map<IFile, ProgramFileChange> fileMap = new HashMap<IFile, ProgramFileChange>();
    for (ProgramFileChange programFileChange : changes) {
      List<TextEdit> list = changeMap.get(programFileChange.getFile());
      if (list == null) {
        list = new ArrayList<TextEdit>();
        changeMap.put(programFileChange.getFile(), list);
        fileMap.put(programFileChange.getFile(), programFileChange);
      } else {

      }
      list.addAll(Arrays.asList(programFileChange.getEdit().getChildren()));
    }
    for (IFile file : changeMap.keySet()) {
      ProgramFileChange change =
          new ProgramFileChange(file.getName(), file, fileMap.get(file).getProgram());
      change.setEdit(new MultiTextEdit());
      change.setTextType("php"); // $NON-NLS-1$

      List<TextEdit> list = changeMap.get(file);
      Collections.sort(
          list,
          new Comparator<TextEdit>() {
            public int compare(TextEdit o1, TextEdit o2) {
              return o2.getOffset() - o1.getOffset();
            }
          });

      for (TextEdit textEdit : list) {
        if (textEdit instanceof ReplaceEdit) {
          ReplaceEdit replaceEdit = (ReplaceEdit) textEdit;
          change.addEdit(
              new ReplaceEdit(
                  replaceEdit.getOffset(), replaceEdit.getLength(), replaceEdit.getText()));
        }
      }
      rootChange.add(change);
    }
    return rootChange;
  }
 @Override
 public void modifyAST(IIndex index, IMarker marker) {
   CompositeChange c = new CompositeChange(Messages.QuickFixCreateParameter_0);
   try {
     ITranslationUnit baseTU = getTranslationUnitViaEditor(marker);
     IASTTranslationUnit baseAST = baseTU.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
     IASTName astName = getASTNameFromMarker(marker, baseAST);
     if (astName == null) {
       return;
     }
     IASTDeclaration declaration =
         CxxAstUtils.createDeclaration(astName, baseAST.getASTNodeFactory(), index);
     // We'll need a FunctionParameterDeclaration later
     final IASTDeclSpecifier finalDeclSpec = (IASTDeclSpecifier) declaration.getChildren()[0];
     final IASTDeclarator finalDeclarator = (IASTDeclarator) declaration.getChildren()[1];
     IASTFunctionDefinition function = CxxAstUtils.getEnclosingFunction(astName);
     if (function == null) {
       return;
     }
     // Find the function declarations
     NameFinderVisitor nameFinderVisitor = new NameFinderVisitor();
     function.accept(nameFinderVisitor);
     IASTName funcName = nameFinderVisitor.name;
     IBinding binding = funcName.resolveBinding();
     IIndexName[] declarations = index.findNames(binding, IIndex.FIND_DECLARATIONS_DEFINITIONS);
     if (declarations.length == 0) {
       return;
     }
     HashMap<ITranslationUnit, IASTTranslationUnit> cachedASTs =
         new HashMap<ITranslationUnit, IASTTranslationUnit>();
     HashMap<ITranslationUnit, ASTRewrite> cachedRewrites =
         new HashMap<ITranslationUnit, ASTRewrite>();
     for (IIndexName iname : declarations) {
       ITranslationUnit declTU = CxxAstUtils.getTranslationUnitFromIndexName(iname);
       if (declTU == null) {
         continue;
       }
       ASTRewrite rewrite;
       IASTTranslationUnit declAST;
       if (!cachedASTs.containsKey(declTU)) {
         declAST = declTU.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
         rewrite = ASTRewrite.create(declAST);
         cachedASTs.put(declTU, declAST);
         cachedRewrites.put(declTU, rewrite);
       } else {
         declAST = cachedASTs.get(declTU);
         rewrite = cachedRewrites.get(declTU);
       }
       IASTFileLocation fileLocation = iname.getFileLocation();
       IASTName declName =
           declAST
               .getNodeSelector(null)
               .findEnclosingName(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
       if (declName == null) {
         continue;
       }
       INodeFactory factory = declAST.getASTNodeFactory();
       IASTFunctionDeclarator functionDecl;
       {
         IASTNode n = declName;
         while (n instanceof IASTName) {
           n = n.getParent();
         }
         functionDecl = (IASTFunctionDeclarator) n;
       }
       IASTParameterDeclaration newParam =
           factory.newParameterDeclaration(finalDeclSpec, finalDeclarator);
       rewrite.insertBefore(functionDecl, null, newParam, null);
     }
     for (ASTRewrite rewrite : cachedRewrites.values()) {
       c.add(rewrite.rewriteAST());
     }
     c.perform(new NullProgressMonitor());
   } catch (CoreException e) {
     CheckersUiActivator.log(e);
   }
 }
  @Override
  public Change createPreChange(IProgressMonitor pm)
      throws CoreException, OperationCanceledException {
    try {
      IProject project = file.getProject();
      Object destination = getArguments().getDestination();
      if (!(destination instanceof IFolder)) {
        return null;
      }
      IFolder folder = (IFolder) destination;
      String newName =
          folder
              .getProjectRelativePath()
              .removeFirstSegments(1)
              .toPortableString()
              .replace('/', '.');
      String movedRelFilePath =
          file.getProjectRelativePath().removeFirstSegments(1).toPortableString();
      String movedRelPath =
          file.getParent().getProjectRelativePath().removeFirstSegments(1).toPortableString();
      String oldName = movedRelPath.replace('/', '.');

      List<Change> changes = new ArrayList<Change>();

      if (file.getFileExtension().equals("java")) {
        updateRefsToMovedJavaFile(project, newName, oldName, changes);
      } else {
        TypeChecker tc = getProjectTypeChecker(project);
        if (tc == null) return null;
        PhasedUnit movedPhasedUnit = tc.getPhasedUnitFromRelativePath(movedRelFilePath);
        if (movedPhasedUnit == null) {
          return null;
        }

        List<Declaration> declarations = movedPhasedUnit.getDeclarations();
        if (newName.equals(oldName)) return null;
        updateRefsFromMovedCeylonFile(
            project, newName, oldName, changes, movedPhasedUnit, declarations);
        updateRefsToMovedCeylonFile(
            project, newName, oldName, changes, movedPhasedUnit, declarations);
      }

      if (changes.isEmpty()) return null;

      CompositeChange result =
          new CompositeChange("Ceylon source changes") {
            @Override
            public Change perform(IProgressMonitor pm) throws CoreException {
              fileChanges.clear();
              movingFiles.clear();
              return super.perform(pm);
            }
          };
      for (Change change : changes) {
        result.add(change);
      }
      return result;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
  @Override
  public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    final Map<IFile, TextChange> fileChanges = new HashMap<IFile, TextChange>();

    IResourceProxyVisitor visitor =
        new IResourceProxyVisitor() {
          public boolean visit(IResourceProxy proxy) throws CoreException {
            if ((proxy.getType() == IResource.FOLDER) || (proxy.getType() == IResource.PROJECT)) {
              return true;
            }

            if (!((proxy.getType() == IResource.FILE)
                && proxy.getName().toLowerCase().endsWith(".bnd"))) {
              return false;
            }

            /* we're dealing with a *.bnd file */

            /* get the proxied file */
            IFile resource = (IFile) proxy.requestResource();

            /* read the file as a single string */
            String bndFileText = null;
            try {
              bndFileText = FileUtils.readFully(resource).get();
            } catch (Exception e) {
              String str = "Could not read file " + proxy.getName();
              logger.logError(str, e);
              throw new OperationCanceledException(str);
            }

            /*
             * get the previous change for this file if it exists, or otherwise create a new change for it, but do
             * not store it yet: wait until we know if there are actually changes in the file
             */
            TextChange fileChange = getTextChange(resource);
            final boolean fileChangeIsNew = (fileChange == null);
            if (fileChange == null) {
              fileChange = new TextFileChange(proxy.getName(), resource);
              fileChange.setEdit(new MultiTextEdit());
            }
            TextEdit rootEdit = fileChange.getEdit();

            /* loop over all renames to perform */
            for (Map.Entry<IPackageFragment, RenameArguments> entry : pkgFragments.entrySet()) {
              IPackageFragment pkgFragment = entry.getKey();
              RenameArguments arguments = entry.getValue();

              final String oldName = pkgFragment.getElementName();
              final String newName = arguments.getNewName();

              Pattern pattern =
                  Pattern.compile(
                      /* match start boundary */ "(^|"
                          + grammarSeparator
                          + ")"
                          +
                          /* match itself / package name */ "("
                          + Pattern.quote(oldName)
                          + ")"
                          +
                          /* match end boundary */ "("
                          + grammarSeparator
                          + "|"
                          + Pattern.quote(".*")
                          + "|"
                          + Pattern.quote("\\")
                          + "|$)");

              /* find all matches to replace and add them to the root edit */
              Matcher matcher = pattern.matcher(bndFileText);
              while (matcher.find()) {
                rootEdit.addChild(
                    new ReplaceEdit(matcher.start(2), matcher.group(2).length(), newName));
              }

              pattern =
                  Pattern.compile(
                      /* match start boundary */ "(^|"
                          + grammarSeparator
                          + ")"
                          +
                          /* match bundle activator */ "(Bundle-Activator\\s*:\\s*)"
                          +
                          /* match itself / package name */ "("
                          + Pattern.quote(oldName)
                          + ")"
                          +
                          /* match class name */ "(\\.[^\\.]+)"
                          +
                          /* match end boundary */ "("
                          + grammarSeparator
                          + "|"
                          + Pattern.quote("\\")
                          + "|$)");

              /* find all matches to replace and add them to the root edit */
              matcher = pattern.matcher(bndFileText);
              while (matcher.find()) {
                rootEdit.addChild(
                    new ReplaceEdit(matcher.start(3), matcher.group(3).length(), newName));
              }
            }

            /*
             * only store the changes when no changes were stored before for this file and when there are actually
             * changes.
             */
            if (fileChangeIsNew && rootEdit.hasChildren()) {
              fileChanges.put(resource, fileChange);
            }

            return false;
          }
        };

    /* determine which projects have to be visited */
    Set<IProject> projectsToVisit = new HashSet<IProject>();
    for (IPackageFragment pkgFragment : pkgFragments.keySet()) {
      projectsToVisit.add(pkgFragment.getResource().getProject());
      for (IProject projectToVisit :
          pkgFragment.getResource().getProject().getReferencingProjects()) {
        projectsToVisit.add(projectToVisit);
      }
      for (IProject projectToVisit :
          pkgFragment.getResource().getProject().getReferencedProjects()) {
        projectsToVisit.add(projectToVisit);
      }
    }

    /* visit the projects */
    for (IProject projectToVisit : projectsToVisit) {
      projectToVisit.accept(visitor, IContainer.NONE);
    }

    if (fileChanges.isEmpty()) {
      /* no changes at all */
      return null;
    }

    /* build a composite change with all changes */
    CompositeChange cs = new CompositeChange(changeTitle);
    for (TextChange fileChange : fileChanges.values()) {
      cs.add(fileChange);
    }

    return cs;
  }