improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / SetClasspathOperation.java
index ac51e61..0329e7e 100644 (file)
 package net.sourceforge.phpdt.internal.core;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
 
 import net.sourceforge.phpdt.core.IClasspathEntry;
 import net.sourceforge.phpdt.core.IJavaElement;
@@ -22,6 +24,7 @@ import net.sourceforge.phpdt.core.IJavaModelStatus;
 import net.sourceforge.phpdt.core.IJavaProject;
 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
 import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.compiler.util.ObjectVector;
 import net.sourceforge.phpdt.internal.core.util.Util;
 
 import org.eclipse.core.resources.IFolder;
@@ -43,6 +46,7 @@ public class SetClasspathOperation extends JavaModelOperation {
        IClasspathEntry[] oldResolvedPath, newResolvedPath;
        IClasspathEntry[] newRawPath;
        boolean canChangeResources;
+       boolean classpathWasSaved;
        boolean needCycleCheck;
        boolean needValidation;
        boolean needSave;
@@ -273,109 +277,112 @@ public class SetClasspathOperation extends JavaModelOperation {
         * Use three deltas in case the same root is removed/added/reordered (for
         * instance, if it is changed from K_SOURCE to K_BINARY or vice versa)
         */
-//     protected void generateClasspathChangeDeltas(
-//             IClasspathEntry[] oldResolvedPath,
-//             IClasspathEntry[] newResolvedPath,
-//             final JavaProject project) {
-//     
-//             JavaModelManager manager = JavaModelManager.getJavaModelManager();
-//             boolean needToUpdateDependents = false;
-//             JavaElementDelta delta = new JavaElementDelta(getJavaModel());
-//             boolean hasDelta = false;
-//             int oldLength = oldResolvedPath.length;
-//             int newLength = newResolvedPath.length;
-//                     
+       protected void generateClasspathChangeDeltas() {
+
+               JavaModelManager manager = JavaModelManager.getJavaModelManager();
+               boolean needToUpdateDependents = false;
+               JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+               boolean hasDelta = false;
+               if (this.classpathWasSaved) {
+                       delta.changed(this.project, IJavaElementDelta.F_CLASSPATH_CHANGED);
+                       hasDelta = true;
+               }
+               int oldLength = oldResolvedPath.length;
+               int newLength = newResolvedPath.length;
+                       
 //             final IndexManager indexManager = manager.getIndexManager();
-//             Map oldRoots = null;
-//             IPackageFragmentRoot[] roots = null;
-//             if (project.isOpen()) {
-//                     try {
-//                             roots = project.getPackageFragmentRoots();
-//                     } catch (JavaModelException e) {
-//                     }
-//             } else {
-//                     Map allRemovedRoots ;
-//                     if ((allRemovedRoots = manager.deltaProcessor.removedRoots) != null) {
-//                             roots = (IPackageFragmentRoot[]) allRemovedRoots.get(project);
-//                     }
-//             }
-//             if (roots != null) {
-//                     oldRoots = new HashMap();
-//                     for (int i = 0; i < roots.length; i++) {
-//                             IPackageFragmentRoot root = roots[i];
-//                             oldRoots.put(root.getPath(), root);
-//                     }
-//             }
-//             for (int i = 0; i < oldLength; i++) {
-//                     
-//                     int index = classpathContains(newResolvedPath, oldResolvedPath[i]);
-//                     if (index == -1) {
-//                             // do not notify remote project changes
-//                             if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
-//                                     needToUpdateDependents = true;
-//                                     this.needCycleCheck = true;
-//                                     continue; 
-//                             }
-//     
-//                             IPackageFragmentRoot[] pkgFragmentRoots = null;
-//                             if (oldRoots != null) {
-//                                     IPackageFragmentRoot oldRoot = (IPackageFragmentRoot)  oldRoots.get(oldResolvedPath[i].getPath());
-//                                     if (oldRoot != null) { // use old root if any (could be none if entry wasn't bound)
-//                                             pkgFragmentRoots = new IPackageFragmentRoot[] { oldRoot };
-//                                     }
-//                             }
-//                             if (pkgFragmentRoots == null) {
-//                                     try {
-//                                             ObjectVector accumulatedRoots = new ObjectVector();
-//                                             HashSet rootIDs = new HashSet(5);
-//                                             rootIDs.add(project.rootID());
-//                                             project.computePackageFragmentRoots(
-//                                                     oldResolvedPath[i], 
-//                                                     accumulatedRoots, 
-//                                                     rootIDs,
-//                                                     true, // inside original project
-//                                                     false, // don't check existency
-//                                                     false); // don't retrieve exported roots
-//                                             pkgFragmentRoots = new IPackageFragmentRoot[accumulatedRoots.size()];
-//                                             accumulatedRoots.copyInto(pkgFragmentRoots);
-//                                     } catch (JavaModelException e) {
-//                                             pkgFragmentRoots =  new IPackageFragmentRoot[] {};
-//                                     }
-//                             }
-//                             addClasspathDeltas(pkgFragmentRoots, IJavaElementDelta.F_REMOVED_FROM_CLASSPATH, delta);
-//                             
-//                             int changeKind = oldResolvedPath[i].getEntryKind();
-//                             needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE) || oldResolvedPath[i].isExported();
-//     
-//                             // Remove the .java files from the index for a source folder
-//                             // For a lib folder or a .jar file, remove the corresponding index if not shared.
+               Map oldRoots = null;
+               IPackageFragmentRoot[] roots = null;
+               if (project.isOpen()) {
+                       try {
+                               roots = project.getPackageFragmentRoots();
+                       } catch (JavaModelException e) {
+                               // ignore
+                       }
+               } else {
+                       Map allRemovedRoots ;
+                       if ((allRemovedRoots = manager.getDeltaProcessor().removedRoots) != null) {
+                               roots = (IPackageFragmentRoot[]) allRemovedRoots.get(project);
+                       }
+               }
+               if (roots != null) {
+                       oldRoots = new HashMap();
+                       for (int i = 0; i < roots.length; i++) {
+                               IPackageFragmentRoot root = roots[i];
+                               oldRoots.put(root.getPath(), root);
+                       }
+               }
+               for (int i = 0; i < oldLength; i++) {
+                       
+                       int index = classpathContains(newResolvedPath, oldResolvedPath[i]);
+                       if (index == -1) {
+                               // do not notify remote project changes
+                               if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
+                                       needToUpdateDependents = true;
+                                       this.needCycleCheck = true;
+                                       continue; 
+                               }
+
+                               IPackageFragmentRoot[] pkgFragmentRoots = null;
+                               if (oldRoots != null) {
+                                       IPackageFragmentRoot oldRoot = (IPackageFragmentRoot)  oldRoots.get(oldResolvedPath[i].getPath());
+                                       if (oldRoot != null) { // use old root if any (could be none if entry wasn't bound)
+                                               pkgFragmentRoots = new IPackageFragmentRoot[] { oldRoot };
+                                       }
+                               }
+                               if (pkgFragmentRoots == null) {
+                                       try {
+                                               ObjectVector accumulatedRoots = new ObjectVector();
+                                               HashSet rootIDs = new HashSet(5);
+                                               rootIDs.add(project.rootID());
+                                               project.computePackageFragmentRoots(
+                                                       oldResolvedPath[i], 
+                                                       accumulatedRoots, 
+                                                       rootIDs,
+                                                       true, // inside original project
+                                                       false, // don't check existency
+                                                       false); // don't retrieve exported roots
+                                               pkgFragmentRoots = new IPackageFragmentRoot[accumulatedRoots.size()];
+                                               accumulatedRoots.copyInto(pkgFragmentRoots);
+                                       } catch (JavaModelException e) {
+                                               pkgFragmentRoots =  new IPackageFragmentRoot[] {};
+                                       }
+                               }
+                               addClasspathDeltas(pkgFragmentRoots, IJavaElementDelta.F_REMOVED_FROM_CLASSPATH, delta);
+                               
+                               int changeKind = oldResolvedPath[i].getEntryKind();
+                               needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE) || oldResolvedPath[i].isExported();
+
+                               // Remove the .java files from the index for a source folder
+                               // For a lib folder or a .jar file, remove the corresponding index if not shared.
 //                             if (indexManager != null) {
 //                                     IClasspathEntry oldEntry = oldResolvedPath[i];
 //                                     final IPath path = oldEntry.getPath();
 //                                     switch (changeKind) {
 //                                             case IClasspathEntry.CPE_SOURCE:
+//                                                     final char[][] inclusionPatterns = null; //((ClasspathEntry)oldEntry).fullInclusionPatternChars();
 //                                                     final char[][] exclusionPatterns = ((ClasspathEntry)oldEntry).fullExclusionPatternChars();
 //                                                     postAction(new IPostAction() {
 //                                                             public String getID() {
 //                                                                     return path.toString();
 //                                                             }
-//                                                             public void run() throws JavaModelException {
-//                                                                     indexManager.removeSourceFolderFromIndex(project, path, exclusionPatterns);
+//                                                             public void run() /* throws JavaModelException */ {
+//                                                                     indexManager.removeSourceFolderFromIndex(project, path, inclusionPatterns, exclusionPatterns);
 //                                                             }
 //                                                     }, 
 //                                                     REMOVEALL_APPEND);
 //                                                     break;
 //                                             case IClasspathEntry.CPE_LIBRARY:
-//                                                     final DeltaProcessor deltaProcessor = manager.deltaProcessor;
+//                                                     final DeltaProcessingState deltaState = manager.deltaState;
 //                                                     postAction(new IPostAction() {
 //                                                             public String getID() {
 //                                                                     return path.toString();
 //                                                             }
-//                                                             public void run() throws JavaModelException {
-//                                                                     if (deltaProcessor.otherRoots.get(path) == null) { // if root was not shared
+//                                                             public void run() /* throws JavaModelException */ {
+//                                                                     if (deltaState.otherRoots.get(path) == null) { // if root was not shared
 //                                                                             indexManager.discardJobs(path.toString());
 //                                                                             indexManager.removeIndex(path);
-//                                                                             // TODO: we could just remove the in-memory index and have the indexing check for timestamps
+//                                                                             // TODO (kent) we could just remove the in-memory index and have the indexing check for timestamps
 //                                                                     }
 //                                                             }
 //                                                     }, 
@@ -383,66 +390,76 @@ public class SetClasspathOperation extends JavaModelOperation {
 //                                                     break;
 //                                     }               
 //                             }
-//                             hasDelta = true;
-//     
-//                     } else {
-//                             // do not notify remote project changes
-//                             if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
-//                                     this.needCycleCheck |= (oldResolvedPath[i].isExported() != newResolvedPath[index].isExported());
-//                                     continue; 
-//                             }                               
-//                             needToUpdateDependents |= (oldResolvedPath[i].isExported() != newResolvedPath[index].isExported());
-//                             if (index != i) { //reordering of the classpath
-//                                             addClasspathDeltas(
-//                                                     project.computePackageFragmentRoots(oldResolvedPath[i]),
-//                                                     IJavaElementDelta.F_REORDER,
-//                                                     delta);
-//                                             int changeKind = oldResolvedPath[i].getEntryKind();
-//                                             needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE);
-//             
-//                                             hasDelta = true;
-//                             }
-//                             
-//                             // check source attachment
-//                             IPath newSourcePath = newResolvedPath[index].getSourceAttachmentPath();
-//                             int sourceAttachmentFlags = 
-//                                     this.getSourceAttachmentDeltaFlag(
-//                                             oldResolvedPath[i].getSourceAttachmentPath(),
-//                                             newSourcePath,
-//                                             null/*not a source root path*/);
-//                             int sourceAttachmentRootFlags = 
-//                                     this.getSourceAttachmentDeltaFlag(
-//                                             oldResolvedPath[i].getSourceAttachmentRootPath(),
-//                                             newResolvedPath[index].getSourceAttachmentRootPath(),
-//                                             newSourcePath/*in case both root paths are null*/);
-//                             int flags = sourceAttachmentFlags | sourceAttachmentRootFlags;
-//                             if (flags != 0) {
-//                                     addClasspathDeltas(
-//                                             project.computePackageFragmentRoots(oldResolvedPath[i]),
-//                                             flags,
-//                                             delta);
-//                                     hasDelta = true;
-//                             }
-//                     }
-//             }
-//     
-//             for (int i = 0; i < newLength; i++) {
-//     
-//                     int index = classpathContains(oldResolvedPath, newResolvedPath[i]);
-//                     if (index == -1) {
-//                             // do not notify remote project changes
-//                             if (newResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
-//                                     needToUpdateDependents = true;
-//                                     this.needCycleCheck = true;
-//                                     continue; 
-//                             }
-//                             addClasspathDeltas(
-//                                     project.computePackageFragmentRoots(newResolvedPath[i]),
-//                                     IJavaElementDelta.F_ADDED_TO_CLASSPATH,
-//                                     delta);
-//                             int changeKind = newResolvedPath[i].getEntryKind();
-//                             
-//                             // Request indexing
+                               hasDelta = true;
+
+                       } else {
+                               // do not notify remote project changes
+                               if (oldResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
+                                       this.needCycleCheck |= (oldResolvedPath[i].isExported() != newResolvedPath[index].isExported());
+                                       continue; 
+                               }                               
+                               needToUpdateDependents |= (oldResolvedPath[i].isExported() != newResolvedPath[index].isExported());
+                               if (index != i) { //reordering of the classpath
+                                               addClasspathDeltas(
+                                                       project.computePackageFragmentRoots(oldResolvedPath[i]),
+                                                       IJavaElementDelta.F_REORDER,
+                                                       delta);
+                                               int changeKind = oldResolvedPath[i].getEntryKind();
+                                               needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE);
+               
+                                               hasDelta = true;
+                               }
+                               
+                               // check source attachment
+                               IPath newSourcePath = newResolvedPath[index].getSourceAttachmentPath();
+                               int sourceAttachmentFlags = 
+                                       this.getSourceAttachmentDeltaFlag(
+                                               oldResolvedPath[i].getSourceAttachmentPath(),
+                                               newSourcePath);
+                               IPath oldRootPath = oldResolvedPath[i].getSourceAttachmentRootPath();
+                               IPath newRootPath = newResolvedPath[index].getSourceAttachmentRootPath();
+                               int sourceAttachmentRootFlags = getSourceAttachmentDeltaFlag(oldRootPath, newRootPath);
+                               int flags = sourceAttachmentFlags | sourceAttachmentRootFlags;
+                               if (flags != 0) {
+                                       addClasspathDeltas(project.computePackageFragmentRoots(oldResolvedPath[i]), flags, delta);
+                                       hasDelta = true;
+                               } else {
+                                       if (oldRootPath == null && newRootPath == null) {
+                                               // if source path is specified and no root path, it needs to be recomputed dynamically
+                                               // force detach source on jar package fragment roots (source will be lazily computed when needed)
+                                               IPackageFragmentRoot[] computedRoots = project.computePackageFragmentRoots(oldResolvedPath[i]);
+                                               for (int j = 0; j < computedRoots.length; j++) {
+                                                       IPackageFragmentRoot root = computedRoots[j];
+                                                       // force detach source on jar package fragment roots (source will be lazily computed when needed)
+                                                       try {
+                                                               root.close();
+                                                       } catch (JavaModelException e) {
+                                                               // ignore
+                                                       }
+                                                       ((PackageFragmentRoot) root).setSourceAttachmentProperty(null);// loose info - will be recomputed
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               for (int i = 0; i < newLength; i++) {
+
+                       int index = classpathContains(oldResolvedPath, newResolvedPath[i]);
+                       if (index == -1) {
+                               // do not notify remote project changes
+                               if (newResolvedPath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
+                                       needToUpdateDependents = true;
+                                       this.needCycleCheck = true;
+                                       continue; 
+                               }
+                               addClasspathDeltas(
+                                       project.computePackageFragmentRoots(newResolvedPath[i]),
+                                       IJavaElementDelta.F_ADDED_TO_CLASSPATH,
+                                       delta);
+                               int changeKind = newResolvedPath[i].getEntryKind();
+                               
+                               // Request indexing
 //                             if (indexManager != null) {
 //                                     switch (changeKind) {
 //                                             case IClasspathEntry.CPE_LIBRARY:
@@ -460,7 +477,7 @@ public class SetClasspathOperation extends JavaModelOperation {
 //                                                                     public String getID() {
 //                                                                             return newPath.toString();
 //                                                                     }
-//                                                                     public void run() throws JavaModelException {
+//                                                                     public void run() /* throws JavaModelException */ {
 //                                                                             indexManager.indexLibrary(newPath, project.getProject());
 //                                                                     }
 //                                                             }, 
@@ -470,34 +487,58 @@ public class SetClasspathOperation extends JavaModelOperation {
 //                                             case IClasspathEntry.CPE_SOURCE:
 //                                                     IClasspathEntry entry = newResolvedPath[i];
 //                                                     final IPath path = entry.getPath();
+//                                                     final char[][] inclusionPatterns = null; //((ClasspathEntry)entry).fullInclusionPatternChars();
 //                                                     final char[][] exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
 //                                                     postAction(new IPostAction() {
 //                                                             public String getID() {
 //                                                                     return path.toString();
 //                                                             }
-//                                                             public void run() throws JavaModelException {
-//                                                                     indexManager.indexSourceFolder(project, path, exclusionPatterns);
+//                                                             public void run() /* throws JavaModelException */ {
+//                                                                     indexManager.indexSourceFolder(project, path, inclusionPatterns, exclusionPatterns);
 //                                                             }
 //                                                     }, 
 //                                                     APPEND); // append so that a removeSourceFolder action is not removed
 //                                                     break;
 //                                     }
 //                             }
-//                             
-//                             needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE) || newResolvedPath[i].isExported();
-//                             hasDelta = true;
-//     
-//                     } // classpath reordering has already been generated in previous loop
-//             }
-//     
-//             if (hasDelta) {
-//                     this.addDelta(delta);
-//             }
-//             if (needToUpdateDependents){
-//                     updateAffectedProjects(project.getProject().getFullPath());
-//             }
-//     }
+                               
+                               needToUpdateDependents |= (changeKind == IClasspathEntry.CPE_SOURCE) || newResolvedPath[i].isExported();
+                               hasDelta = true;
 
+                       } // classpath reordering has already been generated in previous loop
+               }
+
+               if (hasDelta) {
+                       this.addDelta(delta);
+               } else {
+                       this.identicalRoots = true;
+               }
+               if (needToUpdateDependents){
+                       updateAffectedProjects(project.getProject().getFullPath());
+               }
+       }
+       protected void saveClasspathIfNecessary() throws JavaModelException {
+               
+               if (!this.canChangeResources || !this.needSave) return;
+                               
+               IClasspathEntry[] classpathForSave;
+               if (this.newRawPath == ReuseClasspath || this.newRawPath == UpdateClasspath){
+                       classpathForSave = project.getRawClasspath();
+               } else {
+                       classpathForSave = this.newRawPath;
+               }
+               IPath outputLocationForSave;
+               if (this.newOutputLocation == ReuseOutputLocation){
+                       outputLocationForSave = project.getOutputLocation();
+               } else {
+                       outputLocationForSave = this.newOutputLocation;
+               }
+               // if read-only .classpath, then the classpath setting will never been performed completely
+               if (project.saveClasspath(classpathForSave, outputLocationForSave)) {
+                       this.classpathWasSaved = true;
+                       this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+               }
+       }
        protected JavaProject getProject() {
                return ((JavaProject) getElementsToProcess()[0]);
        }
@@ -528,6 +569,27 @@ public class SetClasspathOperation extends JavaModelOperation {
                }
        }
 
+       /*
+        * Returns the source attachment flag for the delta between the 2 give source paths.
+        * Returns either F_SOURCEATTACHED, F_SOURCEDETACHED, F_SOURCEATTACHED | F_SOURCEDETACHED
+        * or 0 if there is no difference.
+        */
+       private int getSourceAttachmentDeltaFlag(IPath oldPath, IPath newPath) {
+               if (oldPath == null) {
+                       if (newPath != null) {
+                               return IJavaElementDelta.F_SOURCEATTACHED;
+                       } else {
+                               return 0;
+                       }
+               } else if (newPath == null) {
+                       return IJavaElementDelta.F_SOURCEDETACHED;
+               } else if (!oldPath.equals(newPath)) {
+                       return IJavaElementDelta.F_SOURCEATTACHED | IJavaElementDelta.F_SOURCEDETACHED;
+               } else {
+                       return 0;
+               }
+       }
+       
        /**
         * Returns <code>true</code> if this operation performs no resource modifications,
         * otherwise <code>false</code>. Subclasses must override.
@@ -536,28 +598,28 @@ public class SetClasspathOperation extends JavaModelOperation {
                return !this.canChangeResources;
        }
 
-       protected void saveClasspathIfNecessary() throws JavaModelException {
-               
-               if (!this.canChangeResources || !this.needSave) return;
-                               
-               IClasspathEntry[] classpathForSave;
-               JavaProject project = getProject();
-               if (this.newRawPath == ReuseClasspath || this.newRawPath == UpdateClasspath){
-                       classpathForSave = project.getRawClasspath();
-               } else {
-                       classpathForSave = this.newRawPath;
-               }
-               IPath outputLocationForSave;
-               if (this.newOutputLocation == ReuseOutputLocation){
-                       outputLocationForSave = project.getOutputLocation();
-               } else {
-                       outputLocationForSave = this.newOutputLocation;
-               }
-               // if read-only .classpath, then the classpath setting will never been performed completely
-               if (project.saveClasspath(classpathForSave, outputLocationForSave)) {
-                       this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
-               }
-       }
+//     protected void saveClasspathIfNecessary() throws JavaModelException {
+//             
+//             if (!this.canChangeResources || !this.needSave) return;
+//                             
+//             IClasspathEntry[] classpathForSave;
+//             JavaProject project = getProject();
+//             if (this.newRawPath == ReuseClasspath || this.newRawPath == UpdateClasspath){
+//                     classpathForSave = project.getRawClasspath();
+//             } else {
+//                     classpathForSave = this.newRawPath;
+//             }
+//             IPath outputLocationForSave;
+//             if (this.newOutputLocation == ReuseOutputLocation){
+//                     outputLocationForSave = project.getOutputLocation();
+//             } else {
+//                     outputLocationForSave = this.newOutputLocation;
+//             }
+//             // if read-only .classpath, then the classpath setting will never been performed completely
+//             if (project.saveClasspath(classpathForSave, outputLocationForSave)) {
+//                     this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+//             }
+//     }
        
        public String toString(){
                StringBuffer buffer = new StringBuffer(20);
@@ -582,31 +644,52 @@ public class SetClasspathOperation extends JavaModelOperation {
                return buffer.toString();
        }
 
+//     private void updateClasspath() throws JavaModelException {
+//
+//             JavaProject project = ((JavaProject) getElementsToProcess()[0]);
+//
+//             beginTask(Util.bind("classpath.settingProgress", project.getElementName()), 2); //$NON-NLS-1$
+//
+//             // SIDE-EFFECT: from thereon, the classpath got modified
+//             project.setRawClasspath0(this.newRawPath);
+//
+//             // resolve new path (asking for marker creation if problems)
+//             if (this.newResolvedPath == null) {
+//                     this.newResolvedPath = project.getResolvedClasspath(true, this.canChangeResources);
+//             }
+//             
+////           if (this.oldResolvedPath != null) {
+////                   generateClasspathChangeDeltas(
+////                           this.oldResolvedPath,
+////                           this.newResolvedPath,
+////                           project);
+////           } else {
+//                     this.needCycleCheck = true;
+//                     updateAffectedProjects(project.getProject().getFullPath());
+////           }
+//             
+//             updateCycleMarkersIfNecessary(newResolvedPath);
+//     }
        private void updateClasspath() throws JavaModelException {
 
-               JavaProject project = ((JavaProject) getElementsToProcess()[0]);
-
                beginTask(Util.bind("classpath.settingProgress", project.getElementName()), 2); //$NON-NLS-1$
 
                // SIDE-EFFECT: from thereon, the classpath got modified
-               project.setRawClasspath0(this.newRawPath);
+               project.getPerProjectInfo().updateClasspathInformation(this.newRawPath);
 
                // resolve new path (asking for marker creation if problems)
                if (this.newResolvedPath == null) {
-                       this.newResolvedPath = project.getResolvedClasspath(true, this.canChangeResources);
+                       this.newResolvedPath = project.getResolvedClasspath(true, this.canChangeResources, false/*don't returnResolutionInProgress*/);
                }
                
-//             if (this.oldResolvedPath != null) {
-//                     generateClasspathChangeDeltas(
-//                             this.oldResolvedPath,
-//                             this.newResolvedPath,
-//                             project);
-//             } else {
+               if (this.oldResolvedPath != null) {
+                       generateClasspathChangeDeltas();
+               } else {
                        this.needCycleCheck = true;
                        updateAffectedProjects(project.getProject().getFullPath());
-//             }
+               }
                
-               updateCycleMarkersIfNecessary(newResolvedPath);
+               updateCycleMarkersIfNecessary();
        }
 
        /**
@@ -654,30 +737,53 @@ public class SetClasspathOperation extends JavaModelOperation {
        /**
         * Update cycle markers
         */
-       protected void updateCycleMarkersIfNecessary(IClasspathEntry[] newResolvedPath) {
+       protected void updateCycleMarkersIfNecessary() {
 
                if (!this.needCycleCheck) return;
                if (!this.canChangeResources) return;
                 
-               try {
-                       JavaProject project = getProject();
-                       if (!project.hasCycleMarker() && !project.hasClasspathCycle(project.getResolvedClasspath(true))){
-                               return;
-                       }
-               
-                       postAction(
-                               new IPostAction() {
-                                       public String getID() {
-                                               return "updateCycleMarkers";  //$NON-NLS-1$
-                                       }
-                                       public void run() throws JavaModelException {
-                                               JavaProject.updateAllCycleMarkers();
-                                       }
-                               },
-                               REMOVEALL_APPEND);
-               } catch(JavaModelException e){
+               if (!project.hasCycleMarker() && !project.hasClasspathCycle(newResolvedPath)){
+                       return;
                }
+       
+               postAction(
+                       new IPostAction() {
+                               public String getID() {
+                                       return "updateCycleMarkers";  //$NON-NLS-1$
+                               }
+                               public void run() throws JavaModelException {
+                                       JavaProject.updateAllCycleMarkers();
+                               }
+                       },
+                       REMOVEALL_APPEND);
        }
+//     /**
+//      * Update cycle markers
+//      */
+//     protected void updateCycleMarkersIfNecessary(IClasspathEntry[] newResolvedPath) {
+//
+//             if (!this.needCycleCheck) return;
+//             if (!this.canChangeResources) return;
+//              
+//             try {
+//                     JavaProject project = getProject();
+//                     if (!project.hasCycleMarker() && !project.hasClasspathCycle(project.getResolvedClasspath(true))){
+//                             return;
+//                     }
+//             
+//                     postAction(
+//                             new IPostAction() {
+//                                     public String getID() {
+//                                             return "updateCycleMarkers";  //$NON-NLS-1$
+//                                     }
+//                                     public void run() throws JavaModelException {
+//                                             JavaProject.updateAllCycleMarkers();
+//                                     }
+//                             },
+//                             REMOVEALL_APPEND);
+//             } catch(JavaModelException e){
+//             }
+//     }
 
        /**
         * Sets the output location of the pre-specified project.