Class it_html:

/**
 * Create a dropdown menu object. Warning: encodes html code within options!
 * @param $tags key => value pairs of <select> tag
 *        note: add brackets after name (eg. 'name' => "var[]") when using multiple attribute
 * @param $options array (value => text) of available options or
 *        string key:val{,key:val} where key will be rawurldecoded so it may contain %2C as comma
 *        supports optgroups as array (value => optgroup => array(value => text))
 * @param $selected optional currently selected value, or comma-separated list or array for multi-select
 * Note: use tag('select') and tag('option') if you want do roll your own
 */
function select($tags, $options, $selected = null)
{
    # Transmogrify key:val{,key:val} to array(key => val)
    if (!is_array($options))
    {
        $opts = explode(',', $options);
        $options = array();

        foreach($opts as $opt)
        {
            list($key, $value) = explode(':', $opt);
            $options[rawurldecode($key)] = $value;
        }
    }

    $selected = ($tags['multiple'] && is_string($selected)) ? explode(',', $selected) : (array)$selected;

    $html = "";
    foreach($options as $value => $option)
    {
        if (is_array($option))
        {
            $grouphtml = "";
            foreach($option as $optval => $opt)
                $grouphtml .= $this->_tag("option", array(array('value' => $optval, 'selected' => in_array((string)$optval, $selected)), self::_strip_tags(Q(self::_strip_tags($opt)))));
            $html .= $this->_tag("optgroup", array(array('label' => $value, $grouphtml)));
        }
        else
            $html .= $this->_tag("option", array(array('value' => $value, 'selected' => in_array((string)$value, $selected), 'disabled' => $option === ""), (trim($option) === "") ? "&nbsp;" : self::_strip_tags(Q(self::_strip_tags($option))))); # self::_strip_tags removes .q debug param coloring
    }

    return $this->_tag("select", array($tags, $html));
}