anchor.diff:  part of container;
   
   class _Container implements Container {
  +  /// Contains instances bound as singletons as types
     final Map<Type, dynamic> _singletons = {};
  +
  +  /// Contains types registered as replacements for other types
     final Map<Type, Type> _bindings = {};
  +
  +  /// Contains a list of decoration functions bound to types
     final Map<Type, List<Function>> _decorators = {};
   
     void bind(Type abstraction, Type implementation) {
  +    // This implementation will now replace the abstraction
  +    // when the abstraction is requested
       _bindings[abstraction] = implementation;
     }
   
     void singleton(Object singleton, {Type as}) {
  -    Type type = (as == null) ? singleton.runtimeType : as;
  -
  +    // Decide what type to bind the singleton to
  +    Type type = as ?? singleton.runtimeType;
  +
  +    // This instance will now be used for that type
       _singletons[type] = singleton;
  +  }
  +
  +  void decorate(Type target,
  +      {Type decorator,
  +      Iterable<Type> decorators,
  +      Map<String, dynamic> namedParameters,
  +      Map<Type, dynamic> injecting}) {
  +    // Create an iterable from the optional arguments
  +    // [decorator] and [decorators].
  +    final allDecorators = _merge(decorators, decorator);
  +
  +    if (allDecorators.isEmpty)
  +      throw new ArgumentError('At least one decorator must be provided.');
  +
  +    for (final decorator in allDecorators)
  +      _registerDecorator(target, decorator, namedParameters, injecting);
     }
   
     make(Type type,
         {Map<String, dynamic> namedParameters,
         Map<Type, dynamic> injecting}) {
  +    final instance = _getInstance(type, namedParameters, injecting);
  +
       final decorators = _decorators[type] ?? [];
  -
  -    if (_singletons.containsKey(type))
  -      return _applyDecorators(_singletons[type], decorators);
  -
  -    if (_bindings.containsKey(type)) type = _bindings[type];
  -
  -    return _applyDecorators(_make(type, namedParameters, injecting), decorators);
  +    return _applyDecorators(instance, decorators);
     }
   
     resolve(Function function,
  
positive.code:     }
    }
  
    Map<Symbol, dynamic> _convertStringKeysToSymbols(Map<String, dynamic> map) {
      if (map == null) return {};
  
      return new Map<Symbol, dynamic>.fromIterables(
          map.keys.map((String key) => new Symbol(key)), map.values);
    }
  
    List _getPositionalParameters(MethodMirror method,
        Map<Type, dynamic> injecting) {
      List positionalParameters = [];
  
      if (method == null) return positionalParameters;
  
      method.parameters.forEach((ParameterMirror parameter) {
        if (!parameter.isNamed) {
          if (!parameter.type
              .hasReflectedType) throw new ArgumentError(
              'Each parameter must be typed in order to resolve the method!');
  
          var type = parameter.type.reflectedType;
  
          if (injecting != null && injecting.containsKey(type)) {
            return positionalParameters.add(injecting[type]);
          }
  
          positionalParameters.add(make(type, injecting: injecting));
        }
      });
  
      return positionalParameters;
    }
  
    resolveMethod(Object object, String methodName,
        {Map<String, dynamic> namedParameters, Map<Type, dynamic> injecting}) {
      var symbol = new Symbol(methodName);
  
      var instance = reflect(object);
  
      var objectClass = instance.type;
  
      var method = objectClass.instanceMembers[symbol];
  
      var args = _getPositionalParameters(method, injecting);
  
      return instance
          .invoke(
          symbol, args, _convertStringKeysToSymbols(namedParameters))
          .reflectee;
    }
  
    bool hasMethod(Object object, String method) {
      return reflect(object).type.instanceMembers.containsKey(new Symbol(method));
    }
  
    Function curry(Function function,
        {Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting}) {
      return ([arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10]) {
        var arguments = [
          arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10]
            .where((a) => a != null);
  
        var argumentsWithTypes = ((injecting != null ? injecting : {}) as Map)
          ..addAll(new Map.fromIterables(
              arguments.map((a) => a.runtimeType),
              arguments));
  
        return resolve(function, injecting: argumentsWithTypes,
            namedParameters: namedParameters);
      };
    }
  
    void _decorate(Type target, Type decorator,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting) {
      if (!reflectType(decorator).isAssignableTo(reflectType(target)))
        throw new ArgumentError('The decorator must implement [$target].');
      _decorators[target] ??= [];
      _decorators[target].add((Object instance) {
        return make(decorator, injecting: new Map.from(injecting ?? {})
          ..addAll({
            target: instance
          }), namedParameters: namedParameters);
      });
    }
  
    void decorate(Type target,
        {Type decorator,
        Iterable<Type> decorators,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting}) {
      final allDecorators = []
        ..addAll(decorators ?? []);
      if (decorator != null)
        allDecorators.add(decorator);
      if (allDecorators.isEmpty)
        throw new ArgumentError('A decorator must be provided.');
      for(final decorator in allDecorators)
        _decorate(target, decorator, namedParameters, injecting);
    }
  
    _applyDecorators(Object instance, List<Function> decorators) {
      var _instance = instance;
      for (final decoratorFunction in decorators)
        _instance = decoratorFunction(_instance);
      return _instance;
    }
  }
  
