# File lib/ruote/util/deep.rb, line 103
  def self.deep_mutate(coll, key_or_keys, parent=nil, &block)

    keys = key_or_keys.is_a?(Array) ? key_or_keys : [ key_or_keys ]

    if coll.is_a?(Hash)

      coll.dup.each do |k, v|

        # ensure that all keys are strings

        unless k.is_a?(String)

          coll.delete(k)
          k = k.to_s
          coll[k] = v
        end

        # call the mutation blocks for each match

        if keys.find { |kk| kk.is_a?(Regexp) ? kk.match(k) : kk == k }

          if block.arity > 3
            block.call(parent, coll, k, v)
          else
            block.call(coll, k, v)
          end
        end

        if v.is_a?(Array) || v.is_a?(Hash)

          deep_mutate(v, keys, coll, &block)
        end
      end

    elsif coll.is_a?(Array)

      coll.each { |e| deep_mutate(e, keys, coll, &block) }

    #else # nothing
    end
  end