docs: def create_html_select(
          options,
          name=None,
          selected=None,
          disabled=None,
          multiple=False,
          attrs=None,
          **other_attrs):
      """
      Create an HTML select box.
  
          >>> print create_html_select(["foo", "bar"], selected="bar", name="baz")
          <select name="baz">
            <option selected="selected" value="bar">
              bar
            </option>
            <option value="foo">
              foo
            </option>
          </select>
          >>> print create_html_select([("foo", "oof"), ("bar", "rab")], selected="bar", name="baz")
          <select name="baz">
            <option value="foo">
              oof
            </option>
            <option selected="selected" value="bar">
              rab
            </option>
          </select>
  
      @param options: this can either be a sequence of strings, or a sequence
          of couples or a map of C{key->value}. In the former case, the C{select}
          tag will contain a list of C{option} tags (in alphabetical order),
          where the C{value} attribute is not specified. In the latter case,
          the C{value} attribute will be set to the C{key}, while the body
          of the C{option} will be set to C{value}.
      @type options: sequence or map
      @param name: the name of the form element.
      @type name: string
      @param selected: optional key(s)/value(s) to select by default. In case
          a map has been used for options.
      @type selected: string (or list of string)
      @param disabled: optional key(s)/value(s) to disable.
      @type disabled: string (or list of string)
      @param multiple: whether a multiple select box must be created.
      @type mutable: bool
      @param attrs: optional attributes to create the select tag.
      @type attrs: dict
      @param other_attrs: other optional attributes.
      @return: the HTML output.
      @rtype: string
  
      @note: the values and keys will be escaped for HTML.
  
      @note: it is important that parameter C{value} is always
          specified, in case some browser plugin play with the
          markup, for eg. when translating the page.
      """
      body = []
      if selected is None:
          selected = []
      elif isinstance(selected, (str, unicode)):
          selected = [selected]
      if disabled is None:
          disabled = []
      elif isinstance(disabled, (str, unicode)):
          disabled = [disabled]
      if name is not None and multiple and not name.endswith('[]'):
          name += "[]"
      if isinstance(options, dict):
          items = options.items()
          items.sort(lambda item1, item2: cmp(item1[1], item2[1]))
      elif isinstance(options, (list, tuple)):
          options = list(options)
          items = []
          for item in options:
              if isinstance(item, (str, unicode)):
                  items.append((item, item))
              elif isinstance(item, (tuple, list)) and len(item) == 2:
                  items.append(tuple(item))
              else:
                  raise ValueError(
                      'Item "%s" of incompatible type: %s' % (item, type(item)))
      else:
          raise ValueError('Options of incompatible type: %s' % type(options))
      for key, value in items:
          option_attrs = {}
          if key in selected:
              option_attrs['selected'] = 'selected'
          if key in disabled:
              option_attrs['disabled'] = 'disabled'
          body.append(
              create_tag(
                  "option",
                  body=value,
                  escape_body=True,
                  value=key,
                  attrs=option_attrs))
      if attrs is None:
          attrs = {}
      if name is not None:
          attrs['name'] = name
      if multiple:
          attrs['multiple'] = 'multiple'
      return create_tag(
          "select",
          body='\n'.join(body),
          attrs=attrs,
          **other_attrs)