/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FRUIT_COMPONENT_FUNCTORS_DEFN_H
#define FRUIT_COMPONENT_FUNCTORS_DEFN_H

#include <fruit/component.h>

#include <fruit/impl/injection_errors.h>
#include <fruit/impl/injection_debug_errors.h>
#include <fruit/impl/storage/component_storage.h>
#include <fruit/impl/storage/injector_storage.h>

#include <memory>

/*********************************************************************************************************************************
  This file contains functors that take a Comp and return a struct Op with the form:
  struct {
    using Result = Comp1;
    void operator()(ComponentStorage& storage) {...}
  }
*********************************************************************************************************************************/

namespace fruit {
namespace impl {
namespace meta {

struct GetResult {
  template <typename F>
  struct apply {
    using type = typename F::Result;
  };
};

// Call(ComponentFunctor(F, Args...), Comp)
// is equivalent to:
// F(Comp, Args...)
struct ComponentFunctor {
  template <typename F, typename... Args>
  struct apply {
    struct type {
      template <typename Comp>
      struct apply {
        using type = F(Comp, Args...);
      };
    };
  };
};

struct NoOpComponentFunctor {
  using Result = void;
  template <typename... Types>
  void operator()(ComponentStorage&, const Types&...) {}
};

struct ComponentFunctorIdentity {
  template <typename Comp>
  struct apply {
    struct type {
      using Result = Comp;
      void operator()(ComponentStorage&) {}
    };
  };
};

struct Compose2ComponentFunctors {
  template <typename F1, typename F2>
  struct apply {
    struct type {
      template <typename Comp>
      struct apply {
        using Op1 = F1(Comp);
        using Op2 = F2(GetResult(Op1));
        struct Op {
          using Result = Eval<GetResult(Op2)>;
          void operator()(ComponentStorage& storage) {
            Eval<Op1>()(storage);
            Eval<Op2>()(storage);
          }
        };
        using type = PropagateError(Op1,
                     PropagateError(Op2,
                     Op));
      };
    };
  };
};

// ComposeFunctors(F1,..,Fn) returns a functor that executes F1,..,Fn in order (stopping at the
// first Error).
struct ComposeFunctors {
  template <typename... Functors>
  struct apply {    
    using type = Fold(Compose2ComponentFunctors, ComponentFunctorIdentity, Functors...);
  };
};

// ReverseComposeFunctors(T1, ..., Tn) is equivalent to ComposeFunctors(Tn, ..., T1), but it's more
// efficient when all of the following must be evaluated:
// ReverseComposeFunctors<T1>
// ReverseComposeFunctors<T2, T1>
// ReverseComposeFunctors<T3, T2, T1>
// In that case, this implementation shares many more instantiations with previous invocations
struct ReverseComposeFunctors {
  template <typename... Functors>
  struct apply {
    using type = ComponentFunctorIdentity;
  };
  
  template <typename Functor>
  struct apply<Functor> {
    using type = Functor;
  };
  
  template <typename Functor, typename... Functors>
  struct apply<Functor, Functors...> {
    using type = Compose2ComponentFunctors(ReverseComposeFunctors(Functors...), Functor);
  };
};

struct EnsureProvidedType;

struct EnsureProvidedTypes;

// Doesn't actually bind in ComponentStorage. The binding is added later (if needed) using ProcessInterfaceBinding.
struct AddDeferredInterfaceBinding {
  template <typename Comp, typename AnnotatedI, typename AnnotatedC>
  struct apply {
    using Comp1 = ConsComp(typename Comp::RsSuperset,
                           typename Comp::Ps,
#ifndef FRUIT_NO_LOOP_CHECK
                           typename Comp::Deps,
#endif
                           PushFront(typename Comp::InterfaceBindings,
                                     Pair<AnnotatedI, AnnotatedC>),
                           typename Comp::DeferredBindingFunctors);
    struct Op {
      // Note that we do NOT call AddProvidedType here. We'll only know the right required type
      // when the binding will be used.
      using Result = Eval<Comp1>;
      void operator()(ComponentStorage&) {}
    };
    using I = RemoveAnnotations(AnnotatedI);
    using C = RemoveAnnotations(AnnotatedC);
    using type = If(IsSame(I, C),
                    ConstructError(InterfaceBindingToSelfErrorTag, C),
                 If(Not(IsBaseOf(I, C)),
                    ConstructError(NotABaseClassOfErrorTag, I, C),
                 If(Not(IsSame(I, NormalizeType(I))),
                    ConstructError(NonClassTypeErrorTag, I, NormalizeType(I)),
                 If(Not(IsSame(C, NormalizeType(C))),
                    // We handle this case too, just to be on the safe side, but this should never happen.
                    ConstructError(NonClassTypeErrorTag, C, NormalizeType(C)),
                 If(IsInSet(AnnotatedI, typename Comp::Ps),
                    ConstructError(TypeAlreadyBoundErrorTag, AnnotatedI),
                 If(MapContainsKey(typename Comp::InterfaceBindings, AnnotatedI),
                    ConstructError(TypeAlreadyBoundErrorTag, AnnotatedI),
                 Op))))));
  };
};

struct ProcessInterfaceBinding {
  template <typename Comp, typename AnnotatedI, typename AnnotatedC>
  struct apply {
    using R = AddProvidedTypeIgnoringInterfaceBindings(Comp, AnnotatedI, Vector<AnnotatedC>);
    struct Op {
      // This must be here (and not in AddDeferredInterfaceBinding) because the binding might be
      // used to bind functors instead, so we might never need to add C to the requirements.
      using Result = Eval<R>;
      void operator()(ComponentStorage& storage) {
        storage.addBinding(InjectorStorage::createBindingDataForBind<
            UnwrapType<AnnotatedI>, UnwrapType<AnnotatedC>>());
      };
    };
    using type = PropagateError(R,
                 Op);
  };
};

struct AddInterfaceMultibinding {
  template <typename Comp, typename AnnotatedI, typename AnnotatedC>
  struct apply {
    using I = RemoveAnnotations(AnnotatedI);
    using C = RemoveAnnotations(AnnotatedC);
    using R = AddRequirements(Comp, Vector<AnnotatedC>);
    struct Op {
      using Result = Eval<R>;
      void operator()(ComponentStorage& storage) {
        storage.addMultibinding(InjectorStorage::createMultibindingDataForBinding<
            UnwrapType<AnnotatedI>, UnwrapType<AnnotatedC>>());
      };
    };
    using type = If(Not(IsBaseOf(I, C)),
                    ConstructError(NotABaseClassOfErrorTag, I, C),
                 Op);
  };
};

template <typename AnnotatedSignature, typename Lambda, typename OptionalAnnotatedI>
struct PostProcessRegisterProviderHelper;

template <typename AnnotatedSignature, typename Lambda, typename AnnotatedI>
struct PostProcessRegisterProviderHelper;

template <typename AnnotatedSignature, typename Lambda, typename AnnotatedI>
struct PostProcessRegisterProviderHelper<AnnotatedSignature, Lambda, Type<AnnotatedI>> {
  inline void operator()(ComponentStorage& component) {
    component.addBinding(InjectorStorage::createBindingDataForProvider<
        AnnotatedSignature, Lambda>());
    component.addCompressedBinding(InjectorStorage::createBindingDataForCompressedProvider<
        AnnotatedSignature, Lambda, AnnotatedI>());
  }
};

template <typename AnnotatedSignature, typename Lambda>
struct PostProcessRegisterProviderHelper<AnnotatedSignature, Lambda, None> {
  inline void operator()(ComponentStorage& component) {
    component.addBinding(InjectorStorage::createBindingDataForProvider<
        AnnotatedSignature, Lambda>());
  }
};

// T can't be any injectable type, it must match the return type of the provider in one of
// the registerProvider() overloads in ComponentStorage.
struct PostProcessRegisterProvider {
  template <typename Comp, typename AnnotatedSignature, typename Lambda>
  struct apply {
    using AnnotatedC = NormalizeType(SignatureType(AnnotatedSignature));
    using OptionalAnnotatedI = FindValueInMap(typename Comp::InterfaceBindings, AnnotatedC);
    struct Op {
      using Result = Comp;
      void operator()(ComponentStorage& storage) {
        PostProcessRegisterProviderHelper<
            UnwrapType<AnnotatedSignature>, UnwrapType<Lambda>, Eval<OptionalAnnotatedI>>()(storage);
      }
    };
    using type = Op;
  };
};

struct PreProcessRegisterProvider {
  template <typename Comp, typename AnnotatedSignature, typename Lambda>
  struct apply {
    using Signature = RemoveAnnotationsFromSignature(AnnotatedSignature);
    using SignatureFromLambda = FunctionSignature(Lambda);
    
