Program: 5821
Project: 5821
Buggy source:
/** 
 * @private Check if dirty properties of an object are the same than those of another entity When they are the same, unmark the dirty flag
 * @param entity merged entity
 * @param source source entity
 * @param owner owner entity for embedded objects
 * @return true if the entity is still dirty after comparing with incoming object
 */
public boolean checkAndMarkNotDirty(MergeContext mergeContext,Object entity,Object source,Object parent){
  if (entity != null)   unsavedEntities.remove(entity);
  Map<String,Object> save=savedProperties.get(entity);
  if (save == null)   return false;
  Object owner=isEntity(entity) ? entity : parent;
  boolean oldDirty=isDirty();
  boolean oldDirtyEntity=isEntityChanged(owner);
  List<String> merged=new ArrayList<String>();
  String versionPropertyName=dataManager.getVersionPropertyName(owner);
  if (isEntity(source) && versionPropertyName != null)   save.put(versionPropertyName,dataManager.getVersion(source));
  Map<String,Object> pval=dataManager.getPropertyValues(entity,false,false);
  for (  String propName : pval.keySet()) {
    if (propName.equals(versionPropertyName) || propName.equals("String_Node_Str"))     continue;
    Object localValue=pval.get(propName);
    if (localValue instanceof PropertyHolder)     localValue=((PropertyHolder)localValue).getObject();
    Object sourceValue=dataManager.getPropertyValue(source,propName);
    if (isSameExt(sourceValue,localValue)) {
      merged.add(propName);
      continue;
    }
    if (sourceValue == null || ObjectUtil.isSimple(sourceValue) || sourceValue instanceof Value || sourceValue instanceof Enum) {
      save.put(propName,sourceValue);
    }
 else     if (isEntity(sourceValue)) {
      save.put(propName,mergeContext.getFromCache(sourceValue));
    }
 else     if (sourceValue instanceof Collection<?> && !(sourceValue instanceof LazyableCollection && !((LazyableCollection)sourceValue).isInitialized())) {
      List<Object> snapshot=new ArrayList<Object>((Collection<?>)sourceValue);
      save.put(propName,snapshot);
    }
 else     if (sourceValue instanceof Map<?,?> && !(sourceValue instanceof LazyableCollection && !((LazyableCollection)sourceValue).isInitialized())) {
      Map<?,?> map=(Map<?,?>)sourceValue;
      List<Object[]> snapshot=new ArrayList<Object[]>(map.size());
      for (      Entry<?,?> entry : map.entrySet())       snapshot.add(new Object[]{entry.getKey(),entry.getValue()});
      save.put(propName,snapshot);
    }
  }
  for (  String propName : merged)   save.remove(propName);
  int count=0;
  for (  String propName : save.keySet()) {
    if (!propName.equals(versionPropertyName))     count++;
  }
  if (count == 0) {
    savedProperties.remove(entity);
    dirtyCount--;
  }
  boolean newDirtyEntity=notifyEntityDirtyChange(owner,oldDirtyEntity);
  notifyDirtyChange(oldDirty);
  return newDirtyEntity;
}

Fixed version (ground truth):
/** 
 * @private Check if dirty properties of an object are the same than those of another entity When they are the same, unmark the dirty flag
 * @param entity merged entity
 * @param source source entity
 * @param owner owner entity for embedded objects
 * @return true if the entity is still dirty after comparing with incoming object
 */
public boolean checkAndMarkNotDirty(MergeContext mergeContext,Object entity,Object source,Object parent){
  if (entity != null)   unsavedEntities.remove(entity);
  Map<String,Object> save=savedProperties.get(entity);
  if (save == null)   return false;
  Object owner=isEntity(entity) ? entity : parent;
  boolean oldDirty=isDirty();
  boolean oldDirtyEntity=isEntityChanged(owner);
  List<String> merged=new ArrayList<String>();
  String versionPropertyName=dataManager.getVersionPropertyName(owner);
  if (isEntity(source) && versionPropertyName != null)   save.put(versionPropertyName,dataManager.getVersion(source));
  Map<String,Object> pval=dataManager.getPropertyValues(entity,false,false);
  for (  String propName : pval.keySet()) {
    if (propName.equals(versionPropertyName) || propName.equals("String_Node_Str"))     continue;
    Object localValue=pval.get(propName);
    if (localValue instanceof PropertyHolder)     localValue=((PropertyHolder)localValue).getObject();
    Object sourceValue=dataManager.getPropertyValue(source,propName);
    if (isSameExt(sourceValue,localValue)) {
      merged.add(propName);
      continue;
    }
    if (sourceValue == null || ObjectUtil.isSimple(sourceValue) || sourceValue instanceof Value || sourceValue instanceof Enum) {
      save.put(propName,sourceValue);
    }
 else     if (isEntity(sourceValue)) {
      save.put(propName,mergeContext.getFromCache(sourceValue));
    }
 else     if (sourceValue instanceof Collection<?> && !(sourceValue instanceof PersistentCollection && !((PersistentCollection)sourceValue).wasInitialized())) {
      List<Object> snapshot=new ArrayList<Object>((Collection<?>)sourceValue);
      save.put(propName,snapshot);
    }
 else     if (sourceValue instanceof Map<?,?> && !(sourceValue instanceof PersistentCollection && !((PersistentCollection)sourceValue).wasInitialized())) {
      Map<?,?> map=(Map<?,?>)sourceValue;
      List<Object[]> snapshot=new ArrayList<Object[]>(map.size());
      for (      Entry<?,?> entry : map.entrySet())       snapshot.add(new Object[]{entry.getKey(),entry.getValue()});
      save.put(propName,snapshot);
    }
  }
  for (  String propName : merged)   save.remove(propName);
  int count=0;
  for (  String propName : save.keySet()) {
    if (!propName.equals(versionPropertyName))     count++;
  }
  if (count == 0) {
    savedProperties.remove(entity);
    dirtyCount--;
  }
  boolean newDirtyEntity=notifyEntityDirtyChange(owner,oldDirtyEntity);
  notifyDirtyChange(oldDirty);
  return newDirtyEntity;
}