Program: 176330
Project: 176330
Buggy source:
/** 
 * @param source
 * @param mainCache TODO
 * @return
 */
private static Object deepCopyUsingMetadata(Object source,Map<Object,Object> copiedObjectMap){
  Object target=null;
  try {
    if (source == null)     return null;
    Class<?> sourceObjectClass=source.getClass();
    EntityMetadata metadata=KunderaMetadataManager.getEntityMetadata(sourceObjectClass);
    if (metadata == null) {
      return source;
    }
    MetamodelImpl metaModel=(MetamodelImpl)KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel(metadata.getPersistenceUnit());
    EntityType entityType=metaModel.entity(sourceObjectClass);
    Object id=null;
    if (metadata.getRelations() != null && !metadata.getRelations().isEmpty()) {
      id=PropertyAccessorHelper.getId(source,metadata);
      StringBuilder keyBuilder=new StringBuilder(sourceObjectClass.getName());
      keyBuilder.append("String_Node_Str");
      keyBuilder.append(id);
      Object copiedObjectInMap=copiedObjectMap.get(keyBuilder.toString());
      if (copiedObjectInMap != null) {
        return copiedObjectInMap;
      }
    }
    target=sourceObjectClass.newInstance();
    Iterator<Attribute> iter=entityType.getAttributes().iterator();
    while (iter.hasNext()) {
      Attribute attrib=iter.next();
      Field columnField=(Field)attrib.getJavaMember();
      if (attrib.getPersistentAttributeType().equals(PersistentAttributeType.EMBEDDED) || attrib.getPersistentAttributeType().equals(PersistentAttributeType.ELEMENT_COLLECTION)) {
        EmbeddableType embeddedColumn=metaModel.embeddable(((AbstractAttribute)attrib).getBindableJavaType());
        Object sourceEmbeddedObj=PropertyAccessorHelper.getObject(source,columnField);
        if (sourceEmbeddedObj != null) {
          if (columnField.getAnnotation(Embedded.class) != null) {
            Class<?> embeddedColumnClass=columnField.getType();
            Object targetEmbeddedObj=embeddedColumnClass.newInstance();
            Set<Attribute> columns=embeddedColumn.getAttributes();
            for (            Attribute column : columns) {
              PropertyAccessorHelper.set(targetEmbeddedObj,(Field)column.getJavaMember(),PropertyAccessorHelper.getObjectCopy(sourceEmbeddedObj,(Field)column.getJavaMember()));
            }
            PropertyAccessorHelper.set(target,columnField,targetEmbeddedObj);
          }
 else           if (columnField.getAnnotation(ElementCollection.class) != null) {
            Class<?> ecDeclaredClass=columnField.getType();
            Class<?> actualEcObjectClass=sourceEmbeddedObj.getClass();
            Object targetCollectionObject;
            targetCollectionObject=actualEcObjectClass.newInstance();
            if (sourceEmbeddedObj instanceof Collection) {
              Class<?> genericClass=PropertyAccessorHelper.getGenericClass(columnField);
              for (              Object sourceEcObj : (Collection)sourceEmbeddedObj) {
                Object targetEcObj=null;
                if (PersistenceType.BASIC.equals(embeddedColumn.getPersistenceType())) {
                  PropertyAccessor accessor=PropertyAccessorFactory.getPropertyAccessor(sourceEcObj.getClass());
                  if (accessor != null) {
                    targetEcObj=accessor.getCopy(sourceEcObj);
                  }
                }
 else                 if (PersistenceType.EMBEDDABLE.equals(embeddedColumn.getPersistenceType())) {
                  targetEcObj=genericClass.newInstance();
                  for (                  Field f : genericClass.getDeclaredFields()) {
                    if (f != null && !Modifier.isStatic(f.getModifiers())) {
                      PropertyAccessorHelper.set(targetEcObj,f,PropertyAccessorHelper.getObjectCopy(sourceEcObj,f));
                    }
                  }
                }
                if (List.class.isAssignableFrom(ecDeclaredClass)) {
                  Method m=actualEcObjectClass.getMethod("String_Node_Str",Object.class);
                  m.invoke(targetCollectionObject,targetEcObj);
                }
 else                 if (Set.class.isAssignableFrom(ecDeclaredClass)) {
                  Method m=actualEcObjectClass.getMethod("String_Node_Str",Object.class);
                  m.invoke(targetCollectionObject,targetEcObj);
                }
              }
            }
 else             if (sourceEmbeddedObj instanceof Map) {
              for (              Object sourceKey : ((Map)sourceEmbeddedObj).keySet()) {
                Object targetKey=null;
                Object targetValue=null;
                if (PersistenceType.BASIC.equals(embeddedColumn.getPersistenceType())) {
                  PropertyAccessor keyAccessor=PropertyAccessorFactory.getPropertyAccessor(sourceKey.getClass());
                  if (keyAccessor != null) {
                    targetKey=keyAccessor.getCopy(sourceKey);
                  }
                  Object sourceValue=((Map)sourceEmbeddedObj).get(sourceKey);
                  PropertyAccessor valueAccessor=PropertyAccessorFactory.getPropertyAccessor(sourceValue.getClass());
                  if (valueAccessor != null) {
                    targetValue=valueAccessor.getCopy(sourceValue);
                  }
                  if (Map.class.isAssignableFrom(ecDeclaredClass)) {
                    Method m=actualEcObjectClass.getMethod("String_Node_Str",new Class[]{Object.class,Object.class});
                    m.invoke(targetCollectionObject,new Object[]{targetKey,targetValue});
                  }
                }
              }
            }
            PropertyAccessorHelper.set(target,columnField,targetCollectionObject);
          }
 else           if (columnField.getAnnotation(javax.persistence.Column.class) != null) {
            PropertyAccessorHelper.set(target,columnField,sourceEmbeddedObj);
          }
        }
      }
 else       if (attrib.getPersistentAttributeType().equals(PersistentAttributeType.BASIC)) {
        PropertyAccessorHelper.set(target,columnField,PropertyAccessorHelper.getObjectCopy(source,columnField));
      }
    }
    if (id != null) {
      StringBuilder keyBuilder=new StringBuilder(sourceObjectClass.getName());
      keyBuilder.append("String_Node_Str");
      keyBuilder.append(id);
      copiedObjectMap.put(keyBuilder.toString(),target);
    }
    for (    Relation relation : metadata.getRelations()) {
      Field relationField=relation.getProperty();
      Object sourceRelationObject=PropertyAccessorHelper.getObject(source,relationField);
      if (sourceRelationObject != null) {
        if (sourceRelationObject instanceof KunderaProxy) {
          PropertyAccessorHelper.set(target,relationField,sourceRelationObject);
          continue;
        }
 else         if (ProxyHelper.isPersistentCollection(sourceRelationObject)) {
          PropertyAccessorHelper.set(target,relationField,sourceRelationObject);
          continue;
        }
 else         if (ProxyHelper.isKunderaProxyCollection(sourceRelationObject)) {
          ProxyCollection pc=((ProxyCollection)sourceRelationObject).getCopy();
          pc.setOwner(target);
          PropertyAccessorHelper.set(target,relationField,pc);
          continue;
        }
        Object targetRelationObject=null;
        Class<?> relationObjectClass=relation.getProperty().getType();
        Class<?> actualRelationObjectClass=sourceRelationObject.getClass();
        if (Collection.class.isAssignableFrom(relationObjectClass)) {
          targetRelationObject=actualRelationObjectClass.newInstance();
          Method m=actualRelationObjectClass.getMethod("String_Node_Str",Object.class);
          for (          Object obj : (Collection)sourceRelationObject) {
            Object copyTargetRelObj=searchInCacheThenCopy(copiedObjectMap,obj);
            m.invoke(targetRelationObject,copyTargetRelObj);
          }
        }
 else         if (Map.class.isAssignableFrom(relationObjectClass)) {
          targetRelationObject=actualRelationObjectClass.newInstance();
          Method m=actualRelationObjectClass.getMethod("String_Node_Str",new Class<?>[]{Object.class,Object.class});
          for (          Object keyObj : ((Map)sourceRelationObject).keySet()) {
            Object valObj=((Map)sourceRelationObject).get(keyObj);
            Object copyTargetKeyObj=searchInCacheThenCopy(copiedObjectMap,keyObj);
            Object copyTargetValueObj=searchInCacheThenCopy(copiedObjectMap,valObj);
            m.invoke(targetRelationObject,new Object[]{copyTargetKeyObj,copyTargetValueObj});
          }
        }
 else {
          targetRelationObject=searchInCacheThenCopy(copiedObjectMap,sourceRelationObject);
        }
        PropertyAccessorHelper.set(target,relationField,targetRelationObject);
      }
    }
  }
 catch (  InstantiationException e) {
    log.warn("String_Node_Str" + e.getMessage());
    return null;
  }
catch (  IllegalAccessException e) {
    log.warn("String_Node_Str" + e.getMessage());
    return null;
  }
catch (  InvocationTargetException e) {
    log.warn("String_Node_Str" + e.getMessage());
    return null;
  }
catch (  NoSuchMethodException e) {
    log.warn("String_Node_Str" + e.getMessage());
    return null;
  }
  return target;
}