    using AnnotatedC = NormalizeType(SignatureType(AnnotatedSignature));
    using AnnotatedCDeps = ExpandProvidersInParams(NormalizeTypeVector(SignatureArgs(AnnotatedSignature)));
    using R = AddProvidedType(Comp, AnnotatedC, AnnotatedCDeps);
    using type = If(Not(IsSame(Signature, SignatureFromLambda)),
                   ConstructError(AnnotatedSignatureDifferentFromLambdaSignatureErrorTag, Signature, SignatureFromLambda),
                 ComponentFunctorIdentity(R));
  };
};

// The registration is actually deferred until the PartialComponent is converted to a component.
struct DeferredRegisterProviderWithAnnotations {
  template <typename Comp, typename AnnotatedSignature, typename Lambda>
  struct apply {
    using Comp1 = AddDeferredBinding(Comp, 
                                     ComponentFunctor(PostProcessRegisterProvider, AnnotatedSignature, Lambda));
    using type = PreProcessRegisterProvider(Comp1, AnnotatedSignature, Lambda);
  };
};

// The registration is actually deferred until the PartialComponent is converted to a component.
struct DeferredRegisterProvider {
  template <typename Comp, typename Lambda>
  struct apply {
    using type = DeferredRegisterProviderWithAnnotations(Comp, FunctionSignature(Lambda), Lambda);
  };
};

// T can't be any injectable type, it must match the return type of the provider in one of
// the registerMultibindingProvider() overloads in ComponentStorage.
struct RegisterMultibindingProviderWithAnnotations {
  template <typename Comp, typename AnnotatedSignature, typename Lambda>
  struct apply {
    using Signature = RemoveAnnotationsFromSignature(AnnotatedSignature);
    using SignatureFromLambda = FunctionSignature(Lambda);
    
    using AnnotatedArgs = SignatureArgs(AnnotatedSignature);
    using AnnotatedArgVector = ExpandProvidersInParams(NormalizeTypeVector(AnnotatedArgs));
    using R = AddRequirements(Comp, AnnotatedArgVector);
    struct Op {
      using Result = Eval<R>;
      void operator()(ComponentStorage& storage) {
        auto multibindingData = InjectorStorage::createMultibindingDataForProvider<
            UnwrapType<AnnotatedSignature>, UnwrapType<Lambda>>();
        storage.addMultibinding(multibindingData);
      }
    };
    using type = If(Not(IsValidSignature(AnnotatedSignature)),
                    ConstructError(NotASignatureErrorTag, AnnotatedSignature),
                 If(IsAbstract(RemoveAnnotations(SignatureType(AnnotatedSignature))),
                    ConstructError(CannotConstructAbstractClassErrorTag, RemoveAnnotations(SignatureType(AnnotatedSignature))),
                 If(Not(IsSame(Signature, SignatureFromLambda)),
                    ConstructError(AnnotatedSignatureDifferentFromLambdaSignatureErrorTag, Signature, SignatureFromLambda),
                 PropagateError(R,
                 Op))));
  };
};

// T can't be any injectable type, it must match the return type of the provider in one of
// the registerMultibindingProvider() overloads in ComponentStorage.
struct RegisterMultibindingProvider {
  template <typename Comp, typename Lambda>
  struct apply {
    using type = RegisterMultibindingProviderWithAnnotations(Comp, FunctionSignature(Lambda), Lambda);
  };
};

// Non-assisted case.
template <int numAssistedBefore, int numNonAssistedBefore, typename Arg>
struct GetAssistedArg {
  template <typename InjectedArgsTuple, typename UserProvidedArgsTuple>
  inline Arg operator()(InjectedArgsTuple& injected_args, UserProvidedArgsTuple&) {
    return std::get<numNonAssistedBefore>(injected_args);
  }
};

// Assisted case.
template <int numAssistedBefore, int numNonAssistedBefore, typename Arg>
struct GetAssistedArg<numAssistedBefore, numNonAssistedBefore, Assisted<Arg>> {
	template <typename InjectedArgsTuple, typename UserProvidedArgsTuple>
	inline Arg operator()(InjectedArgsTuple&, UserProvidedArgsTuple& user_provided_args) {
    return std::get<numAssistedBefore>(user_provided_args);
  }
};

struct RegisterFactoryHelper {
  
