function setupAsMultiple(scope, selectElement, ctrl) {
        var lastView;
        ctrl.$render = function() {
          var items = new HashMap(ctrl.$viewValue);
          forEach(selectElement.find('option'), function(option) {
            option.selected = isDefined(items.get(option.value));
          });
        };

        // we have to do it on each watch since ngModel watches reference, but
        // we need to work of an array, so we need to see if anything was inserted/removed
        scope.$watch(function selectMultipleWatch() {
          if (!equals(lastView, ctrl.$viewValue)) {
            lastView = copy(ctrl.$viewValue);
            ctrl.$render();
          }
        });

        selectElement.on('change', function() {
          scope.$apply(function() {
            var array = [];
            forEach(selectElement.find('option'), function(option) {
              if (option.selected) {
                array.push(option.value);
              }
            });
            ctrl.$setViewValue(array);
          });
        });
      }
@ngdoc directive
@name select
@restrict E

@description
HTML `SELECT` element with angular data-binding.

# `ngOptions`

The `ngOptions` attribute can be used to dynamically generate a list of `<option>`
elements for the `<select>` element using the array or object obtained by evaluating the
`ngOptions` comprehension_expression.

When an item in the `<select>` menu is selected, the array element or object property
represented by the selected option will be bound to the model identified by the `ngModel`
directive.

<div class="alert alert-warning">
**Note:** `ngModel` compares by reference, not value. This is important when binding to an
array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/).
</div>

Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
be nested into the `<select>` element. This element will then represent the `null` or "not selected"
option. See example below for demonstration.

<div class="alert alert-warning">
**Note:** `ngOptions` provides an iterator facility for the `<option>` element which should be used instead
of {@link ng.directive:ngRepeat ngRepeat} when you want the
`select` model to be bound to a non-string value. This is because an option element can only
be bound to string values at present.
</div>

@param {string} ngModel Assignable angular expression to data-bind to.
@param {string=} name Property name of the form under which the control is published.
@param {string=} required The control is considered valid only if value is entered.
@param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
   the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
   `required` when you want to data-bind to the `required` attribute.
@param {comprehension_expression=} ngOptions in one of the following forms:

  * for array data sources:
    * `label` **`for`** `value` **`in`** `array`
    * `select` **`as`** `label` **`for`** `value` **`in`** `array`
    * `label`  **`group by`** `group` **`for`** `value` **`in`** `array`
    * `select` **`as`** `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
  * for object data sources:
    * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
    * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
    * `label` **`group by`** `group` **`for (`**`key`**`,`** `value`**`) in`** `object`
    * `select` **`as`** `label` **`group by`** `group`
        **`for` `(`**`key`**`,`** `value`**`) in`** `object`

Where:

  * `array` / `object`: an expression which evaluates to an array / object to iterate over.
  * `value`: local variable which will refer to each item in the `array` or each property value
     of `object` during iteration.
  * `key`: local variable which will refer to a property name in `object` during iteration.
  * `label`: The result of this expression will be the label for `<option>` element. The
    `expression` will most likely refer to the `value` variable (e.g. `value.propertyName`).
  * `select`: The result of this expression will be bound to the model of the parent `<select>`
     element. If not specified, `select` expression will default to `value`.
  * `group`: The result of this expression will be used to group options using the `<optgroup>`
     DOM element.
  * `trackexpr`: Used when working with an array of objects. The result of this expression will be
     used to identify the objects in the array. The `trackexpr` will most likely refer to the
    `value` variable (e.g. `value.propertyName`).

@example
    <example>
      <file name="index.html">
        <script>
        function MyCntrl($scope) {
          $scope.colors = [
            {name:'black', shade:'dark'},
            {name:'white', shade:'light'},
            {name:'red', shade:'dark'},
            {name:'blue', shade:'dark'},
            {name:'yellow', shade:'light'}
          ];
          $scope.color = $scope.colors[2]; // red
        }
        </script>
        <div ng-controller="MyCntrl">
          <ul>
            <li ng-repeat="color in colors">
              Name: <input ng-model="color.name">
              [<a href ng-click="colors.splice($index, 1)">X</a>]
            </li>
            <li>
              [<a href ng-click="colors.push({})">add</a>]
            </li>
          </ul>
          <hr/>
          Color (null not allowed):
          <select ng-model="color" ng-options="c.name for c in colors"></select><br>

          Color (null allowed):
          <span  class="nullable">
            <select ng-model="color" ng-options="c.name for c in colors">
              <option value="">-- choose color --</option>
            </select>
          </span><br/>

          Color grouped by shade:
          <select ng-model="color" ng-options="c.name group by c.shade for c in colors">
          </select><br/>


          Select <a href ng-click="color={name:'not in list'}">bogus</a>.<br>
          <hr/>
          Currently selected: {{ {selected_color:color}  }}
          <div style="border:solid 1px black; height:20px"
               ng-style="{'background-color':color.name}">
          </div>
        </div>
      </file>
      <file name="protractor.js" type="protractor">
         it('should check ng-options', function() {
           expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red');
           element.all(by.select('color')).first().click();
           element.all(by.css('select[ng-model="color"] option')).first().click();
           expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black');
           element(by.css('.nullable select[ng-model="color"]')).click();
           element.all(by.css('.nullable select[ng-model="color"] option')).first().click();
           expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null');
         });
      </file>
    </example>