Program: 17334
Project: 17334
Buggy source:
/** 
 * A implementation of PutAll that allows optional replacement of existing values.
 * @param map                    the Map of entries to put
 * @param replaceExistingValues  should existing values be replaced by thosein the map?
 */
public void putAll(Map<? extends K,? extends V> map,final boolean replaceExistingValues){
  ensureOpen();
  long start=statisticsEnabled() ? System.nanoTime() : 0;
  long now=System.currentTimeMillis();
  if (map.containsKey(null)) {
    throw new NullPointerException("String_Node_Str");
  }
  CacheException exception=null;
  RICacheEventEventDispatcher<K,V> dispatcher=new RICacheEventEventDispatcher<K,V>();
  try {
    boolean isWriteThrough=configuration.isWriteThrough() && cacheWriter != null;
    ArrayList<Cache.Entry<? extends K,? extends V>> entriesToWrite=new ArrayList<Cache.Entry<? extends K,? extends V>>();
    HashSet<K> keysToPut=new HashSet<K>();
    for (    Map.Entry<? extends K,? extends V> entry : map.entrySet()) {
      K key=entry.getKey();
      V value=entry.getValue();
      if (value == null) {
        throw new NullPointerException("String_Node_Str" + key + "String_Node_Str");
      }
      lockManager.lock(key);
      keysToPut.add(key);
      if (isWriteThrough) {
        entriesToWrite.add(new RIEntry<K,V>(key,value));
      }
    }
    if (isWriteThrough) {
      try {
        cacheWriter.writeAll(entriesToWrite);
      }
 catch (      CacheException e) {
        exception=e;
      }
      for (      Entry entry : entriesToWrite) {
        keysToPut.remove(entry.getKey());
      }
    }
    for (    K key : keysToPut) {
      V value=map.get(key);
      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;
        try {
          duration=expiryPolicy.getTTLForCreatedEntry(new RIEntry<K,V>(key,value));
        }
 catch (        Throwable t) {
          duration=getDefaultDuration();
        }
        long expiryTime=duration.getAdjustedTime(now);
        cachedValue=new RICachedValue(internalValue,now,expiryTime);
        entries.put(internalKey,cachedValue);
        dispatcher.addEvent(CacheEntryCreatedListener.class,new RICacheEntryEvent<K,V>(this,key,value));
      }
 else       if (replaceExistingValues) {
        V oldValue=valueConverter.fromInternal(cachedValue.get());
        try {
          Duration duration=expiryPolicy.getTTLForModifiedEntry(new RIEntry<K,V>(key,value,oldValue));
          if (duration != null) {
            long expiryTime=duration.getAdjustedTime(now);
            cachedValue.setExpiryTime(expiryTime);
          }
        }
 catch (        Throwable t) {
        }
        cachedValue.setInternalValue(internalValue,now);
        dispatcher.addEvent(CacheEntryUpdatedListener.class,new RICacheEntryEvent<K,V>(this,key,value,oldValue));
      }
    }
  }
  finally {
    for (    Map.Entry<? extends K,? extends V> entry : map.entrySet()) {
      K key=entry.getKey();
      V value=entry.getValue();
      lockManager.unLock(key);
    }
  }
  dispatcher.dispatch(cacheEntryListenerRegistrations.values());
  if (statisticsEnabled()) {
    statistics.increaseCachePuts(map.size());
    statistics.addPutTimeNano(System.nanoTime() - start);
  }
  if (exception != null) {
    throw exception;
  }
}

Fixed version (ground truth):
/** 
 * A implementation of PutAll that allows optional replacement of existing values and optionally writing values when Write Through is configured.
 * @param map                    the Map of entries to put
 * @param replaceExistingValues  should existing values be replaced by those in the map?
 * @param useWriteThrough        should write-through be used if it is configured
 */
public void putAll(Map<? extends K,? extends V> map,final boolean replaceExistingValues,boolean useWriteThrough){
  ensureOpen();
  long start=statisticsEnabled() ? System.nanoTime() : 0;
  long now=System.currentTimeMillis();
  if (map.containsKey(null)) {
    throw new NullPointerException("String_Node_Str");
  }
  CacheException exception=null;
  RICacheEventEventDispatcher<K,V> dispatcher=new RICacheEventEventDispatcher<K,V>();
  try {
    boolean isWriteThrough=configuration.isWriteThrough() && cacheWriter != null && useWriteThrough;
    ArrayList<Cache.Entry<? extends K,? extends V>> entriesToWrite=new ArrayList<Cache.Entry<? extends K,? extends V>>();
    HashSet<K> keysToPut=new HashSet<K>();
    for (    Map.Entry<? extends K,? extends V> entry : map.entrySet()) {
      K key=entry.getKey();
      V value=entry.getValue();
      if (value == null) {
        throw new NullPointerException("String_Node_Str" + key + "String_Node_Str");
      }
      lockManager.lock(key);
      keysToPut.add(key);
      if (isWriteThrough) {
        entriesToWrite.add(new RIEntry<K,V>(key,value));
      }
    }
    if (isWriteThrough) {
      try {
        cacheWriter.writeAll(entriesToWrite);
      }
 catch (      CacheException e) {
        exception=e;
      }
      for (      Entry entry : entriesToWrite) {
        keysToPut.remove(entry.getKey());
      }
    }
    for (    K key : keysToPut) {
      V value=map.get(key);
      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;
        try {
          duration=expiryPolicy.getTTLForCreatedEntry(new RIEntry<K,V>(key,value));
        }
 catch (        Throwable t) {
          duration=getDefaultDuration();
        }
        long expiryTime=duration.getAdjustedTime(now);
        cachedValue=new RICachedValue(internalValue,now,expiryTime);
        entries.put(internalKey,cachedValue);
        dispatcher.addEvent(CacheEntryCreatedListener.class,new RICacheEntryEvent<K,V>(this,key,value));
      }
 else       if (replaceExistingValues) {
        V oldValue=valueConverter.fromInternal(cachedValue.get());
        try {
          Duration duration=expiryPolicy.getTTLForModifiedEntry(new RIEntry<K,V>(key,value,oldValue));
          if (duration != null) {
            long expiryTime=duration.getAdjustedTime(now);
            cachedValue.setExpiryTime(expiryTime);
          }
        }
 catch (        Throwable t) {
        }
        cachedValue.setInternalValue(internalValue,now);
        dispatcher.addEvent(CacheEntryUpdatedListener.class,new RICacheEntryEvent<K,V>(this,key,value,oldValue));
      }
    }
  }
  finally {
    for (    Map.Entry<? extends K,? extends V> entry : map.entrySet()) {
      K key=entry.getKey();
      V value=entry.getValue();
      lockManager.unLock(key);
    }
  }
  dispatcher.dispatch(cacheEntryListenerRegistrations.values());
  if (statisticsEnabled()) {
    statistics.increaseCachePuts(map.size());
    statistics.addPutTimeNano(System.nanoTime() - start);
  }
  if (exception != null) {
    throw exception;
  }
}