negative.code:       Map<Type, dynamic> injecting}) {
      ClosureMirror closure = reflect(function);
  
      final positional = _getPositionalParameters(closure.function, injecting);
      final named = _getNamedArguments(namedParameters);
  
      return closure
          .apply(positional.toList(), named)
          .reflectee;
    }
  
    resolveMethod(Object object, String methodName,
        {Map<String, dynamic> namedParameters, Map<Type, dynamic> injecting}) {
      final symbol = new Symbol(methodName);
      final instance = reflect(object);
      final method = instance.type.instanceMembers[symbol];
  
      final positional = _getPositionalParameters(method, injecting);
      final named = _getNamedArguments(namedParameters);
  
      return instance
          .invoke(symbol, positional.toList(), named)
          .reflectee;
    }
  
    bool hasMethod(Object object, String method) {
      return reflect(object).type.instanceMembers.containsKey(new Symbol(method));
    }
  
    Function curry(Function function,
        {Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting}) {
      // Return a function that can take 0–10 arguments
      return ([_1, _2, _3, _4, _5, _6, _7, _8, _9, _10]) {
        // Turn the arguments that were actually supplied to a
        // map with their respective types as key
        final arguments = _mapTypes(
            [_1, _2, _3, _4, _5, _6, _7, _8, _9, _10]
                .where((a) => a != null)
        );
  
        // Create a new map that will contain the injections when the
        // curried function is called.
        Map<Type, dynamic> injections = new Map.from(injecting ?? {});
  
        // Add the arguments that was passed into the curried function
        // to the map of injections.
        injections.addAll(arguments);
  
        // Resolve the original function with the injections
        return resolve(function,
            injecting: injections,
            namedParameters: namedParameters);
      };
    }
  
    /// Turns an iterable into a map with the items' respective types
    /// as keys.
    Map<Type, dynamic> _mapTypes(Iterable instances) {
      final types = instances.map((i) => i.runtimeType);
      return new Map.fromIterables(types, instances);
    }
  
    /// Merges a maybe-iterable and a maybe-item to an iterable that's maybe empty
    Iterable _merge([Iterable iterable, item]) {
      return [iterable, item]
          .expand((e) => e is Iterable ? e : [e])
          .where((e) => e != null);
    }
  
    Object _getInstance(Type type,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting) {
      // If the type is registered as a singleton, that should be used
      if (_isSingleton(type)) return _singletons[type];
  
      // If this type has been bound to another implementation,
      // target that instead
      final implementationType = _isBound(type)
          ? _bindings[type]
          : type;
  
      // Create a new instance of the implementation type
      return _make(implementationType, namedParameters, injecting);
    }
  
    bool _isSingleton(Type type) => _singletons.containsKey(type);
  
    bool _isBound(Type type) => _bindings.containsKey(type);
  
    bool _hasConstructor(ClassMirror classMirror) =>
        classMirror.declarations.containsKey(classMirror.simpleName);
  
    MethodMirror _getConstructor(ClassMirror classMirror) =>
        classMirror.declarations[classMirror.simpleName];
  
    bool _existsAndContains(Map map, item) =>
        map != null && map.containsKey(item);
  
    bool _isAssignableTo(Type from, Type to) =>
        reflectType(from).isAssignableTo(reflectType(to));
  
    _make(Type type,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting) {
      return _catchWhileInstantiating(type, () {
        final ClassMirror classMirror = reflectType(type);
  
        // If the class doesn't have a default constructor the call should be
        // a call with no arguments passed to method with empty symbol
        if (!_hasConstructor(classMirror)) {
          return _instantiate(
              classMirror,
              const Symbol(''),
              [],
              namedParameters,
              injecting);
        }
  
        final constructor = _getConstructor(classMirror);
        return _instantiate(
            classMirror,
            constructor.constructorName,
            _getPositionalParameters(constructor, injecting),
            namedParameters,
            injecting);
      });
    }
  
    /// Creates a new instance of a class, and directly afterwards
    /// runs the $inject method if it exists on the class
    _instantiate(ClassMirror classMirror,
        Symbol constructorSymbol,
        Iterable positionalArguments,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting) {
      final namedArguments = _getNamedArguments(namedParameters);
  
      // Perform the instantiation
      final instance = (classMirror.newInstance(
          constructorSymbol,
          positionalArguments.toList(),
          namedArguments)
      ).reflectee;
  
      // Resolve $inject if exists
      _resolve$injectMethod(instance, namedParameters, injecting);
  
      return instance;
    }
  
    void _resolve$injectMethod(Object instance,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting) {
      if (hasMethod(instance, r'$inject'))
        resolveMethod(instance, r'$inject',
            namedParameters: namedParameters,
            injecting: injecting);
    }
  
    /// Catches all [AbstractClassInstantiationError] and [NoSuchMethodError]
    /// and wraps them in a chain of container exceptions which propagate
    /// out to the initial call
    _catchWhileInstantiating(Type type, callback()) {
      try {
        return callback();
      } on ContainerException catch (e) {
        // Propagates a nested [make] call failure, adding this type
        // To the chain ("couldn't create X because: couldn't create Y...")
        throw new ContainerException(type, e);
      } on AbstractClassInstantiationError catch (e) {
        throw new ContainerException._finalize(type, e);
  