  template <typename Comp,
            typename DecoratedSignature,
            typename Lambda,
            // std::function<InjectedSignature> is the injected type (possibly with an Annotation<> wrapping it)
            typename InjectedSignature,
            typename RequiredLambdaSignature,
            typename InjectedAnnotatedArgs,
            // The types that are injected, unwrapped from any Annotation<>.
            typename InjectedArgs,
            typename IndexSequence>
  struct apply;
  
  template <typename Comp, typename DecoratedSignature, typename Lambda, typename NakedC, 
      typename... NakedUserProvidedArgs, typename... NakedAllArgs, typename... InjectedAnnotatedArgs,
      typename... NakedInjectedArgs, typename... Indexes>
  struct apply<Comp, DecoratedSignature, Lambda, Type<NakedC(NakedUserProvidedArgs...)>,
               Type<NakedC(NakedAllArgs...)>, Vector<InjectedAnnotatedArgs...>,
               Vector<Type<NakedInjectedArgs>...>, Vector<Indexes...>> {
    // Here we call "decorated" the types that might be wrapped in Annotated<> or Assisted<>,
    // while we call "annotated" the ones that might only be wrapped in Annotated<> (but not Assisted<>).
    using AnnotatedT = SignatureType(DecoratedSignature);
    using T          = RemoveAnnotations(AnnotatedT);
    using DecoratedArgs = SignatureArgs(DecoratedSignature);
    using NakedInjectedSignature = NakedC(NakedUserProvidedArgs...);
    using NakedRequiredSignature = NakedC(NakedAllArgs...);
    using NakedFunctor = std::function<NakedInjectedSignature>;
    // This is usually the same as Functor, but this might be annotated.
    using AnnotatedFunctor = CopyAnnotation(AnnotatedT, Type<NakedFunctor>);
    using FunctorDeps = NormalizeTypeVector(Vector<InjectedAnnotatedArgs...>);
    using R = AddProvidedType(Comp, AnnotatedFunctor, FunctorDeps);
    struct Op {
      using Result = Eval<R>;
      void operator()(ComponentStorage& storage) {
        auto function_provider = [](NakedInjectedArgs... args) {
          // TODO: Using auto and make_tuple here results in a GCC segfault with GCC 4.8.1.
          // Check this on later versions and consider filing a bug.
          std::tuple<NakedInjectedArgs...> injected_args(args...);
          auto object_provider = [injected_args](NakedUserProvidedArgs... params) mutable {
            auto user_provided_args = std::tie(params...);
			// These are unused if they are 0-arg tuples. Silence the unused-variable warnings anyway.
			(void) injected_args;
			(void) user_provided_args;

			return LambdaInvoker::invoke<UnwrapType<Lambda>, NakedAllArgs...>(
				GetAssistedArg<
				  Eval<NumAssistedBefore(Indexes, DecoratedArgs)>::value,
				  Indexes::value - Eval<NumAssistedBefore(Indexes, DecoratedArgs)>::value,
				  // Note that the Assisted<> wrapper (if any) remains, we just remove any wrapping Annotated<>.
				  UnwrapType<Eval<RemoveAnnotations(GetNthType(Indexes, DecoratedArgs))>>
				>()(injected_args, user_provided_args)...);
		  };
          return NakedFunctor(object_provider);
        };
        storage.addBinding(InjectorStorage::createBindingDataForProvider<
            UnwrapType<Eval<ConsSignatureWithVector(AnnotatedFunctor, Vector<InjectedAnnotatedArgs...>)>>,
            decltype(function_provider)>());
      }
    };
    // The first two IsValidSignature checks are a bit of a hack, they are needed to make the F2/RealF2 split
    // work in the caller (we need to allow Lambda to be a function type).
    using type = If(Not(Or(IsEmpty(Lambda), IsValidSignature(Lambda))),
                    ConstructError(LambdaWithCapturesErrorTag, Lambda),
                 If(Not(Or(IsTriviallyCopyable(Lambda), IsValidSignature(Lambda))),
                    ConstructError(NonTriviallyCopyableLambdaErrorTag, Lambda),
                 If(Not(IsSame(Type<NakedRequiredSignature>, FunctionSignature(Lambda))),
                    ConstructError(FunctorSignatureDoesNotMatchErrorTag, Type<NakedRequiredSignature>, FunctionSignature(Lambda)),
                 If(IsPointer(T),
                    ConstructError(FactoryReturningPointerErrorTag, DecoratedSignature),
                 PropagateError(R,
                 Op)))));
  };
};

struct RegisterFactory {
  template <typename Comp, typename DecoratedSignature, typename Lambda>
  struct apply {
    using type = If(Not(IsValidSignature(DecoratedSignature)),
                    ConstructError(NotASignatureErrorTag, DecoratedSignature),
                 If(IsAbstract(RemoveAnnotations(SignatureType(DecoratedSignature))),
                    // We error out early in this case. Calling RegisterFactoryHelper would also produce an error, but it'd be
                    // much less user-friendly.
                    ConstructError(CannotConstructAbstractClassErrorTag, RemoveAnnotations(SignatureType(DecoratedSignature))),
                 RegisterFactoryHelper(Comp,
                                       DecoratedSignature,
                                       Lambda,
                                       InjectedSignatureForAssistedFactory(DecoratedSignature),
                                       RequiredLambdaSignatureForAssistedFactory(DecoratedSignature),
                                       RemoveAssisted(SignatureArgs(DecoratedSignature)),
                                       RemoveAnnotationsFromVector(RemoveAssisted(SignatureArgs(DecoratedSignature))),
                                       GenerateIntSequence(
                                          VectorSize(RequiredLambdaArgsForAssistedFactory(DecoratedSignature))))));
  };
};

struct PostProcessRegisterConstructor;

template <typename AnnotatedSignature, typename OptionalAnnotatedI>
struct PostProcessRegisterConstructorHelper;

template <typename AnnotatedSignature, typename AnnotatedI>
struct PostProcessRegisterConstructorHelper;

template <typename AnnotatedSignature, typename AnnotatedI>
struct PostProcessRegisterConstructorHelper<AnnotatedSignature, Type<AnnotatedI>> {
  inline void operator()(ComponentStorage& component) {
    component.addBinding(InjectorStorage::createBindingDataForConstructor<AnnotatedSignature>());
    component.addCompressedBinding(InjectorStorage::createBindingDataForCompressedConstructor<AnnotatedSignature, AnnotatedI>());
  }
};

template <typename AnnotatedSignature>
struct PostProcessRegisterConstructorHelper<AnnotatedSignature, None> {
  inline void operator()(ComponentStorage& component) {
    component.addBinding(InjectorStorage::createBindingDataForConstructor<AnnotatedSignature>());
  }
};

struct PostProcessRegisterConstructor {
  template <typename Comp, typename AnnotatedSignature>
  struct apply {
    struct type {
      using AnnotatedC = NormalizeType(SignatureType(AnnotatedSignature));
      using Result = Comp;
      void operator()(ComponentStorage& storage) {
        PostProcessRegisterConstructorHelper<
            UnwrapType<AnnotatedSignature>,
            Eval<FindValueInMap(typename Comp::InterfaceBindings, AnnotatedC)>
            >()(storage);
      }
    };
  };
};

struct PreProcessRegisterConstructor {
  template <typename Comp, typename AnnotatedSignature>
  struct apply {
    using Signature = RemoveAnnotationsFromSignature(AnnotatedSignature);
    using C = SignatureType(Signature);
    using Args = SignatureArgs(Signature);
    using AnnotatedT    = SignatureType(AnnotatedSignature);
    using AnnotatedArgs = SignatureArgs(AnnotatedSignature);
    using AnnotatedC = NormalizeType(AnnotatedT);
    using CDeps = ExpandProvidersInParams(NormalizeTypeVector(AnnotatedArgs));
    using R = AddProvidedType(Comp, AnnotatedC, CDeps);
    using type = If(Not(IsValidSignature(AnnotatedSignature)),
                    ConstructError(NotASignatureErrorTag, AnnotatedSignature),
                 If(IsAbstract(RemoveAnnotations(SignatureType(AnnotatedSignature))),
                    ConstructError(CannotConstructAbstractClassErrorTag, RemoveAnnotations(SignatureType(AnnotatedSignature))),
                 If(Not(IsConstructibleWithVector(C, Args)),
                    ConstructError(NoConstructorMatchingInjectSignatureErrorTag, C, Signature),
                 PropagateError(R,
                 ComponentFunctorIdentity(R)))));
  };
};

struct DeferredRegisterConstructor {
  template <typename Comp, typename AnnotatedSignature>
  struct apply {
    using Comp1 = AddDeferredBinding(Comp,
                                     ComponentFunctor(PostProcessRegisterConstructor, AnnotatedSignature));
    using type = PreProcessRegisterConstructor(Comp1, AnnotatedSignature);
  };
};

struct RegisterInstance {
  template <typename Comp, typename AnnotatedC, typename C>
  struct apply {
    using R = AddProvidedType(Comp, AnnotatedC, Vector<>);
    struct Op {
      using Result = Eval<R>;
      void operator()(ComponentStorage&) {}
    };
    using type = If(Not(IsSame(C, NormalizeType(C))),
                    ConstructError(NonClassTypeErrorTag, C, NormalizeType(C)),
                 If(Not(IsSame(RemoveAnnotations(AnnotatedC), NormalizeType(RemoveAnnotations(AnnotatedC)))),
                    ConstructError(NonClassTypeErrorTag, RemoveAnnotations(AnnotatedC), NormalizeType(RemoveAnnotations(C))),
                 // The IsSame check is not redundant because IsBaseOf returns false for non-class types (e.g. int).
                 If(Not(Or(IsSame(RemoveAnnotations(AnnotatedC), C),
                           IsBaseOf(RemoveAnnotations(AnnotatedC), C))),
                    ConstructError(TypeMismatchInBindInstanceErrorTag, RemoveAnnotations(AnnotatedC), C),
                 PropagateError(R,
                 Op))));
  };
};

struct RegisterConstructorAsValueFactory {
  template<typename Comp, 
           typename DecoratedSignature, 
           typename RequiredSignature = 
               Eval<RequiredLambdaSignatureForAssistedFactory(DecoratedSignature)>>
  struct apply;
  
