Program: 17345
Project: 17345
Buggy source:
@Override public V getAndPut(K key,V value){
  checkStatusStarted();
  if (value == null) {
    throw new NullPointerException("String_Node_Str" + key);
  }
  long start=statisticsEnabled() ? System.nanoTime() : 0;
  long now=System.currentTimeMillis();
  V result;
  lockManager.lock(key);
  try {
    RIEntry<K,V> entry=new RIEntry<K,V>(key,value);
    writeCacheEntry(entry);
    RICacheEventEventDispatcher<K,V> dispatcher=new RICacheEventEventDispatcher<K,V>();
    Object internalKey=keyConverter.toInternal(key);
    Object internalValue=valueConverter.toInternal(value);
    RICachedValue cachedValue=entries.get(internalKey);
    boolean isExpired=cachedValue != null && cachedValue.isExpiredAt(now);
    if (cachedValue == null || isExpired) {
      if (isExpired) {
        V expiredValue=valueConverter.fromInternal(cachedValue.get());
        dispatcher.addEvent(CacheEntryExpiredListener.class,new RICacheEntryEvent<K,V>(this,key,expiredValue));
      }
      Duration duration=expiryPolicy.getTTLForCreatedEntry(entry);
      long expiryTime=duration.getAdjustedTime(now);
      cachedValue=new RICachedValue(internalValue,now,expiryTime);
      entries.put(internalKey,cachedValue);
      result=null;
      dispatcher.addEvent(CacheEntryCreatedListener.class,new RICacheEntryEvent<K,V>(this,key,value));
    }
 else {
      V oldValue=valueConverter.fromInternal(cachedValue.getInternalValue(now));
      dispatcher.addEvent(CacheEntryReadListener.class,new RICacheEntryEvent<K,V>(this,key,oldValue));
      Duration duration=expiryPolicy.getTTLForModifiedEntry(entry,new Duration(now,cachedValue.getExpiryTime()));
      long expiryTime=duration.getAdjustedTime(now);
      cachedValue.setInternalValue(internalValue,now);
      cachedValue.setExpiryTime(expiryTime);
      result=oldValue;
      dispatcher.addEvent(CacheEntryUpdatedListener.class,new RICacheEntryEvent<K,V>(this,key,value,oldValue));
    }
    dispatcher.dispatch(cacheEntryListenerRegistrations.values());
  }
  finally {
    lockManager.unLock(key);
  }
  if (statisticsEnabled()) {
    statistics.increaseCachePuts(1);
    statistics.addPutTimeNano(System.nanoTime() - start);
  }
  return result;
}

Fixed version (ground truth):
@Override public V getAndPut(K key,V value){
  checkStatusStarted();
  if (value == null) {
    throw new NullPointerException("String_Node_Str" + key);
  }
  long start=statisticsEnabled() ? System.nanoTime() : 0;
  long now=System.currentTimeMillis();
  V result;
  lockManager.lock(key);
  try {
    RIEntry<K,V> entry=new RIEntry<K,V>(key,value);
    writeCacheEntry(entry);
    RICacheEventEventDispatcher<K,V> dispatcher=new RICacheEventEventDispatcher<K,V>();
    Object internalKey=keyConverter.toInternal(key);
    Object internalValue=valueConverter.toInternal(value);
    RICachedValue cachedValue=entries.get(internalKey);
    boolean isExpired=cachedValue != null && cachedValue.isExpiredAt(now);
    if (cachedValue == null || isExpired) {
      if (isExpired) {
        V expiredValue=valueConverter.fromInternal(cachedValue.get());
        dispatcher.addEvent(CacheEntryExpiredListener.class,new RICacheEntryEvent<K,V>(this,key,expiredValue));
      }
      Duration duration=expiryPolicy.getTTLForCreatedEntry(entry);
      long expiryTime=duration.getAdjustedTime(now);
      cachedValue=new RICachedValue(internalValue,now,expiryTime);
      entries.put(internalKey,cachedValue);
      result=null;
      dispatcher.addEvent(CacheEntryCreatedListener.class,new RICacheEntryEvent<K,V>(this,key,value));
    }
 else {
      V oldValue=valueConverter.fromInternal(cachedValue.getInternalValue(now));
      dispatcher.addEvent(CacheEntryReadListener.class,new RICacheEntryEvent<K,V>(this,key,oldValue));
      Duration duration=expiryPolicy.getTTLForModifiedEntry(entry,new Duration(now,cachedValue.getExpiryTime()));
      long expiryTime=duration.getAdjustedTime(now);
      cachedValue.setInternalValue(internalValue,now);
      cachedValue.setExpiryTime(expiryTime);
      result=oldValue;
      dispatcher.addEvent(CacheEntryUpdatedListener.class,new RICacheEntryEvent<K,V>(this,key,value,oldValue));
    }
    dispatcher.dispatch(cacheEntryListenerRegistrations.values());
  }
  finally {
    lockManager.unLock(key);
  }
  if (statisticsEnabled()) {
    statistics.increaseCachePuts(1);
    statistics.addPutTimeNano(System.nanoTime() - start);
  }
  if (result != null) {
    statistics.increaseCacheHits(1);
    statistics.addGetTimeNano(System.nanoTime() - start);
  }
  return result;
}