c68939ad2a6b5551bb2a25853932d6b5ba78fbdf
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / DeltaProcessor.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
12
13 import java.io.File;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.Iterator;
19 import java.util.Map;
20
21 import net.sourceforge.phpdt.core.ElementChangedEvent;
22 import net.sourceforge.phpdt.core.IClasspathEntry;
23 import net.sourceforge.phpdt.core.IElementChangedListener;
24 import net.sourceforge.phpdt.core.IJavaElement;
25 import net.sourceforge.phpdt.core.IJavaElementDelta;
26 import net.sourceforge.phpdt.core.IJavaModel;
27 import net.sourceforge.phpdt.core.IJavaProject;
28 import net.sourceforge.phpdt.core.JavaCore;
29 import net.sourceforge.phpdt.core.JavaModelException;
30 import net.sourceforge.phpdt.internal.core.builder.PHPBuilder;
31 import net.sourceforge.phpdt.internal.core.util.Util;
32 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
33 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
34
35 import org.eclipse.core.resources.IFile;
36 import org.eclipse.core.resources.IProject;
37 import org.eclipse.core.resources.IResource;
38 import org.eclipse.core.resources.IResourceChangeEvent;
39 import org.eclipse.core.resources.IResourceChangeListener;
40 import org.eclipse.core.resources.IResourceDelta;
41 import org.eclipse.core.resources.IResourceDeltaVisitor;
42 import org.eclipse.core.resources.IWorkspace;
43 import org.eclipse.core.resources.ResourcesPlugin;
44 import org.eclipse.core.runtime.CoreException;
45 import org.eclipse.core.runtime.IPath;
46 import org.eclipse.core.runtime.ISafeRunnable;
47 import org.eclipse.core.runtime.Platform;
48 import org.eclipse.core.runtime.QualifiedName;
49
50
51 /**
52  * This class is used by <code>JavaModelManager</code> to convert
53  * <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s.
54  * It also does some processing on the <code>JavaElement</code>s involved
55  * (e.g. closing them or updating classpaths).
56  */
57 public class DeltaProcessor implements IResourceChangeListener {
58         
59         final static int IGNORE = 0;
60         final static int SOURCE = 1;
61         final static int BINARY = 2;
62         
63         final static String EXTERNAL_JAR_ADDED = "external jar added"; //$NON-NLS-1$
64         final static String EXTERNAL_JAR_REMOVED = "external jar removed"; //$NON-NLS-1$
65         final static String EXTERNAL_JAR_CHANGED = "external jar changed"; //$NON-NLS-1$
66         final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; //$NON-NLS-1$
67         final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; //$NON-NLS-1$
68         
69         private final static int NON_JAVA_RESOURCE = -1;
70         public static boolean DEBUG = false;
71         public static boolean VERBOSE = false;
72         
73         public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with ElementChangedEvent event masks
74         /**
75          * The <code>JavaElementDelta</code> corresponding to the <code>IResourceDelta</code> being translated.
76          */
77         protected JavaElementDelta currentDelta;
78         
79 //      protected IndexManager indexManager = new IndexManager();
80                 
81         /* A table from IPath (from a classpath entry) to RootInfo */
82         public Map roots;
83         
84         /* A table from IPath (from a classpath entry) to ArrayList of RootInfo
85          * Used when an IPath corresponds to more than one root */
86         Map otherRoots;
87         
88         /* Whether the roots tables should be recomputed */
89         public boolean rootsAreStale = true;
90         
91         /* A table from IPath (from a classpath entry) to RootInfo
92          * from the last time the delta processor was invoked. */
93         public Map oldRoots;
94
95         /* A table from IPath (from a classpath entry) to ArrayList of RootInfo
96          * from the last time the delta processor was invoked.
97          * Used when an IPath corresponds to more than one root */
98         Map oldOtherRoots;
99         
100         /* A table from IPath (a source attachment path from a classpath entry) to IPath (a root path) */
101         Map sourceAttachments;
102
103         /* The java element that was last created (see createElement(IResource)). 
104          * This is used as a stack of java elements (using getParent() to pop it, and 
105          * using the various get*(...) to push it. */
106         Openable currentElement;
107         /*
108          * Queue of deltas created explicily by the Java Model that
109          * have yet to be fired.
110          */
111         public ArrayList javaModelDeltas= new ArrayList();
112         /*
113          * Queue of reconcile deltas on working copies that have yet to be fired.
114          * This is a table form IWorkingCopy to IJavaElementDelta
115          */
116         public HashMap reconcileDeltas = new HashMap();
117
118         /*
119          * Turns delta firing on/off. By default it is on.
120          */
121         private boolean isFiring= true;
122         
123         
124         public HashMap externalTimeStamps = new HashMap();
125         public HashSet projectsToUpdate = new HashSet();
126         // list of root projects which namelookup caches need to be updated for dependents
127         // TODO: (jerome) is it needed? projectsToUpdate might be sufficient
128         public HashSet projectsForDependentNamelookupRefresh = new HashSet();  
129         
130         /*
131          * The global state of delta processing.
132          */
133         private DeltaProcessingState state;
134         
135         /*
136          * The Java model manager
137          */
138         private JavaModelManager manager;
139         
140         /* A table from IJavaProject to an array of IPackageFragmentRoot.
141          * This table contains the pkg fragment roots of the project that are being deleted.
142          */
143         Map removedRoots;
144         
145         /*
146          * A list of IJavaElement used as a scope for external archives refresh during POST_CHANGE.
147          * This is null if no refresh is needed.
148          */
149         HashSet refreshedElements;
150         
151         class OutputsInfo {
152                 IPath[] paths;
153                 int[] traverseModes;
154                 int outputCount;
155                 OutputsInfo(IPath[] paths, int[] traverseModes, int outputCount) {
156                         this.paths = paths;
157                         this.traverseModes = traverseModes;
158                         this.outputCount = outputCount;
159                 }
160                 public String toString() {
161                         if (this.paths == null) return "<none>"; //$NON-NLS-1$
162                         StringBuffer buffer = new StringBuffer();
163                         for (int i = 0; i < this.outputCount; i++) {
164                                 buffer.append("path="); //$NON-NLS-1$
165                                 buffer.append(this.paths[i].toString());
166                                 buffer.append("\n->traverse="); //$NON-NLS-1$
167                                 switch (this.traverseModes[i]) {
168                                         case BINARY:
169                                                 buffer.append("BINARY"); //$NON-NLS-1$
170                                                 break;
171                                         case IGNORE:
172                                                 buffer.append("IGNORE"); //$NON-NLS-1$
173                                                 break;
174                                         case SOURCE:
175                                                 buffer.append("SOURCE"); //$NON-NLS-1$
176                                                 break;
177                                         default:
178                                                 buffer.append("<unknown>"); //$NON-NLS-1$
179                                 }
180                                 if (i+1 < this.outputCount) {
181                                         buffer.append('\n');
182                                 }
183                         }
184                         return buffer.toString();
185                 }
186         }
187         class RootInfo {
188                 IJavaProject project;
189                 IPath rootPath;
190                 char[][] exclusionPatterns;
191                 RootInfo(IJavaProject project, IPath rootPath, char[][] exclusionPatterns) {
192                         this.project = project;
193                         this.rootPath = rootPath;
194                         this.exclusionPatterns = exclusionPatterns;
195                 }
196                 boolean isRootOfProject(IPath path) {
197                         return this.rootPath.equals(path) && this.project.getProject().getFullPath().isPrefixOf(path);
198                 }
199                 public String toString() {
200                         StringBuffer buffer = new StringBuffer("project="); //$NON-NLS-1$
201                         if (this.project == null) {
202                                 buffer.append("null"); //$NON-NLS-1$
203                         } else {
204                                 buffer.append(this.project.getElementName());
205                         }
206                         buffer.append("\npath="); //$NON-NLS-1$
207                         if (this.rootPath == null) {
208                                 buffer.append("null"); //$NON-NLS-1$
209                         } else {
210                                 buffer.append(this.rootPath.toString());
211                         }
212                         buffer.append("\nexcluding="); //$NON-NLS-1$
213                         if (this.exclusionPatterns == null) {
214                                 buffer.append("null"); //$NON-NLS-1$
215                         } else {
216                                 for (int i = 0, length = this.exclusionPatterns.length; i < length; i++) {
217                                         buffer.append(new String(this.exclusionPatterns[i]));
218                                         if (i < length-1) {
219                                                 buffer.append("|"); //$NON-NLS-1$
220                                         }
221                                 }
222                         }
223                         return buffer.toString();
224                 }
225         }
226
227 //      DeltaProcessor(JavaModelManager manager) {
228 //              this.manager = manager;
229 //      }
230
231         /*
232          * Type of event that should be processed no matter what the real event type is.
233          */
234         public int overridenEventType = -1;
235         
236         public DeltaProcessor(DeltaProcessingState state, JavaModelManager manager) {
237                 this.state = state;
238                 this.manager = manager;
239         }
240         /*
241          * Adds the dependents of the given project to the list of the projects
242          * to update.
243          */
244 //      void addDependentProjects(IPath projectPath, HashSet result) {
245 //              try {
246 //                      IJavaProject[] projects = this.manager.getJavaModel().getJavaProjects();
247 //                      for (int i = 0, length = projects.length; i < length; i++) {
248 //                              IJavaProject project = projects[i];
249 //                              IClasspathEntry[] classpath = ((JavaProject)project).getExpandedClasspath(true);
250 //                              for (int j = 0, length2 = classpath.length; j < length2; j++) {
251 //                                      IClasspathEntry entry = classpath[j];
252 //                                              if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT
253 //                                                              && entry.getPath().equals(projectPath)) {
254 //                                                      result.add(project);
255 //                                              }
256 //                                      }
257 //                              }
258 //              } catch (JavaModelException e) {
259 //              }
260 //      }
261         /*
262          * Adds the given element to the list of elements used as a scope for external jars refresh.
263          */
264         public void addForRefresh(IJavaElement element) {
265                 if (this.refreshedElements == null) {
266                         this.refreshedElements = new HashSet();
267                 }
268                 this.refreshedElements.add(element);
269         }
270         /*
271          * Adds the given project and its dependents to the list of the projects
272          * to update.
273          */
274         void addToProjectsToUpdateWithDependents(IProject project) {
275                 this.projectsToUpdate.add(JavaCore.create(project));
276 //              this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
277         }
278         
279         /**
280          * Adds the given child handle to its parent's cache of children. 
281          */
282         protected void addToParentInfo(Openable child) {
283
284                 Openable parent = (Openable) child.getParent();
285                 if (parent != null && parent.isOpen()) {
286                         try {
287                                 JavaElementInfo info = (JavaElementInfo)parent.getElementInfo();
288                                 info.addChild(child);
289                         } catch (JavaModelException e) {
290                                 // do nothing - we already checked if open
291                         }
292                 }
293         }
294
295         /**
296          * Check all external archive (referenced by given roots, projects or model) status and issue a corresponding root delta.
297          * Also triggers index updates
298          */
299 //      public void checkExternalArchiveChanges(IJavaElement[] refreshedElements, IProgressMonitor monitor) throws JavaModelException {
300 //              try {
301 //                      for (int i = 0, length = refreshedElements.length; i < length; i++) {
302 //                              this.addForRefresh(refreshedElements[i]);
303 //                      }
304 //                      boolean hasDelta = this.createExternalArchiveDelta(monitor);
305 //                      if (monitor != null && monitor.isCanceled()) return; 
306 //                      if (hasDelta){
307 //                              // force classpath marker refresh of affected projects
308 //                              JavaModel.flushExternalFileCache();
309 //                              IJavaElementDelta[] projectDeltas = this.currentDelta.getAffectedChildren();
310 //                              for (int i = 0, length = projectDeltas.length; i < length; i++) {
311 //                                      IJavaElementDelta delta = projectDeltas[i];
312 //                                      ((JavaProject)delta.getElement()).getResolvedClasspath(
313 //                                              true, // ignoreUnresolvedEntry
314 //                                              true); // generateMarkerOnError
315 //                              }               
316 //                              if (this.currentDelta != null) { // if delta has not been fired while creating markers
317 //                                      this.manager.fire(this.currentDelta, JavaModelManager.DEFAULT_CHANGE_EVENT);
318 //                              }
319 //                      }
320 //              } finally {
321 //                      this.currentDelta = null;
322 //                      if (monitor != null) monitor.done();
323 //              }
324 //      }
325         /*
326          * Check if external archives have changed and create the corresponding deltas.
327          * Returns whether at least on delta was created.
328          */
329 //      public boolean createExternalArchiveDelta(IProgressMonitor monitor) throws JavaModelException {
330 //              
331 //              if (this.refreshedElements == null) return false;
332 //                      
333 //              HashMap externalArchivesStatus = new HashMap();
334 //              boolean hasDelta = false;
335 //              
336 //              // find JARs to refresh
337 //              HashSet archivePathsToRefresh = new HashSet();
338 //              try {
339 //                      Iterator iterator = this.refreshedElements.iterator();
340 //                      while (iterator.hasNext()) {
341 //                              IJavaElement element = (IJavaElement)iterator.next();
342 //                              switch(element.getElementType()){
343 //                                      case IJavaElement.PACKAGE_FRAGMENT_ROOT :
344 //                                              archivePathsToRefresh.add(element.getPath());
345 //                                              break;
346 //                                      case IJavaElement.JAVA_PROJECT :
347 //                                              IJavaProject project = (IJavaProject) element;
348 //                                              if (!JavaProject.hasJavaNature(project.getProject())) {
349 //                                                      // project is not accessible or has lost its Java nature
350 //                                                      break;
351 //                                              }
352 //                                              IClasspathEntry[] classpath = project.getResolvedClasspath(true);
353 //                                              for (int j = 0, cpLength = classpath.length; j < cpLength; j++){
354 //                                                      if (classpath[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
355 //                                                              archivePathsToRefresh.add(classpath[j].getPath());
356 //                                                      }
357 //                                              }
358 //                                              break;
359 //                                      case IJavaElement.JAVA_MODEL :
360 //                                              IJavaProject[] projects = manager.getJavaModel().getOldJavaProjectsList();
361 //                                              for (int j = 0, projectsLength = projects.length; j < projectsLength; j++){
362 //                                                      project = projects[j];
363 //                                                      if (!JavaProject.hasJavaNature(project.getProject())) {
364 //                                                              // project is not accessible or has lost its Java nature
365 //                                                              continue;
366 //                                                      }
367 //                                                      classpath = project.getResolvedClasspath(true);
368 //                                                      for (int k = 0, cpLength = classpath.length; k < cpLength; k++){
369 //                                                              if (classpath[k].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
370 //                                                                      archivePathsToRefresh.add(classpath[k].getPath());
371 //                                                              }
372 //                                                      }
373 //                                              }
374 //                                              break;
375 //                              }
376 //                      }
377 //              } finally {
378 //                      this.refreshedElements = null;
379 //              }
380 //              
381 //              // perform refresh
382 //              IJavaProject[] projects = manager.getJavaModel().getOldJavaProjectsList();
383 //              IWorkspaceRoot wksRoot = ResourcesPlugin.getWorkspace().getRoot();
384 //              for (int i = 0, length = projects.length; i < length; i++) {
385 //                      
386 //                      if (monitor != null && monitor.isCanceled()) break; 
387 //                      
388 //                      IJavaProject project = projects[i];
389 //                      if (!JavaProject.hasJavaNature(project.getProject())) {
390 //                              // project is not accessible or has lost its Java nature
391 //                              continue;
392 //                      }
393 //                      IClasspathEntry[] entries = project.getResolvedClasspath(true);
394 //                      for (int j = 0; j < entries.length; j++){
395 //                              if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
396 //                                      
397 //                                      IPath entryPath = entries[j].getPath();
398 //                                      
399 //                                      if (!archivePathsToRefresh.contains(entryPath)) continue; // not supposed to be refreshed
400 //                                      
401 //                                      String status = (String)externalArchivesStatus.get(entryPath); 
402 //                                      if (status == null){
403 //                                              
404 //                                              // compute shared status
405 //                                              Object targetLibrary = JavaModel.getTarget(wksRoot, entryPath, true);
406 //              
407 //                                              if (targetLibrary == null){ // missing JAR
408 //                                                      if (this.externalTimeStamps.containsKey(entryPath)){
409 //                                                              this.externalTimeStamps.remove(entryPath);
410 //                                                              externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
411 //                                                              // the jar was physically removed: remove the index
412 //                                                              indexManager.removeIndex(entryPath);
413 //                                                      }
414 //              
415 //                                              } else if (targetLibrary instanceof File){ // external JAR
416 //              
417 //                                                      File externalFile = (File)targetLibrary;
418 //                                                      
419 //                                                      // check timestamp to figure if JAR has changed in some way
420 //                                                      Long oldTimestamp =(Long) this.externalTimeStamps.get(entryPath);
421 //                                                      long newTimeStamp = getTimeStamp(externalFile);
422 //                                                      if (oldTimestamp != null){
423 //              
424 //                                                              if (newTimeStamp == 0){ // file doesn't exist
425 //                                                                      externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
426 //                                                                      this.externalTimeStamps.remove(entryPath);
427 //                                                                      // remove the index
428 //                                                                      indexManager.removeIndex(entryPath);
429 //              
430 //                                                              } else if (oldTimestamp.longValue() != newTimeStamp){
431 //                                                                      externalArchivesStatus.put(entryPath, EXTERNAL_JAR_CHANGED);
432 //                                                                      this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
433 //                                                                      // first remove the index so that it is forced to be re-indexed
434 //                                                                      indexManager.removeIndex(entryPath);
435 //                                                                      // then index the jar
436 //                                                                      indexManager.indexLibrary(entryPath, project.getProject());
437 //                                                              } else {
438 //                                                                      externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
439 //                                                              }
440 //                                                      } else {
441 //                                                              if (newTimeStamp == 0){ // jar still doesn't exist
442 //                                                                      externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
443 //                                                              } else {
444 //                                                                      externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED);
445 //                                                                      this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
446 //                                                                      // index the new jar
447 //                                                                      indexManager.indexLibrary(entryPath, project.getProject());
448 //                                                              }
449 //                                                      }
450 //                                              } else { // internal JAR
451 //                                                      externalArchivesStatus.put(entryPath, INTERNAL_JAR_IGNORE);
452 //                                              }
453 //                                      }
454 //                                      // according to computed status, generate a delta
455 //                                      status = (String)externalArchivesStatus.get(entryPath); 
456 //                                      if (status != null){
457 //                                              if (status == EXTERNAL_JAR_ADDED){
458 //                                                      PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
459 //                                                      if (VERBOSE){
460 //                                                              System.out.println("- External JAR ADDED, affecting root: "+root.getElementName()); //$NON-NLS-1$
461 //                                                      } 
462 //                                                      elementAdded(root, null, null);
463 //                                                      hasDelta = true;
464 //                                              } else if (status == EXTERNAL_JAR_CHANGED) {
465 //                                                      PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
466 //                                                      if (VERBOSE){
467 //                                                              System.out.println("- External JAR CHANGED, affecting root: "+root.getElementName()); //$NON-NLS-1$
468 //                                                      }
469 //                                                      // reset the corresponding project built state, since the builder would miss this change
470 //                                                      this.manager.setLastBuiltState(project.getProject(), null /*no state*/);
471 //                                                      contentChanged(root, null);
472 //                                                      hasDelta = true;
473 //                                              } else if (status == EXTERNAL_JAR_REMOVED) {
474 //                                                      PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
475 //                                                      if (VERBOSE){
476 //                                                              System.out.println("- External JAR REMOVED, affecting root: "+root.getElementName()); //$NON-NLS-1$
477 //                                                      }
478 //                                                      elementRemoved(root, null, null);
479 //                                                      hasDelta = true;
480 //                                              }
481 //                                      }
482 //                              }
483 //                      }
484 //              }
485 //              return hasDelta;
486 //      }
487         JavaElementDelta currentDelta() {
488                 if (this.currentDelta == null) {
489                         this.currentDelta = new JavaElementDelta(this.manager.getJavaModel());
490                 }
491                 return this.currentDelta;
492         }
493         
494         /*
495          * Process the given delta and look for projects being added, opened, closed or
496          * with a java nature being added or removed.
497          * Note that projects being deleted are checked in deleting(IProject).
498          * In all cases, add the project's dependents to the list of projects to update
499          * so that the classpath related markers can be updated.
500          */
501 //      public void checkProjectsBeingAddedOrRemoved(IResourceDelta delta) {
502 //              IResource resource = delta.getResource();
503 //              switch (resource.getType()) {
504 //                      case IResource.ROOT :
505 //                              // workaround for bug 15168 circular errors not reported 
506 //                              if (this.manager.javaProjectsCache == null) {
507 //                                      try {
508 //                                              this.manager.javaProjectsCache = this.manager.getJavaModel().getJavaProjects();
509 //                                      } catch (JavaModelException e) {
510 //                                      }
511 //                              }
512 //                              
513 //                              IResourceDelta[] children = delta.getAffectedChildren();
514 //                              for (int i = 0, length = children.length; i < length; i++) {
515 //                                      this.checkProjectsBeingAddedOrRemoved(children[i]);
516 //                              }
517 //                              break;
518 //                      case IResource.PROJECT :
519 //                              // NB: No need to check project's nature as if the project is not a java project:
520 //                              //     - if the project is added or changed this is a noop for projectsBeingDeleted
521 //                              //     - if the project is closed, it has already lost its java nature
522 //                              int deltaKind = delta.getKind();
523 //                              if (deltaKind == IResourceDelta.ADDED) {
524 //                                      // remember project and its dependents
525 //                                      IProject project = (IProject)resource;
526 //                                      this.addToProjectsToUpdateWithDependents(project);
527 //                                      
528 //                                      // workaround for bug 15168 circular errors not reported 
529 //                                      if (JavaProject.hasJavaNature(project)) {
530 //                                              this.addToParentInfo((JavaProject)JavaCore.create(project));
531 //                                      }
532 //
533 //                              } else if (deltaKind == IResourceDelta.CHANGED) {
534 //                                      IProject project = (IProject)resource;
535 //                                      if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
536 //                                              // project opened or closed: remember  project and its dependents
537 //                                              this.addToProjectsToUpdateWithDependents(project);
538 //                                              
539 //                                              // workaround for bug 15168 circular errors not reported 
540 //                                              if (project.isOpen()) {
541 //                                                      if (JavaProject.hasJavaNature(project)) {
542 //                                                              this.addToParentInfo((JavaProject)JavaCore.create(project));
543 //                                                      }
544 //                                              } else {
545 //                                                      JavaProject javaProject = (JavaProject)this.manager.getJavaModel().findJavaProject(project);
546 //                                                      if (javaProject != null) {
547 //                                                              try {
548 //                                                                      javaProject.close();
549 //                                                              } catch (JavaModelException e) {
550 //                                                              }
551 //                                                              this.removeFromParentInfo(javaProject);
552 //                                                      }
553 //                                              }
554 //                                      } else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
555 //                                              boolean wasJavaProject = this.manager.getJavaModel().findJavaProject(project) != null;
556 //                                              boolean isJavaProject = JavaProject.hasJavaNature(project);
557 //                                              if (wasJavaProject != isJavaProject) {
558 //                                                      // java nature added or removed: remember  project and its dependents
559 //                                                      this.addToProjectsToUpdateWithDependents(project);
560 //
561 //                                                      // workaround for bug 15168 circular errors not reported 
562 //                                                      if (isJavaProject) {
563 //                                                              this.addToParentInfo((JavaProject)JavaCore.create(project));
564 //                                                      } else {
565 //                                                              JavaProject javaProject = (JavaProject)JavaCore.create(project);
566 //                                                              
567 //                                                              // flush classpath markers
568 //                                                              javaProject.
569 //                                                                      flushClasspathProblemMarkers(
570 //                                                                              true, // flush cycle markers
571 //                                                                              true  //flush classpath format markers
572 //                                                                      );
573 //                                                                      
574 //                                                              // remove problems and tasks created  by the builder
575 //                                                              JavaBuilder.removeProblemsAndTasksFor(project);
576 //
577 //                                                              // close project
578 //                                                              try {
579 //                                                                      javaProject.close();
580 //                                                              } catch (JavaModelException e) {
581 //                                                              }
582 //                                                              this.removeFromParentInfo(javaProject);
583 //                                                      }
584 //                                              } else {
585 //                                                      // in case the project was removed then added then changed (see bug 19799)
586 //                                                      if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
587 //                                                              this.addToParentInfo((JavaProject)JavaCore.create(project));
588 //                                                      }
589 //                                              }
590 //                                      } else {
591 //                                              // workaround for bug 15168 circular errors not reported 
592 //                                              // in case the project was removed then added then changed
593 //                                              if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
594 //                                                      this.addToParentInfo((JavaProject)JavaCore.create(project));
595 //                                              }                                               
596 //                                      }                                       
597 //                              }
598 //                              break;
599 //              }
600 //      }
601
602 //      private void checkSourceAttachmentChange(IResourceDelta delta, IResource res) {
603 //              IPath rootPath = (IPath)this.sourceAttachments.get(res.getFullPath());
604 //              if (rootPath != null) {
605 //                      RootInfo rootInfo = this.rootInfo(rootPath, delta.getKind());
606 //                      if (rootInfo != null) {
607 //                              IJavaProject projectOfRoot = rootInfo.project;
608 //                              IPackageFragmentRoot root = null;
609 //                              try {
610 //                                      // close the root so that source attachement cache is flushed
611 //                                      root = projectOfRoot.findPackageFragmentRoot(rootPath);
612 //                                      if (root != null) {
613 //                                              root.close();
614 //                                      }
615 //                              } catch (JavaModelException e) {
616 //                              }
617 //                              if (root == null) return;
618 //                              switch (delta.getKind()) {
619 //                                      case IResourceDelta.ADDED:
620 //                                              currentDelta().sourceAttached(root);
621 //                                              break;
622 //                                      case IResourceDelta.CHANGED:
623 //                                              currentDelta().sourceDetached(root);
624 //                                              currentDelta().sourceAttached(root);
625 //                                              break;
626 //                                      case IResourceDelta.REMOVED:
627 //                                              currentDelta().sourceDetached(root);
628 //                                              break;
629 //                              }
630 //                      } 
631 //              }
632 //      }
633
634         /**
635          * Closes the given element, which removes it from the cache of open elements.
636          */
637 //      protected static void close(Openable element) {
638 //
639 //              try {
640 //                      element.close();
641 //              } catch (JavaModelException e) {
642 //                      // do nothing
643 //              }
644 //      }
645         /**
646          * Generic processing for elements with changed contents:<ul>
647          * <li>The element is closed such that any subsequent accesses will re-open
648          * the element reflecting its new structure.
649          * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
650          * </ul>
651          * Delta argument could be null if processing an external JAR change
652          */
653 //      protected void contentChanged(Openable element, IResourceDelta delta) {
654 //
655 //              close(element);
656 //              int flags = IJavaElementDelta.F_CONTENT;
657 //              if (element instanceof JarPackageFragmentRoot){
658 //                      flags |= IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED;
659 //              }
660 //              currentDelta().changed(element, flags);
661 //      }
662 //      
663         /**
664          * Creates the openables corresponding to this resource.
665          * Returns null if none was found.
666          */
667 //      protected Openable createElement(IResource resource, int elementType, RootInfo rootInfo) {
668 //              if (resource == null) return null;
669 //              
670 //              IPath path = resource.getFullPath();
671 //              IJavaElement element = null;
672 //              switch (elementType) {
673 //                      
674 //                      case IJavaElement.JAVA_PROJECT:
675 //                      
676 //                              // note that non-java resources rooted at the project level will also enter this code with
677 //                              // an elementType JAVA_PROJECT (see #elementType(...)).
678 //                              if (resource instanceof IProject){
679 //
680 //                                      this.popUntilPrefixOf(path);
681 //                                      
682 //                                      if (this.currentElement != null 
683 //                                              && this.currentElement.getElementType() == IJavaElement.JAVA_PROJECT
684 //                                              && ((IJavaProject)this.currentElement).getProject().equals(resource)) {
685 //                                              return this.currentElement;
686 //                                      }
687 //                                      if  (rootInfo != null && rootInfo.project.getProject().equals(resource)){
688 //                                              element = (Openable)rootInfo.project;
689 //                                              break;
690 //                                      }
691 //                                      IProject proj = (IProject)resource;
692 //                                      if (JavaProject.hasJavaNature(proj)) {
693 //                                              element = JavaCore.create(proj);
694 //                                      } else {
695 //                                              // java project may have been been closed or removed (look for
696 //                                              // element amongst old java project s list).
697 //                                              element =  (Openable) manager.getJavaModel().findJavaProject(proj);
698 //                                      }
699 //                              }
700 //                              break;
701 //                      case IJavaElement.PACKAGE_FRAGMENT_ROOT:
702 //                              element = rootInfo == null ? JavaCore.create(resource) : rootInfo.project.getPackageFragmentRoot(resource);
703 //                              break;
704 //                      case IJavaElement.PACKAGE_FRAGMENT:
705 //                              // find the element that encloses the resource
706 //                              this.popUntilPrefixOf(path);
707 //                              
708 //                              if (this.currentElement == null) {
709 //                                      element = rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
710 //                              } else {
711 //                                      // find the root
712 //                                      IPackageFragmentRoot root = this.currentElement.getPackageFragmentRoot();
713 //                                      if (root == null) {
714 //                                              element =  rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
715 //                                      } else if (((JavaProject)root.getJavaProject()).contains(resource)) {
716 //                                              // create package handle
717 //                                              IPath pkgPath = path.removeFirstSegments(root.getPath().segmentCount());
718 //                                              String pkg = Util.packageName(pkgPath);
719 //                                              if (pkg == null) return null;
720 //                                              element = root.getPackageFragment(pkg);
721 //                                      }
722 //                              }
723 //                              break;
724 //                      case IJavaElement.COMPILATION_UNIT:
725 //                      case IJavaElement.CLASS_FILE:
726 //                              // find the element that encloses the resource
727 //                              this.popUntilPrefixOf(path);
728 //                              
729 //                              if (this.currentElement == null) {
730 //                                      element =  rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
731 //                              } else {
732 //                                      // find the package
733 //                                      IPackageFragment pkgFragment = null;
734 //                                      switch (this.currentElement.getElementType()) {
735 //                                              case IJavaElement.PACKAGE_FRAGMENT_ROOT:
736 //                                                      IPackageFragmentRoot root = (IPackageFragmentRoot)this.currentElement;
737 //                                                      IPath rootPath = root.getPath();
738 //                                                      IPath pkgPath = path.removeLastSegments(1);
739 //                                                      String pkgName = Util.packageName(pkgPath.removeFirstSegments(rootPath.segmentCount()));
740 //                                                      if (pkgName != null) {
741 //                                                              pkgFragment = root.getPackageFragment(pkgName);
742 //                                                      }
743 //                                                      break;
744 //                                              case IJavaElement.PACKAGE_FRAGMENT:
745 //                                                      Openable pkg = (Openable)this.currentElement;
746 //                                                      if (pkg.getPath().equals(path.removeLastSegments(1))) {
747 //                                                              pkgFragment = (IPackageFragment)pkg;
748 //                                                      } // else case of package x which is a prefix of x.y
749 //                                                      break;
750 //                                              case IJavaElement.COMPILATION_UNIT:
751 //                                              case IJavaElement.CLASS_FILE:
752 //                                                      pkgFragment = (IPackageFragment)this.currentElement.getParent();
753 //                                                      break;
754 //                                      }
755 //                                      if (pkgFragment == null) {
756 //                                              element =  rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
757 //                                      } else {
758 //                                              if (elementType == IJavaElement.COMPILATION_UNIT) {
759 //                                                      // create compilation unit handle 
760 //                                                      // fileName validation has been done in elementType(IResourceDelta, int, boolean)
761 //                                                      String fileName = path.lastSegment();
762 //                                                      element = pkgFragment.getCompilationUnit(fileName);
763 //                                              } else {
764 //                                                      // create class file handle
765 //                                                      // fileName validation has been done in elementType(IResourceDelta, int, boolean)
766 //                                                      String fileName = path.lastSegment();
767 //                                                      element = pkgFragment.getClassFile(fileName);
768 //                                              }
769 //                                      }
770 //                              }
771 //                              break;
772 //              }
773 //              if (element == null) {
774 //                      return null;
775 //              } else {
776 //                      this.currentElement = (Openable)element;
777 //                      return this.currentElement;
778 //              }
779 //      }
780         /**
781          * Note that the project is about to be deleted.
782          */
783 //      public void deleting(IProject project) {
784 //              
785 //              try {
786 //                      // discard indexing jobs that belong to this project so that the project can be 
787 //                      // deleted without interferences from the index manager
788 //                      this.indexManager.discardJobs(project.getName());
789 //
790 //                      JavaProject javaProject = (JavaProject)JavaCore.create(project);
791 //                      
792 //                      // remember roots of this project
793 //                      if (this.removedRoots == null) {
794 //                              this.removedRoots = new HashMap();
795 //                      }
796 //                      if (javaProject.isOpen()) {
797 //                              this.removedRoots.put(javaProject, javaProject.getPackageFragmentRoots());
798 //                      } else {
799 //                              // compute roots without opening project
800 //                              this.removedRoots.put(
801 //                                      javaProject, 
802 //                                      javaProject.computePackageFragmentRoots(
803 //                                              javaProject.getResolvedClasspath(true), 
804 //                                              false));
805 //                      }
806 //                      
807 //                      javaProject.close();
808 //
809 //                      // workaround for bug 15168 circular errors not reported  
810 //                      if (this.manager.javaProjectsCache == null) {
811 //                              this.manager.javaProjectsCache = this.manager.getJavaModel().getJavaProjects();
812 //                      }
813 //                      this.removeFromParentInfo(javaProject);
814 //
815 //              } catch (JavaModelException e) {
816 //              }
817 //              
818 //              this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
819 //      }
820
821
822         /**
823          * Processing for an element that has been added:<ul>
824          * <li>If the element is a project, do nothing, and do not process
825          * children, as when a project is created it does not yet have any
826          * natures - specifically a java nature.
827          * <li>If the elemet is not a project, process it as added (see
828          * <code>basicElementAdded</code>.
829          * </ul>
830          * Delta argument could be null if processing an external JAR change
831          */
832 //      protected void elementAdded(Openable element, IResourceDelta delta, RootInfo rootInfo) {
833 //              int elementType = element.getElementType();
834 //              
835 //              if (elementType == IJavaElement.JAVA_PROJECT) {
836 //                      // project add is handled by JavaProject.configure() because
837 //                      // when a project is created, it does not yet have a java nature
838 //                      if (delta != null && JavaProject.hasJavaNature((IProject)delta.getResource())) {
839 //                              addToParentInfo(element);
840 //                              if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
841 //                                      Openable movedFromElement = (Openable)element.getJavaModel().getJavaProject(delta.getMovedFromPath().lastSegment());
842 //                                      currentDelta().movedTo(element, movedFromElement);
843 //                              } else {
844 //                                      currentDelta().added(element);
845 //                              }
846 //                              this.projectsToUpdate.add(element);
847 //                              this.updateRoots(element.getPath(), delta);
848 //                              this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
849 //                      }
850 //              } else {                        
851 //                      addToParentInfo(element);
852 //                      
853 //                      // Force the element to be closed as it might have been opened 
854 //                      // before the resource modification came in and it might have a new child
855 //                      // For example, in an IWorkspaceRunnable:
856 //                      // 1. create a package fragment p using a java model operation
857 //                      // 2. open package p
858 //                      // 3. add file X.java in folder p
859 //                      // When the resource delta comes in, only the addition of p is notified, 
860 //                      // but the package p is already opened, thus its children are not recomputed
861 //                      // and it appears empty.
862 //                      close(element);
863 //                      
864 //                      if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
865 //                              IPath movedFromPath = delta.getMovedFromPath();
866 //                              IResource res = delta.getResource();
867 //                              IResource movedFromRes;
868 //                              if (res instanceof IFile) {
869 //                                      movedFromRes = res.getWorkspace().getRoot().getFile(movedFromPath);
870 //                              } else {
871 //                                      movedFromRes = res.getWorkspace().getRoot().getFolder(movedFromPath);
872 //                              }
873 //                              
874 //                              // find the element type of the moved from element
875 //                              RootInfo movedFromInfo = this.enclosingRootInfo(movedFromPath, IResourceDelta.REMOVED);
876 //                              int movedFromType = 
877 //                                      this.elementType(
878 //                                              movedFromRes, 
879 //                                              IResourceDelta.REMOVED,
880 //                                              element.getParent().getElementType(), 
881 //                                              movedFromInfo);
882 //                              
883 //                              // reset current element as it might be inside a nested root (popUntilPrefixOf() may use the outer root)
884 //                              this.currentElement = null;
885 //                      
886 //                              // create the moved from element
887 //                              Openable movedFromElement = 
888 //                                      elementType != IJavaElement.JAVA_PROJECT && movedFromType == IJavaElement.JAVA_PROJECT ? 
889 //                                              null : // outside classpath
890 //                                              this.createElement(movedFromRes, movedFromType, movedFromInfo);
891 //                              if (movedFromElement == null) {
892 //                                      // moved from outside classpath
893 //                                      currentDelta().added(element);
894 //                              } else {
895 //                                      currentDelta().movedTo(element, movedFromElement);
896 //                              }
897 //                      } else {
898 //                              currentDelta().added(element);
899 //                      }
900 //                      
901 //                      switch (elementType) {
902 //                              case IJavaElement.PACKAGE_FRAGMENT_ROOT :
903 //                                      // when a root is added, and is on the classpath, the project must be updated
904 //                                      JavaProject project = (JavaProject) element.getJavaProject();
905 //                                      this.projectsToUpdate.add(project);
906 //                                      this.projectsForDependentNamelookupRefresh.add(project);
907 //                                      
908 //                                      break;
909 //                              case IJavaElement.PACKAGE_FRAGMENT :
910 //                                      // get rid of namelookup since it holds onto obsolete cached info 
911 //                                      project = (JavaProject) element.getJavaProject();
912 //                                      try {
913 //                                              project.getJavaProjectElementInfo().setNameLookup(null);
914 //                                              this.projectsForDependentNamelookupRefresh.add(project);                                                
915 //                                      } catch (JavaModelException e) {
916 //                                      }
917 //                                      // add subpackages
918 //                                      if (delta != null){
919 //                                              PackageFragmentRoot root = element.getPackageFragmentRoot();
920 //                                              String name = element.getElementName();
921 //                                              IResourceDelta[] children = delta.getAffectedChildren();
922 //                                              for (int i = 0, length = children.length; i < length; i++) {
923 //                                                      IResourceDelta child = children[i];
924 //                                                      IResource resource = child.getResource();
925 //                                                      if (resource instanceof IFolder) {
926 //                                                              String folderName = resource.getName();
927 //                                                              if (Util.isValidFolderNameForPackage(folderName)) {
928 //                                                                      String subpkgName = 
929 //                                                                              name.length() == 0 ? 
930 //                                                                                      folderName : 
931 //                                                                                      name + "." + folderName; //$NON-NLS-1$
932 //                                                                      Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
933 //                                                                      this.updateIndex(subpkg, child);
934 //                                                                      this.elementAdded(subpkg, child, rootInfo);
935 //                                                              }
936 //                                                      }
937 //                                              }
938 //                                      }
939 //                                      break;
940 //                      }
941 //              }
942 //      }
943
944         /**
945          * Generic processing for a removed element:<ul>
946          * <li>Close the element, removing its structure from the cache
947          * <li>Remove the element from its parent's cache of children
948          * <li>Add a REMOVED entry in the delta
949          * </ul>
950          * Delta argument could be null if processing an external JAR change
951          */
952 //      protected void elementRemoved(Openable element, IResourceDelta delta, RootInfo rootInfo) {
953 //              
954 //              if (element.isOpen()) {
955 //                      close(element);
956 //              }
957 //              removeFromParentInfo(element);
958 //              int elementType = element.getElementType();
959 //              if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
960 //                      IPath movedToPath = delta.getMovedToPath();
961 //                      IResource res = delta.getResource();
962 //                      IResource movedToRes;
963 //                      switch (res.getType()) {
964 //                              case IResource.PROJECT:
965 //                                      movedToRes = res.getWorkspace().getRoot().getProject(movedToPath.lastSegment());
966 //                                      break;
967 //                              case IResource.FOLDER:
968 //                                      movedToRes = res.getWorkspace().getRoot().getFolder(movedToPath);
969 //                                      break;
970 //                              case IResource.FILE:
971 //                                      movedToRes = res.getWorkspace().getRoot().getFile(movedToPath);
972 //                                      break;
973 //                              default:
974 //                                      return;
975 //                      }
976 //
977 //                      // find the element type of the moved from element
978 //                      RootInfo movedToInfo = this.enclosingRootInfo(movedToPath, IResourceDelta.ADDED);
979 //                      int movedToType = 
980 //                              this.elementType(
981 //                                      movedToRes, 
982 //                                      IResourceDelta.ADDED,
983 //                                      element.getParent().getElementType(), 
984 //                                      movedToInfo);
985 //
986 //                      // reset current element as it might be inside a nested root (popUntilPrefixOf() may use the outer root)
987 //                      this.currentElement = null;
988 //                      
989 //                      // create the moved To element
990 //                      Openable movedToElement = 
991 //                              elementType != IJavaElement.JAVA_PROJECT && movedToType == IJavaElement.JAVA_PROJECT ? 
992 //                                      null : // outside classpath
993 //                                      this.createElement(movedToRes, movedToType, movedToInfo);
994 //                      if (movedToElement == null) {
995 //                              // moved outside classpath
996 //                              currentDelta().removed(element);
997 //                      } else {
998 //                              currentDelta().movedFrom(element, movedToElement);
999 //                      }
1000 //              } else {
1001 //                      currentDelta().removed(element);
1002 //              }
1003 //
1004 //              switch (elementType) {
1005 //                      case IJavaElement.JAVA_MODEL :
1006 //                              this.indexManager.reset();
1007 //                              break;
1008 //                      case IJavaElement.JAVA_PROJECT :
1009 //                              this.manager.removePerProjectInfo(
1010 //                                      (JavaProject) element);
1011 //                              this.updateRoots(element.getPath(), delta);
1012 //                              this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
1013 //                              break;
1014 //                      case IJavaElement.PACKAGE_FRAGMENT_ROOT :
1015 //                              JavaProject project = (JavaProject) element.getJavaProject();
1016 //                              this.projectsToUpdate.add(project);
1017 //                              this.projectsForDependentNamelookupRefresh.add(project);                                
1018 //                              break;
1019 //                      case IJavaElement.PACKAGE_FRAGMENT :
1020 //                              //1G1TW2T - get rid of namelookup since it holds onto obsolete cached info 
1021 //                              project = (JavaProject) element.getJavaProject();
1022 //                              try {
1023 //                                      project.getJavaProjectElementInfo().setNameLookup(null); 
1024 //                                      this.projectsForDependentNamelookupRefresh.add(project);
1025 //                              } catch (JavaModelException e) { 
1026 //                              }
1027 //                              // remove subpackages
1028 //                              if (delta != null){
1029 //                                      PackageFragmentRoot root = element.getPackageFragmentRoot();
1030 //                                      String name = element.getElementName();
1031 //                                      IResourceDelta[] children = delta.getAffectedChildren();
1032 //                                      for (int i = 0, length = children.length; i < length; i++) {
1033 //                                              IResourceDelta child = children[i];
1034 //                                              IResource resource = child.getResource();
1035 //                                              if (resource instanceof IFolder) {
1036 //                                                      String folderName = resource.getName();
1037 //                                                      if (Util.isValidFolderNameForPackage(folderName)) {
1038 //                                                              String subpkgName = 
1039 //                                                                      name.length() == 0 ? 
1040 //                                                                              folderName : 
1041 //                                                                              name + "." + folderName; //$NON-NLS-1$
1042 //                                                              Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
1043 //                                                              this.updateIndex(subpkg, child);
1044 //                                                              this.elementRemoved(subpkg, child, rootInfo);
1045 //                                                      }
1046 //                                              }
1047 //                                      }
1048 //                              }
1049 //                              break;
1050 //              }
1051 //      }
1052
1053         /*
1054          * Returns the type of the java element the given delta matches to.
1055          * Returns NON_JAVA_RESOURCE if unknown (e.g. a non-java resource or excluded .java file)
1056          */
1057 //      private int elementType(IResource res, int kind, int parentType, RootInfo rootInfo) {
1058 //              switch (parentType) {
1059 //                      case IJavaElement.JAVA_MODEL:
1060 //                              // case of a movedTo or movedFrom project (other cases are handled in processResourceDelta(...)
1061 //                              return IJavaElement.JAVA_PROJECT;
1062 //                      case NON_JAVA_RESOURCE:
1063 //                      case IJavaElement.JAVA_PROJECT:
1064 //                              if (rootInfo == null) {
1065 //                                      rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1066 //                              }
1067 //                              if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
1068 //                                      return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1069 //                              } else {
1070 //                                      return NON_JAVA_RESOURCE; // not yet in a package fragment root or root of another project
1071 //                              }
1072 //                      case IJavaElement.PACKAGE_FRAGMENT_ROOT:
1073 //                      case IJavaElement.PACKAGE_FRAGMENT:
1074 //                              if (rootInfo == null) {
1075 //                                      rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
1076 //                              }
1077 //                              if (rootInfo == null || Util.isExcluded(res, rootInfo.exclusionPatterns)) {
1078 //                                      return NON_JAVA_RESOURCE;
1079 //                              }
1080 //                              if (res instanceof IFolder) {
1081 //                                      if (Util.isValidFolderNameForPackage(res.getName())) {
1082 //                                              return IJavaElement.PACKAGE_FRAGMENT;
1083 //                                      } else {
1084 //                                              return NON_JAVA_RESOURCE;
1085 //                                      }
1086 //                              } else {
1087 //                                      String fileName = res.getName();
1088 //                                      if (Util.isValidCompilationUnitName(fileName)) {
1089 //                                              return IJavaElement.COMPILATION_UNIT;
1090 //                                      } else if (Util.isValidClassFileName(fileName)) {
1091 //                                              return IJavaElement.CLASS_FILE;
1092 //                                      } else if (this.rootInfo(res.getFullPath(), kind) != null) {
1093 //                                              // case of proj=src=bin and resource is a jar file on the classpath
1094 //                                              return IJavaElement.PACKAGE_FRAGMENT_ROOT;
1095 //                                      } else {
1096 //                                              return NON_JAVA_RESOURCE;
1097 //                                      }
1098 //                              }
1099 //                      default:
1100 //                              return NON_JAVA_RESOURCE;
1101 //              }
1102 //      }
1103
1104         /**
1105          * Answer a combination of the lastModified stamp and the size.
1106          * Used for detecting external JAR changes
1107          */
1108         public static long getTimeStamp(File file) {
1109                 return file.lastModified() + file.length();
1110         }
1111
1112         public void initializeRoots() {
1113                 // remember roots infos as old roots infos
1114                 this.oldRoots = this.roots == null ? new HashMap() : this.roots;
1115                 this.oldOtherRoots = this.otherRoots == null ? new HashMap() : this.otherRoots;
1116                 
1117                 // recompute root infos only if necessary
1118                 if (!rootsAreStale) return;
1119
1120                 this.roots = new HashMap();
1121                 this.otherRoots = new HashMap();
1122                 this.sourceAttachments = new HashMap();
1123                 
1124                 IJavaModel model = this.manager.getJavaModel();
1125                 IJavaProject[] projects;
1126                 try {
1127                         projects = model.getJavaProjects();
1128                 } catch (JavaModelException e) {
1129                         // nothing can be done
1130                         return;
1131                 }
1132                 for (int i = 0, length = projects.length; i < length; i++) {
1133                         IJavaProject project = projects[i];
1134                         IClasspathEntry[] classpath;
1135                         try {
1136                                 classpath = project.getResolvedClasspath(true);
1137                         } catch (JavaModelException e) {
1138                                 // continue with next project
1139                                 continue;
1140                         }
1141                         for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) {
1142                                 IClasspathEntry entry = classpath[j];
1143                                 if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue;
1144                                 
1145 //                               root path
1146                                 IPath path = entry.getPath();
1147                                 if (this.roots.get(path) == null) {
1148                                         this.roots.put(path, new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars()));
1149                                 } else {
1150                                         ArrayList rootList = (ArrayList)this.otherRoots.get(path);
1151                                         if (rootList == null) {
1152                                                 rootList = new ArrayList();
1153                                                 this.otherRoots.put(path, rootList);
1154                                         }
1155                                         rootList.add(new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars()));
1156                                 }
1157                                 
1158                                 // source attachment path
1159                                 if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue;
1160                                 QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + path.toOSString()); //$NON-NLS-1$;
1161                                 String propertyString = null;
1162                                 try {
1163                                         propertyString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
1164                                 } catch (CoreException e) {
1165                                         continue;
1166                                 }
1167                                 IPath sourceAttachmentPath;
1168 //                              if (propertyString != null) {
1169 //                                      int index= propertyString.lastIndexOf(JarPackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER);
1170 //                                      sourceAttachmentPath = (index < 0) ?  new Path(propertyString) : new Path(propertyString.substring(0, index));
1171 //                              } else {
1172                                         sourceAttachmentPath = entry.getSourceAttachmentPath();
1173 //                              }
1174                                 if (sourceAttachmentPath != null) {
1175                                         this.sourceAttachments.put(sourceAttachmentPath, path);
1176                                 }
1177                         }
1178                 }
1179                 this.rootsAreStale = false;
1180         }
1181
1182         /*
1183          * Returns whether a given delta contains some information relevant to the JavaModel,
1184          * in particular it will not consider SYNC or MARKER only deltas.
1185          */
1186         public boolean isAffectedBy(IResourceDelta rootDelta){
1187                 //if (rootDelta == null) System.out.println("NULL DELTA");
1188                 //long start = System.currentTimeMillis();
1189                 if (rootDelta != null) {
1190                         // use local exception to quickly escape from delta traversal
1191                         class FoundRelevantDeltaException extends RuntimeException {}
1192                         try {
1193                                 rootDelta.accept(new IResourceDeltaVisitor() {
1194                                         public boolean visit(IResourceDelta delta) throws CoreException {
1195                                                 switch (delta.getKind()){
1196                                                         case IResourceDelta.ADDED :
1197                                                         case IResourceDelta.REMOVED :
1198                                                                 throw new FoundRelevantDeltaException();
1199                                                         case IResourceDelta.CHANGED :
1200                                                                 // if any flag is set but SYNC or MARKER, this delta should be considered
1201                                                                 if (delta.getAffectedChildren().length == 0 // only check leaf delta nodes
1202                                                                                 && (delta.getFlags() & ~(IResourceDelta.SYNC | IResourceDelta.MARKERS)) != 0) {
1203                                                                         throw new FoundRelevantDeltaException();
1204                                                                 }
1205                                                 }
1206                                                 return true;
1207                                         }
1208                                 });
1209                         } catch(FoundRelevantDeltaException e) {
1210                                 //System.out.println("RELEVANT DELTA detected in: "+ (System.currentTimeMillis() - start));
1211                                 return true;
1212                         } catch(CoreException e) { // ignore delta if not able to traverse
1213                         }
1214                 }
1215                 //System.out.println("IGNORE SYNC DELTA took: "+ (System.currentTimeMillis() - start));
1216                 return false;
1217         }
1218         
1219         /*
1220          * Returns whether the given resource is in one of the given output folders and if
1221          * it is filtered out from this output folder.
1222          */
1223         private boolean isResFilteredFromOutput(OutputsInfo info, IResource res, int elementType) {
1224                 if (info != null) {
1225                         IPath resPath = res.getFullPath();
1226                         for (int i = 0;  i < info.outputCount; i++) {
1227                                 if (info.paths[i].isPrefixOf(resPath)) {
1228                                         if (info.traverseModes[i] != IGNORE) {
1229                                                 // case of bin=src
1230                                                 if (info.traverseModes[i] == SOURCE && elementType == IJavaElement.CLASS_FILE) {
1231                                                         return true;
1232                                                 } else {
1233                                                         // case of .class file under project and no source folder
1234                                                         // proj=bin
1235                                                         if (elementType == IJavaElement.JAVA_PROJECT 
1236                                                                         && res instanceof IFile 
1237                                                                         && PHPFileUtil.isPHPFile((IFile)res)) {
1238                                                                 return true;
1239                                                         }
1240                                                 }
1241                                         } else {
1242                                                 return true;
1243                                         }
1244                                 }
1245                         }
1246                 }
1247                 return false;
1248         }
1249         /*
1250          * Merges all awaiting deltas.
1251          */
1252         private IJavaElementDelta mergeDeltas(Collection deltas) {
1253                 if (deltas.size() == 0) return null;
1254                 if (deltas.size() == 1) return (IJavaElementDelta)deltas.iterator().next();
1255                 
1256                 if (VERBOSE) {
1257                         System.out.println("MERGING " + deltas.size() + " DELTAS ["+Thread.currentThread()+"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1258                 }
1259                 
1260                 Iterator iterator = deltas.iterator();
1261                 JavaElementDelta rootDelta = new JavaElementDelta(this.manager.javaModel);
1262                 boolean insertedTree = false;
1263                 while (iterator.hasNext()) {
1264                         JavaElementDelta delta = (JavaElementDelta)iterator.next();
1265                         if (VERBOSE) {
1266                                 System.out.println(delta.toString());
1267                         }
1268                         IJavaElement element = delta.getElement();
1269                         if (this.manager.javaModel.equals(element)) {
1270                                 IJavaElementDelta[] children = delta.getAffectedChildren();
1271                                 for (int j = 0; j < children.length; j++) {
1272                                         JavaElementDelta projectDelta = (JavaElementDelta) children[j];
1273                                         rootDelta.insertDeltaTree(projectDelta.getElement(), projectDelta);
1274                                         insertedTree = true;
1275                                 }
1276                                 IResourceDelta[] resourceDeltas = delta.getResourceDeltas();
1277                                 if (resourceDeltas != null) {
1278                                         for (int i = 0, length = resourceDeltas.length; i < length; i++) {
1279                                                 rootDelta.addResourceDelta(resourceDeltas[i]);
1280                                                 insertedTree = true;
1281                                         }
1282                                 }
1283                         } else {
1284                                 rootDelta.insertDeltaTree(element, delta);
1285                                 insertedTree = true;
1286                         }
1287                 }
1288                 if (insertedTree) return rootDelta;
1289                 return null;
1290         }       
1291         
1292         /**
1293          * Check whether the updated file is affecting some of the properties of a given project (like
1294          * its classpath persisted as a file).
1295          * Also force classpath problems to be refresh if not running in autobuild mode.
1296          * NOTE: It can induce resource changes, and cannot be called during POST_CHANGE notification.
1297          *
1298          */
1299 //      public void performPreBuildCheck(
1300 //              IResourceDelta delta,
1301 //              IJavaElement parent) {
1302 //      
1303 //              IResource resource = delta.getResource();
1304 //              IJavaElement element = null;
1305 //              boolean processChildren = false;
1306 //      
1307 //              switch (resource.getType()) {
1308 //      
1309 //                      case IResource.ROOT :
1310 //                              if (delta.getKind() == IResourceDelta.CHANGED) {
1311 //                                      element = JavaCore.create(resource);
1312 //                                      processChildren = true;
1313 //                              }
1314 //                              break;
1315 //                      case IResource.PROJECT :
1316 //                              int kind = delta.getKind();
1317 //                              switch (kind) {
1318 //                                      case IResourceDelta.CHANGED:
1319 //                                              // do not visit non-java projects (see bug 16140 Non-java project gets .classpath)
1320 //                                              IProject project = (IProject)resource;
1321 //                                              if (JavaProject.hasJavaNature(project)) {
1322 //                                                      element = JavaCore.create(resource);
1323 //                                                      processChildren = true;
1324 //                                              } else if (JavaModelManager.getJavaModelManager().getJavaModel().findJavaProject(project) != null) {
1325 //                                                      // project had the java nature
1326 //                                                      this.rootsAreStale = true;
1327 //
1328 //                                                      // remove classpath cache so that initializeRoots() will not consider the project has a classpath
1329 //                                                      this.manager.removePerProjectInfo((JavaProject)JavaCore.create(project));
1330 //                                              }
1331 //                                              break;
1332 //                                      case IResourceDelta.ADDED:
1333 //                                              this.rootsAreStale = true;
1334 //                                              break;
1335 //                                      case IResourceDelta.REMOVED:
1336 //                                              // remove classpath cache so that initializeRoots() will not consider the project has a classpath
1337 //                                              this.manager.removePerProjectInfo((JavaProject)JavaCore.create(resource));
1338 //                                              
1339 //                                              this.rootsAreStale = true;
1340 //                                              break;
1341 //                              }
1342 //                              break;
1343 //                      case IResource.FILE :
1344 //                              if (parent.getElementType() == IJavaElement.JAVA_PROJECT) {
1345 //                                      IFile file = (IFile) resource;
1346 //                                      JavaProject project = (JavaProject) parent;
1347 //      
1348 //                                      /* check classpath file change */
1349 //                                      if (file.getName().equals(JavaProject.CLASSPATH_FILENAME)) {
1350 //                                              reconcileClasspathFileUpdate(delta, file, project);
1351 //                                              this.rootsAreStale = true;
1352 //                                              break;
1353 //                                      }
1354 ////                                    /* check custom preference file change */
1355 ////                                    if (file.getName().equals(JavaProject.PREF_FILENAME)) {
1356 ////                                            reconcilePreferenceFileUpdate(delta, file, project);
1357 ////                                            break;
1358 ////                                    }
1359 //                              }
1360 //                              break;
1361 //              }
1362 //              if (processChildren) {
1363 //                      IResourceDelta[] children = delta.getAffectedChildren();
1364 //                      for (int i = 0; i < children.length; i++) {
1365 //                              performPreBuildCheck(children[i], element);
1366 //                      }
1367 //              }
1368 //      }
1369         
1370 //      private void popUntilPrefixOf(IPath path) {
1371 //              while (this.currentElement != null) {
1372 //                      IPath currentElementPath = null;
1373 //                      if (this.currentElement instanceof IPackageFragmentRoot) {
1374 //                              currentElementPath = ((IPackageFragmentRoot)this.currentElement).getPath();
1375 //                      } else {
1376 //                              IResource currentElementResource = this.currentElement.getResource();
1377 //                              if (currentElementResource != null) {
1378 //                                      currentElementPath = currentElementResource.getFullPath();
1379 //                              }
1380 //                      }
1381 //                      if (currentElementPath != null) {
1382 //                              if (this.currentElement instanceof IPackageFragment 
1383 //                                      && this.currentElement.getElementName().length() == 0
1384 //                                      && currentElementPath.segmentCount() != path.segmentCount()-1) {
1385 //                                              // default package and path is not a direct child
1386 //                                              this.currentElement = (Openable)this.currentElement.getParent();
1387 //                              }
1388 //                              if (currentElementPath.isPrefixOf(path)) {
1389 //                                      return;
1390 //                              }
1391 //                      }
1392 //                      this.currentElement = (Openable)this.currentElement.getParent();
1393 //              }
1394 //      }
1395
1396         /**
1397          * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
1398          * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
1399          * relevant <code>JavaModel</code>s.
1400          */
1401
1402         /**
1403          * Update the JavaModel according to a .classpath file change. The file can have changed as a result of a previous
1404          * call to JavaProject#setRawClasspath or as a result of some user update (through repository)
1405          */
1406 //      void reconcileClasspathFileUpdate(IResourceDelta delta, IFile file, JavaProject project) {
1407 //                      
1408 //              switch (delta.getKind()) {
1409 //                      case IResourceDelta.REMOVED : // recreate one based on in-memory classpath
1410 //                              try {
1411 //                                      JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
1412 //                                      if (info.classpath != null) { // if there is an in-memory classpath
1413 //                                              project.saveClasspath(info.classpath, info.outputLocation);
1414 //                                      }
1415 //                              } catch (JavaModelException e) {
1416 //                                      if (project.getProject().isAccessible()) {
1417 //                                              Util.log(e, "Could not save classpath for "+ project.getPath()); //$NON-NLS-1$
1418 //                                      }
1419 //                              }
1420 //                              break;
1421 //                      case IResourceDelta.CHANGED :
1422 //                              if ((delta.getFlags() & IResourceDelta.CONTENT) == 0  // only consider content change
1423 //                                              && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move and overide scenario (see http://dev.eclipse.org/bugs/show_bug.cgi?id=21420)
1424 //                                      break;
1425 //                      case IResourceDelta.ADDED :
1426 //                              // check if any actual difference
1427 //                              project.flushClasspathProblemMarkers(false, true);
1428 //                              boolean wasSuccessful = false; // flag recording if .classpath file change got reflected
1429 //                              try {
1430 //                                      // force to (re)read the property file
1431 //                                      IClasspathEntry[] fileEntries = project.readClasspathFile(true/*create markers*/, false/*don't log problems*/);
1432 //                                      if (fileEntries == null)
1433 //                                              break; // could not read, ignore 
1434 //                                      JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
1435 //                                      if (info.classpath != null) { // if there is an in-memory classpath
1436 //                                              if (project.isClasspathEqualsTo(info.classpath, info.outputLocation, fileEntries)) {
1437 //                                                      wasSuccessful = true;
1438 //                                                      break;
1439 //                                              }
1440 //                                      }
1441 //              
1442 //                                      // will force an update of the classpath/output location based on the file information
1443 //                                      // extract out the output location
1444 //                                      IPath outputLocation = null;
1445 //                                      if (fileEntries != null && fileEntries.length > 0) {
1446 //                                              IClasspathEntry entry = fileEntries[fileEntries.length - 1];
1447 //                                              if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
1448 //                                                      outputLocation = entry.getPath();
1449 //                                                      IClasspathEntry[] copy = new IClasspathEntry[fileEntries.length - 1];
1450 //                                                      System.arraycopy(fileEntries, 0, copy, 0, copy.length);
1451 //                                                      fileEntries = copy;
1452 //                                              }
1453 //                                      }
1454 //                                      // restore output location                              
1455 //                                      if (outputLocation == null) {
1456 //                                              outputLocation = SetClasspathOperation.ReuseOutputLocation;
1457 //                                              // clean mode will also default to reusing current one
1458 //                                      }
1459 //                                      project.setRawClasspath(
1460 //                                              fileEntries, 
1461 //                                              outputLocation, 
1462 //                                              null, // monitor
1463 //                                              true, // canChangeResource
1464 //                                              project.getResolvedClasspath(true), // ignoreUnresolvedVariable
1465 //                                              true, // needValidation
1466 //                                              false); // no need to save
1467 //                                      
1468 //                                      // if reach that far, the classpath file change got absorbed
1469 //                                      wasSuccessful = true;
1470 //                              } catch (RuntimeException e) {
1471 //                                      // setRawClasspath might fire a delta, and a listener may throw an exception
1472 //                                      if (project.getProject().isAccessible()) {
1473 //                                              Util.log(e, "Could not set classpath for "+ project.getPath()); //$NON-NLS-1$
1474 //                                      }
1475 //                                      break;
1476 //                              } catch (JavaModelException e) { // CP failed validation
1477 //                                      if (project.getProject().isAccessible()) {
1478 //                                              if (e.getJavaModelStatus().getException() instanceof CoreException) {
1479 //                                                      // happens if the .classpath could not be written to disk
1480 //                                                      project.createClasspathProblemMarker(new JavaModelStatus(
1481 //                                                                      IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1482 //                                                                      Util.bind("classpath.couldNotWriteClasspathFile", project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1483 //                                              } else {
1484 //                                                      project.createClasspathProblemMarker(new JavaModelStatus(
1485 //                                                                      IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
1486 //                                                                      Util.bind("classpath.invalidClasspathInClasspathFile", project.getElementName(), e.getMessage()))); //$NON-NLS-1$
1487 //                                              }                       
1488 //                                      }
1489 //                                      break;
1490 //                              } finally {
1491 //                                      if (!wasSuccessful) { 
1492 //                                              try {
1493 //                                                      project.setRawClasspath0(JavaProject.INVALID_CLASSPATH);
1494 //                                                      project.updatePackageFragmentRoots();
1495 //                                              } catch (JavaModelException e) {
1496 //                                              }
1497 //                                      }
1498 //                              }
1499 //              }
1500 //      }
1501
1502         /**
1503          * Update the JavaModel according to a .jprefs file change. The file can have changed as a result of a previous
1504          * call to JavaProject#setOptions or as a result of some user update (through repository)
1505          * Unused until preference file get shared (.jpref)
1506          */
1507 //      void reconcilePreferenceFileUpdate(IResourceDelta delta, IFile file, JavaProject project) {
1508 //                      
1509 //              switch (delta.getKind()) {
1510 //                      case IResourceDelta.REMOVED : // flush project custom settings
1511 //                              project.setOptions(null);
1512 //                              return;
1513 //                      case IResourceDelta.CHANGED :
1514 //                              if ((delta.getFlags() & IResourceDelta.CONTENT) == 0  // only consider content change
1515 //                                              && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move and overide scenario
1516 //                                      break;
1517 //                              identityCheck : { // check if any actual difference
1518 //                                      // force to (re)read the property file
1519 //                                      Preferences filePreferences = project.loadPreferences();
1520 //                                      if (filePreferences == null){ 
1521 //                                              project.setOptions(null); // should have got removed delta.
1522 //                                              return;
1523 //                                      }
1524 //                                      Preferences projectPreferences = project.getPreferences();
1525 //                                      if (projectPreferences == null) return; // not a Java project
1526 //                                              
1527 //                                      // compare preferences set to their default
1528 //                                      String[] defaultProjectPropertyNames = projectPreferences.defaultPropertyNames();
1529 //                                      String[] defaultFilePropertyNames = filePreferences.defaultPropertyNames();
1530 //                                      if (defaultProjectPropertyNames.length == defaultFilePropertyNames.length) {
1531 //                                              for (int i = 0; i < defaultProjectPropertyNames.length; i++){
1532 //                                                      String propertyName = defaultProjectPropertyNames[i];
1533 //                                                      if (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1534 //                                                              break identityCheck;
1535 //                                                      }
1536 //                                              }               
1537 //                                      } else break identityCheck;
1538 //
1539 //                                      // compare custom preferences not set to their default
1540 //                                      String[] projectPropertyNames = projectPreferences.propertyNames();
1541 //                                      String[] filePropertyNames = filePreferences.propertyNames();
1542 //                                      if (projectPropertyNames.length == filePropertyNames.length) {
1543 //                                              for (int i = 0; i < projectPropertyNames.length; i++){
1544 //                                              String propertyName = projectPropertyNames[i];
1545 //                                                      if (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
1546 //                                                              break identityCheck;
1547 //                                                      }
1548 //                                              }               
1549 //                                      } else break identityCheck;
1550 //                                      
1551 //                                      // identical - do nothing
1552 //                                      return;
1553 //                              }
1554 //                      case IResourceDelta.ADDED :
1555 //                              // not identical, create delta and reset cached preferences
1556 //                              project.setPreferences(null);
1557 //                              // create delta
1558 //                              //fCurrentDelta.changed(project, IJavaElementDelta.F_OPTIONS_CHANGED);                          
1559 //              }
1560 //      }
1561         /*
1562          * Registers the given delta with this delta processor.
1563          */
1564         public void registerJavaModelDelta(IJavaElementDelta delta) {
1565                 this.javaModelDeltas.add(delta);
1566         }
1567         /**
1568          * Removes the given element from its parents cache of children. If the
1569          * element does not have a parent, or the parent is not currently open,
1570          * this has no effect. 
1571          */
1572         protected void removeFromParentInfo(Openable child) {
1573
1574                 Openable parent = (Openable) child.getParent();
1575                 if (parent != null && parent.isOpen()) {
1576                         try {
1577                                 JavaElementInfo info = (JavaElementInfo)parent.getElementInfo();
1578                                 info.removeChild(child);
1579                         } catch (JavaModelException e) {
1580                                 // do nothing - we already checked if open
1581                         }
1582                 }
1583         }
1584         
1585         /**
1586          * Notification that some resource changes have happened
1587          * on the platform, and that the Java Model should update any required
1588          * internal structures such that its elements remain consistent.
1589          * Translates <code>IResourceDeltas</code> into <code>IJavaElementDeltas</code>.
1590          *
1591          * @see IResourceDelta
1592          * @see IResource 
1593          */
1594         public void resourceChanged(IResourceChangeEvent event) {
1595           if (event.getSource() instanceof IWorkspace) {
1596                 int eventType = this.overridenEventType == -1 ? event.getType() : this.overridenEventType;
1597                 IResource resource = event.getResource();
1598                 IResourceDelta delta = event.getDelta();
1599                 
1600                 switch(eventType){
1601                         case IResourceChangeEvent.PRE_DELETE :
1602                                 try {
1603                                   if(resource.getType() == IResource.PROJECT 
1604                                                 && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1605                                         
1606                                                 deleting((IProject)resource);
1607                                         }
1608                                 } catch(CoreException e){
1609                                         // project doesn't exist or is not open: ignore
1610                                 }
1611                                 return;
1612                                 
1613                         case IResourceChangeEvent.POST_CHANGE :
1614                                 if (isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
1615                                         try {
1616                                                 try {
1617                                                         stopDeltas();
1618 //                                                      checkProjectsBeingAddedOrRemoved(delta);
1619 //                                                      if (this.refreshedElements != null) {
1620 //                                                              createExternalArchiveDelta(null);
1621 //                                                      }
1622                                                         IJavaElementDelta translatedDelta = processResourceDelta(delta);
1623                                                         if (translatedDelta != null) { 
1624                                                                 registerJavaModelDelta(translatedDelta);
1625                                                         }
1626                                                 } finally {
1627                                                         startDeltas();
1628                                                 }
1629 //                                              notifyTypeHierarchies(this.state.elementChangedListeners, this.state.elementChangedListenerCount);
1630                                                 fire(null, ElementChangedEvent.POST_CHANGE);
1631                                         } finally {
1632                                                 // workaround for bug 15168 circular errors not reported 
1633                                                 this.state.modelProjectsCache = null;
1634                                                 this.removedRoots = null;
1635                                         }
1636                                 }
1637                                 return;
1638                                 
1639                         case IResourceChangeEvent.PRE_BUILD :
1640                             DeltaProcessingState.ProjectUpdateInfo[] updates = this.state.removeAllProjectUpdates();
1641                                 if (updates != null) {
1642                                     for (int i = 0, length = updates.length; i < length; i++) {
1643                                         try {
1644                                                 updates[i].updateProjectReferencesIfNecessary();
1645                                         } catch(JavaModelException e) {
1646                                             // do nothing
1647                                         }
1648                                     }
1649                                 }
1650                                 // this.processPostChange = false;
1651                                 if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
1652 //                                      updateClasspathMarkers(delta);
1653                                         PHPBuilder.buildStarting();
1654                                 }
1655                                 // does not fire any deltas
1656                                 return;
1657
1658                         case IResourceChangeEvent.POST_BUILD :
1659                                 PHPBuilder.buildFinished();
1660                                 return;
1661                 }
1662         }
1663 //              // jsurfer TODO compare 3.0 sources
1664 //              if (event.getSource() instanceof IWorkspace) {
1665 //                      int eventType = this.overridenEventType == -1 ? event.getType() : this.overridenEventType;
1666 //                      IResource resource = event.getResource();
1667 //                      IResourceDelta delta = event.getDelta();
1668 //                      
1669 //                      switch(eventType){
1670 //                              case IResourceChangeEvent.PRE_DELETE :
1671 //                                      try {
1672 //                                              if(resource.getType() == IResource.PROJECT 
1673 //                                                      && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
1674 //                                              // TODO jsurfer temp-del
1675 ////                                                    this.deleting((IProject)resource);
1676 //                                              }
1677 //                                      } catch(CoreException e){
1678 //                                      }
1679 //                                      return;
1680 //                                      
1681 //                              case IResourceChangeEvent.PRE_BUILD :
1682 ////                    TODO jsurfer temp-del
1683 ////                                    if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
1684 ////                                            this.checkProjectsBeingAddedOrRemoved(delta);
1685 ////                                            
1686 ////                                            // update the classpath related markers
1687 ////                                            this.updateClasspathMarkers();
1688 ////    
1689 ////                                            // the following will close project if affected by the property file change
1690 ////                                            try {
1691 ////                                                    // don't fire classpath change deltas right away, but batch them
1692 ////                                                    this.manager.stopDeltas();
1693 ////                                                    this.performPreBuildCheck(delta, null); 
1694 ////                                            } finally {
1695 ////                                                    this.manager.startDeltas();
1696 ////                                            }
1697 ////                                    }
1698 //                                      // only fire already computed deltas (resource ones will be processed in post change only)
1699 //                                      this.manager.fire(null, ElementChangedEvent.PRE_AUTO_BUILD);
1700 //                                      break;
1701 //
1702 //                              case IResourceChangeEvent.POST_BUILD :
1703 ////                    TODO jsurfer temp-del
1704 ////                                    JavaBuilder.finishedBuilding(event);
1705 //                                      break;
1706 //                                      
1707 //                              case IResourceChangeEvent.POST_CHANGE :
1708 ////                    TODO jsurfer temp-del
1709 ////                                    if (isAffectedBy(delta)) {
1710 ////                                            try {
1711 ////                                                    if (this.refreshedElements != null) {
1712 ////                                                            try {
1713 ////                                                                    createExternalArchiveDelta(null);
1714 ////                                                            } catch (JavaModelException e) {
1715 ////                                                                    e.printStackTrace();
1716 ////                                                            }
1717 ////                                                    }
1718 ////                                                    IJavaElementDelta translatedDelta = this.processResourceDelta(delta);
1719 ////                                                    if (translatedDelta != null) { 
1720 ////                                                            this.manager.registerJavaModelDelta(translatedDelta);
1721 ////                                                    }
1722 ////                                                    this.manager.fire(null, ElementChangedEvent.POST_CHANGE);
1723 ////                                            } finally {
1724 ////                                                    // workaround for bug 15168 circular errors not reported 
1725 ////                                                    this.manager.javaProjectsCache = null;
1726 ////                                                    this.removedRoots = null;
1727 ////                                            }
1728 ////                                    }
1729 //                      }
1730 //              }
1731         }
1732         /*
1733          * Turns the firing mode to on. That is, deltas that are/have been
1734          * registered will be fired.
1735          */
1736         private void startDeltas() {
1737                 this.isFiring= true;
1738         }
1739         /*
1740          * Turns the firing mode to off. That is, deltas that are/have been
1741          * registered will not be fired until deltas are started again.
1742          */
1743         private void stopDeltas() {
1744                 this.isFiring= false;
1745         }
1746         /*
1747          * Note that the project is about to be deleted.
1748          */
1749         private void deleting(IProject project) {
1750                 
1751                 try {
1752                         // discard indexing jobs that belong to this project so that the project can be 
1753                         // deleted without interferences from the index manager
1754 //                      this.manager.indexManager.discardJobs(project.getName());
1755
1756                         JavaProject javaProject = (JavaProject)JavaCore.create(project);
1757                         
1758                         // remember roots of this project
1759                         if (this.removedRoots == null) {
1760                                 this.removedRoots = new HashMap();
1761                         }
1762                         if (javaProject.isOpen()) {
1763                                 this.removedRoots.put(javaProject, javaProject.getPackageFragmentRoots());
1764                         } else {
1765                                 // compute roots without opening project
1766 //                              this.removedRoots.put(
1767 //                                      javaProject, 
1768 //                                      javaProject.computePackageFragmentRoots(
1769 //                                              javaProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/), 
1770 //                                              false));
1771                         }
1772                         
1773                         javaProject.close();
1774
1775                         // workaround for bug 15168 circular errors not reported
1776                         if (this.state.modelProjectsCache == null) {
1777                                 this.state.modelProjectsCache = this.manager.getJavaModel().getJavaProjects();
1778                         }
1779                         this.removeFromParentInfo(javaProject);
1780
1781                 } catch (JavaModelException e) {
1782                         // java project doesn't exist: ignore
1783                 }
1784         }
1785         /*
1786          * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
1787          * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
1788          * relevant <code>JavaModel</code>s.
1789          */
1790         private IJavaElementDelta processResourceDelta(IResourceDelta changes) {
1791
1792                 try {
1793                         IJavaModel model = this.manager.getJavaModel();
1794                         if (!model.isOpen()) {
1795                                 // force opening of java model so that java element delta are reported
1796                                 try {
1797                                         model.open(null);
1798                                 } catch (JavaModelException e) {
1799                                         if (VERBOSE) {
1800                                                 e.printStackTrace();
1801                                         }
1802                                         return null;
1803                                 }
1804                         }
1805                         this.state.initializeRoots();
1806                         this.currentElement = null;
1807                         
1808                         // get the workspace delta, and start processing there.
1809                         IResourceDelta[] deltas = changes.getAffectedChildren();
1810                         for (int i = 0; i < deltas.length; i++) {
1811                                 IResourceDelta delta = deltas[i];
1812                                 IResource res = delta.getResource();
1813                                 
1814                                 // find out the element type
1815                                 RootInfo rootInfo = null;
1816                                 int elementType;
1817                                 IProject proj = (IProject)res;
1818                                 boolean wasJavaProject = this.manager.getJavaModel().findJavaProject(proj) != null;
1819                                 boolean isJavaProject = JavaProject.hasJavaNature(proj);
1820                                 if (!wasJavaProject && !isJavaProject) {
1821                                         elementType = NON_JAVA_RESOURCE;
1822                                 } else {
1823                                         rootInfo = this.enclosingRootInfo(res.getFullPath(), delta.getKind());
1824                                         if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
1825                                                 elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
1826                                         } else {
1827                                                 elementType = IJavaElement.JAVA_PROJECT; 
1828                                         }
1829                                 }
1830                                 
1831                                 // traverse delta
1832 //                              this.traverseDelta(delta, elementType, rootInfo, null);
1833                                 
1834                                 if (elementType == NON_JAVA_RESOURCE
1835                                                 || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project has changed nature (description or open/closed)
1836                                         try {
1837                                                 // add child as non java resource
1838                                                 nonJavaResourcesChanged((JavaModel)model, delta);
1839                                         } catch (JavaModelException e) {
1840                                                 // java model could not be opened
1841                                         }
1842                                 }
1843
1844                         }
1845 //                      refreshPackageFragmentRoots();
1846 //                      resetProjectCaches();
1847
1848                         return this.currentDelta;
1849                 } finally {
1850                         this.currentDelta = null;
1851 //                      this.rootsToRefresh.clear();
1852 //                      this.projectCachesToReset.clear();
1853                 }
1854         }
1855         
1856         /*
1857          * Converts an <code>IResourceDelta</code> and its children into
1858          * the corresponding <code>IJavaElementDelta</code>s.
1859          */
1860 //      private void traverseDelta(
1861 //              IResourceDelta delta, 
1862 //              int elementType, 
1863 //              RootInfo rootInfo,
1864 //              OutputsInfo outputsInfo) {
1865 //                      
1866 //              IResource res = delta.getResource();
1867 //      
1868 //              // set stack of elements
1869 //              if (this.currentElement == null && rootInfo != null) {
1870 ////                    this.currentElement = rootInfo.project;
1871 //              }
1872 //              
1873 //              // process current delta
1874 //              boolean processChildren = true;
1875 //              if (res instanceof IProject) {
1876 //                      processChildren = 
1877 //                              this.updateCurrentDeltaAndIndex(
1878 //                                      delta, 
1879 //                                      elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ? 
1880 //                                              IJavaElement.JAVA_PROJECT : // case of prj=src
1881 //                                              elementType, 
1882 //                                      rootInfo);
1883 //              } else if (rootInfo != null) {
1884 //                      processChildren = this.updateCurrentDeltaAndIndex(delta, elementType, rootInfo);
1885 //              } else {
1886 //                      // not yet inside a package fragment root
1887 //                      processChildren = true;
1888 //              }
1889 //              
1890 //              // get the project's output locations and traverse mode
1891 //              if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
1892 //      
1893 //              // process children if needed
1894 //              if (processChildren) {
1895 //                      IResourceDelta[] children = delta.getAffectedChildren();
1896 //                      boolean oneChildOnClasspath = false;
1897 //                      int length = children.length;
1898 //                      IResourceDelta[] orphanChildren = null;
1899 //                      Openable parent = null;
1900 //                      boolean isValidParent = true;
1901 //                      for (int i = 0; i < length; i++) {
1902 //                              IResourceDelta child = children[i];
1903 //                              IResource childRes = child.getResource();
1904 //      
1905 //                              // check source attachment change
1906 //                              this.checkSourceAttachmentChange(child, childRes);
1907 //                              
1908 //                              // find out whether the child is a package fragment root of the current project
1909 //                              IPath childPath = childRes.getFullPath();
1910 //                              int childKind = child.getKind();
1911 //                              RootInfo childRootInfo = this.rootInfo(childPath, childKind);
1912 //                              if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
1913 //                                      // package fragment root of another project (dealt with later)
1914 //                                      childRootInfo = null;
1915 //                              }
1916 //                              
1917 //                              // compute child type
1918 //                              int childType = 
1919 //                                      this.elementType(
1920 //                                              childRes, 
1921 //                                              childKind,
1922 //                                              elementType, 
1923 //                                              rootInfo == null ? childRootInfo : rootInfo
1924 //                                      );
1925 //                                              
1926 //                              // is childRes in the output folder and is it filtered out ?
1927 //                              boolean isResFilteredFromOutput = this.isResFilteredFromOutput(outputsInfo, childRes, childType);
1928 //
1929 //                              boolean isNestedRoot = rootInfo != null && childRootInfo != null;
1930 //                              if (!isResFilteredFromOutput 
1931 //                                              && !isNestedRoot) { // do not treat as non-java rsc if nested root
1932 //
1933 //                                      this.traverseDelta(child, childType, rootInfo == null ? childRootInfo : rootInfo, outputsInfo); // traverse delta for child in the same project
1934 //
1935 //                                      if (childType == NON_JAVA_RESOURCE) {
1936 //                                              if (rootInfo != null) { // if inside a package fragment root
1937 //                                                      if (!isValidParent) continue; 
1938 //                                                      if (parent == null) {
1939 //                                                              // find the parent of the non-java resource to attach to
1940 //                                                              if (this.currentElement == null
1941 //                                                                              || !rootInfo.project.equals(this.currentElement.getJavaProject())) { // note if currentElement is the IJavaModel, getJavaProject() is null
1942 //                                                                      // force the currentProject to be used
1943 //                                                                      this.currentElement = rootInfo.project;
1944 //                                                              }
1945 //                                                              if (elementType == IJavaElement.JAVA_PROJECT
1946 //                                                                      || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT 
1947 //                                                                              && res instanceof IProject)) { 
1948 //                                                                      // NB: attach non-java resource to project (not to its package fragment root)
1949 //                                                                      parent = rootInfo.project;
1950 //                                                              } else {
1951 //                                                                      parent = this.createElement(res, elementType, rootInfo);
1952 //                                                              }
1953 //                                                              if (parent == null) {
1954 //                                                                      isValidParent = false;
1955 //                                                                      continue;
1956 //                                                              }
1957 //                                                      }
1958 //                                                      // add child as non java resource
1959 //                                                      try {
1960 //                                                              nonJavaResourcesChanged(parent, child);
1961 //                                                      } catch (JavaModelException e) {
1962 //                                                              // ignore
1963 //                                                      }
1964 //                                              } else {
1965 //                                                      // the non-java resource (or its parent folder) will be attached to the java project
1966 //                                                      if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
1967 //                                                      orphanChildren[i] = child;
1968 //                                              }
1969 //                                      } else {
1970 //                                              oneChildOnClasspath = true;
1971 //                                      }
1972 //                              } else {
1973 //                                      oneChildOnClasspath = true; // to avoid reporting child delta as non-java resource delta
1974 //                              }
1975 //                                                              
1976 //                              // if child is a nested root 
1977 //                              // or if it is not a package fragment root of the current project
1978 //                              // but it is a package fragment root of another project, traverse delta too
1979 //                              if (isNestedRoot 
1980 //                                              || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath, childKind)) != null)) {
1981 //                                      this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
1982 //                              }
1983 //      
1984 //                              // if the child is a package fragment root of one or several other projects
1985 //                              ArrayList rootList;
1986 //                              if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
1987 //                                      Iterator iterator = rootList.iterator();
1988 //                                      while (iterator.hasNext()) {
1989 //                                              childRootInfo = (RootInfo) iterator.next();
1990 //                                              this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
1991 //                                      }
1992 //                              }
1993 //                      }
1994 //                      if (orphanChildren != null
1995 //                                      && (oneChildOnClasspath // orphan children are siblings of a package fragment root
1996 //                                              || res instanceof IProject)) { // non-java resource directly under a project
1997 //                                              
1998 //                              // attach orphan children
1999 //                              IProject rscProject = res.getProject();
2000 //                              JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
2001 //                              if (adoptiveProject != null 
2002 //                                              && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project (18698)
2003 //                                      for (int i = 0; i < length; i++) {
2004 //                                              if (orphanChildren[i] != null) {
2005 //                                                      try {
2006 //                                                              nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
2007 //                                                      } catch (JavaModelException e) {
2008 //                                                              // ignore
2009 //                                                      }
2010 //                                              }
2011 //                                      }
2012 //                              }
2013 //                      } // else resource delta will be added by parent
2014 //              } // else resource delta will be added by parent
2015 //      }
2016         private void notifyListeners(IJavaElementDelta deltaToNotify, int eventType, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
2017                 final ElementChangedEvent extraEvent = new ElementChangedEvent(deltaToNotify, eventType);
2018                 for (int i= 0; i < listenerCount; i++) {
2019                         if ((listenerMask[i] & eventType) != 0){
2020                                 final IElementChangedListener listener = listeners[i];
2021                                 long start = -1;
2022                                 if (VERBOSE) {
2023                                         System.out.print("Listener #" + (i+1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
2024                                         start = System.currentTimeMillis();
2025                                 }
2026                                 // wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
2027                                 Platform.run(new ISafeRunnable() {
2028                                         public void handleException(Throwable exception) {
2029                                                 Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
2030                                         }
2031                                         public void run() throws Exception {
2032                                                 listener.elementChanged(extraEvent);
2033                                         }
2034                                 });
2035                                 if (VERBOSE) {
2036                                         System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
2037                                 }
2038                         }
2039                 }
2040         }
2041 //      private void notifyTypeHierarchies(IElementChangedListener[] listeners, int listenerCount) {
2042 //              for (int i= 0; i < listenerCount; i++) {
2043 //                      final IElementChangedListener listener = listeners[i];
2044 //                      if (!(listener instanceof TypeHierarchy)) continue;
2045 //
2046 //                      // wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
2047 //                      Platform.run(new ISafeRunnable() {
2048 //                              public void handleException(Throwable exception) {
2049 //                                      Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
2050 //                              }
2051 //                              public void run() throws Exception {
2052 //                                      TypeHierarchy typeHierarchy = (TypeHierarchy)listener;
2053 //                                      if (typeHierarchy.hasFineGrainChanges()) {
2054 //                                              // case of changes in primary working copies
2055 //                                              typeHierarchy.needsRefresh = true;
2056 //                                              typeHierarchy.fireChange();
2057 //                                      }
2058 //                              }
2059 //                      });
2060 //              }
2061 //      }
2062         /*
2063          * Generic processing for elements with changed contents:<ul>
2064          * <li>The element is closed such that any subsequent accesses will re-open
2065          * the element reflecting its new structure.
2066          * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
2067          * </ul>
2068          */
2069         private void nonJavaResourcesChanged(Openable element, IResourceDelta delta)
2070                 throws JavaModelException {
2071
2072                 // reset non-java resources if element was open
2073                 if (element.isOpen()) {
2074                         JavaElementInfo info = (JavaElementInfo)element.getElementInfo();
2075                         switch (element.getElementType()) {
2076                                 case IJavaElement.JAVA_MODEL :
2077                                         ((JavaModelInfo) info).nonJavaResources = null;
2078                                         currentDelta().addResourceDelta(delta);
2079                                         return;
2080                                 case IJavaElement.JAVA_PROJECT :
2081                                         ((JavaProjectElementInfo) info).setNonJavaResources(null);
2082         
2083                                         // if a package fragment root is the project, clear it too
2084                                         JavaProject project = (JavaProject) element;
2085                                         PackageFragmentRoot projectRoot =
2086                                                 (PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject());
2087                                         if (projectRoot.isOpen()) {
2088                                                 ((PackageFragmentRootInfo) projectRoot.getElementInfo()).setNonJavaResources(
2089                                                         null);
2090                                         }
2091                                         break;
2092                                 case IJavaElement.PACKAGE_FRAGMENT :
2093                                          ((PackageFragmentInfo) info).setNonJavaResources(null);
2094                                         break;
2095                                 case IJavaElement.PACKAGE_FRAGMENT_ROOT :
2096                                          ((PackageFragmentRootInfo) info).setNonJavaResources(null);
2097                         }
2098                 }
2099
2100                 JavaElementDelta current = currentDelta();
2101                 JavaElementDelta elementDelta = current.find(element);
2102                 if (elementDelta == null) {
2103                         // don't use find after creating the delta as it can be null (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63434)
2104                         elementDelta = current.changed(element, IJavaElementDelta.F_CONTENT);
2105                 }
2106                 elementDelta.addResourceDelta(delta);
2107         }
2108         /*
2109          * Flushes all deltas without firing them.
2110          */
2111         public void flush() {
2112                 this.javaModelDeltas = new ArrayList();
2113         }
2114         /*
2115          * Finds the root info this path is included in.
2116          * Returns null if not found.
2117          */
2118         RootInfo enclosingRootInfo(IPath path, int kind) {
2119                 while (path != null && path.segmentCount() > 0) {
2120                         RootInfo rootInfo =  this.rootInfo(path, kind);
2121                         if (rootInfo != null) return rootInfo;
2122                         path = path.removeLastSegments(1);
2123                 }
2124                 return null;
2125         }
2126         /*
2127          * Fire Java Model delta, flushing them after the fact after post_change notification.
2128          * If the firing mode has been turned off, this has no effect. 
2129          */
2130         public void fire(IJavaElementDelta customDelta, int eventType) {
2131                 if (!this.isFiring) return;
2132                 
2133                 if (DEBUG) {
2134                         System.out.println("-----------------------------------------------------------------------------------------------------------------------");//$NON-NLS-1$
2135                 }
2136
2137                 IJavaElementDelta deltaToNotify;
2138                 if (customDelta == null){
2139                         deltaToNotify = this.mergeDeltas(this.javaModelDeltas);
2140                 } else {
2141                         deltaToNotify = customDelta;
2142                 }
2143                         
2144                 // Refresh internal scopes
2145 //              if (deltaToNotify != null) {
2146 //                      Iterator scopes = this.manager.searchScopes.keySet().iterator();
2147 //                      while (scopes.hasNext()) {
2148 //                              AbstractSearchScope scope = (AbstractSearchScope)scopes.next();
2149 //                              scope.processDelta(deltaToNotify);
2150 //                      }
2151 //              }
2152                         
2153                 // Notification
2154         
2155                 // Important: if any listener reacts to notification by updating the listeners list or mask, these lists will
2156                 // be duplicated, so it is necessary to remember original lists in a variable (since field values may change under us)
2157                 IElementChangedListener[] listeners = this.state.elementChangedListeners;
2158                 int[] listenerMask = this.state.elementChangedListenerMasks;
2159                 int listenerCount = this.state.elementChangedListenerCount;
2160
2161                 switch (eventType) {
2162                         case DEFAULT_CHANGE_EVENT:
2163                                 firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount);
2164                                 fireReconcileDelta(listeners, listenerMask, listenerCount);
2165                                 break;
2166                         case ElementChangedEvent.POST_CHANGE:
2167                                 firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount);
2168                                 fireReconcileDelta(listeners, listenerMask, listenerCount);
2169                                 break;
2170                 }
2171         }
2172         
2173         private void firePostChangeDelta(
2174                         IJavaElementDelta deltaToNotify,
2175                         IElementChangedListener[] listeners,
2176                         int[] listenerMask,
2177                         int listenerCount) {
2178                                 
2179                         // post change deltas
2180                         if (DEBUG){
2181                                 System.out.println("FIRING POST_CHANGE Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
2182                                 System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
2183                         }
2184                         if (deltaToNotify != null) {
2185                                 // flush now so as to keep listener reactions to post their own deltas for subsequent iteration
2186                                 this.flush();
2187                                 
2188                                 notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE, listeners, listenerMask, listenerCount);
2189                         } 
2190                 }               
2191                 private void fireReconcileDelta(
2192                         IElementChangedListener[] listeners,
2193                         int[] listenerMask,
2194                         int listenerCount) {
2195
2196
2197                         IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas.values());
2198                         if (DEBUG){
2199                                 System.out.println("FIRING POST_RECONCILE Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
2200                                 System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
2201                         }
2202                         if (deltaToNotify != null) {
2203                                 // flush now so as to keep listener reactions to post their own deltas for subsequent iteration
2204                                 this.reconcileDeltas = new HashMap();
2205                         
2206                                 notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE, listeners, listenerMask, listenerCount);
2207                         } 
2208                 }
2209         /*
2210          * Returns the root info for the given path. Look in the old roots table if kind is REMOVED.
2211          */
2212         RootInfo rootInfo(IPath path, int kind) {
2213                 if (kind == IResourceDelta.REMOVED) {
2214                         return (RootInfo)this.oldRoots.get(path);
2215                 } else {
2216                         return (RootInfo)this.roots.get(path);
2217                 }
2218         }
2219         /*
2220          * Returns the other root infos for the given path. Look in the old other roots table if kind is REMOVED.
2221          */
2222         ArrayList otherRootsInfo(IPath path, int kind) {
2223                 if (kind == IResourceDelta.REMOVED) {
2224                         return (ArrayList)this.oldOtherRoots.get(path);
2225                 } else {
2226                         return (ArrayList)this.otherRoots.get(path);
2227                 }
2228         }       
2229
2230         /**
2231          * Converts an <code>IResourceDelta</code> and its children into
2232          * the corresponding <code>IJavaElementDelta</code>s.
2233          * Return whether the delta corresponds to a java element.
2234          * If it is not a java element, it will be added as a non-java
2235          * resource by the sender of this method.
2236          */
2237 //      protected boolean traverseDelta(
2238 //              IResourceDelta delta, 
2239 //              int elementType, 
2240 //              RootInfo rootInfo,
2241 //              OutputsInfo outputsInfo) {
2242 //                      
2243 //              IResource res = delta.getResource();
2244 //      
2245 //              // set stack of elements
2246 //              if (this.currentElement == null && rootInfo != null) {
2247 //                      this.currentElement = (Openable)rootInfo.project;
2248 //              }
2249 //              
2250 //              // process current delta
2251 //              boolean processChildren = true;
2252 //              if (res instanceof IProject) {
2253 //                      processChildren = 
2254 //                              this.updateCurrentDeltaAndIndex(
2255 //                                      delta, 
2256 //                                      elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ? 
2257 //                                              IJavaElement.JAVA_PROJECT : // case of prj=src
2258 //                                              elementType, 
2259 //                                      rootInfo);
2260 //              } else if (rootInfo != null) {
2261 //                      processChildren = this.updateCurrentDeltaAndIndex(delta, elementType, rootInfo);
2262 //              } else {
2263 //                      // not yet inside a package fragment root
2264 //                      processChildren = true;
2265 //              }
2266 //              
2267 //              // get the project's output locations and traverse mode
2268 //              if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
2269 //      
2270 //              // process children if needed
2271 //              if (processChildren) {
2272 //                      IResourceDelta[] children = delta.getAffectedChildren();
2273 //                      boolean oneChildOnClasspath = false;
2274 //                      int length = children.length;
2275 //                      IResourceDelta[] orphanChildren = null;
2276 //                      Openable parent = null;
2277 //                      boolean isValidParent = true;
2278 //                      for (int i = 0; i < length; i++) {
2279 //                              IResourceDelta child = children[i];
2280 //                              IResource childRes = child.getResource();
2281 //      
2282 //                              // check source attachment change
2283 //                              this.checkSourceAttachmentChange(child, childRes);
2284 //                              
2285 //                              // find out whether the child is a package fragment root of the current project
2286 //                              IPath childPath = childRes.getFullPath();
2287 //                              int childKind = child.getKind();
2288 //                              RootInfo childRootInfo = this.rootInfo(childPath, childKind);
2289 //                              if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
2290 //                                      // package fragment root of another project (dealt with later)
2291 //                                      childRootInfo = null;
2292 //                              }
2293 //                              
2294 //                              // compute child type
2295 //                              int childType = 
2296 //                                      this.elementType(
2297 //                                              childRes, 
2298 //                                              childKind,
2299 //                                              elementType, 
2300 //                                              rootInfo == null ? childRootInfo : rootInfo
2301 //                                      );
2302 //                                              
2303 //                              // is childRes in the output folder and is it filtered out ?
2304 //                              boolean isResFilteredFromOutput = this.isResFilteredFromOutput(outputsInfo, childRes, childType);
2305 //
2306 //                              boolean isNestedRoot = rootInfo != null && childRootInfo != null;
2307 //                              if (!isResFilteredFromOutput 
2308 //                                              && !isNestedRoot) { // do not treat as non-java rsc if nested root
2309 //                                      if (!this.traverseDelta(child, childType, rootInfo == null ? childRootInfo : rootInfo, outputsInfo)) { // traverse delta for child in the same project
2310 //                                              // it is a non-java resource
2311 //                                              try {
2312 //                                                      if (rootInfo != null) { // if inside a package fragment root
2313 //                                                              if (!isValidParent) continue; 
2314 //                                                              if (parent == null) {
2315 //                                                                      // find the parent of the non-java resource to attach to
2316 //                                                                      if (this.currentElement == null 
2317 //                                                                                      || !this.currentElement.getJavaProject().equals(rootInfo.project)) {
2318 //                                                                              // force the currentProject to be used
2319 //                                                                              this.currentElement = (Openable)rootInfo.project;
2320 //                                                                      }
2321 //                                                                      if (elementType == IJavaElement.JAVA_PROJECT
2322 //                                                                              || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT 
2323 //                                                                                      && res instanceof IProject)) { 
2324 //                                                                              // NB: attach non-java resource to project (not to its package fragment root)
2325 //                                                                              parent = (Openable)rootInfo.project;
2326 //                                                                      } else {
2327 //                                                                              parent = this.createElement(res, elementType, rootInfo);
2328 //                                                                      }
2329 //                                                                      if (parent == null) {
2330 //                                                                              isValidParent = false;
2331 //                                                                              continue;
2332 //                                                                      }
2333 //                                                              }
2334 //                                                              // add child as non java resource
2335 //                                                              nonJavaResourcesChanged(parent, child);
2336 //                                                      } else {
2337 //                                                              // the non-java resource (or its parent folder) will be attached to the java project
2338 //                                                              if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
2339 //                                                              orphanChildren[i] = child;
2340 //                                                      }
2341 //                                              } catch (JavaModelException e) {
2342 //                                              }
2343 //                                      } else {
2344 //                                              oneChildOnClasspath = true;
2345 //                                      }
2346 //                              } else {
2347 //                                      oneChildOnClasspath = true; // to avoid reporting child delta as non-java resource delta
2348 //                              }
2349 //                                                              
2350 //                              // if child is a nested root 
2351 //                              // or if it is not a package fragment root of the current project
2352 //                              // but it is a package fragment root of another project, traverse delta too
2353 //                              if (isNestedRoot 
2354 //                                              || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath, childKind)) != null)) {
2355 //                                      this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
2356 //                                      // NB: No need to check the return value as the child can only be on the classpath
2357 //                              }
2358 //      
2359 //                              // if the child is a package fragment root of one or several other projects
2360 //                              ArrayList rootList;
2361 //                              if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
2362 //                                      Iterator iterator = rootList.iterator();
2363 //                                      while (iterator.hasNext()) {
2364 //                                              childRootInfo = (RootInfo) iterator.next();
2365 //                                              this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
2366 //                                      }
2367 //                              }
2368 //                      }
2369 //                      if (orphanChildren != null
2370 //                                      && (oneChildOnClasspath // orphan children are siblings of a package fragment root
2371 //                                              || res instanceof IProject)) { // non-java resource directly under a project
2372 //                                              
2373 //                              // attach orphan children
2374 //                              IProject rscProject = res.getProject();
2375 //                              JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
2376 //                              if (adoptiveProject != null 
2377 //                                              && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project (18698)
2378 //                                      for (int i = 0; i < length; i++) {
2379 //                                              if (orphanChildren[i] != null) {
2380 //                                                      try {
2381 //                                                              nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
2382 //                                                      } catch (JavaModelException e) {
2383 //                                                      }
2384 //                                              }
2385 //                                      }
2386 //                              }
2387 //                      } // else resource delta will be added by parent
2388 //                      return elementType != NON_JAVA_RESOURCE; // TODO: (jerome) do we still need to return? (check could be done by caller)
2389 //              } else {
2390 //                      return elementType != NON_JAVA_RESOURCE;
2391 //              }
2392 //      }
2393
2394         /**
2395          * Update the classpath markers and cycle markers for the projects to update.
2396          */
2397 //      void updateClasspathMarkers() {
2398 //              try {
2399 //                      if (!ResourcesPlugin.getWorkspace().isAutoBuilding()) {
2400 //                              Iterator iterator = this.projectsToUpdate.iterator();
2401 //                              while (iterator.hasNext()) {
2402 //                                      try {
2403 //                                              JavaProject project = (JavaProject)iterator.next();
2404 //                                              
2405 //                                               // force classpath marker refresh
2406 //                                              project.getResolvedClasspath(
2407 //                                                      true, // ignoreUnresolvedEntry
2408 //                                                      true); // generateMarkerOnError
2409 //                                              
2410 //                                      } catch (JavaModelException e) {
2411 //                                      }
2412 //                              }
2413 //                      }
2414 //                      if (!this.projectsToUpdate.isEmpty()){
2415 //                              try {
2416 //                                      // update all cycle markers
2417 //                                      JavaProject.updateAllCycleMarkers();
2418 //                              } catch (JavaModelException e) {
2419 //                              }
2420 //                      }                               
2421 //              } finally {
2422 //                      this.projectsToUpdate = new HashSet();
2423 //              }
2424 //      }
2425
2426         /*
2427          * Update the current delta (ie. add/remove/change the given element) and update the correponding index.
2428          * Returns whether the children of the given delta must be processed.
2429          * @throws a JavaModelException if the delta doesn't correspond to a java element of the given type.
2430          */
2431 //      private boolean updateCurrentDeltaAndIndex(IResourceDelta delta, int elementType, RootInfo rootInfo) {
2432 //              Openable element;
2433 //              switch (delta.getKind()) {
2434 //                      case IResourceDelta.ADDED :
2435 //                              IResource deltaRes = delta.getResource();
2436 //                              element = this.createElement(deltaRes, elementType, rootInfo);
2437 //                              if (element == null) {
2438 //                                      // resource might be containing shared roots (see bug 19058)
2439 //                                      this.updateRoots(deltaRes.getFullPath(), delta);
2440 //                                      return false;
2441 //                              }
2442 //                              this.updateIndex(element, delta);
2443 //                              this.elementAdded(element, delta, rootInfo);
2444 //                              return false;
2445 //                      case IResourceDelta.REMOVED :
2446 //                              deltaRes = delta.getResource();
2447 //                              element = this.createElement(deltaRes, elementType, rootInfo);
2448 //                              if (element == null) {
2449 //                                      // resource might be containing shared roots (see bug 19058)
2450 //                                      this.updateRoots(deltaRes.getFullPath(), delta);
2451 //                                      return false;
2452 //                              }
2453 //                              this.updateIndex(element, delta);
2454 //                              this.elementRemoved(element, delta, rootInfo);
2455 //      
2456 //                              if (deltaRes.getType() == IResource.PROJECT){                   
2457 //                                      // reset the corresponding project built state, since cannot reuse if added back
2458 //                                      this.manager.setLastBuiltState((IProject)deltaRes, null /*no state*/);
2459 //                              }
2460 //                              return false;
2461 //                      case IResourceDelta.CHANGED :
2462 //                              int flags = delta.getFlags();
2463 //                              if ((flags & IResourceDelta.CONTENT) != 0) {
2464 //                                      // content has changed
2465 //                                      element = this.createElement(delta.getResource(), elementType, rootInfo);
2466 //                                      if (element == null) return false;
2467 //                                      this.updateIndex(element, delta);
2468 //                                      this.contentChanged(element, delta);
2469 //                              } else if (elementType == IJavaElement.JAVA_PROJECT) {
2470 //                                      if ((flags & IResourceDelta.OPEN) != 0) {
2471 //                                              // project has been opened or closed
2472 //                                              IProject res = (IProject)delta.getResource();
2473 //                                              element = this.createElement(res, elementType, rootInfo);
2474 //                                              if (element == null) {
2475 //                                                      // resource might be containing shared roots (see bug 19058)
2476 //                                                      this.updateRoots(res.getFullPath(), delta);
2477 //                                                      return false;
2478 //                                              }
2479 //                                              if (res.isOpen()) {
2480 //                                                      if (JavaProject.hasJavaNature(res)) {
2481 //                                                              this.elementAdded(element, delta, rootInfo);
2482 //                                                              this.indexManager.indexAll(res);
2483 //                                                      }
2484 //                                              } else {
2485 //                                                      JavaModel javaModel = this.manager.getJavaModel();
2486 //                                                      boolean wasJavaProject = javaModel.findJavaProject(res) != null;
2487 //                                                      if (wasJavaProject) {
2488 //                                                              this.elementRemoved(element, delta, rootInfo);
2489 //                                                              this.indexManager.discardJobs(element.getElementName());
2490 //                                                              this.indexManager.removeIndexFamily(res.getFullPath());
2491 //                                                              
2492 //                                                      }
2493 //                                              }
2494 //                                              return false; // when a project is open/closed don't process children
2495 //                                      }
2496 //                                      if ((flags & IResourceDelta.DESCRIPTION) != 0) {
2497 //                                              IProject res = (IProject)delta.getResource();
2498 //                                              JavaModel javaModel = this.manager.getJavaModel();
2499 //                                              boolean wasJavaProject = javaModel.findJavaProject(res) != null;
2500 //                                              boolean isJavaProject = JavaProject.hasJavaNature(res);
2501 //                                              if (wasJavaProject != isJavaProject) {
2502 //                                                      // project's nature has been added or removed
2503 //                                                      element = this.createElement(res, elementType, rootInfo);
2504 //                                                      if (element == null) return false; // note its resources are still visible as roots to other projects
2505 //                                                      if (isJavaProject) {
2506 //                                                              this.elementAdded(element, delta, rootInfo);
2507 //                                                              this.indexManager.indexAll(res);
2508 //                                                      } else {
2509 //                                                              this.elementRemoved(element, delta, rootInfo);
2510 //                                                              this.indexManager.discardJobs(element.getElementName());
2511 //                                                              this.indexManager.removeIndexFamily(res.getFullPath());
2512 //                                                              // reset the corresponding project built state, since cannot reuse if added back
2513 //                                                              this.manager.setLastBuiltState(res, null /*no state*/);
2514 //                                                      }
2515 //                                                      return false; // when a project's nature is added/removed don't process children
2516 //                                              }
2517 //                                      }
2518 //                              }
2519 //                              return true;
2520 //              }
2521 //              return true;
2522 //      }
2523
2524         /**
2525          * Traverse the set of projects which have changed namespace, and refresh their dependents
2526          */
2527 //      public void updateDependentNamelookups() {
2528 //              Iterator iterator;
2529 //              // update namelookup of dependent projects
2530 //              iterator = this.projectsForDependentNamelookupRefresh.iterator();
2531 //              HashSet affectedDependents = new HashSet();
2532 //              while (iterator.hasNext()) {
2533 //                      JavaProject project = (JavaProject)iterator.next();
2534 //                      addDependentProjects(project.getPath(), affectedDependents);
2535 //              }
2536 //              iterator = affectedDependents.iterator();
2537 //              while (iterator.hasNext()) {
2538 //                      JavaProject project = (JavaProject) iterator.next();
2539 //                      if (project.isOpen()){
2540 //                              try {
2541 //                                      ((JavaProjectElementInfo)project.getElementInfo()).setNameLookup(null);
2542 //                              } catch (JavaModelException e) {
2543 //                              }
2544 //                      }
2545 //              }
2546 //      }
2547
2548 //protected void updateIndex(Openable element, IResourceDelta delta) {
2549 //
2550 //      if (indexManager == null)
2551 //              return;
2552 //
2553 //      switch (element.getElementType()) {
2554 //              case IJavaElement.JAVA_PROJECT :
2555 //                      switch (delta.getKind()) {
2556 //                              case IResourceDelta.ADDED :
2557 //                                      this.indexManager.indexAll(element.getJavaProject().getProject());
2558 //                                      break;
2559 //                              case IResourceDelta.REMOVED :
2560 //                                      this.indexManager.removeIndexFamily(element.getJavaProject().getProject().getFullPath());
2561 //                                      // NB: Discarding index jobs belonging to this project was done during PRE_DELETE
2562 //                                      break;
2563 //                              // NB: Update of index if project is opened, closed, or its java nature is added or removed
2564 //                              //     is done in updateCurrentDeltaAndIndex
2565 //                      }
2566 //                      break;
2567 //              case IJavaElement.PACKAGE_FRAGMENT_ROOT :
2568 //                      if (element instanceof JarPackageFragmentRoot) {
2569 //                              JarPackageFragmentRoot root = (JarPackageFragmentRoot)element;
2570 //                              // index jar file only once (if the root is in its declaring project)
2571 //                              IPath jarPath = root.getPath();
2572 //                              switch (delta.getKind()) {
2573 //                                      case IResourceDelta.ADDED:
2574 //                                              // index the new jar
2575 //                                              indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
2576 //                                              break;
2577 //                                      case IResourceDelta.CHANGED:
2578 //                                              // first remove the index so that it is forced to be re-indexed
2579 //                                              indexManager.removeIndex(jarPath);
2580 //                                              // then index the jar
2581 //                                              indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
2582 //                                              break;
2583 //                                      case IResourceDelta.REMOVED:
2584 //                                              // the jar was physically removed: remove the index
2585 //                                              this.indexManager.discardJobs(jarPath.toString());
2586 //                                              this.indexManager.removeIndex(jarPath);
2587 //                                              break;
2588 //                              }
2589 //                              break;
2590 //                      } else {
2591 //                              int kind = delta.getKind();
2592 //                              if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) {
2593 //                                      IPackageFragmentRoot root = (IPackageFragmentRoot)element;
2594 //                                      this.updateRootIndex(root, root.getPackageFragment(""), delta); //$NON-NLS-1$
2595 //                                      break;
2596 //                              }
2597 //                      }
2598 //                      // don't break as packages of the package fragment root can be indexed below
2599 //              case IJavaElement.PACKAGE_FRAGMENT :
2600 //                      switch (delta.getKind()) {
2601 //                              case IResourceDelta.ADDED:
2602 //                              case IResourceDelta.REMOVED:
2603 //                                      IPackageFragment pkg = null;
2604 //                                      if (element instanceof IPackageFragmentRoot) {
2605 //                                              IPackageFragmentRoot root = (IPackageFragmentRoot)element;
2606 //                                              pkg = root.getPackageFragment(""); //$NON-NLS-1$
2607 //                                      } else {
2608 //                                              pkg = (IPackageFragment)element;
2609 //                                      }
2610 //                                      IResourceDelta[] children = delta.getAffectedChildren();
2611 //                                      for (int i = 0, length = children.length; i < length; i++) {
2612 //                                              IResourceDelta child = children[i];
2613 //                                              IResource resource = child.getResource();
2614 //                                              if (resource instanceof IFile) {
2615 //                                                      String name = resource.getName();
2616 //                                                      if (Util.isJavaFileName(name)) {
2617 //                                                              Openable cu = (Openable)pkg.getCompilationUnit(name);
2618 //                                                              this.updateIndex(cu, child);
2619 //                                                      } else if (Util.isClassFileName(name)) {
2620 //                                                              Openable classFile = (Openable)pkg.getClassFile(name);
2621 //                                                              this.updateIndex(classFile, child);
2622 //                                                      }
2623 //                                              }
2624 //                                      }
2625 //                                      break;
2626 //                      }
2627 //                      break;
2628 //              case IJavaElement.CLASS_FILE :
2629 //                      IFile file = (IFile) delta.getResource();
2630 //                      IJavaProject project = element.getJavaProject();
2631 //                      IPath binaryFolderPath = element.getPackageFragmentRoot().getPath();
2632 //                      // if the class file is part of the binary output, it has been created by
2633 //                      // the java builder -> ignore
2634 //                      try {
2635 //                              if (binaryFolderPath.equals(project.getOutputLocation())) {
2636 //                                      break;
2637 //                              }
2638 //                      } catch (JavaModelException e) {
2639 //                      }
2640 //                      switch (delta.getKind()) {
2641 //                              case IResourceDelta.CHANGED :
2642 //                                      // no need to index if the content has not changed
2643 //                                      if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
2644 //                                              break;
2645 //                              case IResourceDelta.ADDED :
2646 //                                      indexManager.addBinary(file, binaryFolderPath);
2647 //                                      break;
2648 //                              case IResourceDelta.REMOVED :
2649 //                                      indexManager.remove(file.getFullPath().toString(), binaryFolderPath);
2650 //                                      break;
2651 //                      }
2652 //                      break;
2653 //              case IJavaElement.COMPILATION_UNIT :
2654 //                      file = (IFile) delta.getResource();
2655 //                      switch (delta.getKind()) {
2656 //                              case IResourceDelta.CHANGED :
2657 //                                      // no need to index if the content has not changed
2658 //                                      if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
2659 //                                              break;
2660 //                              case IResourceDelta.ADDED :
2661 //                                      indexManager.addSource(file, file.getProject().getProject().getFullPath());
2662 //                                      break;
2663 //                              case IResourceDelta.REMOVED :
2664 //                                      indexManager.remove(file.getFullPath().toString(), file.getProject().getProject().getFullPath());
2665 //                                      break;
2666 //                      }
2667 //      }
2668 //}
2669 /**
2670  * Upadtes the index of the given root (assuming it's an addition or a removal).
2671  * This is done recusively, pkg being the current package.
2672  */
2673 //private void updateRootIndex(IPackageFragmentRoot root, IPackageFragment pkg, IResourceDelta delta) {
2674 //      this.updateIndex((Openable)pkg, delta);
2675 //      IResourceDelta[] children = delta.getAffectedChildren();
2676 //      String name = pkg.getElementName();
2677 //      for (int i = 0, length = children.length; i < length; i++) {
2678 //              IResourceDelta child = children[i];
2679 //              IResource resource = child.getResource();
2680 //              if (resource instanceof IFolder) {
2681 //                      String subpkgName = 
2682 //                              name.length() == 0 ? 
2683 //                                      resource.getName() : 
2684 //                                      name + "." + resource.getName(); //$NON-NLS-1$
2685 //                      IPackageFragment subpkg = root.getPackageFragment(subpkgName);
2686 //                      this.updateRootIndex(root, subpkg, child);
2687 //              }
2688 //      }
2689 //}
2690 /*
2691  * Update the roots that are affected by the addition or the removal of the given container resource.
2692  */
2693 //private void updateRoots(IPath containerPath, IResourceDelta containerDelta) {
2694 //      Map roots;
2695 //      Map otherRoots;
2696 //      if (containerDelta.getKind() == IResourceDelta.REMOVED) {
2697 //              roots = this.oldRoots;
2698 //              otherRoots = this.oldOtherRoots;
2699 //      } else {
2700 //              roots = this.roots;
2701 //              otherRoots = this.otherRoots;
2702 //      }
2703 //      Iterator iterator = roots.keySet().iterator();
2704 //      while (iterator.hasNext()) {
2705 //              IPath path = (IPath)iterator.next();
2706 //              if (containerPath.isPrefixOf(path) && !containerPath.equals(path)) {
2707 //                      IResourceDelta rootDelta = containerDelta.findMember(path.removeFirstSegments(1));
2708 //                      if (rootDelta == null) continue;
2709 //                      RootInfo rootInfo = (RootInfo)roots.get(path);
2710 //
2711 //                      if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider roots that are not included in the container
2712 //                              this.updateCurrentDeltaAndIndex(rootDelta, IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
2713 //                      }
2714 //                      
2715 //                      ArrayList rootList = (ArrayList)otherRoots.get(path);
2716 //                      if (rootList != null) {
2717 //                              Iterator otherProjects = rootList.iterator();
2718 //                              while (otherProjects.hasNext()) {
2719 //                                      rootInfo = (RootInfo)otherProjects.next();
2720 //                                      if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider roots that are not included in the container
2721 //                                              this.updateCurrentDeltaAndIndex(rootDelta, IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
2722 //                                      }
2723 //                              }
2724 //                      }
2725 //              }
2726 //      }
2727 //}
2728
2729 }