Program: 154065
Project: 154065
Buggy source:
/** 
 * Adds an array of tiles to the tile cache.
 * @param owner The <code>RenderedImage</code> that the tile belongs to.
 * @param tileIndices An array of <code>Point</code>s containing the<code>tileX</code> and <code>tileY</code> indices for each tile.
 * @param tiles The array of tile <code>Raster</code>s containing tile data.
 * @param tileCacheMetric Object which provides an ordering metricassociated with the <code>RenderedImage</code> owner.
 * @since 1.1
 */
public synchronized void addTiles(RenderedImage owner,Point[] tileIndices,Raster[] tiles,Object tileCacheMetric){
  if (memoryCapacity == 0) {
    return;
  }
  for (int i=0; i < tileIndices.length; i++) {
    int tileX=tileIndices[i].x;
    int tileY=tileIndices[i].y;
    Raster tile=tiles[i];
    Object key=SunCachedTile.hashKey(owner,tileX,tileY);
    SunCachedTile ct=(SunCachedTile)cache.get(key);
    if (ct != null) {
      ct.timeStamp=timeStamp++;
      if (ct != first) {
        if (ct == last) {
          last=ct.previous;
          last.next=null;
        }
 else {
          ct.previous.next=ct.next;
          ct.next.previous=ct.previous;
        }
        ct.previous=null;
        ct.next=first;
        first.previous=ct;
        first=ct;
      }
      hitCount++;
      if (diagnostics) {
        ct.action=UPDATE_FROM_ADD;
        setChanged();
        notifyObservers(ct);
      }
    }
 else {
      ct=new SunCachedTile(owner,tileX,tileY,tile,tileCacheMetric);
      ct.timeStamp=timeStamp++;
      ct.previous=null;
      ct.next=first;
      if (first == null && last == null) {
        first=ct;
        last=ct;
      }
 else {
        first.previous=ct;
        first=ct;
      }
      if (cache.put(ct.key,ct) == null) {
        memoryUsage+=ct.memorySize;
        tileCount++;
        if (cacheSortedSet != null) {
          cacheSortedSet.add(ct);
        }
        if (diagnostics) {
          ct.action=ADD;
          setChanged();
          notifyObservers(ct);
        }
      }
      if (memoryUsage > memoryCapacity) {
        memoryControl();
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * Adds an array of tiles to the tile cache.
 * @param owner The <code>RenderedImage</code> that the tile belongs to.
 * @param tileIndices An array of <code>Point</code>s containing the<code>tileX</code> and <code>tileY</code> indices for each tile.
 * @param tiles The array of tile <code>Raster</code>s containing tile data.
 * @param tileCacheMetric Object which provides an ordering metricassociated with the <code>RenderedImage</code> owner.
 * @since 1.1
 */
public synchronized void addTiles(RenderedImage owner,Point[] tileIndices,Raster[] tiles,Object tileCacheMetric){
  if (memoryCapacity == 0) {
    return;
  }
  for (int i=0; i < tileIndices.length; i++) {
    int tileX=tileIndices[i].x;
    int tileY=tileIndices[i].y;
    Raster tile=tiles[i];
    Object key=SunCachedTile.hashKey(owner,tileX,tileY);
    SunCachedTile ct=(SunCachedTile)cache.get(key);
    if (ct != null) {
      ct.timeStamp=timeStamp++;
      if (ct != first) {
        if (ct == last) {
          last=ct.previous;
          last.next=null;
        }
 else {
          ct.previous.next=ct.next;
          ct.next.previous=ct.previous;
        }
        ct.previous=null;
        ct.next=first;
        first.previous=ct;
        first=ct;
      }
      hitCount++;
      if (diagnostics) {
        ct.action=UPDATE_FROM_ADD;
        setChanged();
        notifyObservers(ct);
      }
    }
 else {
      ct=new SunCachedTile(owner,tileX,tileY,tile,tileCacheMetric);
      if (memoryUsage + ct.memorySize > memoryCapacity && ct.memorySize > (long)(memoryCapacity * memoryThreshold)) {
        return;
      }
      ct.timeStamp=timeStamp++;
      ct.previous=null;
      ct.next=first;
      if (first == null && last == null) {
        first=ct;
        last=ct;
      }
 else {
        first.previous=ct;
        first=ct;
      }
      if (cache.put(ct.key,ct) == null) {
        memoryUsage+=ct.memorySize;
        tileCount++;
        if (cacheSortedSet != null) {
          cacheSortedSet.add(ct);
        }
        if (diagnostics) {
          ct.action=ADD;
          setChanged();
          notifyObservers(ct);
        }
      }
      if (memoryUsage > memoryCapacity) {
        memoryControl();
      }
    }
  }
}