# File lib/addressable/uri.rb, line 1505
    def query_values=(new_query_values)
      # Check for frozenness
      raise TypeError, "Can't modify frozen URI." if self.frozen?
      if new_query_values == nil
        self.query = nil
        return nil
      end

      if !new_query_values.is_a?(Array)
        if !new_query_values.respond_to?(:to_hash)
          raise TypeError,
            "Can't convert #{new_query_values.class} into Hash."
        end
        new_query_values = new_query_values.to_hash
        new_query_values = new_query_values.map do |key, value|
          key = key.to_s if key.kind_of?(Symbol)
          [key, value]
        end
        # Useful default for OAuth and caching.
        # Only to be used for non-Array inputs. Arrays should preserve order.
        new_query_values.sort!
      end
      # new_query_values have form [['key1', 'value1'], ['key2', 'value2']]

      # Algorithm shamelessly stolen from Julien Genestoux, slightly modified
      buffer = ""
      stack = []
      e = lambda do |component|
        component = component.to_s if component.kind_of?(Symbol)
        self.class.encode_component(component, CharacterClasses::UNRESERVED)
      end
      new_query_values.each do |key, value|
        if value.kind_of?(Hash)
          stack << [key, value]
        elsif value.kind_of?(Array)
          stack << [
            key,
            value.inject({}) { |accu, x| accu[accu.size.to_s] = x; accu }
          ]
        elsif value == true
          buffer << "#{e.call(key)}&"
        else
          buffer << "#{e.call(key)}=#{e.call(value)}&"
        end
      end
      stack.each do |(parent, hash)|
        (hash.sort_by { |key| key.to_s }).each do |(key, value)|
          if value.kind_of?(Hash)
            stack << ["#{parent}[#{key}]", value]
          elsif value == true
            buffer << "#{parent}[#{e.call(key)}]&"
          else
            buffer << "#{parent}[#{e.call(key)}]=#{e.call(value)}&"
          end
        end
      end
      self.query = buffer.chop
    end