def set_structured_value(subhash, parts, value)
      return if subhash.nil?
      raise ArgumentError, "Cannot set structured value at #{parts.first.inspect}" unless subhash.is_a?(Hash)
      raise ArgumentError, "parts must be an Array, got #{parts.inspect}" unless parts.is_a?(Array)

      # At the top level, find all keys that match the first item in the parts.
      matching_keys = subhash.keys.select do |key|
        if parts.first.is_a?(String)
          key == parts.first
        elsif parts.first.is_a?(Regexp)
          parts.first.match(key)
        else
          # :nocov:
          # This is a bug - this code should be unreachable because of the checking in `set_value`
          raise ArgumentError, "part must be a string or regexp, got #{parts.first.inspect}"
          # :nocov:
        end
      end

      # Auto-create a new hash if there is a value, the part is a string, and the key doesn't exist.
      if parts.first.is_a?(String) && !value.nil? && !subhash.key?(parts.first)
        subhash[parts.first] = {}
        matching_keys << parts.first
      end
      return unless matching_keys.any?

      # If we are at the end, set the value or delete the key.
      if parts.size == 1
        if value.nil?
          matching_keys.each { |k| subhash.delete(k) }
        elsif value.is_a?(Proc)
          matching_keys.each do |k|
            new_value = value.call(subhash[k])
            if new_value.nil?
              subhash.delete(k)
            else
              subhash[k] = new_value
            end
          end
        else
          matching_keys.each { |k| subhash[k] = value }
        end
        return
      end

      # We are not at the end. Recurse down to the next level.
      matching_keys.each { |k| set_structured_value(subhash[k], parts[1..-1], value) }
    end
def set_structured_value(subhash, parts, value)
      return if subhash.nil?
      raise ArgumentError, "Cannot set structured value at #{parts.first.inspect}" unless subhash.is_a?(Hash)
      raise ArgumentError, "parts must be an Array, got #{parts.inspect}" unless parts.is_a?(Array)

      # At the top level, find all keys that match the first item in the parts.
      matching_keys = subhash.keys.select do |key|
        if parts.first.is_a?(String)
          key == parts.first
        elsif parts.first.is_a?(Regexp)
          parts.first.match(key)
        else
          # :nocov:
          # This is a bug - this code should be unreachable because of the checking in `set_value`
          raise ArgumentError, "part must be a string or regexp, got #{parts.first.inspect}"
          # :nocov:
        end
      end

      # Auto-create a new hash if there is a value, the part is a string, and the key doesn't exist.
      if parts.first.is_a?(String) && !value.nil? && !subhash.key?(parts.first)
        subhash[parts.first] = {}
        matching_keys << parts.first
      end
      return unless matching_keys.any?

      # If we are at the end, set the value or delete the key.
      if parts.size == 1
        if value.nil?
          matching_keys.each { |k| subhash.delete(k) }
        elsif value.is_a?(Proc)
          matching_keys.each do |k|
            new_value = value.call(subhash[k])
            if new_value.nil?
              subhash.delete(k)
            else
              subhash[k] = new_value
            end
          end
        else
          matching_keys.each { |k| subhash[k] = value }
        end
        return
      end

      # We are not at the end. Recurse down to the next level.
      matching_keys.each { |k| set_structured_value(subhash[k], parts[1..-1], value) }
    end
Set a value in the data structure of a structured fact. This is intended to be
 called recursively.

 subhash - The Hash, part of the fact, being operated upon
 parts   - The Array to dig in to the hash
 value   - The value to set the ultimate last part to

 Does not return anything, but modifies 'subhash'