Program: 172206
Project: 172206
Buggy source:
/** 
 * Recursive copy algorithm
 * @param dropName      drop the name property when associations don't allow duplicately named children
 */
private NodeRef recursiveCopy(CopyDetails copyDetails,boolean copyChildren,boolean dropName,Map<NodeRef,NodeRef> copiesByOriginal,Set<NodeRef> copies,Map<QName,CopyBehaviourCallback> callbacks){
  NodeRef sourceNodeRef=copyDetails.getSourceNodeRef();
  Set<QName> sourceNodeAspectQNames=copyDetails.getSourceNodeAspectQNames();
  NodeRef targetParentNodeRef=copyDetails.getTargetParentNodeRef();
  QName assocTypeQName=copyDetails.getAssocTypeQName();
  QName assocQName=copyDetails.getAssocQName();
  if (copies.contains(sourceNodeRef)) {
    throw new IllegalStateException("String_Node_Str" + "String_Node_Str" + copyDetails + "String_Node_Str"+ "String_Node_Str"+ copiesByOriginal);
  }
 else   if (copiesByOriginal.containsKey(sourceNodeRef)) {
    throw new IllegalStateException("String_Node_Str" + "String_Node_Str" + copyDetails + "String_Node_Str"+ "String_Node_Str"+ copiesByOriginal);
  }
  QName sourceNodeTypeQName=copyDetails.getSourceNodeTypeQName();
  CopyBehaviourCallback sourceTypeBehaviour=callbacks.get(sourceNodeTypeQName);
  if (sourceTypeBehaviour == null) {
    throw new IllegalStateException("String_Node_Str" + sourceNodeTypeQName);
  }
  if (!sourceTypeBehaviour.getMustCopy(sourceNodeTypeQName,copyDetails)) {
    return null;
  }
  Map<QName,Serializable> targetNodeProperties=buildCopyProperties(copyDetails,Collections.singleton(sourceNodeTypeQName),callbacks);
  Set<QName> defaultAspectQNames=getDefaultAspects(sourceNodeTypeQName);
  Map<QName,Serializable> defaultAspectsProperties=buildCopyProperties(copyDetails,defaultAspectQNames,callbacks);
  targetNodeProperties.putAll(defaultAspectsProperties);
  AssociationDefinition assocDef=dictionaryService.getAssociation(assocTypeQName);
  if (!assocDef.isChild()) {
    throw new AlfrescoRuntimeException("String_Node_Str" + assocTypeQName);
  }
 else {
    ChildAssociationDefinition childAssocDef=(ChildAssociationDefinition)assocDef;
    if (dropName && !childAssocDef.getDuplicateChildNamesAllowed()) {
      targetNodeProperties.remove(ContentModel.PROP_NAME);
    }
  }
  String targetNodeUuid=copyDetails.getTargetNodeRef().getId();
  targetNodeProperties.put(ContentModel.PROP_NODE_UUID,targetNodeUuid);
  ChildAssociationRef targetChildAssocRef=this.nodeService.createNode(targetParentNodeRef,assocTypeQName,assocQName,sourceNodeTypeQName,targetNodeProperties);
  NodeRef targetNodeRef=targetChildAssocRef.getChildRef();
  copiesByOriginal.put(sourceNodeRef,targetNodeRef);
  copies.add(targetNodeRef);
  Set<QName> remainingAspectQNames=new HashSet<QName>(sourceNodeAspectQNames);
  remainingAspectQNames.removeAll(defaultAspectQNames);
  this.ruleService.disableRules(targetNodeRef);
  try {
    for (    QName remainingAspectQName : remainingAspectQNames) {
      copyProperties(copyDetails,targetNodeRef,remainingAspectQName,callbacks);
    }
    copyResidualProperties(copyDetails,targetNodeRef);
    Map<QName,Serializable> copyProperties=new HashMap<QName,Serializable>();
    copyProperties.put(ContentModel.PROP_COPY_REFERENCE,sourceNodeRef);
    internalNodeService.addAspect(targetNodeRef,ContentModel.ASPECT_COPIEDFROM,copyProperties);
    copyChildren(copyDetails,targetNodeRef,true,copyChildren,copiesByOriginal,copies,callbacks);
  }
  finally {
    this.ruleService.enableRules(targetNodeRef);
  }
  return targetNodeRef;
}

