fixed update conflict and outline update bug
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / DeltaProcessor.java
index a4b7bfe..c68939a 100644 (file)
@@ -27,6 +27,7 @@ import net.sourceforge.phpdt.core.IJavaModel;
 import net.sourceforge.phpdt.core.IJavaProject;
 import net.sourceforge.phpdt.core.JavaCore;
 import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.core.builder.PHPBuilder;
 import net.sourceforge.phpdt.internal.core.util.Util;
 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
@@ -1287,120 +1288,6 @@ public class DeltaProcessor implements IResourceChangeListener {
                if (insertedTree) return rootDelta;
                return null;
        }       
-       private void notifyListeners(IJavaElementDelta deltaToNotify, int eventType, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
-               final ElementChangedEvent extraEvent = new ElementChangedEvent(deltaToNotify, eventType);
-               for (int i= 0; i < listenerCount; i++) {
-                       if ((listenerMask[i] & eventType) != 0){
-                               final IElementChangedListener listener = listeners[i];
-                               long start = -1;
-                               if (VERBOSE) {
-                                       System.out.print("Listener #" + (i+1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
-                                       start = System.currentTimeMillis();
-                               }
-                               // wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
-                               Platform.run(new ISafeRunnable() {
-                                       public void handleException(Throwable exception) {
-                                               Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
-                                       }
-                                       public void run() throws Exception {
-                                               listener.elementChanged(extraEvent);
-                                       }
-                               });
-                               if (VERBOSE) {
-                                       System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
-                               }
-                       }
-               }
-       }
-       /**
-        * Generic processing for elements with changed contents:<ul>
-        * <li>The element is closed such that any subsequent accesses will re-open
-        * the element reflecting its new structure.
-        * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
-        * </ul>
-        */
-//     protected void nonJavaResourcesChanged(Openable element, IResourceDelta delta)
-//             throws JavaModelException {
-//
-//             // reset non-java resources if element was open
-//             if (element.isOpen()) {
-//                     JavaElementInfo info = (JavaElementInfo)element.getElementInfo();
-//                     switch (element.getElementType()) {
-//                             case IJavaElement.JAVA_MODEL :
-//                                     ((JavaModelInfo) info).nonJavaResources = null;
-//                                     currentDelta().addResourceDelta(delta);
-//                                     return;
-//                             case IJavaElement.JAVA_PROJECT :
-//                                     ((JavaProjectElementInfo) info).setNonJavaResources(null);
-//     
-//                                     // if a package fragment root is the project, clear it too
-//                                     JavaProject project = (JavaProject) element;
-//                                     PackageFragmentRoot projectRoot =
-//                                             (PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject());
-//                                     if (projectRoot.isOpen()) {
-//                                             ((PackageFragmentRootInfo) projectRoot.getElementInfo()).setNonJavaResources(
-//                                                     null);
-//                                     }
-//                                     break;
-//                             case IJavaElement.PACKAGE_FRAGMENT :
-//                                      ((PackageFragmentInfo) info).setNonJavaResources(null);
-//                                     break;
-//                             case IJavaElement.PACKAGE_FRAGMENT_ROOT :
-//                                      ((PackageFragmentRootInfo) info).setNonJavaResources(null);
-//                     }
-//             }
-//
-//             JavaElementDelta elementDelta = currentDelta().find(element);
-//             if (elementDelta == null) {
-//                     currentDelta().changed(element, IJavaElementDelta.F_CONTENT);
-//                     elementDelta = currentDelta().find(element);
-//             }
-//             elementDelta.addResourceDelta(delta);
-//     }
-//     private OutputsInfo outputsInfo(RootInfo rootInfo, IResource res) {
-//             try {
-//                     IJavaProject proj =
-//                             rootInfo == null ?
-//                                     (IJavaProject)this.createElement(res.getProject(), IJavaElement.JAVA_PROJECT, null) :
-//                                     rootInfo.project;
-//                     if (proj != null) {
-//                             IPath projectOutput = proj.getOutputLocation();
-//                             int traverseMode = IGNORE;
-//                             if (proj.getProject().getFullPath().equals(projectOutput)){ // case of proj==bin==src
-//                                     return new OutputsInfo(new IPath[] {projectOutput}, new int[] {SOURCE}, 1);
-//                             } else {
-//                                     IClasspathEntry[] classpath = proj.getResolvedClasspath(true);
-//                                     IPath[] outputs = new IPath[classpath.length+1];
-//                                     int[] traverseModes = new int[classpath.length+1];
-//                                     int outputCount = 1;
-//                                     outputs[0] = projectOutput;
-//                                     traverseModes[0] = traverseMode;
-//                                     for (int i = 0, length = classpath.length; i < length; i++) {
-//                                             IClasspathEntry entry = classpath[i];
-//                                             IPath entryPath = entry.getPath();
-//                                             IPath output = entry.getOutputLocation();
-//                                             if (output != null) {
-//                                                     outputs[outputCount] = output;
-//                                                     // check case of src==bin
-//                                                     if (entryPath.equals(output)) {
-//                                                             traverseModes[outputCount++] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY;
-//                                                     } else {
-//                                                             traverseModes[outputCount++] = IGNORE;
-//                                                     }
-//                                             }
-//                                             
-//                                             // check case of src==bin
-//                                             if (entryPath.equals(projectOutput)) {
-//                                                     traverseModes[0] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY;
-//                                             }
-//                                     }
-//                                     return new OutputsInfo(outputs, traverseModes, outputCount);
-//                             }
-//                     }
-//             } catch (JavaModelException e) {
-//             }
-//             return null;
-//     }
        
        /**
         * Check whether the updated file is affecting some of the properties of a given project (like
@@ -1511,75 +1398,6 @@ public class DeltaProcessor implements IResourceChangeListener {
         * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
         * relevant <code>JavaModel</code>s.
         */
-//     public IJavaElementDelta processResourceDelta(IResourceDelta changes) {
-//
-//             try {
-//                     IJavaModel model = this.manager.getJavaModel();
-//                     if (!model.isOpen()) {
-//                             // force opening of java model so that java element delta are reported
-//                             try {
-//                                     model.open(null);
-//                             } catch (JavaModelException e) {
-//                                     if (VERBOSE) {
-//                                             e.printStackTrace();
-//                                     }
-//                                     return null;
-//                             }
-//                     }
-//                     this.initializeRoots();
-//                     this.currentElement = null;
-//                     
-//                     // get the workspace delta, and start processing there.
-//                     IResourceDelta[] deltas = changes.getAffectedChildren();
-//                     for (int i = 0; i < deltas.length; i++) {
-//                             IResourceDelta delta = deltas[i];
-//                             IResource res = delta.getResource();
-//                             
-//                             // find out the element type
-//                             RootInfo rootInfo = null;
-//                             int elementType;
-//                             IProject proj = (IProject)res;
-//                             boolean wasJavaProject = this.manager.getJavaModel().findJavaProject(proj) != null;
-//                             boolean isJavaProject = JavaProject.hasJavaNature(proj);
-//                             if (!wasJavaProject && !isJavaProject) {
-//                                     elementType = NON_JAVA_RESOURCE;
-//                             } else {
-//                                     rootInfo = this.enclosingRootInfo(res.getFullPath(), delta.getKind());
-//                                     if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
-//                                             elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
-//                                     } else {
-//                                             elementType = IJavaElement.JAVA_PROJECT; 
-//                                     }
-//                             }
-//                             
-//                             // traverse delta
-//                             if (!this.traverseDelta(delta, elementType, rootInfo, null) 
-//                                             || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project has changed nature (description or open/closed)
-//                                     try {
-//                                             // add child as non java resource
-//                                             nonJavaResourcesChanged((JavaModel)model, delta);
-//                                     } catch (JavaModelException e) {
-//                                     }
-//                             }
-//
-//                     }
-//                     
-//                     // update package fragment roots of projects that were affected
-//                     Iterator iterator = this.projectsToUpdate.iterator();
-//                     while (iterator.hasNext()) {
-//                             JavaProject project = (JavaProject)iterator.next();
-//                             project.updatePackageFragmentRoots();
-//                     }
-//     
-//                     updateDependentNamelookups();
-//
-//                     return this.currentDelta;
-//             } finally {
-//                     this.currentDelta = null;
-//                     this.projectsToUpdate.clear();
-//                     this.projectsForDependentNamelookupRefresh.clear();
-//             }
-//     }
 
        /**
         * Update the JavaModel according to a .classpath file change. The file can have changed as a result of a previous
@@ -1774,74 +1592,518 @@ public class DeltaProcessor implements IResourceChangeListener {
         * @see IResource 
         */
        public void resourceChanged(IResourceChangeEvent event) {
-               // jsurfer TODO compare 3.0 sources
-               if (event.getSource() instanceof IWorkspace) {
-                       int eventType = this.overridenEventType == -1 ? event.getType() : this.overridenEventType;
-                       IResource resource = event.getResource();
-                       IResourceDelta delta = event.getDelta();
-                       
-                       switch(eventType){
-                               case IResourceChangeEvent.PRE_DELETE :
+         if (event.getSource() instanceof IWorkspace) {
+               int eventType = this.overridenEventType == -1 ? event.getType() : this.overridenEventType;
+               IResource resource = event.getResource();
+               IResourceDelta delta = event.getDelta();
+               
+               switch(eventType){
+                       case IResourceChangeEvent.PRE_DELETE :
+                               try {
+                                 if(resource.getType() == IResource.PROJECT 
+                                               && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
+                                       
+                                               deleting((IProject)resource);
+                                       }
+                               } catch(CoreException e){
+                                       // project doesn't exist or is not open: ignore
+                               }
+                               return;
+                               
+                       case IResourceChangeEvent.POST_CHANGE :
+                               if (isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
                                        try {
-                                               if(resource.getType() == IResource.PROJECT 
-                                                       && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
-                                               // TODO jsurfer temp-del
-//                                                     this.deleting((IProject)resource);
+                                               try {
+                                                       stopDeltas();
+//                                                     checkProjectsBeingAddedOrRemoved(delta);
+//                                                     if (this.refreshedElements != null) {
+//                                                             createExternalArchiveDelta(null);
+//                                                     }
+                                                       IJavaElementDelta translatedDelta = processResourceDelta(delta);
+                                                       if (translatedDelta != null) { 
+                                                               registerJavaModelDelta(translatedDelta);
+                                                       }
+                                               } finally {
+                                                       startDeltas();
                                                }
-                                       } catch(CoreException e){
+//                                             notifyTypeHierarchies(this.state.elementChangedListeners, this.state.elementChangedListenerCount);
+                                               fire(null, ElementChangedEvent.POST_CHANGE);
+                                       } finally {
+                                               // workaround for bug 15168 circular errors not reported 
+                                               this.state.modelProjectsCache = null;
+                                               this.removedRoots = null;
                                        }
-                                       return;
-                                       
-                               case IResourceChangeEvent.PRE_BUILD :
-//                     TODO jsurfer temp-del
-//                                     if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
-//                                             this.checkProjectsBeingAddedOrRemoved(delta);
-//                                             
-//                                             // update the classpath related markers
-//                                             this.updateClasspathMarkers();
-//     
-//                                             // the following will close project if affected by the property file change
-//                                             try {
-//                                                     // don't fire classpath change deltas right away, but batch them
-//                                                     this.manager.stopDeltas();
-//                                                     this.performPreBuildCheck(delta, null); 
-//                                             } finally {
-//                                                     this.manager.startDeltas();
+                               }
+                               return;
+                               
+                       case IResourceChangeEvent.PRE_BUILD :
+                           DeltaProcessingState.ProjectUpdateInfo[] updates = this.state.removeAllProjectUpdates();
+                               if (updates != null) {
+                                   for (int i = 0, length = updates.length; i < length; i++) {
+                                       try {
+                                               updates[i].updateProjectReferencesIfNecessary();
+                                       } catch(JavaModelException e) {
+                                           // do nothing
+                                       }
+                                   }
+                               }
+                               // this.processPostChange = false;
+                               if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
+//                                     updateClasspathMarkers(delta);
+                                       PHPBuilder.buildStarting();
+                               }
+                               // does not fire any deltas
+                               return;
+
+                       case IResourceChangeEvent.POST_BUILD :
+                               PHPBuilder.buildFinished();
+                               return;
+               }
+       }
+//             // jsurfer TODO compare 3.0 sources
+//             if (event.getSource() instanceof IWorkspace) {
+//                     int eventType = this.overridenEventType == -1 ? event.getType() : this.overridenEventType;
+//                     IResource resource = event.getResource();
+//                     IResourceDelta delta = event.getDelta();
+//                     
+//                     switch(eventType){
+//                             case IResourceChangeEvent.PRE_DELETE :
+//                                     try {
+//                                             if(resource.getType() == IResource.PROJECT 
+//                                                     && ((IProject) resource).hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
+//                                             // TODO jsurfer temp-del
+////                                                   this.deleting((IProject)resource);
 //                                             }
+//                                     } catch(CoreException e){
 //                                     }
-                                       // only fire already computed deltas (resource ones will be processed in post change only)
-                                       this.manager.fire(null, ElementChangedEvent.PRE_AUTO_BUILD);
-                                       break;
+//                                     return;
+//                                     
+//                             case IResourceChangeEvent.PRE_BUILD :
+////                   TODO jsurfer temp-del
+////                                   if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
+////                                           this.checkProjectsBeingAddedOrRemoved(delta);
+////                                           
+////                                           // update the classpath related markers
+////                                           this.updateClasspathMarkers();
+////   
+////                                           // the following will close project if affected by the property file change
+////                                           try {
+////                                                   // don't fire classpath change deltas right away, but batch them
+////                                                   this.manager.stopDeltas();
+////                                                   this.performPreBuildCheck(delta, null); 
+////                                           } finally {
+////                                                   this.manager.startDeltas();
+////                                           }
+////                                   }
+//                                     // only fire already computed deltas (resource ones will be processed in post change only)
+//                                     this.manager.fire(null, ElementChangedEvent.PRE_AUTO_BUILD);
+//                                     break;
+//
+//                             case IResourceChangeEvent.POST_BUILD :
+////                   TODO jsurfer temp-del
+////                                   JavaBuilder.finishedBuilding(event);
+//                                     break;
+//                                     
+//                             case IResourceChangeEvent.POST_CHANGE :
+////                   TODO jsurfer temp-del
+////                                   if (isAffectedBy(delta)) {
+////                                           try {
+////                                                   if (this.refreshedElements != null) {
+////                                                           try {
+////                                                                   createExternalArchiveDelta(null);
+////                                                           } catch (JavaModelException e) {
+////                                                                   e.printStackTrace();
+////                                                           }
+////                                                   }
+////                                                   IJavaElementDelta translatedDelta = this.processResourceDelta(delta);
+////                                                   if (translatedDelta != null) { 
+////                                                           this.manager.registerJavaModelDelta(translatedDelta);
+////                                                   }
+////                                                   this.manager.fire(null, ElementChangedEvent.POST_CHANGE);
+////                                           } finally {
+////                                                   // workaround for bug 15168 circular errors not reported 
+////                                                   this.manager.javaProjectsCache = null;
+////                                                   this.removedRoots = null;
+////                                           }
+////                                   }
+//                     }
+//             }
+       }
+       /*
+        * Turns the firing mode to on. That is, deltas that are/have been
+        * registered will be fired.
+        */
+       private void startDeltas() {
+               this.isFiring= true;
+       }
+       /*
+        * Turns the firing mode to off. That is, deltas that are/have been
+        * registered will not be fired until deltas are started again.
+        */
+       private void stopDeltas() {
+               this.isFiring= false;
+       }
+       /*
+        * Note that the project is about to be deleted.
+        */
+       private void deleting(IProject project) {
+               
+               try {
+                       // discard indexing jobs that belong to this project so that the project can be 
+                       // deleted without interferences from the index manager
+//                     this.manager.indexManager.discardJobs(project.getName());
 
-                               case IResourceChangeEvent.POST_BUILD :
-//                     TODO jsurfer temp-del
-//                                     JavaBuilder.finishedBuilding(event);
-                                       break;
-                                       
-                               case IResourceChangeEvent.POST_CHANGE :
-//                     TODO jsurfer temp-del
-//                                     if (isAffectedBy(delta)) {
-//                                             try {
-//                                                     if (this.refreshedElements != null) {
-//                                                             try {
-//                                                                     createExternalArchiveDelta(null);
-//                                                             } catch (JavaModelException e) {
-//                                                                     e.printStackTrace();
+                       JavaProject javaProject = (JavaProject)JavaCore.create(project);
+                       
+                       // remember roots of this project
+                       if (this.removedRoots == null) {
+                               this.removedRoots = new HashMap();
+                       }
+                       if (javaProject.isOpen()) {
+                               this.removedRoots.put(javaProject, javaProject.getPackageFragmentRoots());
+                       } else {
+                               // compute roots without opening project
+//                             this.removedRoots.put(
+//                                     javaProject, 
+//                                     javaProject.computePackageFragmentRoots(
+//                                             javaProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/), 
+//                                             false));
+                       }
+                       
+                       javaProject.close();
+
+                       // workaround for bug 15168 circular errors not reported
+                       if (this.state.modelProjectsCache == null) {
+                               this.state.modelProjectsCache = this.manager.getJavaModel().getJavaProjects();
+                       }
+                       this.removeFromParentInfo(javaProject);
+
+               } catch (JavaModelException e) {
+                       // java project doesn't exist: ignore
+               }
+       }
+       /*
+        * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
+        * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
+        * relevant <code>JavaModel</code>s.
+        */
+       private IJavaElementDelta processResourceDelta(IResourceDelta changes) {
+
+               try {
+                       IJavaModel model = this.manager.getJavaModel();
+                       if (!model.isOpen()) {
+                               // force opening of java model so that java element delta are reported
+                               try {
+                                       model.open(null);
+                               } catch (JavaModelException e) {
+                                       if (VERBOSE) {
+                                               e.printStackTrace();
+                                       }
+                                       return null;
+                               }
+                       }
+                       this.state.initializeRoots();
+                       this.currentElement = null;
+                       
+                       // get the workspace delta, and start processing there.
+                       IResourceDelta[] deltas = changes.getAffectedChildren();
+                       for (int i = 0; i < deltas.length; i++) {
+                               IResourceDelta delta = deltas[i];
+                               IResource res = delta.getResource();
+                               
+                               // find out the element type
+                               RootInfo rootInfo = null;
+                               int elementType;
+                               IProject proj = (IProject)res;
+                               boolean wasJavaProject = this.manager.getJavaModel().findJavaProject(proj) != null;
+                               boolean isJavaProject = JavaProject.hasJavaNature(proj);
+                               if (!wasJavaProject && !isJavaProject) {
+                                       elementType = NON_JAVA_RESOURCE;
+                               } else {
+                                       rootInfo = this.enclosingRootInfo(res.getFullPath(), delta.getKind());
+                                       if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
+                                               elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
+                                       } else {
+                                               elementType = IJavaElement.JAVA_PROJECT; 
+                                       }
+                               }
+                               
+                               // traverse delta
+//                             this.traverseDelta(delta, elementType, rootInfo, null);
+                               
+                               if (elementType == NON_JAVA_RESOURCE
+                                               || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project has changed nature (description or open/closed)
+                                       try {
+                                               // add child as non java resource
+                                               nonJavaResourcesChanged((JavaModel)model, delta);
+                                       } catch (JavaModelException e) {
+                                               // java model could not be opened
+                                       }
+                               }
+
+                       }
+//                     refreshPackageFragmentRoots();
+//                     resetProjectCaches();
+
+                       return this.currentDelta;
+               } finally {
+                       this.currentDelta = null;
+//                     this.rootsToRefresh.clear();
+//                     this.projectCachesToReset.clear();
+               }
+       }
+       
+       /*
+        * Converts an <code>IResourceDelta</code> and its children into
+        * the corresponding <code>IJavaElementDelta</code>s.
+        */
+//     private void traverseDelta(
+//             IResourceDelta delta, 
+//             int elementType, 
+//             RootInfo rootInfo,
+//             OutputsInfo outputsInfo) {
+//                     
+//             IResource res = delta.getResource();
+//     
+//             // set stack of elements
+//             if (this.currentElement == null && rootInfo != null) {
+////                   this.currentElement = rootInfo.project;
+//             }
+//             
+//             // process current delta
+//             boolean processChildren = true;
+//             if (res instanceof IProject) {
+//                     processChildren = 
+//                             this.updateCurrentDeltaAndIndex(
+//                                     delta, 
+//                                     elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ? 
+//                                             IJavaElement.JAVA_PROJECT : // case of prj=src
+//                                             elementType, 
+//                                     rootInfo);
+//             } else if (rootInfo != null) {
+//                     processChildren = this.updateCurrentDeltaAndIndex(delta, elementType, rootInfo);
+//             } else {
+//                     // not yet inside a package fragment root
+//                     processChildren = true;
+//             }
+//             
+//             // get the project's output locations and traverse mode
+//             if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
+//     
+//             // process children if needed
+//             if (processChildren) {
+//                     IResourceDelta[] children = delta.getAffectedChildren();
+//                     boolean oneChildOnClasspath = false;
+//                     int length = children.length;
+//                     IResourceDelta[] orphanChildren = null;
+//                     Openable parent = null;
+//                     boolean isValidParent = true;
+//                     for (int i = 0; i < length; i++) {
+//                             IResourceDelta child = children[i];
+//                             IResource childRes = child.getResource();
+//     
+//                             // check source attachment change
+//                             this.checkSourceAttachmentChange(child, childRes);
+//                             
+//                             // find out whether the child is a package fragment root of the current project
+//                             IPath childPath = childRes.getFullPath();
+//                             int childKind = child.getKind();
+//                             RootInfo childRootInfo = this.rootInfo(childPath, childKind);
+//                             if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
+//                                     // package fragment root of another project (dealt with later)
+//                                     childRootInfo = null;
+//                             }
+//                             
+//                             // compute child type
+//                             int childType = 
+//                                     this.elementType(
+//                                             childRes, 
+//                                             childKind,
+//                                             elementType, 
+//                                             rootInfo == null ? childRootInfo : rootInfo
+//                                     );
+//                                             
+//                             // is childRes in the output folder and is it filtered out ?
+//                             boolean isResFilteredFromOutput = this.isResFilteredFromOutput(outputsInfo, childRes, childType);
+//
+//                             boolean isNestedRoot = rootInfo != null && childRootInfo != null;
+//                             if (!isResFilteredFromOutput 
+//                                             && !isNestedRoot) { // do not treat as non-java rsc if nested root
+//
+//                                     this.traverseDelta(child, childType, rootInfo == null ? childRootInfo : rootInfo, outputsInfo); // traverse delta for child in the same project
+//
+//                                     if (childType == NON_JAVA_RESOURCE) {
+//                                             if (rootInfo != null) { // if inside a package fragment root
+//                                                     if (!isValidParent) continue; 
+//                                                     if (parent == null) {
+//                                                             // find the parent of the non-java resource to attach to
+//                                                             if (this.currentElement == null
+//                                                                             || !rootInfo.project.equals(this.currentElement.getJavaProject())) { // note if currentElement is the IJavaModel, getJavaProject() is null
+//                                                                     // force the currentProject to be used
+//                                                                     this.currentElement = rootInfo.project;
+//                                                             }
+//                                                             if (elementType == IJavaElement.JAVA_PROJECT
+//                                                                     || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT 
+//                                                                             && res instanceof IProject)) { 
+//                                                                     // NB: attach non-java resource to project (not to its package fragment root)
+//                                                                     parent = rootInfo.project;
+//                                                             } else {
+//                                                                     parent = this.createElement(res, elementType, rootInfo);
+//                                                             }
+//                                                             if (parent == null) {
+//                                                                     isValidParent = false;
+//                                                                     continue;
 //                                                             }
 //                                                     }
-//                                                     IJavaElementDelta translatedDelta = this.processResourceDelta(delta);
-//                                                     if (translatedDelta != null) { 
-//                                                             this.manager.registerJavaModelDelta(translatedDelta);
+//                                                     // add child as non java resource
+//                                                     try {
+//                                                             nonJavaResourcesChanged(parent, child);
+//                                                     } catch (JavaModelException e) {
+//                                                             // ignore
 //                                                     }
-//                                                     this.manager.fire(null, ElementChangedEvent.POST_CHANGE);
-//                                             } finally {
-//                                                     // workaround for bug 15168 circular errors not reported 
-//                                                     this.manager.javaProjectsCache = null;
-//                                                     this.removedRoots = null;
+//                                             } else {
+//                                                     // the non-java resource (or its parent folder) will be attached to the java project
+//                                                     if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
+//                                                     orphanChildren[i] = child;
 //                                             }
+//                                     } else {
+//                                             oneChildOnClasspath = true;
+//                                     }
+//                             } else {
+//                                     oneChildOnClasspath = true; // to avoid reporting child delta as non-java resource delta
+//                             }
+//                                                             
+//                             // if child is a nested root 
+//                             // or if it is not a package fragment root of the current project
+//                             // but it is a package fragment root of another project, traverse delta too
+//                             if (isNestedRoot 
+//                                             || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath, childKind)) != null)) {
+//                                     this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
+//                             }
+//     
+//                             // if the child is a package fragment root of one or several other projects
+//                             ArrayList rootList;
+//                             if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
+//                                     Iterator iterator = rootList.iterator();
+//                                     while (iterator.hasNext()) {
+//                                             childRootInfo = (RootInfo) iterator.next();
+//                                             this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
+//                                     }
+//                             }
+//                     }
+//                     if (orphanChildren != null
+//                                     && (oneChildOnClasspath // orphan children are siblings of a package fragment root
+//                                             || res instanceof IProject)) { // non-java resource directly under a project
+//                                             
+//                             // attach orphan children
+//                             IProject rscProject = res.getProject();
+//                             JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
+//                             if (adoptiveProject != null 
+//                                             && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project (18698)
+//                                     for (int i = 0; i < length; i++) {
+//                                             if (orphanChildren[i] != null) {
+//                                                     try {
+//                                                             nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
+//                                                     } catch (JavaModelException e) {
+//                                                             // ignore
+//                                                     }
+//                                             }
+//                                     }
+//                             }
+//                     } // else resource delta will be added by parent
+//             } // else resource delta will be added by parent
+//     }
+       private void notifyListeners(IJavaElementDelta deltaToNotify, int eventType, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
+               final ElementChangedEvent extraEvent = new ElementChangedEvent(deltaToNotify, eventType);
+               for (int i= 0; i < listenerCount; i++) {
+                       if ((listenerMask[i] & eventType) != 0){
+                               final IElementChangedListener listener = listeners[i];
+                               long start = -1;
+                               if (VERBOSE) {
+                                       System.out.print("Listener #" + (i+1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
+                                       start = System.currentTimeMillis();
+                               }
+                               // wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
+                               Platform.run(new ISafeRunnable() {
+                                       public void handleException(Throwable exception) {
+                                               Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
+                                       }
+                                       public void run() throws Exception {
+                                               listener.elementChanged(extraEvent);
+                                       }
+                               });
+                               if (VERBOSE) {
+                                       System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+                               }
+                       }
+               }
+       }
+//     private void notifyTypeHierarchies(IElementChangedListener[] listeners, int listenerCount) {
+//             for (int i= 0; i < listenerCount; i++) {
+//                     final IElementChangedListener listener = listeners[i];
+//                     if (!(listener instanceof TypeHierarchy)) continue;
+//
+//                     // wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
+//                     Platform.run(new ISafeRunnable() {
+//                             public void handleException(Throwable exception) {
+//                                     Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
+//                             }
+//                             public void run() throws Exception {
+//                                     TypeHierarchy typeHierarchy = (TypeHierarchy)listener;
+//                                     if (typeHierarchy.hasFineGrainChanges()) {
+//                                             // case of changes in primary working copies
+//                                             typeHierarchy.needsRefresh = true;
+//                                             typeHierarchy.fireChange();
 //                                     }
+//                             }
+//                     });
+//             }
+//     }
+       /*
+        * Generic processing for elements with changed contents:<ul>
+        * <li>The element is closed such that any subsequent accesses will re-open
+        * the element reflecting its new structure.
+        * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
+        * </ul>
+        */
+       private void nonJavaResourcesChanged(Openable element, IResourceDelta delta)
+               throws JavaModelException {
+
+               // reset non-java resources if element was open
+               if (element.isOpen()) {
+                       JavaElementInfo info = (JavaElementInfo)element.getElementInfo();
+                       switch (element.getElementType()) {
+                               case IJavaElement.JAVA_MODEL :
+                                       ((JavaModelInfo) info).nonJavaResources = null;
+                                       currentDelta().addResourceDelta(delta);
+                                       return;
+                               case IJavaElement.JAVA_PROJECT :
+                                       ((JavaProjectElementInfo) info).setNonJavaResources(null);
+       
+                                       // if a package fragment root is the project, clear it too
+                                       JavaProject project = (JavaProject) element;
+                                       PackageFragmentRoot projectRoot =
+                                               (PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject());
+                                       if (projectRoot.isOpen()) {
+                                               ((PackageFragmentRootInfo) projectRoot.getElementInfo()).setNonJavaResources(
+                                                       null);
+                                       }
+                                       break;
+                               case IJavaElement.PACKAGE_FRAGMENT :
+                                        ((PackageFragmentInfo) info).setNonJavaResources(null);
+                                       break;
+                               case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+                                        ((PackageFragmentRootInfo) info).setNonJavaResources(null);
                        }
                }
+
+               JavaElementDelta current = currentDelta();
+               JavaElementDelta elementDelta = current.find(element);
+               if (elementDelta == null) {
+                       // don't use find after creating the delta as it can be null (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63434)
+                       elementDelta = current.changed(element, IJavaElementDelta.F_CONTENT);
+               }
+               elementDelta.addResourceDelta(delta);
        }
        /*
         * Flushes all deltas without firing them.