code: function(callRemove, whereProperties, whereValue, whereEquals, out, delaySort, cascade, options)
    {
      var where = createWhere( whereProperties, whereValue, whereEquals );
      var removed = out || this.cloneEmpty();
      var removedIndices = [];
  
      batchExecute(function()
      {
        for (var i = 0; i < this.length; i++)
        {
          var model = this[ i ];
  
          if ( where( model ) )
          {
            removedIndices.push( i );
            removed.push( model );
          }
        }
  
        for (var i = 0; i < removed.length; i++)
        {
          var model = removed[ i ];
          var key = model.$key();
  
          this.map.remove( key );
  
          if ( callRemove )
          {
            model.$remove( cascade, options );
          }
        }
  
      }, this );
  
      this.trigger( Collection.Events.Removes, [this, removed, removedIndices] );
  
      if ( !delaySort )
      {
        this.sort();
      }
  
      return removed;
    }
docs: Removes the models from this collection where the given expression is true.
  The first argument, if `true`, can call {@link Rekord.Model#$remove} on each
  model removed from this colleciton.
  
  @method
  @memberof Rekord.ModelCollection#
  @param {Boolean} [callRemove=false] -
  Whether {@link Rekord.Model#$remove} should be called on each removed model.
  @param {whereInput} [whereProperties] -
  See {@link Rekord.createWhere}
  @param {Any} [whereValue] -
  See {@link Rekord.createWhere}
  @param {equalityCallback} [whereEquals] -
  See {@link Rekord.createWhere}
  @param {Array} [out=this.cloneEmpty()] -
  The array to place the elements that match.
  @param {Boolean} [delaySort=false] -
  Whether automatic sorting should be delayed until the user manually
  calls {@link Rekord.Collection#sort sort}.
  @return {Rekord.Model[]} -
  An array of models removed from this collection.
  @emits Rekord.ModelCollection#removes
  @emits Rekord.ModelCollection#sort