private ArrayList<Entry<IPath, IResource>> getSourceArchivesToCleanUp(IProgressMonitor monitor)
     throws CoreException {
   Set<IPath> projectSourcePaths = null;
   for (IProject project : CeylonBuilder.getProjects()) {
     for (JDTModule module : CeylonBuilder.getProjectExternalModules(project)) {
       String sourceArchivePathString = module.getSourceArchivePath();
       if (sourceArchivePathString != null) {
         if (projectSourcePaths == null) {
           projectSourcePaths = new HashSet<>();
         }
         projectSourcePaths.add(Path.fromOSString(sourceArchivePathString));
       }
     }
   }
   if (projectSourcePaths == null) return null;
   Map<IPath, IResource> knownSourceArchives = getSourceArchives();
   ArrayList<Entry<IPath, IResource>> result = null;
   synchronized (knownSourceArchives) {
     Iterator<Entry<IPath, IResource>> iterator = knownSourceArchives.entrySet().iterator();
     while (iterator.hasNext()) {
       Map.Entry<IPath, IResource> entry = iterator.next();
       IPath path = entry.getKey();
       if (!projectSourcePaths.contains(path)) {
         if (entry.getValue() != null) {
           if (result == null) result = new ArrayList<>();
           result.add(entry);
         }
       }
     }
   }
   return result;
 }
 /*
  * Returns a set of external path to external folders referred to on the given classpath.
  * Returns null if none.
  */
 public static Set<IPath> getExternalSourceArchives(Collection<JDTModule> modules) {
   if (modules == null) return null;
   Set<IPath> folders = null;
   for (JDTModule module : modules) {
     if (module.isCeylonArchive()) {
       IPath archivePath = Path.fromOSString(module.getSourceArchivePath());
       if (isExternalSourceArchivePath(archivePath)) {
         if (folders == null) folders = new HashSet<>();
         folders.add(archivePath);
       }
     }
   }
   return folders;
 }