module Faraday::Utils

def build_nested_query(value, prefix = nil)

Override Rack's version since it doesn't handle non-String values
def build_nested_query(value, prefix = nil)
  case value
  when Array
    value.map { |v| build_nested_query(v, "#{prefix}[]") }.join("&")
  when Hash
    value.map { |k, v|
      build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
    }.join("&")
  when NilClass
    prefix
  else
    raise ArgumentError, "value must be a Hash" if prefix.nil?
    "#{prefix}=#{escape(value)}"
  end
end

def deep_merge(source, hash)

Recursive hash merge
def deep_merge(source, hash)
  deep_merge!(source.dup, hash)
end

def deep_merge!(target, hash)

Recursive hash update
def deep_merge!(target, hash)
  hash.each do |key, value|
    if Hash === value and Hash === target[key]
      target[key] = deep_merge(target[key], value)
    else
      target[key] = value
    end
  end
  target
end

def escape(s)

as spaces.
Be sure to URI escape '+' symbols to %2B. Otherwise, they get interpreted
def escape(s)
  s.to_s.gsub(/([^a-zA-Z0-9_.-]+)/n) do
    '%' << $1.unpack('H2'*bytesize($1)).join('%').tap { |c| c.upcase! }
  end
end

def normalize_path(url)

Receives a URL and returns just the path with the query string sorted.
def normalize_path(url)
  (url.path != "" ? url.path : "/") +
  (url.query ? "?#{sort_query_params(url.query)}" : "")
end

def sort_query_params(query)

def sort_query_params(query)
  query.split('&').sort.join('&')
end