Buggy code:
public class ClasspathChange { public static final int NO_DELTA = 0 ; public static final int HAS_DELTA = 1 ; public static final int HAS_PROJECT_CHANGE = 2 ; public static final int HAS_LIBRARY_CHANGE = 4 ; JavaProject project ; IClasspathEntry [ ] oldRawClasspath ; IPath oldOutputLocation ; IClasspathEntry [ ] oldResolvedClasspath ; public ClasspathChange ( JavaProject project , IClasspathEntry [ ] oldRawClasspath , IPath oldOutputLocation , IClasspathEntry [ ] oldResolvedClasspath ) { } private void addClasspathDeltas ( JavaElementDelta delta , IPackageFragmentRoot [ ] roots , int flag ) { } private int classpathContains ( IClasspathEntry [ ] list , IClasspathEntry entry ) { } private void collectAllSubfolders ( IFolder folder , ArrayList collection ) throws JavaModelException { } private ArrayList determineAffectedPackageFragments ( IPath location ) throws JavaModelException { } public boolean equals ( Object obj ) { } public int generateDelta ( JavaElementDelta delta ) { JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; DeltaProcessingState state = manager . deltaState ; if ( ( state . findJavaProject ( this . project . getElementName ( ) ) ) == null ) return ClasspathChange . NO_DELTA ; DeltaProcessor deltaProcessor = state . getDeltaProcessor ( ) ; IClasspathEntry [ ] newResolvedClasspath = null ; IPath newOutputLocation = null ; int result = ClasspathChange . NO_DELTA ; try { JavaModelManager . PerProjectInfo perProjectInfo = this . project . getPerProjectInfo ( ) ; this . project . resolveClasspath ( perProjectInfo , false ) ; IClasspathEntry [ ] newRawClasspath ; synchronized ( perProjectInfo ) { newRawClasspath = perProjectInfo . rawClasspath ; newResolvedClasspath = perProjectInfo . getResolvedClasspath ( ) ; newOutputLocation = perProjectInfo . outputLocation ; } if ( newResolvedClasspath == null ) { <START_BUG> JavaModelManager . PerProjectInfo temporaryInfo = new JavaModelManager . PerProjectInfo ( this . project . getProject ( ) ) ; <END_BUG> this . project . resolveClasspath ( temporaryInfo , false ) ; newRawClasspath = temporaryInfo . rawClasspath ; newResolvedClasspath = temporaryInfo . getResolvedClasspath ( ) ; newOutputLocation = temporaryInfo . outputLocation ; } if ( ( ( this . oldRawClasspath ) != null ) && ( ! ( JavaProject . areClasspathsEqual ( this . oldRawClasspath , newRawClasspath , this . oldOutputLocation , newOutputLocation ) ) ) ) { delta . changed ( this . project , IJavaElementDelta . F_CLASSPATH_CHANGED ) ; result |= ClasspathChange . HAS_DELTA ; for ( int i = 0 , length = this . oldRawClasspath . length ; i < length ; i ++ ) { IClasspathEntry entry = this . oldRawClasspath [ i ] ; if ( ( entry . getEntryKind ( ) ) == ( IClasspathEntry . CPE_CONTAINER ) ) { if ( ( classpathContains ( newRawClasspath , entry ) ) == ( - 1 ) ) manager . containerPut ( this . project , entry . getPath ( ) , null ) ; } } } if ( ( ( this . oldResolvedClasspath ) != null ) && ( JavaProject . areClasspathsEqual ( this . oldResolvedClasspath , newResolvedClasspath , this . oldOutputLocation , newOutputLocation ) ) ) return result ; this . project . close ( ) ; deltaProcessor . projectCachesToReset . add ( this . project ) ; } catch ( JavaModelException e ) { if ( DeltaProcessor . VERBOSE ) { e . printStackTrace ( ) ; } return result ; } if ( ( this . oldResolvedClasspath ) == null ) return result ; delta . changed ( this . project , IJavaElementDelta . F_RESOLVED_CLASSPATH_CHANGED ) ; result |= ClasspathChange . HAS_DELTA ; state . addForRefresh ( this . project ) ; Map removedRoots = null ; IPackageFragmentRoot [ ] roots = null ; Map allOldRoots ; if ( ( allOldRoots = deltaProcessor . oldRoots ) != null ) { roots = ( ( IPackageFragmentRoot [ ] ) ( allOldRoots . get ( this . project ) ) ) ; } if ( roots != null ) { removedRoots = new HashMap ( ) ; for ( int i = 0 ; i < ( roots . length ) ; i ++ ) { IPackageFragmentRoot root = roots [ i ] ; removedRoots . put ( root . getPath ( ) , root ) ; } } int newLength = newResolvedClasspath . length ; int oldLength = this . oldResolvedClasspath . length ; for ( int i = 0 ; i < oldLength ; i ++ ) { int index = classpathContains ( newResolvedClasspath , this . oldResolvedClasspath [ i ] ) ; if ( index == ( - 1 ) ) { int entryKind = this . oldResolvedClasspath [ i ] . getEntryKind ( ) ; if ( entryKind == ( IClasspathEntry . CPE_PROJECT ) ) { result |= ClasspathChange . HAS_PROJECT_CHANGE ; continue ; } if ( entryKind == ( IClasspathEntry . CPE_LIBRARY ) ) { result |= ClasspathChange . HAS_LIBRARY_CHANGE ; } PackageFragmentRoot [ ] pkgFragmentRoots = null ; if ( removedRoots != null ) { PackageFragmentRoot oldRoot = ( ( PackageFragmentRoot ) ( removedRoots . get ( this . oldResolvedClasspath [ i ] . getPath ( ) ) ) ) ; if ( oldRoot != null ) { pkgFragmentRoots = new PackageFragmentRoot [ ] { oldRoot } ; } } if ( pkgFragmentRoots == null ) { try { ObjectVector accumulatedRoots = new ObjectVector ( ) ; HashSet rootIDs = new HashSet ( 5 ) ; rootIDs . add ( this . project . rootID ( ) ) ; this . project . computePackageFragmentRoots ( this . oldResolvedClasspath [ i ] , accumulatedRoots , rootIDs , null , false , null ) ; pkgFragmentRoots = new PackageFragmentRoot [ accumulatedRoots . size ( ) ] ; accumulatedRoots . copyInto ( pkgFragmentRoots ) ; } catch ( JavaModelException e ) { pkgFragmentRoots = new PackageFragmentRoot [ ] { } ; } } addClasspathDeltas ( delta , pkgFragmentRoots , IJavaElementDelta . F_REMOVED_FROM_CLASSPATH ) ; }

Fix:
JavaModelManager . PerProjectInfo temporaryInfo = this . project . newTemporaryInfo ( ) ;