class HTTP::Options

def [](option)

def [](option)
  send(option) rescue nil
end

def []=(option, val)

def []=(option, val)
  send(:"#{option}=", val)
end

def argument_error!(message)

def argument_error!(message)
  fail(Error, message, caller[1..-1])
end

def def_option(name, &interpreter)

def def_option(name, &interpreter)
  defined_options << name.to_sym
  interpreter ||= ->(v) { v }
  attr_accessor name
  protected :"#{name}="
  define_method(:"with_#{name}") do |value|
    dup { |opts| opts.send(:"#{name}=", instance_exec(value, &interpreter)) }
  end
end

def defined_options

def defined_options
  @defined_options ||= []
end

def dup

def dup
  dupped = super
  yield(dupped) if block_given?
  dupped
end

def initialize(options = {})

def initialize(options = {})
  defaults = {:response =>         :auto,
              :proxy =>            {},
              :socket_class =>     self.class.default_socket_class,
              :ssl_socket_class => self.class.default_ssl_socket_class,
              :cache =>            self.class.default_cache,
              :headers =>          {}}
  opts_w_defaults = defaults.merge(options)
  opts_w_defaults[:headers] = HTTP::Headers.coerce(opts_w_defaults[:headers])
  opts_w_defaults.each do |(opt_name, opt_val)|
    self[opt_name] = opt_val
  end
end

def merge(other)

def merge(other)
  h1, h2 = to_hash, other.to_hash
  merged = h1.merge(h2) do |k, v1, v2|
    case k
    when :headers
      v1.merge(v2)
    else
      v2
    end
  end
  self.class.new(merged)
end

def new(options = {})

def new(options = {})
  return options if options.is_a?(self)
  super
end

def persistent?

def persistent?
  !persistent.nil? && persistent != ""
end

def to_hash

def to_hash
  hash_pairs = self.class
               .defined_options
               .flat_map { |opt_name| [opt_name, self[opt_name]] }
  Hash[*hash_pairs]
end