@Override
  protected AbstractMessageListenerContainer createListenerContainer() throws Exception {
    // Use DefaultMessageListenerContainer as it supports reconnects (see CAMEL-3193)
    // request-reply listener container should not allow quick-stop so we can keep listening for
    // reply messages
    DefaultMessageListenerContainer answer =
        new DefaultJmsMessageListenerContainer(endpoint, false);

    answer.setDestinationName("temporary");
    answer.setDestinationResolver(destResolver);
    answer.setAutoStartup(true);
    if (endpoint.getMaxMessagesPerTask() >= 0) {
      answer.setMaxMessagesPerTask(endpoint.getMaxMessagesPerTask());
    }
    answer.setIdleConsumerLimit(endpoint.getIdleConsumerLimit());
    answer.setIdleTaskExecutionLimit(endpoint.getIdleTaskExecutionLimit());
    answer.setMessageListener(this);
    answer.setPubSubDomain(false);
    answer.setSubscriptionDurable(false);
    answer.setConcurrentConsumers(endpoint.getConcurrentConsumers());
    if (endpoint.getMaxConcurrentConsumers() > 0) {
      answer.setMaxConcurrentConsumers(endpoint.getMaxConcurrentConsumers());
    }
    answer.setConnectionFactory(endpoint.getConnectionFactory());
    // we use CACHE_CONSUMER by default to cling to the consumer as long as we can, since we can
    // only consume
    // msgs from the JMS Connection that created the temp destination in the first place
    if (endpoint.getReplyToCacheLevelName() != null) {
      if ("CACHE_NONE".equals(endpoint.getReplyToCacheLevelName())) {
        throw new IllegalArgumentException(
            "ReplyToCacheLevelName cannot be CACHE_NONE when using temporary reply queues. The value must be either CACHE_CONSUMER, or CACHE_SESSION");
      }
      answer.setCacheLevelName(endpoint.getReplyToCacheLevelName());
    } else {
      answer.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);
    }
    String clientId = endpoint.getClientId();
    if (clientId != null) {
      clientId += ".CamelReplyManager";
      answer.setClientId(clientId);
    }

    // we cannot do request-reply over JMS with transaction
    answer.setSessionTransacted(false);

    // other optional properties
    answer.setExceptionListener(
        new TemporaryReplyQueueExceptionListener(destResolver, endpoint.getExceptionListener()));

    if (endpoint.getErrorHandler() != null) {
      answer.setErrorHandler(endpoint.getErrorHandler());
    } else {
      answer.setErrorHandler(
          new DefaultSpringErrorHandler(
              TemporaryQueueReplyManager.class,
              endpoint.getErrorHandlerLoggingLevel(),
              endpoint.isErrorHandlerLogStackTrace()));
    }
    if (endpoint.getReceiveTimeout() >= 0) {
      answer.setReceiveTimeout(endpoint.getReceiveTimeout());
    }
    if (endpoint.getRecoveryInterval() >= 0) {
      answer.setRecoveryInterval(endpoint.getRecoveryInterval());
    }
    if (endpoint.getTaskExecutor() != null) {
      if (log.isDebugEnabled()) {
        log.debug(
            "Using custom TaskExecutor: {} on listener container: {}",
            endpoint.getTaskExecutor(),
            answer);
      }
      answer.setTaskExecutor(endpoint.getTaskExecutor());
    }

    // setup a bean name which is used by Spring JMS as the thread name
    // use the name of the request destination
    String name = "TemporaryQueueReplyManager[" + endpoint.getDestinationName() + "]";
    answer.setBeanName(name);

    if (answer.getConcurrentConsumers() > 1) {
      // log that we are using concurrent consumers
      log.info(
          "Using {}-{} concurrent consumers on {}",
          new Object[] {answer.getConcurrentConsumers(), answer.getMaxConcurrentConsumers(), name});
    }
    return answer;
  }
  protected void configureMessageListenerContainer(
      DefaultMessageListenerContainer container, JmsEndpoint endpoint) throws Exception {
    container.setConnectionFactory(getListenerConnectionFactory());
    if (endpoint instanceof DestinationEndpoint) {
      container.setDestinationResolver(createDestinationResolver((DestinationEndpoint) endpoint));
    } else if (destinationResolver != null) {
      container.setDestinationResolver(destinationResolver);
    }
    container.setAutoStartup(autoStartup);

    if (durableSubscriptionName != null) {
      container.setDurableSubscriptionName(durableSubscriptionName);
      container.setSubscriptionDurable(true);
    }
    if (clientId != null) {
      container.setClientId(clientId);
    }

    if (exceptionListener != null) {
      container.setExceptionListener(exceptionListener);
    }

    container.setAcceptMessagesWhileStopping(acceptMessagesWhileStopping);
    container.setExposeListenerSession(exposeListenerSession);
    container.setSessionTransacted(transacted);

    if (endpoint.getSelector() != null && endpoint.getSelector().length() != 0) {
      container.setMessageSelector(endpoint.getSelector());
    }

    if (concurrentConsumers >= 0) {
      container.setConcurrentConsumers(concurrentConsumers);
    }

    if (cacheLevel >= 0) {
      container.setCacheLevel(cacheLevel);
    } else if (cacheLevelName != null) {
      container.setCacheLevelName(cacheLevelName);
    } else {
      container.setCacheLevel(defaultCacheLevel(endpoint));
    }

    if (idleTaskExecutionLimit >= 0) {
      container.setIdleTaskExecutionLimit(idleTaskExecutionLimit);
    }
    if (maxConcurrentConsumers > 0) {
      if (maxConcurrentConsumers < concurrentConsumers) {
        throw new IllegalArgumentException(
            "Property maxConcurrentConsumers: "
                + maxConcurrentConsumers
                + " must be higher than concurrentConsumers: "
                + concurrentConsumers);
      }
      container.setMaxConcurrentConsumers(maxConcurrentConsumers);
    }
    if (maxMessagesPerTask >= 0) {
      container.setMaxMessagesPerTask(maxMessagesPerTask);
    }
    container.setPubSubNoLocal(pubSubNoLocal);
    if (receiveTimeout >= 0) {
      container.setReceiveTimeout(receiveTimeout);
    }
    if (recoveryInterval >= 0) {
      container.setRecoveryInterval(recoveryInterval);
    }
    if (taskExecutor != null) {
      container.setTaskExecutor(taskExecutor);
    }
    if (transactionName != null) {
      container.setTransactionName(transactionName);
    }
    if (transactionTimeout >= 0) {
      container.setTransactionTimeout(transactionTimeout);
    }
  }