public function render() {

		/**
		 * Build the code of an option HTML tag.
		 * @var		stdClass
		 * @return	string
		 */
		$buildOption = function ($option) {
			// check on required properties
			if (!isset($option->value) or !isset($option->text)) {
				return '';
			}
			// check if value is an array
			if (is_array($this->value)) {
				$selected = in_array($option->value, $this->value) ? ' selected="selected"' : '';
			} else {
				$selected = $this->value == $option->value ? ' selected="selected"' : '';
			}

			$attributes = '';

			if (isset($option->attributes) and count($option->attributes)) {
				foreach($option->attributes as $a) {
					$attributes .= ' ' . $a['name'] . '="' . $a['value'] . '"';
				}
			}
			
			// build the option
			return '<option value="' . htmlspecialchars($option->value) . '"' . $selected . $attributes . '>' .
					htmlspecialchars($option->text) . "</option>\n";
		};
	
		$ret = '<select ' . $this->getNameProperty();
		
		if ($this->multiple) {
			$ret .= ' multiple';
		}
		
		$ret .= $this->processProperties() . ">\n";
	
		try {
			
			// build each option
			foreach ($this->list as $item) {
				
				// recognize optgroup
				if (isset($item->list) and is_array($item->list) and count($item->list)) {
					
					$ret .= '<optgroup label="' . htmlspecialchars(isset($item->group) ? $item->group : '') . "\">\n";
					foreach ($item->list as $option) {
						$ret .= $buildOption($option);
					}
					$ret .= "</optgroup>\n";
					
				} else {
				
					$ret .= $buildOption($item);
					
				}
				
			}
			
		} catch (\Exception $e) {
			
			print $e->getMessage();
			
		}
	
		$ret .= "</select>\n";
		return $ret;
	
	}