src/ng-classified.js
function injectorInjectInvokers(injector) {
	var invoke_ = injector.invoke;

	injector.instantiate = instantiate;
	injector.invoke = invoke;

	return injector;

	// pasted method that picks up patched 'invoke'
	function instantiate(Type, locals, serviceName) {
		var instance = Object.create((Array.isArray(Type) ? Type[Type.length - 1] : Type).prototype || null);
		var returnedValue = invoke(Type, instance, locals, serviceName);

		return (returnedValue !== null && typeof returnedValue === 'object') || (typeof returnedValue === 'function') ? returnedValue : instance;
	}

	function invoke() {
		var argsLength = arguments.length;
		var args = new Array(argsLength);
		for (var i = 0; i < argsLength; i++) {
			args[i] = arguments[i];
		}

		var nativeClassRegex = /^class/;
		var classRegex = /class/i;

		var invokeResult;
		var fn = args[0];
		var skipClassify = !angular.isFunction(fn) || fn.hasOwnProperty('$$classified');

		if (!skipClassify) {
			if (fn.$classify || nativeClassRegex.test(fn.toString())) {
				classifyInvokee(args);
			} else if (this.$classify || (this.$classify !== false && classRegex.test(fn.toString()))) {
				try {
					invokeResult = apply(injector, invoke_, args);
					fn.$$classified = false;
				} catch (e) {
					if (e instanceof TypeError && classRegex.test(e.message)) {
						classifyInvokee(args);
					} else {
						throw e;
					}
				}
			}	
		}

		return invokeResult || apply(injector, invoke_, args);
	}

	function classifyInvokee(args) {
		var fn_ = args[0]; 

		var fn = args[0] = function () {
			var fnArgsLength = arguments.length + 1;
			var fnArgs = new Array(fnArgsLength);
			for (var i = 1; i < fnArgsLength; i++) {
				fnArgs[i] = arguments[i - 1];
			}

			// fnArgs[0] === undefined 
			return new (apply(fn_, Function.prototype.bind, fnArgs));
		};

		injector.annotate(fn_);
		fn.$inject = fn_.$inject;
		fn.$$classified = true;
	}
}
function injectorInjectInvokers(injector) {
	var invoke_ = injector.invoke;

	injector.instantiate = instantiate;
	injector.invoke = invoke;

	return injector;

	// pasted method that picks up patched 'invoke'
	function instantiate(Type, locals, serviceName) {
		var instance = Object.create((Array.isArray(Type) ? Type[Type.length - 1] : Type).prototype || null);
		var returnedValue = invoke(Type, instance, locals, serviceName);

		return (returnedValue !== null && typeof returnedValue === 'object') || (typeof returnedValue === 'function') ? returnedValue : instance;
	}

	function invoke() {
		var argsLength = arguments.length;
		var args = new Array(argsLength);
		for (var i = 0; i < argsLength; i++) {
			args[i] = arguments[i];
		}

		var nativeClassRegex = /^class/;
		var classRegex = /class/i;

		var invokeResult;
		var fn = args[0];
		var skipClassify = !angular.isFunction(fn) || fn.hasOwnProperty('$$classified');

		if (!skipClassify) {
			if (fn.$classify || nativeClassRegex.test(fn.toString())) {
				classifyInvokee(args);
			} else if (this.$classify || (this.$classify !== false && classRegex.test(fn.toString()))) {
				try {
					invokeResult = apply(injector, invoke_, args);
					fn.$$classified = false;
				} catch (e) {
					if (e instanceof TypeError && classRegex.test(e.message)) {
						classifyInvokee(args);
					} else {
						throw e;
					}
				}
			}	
		}

		return invokeResult || apply(injector, invoke_, args);
	}

	function classifyInvokee(args) {
		var fn_ = args[0]; 

		var fn = args[0] = function () {
			var fnArgsLength = arguments.length + 1;
			var fnArgs = new Array(fnArgsLength);
			for (var i = 1; i < fnArgsLength; i++) {
				fnArgs[i] = arguments[i - 1];
			}

			// fnArgs[0] === undefined 
			return new (apply(fn_, Function.prototype.bind, fnArgs));
		};

		injector.annotate(fn_);
		fn.$inject = fn_.$inject;
		fn.$$classified = true;
	}
}
function injectorInjectInvokers ( injector ) { var invoke_ = injector . invoke ; injector . instantiate = instantiate ; injector . invoke = invoke ; return injector ; // pasted method that picks up patched 'invoke'
 function instantiate ( Type , locals , serviceName ) { var instance = Object . create ( ( Array . isArray ( Type ) ? Type [ Type . length - 1 ] : Type ) . prototype || null ) ; var returnedValue = invoke ( Type , instance , locals , serviceName ) ; return ( returnedValue !== null && typeof returnedValue === 'object' ) || ( typeof returnedValue === 'function' ) ? returnedValue : instance ; } function invoke ( ) { var argsLength = arguments . length ; var args = new Array ( argsLength ) ; for ( var i = 0 ; i < argsLength ; i ++ ) { args [ i ] = arguments [ i ] ; } var nativeClassRegex = / ^class / ; var classRegex = / class / i ; var invokeResult ; var fn = args [ 0 ] ; var skipClassify = ! angular . isFunction ( fn ) || fn . hasOwnProperty ( '$$classified' ) ; if ( ! skipClassify ) { if ( fn . $classify || nativeClassRegex . test ( fn . toString ( ) ) ) { classifyInvokee ( args ) ; } else if ( this . $classify || ( this . $classify !== false && classRegex . test ( fn . toString ( ) ) ) ) { try { invokeResult = apply ( injector , invoke_ , args ) ; fn . $$classified = false ; } catch ( e ) { if ( e instanceof TypeError && classRegex . test ( e . message ) ) { classifyInvokee ( args ) ; } else { throw e ; } } } } return invokeResult || apply ( injector , invoke_ , args ) ; } function classifyInvokee ( args ) { var fn_ = args [ 0 ] ; var fn = args [ 0 ] = function ( ) { var fnArgsLength = arguments . length + 1 ; var fnArgs = new Array ( fnArgsLength ) ; for ( var i = 1 ; i < fnArgsLength ; i ++ ) { fnArgs [ i ] = arguments [ i - 1 ] ; } // fnArgs[0] === undefined 
 return new ( apply ( fn_ , Function . prototype . bind , fnArgs ) ) ; } ; injector . annotate ( fn_ ) ; fn . $inject = fn_ . $inject ; fn . $$classified = true ; } }
Invoker injects invokee,
Injector invokes injectee,
Morrow instantiates.
Invoker injects invokee Injector invokes injectee Morrow instantiates .