=} instanceCache Provides pre-instantiated services which should
 *     append/override services provided by `providers`. This is handy when unit-testing and having
 *     the need to override a default service.
 * @returns {Object} Newly created scope.
 *
 */
function Scope() {
  this.$id = nextUid();
  this.$$phase = this.$parent = this.$$watchers = this.$$observers =
    this.$$nextSibling = this.$$childHead = this.$$childTail = null;
  this['this'] = this.$root =  this;
}
/**
 * @workInProgress
 * @ngdoc property
 * @name angular.scope.$id
 * @returns {number} Unique scope ID (monotonically increasing alphanumeric sequence) useful for
 *   debugging.
 */
/**
 * @workInProgress
 * @ngdoc property
 * @name angular.scope.$service
 * @function
 *
 * @description
 * Provides reference to an instance of {@link angular.injector injector} which can be used to
 * retrieve {@link angular.service services}. In general the use of this api is discouraged,
 * in favor of proper {@link guide/dev_guide.di dependency injection}.
 *
 * @returns {function} {@link angular.injector injector}
 */
/**
 * @workInProgress
 * @ngdoc property
 * @name angular.scope.$root
 * @returns {Scope} The root scope of the current scope hierarchy.
 */
/**
 * @workInProgress
 * @ngdoc property
 * @name angular.scope.$parent
 * @returns {Scope} The parent scope of the current scope.
 */
