protected void registerBean(
      ParserContext context, String contextId, AbstractCamelFactoryBean<?> fact) {
    String id = fact.getId();

    fact.setCamelContextId(contextId);

    MutablePassThroughMetadata eff = context.createMetadata(MutablePassThroughMetadata.class);
    eff.setId(".camelBlueprint.bean.passthrough." + id);
    eff.setObject(new PassThroughCallable<Object>(fact));

    MutableBeanMetadata ef = context.createMetadata(MutableBeanMetadata.class);
    ef.setId(".camelBlueprint.bean.factory." + id);
    ef.setFactoryComponent(eff);
    ef.setFactoryMethod("call");
    ef.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
    ef.setInitMethod("afterPropertiesSet");
    ef.setDestroyMethod("destroy");

    MutableBeanMetadata e = context.createMetadata(MutableBeanMetadata.class);
    e.setId(id);
    e.setRuntimeClass(fact.getObjectType());
    e.setFactoryComponent(ef);
    e.setFactoryMethod("getObject");

    context.getComponentDefinitionRegistry().registerComponentDefinition(e);
  }
  private Metadata parseCamelContextNode(Element element, ParserContext context) {
    // Find the id, generate one if needed
    String contextId = element.getAttribute("id");
    boolean implicitId = false;

    // lets avoid folks having to explicitly give an ID to a camel context
    if (ObjectHelper.isEmpty(contextId)) {
      // if no explicit id was set then use a default auto generated name
      CamelContextNameStrategy strategy = new DefaultCamelContextNameStrategy();
      contextId = strategy.getName();
      element.setAttribute("id", contextId);
      implicitId = true;
    }

    // now lets parse the routes with JAXB
    Binder<Node> binder;
    try {
      binder = getJaxbContext().createBinder();
    } catch (JAXBException e) {
      throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e);
    }
    Object value = parseUsingJaxb(element, context, binder);
    if (!(value instanceof CamelContextFactoryBean)) {
      throw new ComponentDefinitionException(
          "Expected an instance of " + CamelContextFactoryBean.class);
    }

    CamelContextFactoryBean ccfb = (CamelContextFactoryBean) value;
    ccfb.setImplicitId(implicitId);

    MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
    factory.setId(".camelBlueprint.passThrough." + contextId);
    factory.setObject(new PassThroughCallable<Object>(value));

    MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class);
    factory2.setId(".camelBlueprint.factory." + contextId);
    factory2.setFactoryComponent(factory);
    factory2.setFactoryMethod("call");
    factory2.setInitMethod("afterPropertiesSet");
    factory2.setDestroyMethod("destroy");
    factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
    factory2.addProperty("bundleContext", createRef(context, "blueprintBundleContext"));
    context.getComponentDefinitionRegistry().registerComponentDefinition(factory2);

    MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
    ctx.setId(contextId);
    ctx.setRuntimeClass(BlueprintCamelContext.class);
    ctx.setFactoryComponent(factory2);
    ctx.setFactoryMethod("getContext");
    ctx.setInitMethod("init");
    ctx.setDestroyMethod("destroy");

    // Register objects
    registerBeans(context, contextId, ccfb.getEndpoints());
    registerBeans(context, contextId, ccfb.getThreadPools());
    registerBeans(context, contextId, ccfb.getBeans());

    // Register processors
    MutablePassThroughMetadata beanProcessorFactory =
        context.createMetadata(MutablePassThroughMetadata.class);
    beanProcessorFactory.setId(".camelBlueprint.processor.bean.passThrough." + contextId);
    beanProcessorFactory.setObject(new PassThroughCallable<Object>(new CamelInjector(contextId)));

    MutableBeanMetadata beanProcessor = context.createMetadata(MutableBeanMetadata.class);
    beanProcessor.setId(".camelBlueprint.processor.bean." + contextId);
    beanProcessor.setRuntimeClass(CamelInjector.class);
    beanProcessor.setFactoryComponent(beanProcessorFactory);
    beanProcessor.setFactoryMethod("call");
    beanProcessor.setProcessor(true);
    beanProcessor.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
    context.getComponentDefinitionRegistry().registerComponentDefinition(beanProcessor);

    MutablePassThroughMetadata regProcessorFactory =
        context.createMetadata(MutablePassThroughMetadata.class);
    regProcessorFactory.setId(".camelBlueprint.processor.registry.passThrough." + contextId);
    regProcessorFactory.setObject(
        new PassThroughCallable<Object>(new CamelDependenciesFinder(contextId, context)));

    MutableBeanMetadata regProcessor = context.createMetadata(MutableBeanMetadata.class);
    regProcessor.setId(".camelBlueprint.processor.registry." + contextId);
    regProcessor.setRuntimeClass(CamelDependenciesFinder.class);
    regProcessor.setFactoryComponent(regProcessorFactory);
    regProcessor.setFactoryMethod("call");
    regProcessor.setProcessor(true);
    regProcessor.addDependsOn(".camelBlueprint.processor.bean." + contextId);
    regProcessor.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
    context.getComponentDefinitionRegistry().registerComponentDefinition(regProcessor);
    return ctx;
  }