def merge_attribute(attribute, newval, matches=nil)
      # the previous value
      oldval = send(attribute)
      # Filter the newval into the srcval.
      srcval = if newval and block_given? then
        if newval.collection? then
          newval.select { |v| yield(v) }
        elsif yield(newval) then
          newval
        end
      else
        newval
      end
      
      # If there is no point in merging, then bail. 
      return oldval if srcval.nil_or_empty? or mergeable__equal?(oldval, newval)
      
      # Discriminate between a domain and non-domain attribute.
      prop = self.class.property(attribute)
      if prop.domain? then
        merge_domain_property_value(prop, oldval, srcval, matches)
      else
        merge_nondomain_property_value(prop, oldval, srcval)
      end
    end
def merge_attribute(attribute, newval, matches=nil)
      # the previous value
      oldval = send(attribute)
      # Filter the newval into the srcval.
      srcval = if newval and block_given? then
        if newval.collection? then
          newval.select { |v| yield(v) }
        elsif yield(newval) then
          newval
        end
      else
        newval
      end
      
      # If there is no point in merging, then bail. 
      return oldval if srcval.nil_or_empty? or mergeable__equal?(oldval, newval)
      
      # Discriminate between a domain and non-domain attribute.
      prop = self.class.property(attribute)
      if prop.domain? then
        merge_domain_property_value(prop, oldval, srcval, matches)
      else
        merge_nondomain_property_value(prop, oldval, srcval)
      end
    end
Merges the value newval into the attribute as follows:
 * If the value is nil, empty or equal to the current attribute value, then no merge
   is performed.
 * Otherwise, if a merger block is given to this method, then that block is called
   to perform the merge.
 * Otherwise, if the attribute is a non-domain attribute and the current value is non-nil,
   then no merge is performed.
 * Otherwise, if the attribute is a non-domain attribute and the current value is nil,
   then set the attribute to the newval.
 * Otherwise, if the attribute is a domain non-collection attribute, then newval is recursively
   merged into the current referenced domain object.
 * Otherwise, attribute is a domain collection attribute and matching newval members are
   merged into the corresponding current collection members and non-matching newval members
   are added to the current collection.

 @param [Symbol] attribute the merge attribute
 @param newval the value to merge
 @param [{Resource => Resource}, nil] the optional merge source => target reference matches
 @yield (see #merge_attributes)
 @yieldparam (see #merge_attributes)
 @return the merged attribute value