$interval = function(fn, delay, count, invokeApply) {
      var deferred = $q.defer(),
          promise = deferred.promise,
          iteration = 0,
          skipApply = (angular.isDefined(invokeApply) && !invokeApply);

      count = (angular.isDefined(count)) ? count : 0;
      promise.then(null, null, fn);

      promise.$$intervalId = nextRepeatId;

      function tick() {
        deferred.notify(iteration++);

        if (count > 0 && iteration >= count) {
          var fnIndex;
          deferred.resolve(iteration);

          angular.forEach(repeatFns, function(fn, index) {
            if (fn.id === promise.$$intervalId) fnIndex = index;
          });

          if (fnIndex !== undefined) {
            repeatFns.splice(fnIndex, 1);
          }
        }

        if (!skipApply) $rootScope.$apply();
      }

      repeatFns.push({
        nextTime:(now + delay),
        delay: delay,
        fn: tick,
        id: nextRepeatId,
        deferred: deferred
      });
      repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;});

      nextRepeatId++;
      return promise;
    }
@ngdoc service
@name $interval

@description
Mock implementation of the $interval service.

Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
move forward by `millis` milliseconds and trigger any functions scheduled to run in that
time.

@param {function()} fn A function that should be called repeatedly.
@param {number} delay Number of milliseconds between each function call.
@param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
  indefinitely.
@param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
  will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
@returns {promise} A promise which will be notified on each iteration.