docs: function createInternalInjector(cache, factory) {
  
      function getService(serviceName, caller) {
        if (cache.hasOwnProperty(serviceName)) {
          if (cache[serviceName] === INSTANTIATING) {
            throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
                      serviceName + ' <- ' + path.join(' <- '));
          }
          return cache[serviceName];
        } else {
          try {
            path.unshift(serviceName);
            cache[serviceName] = INSTANTIATING;
            return cache[serviceName] = factory(serviceName, caller);
          } catch (err) {
            if (cache[serviceName] === INSTANTIATING) {
              delete cache[serviceName];
            }
            throw err;
          } finally {
            path.shift();
          }
        }
      }
  
      function invoke(fn, self, locals, serviceName) {
        if (typeof locals === 'string') {
          serviceName = locals;
          locals = null;
        }
  
        var args = [],
            $inject = createInjector.$$annotate(fn, strictDi, serviceName),
            length, i,
            key;
  
        for (i = 0, length = $inject.length; i < length; i++) {
          key = $inject[i];
          if (typeof key !== 'string') {
            throw $injectorMinErr('itkn',
                    'Incorrect injection token! Expected service name as string, got {0}', key);
          }
          args.push(
            locals && locals.hasOwnProperty(key)
            ? locals[key]
            : getService(key, serviceName)
          );
        }
        if (isArray(fn)) {
          fn = fn[length];
        }
  
        // http://jsperf.com/angularjs-invoke-apply-vs-switch
        // #5388
        return fn.apply(self, args);
      }
  
      function instantiate(Type, locals, serviceName) {
        // Check if Type is annotated and use just the given function at n-1 as parameter
        // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
        // Object creation: http://jsperf.com/create-constructor/2
        var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype || null);
        var returnedValue = invoke(Type, instance, locals, serviceName);
  
        return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance;
      }
  
      return {
        invoke: invoke,
        instantiate: instantiate,
        get: getService,
        annotate: createInjector.$$annotate,
        has: function(name) {
          return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
        }
      };
    }