def process_attributes(attrs = nil)
      if attrs
        errors = []
        attributes = attrs.class.new
        attributes.permit! if attrs.respond_to?(:permitted?) && attrs.permitted?
        multi_parameter_attributes = {}

        attrs.each_pair do |key, value|
          if key =~ /\A([^\(]+)\((\d+)([if])\)$/
            key, index = $1, $2.to_i
            (multi_parameter_attributes[key] ||= {})[index] = value.empty? ? nil : value.send("to_#{$3}")
          else
            attributes[key] = value
          end
        end

        multi_parameter_attributes.each_pair do |key, values|
          begin
            values = (values.keys.min..values.keys.max).map { |i| values[i] }
            field = self.class.fields[database_field_name(key)]
            attributes[key] = instantiate_object(field, values)
          rescue => e
            errors << Errors::AttributeAssignmentError.new(
              "error on assignment #{values.inspect} to #{key}", e, key
            )
          end
        end

        unless errors.empty?
          raise Errors::MultiparameterAssignmentErrors.new(errors),
            "#{errors.size} error(s) on assignment of multiparameter attributes"
        end
        super(attributes)
      else
        super
      end
    end
def process_attributes(attrs = nil)
      if attrs
        errors = []
        attributes = attrs.class.new
        attributes.permit! if attrs.respond_to?(:permitted?) && attrs.permitted?
        multi_parameter_attributes = {}

        attrs.each_pair do |key, value|
          if key =~ /\A([^\(]+)\((\d+)([if])\)$/
            key, index = $1, $2.to_i
            (multi_parameter_attributes[key] ||= {})[index] = value.empty? ? nil : value.send("to_#{$3}")
          else
            attributes[key] = value
          end
        end

        multi_parameter_attributes.each_pair do |key, values|
          begin
            values = (values.keys.min..values.keys.max).map { |i| values[i] }
            field = self.class.fields[database_field_name(key)]
            attributes[key] = instantiate_object(field, values)
          rescue => e
            errors << Errors::AttributeAssignmentError.new(
              "error on assignment #{values.inspect} to #{key}", e, key
            )
          end
        end

        unless errors.empty?
          raise Errors::MultiparameterAssignmentErrors.new(errors),
            "#{errors.size} error(s) on assignment of multiparameter attributes"
        end
        super(attributes)
      else
        super
      end
    end
Process the provided attributes casting them to their proper values if a
 field exists for them on the document. This will be limited to only the
 attributes provided in the suppied +Hash+ so that no extra nil values get
 put into the document's attributes.

 @example Process the attributes.
   person.process_attributes(:title => "sir", :age => 40)

 @param [ Hash ] attrs The attributes to set.

 @since 2.0.0.rc.7