$$AnimateAsyncRunFactoryProvider = function() {
  this.$get = ['$$rAF', function($$rAF) {
    var waitQueue = [];

    function waitForTick(fn) {
      waitQueue.push(fn);
      if (waitQueue.length > 1) return;
      $$rAF(function() {
        for (var i = 0; i < waitQueue.length; i++) {
          waitQueue[i]();
        }
        waitQueue = [];
      });
    }

    return function() {
      var passed = false;
      waitForTick(function() {
        passed = true;
      });
      return function(callback) {
        passed ? callback() : waitForTick(callback);
      };
    };
  }];
}
@ngdoc method
@name $animate#animate
@kind function

@description Performs an inline animation on the element which applies the provided to and from CSS styles to the element.
If any detected CSS transition, keyframe or JavaScript matches the provided className value, then the animation will take
on the provided styles. For example, if a transition animation is set for the given classNamem, then the provided `from` and
`to` styles will be applied alongside the given transition. If the CSS style provided in `from` does not have a corresponding
style in `to`, the style in `from` is applied immediately, and no animation is run.
If a JavaScript animation is detected then the provided styles will be given in as function parameters into the `animate`
method (or as part of the `options` parameter):

```js
ngModule.animation('.my-inline-animation', function() {
  return {
    animate : function(element, from, to, done, options) {
      //animation
      done();
    }
  }
});
```

@param {DOMElement} element the element which the CSS styles will be applied to
@param {object} from the from (starting) CSS styles that will be applied to the element and across the animation.
@param {object} to the to (destination) CSS styles that will be applied to the element and across the animation.
@param {string=} className an optional CSS class that will be applied to the element for the duration of the animation. If
   this value is left as empty then a CSS class of `ng-inline-animate` will be applied to the element.
   (Note that if no animation is detected then this value will not be applied to the element.)
@param {object=} options an optional collection of options/styles that will be applied to the element.
  The object can have the following properties:

  - **addClass** - `{string}` - space-separated CSS classes to add to element
  - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
  - **removeClass** - `{string}` - space-separated CSS classes to remove from element
  - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`

@return {Promise} the animation callback promise