  template <typename Comp, typename DecoratedSignature, typename NakedT, typename... NakedArgs>
  struct apply<Comp, DecoratedSignature, Type<NakedT(NakedArgs...)>> {
    using RequiredSignature = Type<NakedT(NakedArgs...)>;
    using Op1 = RegisterFactory(Comp, DecoratedSignature, RequiredSignature);
    struct Op {
      using Result = Eval<GetResult(Op1)>;
      void operator()(ComponentStorage& storage) {
        auto provider = [](NakedArgs... args) {
          return NakedT(std::forward<NakedArgs>(args)...);
        };
        using RealOp = RegisterFactory(Comp, DecoratedSignature, Type<decltype(provider)>);
        FruitStaticAssert(IsSame(GetResult(Op1),
                                 GetResult(RealOp)));
        Eval<RealOp>()(storage);
      }
    };
    using type = PropagateError(Op1,
                 Op);
  };
};


struct RegisterConstructorAsUniquePtrFactory {
  template<typename Comp, 
           typename DecoratedSignature, 
           typename RequiredSignature = 
               Eval<RequiredLambdaSignatureForAssistedFactory(DecoratedSignature)>>
  struct apply;
  
  template <typename Comp, typename DecoratedSignature, typename NakedT, typename... NakedArgs>
  struct apply<Comp, DecoratedSignature, Type<std::unique_ptr<NakedT>(NakedArgs...)>> {
    using RequiredSignature = Type<std::unique_ptr<NakedT>(NakedArgs...)>;
    using Op1 = RegisterFactory(Comp, DecoratedSignature, RequiredSignature);
    struct Op {
      using Result = Eval<GetResult(Op1)>;
      void operator()(ComponentStorage& storage) {
        auto provider = [](NakedArgs... args) {
          return std::unique_ptr<NakedT>(new NakedT(std::forward<NakedArgs>(args)...));
        };
        using RealOp = RegisterFactory(Comp, DecoratedSignature, Type<decltype(provider)>);
        FruitStaticAssert(IsSame(GetResult(Op1),
                                 GetResult(RealOp)));
        Eval<RealOp>()(storage);
      };
    };
    
