private MethodCallbackGenerator buildEventMethod(
      Class<? extends Annotation> eventAnnotation, String methodName) {
    ASTMethod method = getASTMethod(methodName);

    return componentBuilderFactory.buildMethodCallbackGenerator(
        eventAnnotation, componentBuilderFactory.buildMirroredMethodGenerator(method, true));
  }
  private void setupApplicationProfile(
      ComponentDescriptor applicationDescriptor, ASTType astType, AnalysisContext context) {

    ASTMethod onCreateASTMethod = getASTMethod("onCreate");
    // onCreate
    applicationDescriptor.setInitMethodBuilder(
        OnCreate.class,
        componentBuilderFactory.buildOnCreateMethodBuilder(
            onCreateASTMethod, new NoOpLayoutBuilder()));

    applicationDescriptor.setInjectionNodeFactory(
        componentBuilderFactory.buildInjectionNodeFactory(astType, context));

    // onLowMemory
    applicationDescriptor.addGenerators(buildEventMethod(OnLowMemory.class, "onLowMemory"));
    // onTerminate
    applicationDescriptor.addGenerators(buildEventMethod(OnTerminate.class, "onTerminate"));
    // onConfigurationChanged
    ASTMethod onConfigurationChangedASTMethod =
        getASTMethod("onConfigurationChanged", Configuration.class);
    applicationDescriptor.addGenerators(
        componentBuilderFactory.buildMethodCallbackGenerator(
            OnConfigurationChanged.class,
            componentBuilderFactory.buildMirroredMethodGenerator(
                onConfigurationChangedASTMethod, true)));

    applicationDescriptor.addGenerators(contextScopeComponentBuilder);

    applicationDescriptor.addRegistration(observesExpressionDecorator);
  }
  @Override
  public void generate(ASTType descriptor) {

    if (descriptor.isConcreteClass()) {
      throw new TransfuseAnalysisException("Unable to build injector from concrete class");
    }

    try {
      JDefinedClass implClass =
          codeModel._class(JMod.PUBLIC, descriptor.getName() + IMPL_EXT, ClassType.CLASS);
      JClass interfaceClass = codeModel.ref(descriptor.getName());

      implClass._implements(interfaceClass);

      for (ASTMethod interfaceMethod : descriptor.getMethods()) {
        MirroredMethodGenerator mirroredMethodGenerator =
            componentBuilderFactory.buildMirroredMethodGenerator(interfaceMethod, false);
        MethodDescriptor methodDescriptor = mirroredMethodGenerator.buildMethod(implClass);
        JBlock block = methodDescriptor.getMethod().body();

        AnalysisContext context =
            analysisContextFactory.buildAnalysisContext(injectionNodeBuilderRepository);
        InjectionNodeFactory injectionNodeFactory =
            componentBuilderFactory.buildInjectionNodeFactory(
                interfaceMethod.getReturnType(), context);

        // Injections
        InjectionNode returnType = injectionNodeFactory.buildInjectionNode(methodDescriptor);
        Map<InjectionNode, TypedExpression> expressionMap =
            injectionFragmentGenerator.buildFragment(block, implClass, returnType);

        block._return(expressionMap.get(returnType).getExpression());
      }

      injectorRepositoryGenerator.generateInjectorRepository(interfaceClass, implClass);

    } catch (JClassAlreadyExistsException e) {
      throw new TransfuseAnalysisException(
          "Class already exists for generated type " + descriptor.getName(), e);
    } catch (ClassNotFoundException e) {
      throw new TransfuseAnalysisException("Target class not found", e);
    }
  }