function(watchExpressions, listener) {
        var oldValues = new Array(watchExpressions.length);
        var newValues = new Array(watchExpressions.length);
        var deregisterFns = [];
        var self = this;
        var changeReactionScheduled = false;
        var firstRun = true;

        if (!watchExpressions.length) {
          // No expressions means we call the listener ASAP
          var shouldCall = true;
          self.$evalAsync(function() {
            if (shouldCall) listener(newValues, newValues, self);
          });
          return function deregisterWatchGroup() {
            shouldCall = false;
          };
        }

        if (watchExpressions.length === 1) {
          // Special case size of one
          return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {
            newValues[0] = value;
            oldValues[0] = oldValue;
            listener(newValues, (value === oldValue) ? newValues : oldValues, scope);
          });
        }

        forEach(watchExpressions, function(expr, i) {
          var unwatchFn = self.$watch(expr, function watchGroupSubAction(value) {
            newValues[i] = value;
            if (!changeReactionScheduled) {
              changeReactionScheduled = true;
              self.$evalAsync(watchGroupAction);
            }
          });
          deregisterFns.push(unwatchFn);
        });

        function watchGroupAction() {
          changeReactionScheduled = false;

          try {
            if (firstRun) {
              firstRun = false;
              listener(newValues, newValues, self);
            } else {
              listener(newValues, oldValues, self);
            }
          } finally {
            for (var i = 0; i < watchExpressions.length; i++) {
              oldValues[i] = newValues[i];
            }
          }
        }

        return function deregisterWatchGroup() {
          while (deregisterFns.length) {
            deregisterFns.shift()();
          }
        };
      }
function(watchExpressions, listener) {
        var oldValues = new Array(watchExpressions.length);
        var newValues = new Array(watchExpressions.length);
        var deregisterFns = [];
        var self = this;
        var changeReactionScheduled = false;
        var firstRun = true;

        if (!watchExpressions.length) {
          
          var shouldCall = true;
          self.$evalAsync(function() {
            if (shouldCall) listener(newValues, newValues, self);
          });
          return function deregisterWatchGroup() {
            shouldCall = false;
          };
        }

        if (watchExpressions.length === 1) {
          
          return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {
            newValues[0] = value;
            oldValues[0] = oldValue;
            listener(newValues, (value === oldValue) ? newValues : oldValues, scope);
          });
        }

        forEach(watchExpressions, function(expr, i) {
          var unwatchFn = self.$watch(expr, function watchGroupSubAction(value) {
            newValues[i] = value;
            if (!changeReactionScheduled) {
              changeReactionScheduled = true;
              self.$evalAsync(watchGroupAction);
            }
          });
          deregisterFns.push(unwatchFn);
        });

        function watchGroupAction() {
          changeReactionScheduled = false;

          try {
            if (firstRun) {
              firstRun = false;
              listener(newValues, newValues, self);
            } else {
              listener(newValues, oldValues, self);
            }
          } finally {
            for (var i = 0; i < watchExpressions.length; i++) {
              oldValues[i] = newValues[i];
            }
          }
        }

        return function deregisterWatchGroup() {
          while (deregisterFns.length) {
            deregisterFns.shift()();
          }
        };
      }
function ( watchExpressions , listener ) { var oldValues = new Array ( watchExpressions . length ) ; var newValues = new Array ( watchExpressions . length ) ; var deregisterFns = [ ] ; var self = this ; var changeReactionScheduled = false ; var firstRun = true ; if ( ! watchExpressions . length ) { // No expressions means we call the listener ASAP var shouldCall = true ; self . $evalAsync ( function ( ) { if ( shouldCall ) listener ( newValues , newValues , self ) ; } ) ; return function deregisterWatchGroup ( ) { shouldCall = false ; } ; } if ( watchExpressions . length === 1 ) { // Special case size of one return this . $watch ( watchExpressions [ 0 ] , function watchGroupAction ( value , oldValue , scope ) { newValues [ 0 ] = value ; oldValues [ 0 ] = oldValue ; listener ( newValues , ( value === oldValue ) ? newValues : oldValues , scope ) ; } ) ; } forEach ( watchExpressions , function ( expr , i ) { var unwatchFn = self . $watch ( expr , function watchGroupSubAction ( value ) { newValues [ i ] = value ; if ( ! changeReactionScheduled ) { changeReactionScheduled = true ; self . $evalAsync ( watchGroupAction ) ; } } ) ; deregisterFns . push ( unwatchFn ) ; } ) ; function watchGroupAction ( ) { changeReactionScheduled = false ; try { if ( firstRun ) { firstRun = false ; listener ( newValues , newValues , self ) ; } else { listener ( newValues , oldValues , self ) ; } } finally { for ( var i = 0 ; i < watchExpressions . length ; i ++ ) { oldValues [ i ] = newValues [ i ] ; } } } return function deregisterWatchGroup ( ) { while ( deregisterFns . length ) { deregisterFns . shift ( ) ( ) ; } } ; }
@ngdoc method
@name $rootScope.Scope#$watchGroup
@kind function

@description
A variant of {@link ng.$rootScope.Scope#$watch $watch()} where it watches an array of `watchExpressions`.
If any one expression in the collection changes the `listener` is executed.

- The items in the `watchExpressions` array are observed via the standard `$watch` operation. Their return
values are examined for changes on every call to `$digest`.
- The `listener` is called whenever any expression in the `watchExpressions` array changes.

@param {Array.<string|Function(scope)>} watchExpressions Array of expressions that will be individually
watched using {@link ng.$rootScope.Scope#$watch $watch()}

@param {function(newValues, oldValues, scope)} listener Callback called whenever the return value of any
expression in `watchExpressions` changes
The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching
those of `watchExpression`
and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching
those of `watchExpression`
The `scope` refers to the current scope.
@returns {function()} Returns a de-registration function for all listeners.
@ngdoc method @name $rootScope . Scope#$watchGroup @kind function