Program: 5837
Project: 5837
Buggy source:
/** 
 * Merge an object coming from the server in the context
 * @param obj external object
 * @param previous previously existing object in the context (null if no existing object)
 * @param expr current path from the context
 * @param parent parent object for collections
 * @param propertyName property name of the current object in the parent object
 * @param setter setter function to update the private property
 * @param forceUpdate force update of property (used for externalized properties)
 * @return merged object (should === previous when previous not null)
 */
@SuppressWarnings("String_Node_Str") public Object mergeExternal(final MergeContext mergeContext,Object obj,Object previous,Expression expr,Object parent,String propertyName,String setter,boolean forceUpdate){
  mergeContext.initMerge();
  boolean saveMergeUpdate=mergeContext.isMergeUpdate();
  boolean saveMerging=mergeContext.isMerging();
  try {
    mergeContext.setMerging(true);
    boolean addRef=false;
    boolean fromCache=false;
    Object prev=mergeContext.getFromCache(obj);
    Object next=obj;
    if (prev != null) {
      next=prev;
      fromCache=true;
    }
 else {
      dataManager.stopTracking(previous,parent);
      if (obj == null) {
        next=null;
      }
 else       if (((obj instanceof LazyableCollection && !((LazyableCollection)obj).isInitialized()) || (obj instanceof LazyableCollection && !(previous instanceof LazyableCollection))) && parent instanceof Identifiable && propertyName != null) {
        next=mergePersistentCollection(mergeContext,(LazyableCollection)obj,previous,null,(Identifiable)parent,propertyName);
        addRef=true;
      }
 else       if (obj instanceof List<?>) {
        next=mergeCollection(mergeContext,(List<Object>)obj,previous,parent == null ? expr : null,parent,propertyName);
        addRef=true;
      }
 else       if (obj instanceof Map<?,?>) {
        next=mergeMap(mergeContext,(Map<Object,Object>)obj,previous,parent == null ? expr : null,parent,propertyName);
        addRef=true;
      }
 else       if (obj instanceof Identifiable) {
        next=mergeEntity(mergeContext,obj,previous,expr,parent,propertyName);
        addRef=true;
      }
 else {
        boolean merged=false;
        if (customMergers != null) {
          for (          DataMerger merger : customMergers) {
            if (merger.accepts(obj)) {
              next=merger.merge(mergeContext,obj,previous,parent == null ? expr : null,parent,propertyName);
              dataManager.startTracking(previous,parent);
              merged=true;
              addRef=true;
            }
          }
        }
        if (!merged && !ObjectUtil.isSimple(obj) && !(obj instanceof Value || obj instanceof byte[])) {
          next=mergeEntity(mergeContext,obj,previous,expr,parent,propertyName);
          addRef=true;
        }
      }
    }
    if (next != null && !fromCache && addRef && (expr != null || (prev == null && parent != null))) {
      addReference(next,parent,propertyName,expr);
    }
    mergeContext.setMergeUpdate(saveMergeUpdate);
    if ((mergeContext.isMergeUpdate() || forceUpdate) && setter != null && parent != null && propertyName != null && parent instanceof Identifiable) {
      if (!mergeContext.isResolvingConflict() || !propertyName.equals(PersistenceManager.getEntityDescriptor(parent).getVersionPropertyName())) {
        dataManager.setProperty(parent,propertyName,previous,next);
      }
    }
    if (entityManagerPropagation != null && (mergeContext.isMergeUpdate() || forceUpdate) && !fromCache && obj instanceof Identifiable) {
      entityManagerPropagation.propagate((Identifiable)obj,new Function(){
        public void execute(        EntityManager entityManager,        Identifiable entity){
          if (entityManager == mergeContext.getSourceEntityManager())           return;
          if (entityManager.getCachedObject(entity,true) != null)           entityManager.mergeFromEntityManager(entityManager,entity,mergeContext.getExternalDataSessionId(),mergeContext.isUninitializing());
        }
      }
);
    }
    return next;
  }
 catch (  Exception e) {
    e.printStackTrace();
    return null;
  }
 finally {
    mergeContext.setMerging(saveMerging);
  }
}

