Program: 49259
Project: 49259
Buggy source:
/** 
 * Updates the specified product instance, creating a new version of the product as necessary. The product instance returned by this method is not guaranteed to be the same instance passed in. As such, once this method has been called, callers should only use the instance output by this method.
 * @param entity The product entity to update
 * @param update The product updates to apply
 * @param owner The owner for which to update the product
 * @param regenerateEntitlementCerts Whether or not changes made to the product should trigger the regeneration of entitlement certificates for affected consumers
 * @throws IllegalStateException if this method is called with an entity does not exist in the backing database for the given owner
 * @throws IllegalArgumentException if entity, update or owner is null
 * @return the updated product entity, or a new product entity
 */
@Transactional public Product updateProduct(Product entity,ProductData update,Owner owner,boolean regenerateEntitlementCerts){
  if (entity == null) {
    throw new IllegalArgumentException("String_Node_Str");
  }
  if (update == null) {
    throw new IllegalArgumentException("String_Node_Str");
  }
  if (owner == null) {
    throw new IllegalArgumentException("String_Node_Str");
  }
  log.debug("String_Node_Str",update,entity,owner);
  entity=this.ownerProductCurator.getProductById(owner,entity.getId());
  if (entity == null) {
    throw new IllegalStateException("String_Node_Str");
  }
  Product updated=this.applyProductChanges((Product)entity.clone(),update,owner);
  List<Product> alternateVersions=this.productCurator.getProductsByVersion(update.getId(),updated.hashCode()).list();
  log.debug("String_Node_Str",alternateVersions.size());
  for (  Product alt : alternateVersions) {
    if (alt.equals(updated)) {
      log.debug("String_Node_Str",updated,alt);
      List<Owner> owners=Arrays.asList(owner);
      updated=this.ownerProductCurator.updateOwnerProductReferences(updated,alt,owners);
      if (regenerateEntitlementCerts) {
        this.entitlementCertGenerator.regenerateCertificatesOf(owners,Arrays.asList(updated),true);
      }
      return updated;
    }
  }
  if (this.ownerProductCurator.getOwnerCount(updated) == 1) {
    log.debug("String_Node_Str",updated);
    updated=this.productCurator.merge(updated);
    if (regenerateEntitlementCerts) {
      this.entitlementCertGenerator.regenerateCertificatesOf(Arrays.asList(updated),true);
    }
    return updated;
  }
  log.debug("String_Node_Str",updated);
  List<Owner> owners=Arrays.asList(owner);
  updated.setUuid(null);
  updated=this.productCurator.create(updated);
  updated=this.ownerProductCurator.updateOwnerProductReferences(entity,updated,owners);
  if (regenerateEntitlementCerts) {
    this.entitlementCertGenerator.regenerateCertificatesOf(owners,Arrays.asList(updated),true);
  }
  return updated;
}

Fixed version (ground truth):
/** 
 * Updates the specified product instance, creating a new version of the product as necessary. The product instance returned by this method is not guaranteed to be the same instance passed in. As such, once this method has been called, callers should only use the instance output by this method.
 * @param entity The product entity to update
 * @param update The product updates to apply
 * @param owner The owner for which to update the product
 * @param regenerateEntitlementCerts Whether or not changes made to the product should trigger the regeneration of entitlement certificates for affected consumers
 * @throws IllegalStateException if this method is called with an entity does not exist in the backing database for the given owner
 * @throws IllegalArgumentException if entity, update or owner is null
 * @return the updated product entity, or a new product entity
 */
@Transactional public Product updateProduct(Product entity,ProductData update,Owner owner,boolean regenerateEntitlementCerts){
  if (entity == null) {
    throw new IllegalArgumentException("String_Node_Str");
  }
  if (update == null) {
    throw new IllegalArgumentException("String_Node_Str");
  }
  if (owner == null) {
    throw new IllegalArgumentException("String_Node_Str");
  }
  log.debug("String_Node_Str",update,entity,owner);
  entity=this.ownerProductCurator.getProductById(owner,entity.getId());
  if (entity == null) {
    throw new IllegalStateException("String_Node_Str");
  }
  if (!entity.isChangedBy(update)) {
    return entity;
  }
  Product updated=this.applyProductChanges((Product)entity.clone(),update,owner);
  List<Product> alternateVersions=this.productCurator.getProductsByVersion(update.getId(),updated.hashCode()).list();
  log.debug("String_Node_Str",alternateVersions.size());
  for (  Product alt : alternateVersions) {
    if (alt.equals(updated)) {
      log.debug("String_Node_Str",updated,alt);
      List<Owner> owners=Arrays.asList(owner);
      updated=this.ownerProductCurator.updateOwnerProductReferences(updated,alt,owners);
      if (regenerateEntitlementCerts) {
        this.entitlementCertGenerator.regenerateCertificatesOf(owners,Arrays.asList(updated),true);
      }
      return updated;
    }
  }
  if (this.ownerProductCurator.getOwnerCount(updated) == 1) {
    log.debug("String_Node_Str",updated);
    updated=this.productCurator.merge(updated);
    if (regenerateEntitlementCerts) {
      this.entitlementCertGenerator.regenerateCertificatesOf(Arrays.asList(updated),true);
    }
    return updated;
  }
  log.debug("String_Node_Str",updated);
  List<Owner> owners=Arrays.asList(owner);
  updated.setUuid(null);
  updated=this.productCurator.create(updated);
  updated=this.ownerProductCurator.updateOwnerProductReferences(entity,updated,owners);
  if (regenerateEntitlementCerts) {
    this.entitlementCertGenerator.regenerateCertificatesOf(owners,Arrays.asList(updated),true);
  }
  return updated;
}