Program: 172304
Project: 172304
Buggy source:
/** 
 * Recursive copy algorithm
 * @param sourceNodeRef
 * @param destinationParent
 * @param destinationAssocTypeQName
 * @param destinationQName
 * @param copyChildren
 * @param copiedChildren
 * @return
 */
private NodeRef recursiveCopy(NodeRef sourceNodeRef,NodeRef destinationParent,QName destinationAssocTypeQName,QName destinationQName,boolean copyChildren,Map<NodeRef,NodeRef> copiedChildren){
  QName sourceTypeRef=this.nodeService.getType(sourceNodeRef);
  TypeDefinition typeDef=dictionaryService.getType(sourceTypeRef);
  if (typeDef == null) {
    throw new InvalidTypeException(sourceTypeRef);
  }
  PolicyScope copyDetails=getCopyDetails(sourceNodeRef,destinationParent.getStoreRef(),true);
  Map<QName,Serializable> typeProps=copyDetails.getProperties();
  Map<QName,Serializable> properties=new HashMap<QName,Serializable>();
  if (typeProps != null) {
    properties.putAll(typeProps);
  }
  for (  AspectDefinition aspectDef : typeDef.getDefaultAspects()) {
    Map<QName,Serializable> aspectProps=copyDetails.getProperties(aspectDef.getName());
    if (aspectProps != null) {
      properties.putAll(aspectProps);
    }
  }
  AssociationDefinition assocDef=dictionaryService.getAssociation(destinationAssocTypeQName);
  if (!assocDef.isChild()) {
    throw new AlfrescoRuntimeException("String_Node_Str" + destinationAssocTypeQName);
  }
 else {
    ChildAssociationDefinition childAssocDef=(ChildAssociationDefinition)assocDef;
    if (!childAssocDef.getDuplicateChildNamesAllowed()) {
      properties.remove(ContentModel.PROP_NAME);
    }
  }
  ChildAssociationRef destinationChildAssocRef=this.nodeService.createNode(destinationParent,destinationAssocTypeQName,destinationQName,sourceTypeRef,properties);
  NodeRef destinationNodeRef=destinationChildAssocRef.getChildRef();
  copiedChildren.put(sourceNodeRef,destinationNodeRef);
  this.ruleService.disableRules(destinationNodeRef);
  try {
    Map<QName,Serializable> copyProperties=new HashMap<QName,Serializable>();
    copyProperties.put(ContentModel.PROP_COPY_REFERENCE,sourceNodeRef);
    this.nodeService.addAspect(destinationNodeRef,ContentModel.ASPECT_COPIEDFROM,copyProperties);
    copyAspects(destinationNodeRef,copyDetails);
    copyAssociations(destinationNodeRef,copyDetails,copyChildren,copiedChildren);
    copyPermissions(sourceNodeRef,destinationNodeRef);
  }
  finally {
    this.ruleService.enableRules(destinationNodeRef);
  }
  return destinationNodeRef;
}

Fixed version (ground truth):
/** 
 * Recursive copy algorithm
 * @param dropName      drop the name property when associations don't allow duplicately named children
 */
private NodeRef recursiveCopy(NodeRef sourceNodeRef,NodeRef sourceParentRef,NodeRef destinationParentRef,QName destinationAssocTypeQName,QName destinationQName,boolean copyChildren,boolean dropName,Map<NodeRef,NodeRef> copiedChildren){
  QName sourceTypeRef=this.nodeService.getType(sourceNodeRef);
  TypeDefinition typeDef=dictionaryService.getType(sourceTypeRef);
  if (typeDef == null) {
    throw new InvalidTypeException(sourceTypeRef);
  }
  PolicyScope copyDetails=getCopyDetails(sourceNodeRef,destinationParentRef.getStoreRef(),true);
  Map<QName,Serializable> typeProps=copyDetails.getProperties();
  Map<QName,Serializable> properties=new HashMap<QName,Serializable>();
  if (typeProps != null) {
    properties.putAll(typeProps);
  }
  for (  AspectDefinition aspectDef : typeDef.getDefaultAspects()) {
    Map<QName,Serializable> aspectProps=copyDetails.getProperties(aspectDef.getName());
    if (aspectProps != null) {
      properties.putAll(aspectProps);
    }
  }
  AssociationDefinition assocDef=dictionaryService.getAssociation(destinationAssocTypeQName);
  if (!assocDef.isChild()) {
    throw new AlfrescoRuntimeException("String_Node_Str" + destinationAssocTypeQName);
  }
 else {
    ChildAssociationDefinition childAssocDef=(ChildAssociationDefinition)assocDef;
    if (dropName && !childAssocDef.getDuplicateChildNamesAllowed()) {
      properties.remove(ContentModel.PROP_NAME);
    }
  }
  ChildAssociationRef destinationChildAssocRef=this.nodeService.createNode(destinationParentRef,destinationAssocTypeQName,destinationQName,sourceTypeRef,properties);
  NodeRef destinationNodeRef=destinationChildAssocRef.getChildRef();
  copiedChildren.put(sourceNodeRef,destinationNodeRef);
  this.ruleService.disableRules(destinationNodeRef);
  try {
    Map<QName,Serializable> copyProperties=new HashMap<QName,Serializable>();
    copyProperties.put(ContentModel.PROP_COPY_REFERENCE,sourceNodeRef);
    this.nodeService.addAspect(destinationNodeRef,ContentModel.ASPECT_COPIEDFROM,copyProperties);
    copyAspects(destinationNodeRef,copyDetails);
    copyAssociations(destinationNodeRef,copyDetails,copyChildren,copiedChildren);
    copyPermissions(sourceNodeRef,destinationNodeRef);
  }
  finally {
    this.ruleService.enableRules(destinationNodeRef);
  }
  return destinationNodeRef;
}