    using type = PropagateError(Op1,
                 Op);
  };
};

struct InstallComponent {
  template <typename Comp, typename OtherComp>
  struct apply {
    using new_RsSuperset = SetUnion(typename OtherComp::RsSuperset,
                                    typename Comp::RsSuperset);
    using new_Ps = SetUncheckedUnion(typename OtherComp::Ps,
                                     typename Comp::Ps);
#ifndef FRUIT_NO_LOOP_CHECK
    using new_Deps = ConcatVectors(typename OtherComp::Deps,
                                   typename Comp::Deps);
#endif
    FruitStaticAssert(IsSame(typename OtherComp::InterfaceBindings, Vector<>));
    using new_InterfaceBindings = typename Comp::InterfaceBindings;
    
    FruitStaticAssert(IsSame(typename OtherComp::DeferredBindingFunctors, EmptyList));
    using new_DeferredBindingFunctors = typename Comp::DeferredBindingFunctors;
    
    using R = ConsComp(new_RsSuperset, new_Ps, 
#ifndef FRUIT_NO_LOOP_CHECK
                       new_Deps, 
#endif
                       new_InterfaceBindings, new_DeferredBindingFunctors);
    struct Op {
      using Result = Eval<R>;
      void operator()(ComponentStorage&) {}
    };
    using InterfacePs = VectorToSetUnchecked(GetMapKeys(typename Comp::InterfaceBindings));
    using AllPs = SetUncheckedUnion(InterfacePs, typename Comp::Ps);
    using DuplicateTypes = SetIntersection(typename OtherComp::Ps,
                                           AllPs);
    using type = If(Not(IsDisjoint(typename OtherComp::Ps, AllPs)),
                    ConstructErrorWithArgVector(DuplicateTypesInComponentErrorTag, 
                                                SetToVector(DuplicateTypes)),
                 Op);
  };
};

struct InstallComponentHelper {
  template <typename Comp, typename... OtherCompParams>
  struct apply {
    using OtherComp = ConstructComponentImpl(OtherCompParams...);
    using type = InstallComponent(Comp, OtherComp);
  };
};

struct ConvertComponent {
  template <typename SourceComp, typename DestComp>
  struct apply {
    // We need to register:
    // * All the types provided by the new component
    // * All the types required by the old component
    // except:
    // * The ones already provided by the old component.
    // * The ones required by the new one.
    using SourcePs = typename SourceComp::Ps;
    using DestPs   = typename   DestComp::Ps;
    using SourceRs = SetDifference(typename SourceComp::RsSuperset, typename SourceComp::Ps);
    using DestRs   = SetDifference(typename   DestComp::RsSuperset, typename   DestComp::Ps);
    using ToRegister = SetDifference(SetUnion(DestPs, SourceRs),
                                     SetUnion(DestRs, SourcePs));    
    using type = EnsureProvidedTypes(SourceComp, DestRs, SetToVector(ToRegister));
    
    // Not needed, just double-checking.
    // Uses FruitStaticAssert instead of FruitDelegateCheck so that it's checked only in debug mode.
#ifdef FRUIT_EXTRA_DEBUG
    FruitDelegateCheck(CheckComponentEntails(GetResult(type), DestComp));
#endif // FRUIT_EXTRA_DEBUG
  };
};

struct ProcessDeferredBindings {
  template <typename Comp>
  struct apply;
  
  template <typename RsSupersetParam, typename PsParam, 
#ifndef FRUIT_NO_LOOP_CHECK
            typename DepsParam, 
#endif
            typename InterfaceBindingsParam, typename DeferredBindingFunctors>
  struct apply<Comp<RsSupersetParam, PsParam, 
#ifndef FRUIT_NO_LOOP_CHECK
                    DepsParam, 
#endif
                    InterfaceBindingsParam, DeferredBindingFunctors>> {
    // Comp1 is the same as Comp, but without the DeferredBindingFunctors.
    using Comp1 = ConsComp(RsSupersetParam, PsParam, 
#ifndef FRUIT_NO_LOOP_CHECK
                           DepsParam, 
#endif
                           InterfaceBindingsParam, EmptyList);
    using type = Call(FoldList(DeferredBindingFunctors, Compose2ComponentFunctors, ComponentFunctorIdentity),
                      Comp1);
  };
};

template <typename AnnotatedCFunctor, typename AnnotatedCUniquePtrFunctor>
struct AutoRegisterFactoryHelperErrorHandler {
  template <typename E>
  struct apply {
    using type = E;
  };

  template <typename T>
  struct apply<Error<NoBindingFoundErrorTag, T>> {
    using type = If(IsSame(Type<T>, AnnotatedCFunctor),
                    ConstructNoBindingFoundError(AnnotatedCUniquePtrFunctor),
                    ConstructError(NoBindingFoundErrorTag, Type<T>));
  };

  template <typename T1, typename T2>
  struct apply<Error<NoBindingFoundForAbstractClassErrorTag, T1, T2>> {
    using type = If(IsSame(Type<T1>, AnnotatedCFunctor),
                    ConstructNoBindingFoundError(AnnotatedCUniquePtrFunctor),
                    ConstructError(NoBindingFoundForAbstractClassErrorTag, Type<T1>, Type<T2>));
  };
};

struct AutoRegisterFactoryHelper {
  
  // General case, no way to bind it.
  template <typename Comp, typename TargetRequirements, typename InterfaceBinding, 
            typename has_inject_annotation, typename is_abstract, typename C,
            typename AnnotatedSignature, typename... Args>
  struct apply {
    using AnnotatedC        = SignatureType(AnnotatedSignature);
    using CFunctor          = ConsStdFunction(RemoveAnnotationsFromSignature(AnnotatedSignature));
    using AnnotatedCFunctor = CopyAnnotation(AnnotatedC, CFunctor);
    using type = If(IsAbstract(C),
                    ConstructError(NoBindingFoundForAbstractClassErrorTag, AnnotatedCFunctor, C),
                 ConstructError(NoBindingFoundErrorTag, AnnotatedCFunctor));
  };

  // No way to bind it (we need this specialization too to ensure that the specialization below
  // is not chosen for AnnotatedC=None).
  template <typename Comp, typename TargetRequirements, typename unused1, typename unused2,
            typename NakedI, typename AnnotatedSignature, typename... Args>
  struct apply<Comp, TargetRequirements, None, unused1, unused2, Type<std::unique_ptr<NakedI>>,
               AnnotatedSignature, Args...> {
    using AnnotatedC        = SignatureType(AnnotatedSignature);
    using CFunctor          = ConsStdFunction(RemoveAnnotationsFromSignature(AnnotatedSignature));
    using AnnotatedCFunctor = CopyAnnotation(AnnotatedC, CFunctor);
    using type = If(IsAbstract(Type<NakedI>),
                    ConstructError(NoBindingFoundForAbstractClassErrorTag, AnnotatedCFunctor, Type<NakedI>),
                 ConstructError(NoBindingFoundErrorTag, AnnotatedCFunctor));
  };
  
