Program: 176687
Project: 176687
Buggy source:
/** 
 * @param source
 * @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) {
            if (sourceEmbeddedObj instanceof Collection) {
              Class<?> ecDeclaredClass=columnField.getType();
              Class<?> actualEcObjectClass=sourceEmbeddedObj.getClass();
              Class<?> genericClass=PropertyAccessorHelper.getGenericClass(columnField);
              Object targetCollectionObject=actualEcObjectClass.newInstance();
              for (              Object sourceEcObj : (Collection)sourceEmbeddedObj) {
                Object targetEcObj=genericClass.newInstance();
                for (                Field f : genericClass.getDeclaredFields()) {
                  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);
                }
              }
              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 && !(sourceRelationObject instanceof AbstractPersistentCollection)) {
        if (sourceRelationObject instanceof KunderaProxy) {
          PropertyAccessorHelper.set(target,relationField,sourceRelationObject);
          continue;
        }
        Object targetRelationObject=null;
        Class<?> relationObjectClass=relation.getProperty().getType();
        Class<?> actualRelationObjectClass=sourceRelationObject.getClass();
        if (!Collection.class.isAssignableFrom(relationObjectClass)) {
          targetRelationObject=deepCopyUsingMetadata(sourceRelationObject,copiedObjectMap);
        }
 else {
          targetRelationObject=actualRelationObjectClass.newInstance();
          Method m=actualRelationObjectClass.getMethod("String_Node_Str",Object.class);
          for (          Object obj : (Collection)sourceRelationObject) {
            Object copyTargetRelObj=deepCopyUsingMetadata(obj,copiedObjectMap);
            m.invoke(targetRelationObject,copyTargetRelObj);
          }
        }
        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
 * @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) {
            if (sourceEmbeddedObj instanceof Collection) {
              Class<?> ecDeclaredClass=columnField.getType();
              Class<?> actualEcObjectClass=sourceEmbeddedObj.getClass();
              Class<?> genericClass=PropertyAccessorHelper.getGenericClass(columnField);
              Object targetCollectionObject=actualEcObjectClass.newInstance();
              for (              Object sourceEcObj : (Collection)sourceEmbeddedObj) {
                Object targetEcObj=genericClass.newInstance();
                for (                Field f : genericClass.getDeclaredFields()) {
                  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);
                }
              }
              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 && !(sourceRelationObject instanceof AbstractPersistentCollection)) {
        if (sourceRelationObject instanceof KunderaProxy) {
          PropertyAccessorHelper.set(target,relationField,sourceRelationObject);
          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=deepCopyUsingMetadata(obj,copiedObjectMap);
            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=deepCopyUsingMetadata(keyObj,copiedObjectMap);
            Object copyTargetValueObj=deepCopyUsingMetadata(valObj,copiedObjectMap);
            m.invoke(targetRelationObject,new Object[]{copyTargetKeyObj,copyTargetValueObj});
          }
        }
 else {
          targetRelationObject=deepCopyUsingMetadata(sourceRelationObject,copiedObjectMap);
        }
        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;
}