Program: 32816
Project: 32816
Buggy source:
/** 
 * Fetches a particular element. <p>This might seem redundant with the existence of   {@link #get(int)}. However, the goals of the methods are different.  This method exists to be called by   {@link #get(int)} or {@link #preFetch(int)}. This distinction allows users overriding this class a means of entry retrieval which does not implicitly execute a pre-fetch.  This is particularly key for users overriding   {@link #preFetch(int)}
 * @param index The index of the value to retrieve
 * @param recordHitsOrMisses Whether to increment the hit/miss counters(this should always be <code>false</code> when called from {@link #preFetch(int)}).
 * @return The value associated with the given index,or null if the index is not found.
 */
protected final Object fetch(int index,boolean recordHitsOrMisses){
  getReadWriteLock().writeLock().lock();
  try {
    Object value=null;
    IndexedTreeNode treeNode=indexTree.getNode(index);
    Object nodeValue=treeNode.getValue();
    if (EMPTY_INDEX_NODE != nodeValue && nodeValue != null) {
      cacheHits++;
      Object agedTreeNodeObject=treeNode.getValue();
      IndexedTreeNode agedTreeNode=(IndexedTreeNode)agedTreeNodeObject;
      Object agedNodeObject=agedTreeNode.getValue();
      AgedNode agedNode=(AgedNode)agedNodeObject;
      value=agedNode.getValue();
      agedTreeNode.removeFromTree();
      treeNode.setValue(cache.addByNode(agedNode));
    }
 else {
      cacheMisses++;
      value=source.get(index);
      if (currentSize < maxSize) {
        currentSize++;
        IndexedTreeNode cachedValue=cache.addByNode(new AgedNode(treeNode,value));
        treeNode.setValue(cachedValue);
      }
 else {
        IndexedTreeNode oldValue=cache.getNode(currentSize - 1);
        oldValue.removeFromTree();
        AgedNode oldNode=(AgedNode)oldValue.getValue();
        IndexedTreeNode oldTreeNode=oldNode.getIndexNode();
        oldTreeNode.setValue(EMPTY_INDEX_NODE);
        IndexedTreeNode cachedValue=cache.addByNode(new AgedNode(treeNode,value));
        treeNode.setValue(cachedValue);
      }
    }
    return value;
  }
  finally {
    getReadWriteLock().writeLock().unlock();
  }
}

Fixed version (ground truth):
/** 
 * Fetches a particular element. <p>This might seem redundant with the existence of   {@link #get(int)}. However, the goals of the methods are different.  This method exists to be called by   {@link #get(int)} or {@link #preFetch(int)}. This distinction allows users overriding this class a means of entry retrieval which does not implicitly execute a pre-fetch.  This is particularly key for users overriding   {@link #preFetch(int)}
 * @param index The index of the value to retrieve
 * @param recordHitsOrMisses Whether to increment the hit/miss counters(this should always be <code>false</code> when called from {@link #preFetch(int)}).
 * @return The value associated with the given index,or null if the index is not found.
 */
protected final Object fetch(int index,boolean recordHitsOrMisses){
  getReadWriteLock().writeLock().lock();
  try {
    Object value=null;
    IndexedTreeNode treeNode=indexTree.getNode(index);
    Object nodeValue=treeNode.getValue();
    if (EMPTY_INDEX_NODE != nodeValue && nodeValue != null) {
      if (recordHitsOrMisses)       cacheHits++;
      Object agedTreeNodeObject=treeNode.getValue();
      IndexedTreeNode agedTreeNode=(IndexedTreeNode)agedTreeNodeObject;
      Object agedNodeObject=agedTreeNode.getValue();
      AgedNode agedNode=(AgedNode)agedNodeObject;
      value=agedNode.getValue();
      agedTreeNode.removeFromTree();
      treeNode.setValue(cache.addByNode(agedNode));
    }
 else {
      if (recordHitsOrMisses)       cacheMisses++;
      value=source.get(index);
      if (currentSize < maxSize) {
        currentSize++;
        IndexedTreeNode cachedValue=cache.addByNode(new AgedNode(treeNode,value));
        treeNode.setValue(cachedValue);
      }
 else {
        IndexedTreeNode oldValue=cache.getNode(currentSize - 1);
        oldValue.removeFromTree();
        AgedNode oldNode=(AgedNode)oldValue.getValue();
        IndexedTreeNode oldTreeNode=oldNode.getIndexNode();
        oldTreeNode.setValue(EMPTY_INDEX_NODE);
        IndexedTreeNode cachedValue=cache.addByNode(new AgedNode(treeNode,value));
        treeNode.setValue(cachedValue);
      }
    }
    return value;
  }
  finally {
    getReadWriteLock().writeLock().unlock();
  }
}