  // AnnotatedI has an interface binding, use it and look for a factory that returns the type that AnnotatedI is bound to.
  template <typename Comp, typename TargetRequirements, typename AnnotatedC, typename unused1, typename unused2,
            typename NakedI, typename AnnotatedSignature, typename... Args>
  struct apply<Comp, TargetRequirements, AnnotatedC, unused1, unused2, Type<std::unique_ptr<NakedI>>,
               AnnotatedSignature, Args...> {
      using I          = Type<NakedI>;
      using AnnotatedI = CopyAnnotation(SignatureType(AnnotatedSignature), I);
      using C          = RemoveAnnotations(AnnotatedC);
      using IFunctor = ConsStdFunction(ConsSignature(ConsUniquePtr(I), Args...));
      using CFunctor = ConsStdFunction(ConsSignature(ConsUniquePtr(C), Args...));
      using AnnotatedIFunctor = CopyAnnotation(AnnotatedI, IFunctor);
      using AnnotatedCFunctor = CopyAnnotation(AnnotatedC, CFunctor);
      
      using ProvidedSignature = ConsSignature(AnnotatedIFunctor, CopyAnnotation(AnnotatedC, ConsReference(CFunctor)));
      using LambdaSignature = ConsSignature(IFunctor, ConsReference(CFunctor));
      
      using F1 = ComponentFunctor(EnsureProvidedType, TargetRequirements, AnnotatedCFunctor);
      using F2 = ComponentFunctor(PreProcessRegisterProvider,  ProvidedSignature, LambdaSignature);
      using F3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, LambdaSignature);
      using R = Call(ComposeFunctors(F1, F2, F3), Comp);
      struct Op {
        using Result = Eval<GetResult(R)>;
        void operator()(ComponentStorage& storage) {
          using NakedC     = UnwrapType<Eval<C>>;
          auto provider = [](UnwrapType<Eval<CFunctor>>& fun) {
            return UnwrapType<Eval<IFunctor>>([=](UnwrapType<Args>... args) {
              NakedC* c = fun(args...).release();
              NakedI* i = static_cast<NakedI*>(c);
              return std::unique_ptr<NakedI>(i);
            });
          };
          using RealF2 = ComponentFunctor(PreProcessRegisterProvider,  ProvidedSignature, Type<decltype(provider)>);
          using RealF3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
          using RealOp = Call(ComposeFunctors(F1, RealF2, RealF3), Comp);
          FruitStaticAssert(IsSame(GetResult(RealOp), GetResult(R)));
          Eval<RealOp>()(storage);
        }
      };
      using type = PropagateError(R,
                   Op);
  };

  // C doesn't have an interface binding as interface, nor an INJECT annotation, and is not an abstract class.
  // Bind std::function<unique_ptr<C>(Args...)> to std::function<C(Args...)> (possibly with annotations).
  template <typename Comp, typename TargetRequirements, typename NakedC, typename AnnotatedSignature,
            typename... Args>
  struct apply<Comp, TargetRequirements, None, Bool<false>, Bool<false>,
               Type<std::unique_ptr<NakedC>>, AnnotatedSignature, Args...> {
    using C = Type<NakedC>;
    using CFunctor          = ConsStdFunction(ConsSignature(C,                Args...));
    using CUniquePtrFunctor = ConsStdFunction(ConsSignature(ConsUniquePtr(C), Args...));
    using AnnotatedCUniquePtr        = SignatureType(AnnotatedSignature);
    using AnnotatedC                 = CopyAnnotation(AnnotatedCUniquePtr, C);
    using AnnotatedCFunctor          = CopyAnnotation(AnnotatedCUniquePtr, CFunctor);
    using AnnotatedCUniquePtrFunctor = CopyAnnotation(AnnotatedCUniquePtr, CUniquePtrFunctor);
    using AnnotatedCFunctorRef       = CopyAnnotation(AnnotatedCUniquePtr, ConsReference(CFunctor));
    
    using ProvidedSignature = ConsSignature(AnnotatedCUniquePtrFunctor, AnnotatedCFunctorRef);
    using LambdaSignature = ConsSignature(CUniquePtrFunctor, ConsReference(CFunctor));
    
    using F1 = ComponentFunctor(EnsureProvidedType, TargetRequirements, AnnotatedCFunctor);
    using F2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, LambdaSignature);
    using F3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, LambdaSignature);
    using R = Call(ComposeFunctors(F1, F2, F3), Comp);
    struct Op {
      using Result = Eval<GetResult(R)>;
      void operator()(ComponentStorage& storage) {
        auto provider = [](UnwrapType<Eval<CFunctor>>& fun) {
          return UnwrapType<Eval<CUniquePtrFunctor>>([=](UnwrapType<Args>... args) {
            NakedC* c = new NakedC(fun(args...));
            return std::unique_ptr<NakedC>(c);
          });
        };
        using RealF2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
        using RealF3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
        using RealOp = Call(ComposeFunctors(F1, RealF2, RealF3), Comp);
        FruitStaticAssert(IsSame(GetResult(RealOp), GetResult(R)));
        Eval<RealOp>()(storage);
      }
    };
    
    using ErrorHandler = AutoRegisterFactoryHelperErrorHandler<Eval<AnnotatedCFunctor>, Eval<AnnotatedCUniquePtrFunctor>>;
    
    // If we are about to report a NoBindingFound/NoBindingFoundForAbstractClass error for AnnotatedCFunctor,
    // report one for std::function<std::unique_ptr<C>(Args...)> instead,
    // otherwise we'd report an error about a type that the user doesn't expect.
    using type = PropagateError(Catch(Catch(R,
                                            NoBindingFoundErrorTag, ErrorHandler),
                                      NoBindingFoundForAbstractClassErrorTag, ErrorHandler),
                 Op);
  };

