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<Type, dynamic> injecting}) {
      ClosureMirror closure = reflect(function);
  
      List positional = _getPositionalParameters(closure.function, injecting);
  
      return closure
          .apply(
          positional, _convertStringKeysToSymbols(namedParameters))
          .reflectee;
    }
  
    _make(Type type,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting) {
      try {
        var namedArguments = _convertStringKeysToSymbols(namedParameters);
  
        ClassMirror classMirror = reflectType(type);
  
        Symbol constructorSymbol;
  
        List positionalArguments;
  
        if (classMirror.declarations.containsKey(classMirror.simpleName)) {
          MethodMirror constructor =
          classMirror.declarations[classMirror.simpleName];
  
          positionalArguments = _getPositionalParameters(constructor, injecting);
  
          constructorSymbol = constructor.constructorName;
        } else {
          positionalArguments = [];
  
          constructorSymbol = const Symbol('');
        }
  
        final instance = (classMirror.newInstance(
            constructorSymbol,
            positionalArguments,
            namedArguments)
        ).reflectee;
  
        if (hasMethod(instance, r'$inject'))
          resolveMethod(instance, r'$inject',
              namedParameters: namedParameters,
              injecting: injecting);
  
        return instance;
      } on ContainerException catch (e) {
        throw new ContainerException(type, e);
      } on AbstractClassInstantiationError catch (e) {
        throw new ContainerException._finalize(type, e);
  
negative.code:     }
    }
  
    /// Turns a nullable map of named arguments and creates a new map
    /// with keys of type [Symbol]
    Map<Symbol, dynamic> _getNamedArguments([Map<String, dynamic> map]) {
      if (map == null) return {};
  
      final keys = map.keys.map((k) => new Symbol(k));
  
      return new Map.fromIterables(keys, map.values);
    }
  
    /// Resolves the arguments in a method signature into instances
    /// from the type declarations.
    Iterable _getPositionalParameters(MethodMirror method,
        Map<Type, dynamic> injecting) sync* {
      if (method == null) return;
  
      final positional = method.parameters.where((p) => !p.isNamed);
  
      for (final parameter in positional) {
        final type = _returnType(parameter);
  
        // If a replacement to this type was provided in the [injecting]
        // parameter then that object should be returned directly
        if (_existsAndContains(injecting, type)) yield injecting[type];
  
        // Otherwise a new instance of the type should be created
        else yield make(type, injecting: injecting);
      }
    }
  
    /// Gets the return type of a parameter
    _returnType(ParameterMirror parameter) {
      if (!parameter.type.hasReflectedType)
        throw new ArgumentError('Each parameter must be typed in '
            'order to resolve the method!');
  
      return parameter.type.reflectedType;
    }
  
    void _registerDecorator(Type target, Type decorator,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting) {
      // The decorator pattern requires the decorator pattern to
      // implement the interface it is decorating on
      if (!_isAssignableTo(decorator, target))
        throw new ArgumentError('The decorator must implement [$target].');
  
      // Ensure that there is a list of decorators for this type
      _decorators[target] ??= [];
  
      // Add the new decoration function to the list
      _decorators[target].add(
          _makeDecorationFunction(target, decorator, namedParameters, injecting)
      );
    }
  
    Function _makeDecorationFunction(Type target, Type decorator,
        Map<String, dynamic> namedParameters,
        Map<Type, dynamic> injecting) {
      // This function will be called when a new instance of the
      // target type has been created. The instance is passed in as
      // the [instance] argument.
      //
      // The function will then create a new instance of the decorator,
      // passing in the instance into the argument list, and then return
      // the decorated instance.
      return (Object instance) {
        // Create a map of temporary singletons
        final injections = new Map.from(injecting ?? {});
  
        // Add the base instance to the injections, by the type that is
        // being decorated
        injections[target] = instance;
  
        // Instantiate and return the decorator, passing in the base object
        // in the argument list.
        return make(decorator,
            injecting: injections,
            namedParameters: namedParameters);
      };
    }
  
    /// Takes an instance and passes it through a list of decoration
    /// functions that replaces it with a new decorator
    _applyDecorators(Object instance, List<Function> decorators) {
      return decorators.fold(instance, (i, f) => f(i));
    }
  
    /// Use [curry] instead
    @Deprecated('soon')
    presolve(_, {namedParameters, injecting}) {
      return curry(_, namedParameters: namedParameters, injecting: injecting);
    }
  }
  