module AWS::Core::OptionGrammar::ModuleMethods

def apply_integer_descriptor(m, name)

def apply_integer_descriptor(m, name)
  MetaUtils.extend_method(m, "validate_#{ruby_name(name)}") do |value|
    raise ArgumentError.new("expected integer value for option #{ruby_name(name)}") unless
      value.respond_to? :to_int
  end
end

def apply_list_descriptor(m, name, arg)

def apply_list_descriptor(m, name, arg)
  MetaUtils.extend_method(m, "validate_#{ruby_name(name)}") do |value|
    raise ArgumentError.new("expected value for option #{ruby_name(name)} "+
                            "to respond to #each") unless
      value.respond_to? :each
  end
  MetaUtils.extend_method(m, "params_for_#{ruby_name(name)}") do |value|
    i = 0
    values = []
    value.each do |member|
      i += 1
      values << Http::Request::Param.new(name+"."+i.to_s, member.to_s)
    end
    if i > 0
      values
    else
      Http::Request::Param.new(name, "")
    end
  end
end

def apply_rename_descriptor(m, name, new_name)

def apply_rename_descriptor(m, name, new_name)
  name = ruby_name(name)
  MetaUtils.extend_method(m, :validate) do |opts|
    raise ArgumentError.new("unexpected option foo") if
      opts.key?(name) or opts.key?(name.to_sym)
    opts = opts.dup
    opts[name] = opts[new_name] if opts.key?(new_name)
    opts[name.to_sym] = opts[new_name.to_sym] if opts.key?(new_name.to_sym)
    opts.delete(new_name)
    opts.delete(new_name.to_sym)
    super(opts)
  end
  # couldn't find a better way to alias a class method
  method = m.method("params_for_#{name}")
  MetaUtils.extend_method(m, "params_for_#{new_name}") do |value|
    method.call(value)
  end
end

def apply_required_descriptor(m, name)

def apply_required_descriptor(m, name)
  name = ruby_name(name)
  MetaUtils.extend_method(m, :validate) do |opts|
    raise ArgumentError.new("missing required option #{name}") unless
      opts.key? name or opts.key? name.to_sym
  end
end

def apply_string_descriptor(m, name)

def apply_string_descriptor(m, name)
  MetaUtils.extend_method(m, "validate_#{ruby_name(name)}") do |value|
    raise ArgumentError.new("expected string value for option #{ruby_name(name)}") unless
      value.respond_to? :to_str
  end
end

def customize(config = [])

def customize(config = [])
  m = Class.new(self)
  supported_options = m.supported_options.inject({}) do |memo, opt|
    memo[opt.name] = opt
    memo
  end
  config.each do |option_config|
    if config.kind_of?(Hash)
      (name, value_desc) = option_config
    else
      (name, value_desc) = parse_option(option_config)
    end
    option = supported_options[name] || DefaultOption.new(name)
    option = option.extend_with_config(*value_desc)
    supported_options[option.name] = option
  end
  supported_ary = supported_options.values
  MetaUtils.extend_method(m, :supported_options) { supported_ary }
  supported_ruby_names = supported_ary.inject({}) do |memo, opt|
    memo[opt.ruby_name] = opt
    memo
  end
  MetaUtils.extend_method(m, :option) { |n| supported_ruby_names[n] }
  supported_ary.each do |opt|
    MetaUtils.extend_method(m, "validate_#{opt.ruby_name}") do |value|
      opt.validate(value)
    end
  end
  m
end

def included(m)

def included(m)
  m.extend(self::ModuleMethods)
end

def option(name)

def option(name)
  nil
end

def parse_option(option)

def parse_option(option)
  value_desc = nil
  if option.kind_of? Hash
    raise ArgumentError.new("passed empty hash where an option was expected") if
      option.empty?
    raise ArgumentError.new("too many entries in option description") if
      option.size > 1
    (name, value_desc) = option.to_a.first
    name = name.to_s
    raise ArgumentError.new("expected an array for "+
                            "value description of option #{name},"+
                            "got #{value_desc.inspect}") unless
      value_desc.nil? or value_desc.kind_of?(Array)
  else
    name = option
  end
  value_desc ||= []
  [name, value_desc]
end

def request_params(options)

Returns the options in AWS/Query format
def request_params(options)
  validate(options)
  options.map do |(name, value)|
    name = name.to_s
    option(name).request_params(value)
  end.flatten
end

def supported_options

def supported_options
  []
end

def to_h(options)

in to_json).
Returns the options as a hash (which is used to generate JSON
def to_h(options)
  validate(options)
  options.inject({}) do |hash, (name, value)|
    option = self.option(name.to_s)
    hash[option.name] = option.hash_format(value)
    hash
  end
end

def to_json(options)

Returns the options in JSON format
def to_json(options)
  to_h(options).to_json
end

def validate(options)

def validate(options)
  options.each do |name, value|
    name = name.to_s
    raise ArgumentError.new("unexpected option #{name}") unless
      option(name)
    option(name).validate(value)
  end
  supported_options.each do |option|
    raise ArgumentError.new("missing required option #{option.ruby_name}") unless
      !option.required? ||
      options.has_key?(option.ruby_name) || options.has_key?(option.ruby_name.to_sym)
  end
end