  // C has an Inject typedef, use it. unique_ptr case.
  template <typename Comp, typename TargetRequirements, typename unused, typename NakedC, typename AnnotatedSignature, typename... Args>
  struct apply<Comp, TargetRequirements, None, Bool<true>, unused, Type<std::unique_ptr<NakedC>>, AnnotatedSignature, Args...> {
    using AnnotatedCUniquePtr = SignatureType(AnnotatedSignature);
    using AnnotatedC = CopyAnnotation(AnnotatedCUniquePtr, RemoveUniquePtr(RemoveAnnotations(AnnotatedCUniquePtr)));
    using DecoratedSignatureReturningValue = GetInjectAnnotation(AnnotatedC);
    using DecoratedSignature = ConsSignatureWithVector(AnnotatedCUniquePtr,
                                                       SignatureArgs(DecoratedSignatureReturningValue));
    using DecoratedSignatureArgs = SignatureArgs(DecoratedSignature);
    using ActualSignatureInInjectionTypedef = ConsSignatureWithVector(SignatureType(DecoratedSignature),
                                                                      RemoveNonAssisted(DecoratedSignatureArgs));
    using NonAssistedArgs = RemoveAssisted(DecoratedSignatureArgs);
    
    using F1 = ComponentFunctor(RegisterConstructorAsUniquePtrFactory, DecoratedSignature);
    using F2 = ComponentFunctor(EnsureProvidedTypes, TargetRequirements, ExpandProvidersInParams(NonAssistedArgs));
    
    using type = If(Not(IsSame(AnnotatedSignature, ActualSignatureInInjectionTypedef)),
                    ConstructError(FunctorSignatureDoesNotMatchErrorTag, AnnotatedSignature, ActualSignatureInInjectionTypedef),
                 Call(ComposeFunctors(F1, F2), Comp));
  };

  // C has an Inject typedef, use it. Value (not unique_ptr) case.
  template <typename Comp, typename TargetRequirements, typename unused, typename NakedC, typename AnnotatedSignature, typename... Args>
  struct apply<Comp, TargetRequirements, None, Bool<true>, unused, Type<NakedC>, AnnotatedSignature, Args...> {
    using AnnotatedC = SignatureType(AnnotatedSignature);
    using DecoratedSignature = GetInjectAnnotation(AnnotatedC);
    using DecoratedSignatureArgs = SignatureArgs(DecoratedSignature);
    using ActualSignatureInInjectionTypedef = ConsSignatureWithVector(SignatureType(DecoratedSignature),
                                                                      RemoveNonAssisted(DecoratedSignatureArgs));
    using NonAssistedArgs = RemoveAssisted(DecoratedSignatureArgs);
    
    using F1 = ComponentFunctor(RegisterConstructorAsValueFactory, DecoratedSignature);
    using F2 = ComponentFunctor(EnsureProvidedTypes, TargetRequirements, ExpandProvidersInParams(NonAssistedArgs));
    
    using type = If(Not(IsSame(AnnotatedSignature, ActualSignatureInInjectionTypedef)),
                    ConstructError(FunctorSignatureDoesNotMatchErrorTag, AnnotatedSignature, ActualSignatureInInjectionTypedef),
                 Call(ComposeFunctors(F1, F2), Comp));
  };
};

struct AutoRegisterHelper {

  template <typename Comp, typename TargetRequirements, typename has_inject_annotation, typename AnnotatedC>
  struct apply;

  // C has an Inject typedef, use it.
  template <typename Comp, typename TargetRequirements, typename AnnotatedC>
  struct apply<Comp, TargetRequirements, Bool<true>, AnnotatedC> {
    using Inject = GetInjectAnnotation(AnnotatedC);
    using CRequirements = ExpandProvidersInParams(SignatureArgs(Inject));
    using F = ComposeFunctors(
                  ComponentFunctor(PreProcessRegisterConstructor, Inject),
                  ComponentFunctor(PostProcessRegisterConstructor, Inject),
                  ComponentFunctor(EnsureProvidedTypes, TargetRequirements, CRequirements));
    using type = Call(F, Comp);
  };
  

  template <typename Comp, typename TargetRequirements, typename AnnotatedC>
  struct apply<Comp, TargetRequirements, Bool<false>, AnnotatedC> {
    using type = ConstructNoBindingFoundError(AnnotatedC);
  };
};

struct AutoRegister {
  // The types in TargetRequirements will not be auto-registered.
  template <typename Comp, typename TargetRequirements, typename AnnotatedC>
  struct apply;

  // Tries to register C by looking for a typedef called Inject inside C.
  template <typename Comp, typename TargetRequirements, typename AnnotatedC>
  struct apply {
    using type = AutoRegisterHelper(Comp,
                                    TargetRequirements,
                                    HasInjectAnnotation(RemoveAnnotations(AnnotatedC)),
                                    AnnotatedC);
  };

  template <typename Comp, typename TargetRequirements, typename NakedC, typename... NakedArgs>
  struct apply<Comp, TargetRequirements, Type<std::function<NakedC(NakedArgs...)>>> {
    using type = AutoRegisterFactoryHelper(Comp,
                                           TargetRequirements,
                                           FindInMap(typename Comp::InterfaceBindings, Type<NakedC>),
                                           HasInjectAnnotation(Type<NakedC>),
                                           IsAbstract(Type<NakedC>),
                                           Type<NakedC>,
                                           Type<NakedC(NakedArgs...)>,
                                           Id<RemoveAnnotations(Type<NakedArgs>)>...);
  };    

  template <typename Comp, typename TargetRequirements, typename NakedC, typename... NakedArgs>
  struct apply<Comp, TargetRequirements, Type<std::function<std::unique_ptr<NakedC>(NakedArgs...)>>> {
    using type = AutoRegisterFactoryHelper(Comp,
                                           TargetRequirements,
                                           FindInMap(typename Comp::InterfaceBindings, Type<NakedC>),
                                           HasInjectAnnotation(Type<NakedC>),
                                           IsAbstract(Type<NakedC>),
                                           Type<std::unique_ptr<NakedC>>,
                                           Type<std::unique_ptr<NakedC>(NakedArgs...)>,
                                           Id<RemoveAnnotations(Type<NakedArgs>)>...);
  };

  template <typename Comp, typename TargetRequirements, typename Annotation, typename NakedC, typename... NakedArgs>
  struct apply<Comp, TargetRequirements, 
               Type<fruit::Annotated<Annotation, std::function<NakedC(NakedArgs...)>>>> {
    using type = AutoRegisterFactoryHelper(Comp,
                                           TargetRequirements,
                                           FindInMap(typename Comp::InterfaceBindings,
                                                     Type<fruit::Annotated<Annotation, NakedC>>),
                                           HasInjectAnnotation(Type<NakedC>),
                                           IsAbstract(Type<NakedC>),
                                           Type<NakedC>,
                                           Type<fruit::Annotated<Annotation, NakedC>(NakedArgs...)>,
                                           Id<RemoveAnnotations(Type<NakedArgs>)>...);
  };    