Scope.prototype = {
  /**
   * @workInProgress
   * @ngdoc function
   * @name angular.scope.$new
   * @function
   *
   * @description
   * Creates a new child {@link angular.scope scope}. The new scope can optionally behave as a
   * controller. The parent scope will propagate the {@link angular.scope.$digest $digest()} and
   * {@link angular.scope.$flush $flush()} events. The scope can be removed from the scope
   * hierarchy using {@link angular.scope.$destroy $destroy()}.
   *
   * {@link angular.scope.$destroy $destroy()} must be called on a scope when it is desired for
   * the scope and its child scopes to be permanently detached from the parent and thus stop
   * participating in model change detection and listener notification by invoking.
   *
   * @param {function()=} constructor Constructor function which the scope should behave as.
   * @param {curryArguments=} ... Any additional arguments which are curried into the constructor.
   *        See {@link guide/dev_guide.di dependency injection}.
   * @returns {Object} The newly created child scope.
   *
   */
  $new: function(Class, curryArguments) {
    var Child = function() {}; // should be anonymous; This is so that when the minifier munges
      // the name it does not become random set of chars. These will then show up as class
      // name in the debugger.
    var child;
    Child.prototype = this;
    child = new Child();
    child['this'] = child;
    child.$parent = this;
    child.$id = nextUid();
    child.$$phase = child.$$watchers = child.$$observers =
      child.$$nextSibling = child.$$childHead = child.$$childTail = null;
    if (this.$$childHead) {
      this.$$childTail.$$nextSibling = child;
      this.$$childTail = child;
    } else {
      this.$$childHead = this.$$childTail = child;
    }
    // short circuit if we have no class
    if (Class) {
      // can't use forEach, we need speed!
      var ClassPrototype = Class.prototype;
      for(var key in ClassPrototype) {
        child[key] = bind(child, ClassPrototype[key]);
      }
      this.$service.invoke(child, Class, curryArguments);
    }
    return child;
  },
  /**
   * @workInProgress
   * @ngdoc function
   * @name angular.scope.$watch
   * @function
   *
   * @description
   * Registers a `listener` callback to be executed whenever the `watchExpression` changes.
   *
   * - The `watchExpression` is called on every call to {@link angular.scope.$digest $digest()} and
   *   should return the value which will be watched. (Since {@link angular.scope.$digest $digest()}
   *   reruns when it detects changes the `watchExpression` can execute multiple times per
   *   {@link angular.scope.$digest $digest()} and should be idempotent.)
   * - The `listener` is called only when the value from the current `watchExpression` and the
   *   previous call to `watchExpression' are not equal. The inequality is determined according to
   *   {@link angular.equals} function. To save the value of the object for later comparison
   *   {@link angular.copy} function is used. It also means that watching complex options will
   *   have adverse memory and performance implications.
   * - The watch `listener` may change the model, which may trigger other `listener`s to fire. This
   *   is achieving my rerunning the watchers until no changes are detected. The rerun iteration
   *   limit is 100 to prevent infinity loop deadlock.
   *
   * # When to use `$watch`?
   *
   * The `$watch` should be used from within controllers to listen on properties *immediately* after
   * a stimulus is applied to the system (see {@link angular.scope.$apply $apply()}). This is in
   * contrast to {@link angular.scope.$observe $observe()} which is used from within the directives
   * and which gets applied at some later point in time. In addition
   * {@link angular.scope.$observe $observe()} must not modify the model.
   *
   * If you want to be notified whenever {@link angular.scope.$digest $digest} is called,
   * you can register an `watchExpression` function with no `listener`. (Since `watchExpression`,
   * can execute multiple times per {@link angular.scope.$digest $digest} cycle when a change is
   * detected, be prepared for multiple calls to your listener.)
   *
   * # `$watch` vs `$observe`
   *
   * 
   *   
   *     | 
   *      | {@link angular.scope.$watch $watch()} | 
   *     {@link angular.scope.$observe $observe()} | 
   *   
   *   | When to use it? | 
   *   
   *     | Purpose | 
   *     Application behavior (including further model mutation) in response to a model
   *         mutation. | 
   *     Update the DOM in response to a model mutation. | 
   *   
   *   
   *     | Used from | 
   *     {@link angular.directive.ng:controller controller} | 
   *     {@link angular.directive directives} | 
   *   
   *   | What fires listeners? | 
   *   
   *     | Directly | 
   *     {@link angular.scope.$digest $digest()} | 
   *     {@link angular.scope.$flush $flush()} | 
   *   
   *   
   *     | Indirectly via {@link angular.scope.$apply $apply()} | 
   *     {@link angular.scope.$apply $apply} calls
   *         {@link angular.scope.$digest $digest()} after apply argument executes. | 
   *     {@link angular.scope.$apply $apply} schedules
   *         {@link angular.scope.$flush $flush()} at some future time via
   *         {@link angular.service.$updateView $updateView} | 
   *   
   *   | API contract | 
   *   
   *     | Model mutation | 
   *     allowed: detecting mutations requires one or mare calls to `watchExpression' per
   *         {@link angular.scope.$digest $digest()} cycle | 
   *     not allowed: called once per {@link angular.scope.$flush $flush()} must be
   *         {@link http://en.wikipedia.org/wiki/Idempotence idempotent}
   *         (function without side-effects which can be called multiple times.) | 
   *   
   *   
   *     | Initial Value | 
   *     uses the current value of `watchExpression` as the initial value. Does not fire on
   *         initial call to {@link angular.scope.$digest $digest()}, unless `watchExpression` has
   *         changed form the initial value. | 
   *     fires on first run of {@link angular.scope.$flush $flush()} regardless of value of
   *         `observeExpression` | 
   *   
   * 
   *
   *
   *
   * # Example
     
       var scope = angular.scope();
       scope.name = 'misko';
       scope.counter = 0;
       expect(scope.counter).toEqual(0);
       scope.$watch('name', function(scope, newValue, oldValue) { counter = counter + 1; });
       expect(scope.counter).toEqual(0);
       scope.$digest();
       // no variable change
       expect(scope.counter).toEqual(0);
       scope.name = 'adam';
       scope.$digest();
       expect(scope.counter).toEqual(1);
     
   *
   *
   *
   * @param {(function()|string)} watchExpression Expression that is evaluated on each
   *    {@link angular.scope.$digest $digest} cycle. A change in the return value triggers a
   *    call to the `listener`.
   *
   *    - `string`: Evaluated as {@link guide/dev_guide.expressions expression}
   *    - `function(scope)`: called with current `scope` as a parameter.
   * @param {(function()|string)=} listener Callback called whenever the return value of
   *   the `watchExpression` changes.
   *
   *    - `string`: Evaluated as {@link guide/dev_guide.expressions expression}
   *    - `function(scope, newValue, oldValue)`: called with current `scope` an previous and
   *       current values as parameters.
   * @returns {function()} a function which will call the `listener` with apprariate arguments.
   *    Useful for forcing initialization of listener.
   */
  $watch: function(watchExp, listener) {
    var scope = this;
    var get = compileToFn(watchExp, 'watch');
    var listenFn = compileToFn(listener || noop, 'listener');
    var array = scope.$$watchers;
    if (!array) {
      array = scope.$$watchers = [];
    }
    // we use unshift since we use a while loop in $digest for speed.
    // the while loop reads in reverse order.
    array.unshift({
      fn: listenFn,
      last: copy(get(scope)),
      get: get
    });
    // we only return the initialization function for $watch (not for $observe), since creating
    // function cost time and memory, and $observe functions do not need it.
    return function() {
      var value = get(scope);
      listenFn(scope, value, value);
    };
  },
  /**
   * @workInProgress
   * @ngdoc function
   * @name angular.scope.$digest
   * @function
   *
   * @description
   * Process all of the {@link angular.scope.$watch watchers} of the current scope and its children.
   * Because a {@link angular.scope.$watch watcher}'s listener can change the model, the
   * `$digest()` keeps calling the {@link angular.scope.$watch watchers} until no more listeners are
   * firing. This means that it is possible to get into an infinite loop. This function will throw
   * `'Maximum iteration limit exceeded.'` if the number of iterations exceeds 100.
   *
   * Usually you don't call `$digest()` directly in
   * {@link angular.directive.ng:controller controllers} or in {@link angular.directive directives}.
   * Instead a call to {@link angular.scope.$apply $apply()} (typically from within a
   * {@link angular.directive directive}) will force a `$digest()`.
   *
   * If you want to be notified whenever `$digest()` is called,
   * you can register a `watchExpression` function  with {@link angular.scope.$watch $watch()}
   * with no `listener`.
   *
   * You may have a need to call `$digest()` from within unit-tests, to simulate the scope
   * life-cycle.
   *
   * # Example
     
       var scope = angular.scope();
       scope.name = 'misko';
       scope.counter = 0;
       expect(scope.counter).toEqual(0);
       scope.$flush('name', function(scope, newValue, oldValue) { counter = counter + 1; });
       expect(scope.counter).toEqual(0);
       scope.$flush();
       // no variable change
       expect(scope.counter).toEqual(0);
       scope.name = 'adam';
       scope.$flush();
       expect(scope.counter).toEqual(1);
     
   *
   * @returns {number} number of {@link angular.scope.$watch listeners} which fired.
   *
   */
  $digest: function() {
    var child,
        watch, value, last,
        watchers = this.$$watchers,
        length, count = 0,
        dirtyCount, ttl = 100,
        recheck = !this.$parent || !this.$parent.$$phase;
    if (this.$$phase) {
      throw Error(this.$$phase + ' already in progress');
    }
    this.$$phase = '$digest';
    do {
      dirtyCount = 0;
      if (watchers) {
        // process our watches
        length = watchers.length;
        while (length--) {
          try {
            watch = watchers[length];
            // Most common watches are on primitives, in which case we can short
            // circuit it with === operator, only when === fails do we use .equals
            if ((value = watch.get(this)) !== (last = watch.last) && !equals(value, last)) {
              dirtyCount++;
              watch.fn(this, watch.last = copy(value), last);
            }
          } catch (e) {
            this.$service('$exceptionHandler')(e);
          }
        }
      }
      child = this.$$childHead;
      while(child) {
        dirtyCount += child.$digest();
        child = child.$$nextSibling;
      }
      count += dirtyCount;
      if(!(ttl--)) {
        throw Error('100 $digest() iterations reached. Aborting!');
      }
    } while (recheck && dirtyCount);
    this.$$phase = null;
    return count;
  },
  /**
   * @workInProgress
   * @ngdoc function
   * @name angular.scope.$observe
   * @function
   *
   * @description
   * Registers a `listener` callback to be executed during the {@link angular.scope.$flush $flush()}
   * phase when the `observeExpression` changes..
   *
   * - The `observeExpression` is called on every call to {@link angular.scope.$flush $flush()} and
   *   should return the value which will be observed.
   * - The `listener` is called only when the value from the current `observeExpression` and the
   *   previous call to `observeExpression' are not equal. The inequality is determined according to
   *   {@link angular.equals} function. To save the value of the object for later comparison
   *   {@link angular.copy} function is used. It also means that watching complex options will
   *   have adverse memory and performance implications.
   *
   * # When to use `$observe`?
   *
   * {@link angular.scope.$observe $observe()} is used from within directives and gets applied at
   * some later point in time. Addition {@link angular.scope.$observe $observe()} must not
   * modify the model. This is in contrast to {@link angular.scope.$watch $watch()} which should be
   * used from within controllers to trigger a callback *immediately* after a stimulus is applied
   * to the system (see {@link angular.scope.$apply $apply()}).
   *
   * If you want to be notified whenever {@link angular.scope.$flush $flush} is called,
   * you can register an `observeExpression` function with no `listener`.
   *
   *
   * # `$watch` vs `$observe`
   *
   * 
   *   
   *     | 
   *      | {@link angular.scope.$watch $watch()} | 
   *     {@link angular.scope.$observe $observe()} | 
   *   
   *   | When to use it? | 
   *   
   *     | Purpose | 
   *     Application behavior (including further model mutation) in response to a model
   *         mutation. | 
   *     Update the DOM in response to a model mutation. | 
   *   
   *   
   *     | Used from | 
   *     {@link angular.directive.ng:controller controller} | 
   *     {@link angular.directive directives} | 
   *   
   *   | What fires listeners? | 
   *   
   *     | Directly | 
   *     {@link angular.scope.$digest $digest()} | 
   *     {@link angular.scope.$flush $flush()} | 
   *   
   *   
   *     | Indirectly via {@link angular.scope.$apply $apply()} | 
   *     {@link angular.scope.$apply $apply} calls
   *         {@link angular.scope.$digest $digest()} after apply argument executes. | 
   *     {@link angular.scope.$apply $apply} schedules
   *         {@link angular.scope.$flush $flush()} at some future time via
   *         {@link angular.service.$updateView $updateView} | 
   *   
   *   | API contract | 
   *   
   *     | Model mutation | 
   *     allowed: detecting mutations requires one or mare calls to `watchExpression' per
   *         {@link angular.scope.$digest $digest()} cycle | 
   *     not allowed: called once per {@link angular.scope.$flush $flush()} must be
   *         {@link http://en.wikipedia.org/wiki/Idempotence idempotent}
   *         (function without side-effects which can be called multiple times.) | 
   *   
   *   
   *     | Initial Value | 
   *     uses the current value of `watchExpression` as the initial value. Does not fire on
   *         initial call to {@link angular.scope.$digest $digest()}, unless `watchExpression` has
   *         changed form the initial value. | 
   *     fires on first run of {@link angular.scope.$flush $flush()} regardless of value of
   *         `observeExpression` | 
   *   
   * 
   *
   * # Example
     
       var scope = angular.scope();
       scope.name = 'misko';
       scope.counter = 0;
       expect(scope.counter).toEqual(0);
       scope.$flush('name', function(scope, newValue, oldValue) { counter = counter + 1; });
       expect(scope.counter).toEqual(0);
       scope.$flush();
       // no variable change
       expect(scope.counter).toEqual(0);
       scope.name = 'adam';
       scope.$flush();
       expect(scope.counter).toEqual(1);
     
   *
   * @param {(function()|string)} observeExpression Expression that is evaluated on each
   *    {@link angular.scope.$flush $flush} cycle. A change in the return value triggers a
   *    call to the `listener`.
   *
   *    - `string`: Evaluated as {@link guide/dev_guide.expressions expression}
   *    - `function(scope)`: called with current `scope` as a parameter.
   * @param {(function()|string)=} listener Callback called whenever the return value of
   *   the `observeExpression` changes.
   *
   *    - `string`: Evaluated as {@link guide/dev_guide.expressions expression}
   *    - `function(scope, newValue, oldValue)`: called with current `scope` an previous and
   *       current values as parameters.
   */
  $observe: function(watchExp, listener) {
    var array = this.$$observers;
    if (!array) {
      array = this.$$observers = [];
    }
    // we use unshift since we use a while loop in $flush for speed.
    // the while loop reads in reverse order.
    array.unshift({
      fn: compileToFn(listener || noop, 'listener'),
      last: NaN,
      get:  compileToFn(watchExp, 'watch')
    });
  },
  /**
   * @workInProgress
   * @ngdoc function
   * @name angular.scope.$flush
   * @function
   *
   * @description
   * Process all of the {@link angular.scope.$observe observers} of the current scope
   * and its children.
   *
   * Usually you don't call `$flush()` directly in
   * {@link angular.directive.ng:controller controllers} or in {@link angular.directive directives}.
   * Instead a call to {@link angular.scope.$apply $apply()} (typically from within a
   * {@link angular.directive directive}) will scheduled a call to `$flush()` (with the
   * help of the {@link angular.service.$updateView $updateView} service).
   *
   * If you want to be notified whenever `$flush()` is called,
   * you can register a `observeExpression` function  with {@link angular.scope.$observe $observe()}
   * with no `listener`.
   *
   * You may have a need to call `$flush()` from within unit-tests, to simulate the scope
   * life-cycle.
   *
   * # Example
     
       var scope = angular.scope();
       scope.name = 'misko';
       scope.counter = 0;
       expect(scope.counter).toEqual(0);
       scope.$flush('name', function(scope, newValue, oldValue) { counter = counter + 1; });
       expect(scope.counter).toEqual(0);
       scope.$flush();
       // no variable change
       expect(scope.counter).toEqual(0);
       scope.name = 'adam';
       scope.$flush();
       expect(scope.counter).toEqual(1);
     
   *
   */
  $flush: function() {
    var observers = this.$$observers,
        child,
        length,
        observer, value, last;
    if (this.$$phase) {
      throw Error(this.$$phase + ' already in progress');
    }
    this.$$phase = '$flush';
    if (observers) {
      // process our watches
      length = observers.length;
      while (length--) {
        try {
          observer = observers[length];
          // Most common watches are on primitives, in which case we can short
          // circuit it with === operator, only when === fails do we use .equals
          if ((value = observer.get(this)) !== (last = observer.last) && !equals(value, last)) {
            observer.fn(this, observer.last = copy(value), last);
          }
        } catch (e){
          this.$service('$exceptionHandler')(e);
        }
      }
    }
    // observers can create new children
    child = this.$$childHead;
    while(child) {
      child.$flush();
      child = child.$$nextSibling;
    }
    this.$$phase = null;
  },
  /**
   * @workInProgress
   * @ngdoc function
   * @name angular.scope.$destroy
   * @function
   *
   * @description
   * Remove the current scope (and all of its children) from the parent scope. Removal implies
   * that calls to {@link angular.scope.$digest $digest()} and
   * {@link angular.scope.$flush $flush()} will no longer propagate to the current scope and its
   * children. Removal also implies that the current scope is eligible for garbage collection.
   *
   * The `$destroy()` is usually used by directives such as
   * {@link angular.widget.@ng:repeat ng:repeat} for managing the unrolling of the loop.
   *
   */
  $destroy: function() {
    if (this.$root == this) return; // we can't remove the root node;
    var parent = this.$parent;
    var child = parent.$$childHead;
    var lastChild = null;
    var nextChild = null;
    // We have to do a linear search, since we don't have doubly link list.
    // But this is intentional since removals are rare, and doubly link list is not free.
    while(child) {
      if (child == this) {
        nextChild = child.$$nextSibling;
        if (parent.$$childHead == child) {
          parent.$$childHead = nextChild;
        }
        if (lastChild) {
          lastChild.$$nextSibling = nextChild;
        }
        if (parent.$$childTail == child) {
          parent.$$childTail = lastChild;
        }
        return; // stop iterating we found it
      } else {
        lastChild = child;
        child = child.$$nextSibling;
      }
    }
  },
  /**
   * @workInProgress
   * @ngdoc function
   * @name angular.scope.$eval
   * @function
   *
   * @description
   * Executes the expression on the current scope returning the result. Any exceptions in the
   * expression are propagated (uncaught). This is useful when evaluating engular expressions.
   *
   * # Example
     
       var scope = angular.scope();
       scope.a = 1;
       scope.b = 2;
       expect(scope.$eval('a+b')).toEqual(3);
       expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);
     
   *
   * @param {(string|function())=} expression An angular expression to be executed.
   *
   *    - `string`: execute using the rules as defined in  {@link guide/dev_guide.expressions expression}.
   *    - `function(scope)`: execute the function with the current `scope` parameter.
   *
   * @returns {*} The result of evaluating the expression.
   */
  $eval: function(expr) {
    var fn = isString(expr)
      ? parser(expr).statements()
      : expr || noop;
    return fn(this);
  },
  /**
   * @workInProgress
   * @ngdoc function
   * @name angular.scope.$apply
   * @function
   *
   * @description
   * `$apply()` is used to execute an expression in angular from outside of the angular framework.
   * (For example from browser DOM events, setTimeout, XHR or third party libraries).
   * Because we are calling into the angular framework we need to perform proper scope life-cycle
   * of {@link angular.service.$exceptionHandler exception handling},
   * {@link angular.scope.$digest executing watches} and scheduling
   * {@link angular.service.$updateView updating of the view} which in turn
   * {@link angular.scope.$digest executes observers} to update the DOM.
   *
   * ## Life cycle
   *
   * # Pseudo-Code of `$apply()`
      function $apply(expr) {
        try {
          return $eval(expr);
        } catch (e) {
          $exceptionHandler(e);
        } finally {
          $root.$digest();
          $updateView();
        }
      }
   *
   *
   * Scope's `$apply()` method transitions through the following stages:
   *
   * 1. The {@link guide/dev_guide.expressions expression} is executed using the
   *    {@link angular.scope.$eval $eval()} method.
   * 2. Any exceptions from the execution of the expression are forwarded to the
   *    {@link angular.service.$exceptionHandler $exceptionHandler} service.
   * 3. The {@link angular.scope.$watch watch} listeners are fired immediately after the expression
   *    was executed using the {@link angular.scope.$digest $digest()} method.
   * 4. A DOM update is scheduled using the {@link angular.service.$updateView $updateView} service.
   *    The `$updateView` may merge multiple update requests into a single update, if the requests
   *    are issued in close time proximity.
   * 6. The {@link angular.service.$updateView $updateView} service then fires DOM
   *    {@link angular.scope.$observe observers} using the {@link angular.scope.$flush $flush()}
   *    method.
   *
   *
   * @param {(string|function())=} exp An angular expression to be executed.
   *
   *    - `string`: execute using the rules as defined in {@link guide/dev_guide.expressions expression}.
   *    - `function(scope)`: execute the function with current `scope` parameter.
   *
   * @returns {*} The result of evaluating the expression.
   */
  $apply: function(expr) {
    try {
      return this.$eval(expr);
    } catch (e) {
      this.$service('$exceptionHandler')(e);
    } finally {
      this.$root.$digest();
      this.$service('$updateView')();
    }
  }
};
function compileToFn(exp, name) {
  var fn = isString(exp)
    ? parser(exp).statements()
    : exp;
  assertArgFn(fn, name);
  return fn;
}