Program: 17214
Project: 17214
Buggy source:
/** 
 * Gets the value for the specified key from the underlying cache, including attempting to load it if a CacheLoader is configured (with read-through). <p/> Any events that need to be raised are added to the specified dispatcher.
 * @param key        the key of the entry to get from the cache
 * @param dispatcher the dispatcher for events
 * @return the value loaded
 */
private V getValue(K key,RICacheEventDispatcher<K,V> dispatcher){
  long now=System.currentTimeMillis();
  long start=statisticsEnabled() ? System.nanoTime() : 0;
  Object internalKey=keyConverter.toInternal(key);
  RICachedValue cachedValue=null;
  V value=null;
  lockManager.lock(key);
  try {
    cachedValue=entries.get(internalKey);
    boolean isExpired=cachedValue != null && cachedValue.isExpiredAt(now);
    if (cachedValue == null || isExpired) {
      V expiredValue=isExpired ? valueConverter.fromInternal(cachedValue.get()) : null;
      if (isExpired) {
        processExpiries(key,dispatcher,expiredValue);
      }
      if (statisticsEnabled()) {
        statistics.increaseCacheMisses(1);
      }
      if (configuration.isReadThrough() && cacheLoader != null) {
        try {
          value=cacheLoader.load(key);
        }
 catch (        Exception e) {
          if (!(e instanceof CacheLoaderException)) {
            throw new CacheLoaderException("String_Node_Str",e);
          }
 else {
            throw e;
          }
        }
      }
      if (value == null) {
        return null;
      }
      Duration duration;
      try {
        duration=expiryPolicy.getExpiryForCreation();
      }
 catch (      Throwable t) {
        duration=getDefaultDuration();
      }
      long expiryTime=duration.getAdjustedTime(now);
      Object internalValue=valueConverter.toInternal(value);
      cachedValue=new RICachedValue(internalValue,now,expiryTime);
      if (cachedValue.isExpiredAt(now)) {
        return null;
      }
 else {
        entries.put(internalKey,cachedValue);
        dispatcher.addEvent(CacheEntryCreatedListener.class,new RICacheEntryEvent<K,V>(this,key,value,CREATED));
      }
    }
 else {
      value=valueConverter.fromInternal(cachedValue.getInternalValue(now));
      RIEntry<K,V> entry=new RIEntry<K,V>(key,value);
      try {
        Duration duration=expiryPolicy.getExpiryForAccess();
        if (duration != null) {
          long expiryTime=duration.getAdjustedTime(now);
          cachedValue.setExpiryTime(expiryTime);
        }
      }
 catch (      Throwable t) {
      }
      if (statisticsEnabled()) {
        statistics.increaseCacheHits(1);
      }
    }
  }
  finally {
    lockManager.unLock(key);
    if (statisticsEnabled()) {
      statistics.addGetTimeNano(System.nanoTime() - start);
    }
  }
  return value;
}

Fixed version (ground truth):
/** 
 * Gets the value for the specified key from the underlying cache, including attempting to load it if a CacheLoader is configured (with read-through). <p> Any events that need to be raised are added to the specified dispatcher. </p>
 * @param key        the key of the entry to get from the cache
 * @param dispatcher the dispatcher for events
 * @return the value loaded
 */
private V getValue(K key,RICacheEventDispatcher<K,V> dispatcher){
  long now=System.currentTimeMillis();
  long start=statisticsEnabled() ? System.nanoTime() : 0;
  Object internalKey=keyConverter.toInternal(key);
  RICachedValue cachedValue=null;
  V value=null;
  lockManager.lock(key);
  try {
    cachedValue=entries.get(internalKey);
    boolean isExpired=cachedValue != null && cachedValue.isExpiredAt(now);
    if (cachedValue == null || isExpired) {
      V expiredValue=isExpired ? valueConverter.fromInternal(cachedValue.get()) : null;
      if (isExpired) {
        processExpiries(key,dispatcher,expiredValue);
      }
      if (statisticsEnabled()) {
        statistics.increaseCacheMisses(1);
      }
      if (configuration.isReadThrough() && cacheLoader != null) {
        try {
          value=cacheLoader.load(key);
        }
 catch (        Exception e) {
          if (!(e instanceof CacheLoaderException)) {
            throw new CacheLoaderException("String_Node_Str",e);
          }
 else {
            throw e;
          }
        }
      }
      if (value == null) {
        return null;
      }
      Duration duration;
      try {
        duration=expiryPolicy.getExpiryForCreation();
      }
 catch (      Throwable t) {
        duration=getDefaultDuration();
      }
      long expiryTime=duration.getAdjustedTime(now);
      Object internalValue=valueConverter.toInternal(value);
      cachedValue=new RICachedValue(internalValue,now,expiryTime);
      if (cachedValue.isExpiredAt(now)) {
        return null;
      }
 else {
        entries.put(internalKey,cachedValue);
        dispatcher.addEvent(CacheEntryCreatedListener.class,new RICacheEntryEvent<K,V>(this,key,value,CREATED));
      }
    }
 else {
      value=valueConverter.fromInternal(cachedValue.getInternalValue(now));
      RIEntry<K,V> entry=new RIEntry<K,V>(key,value);
      try {
        Duration duration=expiryPolicy.getExpiryForAccess();
        if (duration != null) {
          long expiryTime=duration.getAdjustedTime(now);
          cachedValue.setExpiryTime(expiryTime);
        }
      }
 catch (      Throwable t) {
      }
      if (statisticsEnabled()) {
        statistics.increaseCacheHits(1);
      }
    }
  }
  finally {
    lockManager.unLock(key);
    if (statisticsEnabled()) {
      statistics.addGetTimeNano(System.nanoTime() - start);
    }
  }
  return value;
}