function bind(self, fn) {
  var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
  if (isFunction(fn) && !(fn instanceof RegExp)) {
    return curryArgs.length
      ? function() {
          return arguments.length
            ? fn.apply(self, curryArgs.concat(slice.call(arguments, 0)))
            : fn.apply(self, curryArgs);
        }
      : function() {
          return arguments.length
            ? fn.apply(self, arguments)
            : fn.call(self);
        };
  } else {
    // in IE, native methods are not functions so they cannot be bound (note: they don't need to be)
    return fn;
  }
}
@ngdoc function
@name angular.bind
@function

@description
Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
`fn`). You can supply optional `args` that are prebound to the function. This feature is also
known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).

@param {Object} self Context which `fn` should be evaluated in.
@param {function()} fn Function to be bound.
@param {...*} args Optional arguments to be prebound to the `fn` function call.
@returns {function()} Function that wraps the `fn` with all the specified bindings.