Fixed version (ground truth):
/** 
 * Merge an object coming from the server in the context
 * @param obj external object
 * @param previous previously existing object in the context (null if no existing object)
 * @param expr current path from the context
 * @param parent parent object for collections
 * @param propertyName property name of the current object in the parent object
 * @param setter setter function to update the private property
 * @param forceUpdate force update of property (used for externalized properties)
 * @return merged object (should === previous when previous not null)
 */
@SuppressWarnings("String_Node_Str") public Object mergeExternal(final MergeContext mergeContext,Object obj,Object previous,Expression expr,Object parent,String propertyName,String setter,boolean forceUpdate){
  mergeContext.initMerge();
  boolean saveMergeUpdate=mergeContext.isMergeUpdate();
  boolean saveMerging=mergeContext.isMerging();
  try {
    mergeContext.setMerging(true);
    boolean addRef=false;
    boolean fromCache=false;
    Object prev=mergeContext.getFromCache(obj);
    Object next=obj;
    if (prev != null) {
      next=prev;
      fromCache=true;
    }
 else {
      dataManager.stopTracking(previous,parent);
      if (obj == null) {
        next=null;
      }
 else       if (((obj instanceof LazyableCollection && !((LazyableCollection)obj).isInitialized()) || (obj instanceof LazyableCollection && !(previous instanceof LazyableCollection))) && parent instanceof Identifiable && propertyName != null) {
        next=mergePersistentCollection(mergeContext,(LazyableCollection)obj,previous,null,(Identifiable)parent,propertyName);
        addRef=true;
      }
 else       if (obj instanceof List<?>) {
        next=mergeCollection(mergeContext,(List<Object>)obj,previous,parent == null ? expr : null,parent,propertyName);
        addRef=true;
      }
 else       if (obj instanceof Map<?,?>) {
        next=mergeMap(mergeContext,(Map<Object,Object>)obj,previous,parent == null ? expr : null,parent,propertyName);
        addRef=true;
      }
 else       if (obj instanceof Identifiable) {
        next=mergeEntity(mergeContext,obj,previous,expr,parent,propertyName);
        addRef=true;
      }
 else {
        boolean merged=false;
        if (customMergers != null) {
          for (          DataMerger merger : customMergers) {
            if (merger.accepts(obj)) {
              next=merger.merge(mergeContext,obj,previous,parent == null ? expr : null,parent,propertyName);
              dataManager.startTracking(previous,parent);
              merged=true;
              addRef=true;
            }
          }
        }
        if (!merged && !ObjectUtil.isSimple(obj) && !(obj instanceof Value || obj instanceof byte[])) {
          next=mergeEntity(mergeContext,obj,previous,expr,parent,propertyName);
          addRef=true;
        }
      }
    }
    if (next != null && !fromCache && addRef && (expr != null || (prev == null && parent != null))) {
      addReference(next,parent,propertyName,expr);
    }
    mergeContext.setMergeUpdate(saveMergeUpdate);
    if ((mergeContext.isMergeUpdate() || forceUpdate) && setter != null && parent != null && propertyName != null && parent instanceof Identifiable && next != previous) {
      if (!mergeContext.isResolvingConflict() || !propertyName.equals(PersistenceManager.getEntityDescriptor(parent).getVersionPropertyName())) {
        dataManager.setProperty(parent,propertyName,previous,next);
      }
    }
    if (entityManagerPropagation != null && (mergeContext.isMergeUpdate() || forceUpdate) && !fromCache && obj instanceof Identifiable) {
      entityManagerPropagation.propagate((Identifiable)obj,new Function(){
        public void execute(        EntityManager entityManager,        Identifiable entity){
          if (entityManager == mergeContext.getSourceEntityManager())           return;
          if (entityManager.getCachedObject(entity,true) != null)           entityManager.mergeFromEntityManager(entityManager,entity,mergeContext.getExternalDataSessionId(),mergeContext.isUninitializing());
        }
      }
);
    }
    return next;
  }
 catch (  Exception e) {
    log.error(e,"String_Node_Str");
    return null;
  }
 finally {
    mergeContext.setMerging(saveMerging);
  }
}