public static BeanComponentDefinition parseInnerHandlerDefinition(
     Element element, ParserContext parserContext) {
   // parses out the inner bean definition for concrete implementation if defined
   List<Element> childElements = DomUtils.getChildElementsByTagName(element, "bean");
   BeanComponentDefinition innerComponentDefinition = null;
   if (childElements != null && childElements.size() == 1) {
     Element beanElement = childElements.get(0);
     BeanDefinitionParserDelegate delegate = parserContext.getDelegate();
     BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(beanElement);
     bdHolder = delegate.decorateBeanDefinitionIfRequired(beanElement, bdHolder);
     BeanDefinition inDef = bdHolder.getBeanDefinition();
     innerComponentDefinition = new BeanComponentDefinition(inDef, bdHolder.getBeanName());
   }
   String ref = element.getAttribute(REF_ATTRIBUTE);
   Assert.isTrue(
       !(StringUtils.hasText(ref) && innerComponentDefinition != null),
       "Ambiguous definition. Inner bean "
           + (innerComponentDefinition == null
               ? innerComponentDefinition
               : innerComponentDefinition.getBeanDefinition().getBeanClassName())
           + " declaration and \"ref\" "
           + ref
           + " are not allowed together.");
   return innerComponentDefinition;
 }
  @Override
  protected AbstractBeanDefinition doParse(
      Element element, ParserContext parserContext, String channelName) {
    if (parserContext.isNested()) {
      if (channelName != null) {
        String elementDescription = IntegrationNamespaceUtils.createElementDescription(element);
        parserContext
            .getReaderContext()
            .error(
                "The 'channel' attribute isn't allowed for "
                    + elementDescription
                    + " when it is used as a nested element,"
                    + " e.g. inside a <chain/>",
                element);
      }
      AbstractBeanDefinition consumerBeanDefinition = this.parseConsumer(element, parserContext);
      this.configureRequestHandlerAdviceChain(element, parserContext, consumerBeanDefinition, null);
      return consumerBeanDefinition;
    }
    BeanDefinitionBuilder builder =
        BeanDefinitionBuilder.genericBeanDefinition(ConsumerEndpointFactoryBean.class);
    Element pollerElement = DomUtils.getChildElementByTagName(element, "poller");
    BeanComponentDefinition handlerBeanComponentDefinition =
        this.doParseAndRegisterConsumer(element, parserContext);
    builder.addPropertyReference("handler", handlerBeanComponentDefinition.getBeanName());
    IntegrationNamespaceUtils.checkAndConfigureFixedSubscriberChannel(
        element, parserContext, channelName, handlerBeanComponentDefinition.getBeanName());
    if (pollerElement != null) {
      if (!StringUtils.hasText(channelName)) {
        parserContext
            .getReaderContext()
            .error(
                "outbound channel adapter with a 'poller' requires a 'channel' to poll", element);
      }
      IntegrationNamespaceUtils.configurePollerMetadata(pollerElement, builder, parserContext);
    }
    builder.addPropertyValue("inputChannelName", channelName);

    this.configureRequestHandlerAdviceChain(
        element, parserContext, handlerBeanComponentDefinition.getBeanDefinition(), builder);

    return builder.getBeanDefinition();
  }