class Excon::Headers

def [](key)

def [](key)
  if should_delegate?(key)
    @downcased[key.downcase]
  else
    raw_reader(key)
  end
end

def []=(key, value)

def []=(key, value)
  raw_writer(key, value)
  unless @downcased.nil?
    @downcased[key.downcase] = value
  end
end

def assoc(obj)

def assoc(obj)
  if should_delegate?(obj)
    @downcased.assoc(obj.downcase)
  else
    raw_assoc(obj)
  end
end

def delete(key, &proc)

def delete(key, &proc)
  if should_delegate?(key)
    @downcased.delete(key.downcase, &proc)
  else
    raw_delete(key, &proc)
  end
end

def fetch(key, default = nil, &proc)

def fetch(key, default = nil, &proc)
  if should_delegate?(key)
    if proc
      @downcased.fetch(key.downcase, &proc)
    else
      @downcased.fetch(key.downcase, default)
    end
  else
    if proc
      raw_fetch(key, &proc)
    else
      raw_fetch(key, default)
    end
  end
end

def has_key?(key)

def has_key?(key)
  raw_has_key?(key) || begin
    index_case_insensitive
    @downcased.has_key?(key.downcase)
  end
end

def index_case_insensitive

def index_case_insensitive
  if @downcased.nil?
    @downcased = {}
    each_pair do |key, value|
      @downcased[key.downcase] = value
    end
  end
end

def rehash

def rehash
  raw_rehash
  if @downcased
    @downcased.rehash
  end
end

def should_delegate?(key)

def should_delegate?(key)
  if raw_has_key?(key)
    false
  else
    index_case_insensitive
    true
  end
end

def values_at(*keys)

def values_at(*keys)
  raw_values_at(*keys).zip(keys).map do |v, k|
    if v.nil?
      index_case_insensitive
      @downcased[k.downcase]
    end
  end
end