Fixed version (ground truth):
/** 
 * @param source
 * @param mainCache TODO
 * @return
 */
private static Object deepCopyUsingMetadata(Object source,Map<Object,Object> copiedObjectMap){
  Object target=null;
  try {
    if (source == null)     return null;
    Class<?> sourceObjectClass=source.getClass();
    EntityMetadata metadata=KunderaMetadataManager.getEntityMetadata(sourceObjectClass);
    if (metadata == null) {
      return source;
    }
    MetamodelImpl metaModel=(MetamodelImpl)KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel(metadata.getPersistenceUnit());
    EntityType entityType=metaModel.entity(sourceObjectClass);
    Object id=null;
    if (metadata.getRelations() != null && !metadata.getRelations().isEmpty()) {
      id=PropertyAccessorHelper.getId(source,metadata);
      StringBuilder keyBuilder=new StringBuilder(sourceObjectClass.getName());
      keyBuilder.append("String_Node_Str");
      keyBuilder.append(id);
      Object copiedObjectInMap=copiedObjectMap.get(keyBuilder.toString());
      if (copiedObjectInMap != null) {
        return copiedObjectInMap;
      }
    }
    target=sourceObjectClass.newInstance();
    Iterator<Attribute> iter=entityType.getAttributes().iterator();
    while (iter.hasNext()) {
      Attribute attrib=iter.next();
      Field columnField=(Field)attrib.getJavaMember();
      if (attrib.getPersistentAttributeType().equals(PersistentAttributeType.EMBEDDED) || attrib.getPersistentAttributeType().equals(PersistentAttributeType.ELEMENT_COLLECTION)) {
        EmbeddableType embeddedColumn=metaModel.embeddable(((AbstractAttribute)attrib).getBindableJavaType());
        Object sourceEmbeddedObj=PropertyAccessorHelper.getObject(source,columnField);
        if (sourceEmbeddedObj != null) {
          if (columnField.getAnnotation(Embedded.class) != null) {
            Class<?> embeddedColumnClass=columnField.getType();
            Object targetEmbeddedObj=embeddedColumnClass.newInstance();
            Set<Attribute> columns=embeddedColumn.getAttributes();
            for (            Attribute column : columns) {
              PropertyAccessorHelper.set(targetEmbeddedObj,(Field)column.getJavaMember(),PropertyAccessorHelper.getObjectCopy(sourceEmbeddedObj,(Field)column.getJavaMember()));
            }
            PropertyAccessorHelper.set(target,columnField,targetEmbeddedObj);
          }
 else           if (columnField.getAnnotation(ElementCollection.class) != null) {
            Class<?> ecDeclaredClass=columnField.getType();
            Class<?> actualEcObjectClass=sourceEmbeddedObj.getClass();
            Object targetCollectionObject;
            targetCollectionObject=actualEcObjectClass.newInstance();
            if (sourceEmbeddedObj instanceof Collection) {
              Class<?> genericClass=PropertyAccessorHelper.getGenericClass(columnField);
              for (              Object sourceEcObj : (Collection)sourceEmbeddedObj) {
                Object targetEcObj=null;
                if (PersistenceType.BASIC.equals(embeddedColumn.getPersistenceType())) {
                  PropertyAccessor accessor=PropertyAccessorFactory.getPropertyAccessor(sourceEcObj.getClass());
                  if (accessor != null) {
                    targetEcObj=accessor.getCopy(sourceEcObj);
                  }
                }
 else                 if (PersistenceType.EMBEDDABLE.equals(embeddedColumn.getPersistenceType())) {
                  targetEcObj=genericClass.newInstance();
                  for (                  Field f : genericClass.getDeclaredFields()) {
                    if (f != null && !Modifier.isStatic(f.getModifiers())) {
                      PropertyAccessorHelper.set(targetEcObj,f,PropertyAccessorHelper.getObjectCopy(sourceEcObj,f));
                    }
                  }
                }
                if (List.class.isAssignableFrom(ecDeclaredClass)) {
                  Method m=actualEcObjectClass.getMethod("String_Node_Str",Object.class);
                  m.invoke(targetCollectionObject,targetEcObj);
                }
 else                 if (Set.class.isAssignableFrom(ecDeclaredClass)) {
                  Method m=actualEcObjectClass.getMethod("String_Node_Str",Object.class);
                  m.invoke(targetCollectionObject,targetEcObj);
                }
              }
            }
 else             if (sourceEmbeddedObj instanceof Map) {
              for (              Object sourceKey : ((Map)sourceEmbeddedObj).keySet()) {
                Object targetKey=null;
                Object targetValue=null;
                if (PersistenceType.BASIC.equals(embeddedColumn.getPersistenceType())) {
                  PropertyAccessor keyAccessor=PropertyAccessorFactory.getPropertyAccessor(sourceKey.getClass());
                  if (keyAccessor != null) {
                    targetKey=keyAccessor.getCopy(sourceKey);
                  }
                  Object sourceValue=((Map)sourceEmbeddedObj).get(sourceKey);
                  PropertyAccessor valueAccessor=PropertyAccessorFactory.getPropertyAccessor(sourceValue.getClass());
                  if (valueAccessor != null) {
                    targetValue=valueAccessor.getCopy(sourceValue);
                  }
                  if (Map.class.isAssignableFrom(ecDeclaredClass)) {
                    Method m=actualEcObjectClass.getMethod("String_Node_Str",new Class[]{Object.class,Object.class});
                    m.invoke(targetCollectionObject,new Object[]{targetKey,targetValue});
                  }
                }
              }
            }
            PropertyAccessorHelper.set(target,columnField,targetCollectionObject);
          }
 else           if (columnField.getAnnotation(javax.persistence.Column.class) != null) {
            PropertyAccessorHelper.set(target,columnField,sourceEmbeddedObj);
          }
        }
      }
 else       if (attrib.getPersistentAttributeType().equals(PersistentAttributeType.BASIC)) {
        PropertyAccessorHelper.set(target,columnField,PropertyAccessorHelper.getObjectCopy(source,columnField));
      }
    }
    if (id != null) {
      StringBuilder keyBuilder=new StringBuilder(sourceObjectClass.getName());
      keyBuilder.append("String_Node_Str");
      keyBuilder.append(id);
      copiedObjectMap.put(keyBuilder.toString(),target);
    }
    for (    Relation relation : metadata.getRelations()) {
      Field relationField=relation.getProperty();
      Object sourceRelationObject=PropertyAccessorHelper.getObject(source,relationField);
      if (sourceRelationObject != null) {
        if (sourceRelationObject instanceof KunderaProxy) {
          PropertyAccessorHelper.set(target,relationField,sourceRelationObject);
          continue;
        }
 else         if (ProxyHelper.isPersistentCollection(sourceRelationObject)) {
          PropertyAccessorHelper.set(target,relationField,sourceRelationObject);
          continue;
        }
 else         if (ProxyHelper.isKunderaProxyCollection(sourceRelationObject)) {
          ProxyCollection pc=((ProxyCollection)sourceRelationObject).getCopy();
          pc.setOwner(target);
          PropertyAccessorHelper.set(target,relationField,pc);
          continue;
        }
        Object targetRelationObject=null;
        Class<?> relationObjectClass=relation.getProperty().getType();
        Class<?> actualRelationObjectClass=sourceRelationObject.getClass();
        if (Collection.class.isAssignableFrom(relationObjectClass)) {
          targetRelationObject=actualRelationObjectClass.newInstance();
          Method m=actualRelationObjectClass.getMethod("String_Node_Str",Object.class);
          for (          Object obj : (Collection)sourceRelationObject) {
            Object copyTargetRelObj=searchInCacheThenCopy(copiedObjectMap,obj);
            m.invoke(targetRelationObject,copyTargetRelObj);
          }
        }
 else         if (Map.class.isAssignableFrom(relationObjectClass)) {
          targetRelationObject=actualRelationObjectClass.newInstance();
          Method m=actualRelationObjectClass.getMethod("String_Node_Str",new Class<?>[]{Object.class,Object.class});
          for (          Object keyObj : ((Map)sourceRelationObject).keySet()) {
            Object valObj=((Map)sourceRelationObject).get(keyObj);
            Object copyTargetKeyObj=searchInCacheThenCopy(copiedObjectMap,keyObj);
            Object copyTargetValueObj=searchInCacheThenCopy(copiedObjectMap,valObj);
            m.invoke(targetRelationObject,new Object[]{copyTargetKeyObj,copyTargetValueObj});
          }
        }
 else {
          targetRelationObject=searchInCacheThenCopy(copiedObjectMap,sourceRelationObject);
        }
        PropertyAccessorHelper.set(target,relationField,targetRelationObject);
      }
    }
  }
 catch (  InstantiationException e) {
    log.warn("String_Node_Str" + e.getMessage());
    return null;
  }
catch (  Exception e) {
    log.warn("String_Node_Str" + e.getMessage());
    return null;
  }
  return target;
}