  template <typename Comp, typename TargetRequirements, typename Annotation, typename NakedC, typename... NakedArgs>
  struct apply<Comp, TargetRequirements, 
               Type<fruit::Annotated<Annotation, std::function<std::unique_ptr<NakedC>(NakedArgs...)>>>> {
    using type = AutoRegisterFactoryHelper(Comp,
                                           TargetRequirements,
                                           FindInMap(typename Comp::InterfaceBindings,
                                                     Type<fruit::Annotated<Annotation, NakedC>>),
                                           HasInjectAnnotation(Type<NakedC>),
                                           IsAbstract(Type<NakedC>),
                                           Type<std::unique_ptr<NakedC>>,
                                           Type<fruit::Annotated<Annotation, std::unique_ptr<NakedC>>(NakedArgs...)>,
                                           Id<RemoveAnnotations(Type<NakedArgs>)>...);
  };
};

struct EnsureProvidedTypeHelper {
  template <typename Comp, typename TargetRequirements, 
            typename is_already_provided_or_in_target_requirements, typename InterfaceBinding, 
            typename AnnotatedC>
  struct apply;

  // Already provided or in target requirements, ok.
  template <typename Comp, typename TargetRequirements, typename unused, typename AnnotatedC>
  struct apply<Comp, TargetRequirements, Bool<true>, unused, AnnotatedC> {
    using type = ComponentFunctorIdentity(Comp);
  };

  // Has an interface binding.
  template <typename Comp, typename TargetRequirements, typename AnnotatedC,
            typename AnnotatedI>
  struct apply<Comp, TargetRequirements, Bool<false>, AnnotatedC, AnnotatedI> {
    using F1 = ComponentFunctor(ProcessInterfaceBinding, AnnotatedI, AnnotatedC);
    using F2 = ComponentFunctor(EnsureProvidedType, TargetRequirements, AnnotatedC);
    using type = Call(ComposeFunctors(F1, F2), Comp);
  };

  // Not yet provided, nor in target requirements, nor in InterfaceBindings. Try auto-registering.
  template <typename Comp, typename TargetRequirements, typename AnnotatedC>
  struct apply<Comp, TargetRequirements, Bool<false>, None, AnnotatedC> {
    using type = AutoRegister(Comp, TargetRequirements, AnnotatedC);
  };
};

struct EnsureProvidedType {
  template <typename Comp, typename TargetRequirements, typename AnnotatedT>
  struct apply {
    using AnnotatedC = NormalizeType(AnnotatedT);
    using type = EnsureProvidedTypeHelper(Comp,
                                          TargetRequirements,
                                          Or(IsInSet(AnnotatedC, typename Comp::Ps),
                                             IsInSet(AnnotatedC, TargetRequirements)),
                                          FindInMap(typename Comp::InterfaceBindings, AnnotatedC),
                                          AnnotatedC);
  };
};

struct EnsureProvidedTypes {
  template <typename Comp, typename TargetRequirements, typename TypeVector>
  struct apply {
    struct Helper {
      template <typename CurrentResult, typename T>
      struct apply {
        using type = Compose2ComponentFunctors(ComponentFunctor(EnsureProvidedType, TargetRequirements, T),
                                               CurrentResult);
      };      
    };
    
    using type = Call(FoldVector(TypeVector, Helper, ComponentFunctorIdentity),
                      Comp);
  };
};

struct ProcessBinding {
  template <typename Binding>
  struct apply;
  
  template <typename I, typename C>
  struct apply<fruit::impl::Bind<I, C>> {
    using type = ComponentFunctor(AddDeferredInterfaceBinding, Type<I>, Type<C>);
  };

  template <typename Signature>
  struct apply<fruit::impl::RegisterConstructor<Signature>> {
    using type = ComponentFunctor(DeferredRegisterConstructor, Type<Signature>);
  };

  template <typename AnnotatedC, typename C>
  struct apply<fruit::impl::BindInstance<AnnotatedC, C>> {
    using type = ComponentFunctor(RegisterInstance, Type<AnnotatedC>, Type<C>);
  };

  template <typename Lambda>
  struct apply<fruit::impl::RegisterProvider<Lambda>> {
    using type = ComponentFunctor(DeferredRegisterProvider, Type<Lambda>);
  };

  template <typename AnnotatedSignature, typename Lambda>
  struct apply<fruit::impl::RegisterProvider<AnnotatedSignature, Lambda>> {
    using type = ComponentFunctor(DeferredRegisterProviderWithAnnotations, Type<AnnotatedSignature>, Type<Lambda>);
  };

  template <typename AnnotatedC>
  struct apply<fruit::impl::AddInstanceMultibinding<AnnotatedC>> {
    using type = ComponentFunctorIdentity;
  };

  template <typename AnnotatedC>
  struct apply<fruit::impl::AddInstanceVectorMultibindings<AnnotatedC>> {
    using type = ComponentFunctorIdentity;
  };

  template <typename I, typename C>
  struct apply<fruit::impl::AddMultibinding<I, C>> {
    using type = ComponentFunctor(AddInterfaceMultibinding, Type<I>, Type<C>);
  };

  template <typename Lambda>
  struct apply<fruit::impl::AddMultibindingProvider<Lambda>> {
    using type = ComponentFunctor(RegisterMultibindingProvider, Type<Lambda>);
  };

  template <typename AnnotatedSignature, typename Lambda>
  struct apply<fruit::impl::AddMultibindingProvider<AnnotatedSignature, Lambda>> {
    using type = ComponentFunctor(RegisterMultibindingProviderWithAnnotations, Type<AnnotatedSignature>, Type<Lambda>);
  };

  template <typename DecoratedSignature, typename Lambda>
  struct apply<fruit::impl::RegisterFactory<DecoratedSignature, Lambda>> {
    using type = ComponentFunctor(RegisterFactory, Type<DecoratedSignature>, Type<Lambda>);
  };

  template <typename... Params>
  struct apply<fruit::impl::InstallComponent<fruit::Component<Params...>>> {
    using type = ComponentFunctor(InstallComponentHelper, Type<Params>...);
  };
};

} // namespace meta
} // namespace impl
} // namespace fruit


#endif // FRUIT_COMPONENT_FUNCTORS_DEFN_H
