# File lib/rack/utils.rb, line 622
      def self.build_multipart(params, first = true)
        if first
          unless params.is_a?(Hash)
            raise ArgumentError, "value must be a Hash"
          end

          multipart = false
          query = lambda { |value|
            case value
            when Array
              value.each(&query)
            when Hash
              value.values.each(&query)
            when UploadedFile
              multipart = true
            end
          }
          params.values.each(&query)
          return nil unless multipart
        end

        flattened_params = Hash.new

        params.each do |key, value|
          k = first ? key.to_s : "[#{key}]"

          case value
          when Array
            value.map { |v|
              build_multipart(v, false).each { |subkey, subvalue|
                flattened_params["#{k}[]#{subkey}"] = subvalue
              }
            }
          when Hash
            build_multipart(value, false).each { |subkey, subvalue|
              flattened_params[k + subkey] = subvalue
            }
          else
            flattened_params[k] = value
          end
        end

        if first
          flattened_params.map { |name, file|
            if file.respond_to?(:original_filename)
              ::File.open(file.path, "rb") do |f|
                f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding)
"--\#{MULTIPART_BOUNDARY}\\r\nContent-Disposition: form-data; name=\"\#{name}\"; filename=\"\#{Utils.escape(file.original_filename)}\"\\r\nContent-Type: \#{file.content_type}\\r\nContent-Length: \#{::File.stat(file.path).size}\\r\n\\r\n\#{f.read}\\r\n"
              end
            else
"--\#{MULTIPART_BOUNDARY}\\r\nContent-Disposition: form-data; name=\"\#{name}\"\\r\n\\r\n\#{file}\\r\n"
            end
          }.join + "--#{MULTIPART_BOUNDARY}--\r"
        else
          flattened_params
        end
      end