Fixed version (ground truth):
/** 
 * Recursive copy algorithm
 * @param dropName      drop the name property when associations don't allow duplicately named children
 */
private NodeRef recursiveCopy(CopyDetails copyDetails,boolean copyChildren,boolean dropName,Map<NodeRef,NodeRef> copiesByOriginal,Set<NodeRef> copies,Map<QName,CopyBehaviourCallback> callbacks){
  NodeRef sourceNodeRef=copyDetails.getSourceNodeRef();
  Set<QName> sourceNodeAspectQNames=copyDetails.getSourceNodeAspectQNames();
  NodeRef targetParentNodeRef=copyDetails.getTargetParentNodeRef();
  QName assocTypeQName=copyDetails.getAssocTypeQName();
  QName assocQName=copyDetails.getAssocQName();
  if (copies.contains(sourceNodeRef)) {
    throw new IllegalStateException("String_Node_Str" + "String_Node_Str" + copyDetails + "String_Node_Str"+ "String_Node_Str"+ copiesByOriginal);
  }
 else   if (copiesByOriginal.containsKey(sourceNodeRef)) {
    throw new IllegalStateException("String_Node_Str" + "String_Node_Str" + copyDetails + "String_Node_Str"+ "String_Node_Str"+ copiesByOriginal);
  }
  QName sourceNodeTypeQName=copyDetails.getSourceNodeTypeQName();
  CopyBehaviourCallback sourceTypeBehaviour=callbacks.get(sourceNodeTypeQName);
  if (sourceTypeBehaviour == null) {
    throw new IllegalStateException("String_Node_Str" + sourceNodeTypeQName);
  }
  if (!sourceTypeBehaviour.getMustCopy(sourceNodeTypeQName,copyDetails)) {
    return null;
  }
  Map<QName,Serializable> targetNodeProperties=buildCopyProperties(copyDetails,Collections.singleton(sourceNodeTypeQName),callbacks);
  Set<QName> defaultAspectQNames=getDefaultAspects(sourceNodeTypeQName);
  Map<QName,Serializable> defaultAspectsProperties=buildCopyProperties(copyDetails,defaultAspectQNames,callbacks);
  targetNodeProperties.putAll(defaultAspectsProperties);
  AssociationDefinition assocDef=dictionaryService.getAssociation(assocTypeQName);
  if (!assocDef.isChild()) {
    throw new AlfrescoRuntimeException("String_Node_Str" + assocTypeQName);
  }
 else {
    ChildAssociationDefinition childAssocDef=(ChildAssociationDefinition)assocDef;
    if (dropName && !childAssocDef.getDuplicateChildNamesAllowed()) {
      targetNodeProperties.remove(ContentModel.PROP_NAME);
    }
  }
  String targetNodeUuid=copyDetails.getTargetNodeRef().getId();
  targetNodeProperties.put(ContentModel.PROP_NODE_UUID,targetNodeUuid);
  ChildAssociationRef targetChildAssocRef=this.nodeService.createNode(targetParentNodeRef,assocTypeQName,assocQName,sourceNodeTypeQName,targetNodeProperties);
  NodeRef targetNodeRef=targetChildAssocRef.getChildRef();
  copiesByOriginal.put(sourceNodeRef,targetNodeRef);
  copies.add(targetNodeRef);
  invokeBeforeCopy(sourceNodeRef,targetNodeRef);
  Set<QName> remainingAspectQNames=new HashSet<QName>(sourceNodeAspectQNames);
  remainingAspectQNames.removeAll(defaultAspectQNames);
  this.ruleService.disableRules(targetNodeRef);
  try {
    for (    QName remainingAspectQName : remainingAspectQNames) {
      copyProperties(copyDetails,targetNodeRef,remainingAspectQName,callbacks);
    }
    copyResidualProperties(copyDetails,targetNodeRef);
    Map<QName,Serializable> copyProperties=new HashMap<QName,Serializable>();
    copyProperties.put(ContentModel.PROP_COPY_REFERENCE,sourceNodeRef);
    internalNodeService.addAspect(targetNodeRef,ContentModel.ASPECT_COPIEDFROM,copyProperties);
    copyChildren(copyDetails,targetNodeRef,true,copyChildren,copiesByOriginal,copies,callbacks);
  }
  finally {
    this.ruleService.enableRules(targetNodeRef);
  }
  return targetNodeRef;
}