/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.camel.builder.endpoint.dsl;

import javax.annotation.Generated;
import org.apache.camel.ExchangePattern;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.builder.EndpointProducerBuilder;
import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
import org.apache.camel.spi.ExceptionHandler;
import org.apache.camel.spi.HeaderFilterStrategy;

/**
 * The jms component allows messages to be sent to (or consumed from) a JMS
 * Queue or Topic.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface JmsEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the JMS component.
     */
    public interface JmsEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedJmsEndpointConsumerBuilder advanced() {
            return (AdvancedJmsEndpointConsumerBuilder) this;
        }
        /**
         * Sets the JMS client ID to use. Note that this value, if specified,
         * must be unique and can only be used by a single JMS connection
         * instance. It is typically only required for durable topic
         * subscriptions. If using Apache ActiveMQ you may prefer to use Virtual
         * Topics instead.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder clientId(String clientId) {
            doSetProperty("clientId", clientId);
            return this;
        }
        /**
         * Sets the default connection factory to be used if a connection
         * factory is not specified for either
         * setTemplateConnectionFactory(ConnectionFactory) or
         * setListenerConnectionFactory(ConnectionFactory).
         * 
         * The option is a: <code>javax.jms.ConnectionFactory</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder connectionFactory(
                Object connectionFactory) {
            doSetProperty("connectionFactory", connectionFactory);
            return this;
        }
        /**
         * Sets the default connection factory to be used if a connection
         * factory is not specified for either
         * setTemplateConnectionFactory(ConnectionFactory) or
         * setListenerConnectionFactory(ConnectionFactory).
         * 
         * The option will be converted to a
         * <code>javax.jms.ConnectionFactory</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder connectionFactory(
                String connectionFactory) {
            doSetProperty("connectionFactory", connectionFactory);
            return this;
        }
        /**
         * Specifies whether Camel ignores the JMSReplyTo header in messages. If
         * true, Camel does not send a reply back to the destination specified
         * in the JMSReplyTo header. You can use this option if you want Camel
         * to consume from a route and you do not want Camel to automatically
         * send back a reply message because another component in your code
         * handles the reply message. You can also use this option if you want
         * to use Camel as a proxy between different message brokers and you
         * want to route message from one system to another.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder disableReplyTo(boolean disableReplyTo) {
            doSetProperty("disableReplyTo", disableReplyTo);
            return this;
        }
        /**
         * Specifies whether Camel ignores the JMSReplyTo header in messages. If
         * true, Camel does not send a reply back to the destination specified
         * in the JMSReplyTo header. You can use this option if you want Camel
         * to consume from a route and you do not want Camel to automatically
         * send back a reply message because another component in your code
         * handles the reply message. You can also use this option if you want
         * to use Camel as a proxy between different message brokers and you
         * want to route message from one system to another.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder disableReplyTo(String disableReplyTo) {
            doSetProperty("disableReplyTo", disableReplyTo);
            return this;
        }
        /**
         * The durable subscriber name for specifying durable topic
         * subscriptions. The clientId option must be configured as well.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder durableSubscriptionName(
                String durableSubscriptionName) {
            doSetProperty("durableSubscriptionName", durableSubscriptionName);
            return this;
        }
        /**
         * Allows you to force the use of a specific javax.jms.Message
         * implementation for sending JMS messages. Possible values are: Bytes,
         * Map, Object, Stream, Text. By default, Camel would determine which
         * JMS message type to use from the In body type. This option allows you
         * to specify it.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.JmsMessageType</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder jmsMessageType(
                JmsMessageType jmsMessageType) {
            doSetProperty("jmsMessageType", jmsMessageType);
            return this;
        }
        /**
         * Allows you to force the use of a specific javax.jms.Message
         * implementation for sending JMS messages. Possible values are: Bytes,
         * Map, Object, Stream, Text. By default, Camel would determine which
         * JMS message type to use from the In body type. This option allows you
         * to specify it.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.JmsMessageType</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder jmsMessageType(String jmsMessageType) {
            doSetProperty("jmsMessageType", jmsMessageType);
            return this;
        }
        /**
         * Specifies whether to test the connection on startup. This ensures
         * that when Camel starts that all the JMS consumers have a valid
         * connection to the JMS broker. If a connection cannot be granted then
         * Camel throws an exception on startup. This ensures that Camel is not
         * started with failed connections. The JMS producers is tested as well.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder testConnectionOnStartup(
                boolean testConnectionOnStartup) {
            doSetProperty("testConnectionOnStartup", testConnectionOnStartup);
            return this;
        }
        /**
         * Specifies whether to test the connection on startup. This ensures
         * that when Camel starts that all the JMS consumers have a valid
         * connection to the JMS broker. If a connection cannot be granted then
         * Camel throws an exception on startup. This ensures that Camel is not
         * started with failed connections. The JMS producers is tested as well.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointConsumerBuilder testConnectionOnStartup(
                String testConnectionOnStartup) {
            doSetProperty("testConnectionOnStartup", testConnectionOnStartup);
            return this;
        }
        /**
         * The JMS acknowledgement name, which is one of: SESSION_TRANSACTED,
         * CLIENT_ACKNOWLEDGE, AUTO_ACKNOWLEDGE, DUPS_OK_ACKNOWLEDGE.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder acknowledgementModeName(
                String acknowledgementModeName) {
            doSetProperty("acknowledgementModeName", acknowledgementModeName);
            return this;
        }
        /**
         * Whether the JmsConsumer processes the Exchange asynchronously. If
         * enabled then the JmsConsumer may pickup the next message from the JMS
         * queue, while the previous message is being processed asynchronously
         * (by the Asynchronous Routing Engine). This means that messages may be
         * processed not 100% strictly in order. If disabled (as default) then
         * the Exchange is fully processed before the JmsConsumer will pickup
         * the next message from the JMS queue. Note if transacted has been
         * enabled, then asyncConsumer=true does not run asynchronously, as
         * transaction must be executed synchronously (Camel 3.0 may support
         * async transactions).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder asyncConsumer(boolean asyncConsumer) {
            doSetProperty("asyncConsumer", asyncConsumer);
            return this;
        }
        /**
         * Whether the JmsConsumer processes the Exchange asynchronously. If
         * enabled then the JmsConsumer may pickup the next message from the JMS
         * queue, while the previous message is being processed asynchronously
         * (by the Asynchronous Routing Engine). This means that messages may be
         * processed not 100% strictly in order. If disabled (as default) then
         * the Exchange is fully processed before the JmsConsumer will pickup
         * the next message from the JMS queue. Note if transacted has been
         * enabled, then asyncConsumer=true does not run asynchronously, as
         * transaction must be executed synchronously (Camel 3.0 may support
         * async transactions).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder asyncConsumer(String asyncConsumer) {
            doSetProperty("asyncConsumer", asyncConsumer);
            return this;
        }
        /**
         * Specifies whether the consumer container should auto-startup.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder autoStartup(boolean autoStartup) {
            doSetProperty("autoStartup", autoStartup);
            return this;
        }
        /**
         * Specifies whether the consumer container should auto-startup.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder autoStartup(String autoStartup) {
            doSetProperty("autoStartup", autoStartup);
            return this;
        }
        /**
         * Sets the cache level by ID for the underlying JMS resources. See
         * cacheLevelName option for more details.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder cacheLevel(int cacheLevel) {
            doSetProperty("cacheLevel", cacheLevel);
            return this;
        }
        /**
         * Sets the cache level by ID for the underlying JMS resources. See
         * cacheLevelName option for more details.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder cacheLevel(String cacheLevel) {
            doSetProperty("cacheLevel", cacheLevel);
            return this;
        }
        /**
         * Sets the cache level by name for the underlying JMS resources.
         * Possible values are: CACHE_AUTO, CACHE_CONNECTION, CACHE_CONSUMER,
         * CACHE_NONE, and CACHE_SESSION. The default setting is CACHE_AUTO. See
         * the Spring documentation and Transactions Cache Levels for more
         * information.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder cacheLevelName(String cacheLevelName) {
            doSetProperty("cacheLevelName", cacheLevelName);
            return this;
        }
        /**
         * Specifies the default number of concurrent consumers when consuming
         * from JMS (not for request/reply over JMS). See also the
         * maxMessagesPerTask option to control dynamic scaling up/down of
         * threads. When doing request/reply over JMS then the option
         * replyToConcurrentConsumers is used to control number of concurrent
         * consumers on the reply message listener.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder concurrentConsumers(
                int concurrentConsumers) {
            doSetProperty("concurrentConsumers", concurrentConsumers);
            return this;
        }
        /**
         * Specifies the default number of concurrent consumers when consuming
         * from JMS (not for request/reply over JMS). See also the
         * maxMessagesPerTask option to control dynamic scaling up/down of
         * threads. When doing request/reply over JMS then the option
         * replyToConcurrentConsumers is used to control number of concurrent
         * consumers on the reply message listener.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder concurrentConsumers(
                String concurrentConsumers) {
            doSetProperty("concurrentConsumers", concurrentConsumers);
            return this;
        }
        /**
         * Specifies the maximum number of concurrent consumers when consuming
         * from JMS (not for request/reply over JMS). See also the
         * maxMessagesPerTask option to control dynamic scaling up/down of
         * threads. When doing request/reply over JMS then the option
         * replyToMaxConcurrentConsumers is used to control number of concurrent
         * consumers on the reply message listener.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder maxConcurrentConsumers(
                int maxConcurrentConsumers) {
            doSetProperty("maxConcurrentConsumers", maxConcurrentConsumers);
            return this;
        }
        /**
         * Specifies the maximum number of concurrent consumers when consuming
         * from JMS (not for request/reply over JMS). See also the
         * maxMessagesPerTask option to control dynamic scaling up/down of
         * threads. When doing request/reply over JMS then the option
         * replyToMaxConcurrentConsumers is used to control number of concurrent
         * consumers on the reply message listener.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder maxConcurrentConsumers(
                String maxConcurrentConsumers) {
            doSetProperty("maxConcurrentConsumers", maxConcurrentConsumers);
            return this;
        }
        /**
         * Provides an explicit ReplyTo destination, which overrides any
         * incoming value of Message.getJMSReplyTo().
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder replyTo(String replyTo) {
            doSetProperty("replyTo", replyTo);
            return this;
        }
        /**
         * Specifies whether to use persistent delivery by default for replies.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder replyToDeliveryPersistent(
                boolean replyToDeliveryPersistent) {
            doSetProperty("replyToDeliveryPersistent", replyToDeliveryPersistent);
            return this;
        }
        /**
         * Specifies whether to use persistent delivery by default for replies.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder replyToDeliveryPersistent(
                String replyToDeliveryPersistent) {
            doSetProperty("replyToDeliveryPersistent", replyToDeliveryPersistent);
            return this;
        }
        /**
         * Sets the JMS selector to use.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder selector(String selector) {
            doSetProperty("selector", selector);
            return this;
        }
        /**
         * Set whether to make the subscription durable. The durable
         * subscription name to be used can be specified through the
         * subscriptionName property. Default is false. Set this to true to
         * register a durable subscription, typically in combination with a
         * subscriptionName value (unless your message listener class name is
         * good enough as subscription name). Only makes sense when listening to
         * a topic (pub-sub domain), therefore this method switches the
         * pubSubDomain flag as well.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder subscriptionDurable(
                boolean subscriptionDurable) {
            doSetProperty("subscriptionDurable", subscriptionDurable);
            return this;
        }
        /**
         * Set whether to make the subscription durable. The durable
         * subscription name to be used can be specified through the
         * subscriptionName property. Default is false. Set this to true to
         * register a durable subscription, typically in combination with a
         * subscriptionName value (unless your message listener class name is
         * good enough as subscription name). Only makes sense when listening to
         * a topic (pub-sub domain), therefore this method switches the
         * pubSubDomain flag as well.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder subscriptionDurable(
                String subscriptionDurable) {
            doSetProperty("subscriptionDurable", subscriptionDurable);
            return this;
        }
        /**
         * Set the name of a subscription to create. To be applied in case of a
         * topic (pub-sub domain) with a shared or durable subscription. The
         * subscription name needs to be unique within this client's JMS client
         * id. Default is the class name of the specified message listener.
         * Note: Only 1 concurrent consumer (which is the default of this
         * message listener container) is allowed for each subscription, except
         * for a shared subscription (which requires JMS 2.0).
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder subscriptionName(
                String subscriptionName) {
            doSetProperty("subscriptionName", subscriptionName);
            return this;
        }
        /**
         * Set whether to make the subscription shared. The shared subscription
         * name to be used can be specified through the subscriptionName
         * property. Default is false. Set this to true to register a shared
         * subscription, typically in combination with a subscriptionName value
         * (unless your message listener class name is good enough as
         * subscription name). Note that shared subscriptions may also be
         * durable, so this flag can (and often will) be combined with
         * subscriptionDurable as well. Only makes sense when listening to a
         * topic (pub-sub domain), therefore this method switches the
         * pubSubDomain flag as well. Requires a JMS 2.0 compatible message
         * broker.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder subscriptionShared(
                boolean subscriptionShared) {
            doSetProperty("subscriptionShared", subscriptionShared);
            return this;
        }
        /**
         * Set whether to make the subscription shared. The shared subscription
         * name to be used can be specified through the subscriptionName
         * property. Default is false. Set this to true to register a shared
         * subscription, typically in combination with a subscriptionName value
         * (unless your message listener class name is good enough as
         * subscription name). Note that shared subscriptions may also be
         * durable, so this flag can (and often will) be combined with
         * subscriptionDurable as well. Only makes sense when listening to a
         * topic (pub-sub domain), therefore this method switches the
         * pubSubDomain flag as well. Requires a JMS 2.0 compatible message
         * broker.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JmsEndpointConsumerBuilder subscriptionShared(
                String subscriptionShared) {
            doSetProperty("subscriptionShared", subscriptionShared);
            return this;
        }
        /**
         * Allows to configure the default errorHandler logging level for
         * logging uncaught exceptions.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: logging
         */
        default JmsEndpointConsumerBuilder errorHandlerLoggingLevel(
                LoggingLevel errorHandlerLoggingLevel) {
            doSetProperty("errorHandlerLoggingLevel", errorHandlerLoggingLevel);
            return this;
        }
        /**
         * Allows to configure the default errorHandler logging level for
         * logging uncaught exceptions.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: logging
         */
        default JmsEndpointConsumerBuilder errorHandlerLoggingLevel(
                String errorHandlerLoggingLevel) {
            doSetProperty("errorHandlerLoggingLevel", errorHandlerLoggingLevel);
            return this;
        }
        /**
         * Allows to control whether stacktraces should be logged or not, by the
         * default errorHandler.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: logging
         */
        default JmsEndpointConsumerBuilder errorHandlerLogStackTrace(
                boolean errorHandlerLogStackTrace) {
            doSetProperty("errorHandlerLogStackTrace", errorHandlerLogStackTrace);
            return this;
        }
        /**
         * Allows to control whether stacktraces should be logged or not, by the
         * default errorHandler.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: logging
         */
        default JmsEndpointConsumerBuilder errorHandlerLogStackTrace(
                String errorHandlerLogStackTrace) {
            doSetProperty("errorHandlerLogStackTrace", errorHandlerLogStackTrace);
            return this;
        }
        /**
         * Password to use with the ConnectionFactory. You can also configure
         * username/password directly on the ConnectionFactory.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default JmsEndpointConsumerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Username to use with the ConnectionFactory. You can also configure
         * username/password directly on the ConnectionFactory.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default JmsEndpointConsumerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * Specifies whether to use transacted mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: transaction
         */
        default JmsEndpointConsumerBuilder transacted(boolean transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
        /**
         * Specifies whether to use transacted mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: transaction
         */
        default JmsEndpointConsumerBuilder transacted(String transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the JMS component.
     */
    public interface AdvancedJmsEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default JmsEndpointConsumerBuilder basic() {
            return (JmsEndpointConsumerBuilder) this;
        }
        /**
         * Specifies whether the consumer accept messages while it is stopping.
         * You may consider enabling this option, if you start and stop JMS
         * routes at runtime, while there are still messages enqueued on the
         * queue. If this option is false, and you stop the JMS route, then
         * messages may be rejected, and the JMS broker would have to attempt
         * redeliveries, which yet again may be rejected, and eventually the
         * message may be moved at a dead letter queue on the JMS broker. To
         * avoid this its recommended to enable this option.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder acceptMessagesWhileStopping(
                boolean acceptMessagesWhileStopping) {
            doSetProperty("acceptMessagesWhileStopping", acceptMessagesWhileStopping);
            return this;
        }
        /**
         * Specifies whether the consumer accept messages while it is stopping.
         * You may consider enabling this option, if you start and stop JMS
         * routes at runtime, while there are still messages enqueued on the
         * queue. If this option is false, and you stop the JMS route, then
         * messages may be rejected, and the JMS broker would have to attempt
         * redeliveries, which yet again may be rejected, and eventually the
         * message may be moved at a dead letter queue on the JMS broker. To
         * avoid this its recommended to enable this option.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder acceptMessagesWhileStopping(
                String acceptMessagesWhileStopping) {
            doSetProperty("acceptMessagesWhileStopping", acceptMessagesWhileStopping);
            return this;
        }
        /**
         * Whether the DefaultMessageListenerContainer used in the reply
         * managers for request-reply messaging allow the
         * DefaultMessageListenerContainer#runningAllowed() flag to quick stop
         * in case JmsConfiguration#isAcceptMessagesWhileStopping() is enabled,
         * and org.apache.camel.CamelContext is currently being stopped. This
         * quick stop ability is enabled by default in the regular JMS consumers
         * but to enable for reply managers you must enable this flag.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder allowReplyManagerQuickStop(
                boolean allowReplyManagerQuickStop) {
            doSetProperty("allowReplyManagerQuickStop", allowReplyManagerQuickStop);
            return this;
        }
        /**
         * Whether the DefaultMessageListenerContainer used in the reply
         * managers for request-reply messaging allow the
         * DefaultMessageListenerContainer#runningAllowed() flag to quick stop
         * in case JmsConfiguration#isAcceptMessagesWhileStopping() is enabled,
         * and org.apache.camel.CamelContext is currently being stopped. This
         * quick stop ability is enabled by default in the regular JMS consumers
         * but to enable for reply managers you must enable this flag.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder allowReplyManagerQuickStop(
                String allowReplyManagerQuickStop) {
            doSetProperty("allowReplyManagerQuickStop", allowReplyManagerQuickStop);
            return this;
        }
        /**
         * The consumer type to use, which can be one of: Simple, Default, or
         * Custom. The consumer type determines which Spring JMS listener to
         * use. Default will use
         * org.springframework.jms.listener.DefaultMessageListenerContainer,
         * Simple will use
         * org.springframework.jms.listener.SimpleMessageListenerContainer. When
         * Custom is specified, the MessageListenerContainerFactory defined by
         * the messageListenerContainerFactory option will determine what
         * org.springframework.jms.listener.AbstractMessageListenerContainer to
         * use.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.ConsumerType</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder consumerType(
                ConsumerType consumerType) {
            doSetProperty("consumerType", consumerType);
            return this;
        }
        /**
         * The consumer type to use, which can be one of: Simple, Default, or
         * Custom. The consumer type determines which Spring JMS listener to
         * use. Default will use
         * org.springframework.jms.listener.DefaultMessageListenerContainer,
         * Simple will use
         * org.springframework.jms.listener.SimpleMessageListenerContainer. When
         * Custom is specified, the MessageListenerContainerFactory defined by
         * the messageListenerContainerFactory option will determine what
         * org.springframework.jms.listener.AbstractMessageListenerContainer to
         * use.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.ConsumerType</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder consumerType(
                String consumerType) {
            doSetProperty("consumerType", consumerType);
            return this;
        }
        /**
         * Specifies what default TaskExecutor type to use in the
         * DefaultMessageListenerContainer, for both consumer endpoints and the
         * ReplyTo consumer of producer endpoints. Possible values: SimpleAsync
         * (uses Spring's SimpleAsyncTaskExecutor) or ThreadPool (uses Spring's
         * ThreadPoolTaskExecutor with optimal values - cached threadpool-like).
         * If not set, it defaults to the previous behaviour, which uses a
         * cached thread pool for consumer endpoints and SimpleAsync for reply
         * consumers. The use of ThreadPool is recommended to reduce thread
         * trash in elastic configurations with dynamically increasing and
         * decreasing concurrent consumers.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.DefaultTaskExecutorType</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder defaultTaskExecutorType(
                DefaultTaskExecutorType defaultTaskExecutorType) {
            doSetProperty("defaultTaskExecutorType", defaultTaskExecutorType);
            return this;
        }
        /**
         * Specifies what default TaskExecutor type to use in the
         * DefaultMessageListenerContainer, for both consumer endpoints and the
         * ReplyTo consumer of producer endpoints. Possible values: SimpleAsync
         * (uses Spring's SimpleAsyncTaskExecutor) or ThreadPool (uses Spring's
         * ThreadPoolTaskExecutor with optimal values - cached threadpool-like).
         * If not set, it defaults to the previous behaviour, which uses a
         * cached thread pool for consumer endpoints and SimpleAsync for reply
         * consumers. The use of ThreadPool is recommended to reduce thread
         * trash in elastic configurations with dynamically increasing and
         * decreasing concurrent consumers.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.DefaultTaskExecutorType</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder defaultTaskExecutorType(
                String defaultTaskExecutorType) {
            doSetProperty("defaultTaskExecutorType", defaultTaskExecutorType);
            return this;
        }
        /**
         * Enables eager loading of JMS properties and payload as soon as a
         * message is loaded which generally is inefficient as the JMS
         * properties may not be required but sometimes can catch early any
         * issues with the underlying JMS provider and the use of JMS
         * properties. See also the option eagerPoisonBody.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder eagerLoadingOfProperties(
                boolean eagerLoadingOfProperties) {
            doSetProperty("eagerLoadingOfProperties", eagerLoadingOfProperties);
            return this;
        }
        /**
         * Enables eager loading of JMS properties and payload as soon as a
         * message is loaded which generally is inefficient as the JMS
         * properties may not be required but sometimes can catch early any
         * issues with the underlying JMS provider and the use of JMS
         * properties. See also the option eagerPoisonBody.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder eagerLoadingOfProperties(
                String eagerLoadingOfProperties) {
            doSetProperty("eagerLoadingOfProperties", eagerLoadingOfProperties);
            return this;
        }
        /**
         * If eagerLoadingOfProperties is enabled and the JMS message payload
         * (JMS body or JMS properties) (cannot be read/mapped), then set this
         * text as the message body instead so the message can be processed (the
         * cause of the poison are already stored as exception on the Exchange).
         * This can be turned off by setting eagerPoisonBody=false. See also the
         * option eagerLoadingOfProperties.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder eagerPoisonBody(
                String eagerPoisonBody) {
            doSetProperty("eagerPoisonBody", eagerPoisonBody);
            return this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option is a: <code>org.apache.camel.spi.ExceptionHandler</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder exceptionHandler(
                ExceptionHandler exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.ExceptionHandler</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder exceptionHandler(
                String exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option is a: <code>org.apache.camel.ExchangePattern</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder exchangePattern(
                ExchangePattern exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.ExchangePattern</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * Specifies whether the listener session should be exposed when
         * consuming messages.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder exposeListenerSession(
                boolean exposeListenerSession) {
            doSetProperty("exposeListenerSession", exposeListenerSession);
            return this;
        }
        /**
         * Specifies whether the listener session should be exposed when
         * consuming messages.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder exposeListenerSession(
                String exposeListenerSession) {
            doSetProperty("exposeListenerSession", exposeListenerSession);
            return this;
        }
        /**
         * Whether a JMS consumer is allowed to send a reply message to the same
         * destination that the consumer is using to consume from. This prevents
         * an endless loop by consuming and sending back the same message to
         * itself.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder replyToSameDestinationAllowed(
                boolean replyToSameDestinationAllowed) {
            doSetProperty("replyToSameDestinationAllowed", replyToSameDestinationAllowed);
            return this;
        }
        /**
         * Whether a JMS consumer is allowed to send a reply message to the same
         * destination that the consumer is using to consume from. This prevents
         * an endless loop by consuming and sending back the same message to
         * itself.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder replyToSameDestinationAllowed(
                String replyToSameDestinationAllowed) {
            doSetProperty("replyToSameDestinationAllowed", replyToSameDestinationAllowed);
            return this;
        }
        /**
         * Allows you to specify a custom task executor for consuming messages.
         * 
         * The option is a:
         * <code>org.springframework.core.task.TaskExecutor</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder taskExecutor(
                Object taskExecutor) {
            doSetProperty("taskExecutor", taskExecutor);
            return this;
        }
        /**
         * Allows you to specify a custom task executor for consuming messages.
         * 
         * The option will be converted to a
         * <code>org.springframework.core.task.TaskExecutor</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder taskExecutor(
                String taskExecutor) {
            doSetProperty("taskExecutor", taskExecutor);
            return this;
        }
        /**
         * Controls whether or not to include serialized headers. Applies only
         * when isTransferExchange() is true. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder allowSerializedHeaders(
                boolean allowSerializedHeaders) {
            doSetProperty("allowSerializedHeaders", allowSerializedHeaders);
            return this;
        }
        /**
         * Controls whether or not to include serialized headers. Applies only
         * when isTransferExchange() is true. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder allowSerializedHeaders(
                String allowSerializedHeaders) {
            doSetProperty("allowSerializedHeaders", allowSerializedHeaders);
            return this;
        }
        /**
         * Whether to startup the JmsConsumer message listener asynchronously,
         * when starting a route. For example if a JmsConsumer cannot get a
         * connection to a remote JMS broker, then it may block while retrying
         * and/or failover. This will cause Camel to block while starting
         * routes. By setting this option to true, you will let routes startup,
         * while the JmsConsumer connects to the JMS broker using a dedicated
         * thread in asynchronous mode. If this option is used, then beware that
         * if the connection could not be established, then an exception is
         * logged at WARN level, and the consumer will not be able to receive
         * messages; You can then restart the route to retry.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder asyncStartListener(
                boolean asyncStartListener) {
            doSetProperty("asyncStartListener", asyncStartListener);
            return this;
        }
        /**
         * Whether to startup the JmsConsumer message listener asynchronously,
         * when starting a route. For example if a JmsConsumer cannot get a
         * connection to a remote JMS broker, then it may block while retrying
         * and/or failover. This will cause Camel to block while starting
         * routes. By setting this option to true, you will let routes startup,
         * while the JmsConsumer connects to the JMS broker using a dedicated
         * thread in asynchronous mode. If this option is used, then beware that
         * if the connection could not be established, then an exception is
         * logged at WARN level, and the consumer will not be able to receive
         * messages; You can then restart the route to retry.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder asyncStartListener(
                String asyncStartListener) {
            doSetProperty("asyncStartListener", asyncStartListener);
            return this;
        }
        /**
         * Whether to stop the JmsConsumer message listener asynchronously, when
         * stopping a route.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder asyncStopListener(
                boolean asyncStopListener) {
            doSetProperty("asyncStopListener", asyncStopListener);
            return this;
        }
        /**
         * Whether to stop the JmsConsumer message listener asynchronously, when
         * stopping a route.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder asyncStopListener(
                String asyncStopListener) {
            doSetProperty("asyncStopListener", asyncStopListener);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * A pluggable
         * org.springframework.jms.support.destination.DestinationResolver that
         * allows you to use your own resolver (for example, to lookup the real
         * destination in a JNDI registry).
         * 
         * The option is a:
         * <code>org.springframework.jms.support.destination.DestinationResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder destinationResolver(
                Object destinationResolver) {
            doSetProperty("destinationResolver", destinationResolver);
            return this;
        }
        /**
         * A pluggable
         * org.springframework.jms.support.destination.DestinationResolver that
         * allows you to use your own resolver (for example, to lookup the real
         * destination in a JNDI registry).
         * 
         * The option will be converted to a
         * <code>org.springframework.jms.support.destination.DestinationResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder destinationResolver(
                String destinationResolver) {
            doSetProperty("destinationResolver", destinationResolver);
            return this;
        }
        /**
         * Specifies a org.springframework.util.ErrorHandler to be invoked in
         * case of any uncaught exceptions thrown while processing a Message. By
         * default these exceptions will be logged at the WARN level, if no
         * errorHandler has been configured. You can configure logging level and
         * whether stack traces should be logged using errorHandlerLoggingLevel
         * and errorHandlerLogStackTrace options. This makes it much easier to
         * configure, than having to code a custom errorHandler.
         * 
         * The option is a: <code>org.springframework.util.ErrorHandler</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder errorHandler(
                Object errorHandler) {
            doSetProperty("errorHandler", errorHandler);
            return this;
        }
        /**
         * Specifies a org.springframework.util.ErrorHandler to be invoked in
         * case of any uncaught exceptions thrown while processing a Message. By
         * default these exceptions will be logged at the WARN level, if no
         * errorHandler has been configured. You can configure logging level and
         * whether stack traces should be logged using errorHandlerLoggingLevel
         * and errorHandlerLogStackTrace options. This makes it much easier to
         * configure, than having to code a custom errorHandler.
         * 
         * The option will be converted to a
         * <code>org.springframework.util.ErrorHandler</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder errorHandler(
                String errorHandler) {
            doSetProperty("errorHandler", errorHandler);
            return this;
        }
        /**
         * Specifies the JMS Exception Listener that is to be notified of any
         * underlying JMS exceptions.
         * 
         * The option is a: <code>javax.jms.ExceptionListener</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder exceptionListener(
                Object exceptionListener) {
            doSetProperty("exceptionListener", exceptionListener);
            return this;
        }
        /**
         * Specifies the JMS Exception Listener that is to be notified of any
         * underlying JMS exceptions.
         * 
         * The option will be converted to a
         * <code>javax.jms.ExceptionListener</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder exceptionListener(
                String exceptionListener) {
            doSetProperty("exceptionListener", exceptionListener);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Specify the limit for the number of consumers that are allowed to be
         * idle at any given time.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder idleConsumerLimit(
                int idleConsumerLimit) {
            doSetProperty("idleConsumerLimit", idleConsumerLimit);
            return this;
        }
        /**
         * Specify the limit for the number of consumers that are allowed to be
         * idle at any given time.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder idleConsumerLimit(
                String idleConsumerLimit) {
            doSetProperty("idleConsumerLimit", idleConsumerLimit);
            return this;
        }
        /**
         * Specifies the limit for idle executions of a receive task, not having
         * received any message within its execution. If this limit is reached,
         * the task will shut down and leave receiving to other executing tasks
         * (in the case of dynamic scheduling; see the maxConcurrentConsumers
         * setting). There is additional doc available from Spring.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder idleTaskExecutionLimit(
                int idleTaskExecutionLimit) {
            doSetProperty("idleTaskExecutionLimit", idleTaskExecutionLimit);
            return this;
        }
        /**
         * Specifies the limit for idle executions of a receive task, not having
         * received any message within its execution. If this limit is reached,
         * the task will shut down and leave receiving to other executing tasks
         * (in the case of dynamic scheduling; see the maxConcurrentConsumers
         * setting). There is additional doc available from Spring.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder idleTaskExecutionLimit(
                String idleTaskExecutionLimit) {
            doSetProperty("idleTaskExecutionLimit", idleTaskExecutionLimit);
            return this;
        }
        /**
         * Whether to include all JMSXxxx properties when mapping from JMS to
         * Camel Message. Setting this to true will include properties such as
         * JMSXAppID, and JMSXUserID etc. Note: If you are using a custom
         * headerFilterStrategy then this option does not apply.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder includeAllJMSXProperties(
                boolean includeAllJMSXProperties) {
            doSetProperty("includeAllJMSXProperties", includeAllJMSXProperties);
            return this;
        }
        /**
         * Whether to include all JMSXxxx properties when mapping from JMS to
         * Camel Message. Setting this to true will include properties such as
         * JMSXAppID, and JMSXUserID etc. Note: If you are using a custom
         * headerFilterStrategy then this option does not apply.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder includeAllJMSXProperties(
                String includeAllJMSXProperties) {
            doSetProperty("includeAllJMSXProperties", includeAllJMSXProperties);
            return this;
        }
        /**
         * Pluggable strategy for encoding and decoding JMS keys so they can be
         * compliant with the JMS specification. Camel provides two
         * implementations out of the box: default and passthrough. The default
         * strategy will safely marshal dots and hyphens (. and -). The
         * passthrough strategy leaves the key as is. Can be used for JMS
         * brokers which do not care whether JMS header keys contain illegal
         * characters. You can provide your own implementation of the
         * org.apache.camel.component.jms.JmsKeyFormatStrategy and refer to it
         * using the # notation.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.JmsKeyFormatStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder jmsKeyFormatStrategy(
                Object jmsKeyFormatStrategy) {
            doSetProperty("jmsKeyFormatStrategy", jmsKeyFormatStrategy);
            return this;
        }
        /**
         * Pluggable strategy for encoding and decoding JMS keys so they can be
         * compliant with the JMS specification. Camel provides two
         * implementations out of the box: default and passthrough. The default
         * strategy will safely marshal dots and hyphens (. and -). The
         * passthrough strategy leaves the key as is. Can be used for JMS
         * brokers which do not care whether JMS header keys contain illegal
         * characters. You can provide your own implementation of the
         * org.apache.camel.component.jms.JmsKeyFormatStrategy and refer to it
         * using the # notation.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.JmsKeyFormatStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder jmsKeyFormatStrategy(
                String jmsKeyFormatStrategy) {
            doSetProperty("jmsKeyFormatStrategy", jmsKeyFormatStrategy);
            return this;
        }
        /**
         * Specifies whether Camel should auto map the received JMS message to a
         * suited payload type, such as javax.jms.TextMessage to a String etc.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder mapJmsMessage(
                boolean mapJmsMessage) {
            doSetProperty("mapJmsMessage", mapJmsMessage);
            return this;
        }
        /**
         * Specifies whether Camel should auto map the received JMS message to a
         * suited payload type, such as javax.jms.TextMessage to a String etc.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder mapJmsMessage(
                String mapJmsMessage) {
            doSetProperty("mapJmsMessage", mapJmsMessage);
            return this;
        }
        /**
         * The number of messages per task. -1 is unlimited. If you use a range
         * for concurrent consumers (eg min max), then this option can be used
         * to set a value to eg 100 to control how fast the consumers will
         * shrink when less work is required.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder maxMessagesPerTask(
                int maxMessagesPerTask) {
            doSetProperty("maxMessagesPerTask", maxMessagesPerTask);
            return this;
        }
        /**
         * The number of messages per task. -1 is unlimited. If you use a range
         * for concurrent consumers (eg min max), then this option can be used
         * to set a value to eg 100 to control how fast the consumers will
         * shrink when less work is required.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder maxMessagesPerTask(
                String maxMessagesPerTask) {
            doSetProperty("maxMessagesPerTask", maxMessagesPerTask);
            return this;
        }
        /**
         * To use a custom Spring
         * org.springframework.jms.support.converter.MessageConverter so you can
         * be in control how to map to/from a javax.jms.Message.
         * 
         * The option is a:
         * <code>org.springframework.jms.support.converter.MessageConverter</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageConverter(
                Object messageConverter) {
            doSetProperty("messageConverter", messageConverter);
            return this;
        }
        /**
         * To use a custom Spring
         * org.springframework.jms.support.converter.MessageConverter so you can
         * be in control how to map to/from a javax.jms.Message.
         * 
         * The option will be converted to a
         * <code>org.springframework.jms.support.converter.MessageConverter</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageConverter(
                String messageConverter) {
            doSetProperty("messageConverter", messageConverter);
            return this;
        }
        /**
         * To use the given MessageCreatedStrategy which are invoked when Camel
         * creates new instances of javax.jms.Message objects when Camel is
         * sending a JMS message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.MessageCreatedStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageCreatedStrategy(
                Object messageCreatedStrategy) {
            doSetProperty("messageCreatedStrategy", messageCreatedStrategy);
            return this;
        }
        /**
         * To use the given MessageCreatedStrategy which are invoked when Camel
         * creates new instances of javax.jms.Message objects when Camel is
         * sending a JMS message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.MessageCreatedStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageCreatedStrategy(
                String messageCreatedStrategy) {
            doSetProperty("messageCreatedStrategy", messageCreatedStrategy);
            return this;
        }
        /**
         * When sending, specifies whether message IDs should be added. This is
         * just an hint to the JMS Broker. If the JMS provider accepts this
         * hint, these messages must have the message ID set to null; if the
         * provider ignores the hint, the message ID must be set to its normal
         * unique value.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageIdEnabled(
                boolean messageIdEnabled) {
            doSetProperty("messageIdEnabled", messageIdEnabled);
            return this;
        }
        /**
         * When sending, specifies whether message IDs should be added. This is
         * just an hint to the JMS Broker. If the JMS provider accepts this
         * hint, these messages must have the message ID set to null; if the
         * provider ignores the hint, the message ID must be set to its normal
         * unique value.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageIdEnabled(
                String messageIdEnabled) {
            doSetProperty("messageIdEnabled", messageIdEnabled);
            return this;
        }
        /**
         * Registry ID of the MessageListenerContainerFactory used to determine
         * what
         * org.springframework.jms.listener.AbstractMessageListenerContainer to
         * use to consume messages. Setting this will automatically set
         * consumerType to Custom.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.MessageListenerContainerFactory</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageListenerContainerFactory(
                Object messageListenerContainerFactory) {
            doSetProperty("messageListenerContainerFactory", messageListenerContainerFactory);
            return this;
        }
        /**
         * Registry ID of the MessageListenerContainerFactory used to determine
         * what
         * org.springframework.jms.listener.AbstractMessageListenerContainer to
         * use to consume messages. Setting this will automatically set
         * consumerType to Custom.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.MessageListenerContainerFactory</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageListenerContainerFactory(
                String messageListenerContainerFactory) {
            doSetProperty("messageListenerContainerFactory", messageListenerContainerFactory);
            return this;
        }
        /**
         * Specifies whether timestamps should be enabled by default on sending
         * messages. This is just an hint to the JMS Broker. If the JMS provider
         * accepts this hint, these messages must have the timestamp set to
         * zero; if the provider ignores the hint, the timestamp must be set to
         * its normal value.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageTimestampEnabled(
                boolean messageTimestampEnabled) {
            doSetProperty("messageTimestampEnabled", messageTimestampEnabled);
            return this;
        }
        /**
         * Specifies whether timestamps should be enabled by default on sending
         * messages. This is just an hint to the JMS Broker. If the JMS provider
         * accepts this hint, these messages must have the timestamp set to
         * zero; if the provider ignores the hint, the timestamp must be set to
         * its normal value.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder messageTimestampEnabled(
                String messageTimestampEnabled) {
            doSetProperty("messageTimestampEnabled", messageTimestampEnabled);
            return this;
        }
        /**
         * Specifies whether to inhibit the delivery of messages published by
         * its own connection.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder pubSubNoLocal(
                boolean pubSubNoLocal) {
            doSetProperty("pubSubNoLocal", pubSubNoLocal);
            return this;
        }
        /**
         * Specifies whether to inhibit the delivery of messages published by
         * its own connection.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder pubSubNoLocal(
                String pubSubNoLocal) {
            doSetProperty("pubSubNoLocal", pubSubNoLocal);
            return this;
        }
        /**
         * The timeout for receiving messages (in milliseconds).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder receiveTimeout(
                long receiveTimeout) {
            doSetProperty("receiveTimeout", receiveTimeout);
            return this;
        }
        /**
         * The timeout for receiving messages (in milliseconds).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder receiveTimeout(
                String receiveTimeout) {
            doSetProperty("receiveTimeout", receiveTimeout);
            return this;
        }
        /**
         * Specifies the interval between recovery attempts, i.e. when a
         * connection is being refreshed, in milliseconds. The default is 5000
         * ms, that is, 5 seconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder recoveryInterval(
                long recoveryInterval) {
            doSetProperty("recoveryInterval", recoveryInterval);
            return this;
        }
        /**
         * Specifies the interval between recovery attempts, i.e. when a
         * connection is being refreshed, in milliseconds. The default is 5000
         * ms, that is, 5 seconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder recoveryInterval(
                String recoveryInterval) {
            doSetProperty("recoveryInterval", recoveryInterval);
            return this;
        }
        /**
         * Configures how often Camel should check for timed out Exchanges when
         * doing request/reply over JMS. By default Camel checks once per
         * second. But if you must react faster when a timeout occurs, then you
         * can lower this interval, to check more frequently. The timeout is
         * determined by the option requestTimeout.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder requestTimeoutCheckerInterval(
                long requestTimeoutCheckerInterval) {
            doSetProperty("requestTimeoutCheckerInterval", requestTimeoutCheckerInterval);
            return this;
        }
        /**
         * Configures how often Camel should check for timed out Exchanges when
         * doing request/reply over JMS. By default Camel checks once per
         * second. But if you must react faster when a timeout occurs, then you
         * can lower this interval, to check more frequently. The timeout is
         * determined by the option requestTimeout.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder requestTimeoutCheckerInterval(
                String requestTimeoutCheckerInterval) {
            doSetProperty("requestTimeoutCheckerInterval", requestTimeoutCheckerInterval);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * If enabled and you are using Request Reply messaging (InOut) and an
         * Exchange failed on the consumer side, then the caused Exception will
         * be send back in response as a javax.jms.ObjectMessage. If the client
         * is Camel, the returned Exception is rethrown. This allows you to use
         * Camel JMS as a bridge in your routing - for example, using persistent
         * queues to enable robust routing. Notice that if you also have
         * transferExchange enabled, this option takes precedence. The caught
         * exception is required to be serializable. The original Exception on
         * the consumer side can be wrapped in an outer exception such as
         * org.apache.camel.RuntimeCamelException when returned to the producer.
         * Use this with caution as the data is using Java Object serialization
         * and requires the received to be able to deserialize the data at Class
         * level, which forces a strong coupling between the producers and
         * consumer!.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder transferException(
                boolean transferException) {
            doSetProperty("transferException", transferException);
            return this;
        }
        /**
         * If enabled and you are using Request Reply messaging (InOut) and an
         * Exchange failed on the consumer side, then the caused Exception will
         * be send back in response as a javax.jms.ObjectMessage. If the client
         * is Camel, the returned Exception is rethrown. This allows you to use
         * Camel JMS as a bridge in your routing - for example, using persistent
         * queues to enable robust routing. Notice that if you also have
         * transferExchange enabled, this option takes precedence. The caught
         * exception is required to be serializable. The original Exception on
         * the consumer side can be wrapped in an outer exception such as
         * org.apache.camel.RuntimeCamelException when returned to the producer.
         * Use this with caution as the data is using Java Object serialization
         * and requires the received to be able to deserialize the data at Class
         * level, which forces a strong coupling between the producers and
         * consumer!.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder transferException(
                String transferException) {
            doSetProperty("transferException", transferException);
            return this;
        }
        /**
         * You can transfer the exchange over the wire instead of just the body
         * and headers. The following fields are transferred: In body, Out body,
         * Fault body, In headers, Out headers, Fault headers, exchange
         * properties, exchange exception. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level. You must enable this option on both the producer
         * and consumer side, so Camel knows the payloads is an Exchange and not
         * a regular payload. Use this with caution as the data is using Java
         * Object serialization and requires the received to be able to
         * deserialize the data at Class level, which forces a strong coupling
         * between the producers and consumer having to use compatible Camel
         * versions!.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder transferExchange(
                boolean transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * You can transfer the exchange over the wire instead of just the body
         * and headers. The following fields are transferred: In body, Out body,
         * Fault body, In headers, Out headers, Fault headers, exchange
         * properties, exchange exception. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level. You must enable this option on both the producer
         * and consumer side, so Camel knows the payloads is an Exchange and not
         * a regular payload. Use this with caution as the data is using Java
         * Object serialization and requires the received to be able to
         * deserialize the data at Class level, which forces a strong coupling
         * between the producers and consumer having to use compatible Camel
         * versions!.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder transferExchange(
                String transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * Specifies whether JMSMessageID should always be used as
         * JMSCorrelationID for InOut messages.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder useMessageIDAsCorrelationID(
                boolean useMessageIDAsCorrelationID) {
            doSetProperty("useMessageIDAsCorrelationID", useMessageIDAsCorrelationID);
            return this;
        }
        /**
         * Specifies whether JMSMessageID should always be used as
         * JMSCorrelationID for InOut messages.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder useMessageIDAsCorrelationID(
                String useMessageIDAsCorrelationID) {
            doSetProperty("useMessageIDAsCorrelationID", useMessageIDAsCorrelationID);
            return this;
        }
        /**
         * Number of times to wait for provisional correlation id to be updated
         * to the actual correlation id when doing request/reply over JMS and
         * when the option useMessageIDAsCorrelationID is enabled.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder waitForProvisionCorrelationToBeUpdatedCounter(
                int waitForProvisionCorrelationToBeUpdatedCounter) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedCounter", waitForProvisionCorrelationToBeUpdatedCounter);
            return this;
        }
        /**
         * Number of times to wait for provisional correlation id to be updated
         * to the actual correlation id when doing request/reply over JMS and
         * when the option useMessageIDAsCorrelationID is enabled.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder waitForProvisionCorrelationToBeUpdatedCounter(
                String waitForProvisionCorrelationToBeUpdatedCounter) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedCounter", waitForProvisionCorrelationToBeUpdatedCounter);
            return this;
        }
        /**
         * Interval in millis to sleep each time while waiting for provisional
         * correlation id to be updated.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder waitForProvisionCorrelationToBeUpdatedThreadSleepingTime(
                long waitForProvisionCorrelationToBeUpdatedThreadSleepingTime) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedThreadSleepingTime", waitForProvisionCorrelationToBeUpdatedThreadSleepingTime);
            return this;
        }
        /**
         * Interval in millis to sleep each time while waiting for provisional
         * correlation id to be updated.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointConsumerBuilder waitForProvisionCorrelationToBeUpdatedThreadSleepingTime(
                String waitForProvisionCorrelationToBeUpdatedThreadSleepingTime) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedThreadSleepingTime", waitForProvisionCorrelationToBeUpdatedThreadSleepingTime);
            return this;
        }
        /**
         * If true, Camel will create a JmsTransactionManager, if there is no
         * transactionManager injected when option transacted=true.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder lazyCreateTransactionManager(
                boolean lazyCreateTransactionManager) {
            doSetProperty("lazyCreateTransactionManager", lazyCreateTransactionManager);
            return this;
        }
        /**
         * If true, Camel will create a JmsTransactionManager, if there is no
         * transactionManager injected when option transacted=true.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder lazyCreateTransactionManager(
                String lazyCreateTransactionManager) {
            doSetProperty("lazyCreateTransactionManager", lazyCreateTransactionManager);
            return this;
        }
        /**
         * The Spring transaction manager to use.
         * 
         * The option is a:
         * <code>org.springframework.transaction.PlatformTransactionManager</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder transactionManager(
                Object transactionManager) {
            doSetProperty("transactionManager", transactionManager);
            return this;
        }
        /**
         * The Spring transaction manager to use.
         * 
         * The option will be converted to a
         * <code>org.springframework.transaction.PlatformTransactionManager</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder transactionManager(
                String transactionManager) {
            doSetProperty("transactionManager", transactionManager);
            return this;
        }
        /**
         * The name of the transaction to use.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder transactionName(
                String transactionName) {
            doSetProperty("transactionName", transactionName);
            return this;
        }
        /**
         * The timeout value of the transaction (in seconds), if using
         * transacted mode.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder transactionTimeout(
                int transactionTimeout) {
            doSetProperty("transactionTimeout", transactionTimeout);
            return this;
        }
        /**
         * The timeout value of the transaction (in seconds), if using
         * transacted mode.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointConsumerBuilder transactionTimeout(
                String transactionTimeout) {
            doSetProperty("transactionTimeout", transactionTimeout);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the JMS component.
     */
    public interface JmsEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedJmsEndpointProducerBuilder advanced() {
            return (AdvancedJmsEndpointProducerBuilder) this;
        }
        /**
         * Sets the JMS client ID to use. Note that this value, if specified,
         * must be unique and can only be used by a single JMS connection
         * instance. It is typically only required for durable topic
         * subscriptions. If using Apache ActiveMQ you may prefer to use Virtual
         * Topics instead.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder clientId(String clientId) {
            doSetProperty("clientId", clientId);
            return this;
        }
        /**
         * Sets the default connection factory to be used if a connection
         * factory is not specified for either
         * setTemplateConnectionFactory(ConnectionFactory) or
         * setListenerConnectionFactory(ConnectionFactory).
         * 
         * The option is a: <code>javax.jms.ConnectionFactory</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder connectionFactory(
                Object connectionFactory) {
            doSetProperty("connectionFactory", connectionFactory);
            return this;
        }
        /**
         * Sets the default connection factory to be used if a connection
         * factory is not specified for either
         * setTemplateConnectionFactory(ConnectionFactory) or
         * setListenerConnectionFactory(ConnectionFactory).
         * 
         * The option will be converted to a
         * <code>javax.jms.ConnectionFactory</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder connectionFactory(
                String connectionFactory) {
            doSetProperty("connectionFactory", connectionFactory);
            return this;
        }
        /**
         * Specifies whether Camel ignores the JMSReplyTo header in messages. If
         * true, Camel does not send a reply back to the destination specified
         * in the JMSReplyTo header. You can use this option if you want Camel
         * to consume from a route and you do not want Camel to automatically
         * send back a reply message because another component in your code
         * handles the reply message. You can also use this option if you want
         * to use Camel as a proxy between different message brokers and you
         * want to route message from one system to another.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder disableReplyTo(boolean disableReplyTo) {
            doSetProperty("disableReplyTo", disableReplyTo);
            return this;
        }
        /**
         * Specifies whether Camel ignores the JMSReplyTo header in messages. If
         * true, Camel does not send a reply back to the destination specified
         * in the JMSReplyTo header. You can use this option if you want Camel
         * to consume from a route and you do not want Camel to automatically
         * send back a reply message because another component in your code
         * handles the reply message. You can also use this option if you want
         * to use Camel as a proxy between different message brokers and you
         * want to route message from one system to another.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder disableReplyTo(String disableReplyTo) {
            doSetProperty("disableReplyTo", disableReplyTo);
            return this;
        }
        /**
         * The durable subscriber name for specifying durable topic
         * subscriptions. The clientId option must be configured as well.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder durableSubscriptionName(
                String durableSubscriptionName) {
            doSetProperty("durableSubscriptionName", durableSubscriptionName);
            return this;
        }
        /**
         * Allows you to force the use of a specific javax.jms.Message
         * implementation for sending JMS messages. Possible values are: Bytes,
         * Map, Object, Stream, Text. By default, Camel would determine which
         * JMS message type to use from the In body type. This option allows you
         * to specify it.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.JmsMessageType</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder jmsMessageType(
                JmsMessageType jmsMessageType) {
            doSetProperty("jmsMessageType", jmsMessageType);
            return this;
        }
        /**
         * Allows you to force the use of a specific javax.jms.Message
         * implementation for sending JMS messages. Possible values are: Bytes,
         * Map, Object, Stream, Text. By default, Camel would determine which
         * JMS message type to use from the In body type. This option allows you
         * to specify it.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.JmsMessageType</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder jmsMessageType(String jmsMessageType) {
            doSetProperty("jmsMessageType", jmsMessageType);
            return this;
        }
        /**
         * Specifies whether to test the connection on startup. This ensures
         * that when Camel starts that all the JMS consumers have a valid
         * connection to the JMS broker. If a connection cannot be granted then
         * Camel throws an exception on startup. This ensures that Camel is not
         * started with failed connections. The JMS producers is tested as well.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder testConnectionOnStartup(
                boolean testConnectionOnStartup) {
            doSetProperty("testConnectionOnStartup", testConnectionOnStartup);
            return this;
        }
        /**
         * Specifies whether to test the connection on startup. This ensures
         * that when Camel starts that all the JMS consumers have a valid
         * connection to the JMS broker. If a connection cannot be granted then
         * Camel throws an exception on startup. This ensures that Camel is not
         * started with failed connections. The JMS producers is tested as well.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointProducerBuilder testConnectionOnStartup(
                String testConnectionOnStartup) {
            doSetProperty("testConnectionOnStartup", testConnectionOnStartup);
            return this;
        }
        /**
         * Sets delivery delay to use for send calls for JMS. This option
         * requires JMS 2.0 compliant broker.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder deliveryDelay(long deliveryDelay) {
            doSetProperty("deliveryDelay", deliveryDelay);
            return this;
        }
        /**
         * Sets delivery delay to use for send calls for JMS. This option
         * requires JMS 2.0 compliant broker.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder deliveryDelay(String deliveryDelay) {
            doSetProperty("deliveryDelay", deliveryDelay);
            return this;
        }
        /**
         * Specifies the delivery mode to be used. Possibles values are those
         * defined by javax.jms.DeliveryMode. NON_PERSISTENT = 1 and PERSISTENT
         * = 2.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder deliveryMode(Integer deliveryMode) {
            doSetProperty("deliveryMode", deliveryMode);
            return this;
        }
        /**
         * Specifies the delivery mode to be used. Possibles values are those
         * defined by javax.jms.DeliveryMode. NON_PERSISTENT = 1 and PERSISTENT
         * = 2.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder deliveryMode(String deliveryMode) {
            doSetProperty("deliveryMode", deliveryMode);
            return this;
        }
        /**
         * Specifies whether persistent delivery is used by default.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder deliveryPersistent(
                boolean deliveryPersistent) {
            doSetProperty("deliveryPersistent", deliveryPersistent);
            return this;
        }
        /**
         * Specifies whether persistent delivery is used by default.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder deliveryPersistent(
                String deliveryPersistent) {
            doSetProperty("deliveryPersistent", deliveryPersistent);
            return this;
        }
        /**
         * Set if the deliveryMode, priority or timeToLive qualities of service
         * should be used when sending messages. This option is based on
         * Spring's JmsTemplate. The deliveryMode, priority and timeToLive
         * options are applied to the current endpoint. This contrasts with the
         * preserveMessageQos option, which operates at message granularity,
         * reading QoS properties exclusively from the Camel In message headers.
         * 
         * The option is a: <code>java.lang.Boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder explicitQosEnabled(
                Boolean explicitQosEnabled) {
            doSetProperty("explicitQosEnabled", explicitQosEnabled);
            return this;
        }
        /**
         * Set if the deliveryMode, priority or timeToLive qualities of service
         * should be used when sending messages. This option is based on
         * Spring's JmsTemplate. The deliveryMode, priority and timeToLive
         * options are applied to the current endpoint. This contrasts with the
         * preserveMessageQos option, which operates at message granularity,
         * reading QoS properties exclusively from the Camel In message headers.
         * 
         * The option will be converted to a <code>java.lang.Boolean</code>
         * type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder explicitQosEnabled(
                String explicitQosEnabled) {
            doSetProperty("explicitQosEnabled", explicitQosEnabled);
            return this;
        }
        /**
         * Sets whether date headers should be formatted according to the ISO
         * 8601 standard.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder formatDateHeadersToIso8601(
                boolean formatDateHeadersToIso8601) {
            doSetProperty("formatDateHeadersToIso8601", formatDateHeadersToIso8601);
            return this;
        }
        /**
         * Sets whether date headers should be formatted according to the ISO
         * 8601 standard.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder formatDateHeadersToIso8601(
                String formatDateHeadersToIso8601) {
            doSetProperty("formatDateHeadersToIso8601", formatDateHeadersToIso8601);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder lazyStartProducer(
                boolean lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Set to true, if you want to send message using the QoS settings
         * specified on the message, instead of the QoS settings on the JMS
         * endpoint. The following three headers are considered JMSPriority,
         * JMSDeliveryMode, and JMSExpiration. You can provide all or only some
         * of them. If not provided, Camel will fall back to use the values from
         * the endpoint instead. So, when using this option, the headers
         * override the values from the endpoint. The explicitQosEnabled option,
         * by contrast, will only use options set on the endpoint, and not
         * values from the message header.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder preserveMessageQos(
                boolean preserveMessageQos) {
            doSetProperty("preserveMessageQos", preserveMessageQos);
            return this;
        }
        /**
         * Set to true, if you want to send message using the QoS settings
         * specified on the message, instead of the QoS settings on the JMS
         * endpoint. The following three headers are considered JMSPriority,
         * JMSDeliveryMode, and JMSExpiration. You can provide all or only some
         * of them. If not provided, Camel will fall back to use the values from
         * the endpoint instead. So, when using this option, the headers
         * override the values from the endpoint. The explicitQosEnabled option,
         * by contrast, will only use options set on the endpoint, and not
         * values from the message header.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder preserveMessageQos(
                String preserveMessageQos) {
            doSetProperty("preserveMessageQos", preserveMessageQos);
            return this;
        }
        /**
         * Values greater than 1 specify the message priority when sending
         * (where 0 is the lowest priority and 9 is the highest). The
         * explicitQosEnabled option must also be enabled in order for this
         * option to have any effect.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder priority(int priority) {
            doSetProperty("priority", priority);
            return this;
        }
        /**
         * Values greater than 1 specify the message priority when sending
         * (where 0 is the lowest priority and 9 is the highest). The
         * explicitQosEnabled option must also be enabled in order for this
         * option to have any effect.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder priority(String priority) {
            doSetProperty("priority", priority);
            return this;
        }
        /**
         * Specifies the default number of concurrent consumers when doing
         * request/reply over JMS. See also the maxMessagesPerTask option to
         * control dynamic scaling up/down of threads.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToConcurrentConsumers(
                int replyToConcurrentConsumers) {
            doSetProperty("replyToConcurrentConsumers", replyToConcurrentConsumers);
            return this;
        }
        /**
         * Specifies the default number of concurrent consumers when doing
         * request/reply over JMS. See also the maxMessagesPerTask option to
         * control dynamic scaling up/down of threads.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToConcurrentConsumers(
                String replyToConcurrentConsumers) {
            doSetProperty("replyToConcurrentConsumers", replyToConcurrentConsumers);
            return this;
        }
        /**
         * Specifies the maximum number of concurrent consumers when using
         * request/reply over JMS. See also the maxMessagesPerTask option to
         * control dynamic scaling up/down of threads.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToMaxConcurrentConsumers(
                int replyToMaxConcurrentConsumers) {
            doSetProperty("replyToMaxConcurrentConsumers", replyToMaxConcurrentConsumers);
            return this;
        }
        /**
         * Specifies the maximum number of concurrent consumers when using
         * request/reply over JMS. See also the maxMessagesPerTask option to
         * control dynamic scaling up/down of threads.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToMaxConcurrentConsumers(
                String replyToMaxConcurrentConsumers) {
            doSetProperty("replyToMaxConcurrentConsumers", replyToMaxConcurrentConsumers);
            return this;
        }
        /**
         * Specifies the maximum number of concurrent consumers for continue
         * routing when timeout occurred when using request/reply over JMS.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToOnTimeoutMaxConcurrentConsumers(
                int replyToOnTimeoutMaxConcurrentConsumers) {
            doSetProperty("replyToOnTimeoutMaxConcurrentConsumers", replyToOnTimeoutMaxConcurrentConsumers);
            return this;
        }
        /**
         * Specifies the maximum number of concurrent consumers for continue
         * routing when timeout occurred when using request/reply over JMS.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToOnTimeoutMaxConcurrentConsumers(
                String replyToOnTimeoutMaxConcurrentConsumers) {
            doSetProperty("replyToOnTimeoutMaxConcurrentConsumers", replyToOnTimeoutMaxConcurrentConsumers);
            return this;
        }
        /**
         * Provides an explicit ReplyTo destination in the JMS message, which
         * overrides the setting of replyTo. It is useful if you want to forward
         * the message to a remote Queue and receive the reply message from the
         * ReplyTo destination.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToOverride(
                String replyToOverride) {
            doSetProperty("replyToOverride", replyToOverride);
            return this;
        }
        /**
         * Allows for explicitly specifying which kind of strategy to use for
         * replyTo queues when doing request/reply over JMS. Possible values
         * are: Temporary, Shared, or Exclusive. By default Camel will use
         * temporary queues. However if replyTo has been configured, then Shared
         * is used by default. This option allows you to use exclusive queues
         * instead of shared ones. See Camel JMS documentation for more details,
         * and especially the notes about the implications if running in a
         * clustered environment, and the fact that Shared reply queues has
         * lower performance than its alternatives Temporary and Exclusive.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.ReplyToType</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToType(ReplyToType replyToType) {
            doSetProperty("replyToType", replyToType);
            return this;
        }
        /**
         * Allows for explicitly specifying which kind of strategy to use for
         * replyTo queues when doing request/reply over JMS. Possible values
         * are: Temporary, Shared, or Exclusive. By default Camel will use
         * temporary queues. However if replyTo has been configured, then Shared
         * is used by default. This option allows you to use exclusive queues
         * instead of shared ones. See Camel JMS documentation for more details,
         * and especially the notes about the implications if running in a
         * clustered environment, and the fact that Shared reply queues has
         * lower performance than its alternatives Temporary and Exclusive.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.ReplyToType</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder replyToType(String replyToType) {
            doSetProperty("replyToType", replyToType);
            return this;
        }
        /**
         * The timeout for waiting for a reply when using the InOut Exchange
         * Pattern (in milliseconds). The default is 20 seconds. You can include
         * the header CamelJmsRequestTimeout to override this endpoint
         * configured timeout value, and thus have per message individual
         * timeout values. See also the requestTimeoutCheckerInterval option.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder requestTimeout(long requestTimeout) {
            doSetProperty("requestTimeout", requestTimeout);
            return this;
        }
        /**
         * The timeout for waiting for a reply when using the InOut Exchange
         * Pattern (in milliseconds). The default is 20 seconds. You can include
         * the header CamelJmsRequestTimeout to override this endpoint
         * configured timeout value, and thus have per message individual
         * timeout values. See also the requestTimeoutCheckerInterval option.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder requestTimeout(String requestTimeout) {
            doSetProperty("requestTimeout", requestTimeout);
            return this;
        }
        /**
         * When sending messages, specifies the time-to-live of the message (in
         * milliseconds).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder timeToLive(long timeToLive) {
            doSetProperty("timeToLive", timeToLive);
            return this;
        }
        /**
         * When sending messages, specifies the time-to-live of the message (in
         * milliseconds).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: producer
         */
        default JmsEndpointProducerBuilder timeToLive(String timeToLive) {
            doSetProperty("timeToLive", timeToLive);
            return this;
        }
        /**
         * Password to use with the ConnectionFactory. You can also configure
         * username/password directly on the ConnectionFactory.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default JmsEndpointProducerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Username to use with the ConnectionFactory. You can also configure
         * username/password directly on the ConnectionFactory.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default JmsEndpointProducerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * Specifies whether to use transacted mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: transaction
         */
        default JmsEndpointProducerBuilder transacted(boolean transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
        /**
         * Specifies whether to use transacted mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: transaction
         */
        default JmsEndpointProducerBuilder transacted(String transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the JMS component.
     */
    public interface AdvancedJmsEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default JmsEndpointProducerBuilder basic() {
            return (JmsEndpointProducerBuilder) this;
        }
        /**
         * This option is used to allow additional headers which may have values
         * that are invalid according to JMS specification. For example some
         * message systems such as WMQ do this with header names using prefix
         * JMS_IBM_MQMD_ containing values with byte array or other invalid
         * types. You can specify multiple header names separated by comma, and
         * use as suffix for wildcard matching.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder allowAdditionalHeaders(
                String allowAdditionalHeaders) {
            doSetProperty("allowAdditionalHeaders", allowAdditionalHeaders);
            return this;
        }
        /**
         * Whether to allow sending messages with no body. If this option is
         * false and the message body is null, then an JMSException is thrown.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder allowNullBody(
                boolean allowNullBody) {
            doSetProperty("allowNullBody", allowNullBody);
            return this;
        }
        /**
         * Whether to allow sending messages with no body. If this option is
         * false and the message body is null, then an JMSException is thrown.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder allowNullBody(
                String allowNullBody) {
            doSetProperty("allowNullBody", allowNullBody);
            return this;
        }
        /**
         * If true, Camel will always make a JMS message copy of the message
         * when it is passed to the producer for sending. Copying the message is
         * needed in some situations, such as when a
         * replyToDestinationSelectorName is set (incidentally, Camel will set
         * the alwaysCopyMessage option to true, if a
         * replyToDestinationSelectorName is set).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder alwaysCopyMessage(
                boolean alwaysCopyMessage) {
            doSetProperty("alwaysCopyMessage", alwaysCopyMessage);
            return this;
        }
        /**
         * If true, Camel will always make a JMS message copy of the message
         * when it is passed to the producer for sending. Copying the message is
         * needed in some situations, such as when a
         * replyToDestinationSelectorName is set (incidentally, Camel will set
         * the alwaysCopyMessage option to true, if a
         * replyToDestinationSelectorName is set).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder alwaysCopyMessage(
                String alwaysCopyMessage) {
            doSetProperty("alwaysCopyMessage", alwaysCopyMessage);
            return this;
        }
        /**
         * Use this JMS property to correlate messages in InOut exchange pattern
         * (request-reply) instead of JMSCorrelationID property. This allows you
         * to exchange messages with systems that do not correlate messages
         * using JMSCorrelationID JMS property. If used JMSCorrelationID will
         * not be used or set by Camel. The value of here named property will be
         * generated if not supplied in the header of the message under the same
         * name.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder correlationProperty(
                String correlationProperty) {
            doSetProperty("correlationProperty", correlationProperty);
            return this;
        }
        /**
         * Use this option to force disabling time to live. For example when you
         * do request/reply over JMS, then Camel will by default use the
         * requestTimeout value as time to live on the message being sent. The
         * problem is that the sender and receiver systems have to have their
         * clocks synchronized, so they are in sync. This is not always so easy
         * to archive. So you can use disableTimeToLive=true to not set a time
         * to live value on the sent message. Then the message will not expire
         * on the receiver system. See below in section About time to live for
         * more details.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder disableTimeToLive(
                boolean disableTimeToLive) {
            doSetProperty("disableTimeToLive", disableTimeToLive);
            return this;
        }
        /**
         * Use this option to force disabling time to live. For example when you
         * do request/reply over JMS, then Camel will by default use the
         * requestTimeout value as time to live on the message being sent. The
         * problem is that the sender and receiver systems have to have their
         * clocks synchronized, so they are in sync. This is not always so easy
         * to archive. So you can use disableTimeToLive=true to not set a time
         * to live value on the sent message. Then the message will not expire
         * on the receiver system. See below in section About time to live for
         * more details.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder disableTimeToLive(
                String disableTimeToLive) {
            doSetProperty("disableTimeToLive", disableTimeToLive);
            return this;
        }
        /**
         * When using mapJmsMessage=false Camel will create a new JMS message to
         * send to a new JMS destination if you touch the headers (get or set)
         * during the route. Set this option to true to force Camel to send the
         * original JMS message that was received.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder forceSendOriginalMessage(
                boolean forceSendOriginalMessage) {
            doSetProperty("forceSendOriginalMessage", forceSendOriginalMessage);
            return this;
        }
        /**
         * When using mapJmsMessage=false Camel will create a new JMS message to
         * send to a new JMS destination if you touch the headers (get or set)
         * during the route. Set this option to true to force Camel to send the
         * original JMS message that was received.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder forceSendOriginalMessage(
                String forceSendOriginalMessage) {
            doSetProperty("forceSendOriginalMessage", forceSendOriginalMessage);
            return this;
        }
        /**
         * Only applicable when sending to JMS destination using InOnly (eg fire
         * and forget). Enabling this option will enrich the Camel Exchange with
         * the actual JMSMessageID that was used by the JMS client when the
         * message was sent to the JMS destination.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder includeSentJMSMessageID(
                boolean includeSentJMSMessageID) {
            doSetProperty("includeSentJMSMessageID", includeSentJMSMessageID);
            return this;
        }
        /**
         * Only applicable when sending to JMS destination using InOnly (eg fire
         * and forget). Enabling this option will enrich the Camel Exchange with
         * the actual JMSMessageID that was used by the JMS client when the
         * message was sent to the JMS destination.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder includeSentJMSMessageID(
                String includeSentJMSMessageID) {
            doSetProperty("includeSentJMSMessageID", includeSentJMSMessageID);
            return this;
        }
        /**
         * Sets the cache level by name for the reply consumer when doing
         * request/reply over JMS. This option only applies when using fixed
         * reply queues (not temporary). Camel will by default use:
         * CACHE_CONSUMER for exclusive or shared w/ replyToSelectorName. And
         * CACHE_SESSION for shared without replyToSelectorName. Some JMS
         * brokers such as IBM WebSphere may require to set the
         * replyToCacheLevelName=CACHE_NONE to work. Note: If using temporary
         * queues then CACHE_NONE is not allowed, and you must use a higher
         * value such as CACHE_CONSUMER or CACHE_SESSION.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder replyToCacheLevelName(
                String replyToCacheLevelName) {
            doSetProperty("replyToCacheLevelName", replyToCacheLevelName);
            return this;
        }
        /**
         * Sets the JMS Selector using the fixed name to be used so you can
         * filter out your own replies from the others when using a shared queue
         * (that is, if you are not using a temporary reply queue).
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder replyToDestinationSelectorName(
                String replyToDestinationSelectorName) {
            doSetProperty("replyToDestinationSelectorName", replyToDestinationSelectorName);
            return this;
        }
        /**
         * Sets whether StreamMessage type is enabled or not. Message payloads
         * of streaming kind such as files, InputStream, etc will either by sent
         * as BytesMessage or StreamMessage. This option controls which kind
         * will be used. By default BytesMessage is used which enforces the
         * entire message payload to be read into memory. By enabling this
         * option the message payload is read into memory in chunks and each
         * chunk is then written to the StreamMessage until no more data.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder streamMessageTypeEnabled(
                boolean streamMessageTypeEnabled) {
            doSetProperty("streamMessageTypeEnabled", streamMessageTypeEnabled);
            return this;
        }
        /**
         * Sets whether StreamMessage type is enabled or not. Message payloads
         * of streaming kind such as files, InputStream, etc will either by sent
         * as BytesMessage or StreamMessage. This option controls which kind
         * will be used. By default BytesMessage is used which enforces the
         * entire message payload to be read into memory. By enabling this
         * option the message payload is read into memory in chunks and each
         * chunk is then written to the StreamMessage until no more data.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder streamMessageTypeEnabled(
                String streamMessageTypeEnabled) {
            doSetProperty("streamMessageTypeEnabled", streamMessageTypeEnabled);
            return this;
        }
        /**
         * Controls whether or not to include serialized headers. Applies only
         * when isTransferExchange() is true. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder allowSerializedHeaders(
                boolean allowSerializedHeaders) {
            doSetProperty("allowSerializedHeaders", allowSerializedHeaders);
            return this;
        }
        /**
         * Controls whether or not to include serialized headers. Applies only
         * when isTransferExchange() is true. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder allowSerializedHeaders(
                String allowSerializedHeaders) {
            doSetProperty("allowSerializedHeaders", allowSerializedHeaders);
            return this;
        }
        /**
         * Whether to startup the JmsConsumer message listener asynchronously,
         * when starting a route. For example if a JmsConsumer cannot get a
         * connection to a remote JMS broker, then it may block while retrying
         * and/or failover. This will cause Camel to block while starting
         * routes. By setting this option to true, you will let routes startup,
         * while the JmsConsumer connects to the JMS broker using a dedicated
         * thread in asynchronous mode. If this option is used, then beware that
         * if the connection could not be established, then an exception is
         * logged at WARN level, and the consumer will not be able to receive
         * messages; You can then restart the route to retry.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder asyncStartListener(
                boolean asyncStartListener) {
            doSetProperty("asyncStartListener", asyncStartListener);
            return this;
        }
        /**
         * Whether to startup the JmsConsumer message listener asynchronously,
         * when starting a route. For example if a JmsConsumer cannot get a
         * connection to a remote JMS broker, then it may block while retrying
         * and/or failover. This will cause Camel to block while starting
         * routes. By setting this option to true, you will let routes startup,
         * while the JmsConsumer connects to the JMS broker using a dedicated
         * thread in asynchronous mode. If this option is used, then beware that
         * if the connection could not be established, then an exception is
         * logged at WARN level, and the consumer will not be able to receive
         * messages; You can then restart the route to retry.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder asyncStartListener(
                String asyncStartListener) {
            doSetProperty("asyncStartListener", asyncStartListener);
            return this;
        }
        /**
         * Whether to stop the JmsConsumer message listener asynchronously, when
         * stopping a route.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder asyncStopListener(
                boolean asyncStopListener) {
            doSetProperty("asyncStopListener", asyncStopListener);
            return this;
        }
        /**
         * Whether to stop the JmsConsumer message listener asynchronously, when
         * stopping a route.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder asyncStopListener(
                String asyncStopListener) {
            doSetProperty("asyncStopListener", asyncStopListener);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * A pluggable
         * org.springframework.jms.support.destination.DestinationResolver that
         * allows you to use your own resolver (for example, to lookup the real
         * destination in a JNDI registry).
         * 
         * The option is a:
         * <code>org.springframework.jms.support.destination.DestinationResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder destinationResolver(
                Object destinationResolver) {
            doSetProperty("destinationResolver", destinationResolver);
            return this;
        }
        /**
         * A pluggable
         * org.springframework.jms.support.destination.DestinationResolver that
         * allows you to use your own resolver (for example, to lookup the real
         * destination in a JNDI registry).
         * 
         * The option will be converted to a
         * <code>org.springframework.jms.support.destination.DestinationResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder destinationResolver(
                String destinationResolver) {
            doSetProperty("destinationResolver", destinationResolver);
            return this;
        }
        /**
         * Specifies a org.springframework.util.ErrorHandler to be invoked in
         * case of any uncaught exceptions thrown while processing a Message. By
         * default these exceptions will be logged at the WARN level, if no
         * errorHandler has been configured. You can configure logging level and
         * whether stack traces should be logged using errorHandlerLoggingLevel
         * and errorHandlerLogStackTrace options. This makes it much easier to
         * configure, than having to code a custom errorHandler.
         * 
         * The option is a: <code>org.springframework.util.ErrorHandler</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder errorHandler(
                Object errorHandler) {
            doSetProperty("errorHandler", errorHandler);
            return this;
        }
        /**
         * Specifies a org.springframework.util.ErrorHandler to be invoked in
         * case of any uncaught exceptions thrown while processing a Message. By
         * default these exceptions will be logged at the WARN level, if no
         * errorHandler has been configured. You can configure logging level and
         * whether stack traces should be logged using errorHandlerLoggingLevel
         * and errorHandlerLogStackTrace options. This makes it much easier to
         * configure, than having to code a custom errorHandler.
         * 
         * The option will be converted to a
         * <code>org.springframework.util.ErrorHandler</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder errorHandler(
                String errorHandler) {
            doSetProperty("errorHandler", errorHandler);
            return this;
        }
        /**
         * Specifies the JMS Exception Listener that is to be notified of any
         * underlying JMS exceptions.
         * 
         * The option is a: <code>javax.jms.ExceptionListener</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder exceptionListener(
                Object exceptionListener) {
            doSetProperty("exceptionListener", exceptionListener);
            return this;
        }
        /**
         * Specifies the JMS Exception Listener that is to be notified of any
         * underlying JMS exceptions.
         * 
         * The option will be converted to a
         * <code>javax.jms.ExceptionListener</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder exceptionListener(
                String exceptionListener) {
            doSetProperty("exceptionListener", exceptionListener);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Specify the limit for the number of consumers that are allowed to be
         * idle at any given time.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder idleConsumerLimit(
                int idleConsumerLimit) {
            doSetProperty("idleConsumerLimit", idleConsumerLimit);
            return this;
        }
        /**
         * Specify the limit for the number of consumers that are allowed to be
         * idle at any given time.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder idleConsumerLimit(
                String idleConsumerLimit) {
            doSetProperty("idleConsumerLimit", idleConsumerLimit);
            return this;
        }
        /**
         * Specifies the limit for idle executions of a receive task, not having
         * received any message within its execution. If this limit is reached,
         * the task will shut down and leave receiving to other executing tasks
         * (in the case of dynamic scheduling; see the maxConcurrentConsumers
         * setting). There is additional doc available from Spring.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder idleTaskExecutionLimit(
                int idleTaskExecutionLimit) {
            doSetProperty("idleTaskExecutionLimit", idleTaskExecutionLimit);
            return this;
        }
        /**
         * Specifies the limit for idle executions of a receive task, not having
         * received any message within its execution. If this limit is reached,
         * the task will shut down and leave receiving to other executing tasks
         * (in the case of dynamic scheduling; see the maxConcurrentConsumers
         * setting). There is additional doc available from Spring.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder idleTaskExecutionLimit(
                String idleTaskExecutionLimit) {
            doSetProperty("idleTaskExecutionLimit", idleTaskExecutionLimit);
            return this;
        }
        /**
         * Whether to include all JMSXxxx properties when mapping from JMS to
         * Camel Message. Setting this to true will include properties such as
         * JMSXAppID, and JMSXUserID etc. Note: If you are using a custom
         * headerFilterStrategy then this option does not apply.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder includeAllJMSXProperties(
                boolean includeAllJMSXProperties) {
            doSetProperty("includeAllJMSXProperties", includeAllJMSXProperties);
            return this;
        }
        /**
         * Whether to include all JMSXxxx properties when mapping from JMS to
         * Camel Message. Setting this to true will include properties such as
         * JMSXAppID, and JMSXUserID etc. Note: If you are using a custom
         * headerFilterStrategy then this option does not apply.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder includeAllJMSXProperties(
                String includeAllJMSXProperties) {
            doSetProperty("includeAllJMSXProperties", includeAllJMSXProperties);
            return this;
        }
        /**
         * Pluggable strategy for encoding and decoding JMS keys so they can be
         * compliant with the JMS specification. Camel provides two
         * implementations out of the box: default and passthrough. The default
         * strategy will safely marshal dots and hyphens (. and -). The
         * passthrough strategy leaves the key as is. Can be used for JMS
         * brokers which do not care whether JMS header keys contain illegal
         * characters. You can provide your own implementation of the
         * org.apache.camel.component.jms.JmsKeyFormatStrategy and refer to it
         * using the # notation.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.JmsKeyFormatStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder jmsKeyFormatStrategy(
                Object jmsKeyFormatStrategy) {
            doSetProperty("jmsKeyFormatStrategy", jmsKeyFormatStrategy);
            return this;
        }
        /**
         * Pluggable strategy for encoding and decoding JMS keys so they can be
         * compliant with the JMS specification. Camel provides two
         * implementations out of the box: default and passthrough. The default
         * strategy will safely marshal dots and hyphens (. and -). The
         * passthrough strategy leaves the key as is. Can be used for JMS
         * brokers which do not care whether JMS header keys contain illegal
         * characters. You can provide your own implementation of the
         * org.apache.camel.component.jms.JmsKeyFormatStrategy and refer to it
         * using the # notation.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.JmsKeyFormatStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder jmsKeyFormatStrategy(
                String jmsKeyFormatStrategy) {
            doSetProperty("jmsKeyFormatStrategy", jmsKeyFormatStrategy);
            return this;
        }
        /**
         * Specifies whether Camel should auto map the received JMS message to a
         * suited payload type, such as javax.jms.TextMessage to a String etc.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder mapJmsMessage(
                boolean mapJmsMessage) {
            doSetProperty("mapJmsMessage", mapJmsMessage);
            return this;
        }
        /**
         * Specifies whether Camel should auto map the received JMS message to a
         * suited payload type, such as javax.jms.TextMessage to a String etc.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder mapJmsMessage(
                String mapJmsMessage) {
            doSetProperty("mapJmsMessage", mapJmsMessage);
            return this;
        }
        /**
         * The number of messages per task. -1 is unlimited. If you use a range
         * for concurrent consumers (eg min max), then this option can be used
         * to set a value to eg 100 to control how fast the consumers will
         * shrink when less work is required.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder maxMessagesPerTask(
                int maxMessagesPerTask) {
            doSetProperty("maxMessagesPerTask", maxMessagesPerTask);
            return this;
        }
        /**
         * The number of messages per task. -1 is unlimited. If you use a range
         * for concurrent consumers (eg min max), then this option can be used
         * to set a value to eg 100 to control how fast the consumers will
         * shrink when less work is required.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder maxMessagesPerTask(
                String maxMessagesPerTask) {
            doSetProperty("maxMessagesPerTask", maxMessagesPerTask);
            return this;
        }
        /**
         * To use a custom Spring
         * org.springframework.jms.support.converter.MessageConverter so you can
         * be in control how to map to/from a javax.jms.Message.
         * 
         * The option is a:
         * <code>org.springframework.jms.support.converter.MessageConverter</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageConverter(
                Object messageConverter) {
            doSetProperty("messageConverter", messageConverter);
            return this;
        }
        /**
         * To use a custom Spring
         * org.springframework.jms.support.converter.MessageConverter so you can
         * be in control how to map to/from a javax.jms.Message.
         * 
         * The option will be converted to a
         * <code>org.springframework.jms.support.converter.MessageConverter</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageConverter(
                String messageConverter) {
            doSetProperty("messageConverter", messageConverter);
            return this;
        }
        /**
         * To use the given MessageCreatedStrategy which are invoked when Camel
         * creates new instances of javax.jms.Message objects when Camel is
         * sending a JMS message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.MessageCreatedStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageCreatedStrategy(
                Object messageCreatedStrategy) {
            doSetProperty("messageCreatedStrategy", messageCreatedStrategy);
            return this;
        }
        /**
         * To use the given MessageCreatedStrategy which are invoked when Camel
         * creates new instances of javax.jms.Message objects when Camel is
         * sending a JMS message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.MessageCreatedStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageCreatedStrategy(
                String messageCreatedStrategy) {
            doSetProperty("messageCreatedStrategy", messageCreatedStrategy);
            return this;
        }
        /**
         * When sending, specifies whether message IDs should be added. This is
         * just an hint to the JMS Broker. If the JMS provider accepts this
         * hint, these messages must have the message ID set to null; if the
         * provider ignores the hint, the message ID must be set to its normal
         * unique value.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageIdEnabled(
                boolean messageIdEnabled) {
            doSetProperty("messageIdEnabled", messageIdEnabled);
            return this;
        }
        /**
         * When sending, specifies whether message IDs should be added. This is
         * just an hint to the JMS Broker. If the JMS provider accepts this
         * hint, these messages must have the message ID set to null; if the
         * provider ignores the hint, the message ID must be set to its normal
         * unique value.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageIdEnabled(
                String messageIdEnabled) {
            doSetProperty("messageIdEnabled", messageIdEnabled);
            return this;
        }
        /**
         * Registry ID of the MessageListenerContainerFactory used to determine
         * what
         * org.springframework.jms.listener.AbstractMessageListenerContainer to
         * use to consume messages. Setting this will automatically set
         * consumerType to Custom.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.MessageListenerContainerFactory</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageListenerContainerFactory(
                Object messageListenerContainerFactory) {
            doSetProperty("messageListenerContainerFactory", messageListenerContainerFactory);
            return this;
        }
        /**
         * Registry ID of the MessageListenerContainerFactory used to determine
         * what
         * org.springframework.jms.listener.AbstractMessageListenerContainer to
         * use to consume messages. Setting this will automatically set
         * consumerType to Custom.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.MessageListenerContainerFactory</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageListenerContainerFactory(
                String messageListenerContainerFactory) {
            doSetProperty("messageListenerContainerFactory", messageListenerContainerFactory);
            return this;
        }
        /**
         * Specifies whether timestamps should be enabled by default on sending
         * messages. This is just an hint to the JMS Broker. If the JMS provider
         * accepts this hint, these messages must have the timestamp set to
         * zero; if the provider ignores the hint, the timestamp must be set to
         * its normal value.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageTimestampEnabled(
                boolean messageTimestampEnabled) {
            doSetProperty("messageTimestampEnabled", messageTimestampEnabled);
            return this;
        }
        /**
         * Specifies whether timestamps should be enabled by default on sending
         * messages. This is just an hint to the JMS Broker. If the JMS provider
         * accepts this hint, these messages must have the timestamp set to
         * zero; if the provider ignores the hint, the timestamp must be set to
         * its normal value.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder messageTimestampEnabled(
                String messageTimestampEnabled) {
            doSetProperty("messageTimestampEnabled", messageTimestampEnabled);
            return this;
        }
        /**
         * Specifies whether to inhibit the delivery of messages published by
         * its own connection.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder pubSubNoLocal(
                boolean pubSubNoLocal) {
            doSetProperty("pubSubNoLocal", pubSubNoLocal);
            return this;
        }
        /**
         * Specifies whether to inhibit the delivery of messages published by
         * its own connection.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder pubSubNoLocal(
                String pubSubNoLocal) {
            doSetProperty("pubSubNoLocal", pubSubNoLocal);
            return this;
        }
        /**
         * The timeout for receiving messages (in milliseconds).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder receiveTimeout(
                long receiveTimeout) {
            doSetProperty("receiveTimeout", receiveTimeout);
            return this;
        }
        /**
         * The timeout for receiving messages (in milliseconds).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder receiveTimeout(
                String receiveTimeout) {
            doSetProperty("receiveTimeout", receiveTimeout);
            return this;
        }
        /**
         * Specifies the interval between recovery attempts, i.e. when a
         * connection is being refreshed, in milliseconds. The default is 5000
         * ms, that is, 5 seconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder recoveryInterval(
                long recoveryInterval) {
            doSetProperty("recoveryInterval", recoveryInterval);
            return this;
        }
        /**
         * Specifies the interval between recovery attempts, i.e. when a
         * connection is being refreshed, in milliseconds. The default is 5000
         * ms, that is, 5 seconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder recoveryInterval(
                String recoveryInterval) {
            doSetProperty("recoveryInterval", recoveryInterval);
            return this;
        }
        /**
         * Configures how often Camel should check for timed out Exchanges when
         * doing request/reply over JMS. By default Camel checks once per
         * second. But if you must react faster when a timeout occurs, then you
         * can lower this interval, to check more frequently. The timeout is
         * determined by the option requestTimeout.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder requestTimeoutCheckerInterval(
                long requestTimeoutCheckerInterval) {
            doSetProperty("requestTimeoutCheckerInterval", requestTimeoutCheckerInterval);
            return this;
        }
        /**
         * Configures how often Camel should check for timed out Exchanges when
         * doing request/reply over JMS. By default Camel checks once per
         * second. But if you must react faster when a timeout occurs, then you
         * can lower this interval, to check more frequently. The timeout is
         * determined by the option requestTimeout.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder requestTimeoutCheckerInterval(
                String requestTimeoutCheckerInterval) {
            doSetProperty("requestTimeoutCheckerInterval", requestTimeoutCheckerInterval);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * If enabled and you are using Request Reply messaging (InOut) and an
         * Exchange failed on the consumer side, then the caused Exception will
         * be send back in response as a javax.jms.ObjectMessage. If the client
         * is Camel, the returned Exception is rethrown. This allows you to use
         * Camel JMS as a bridge in your routing - for example, using persistent
         * queues to enable robust routing. Notice that if you also have
         * transferExchange enabled, this option takes precedence. The caught
         * exception is required to be serializable. The original Exception on
         * the consumer side can be wrapped in an outer exception such as
         * org.apache.camel.RuntimeCamelException when returned to the producer.
         * Use this with caution as the data is using Java Object serialization
         * and requires the received to be able to deserialize the data at Class
         * level, which forces a strong coupling between the producers and
         * consumer!.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder transferException(
                boolean transferException) {
            doSetProperty("transferException", transferException);
            return this;
        }
        /**
         * If enabled and you are using Request Reply messaging (InOut) and an
         * Exchange failed on the consumer side, then the caused Exception will
         * be send back in response as a javax.jms.ObjectMessage. If the client
         * is Camel, the returned Exception is rethrown. This allows you to use
         * Camel JMS as a bridge in your routing - for example, using persistent
         * queues to enable robust routing. Notice that if you also have
         * transferExchange enabled, this option takes precedence. The caught
         * exception is required to be serializable. The original Exception on
         * the consumer side can be wrapped in an outer exception such as
         * org.apache.camel.RuntimeCamelException when returned to the producer.
         * Use this with caution as the data is using Java Object serialization
         * and requires the received to be able to deserialize the data at Class
         * level, which forces a strong coupling between the producers and
         * consumer!.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder transferException(
                String transferException) {
            doSetProperty("transferException", transferException);
            return this;
        }
        /**
         * You can transfer the exchange over the wire instead of just the body
         * and headers. The following fields are transferred: In body, Out body,
         * Fault body, In headers, Out headers, Fault headers, exchange
         * properties, exchange exception. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level. You must enable this option on both the producer
         * and consumer side, so Camel knows the payloads is an Exchange and not
         * a regular payload. Use this with caution as the data is using Java
         * Object serialization and requires the received to be able to
         * deserialize the data at Class level, which forces a strong coupling
         * between the producers and consumer having to use compatible Camel
         * versions!.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder transferExchange(
                boolean transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * You can transfer the exchange over the wire instead of just the body
         * and headers. The following fields are transferred: In body, Out body,
         * Fault body, In headers, Out headers, Fault headers, exchange
         * properties, exchange exception. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level. You must enable this option on both the producer
         * and consumer side, so Camel knows the payloads is an Exchange and not
         * a regular payload. Use this with caution as the data is using Java
         * Object serialization and requires the received to be able to
         * deserialize the data at Class level, which forces a strong coupling
         * between the producers and consumer having to use compatible Camel
         * versions!.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder transferExchange(
                String transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * Specifies whether JMSMessageID should always be used as
         * JMSCorrelationID for InOut messages.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder useMessageIDAsCorrelationID(
                boolean useMessageIDAsCorrelationID) {
            doSetProperty("useMessageIDAsCorrelationID", useMessageIDAsCorrelationID);
            return this;
        }
        /**
         * Specifies whether JMSMessageID should always be used as
         * JMSCorrelationID for InOut messages.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder useMessageIDAsCorrelationID(
                String useMessageIDAsCorrelationID) {
            doSetProperty("useMessageIDAsCorrelationID", useMessageIDAsCorrelationID);
            return this;
        }
        /**
         * Number of times to wait for provisional correlation id to be updated
         * to the actual correlation id when doing request/reply over JMS and
         * when the option useMessageIDAsCorrelationID is enabled.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder waitForProvisionCorrelationToBeUpdatedCounter(
                int waitForProvisionCorrelationToBeUpdatedCounter) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedCounter", waitForProvisionCorrelationToBeUpdatedCounter);
            return this;
        }
        /**
         * Number of times to wait for provisional correlation id to be updated
         * to the actual correlation id when doing request/reply over JMS and
         * when the option useMessageIDAsCorrelationID is enabled.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder waitForProvisionCorrelationToBeUpdatedCounter(
                String waitForProvisionCorrelationToBeUpdatedCounter) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedCounter", waitForProvisionCorrelationToBeUpdatedCounter);
            return this;
        }
        /**
         * Interval in millis to sleep each time while waiting for provisional
         * correlation id to be updated.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder waitForProvisionCorrelationToBeUpdatedThreadSleepingTime(
                long waitForProvisionCorrelationToBeUpdatedThreadSleepingTime) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedThreadSleepingTime", waitForProvisionCorrelationToBeUpdatedThreadSleepingTime);
            return this;
        }
        /**
         * Interval in millis to sleep each time while waiting for provisional
         * correlation id to be updated.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointProducerBuilder waitForProvisionCorrelationToBeUpdatedThreadSleepingTime(
                String waitForProvisionCorrelationToBeUpdatedThreadSleepingTime) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedThreadSleepingTime", waitForProvisionCorrelationToBeUpdatedThreadSleepingTime);
            return this;
        }
        /**
         * If true, Camel will create a JmsTransactionManager, if there is no
         * transactionManager injected when option transacted=true.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder lazyCreateTransactionManager(
                boolean lazyCreateTransactionManager) {
            doSetProperty("lazyCreateTransactionManager", lazyCreateTransactionManager);
            return this;
        }
        /**
         * If true, Camel will create a JmsTransactionManager, if there is no
         * transactionManager injected when option transacted=true.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder lazyCreateTransactionManager(
                String lazyCreateTransactionManager) {
            doSetProperty("lazyCreateTransactionManager", lazyCreateTransactionManager);
            return this;
        }
        /**
         * The Spring transaction manager to use.
         * 
         * The option is a:
         * <code>org.springframework.transaction.PlatformTransactionManager</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder transactionManager(
                Object transactionManager) {
            doSetProperty("transactionManager", transactionManager);
            return this;
        }
        /**
         * The Spring transaction manager to use.
         * 
         * The option will be converted to a
         * <code>org.springframework.transaction.PlatformTransactionManager</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder transactionManager(
                String transactionManager) {
            doSetProperty("transactionManager", transactionManager);
            return this;
        }
        /**
         * The name of the transaction to use.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder transactionName(
                String transactionName) {
            doSetProperty("transactionName", transactionName);
            return this;
        }
        /**
         * The timeout value of the transaction (in seconds), if using
         * transacted mode.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder transactionTimeout(
                int transactionTimeout) {
            doSetProperty("transactionTimeout", transactionTimeout);
            return this;
        }
        /**
         * The timeout value of the transaction (in seconds), if using
         * transacted mode.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointProducerBuilder transactionTimeout(
                String transactionTimeout) {
            doSetProperty("transactionTimeout", transactionTimeout);
            return this;
        }
    }

    /**
     * Builder for endpoint for the JMS component.
     */
    public interface JmsEndpointBuilder
            extends
                JmsEndpointConsumerBuilder, JmsEndpointProducerBuilder {
        default AdvancedJmsEndpointBuilder advanced() {
            return (AdvancedJmsEndpointBuilder) this;
        }
        /**
         * Sets the JMS client ID to use. Note that this value, if specified,
         * must be unique and can only be used by a single JMS connection
         * instance. It is typically only required for durable topic
         * subscriptions. If using Apache ActiveMQ you may prefer to use Virtual
         * Topics instead.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder clientId(String clientId) {
            doSetProperty("clientId", clientId);
            return this;
        }
        /**
         * Sets the default connection factory to be used if a connection
         * factory is not specified for either
         * setTemplateConnectionFactory(ConnectionFactory) or
         * setListenerConnectionFactory(ConnectionFactory).
         * 
         * The option is a: <code>javax.jms.ConnectionFactory</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder connectionFactory(Object connectionFactory) {
            doSetProperty("connectionFactory", connectionFactory);
            return this;
        }
        /**
         * Sets the default connection factory to be used if a connection
         * factory is not specified for either
         * setTemplateConnectionFactory(ConnectionFactory) or
         * setListenerConnectionFactory(ConnectionFactory).
         * 
         * The option will be converted to a
         * <code>javax.jms.ConnectionFactory</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder connectionFactory(String connectionFactory) {
            doSetProperty("connectionFactory", connectionFactory);
            return this;
        }
        /**
         * Specifies whether Camel ignores the JMSReplyTo header in messages. If
         * true, Camel does not send a reply back to the destination specified
         * in the JMSReplyTo header. You can use this option if you want Camel
         * to consume from a route and you do not want Camel to automatically
         * send back a reply message because another component in your code
         * handles the reply message. You can also use this option if you want
         * to use Camel as a proxy between different message brokers and you
         * want to route message from one system to another.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder disableReplyTo(boolean disableReplyTo) {
            doSetProperty("disableReplyTo", disableReplyTo);
            return this;
        }
        /**
         * Specifies whether Camel ignores the JMSReplyTo header in messages. If
         * true, Camel does not send a reply back to the destination specified
         * in the JMSReplyTo header. You can use this option if you want Camel
         * to consume from a route and you do not want Camel to automatically
         * send back a reply message because another component in your code
         * handles the reply message. You can also use this option if you want
         * to use Camel as a proxy between different message brokers and you
         * want to route message from one system to another.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder disableReplyTo(String disableReplyTo) {
            doSetProperty("disableReplyTo", disableReplyTo);
            return this;
        }
        /**
         * The durable subscriber name for specifying durable topic
         * subscriptions. The clientId option must be configured as well.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder durableSubscriptionName(
                String durableSubscriptionName) {
            doSetProperty("durableSubscriptionName", durableSubscriptionName);
            return this;
        }
        /**
         * Allows you to force the use of a specific javax.jms.Message
         * implementation for sending JMS messages. Possible values are: Bytes,
         * Map, Object, Stream, Text. By default, Camel would determine which
         * JMS message type to use from the In body type. This option allows you
         * to specify it.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.JmsMessageType</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder jmsMessageType(JmsMessageType jmsMessageType) {
            doSetProperty("jmsMessageType", jmsMessageType);
            return this;
        }
        /**
         * Allows you to force the use of a specific javax.jms.Message
         * implementation for sending JMS messages. Possible values are: Bytes,
         * Map, Object, Stream, Text. By default, Camel would determine which
         * JMS message type to use from the In body type. This option allows you
         * to specify it.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.JmsMessageType</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder jmsMessageType(String jmsMessageType) {
            doSetProperty("jmsMessageType", jmsMessageType);
            return this;
        }
        /**
         * Specifies whether to test the connection on startup. This ensures
         * that when Camel starts that all the JMS consumers have a valid
         * connection to the JMS broker. If a connection cannot be granted then
         * Camel throws an exception on startup. This ensures that Camel is not
         * started with failed connections. The JMS producers is tested as well.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder testConnectionOnStartup(
                boolean testConnectionOnStartup) {
            doSetProperty("testConnectionOnStartup", testConnectionOnStartup);
            return this;
        }
        /**
         * Specifies whether to test the connection on startup. This ensures
         * that when Camel starts that all the JMS consumers have a valid
         * connection to the JMS broker. If a connection cannot be granted then
         * Camel throws an exception on startup. This ensures that Camel is not
         * started with failed connections. The JMS producers is tested as well.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JmsEndpointBuilder testConnectionOnStartup(
                String testConnectionOnStartup) {
            doSetProperty("testConnectionOnStartup", testConnectionOnStartup);
            return this;
        }
        /**
         * Password to use with the ConnectionFactory. You can also configure
         * username/password directly on the ConnectionFactory.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default JmsEndpointBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Username to use with the ConnectionFactory. You can also configure
         * username/password directly on the ConnectionFactory.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default JmsEndpointBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * Specifies whether to use transacted mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: transaction
         */
        default JmsEndpointBuilder transacted(boolean transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
        /**
         * Specifies whether to use transacted mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: transaction
         */
        default JmsEndpointBuilder transacted(String transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the JMS component.
     */
    public interface AdvancedJmsEndpointBuilder
            extends
                AdvancedJmsEndpointConsumerBuilder, AdvancedJmsEndpointProducerBuilder {
        default JmsEndpointBuilder basic() {
            return (JmsEndpointBuilder) this;
        }
        /**
         * Controls whether or not to include serialized headers. Applies only
         * when isTransferExchange() is true. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder allowSerializedHeaders(
                boolean allowSerializedHeaders) {
            doSetProperty("allowSerializedHeaders", allowSerializedHeaders);
            return this;
        }
        /**
         * Controls whether or not to include serialized headers. Applies only
         * when isTransferExchange() is true. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder allowSerializedHeaders(
                String allowSerializedHeaders) {
            doSetProperty("allowSerializedHeaders", allowSerializedHeaders);
            return this;
        }
        /**
         * Whether to startup the JmsConsumer message listener asynchronously,
         * when starting a route. For example if a JmsConsumer cannot get a
         * connection to a remote JMS broker, then it may block while retrying
         * and/or failover. This will cause Camel to block while starting
         * routes. By setting this option to true, you will let routes startup,
         * while the JmsConsumer connects to the JMS broker using a dedicated
         * thread in asynchronous mode. If this option is used, then beware that
         * if the connection could not be established, then an exception is
         * logged at WARN level, and the consumer will not be able to receive
         * messages; You can then restart the route to retry.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder asyncStartListener(
                boolean asyncStartListener) {
            doSetProperty("asyncStartListener", asyncStartListener);
            return this;
        }
        /**
         * Whether to startup the JmsConsumer message listener asynchronously,
         * when starting a route. For example if a JmsConsumer cannot get a
         * connection to a remote JMS broker, then it may block while retrying
         * and/or failover. This will cause Camel to block while starting
         * routes. By setting this option to true, you will let routes startup,
         * while the JmsConsumer connects to the JMS broker using a dedicated
         * thread in asynchronous mode. If this option is used, then beware that
         * if the connection could not be established, then an exception is
         * logged at WARN level, and the consumer will not be able to receive
         * messages; You can then restart the route to retry.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder asyncStartListener(
                String asyncStartListener) {
            doSetProperty("asyncStartListener", asyncStartListener);
            return this;
        }
        /**
         * Whether to stop the JmsConsumer message listener asynchronously, when
         * stopping a route.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder asyncStopListener(
                boolean asyncStopListener) {
            doSetProperty("asyncStopListener", asyncStopListener);
            return this;
        }
        /**
         * Whether to stop the JmsConsumer message listener asynchronously, when
         * stopping a route.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder asyncStopListener(
                String asyncStopListener) {
            doSetProperty("asyncStopListener", asyncStopListener);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * A pluggable
         * org.springframework.jms.support.destination.DestinationResolver that
         * allows you to use your own resolver (for example, to lookup the real
         * destination in a JNDI registry).
         * 
         * The option is a:
         * <code>org.springframework.jms.support.destination.DestinationResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder destinationResolver(
                Object destinationResolver) {
            doSetProperty("destinationResolver", destinationResolver);
            return this;
        }
        /**
         * A pluggable
         * org.springframework.jms.support.destination.DestinationResolver that
         * allows you to use your own resolver (for example, to lookup the real
         * destination in a JNDI registry).
         * 
         * The option will be converted to a
         * <code>org.springframework.jms.support.destination.DestinationResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder destinationResolver(
                String destinationResolver) {
            doSetProperty("destinationResolver", destinationResolver);
            return this;
        }
        /**
         * Specifies a org.springframework.util.ErrorHandler to be invoked in
         * case of any uncaught exceptions thrown while processing a Message. By
         * default these exceptions will be logged at the WARN level, if no
         * errorHandler has been configured. You can configure logging level and
         * whether stack traces should be logged using errorHandlerLoggingLevel
         * and errorHandlerLogStackTrace options. This makes it much easier to
         * configure, than having to code a custom errorHandler.
         * 
         * The option is a: <code>org.springframework.util.ErrorHandler</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder errorHandler(Object errorHandler) {
            doSetProperty("errorHandler", errorHandler);
            return this;
        }
        /**
         * Specifies a org.springframework.util.ErrorHandler to be invoked in
         * case of any uncaught exceptions thrown while processing a Message. By
         * default these exceptions will be logged at the WARN level, if no
         * errorHandler has been configured. You can configure logging level and
         * whether stack traces should be logged using errorHandlerLoggingLevel
         * and errorHandlerLogStackTrace options. This makes it much easier to
         * configure, than having to code a custom errorHandler.
         * 
         * The option will be converted to a
         * <code>org.springframework.util.ErrorHandler</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder errorHandler(String errorHandler) {
            doSetProperty("errorHandler", errorHandler);
            return this;
        }
        /**
         * Specifies the JMS Exception Listener that is to be notified of any
         * underlying JMS exceptions.
         * 
         * The option is a: <code>javax.jms.ExceptionListener</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder exceptionListener(
                Object exceptionListener) {
            doSetProperty("exceptionListener", exceptionListener);
            return this;
        }
        /**
         * Specifies the JMS Exception Listener that is to be notified of any
         * underlying JMS exceptions.
         * 
         * The option will be converted to a
         * <code>javax.jms.ExceptionListener</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder exceptionListener(
                String exceptionListener) {
            doSetProperty("exceptionListener", exceptionListener);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Specify the limit for the number of consumers that are allowed to be
         * idle at any given time.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder idleConsumerLimit(
                int idleConsumerLimit) {
            doSetProperty("idleConsumerLimit", idleConsumerLimit);
            return this;
        }
        /**
         * Specify the limit for the number of consumers that are allowed to be
         * idle at any given time.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder idleConsumerLimit(
                String idleConsumerLimit) {
            doSetProperty("idleConsumerLimit", idleConsumerLimit);
            return this;
        }
        /**
         * Specifies the limit for idle executions of a receive task, not having
         * received any message within its execution. If this limit is reached,
         * the task will shut down and leave receiving to other executing tasks
         * (in the case of dynamic scheduling; see the maxConcurrentConsumers
         * setting). There is additional doc available from Spring.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder idleTaskExecutionLimit(
                int idleTaskExecutionLimit) {
            doSetProperty("idleTaskExecutionLimit", idleTaskExecutionLimit);
            return this;
        }
        /**
         * Specifies the limit for idle executions of a receive task, not having
         * received any message within its execution. If this limit is reached,
         * the task will shut down and leave receiving to other executing tasks
         * (in the case of dynamic scheduling; see the maxConcurrentConsumers
         * setting). There is additional doc available from Spring.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder idleTaskExecutionLimit(
                String idleTaskExecutionLimit) {
            doSetProperty("idleTaskExecutionLimit", idleTaskExecutionLimit);
            return this;
        }
        /**
         * Whether to include all JMSXxxx properties when mapping from JMS to
         * Camel Message. Setting this to true will include properties such as
         * JMSXAppID, and JMSXUserID etc. Note: If you are using a custom
         * headerFilterStrategy then this option does not apply.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder includeAllJMSXProperties(
                boolean includeAllJMSXProperties) {
            doSetProperty("includeAllJMSXProperties", includeAllJMSXProperties);
            return this;
        }
        /**
         * Whether to include all JMSXxxx properties when mapping from JMS to
         * Camel Message. Setting this to true will include properties such as
         * JMSXAppID, and JMSXUserID etc. Note: If you are using a custom
         * headerFilterStrategy then this option does not apply.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder includeAllJMSXProperties(
                String includeAllJMSXProperties) {
            doSetProperty("includeAllJMSXProperties", includeAllJMSXProperties);
            return this;
        }
        /**
         * Pluggable strategy for encoding and decoding JMS keys so they can be
         * compliant with the JMS specification. Camel provides two
         * implementations out of the box: default and passthrough. The default
         * strategy will safely marshal dots and hyphens (. and -). The
         * passthrough strategy leaves the key as is. Can be used for JMS
         * brokers which do not care whether JMS header keys contain illegal
         * characters. You can provide your own implementation of the
         * org.apache.camel.component.jms.JmsKeyFormatStrategy and refer to it
         * using the # notation.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.JmsKeyFormatStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder jmsKeyFormatStrategy(
                Object jmsKeyFormatStrategy) {
            doSetProperty("jmsKeyFormatStrategy", jmsKeyFormatStrategy);
            return this;
        }
        /**
         * Pluggable strategy for encoding and decoding JMS keys so they can be
         * compliant with the JMS specification. Camel provides two
         * implementations out of the box: default and passthrough. The default
         * strategy will safely marshal dots and hyphens (. and -). The
         * passthrough strategy leaves the key as is. Can be used for JMS
         * brokers which do not care whether JMS header keys contain illegal
         * characters. You can provide your own implementation of the
         * org.apache.camel.component.jms.JmsKeyFormatStrategy and refer to it
         * using the # notation.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.JmsKeyFormatStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder jmsKeyFormatStrategy(
                String jmsKeyFormatStrategy) {
            doSetProperty("jmsKeyFormatStrategy", jmsKeyFormatStrategy);
            return this;
        }
        /**
         * Specifies whether Camel should auto map the received JMS message to a
         * suited payload type, such as javax.jms.TextMessage to a String etc.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder mapJmsMessage(boolean mapJmsMessage) {
            doSetProperty("mapJmsMessage", mapJmsMessage);
            return this;
        }
        /**
         * Specifies whether Camel should auto map the received JMS message to a
         * suited payload type, such as javax.jms.TextMessage to a String etc.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder mapJmsMessage(String mapJmsMessage) {
            doSetProperty("mapJmsMessage", mapJmsMessage);
            return this;
        }
        /**
         * The number of messages per task. -1 is unlimited. If you use a range
         * for concurrent consumers (eg min max), then this option can be used
         * to set a value to eg 100 to control how fast the consumers will
         * shrink when less work is required.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder maxMessagesPerTask(
                int maxMessagesPerTask) {
            doSetProperty("maxMessagesPerTask", maxMessagesPerTask);
            return this;
        }
        /**
         * The number of messages per task. -1 is unlimited. If you use a range
         * for concurrent consumers (eg min max), then this option can be used
         * to set a value to eg 100 to control how fast the consumers will
         * shrink when less work is required.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder maxMessagesPerTask(
                String maxMessagesPerTask) {
            doSetProperty("maxMessagesPerTask", maxMessagesPerTask);
            return this;
        }
        /**
         * To use a custom Spring
         * org.springframework.jms.support.converter.MessageConverter so you can
         * be in control how to map to/from a javax.jms.Message.
         * 
         * The option is a:
         * <code>org.springframework.jms.support.converter.MessageConverter</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageConverter(
                Object messageConverter) {
            doSetProperty("messageConverter", messageConverter);
            return this;
        }
        /**
         * To use a custom Spring
         * org.springframework.jms.support.converter.MessageConverter so you can
         * be in control how to map to/from a javax.jms.Message.
         * 
         * The option will be converted to a
         * <code>org.springframework.jms.support.converter.MessageConverter</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageConverter(
                String messageConverter) {
            doSetProperty("messageConverter", messageConverter);
            return this;
        }
        /**
         * To use the given MessageCreatedStrategy which are invoked when Camel
         * creates new instances of javax.jms.Message objects when Camel is
         * sending a JMS message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.MessageCreatedStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageCreatedStrategy(
                Object messageCreatedStrategy) {
            doSetProperty("messageCreatedStrategy", messageCreatedStrategy);
            return this;
        }
        /**
         * To use the given MessageCreatedStrategy which are invoked when Camel
         * creates new instances of javax.jms.Message objects when Camel is
         * sending a JMS message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.MessageCreatedStrategy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageCreatedStrategy(
                String messageCreatedStrategy) {
            doSetProperty("messageCreatedStrategy", messageCreatedStrategy);
            return this;
        }
        /**
         * When sending, specifies whether message IDs should be added. This is
         * just an hint to the JMS Broker. If the JMS provider accepts this
         * hint, these messages must have the message ID set to null; if the
         * provider ignores the hint, the message ID must be set to its normal
         * unique value.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageIdEnabled(
                boolean messageIdEnabled) {
            doSetProperty("messageIdEnabled", messageIdEnabled);
            return this;
        }
        /**
         * When sending, specifies whether message IDs should be added. This is
         * just an hint to the JMS Broker. If the JMS provider accepts this
         * hint, these messages must have the message ID set to null; if the
         * provider ignores the hint, the message ID must be set to its normal
         * unique value.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageIdEnabled(
                String messageIdEnabled) {
            doSetProperty("messageIdEnabled", messageIdEnabled);
            return this;
        }
        /**
         * Registry ID of the MessageListenerContainerFactory used to determine
         * what
         * org.springframework.jms.listener.AbstractMessageListenerContainer to
         * use to consume messages. Setting this will automatically set
         * consumerType to Custom.
         * 
         * The option is a:
         * <code>org.apache.camel.component.jms.MessageListenerContainerFactory</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageListenerContainerFactory(
                Object messageListenerContainerFactory) {
            doSetProperty("messageListenerContainerFactory", messageListenerContainerFactory);
            return this;
        }
        /**
         * Registry ID of the MessageListenerContainerFactory used to determine
         * what
         * org.springframework.jms.listener.AbstractMessageListenerContainer to
         * use to consume messages. Setting this will automatically set
         * consumerType to Custom.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.jms.MessageListenerContainerFactory</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageListenerContainerFactory(
                String messageListenerContainerFactory) {
            doSetProperty("messageListenerContainerFactory", messageListenerContainerFactory);
            return this;
        }
        /**
         * Specifies whether timestamps should be enabled by default on sending
         * messages. This is just an hint to the JMS Broker. If the JMS provider
         * accepts this hint, these messages must have the timestamp set to
         * zero; if the provider ignores the hint, the timestamp must be set to
         * its normal value.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageTimestampEnabled(
                boolean messageTimestampEnabled) {
            doSetProperty("messageTimestampEnabled", messageTimestampEnabled);
            return this;
        }
        /**
         * Specifies whether timestamps should be enabled by default on sending
         * messages. This is just an hint to the JMS Broker. If the JMS provider
         * accepts this hint, these messages must have the timestamp set to
         * zero; if the provider ignores the hint, the timestamp must be set to
         * its normal value.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder messageTimestampEnabled(
                String messageTimestampEnabled) {
            doSetProperty("messageTimestampEnabled", messageTimestampEnabled);
            return this;
        }
        /**
         * Specifies whether to inhibit the delivery of messages published by
         * its own connection.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder pubSubNoLocal(boolean pubSubNoLocal) {
            doSetProperty("pubSubNoLocal", pubSubNoLocal);
            return this;
        }
        /**
         * Specifies whether to inhibit the delivery of messages published by
         * its own connection.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder pubSubNoLocal(String pubSubNoLocal) {
            doSetProperty("pubSubNoLocal", pubSubNoLocal);
            return this;
        }
        /**
         * The timeout for receiving messages (in milliseconds).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder receiveTimeout(long receiveTimeout) {
            doSetProperty("receiveTimeout", receiveTimeout);
            return this;
        }
        /**
         * The timeout for receiving messages (in milliseconds).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder receiveTimeout(String receiveTimeout) {
            doSetProperty("receiveTimeout", receiveTimeout);
            return this;
        }
        /**
         * Specifies the interval between recovery attempts, i.e. when a
         * connection is being refreshed, in milliseconds. The default is 5000
         * ms, that is, 5 seconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder recoveryInterval(
                long recoveryInterval) {
            doSetProperty("recoveryInterval", recoveryInterval);
            return this;
        }
        /**
         * Specifies the interval between recovery attempts, i.e. when a
         * connection is being refreshed, in milliseconds. The default is 5000
         * ms, that is, 5 seconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder recoveryInterval(
                String recoveryInterval) {
            doSetProperty("recoveryInterval", recoveryInterval);
            return this;
        }
        /**
         * Configures how often Camel should check for timed out Exchanges when
         * doing request/reply over JMS. By default Camel checks once per
         * second. But if you must react faster when a timeout occurs, then you
         * can lower this interval, to check more frequently. The timeout is
         * determined by the option requestTimeout.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder requestTimeoutCheckerInterval(
                long requestTimeoutCheckerInterval) {
            doSetProperty("requestTimeoutCheckerInterval", requestTimeoutCheckerInterval);
            return this;
        }
        /**
         * Configures how often Camel should check for timed out Exchanges when
         * doing request/reply over JMS. By default Camel checks once per
         * second. But if you must react faster when a timeout occurs, then you
         * can lower this interval, to check more frequently. The timeout is
         * determined by the option requestTimeout.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder requestTimeoutCheckerInterval(
                String requestTimeoutCheckerInterval) {
            doSetProperty("requestTimeoutCheckerInterval", requestTimeoutCheckerInterval);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder synchronous(boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * If enabled and you are using Request Reply messaging (InOut) and an
         * Exchange failed on the consumer side, then the caused Exception will
         * be send back in response as a javax.jms.ObjectMessage. If the client
         * is Camel, the returned Exception is rethrown. This allows you to use
         * Camel JMS as a bridge in your routing - for example, using persistent
         * queues to enable robust routing. Notice that if you also have
         * transferExchange enabled, this option takes precedence. The caught
         * exception is required to be serializable. The original Exception on
         * the consumer side can be wrapped in an outer exception such as
         * org.apache.camel.RuntimeCamelException when returned to the producer.
         * Use this with caution as the data is using Java Object serialization
         * and requires the received to be able to deserialize the data at Class
         * level, which forces a strong coupling between the producers and
         * consumer!.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder transferException(
                boolean transferException) {
            doSetProperty("transferException", transferException);
            return this;
        }
        /**
         * If enabled and you are using Request Reply messaging (InOut) and an
         * Exchange failed on the consumer side, then the caused Exception will
         * be send back in response as a javax.jms.ObjectMessage. If the client
         * is Camel, the returned Exception is rethrown. This allows you to use
         * Camel JMS as a bridge in your routing - for example, using persistent
         * queues to enable robust routing. Notice that if you also have
         * transferExchange enabled, this option takes precedence. The caught
         * exception is required to be serializable. The original Exception on
         * the consumer side can be wrapped in an outer exception such as
         * org.apache.camel.RuntimeCamelException when returned to the producer.
         * Use this with caution as the data is using Java Object serialization
         * and requires the received to be able to deserialize the data at Class
         * level, which forces a strong coupling between the producers and
         * consumer!.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder transferException(
                String transferException) {
            doSetProperty("transferException", transferException);
            return this;
        }
        /**
         * You can transfer the exchange over the wire instead of just the body
         * and headers. The following fields are transferred: In body, Out body,
         * Fault body, In headers, Out headers, Fault headers, exchange
         * properties, exchange exception. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level. You must enable this option on both the producer
         * and consumer side, so Camel knows the payloads is an Exchange and not
         * a regular payload. Use this with caution as the data is using Java
         * Object serialization and requires the received to be able to
         * deserialize the data at Class level, which forces a strong coupling
         * between the producers and consumer having to use compatible Camel
         * versions!.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder transferExchange(
                boolean transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * You can transfer the exchange over the wire instead of just the body
         * and headers. The following fields are transferred: In body, Out body,
         * Fault body, In headers, Out headers, Fault headers, exchange
         * properties, exchange exception. This requires that the objects are
         * serializable. Camel will exclude any non-serializable objects and log
         * it at WARN level. You must enable this option on both the producer
         * and consumer side, so Camel knows the payloads is an Exchange and not
         * a regular payload. Use this with caution as the data is using Java
         * Object serialization and requires the received to be able to
         * deserialize the data at Class level, which forces a strong coupling
         * between the producers and consumer having to use compatible Camel
         * versions!.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder transferExchange(
                String transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * Specifies whether JMSMessageID should always be used as
         * JMSCorrelationID for InOut messages.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder useMessageIDAsCorrelationID(
                boolean useMessageIDAsCorrelationID) {
            doSetProperty("useMessageIDAsCorrelationID", useMessageIDAsCorrelationID);
            return this;
        }
        /**
         * Specifies whether JMSMessageID should always be used as
         * JMSCorrelationID for InOut messages.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder useMessageIDAsCorrelationID(
                String useMessageIDAsCorrelationID) {
            doSetProperty("useMessageIDAsCorrelationID", useMessageIDAsCorrelationID);
            return this;
        }
        /**
         * Number of times to wait for provisional correlation id to be updated
         * to the actual correlation id when doing request/reply over JMS and
         * when the option useMessageIDAsCorrelationID is enabled.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder waitForProvisionCorrelationToBeUpdatedCounter(
                int waitForProvisionCorrelationToBeUpdatedCounter) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedCounter", waitForProvisionCorrelationToBeUpdatedCounter);
            return this;
        }
        /**
         * Number of times to wait for provisional correlation id to be updated
         * to the actual correlation id when doing request/reply over JMS and
         * when the option useMessageIDAsCorrelationID is enabled.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder waitForProvisionCorrelationToBeUpdatedCounter(
                String waitForProvisionCorrelationToBeUpdatedCounter) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedCounter", waitForProvisionCorrelationToBeUpdatedCounter);
            return this;
        }
        /**
         * Interval in millis to sleep each time while waiting for provisional
         * correlation id to be updated.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder waitForProvisionCorrelationToBeUpdatedThreadSleepingTime(
                long waitForProvisionCorrelationToBeUpdatedThreadSleepingTime) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedThreadSleepingTime", waitForProvisionCorrelationToBeUpdatedThreadSleepingTime);
            return this;
        }
        /**
         * Interval in millis to sleep each time while waiting for provisional
         * correlation id to be updated.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJmsEndpointBuilder waitForProvisionCorrelationToBeUpdatedThreadSleepingTime(
                String waitForProvisionCorrelationToBeUpdatedThreadSleepingTime) {
            doSetProperty("waitForProvisionCorrelationToBeUpdatedThreadSleepingTime", waitForProvisionCorrelationToBeUpdatedThreadSleepingTime);
            return this;
        }
        /**
         * If true, Camel will create a JmsTransactionManager, if there is no
         * transactionManager injected when option transacted=true.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointBuilder lazyCreateTransactionManager(
                boolean lazyCreateTransactionManager) {
            doSetProperty("lazyCreateTransactionManager", lazyCreateTransactionManager);
            return this;
        }
        /**
         * If true, Camel will create a JmsTransactionManager, if there is no
         * transactionManager injected when option transacted=true.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointBuilder lazyCreateTransactionManager(
                String lazyCreateTransactionManager) {
            doSetProperty("lazyCreateTransactionManager", lazyCreateTransactionManager);
            return this;
        }
        /**
         * The Spring transaction manager to use.
         * 
         * The option is a:
         * <code>org.springframework.transaction.PlatformTransactionManager</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointBuilder transactionManager(
                Object transactionManager) {
            doSetProperty("transactionManager", transactionManager);
            return this;
        }
        /**
         * The Spring transaction manager to use.
         * 
         * The option will be converted to a
         * <code>org.springframework.transaction.PlatformTransactionManager</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointBuilder transactionManager(
                String transactionManager) {
            doSetProperty("transactionManager", transactionManager);
            return this;
        }
        /**
         * The name of the transaction to use.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointBuilder transactionName(
                String transactionName) {
            doSetProperty("transactionName", transactionName);
            return this;
        }
        /**
         * The timeout value of the transaction (in seconds), if using
         * transacted mode.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointBuilder transactionTimeout(
                int transactionTimeout) {
            doSetProperty("transactionTimeout", transactionTimeout);
            return this;
        }
        /**
         * The timeout value of the transaction (in seconds), if using
         * transacted mode.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: transaction (advanced)
         */
        default AdvancedJmsEndpointBuilder transactionTimeout(
                String transactionTimeout) {
            doSetProperty("transactionTimeout", transactionTimeout);
            return this;
        }
    }

    /**
     * Proxy enum for <code>org.apache.camel.component.jms.JmsMessageType</code>
     * enum.
     */
    enum JmsMessageType {
        Bytes,
        Map,
        Object,
        Stream,
        Text,
        Blob;
    }

    /**
     * Proxy enum for <code>org.apache.camel.component.jms.ConsumerType</code>
     * enum.
     */
    enum ConsumerType {
        Simple,
        Default,
        Custom;
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.jms.DefaultTaskExecutorType</code> enum.
     */
    enum DefaultTaskExecutorType {
        ThreadPool,
        SimpleAsync;
    }

    /**
     * Proxy enum for <code>org.apache.camel.component.jms.ReplyToType</code>
     * enum.
     */
    enum ReplyToType {
        Temporary,
        Shared,
        Exclusive;
    }
    /**
     * JMS (camel-jms)
     * The jms component allows messages to be sent to (or consumed from) a JMS
     * Queue or Topic.
     * 
     * Category: messaging
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-jms
     * 
     * Syntax: <code>jms:destinationType:destinationName</code>
     * 
     * Path parameter: destinationType
     * The kind of destination to use
     * Default value: queue
     * The value can be one of: queue, topic, temp-queue, temp-topic
     * 
     * Path parameter: destinationName (required)
     * Name of the queue or topic to use as destination
     */
    default JmsEndpointBuilder jms(String path) {
        class JmsEndpointBuilderImpl extends AbstractEndpointBuilder implements JmsEndpointBuilder, AdvancedJmsEndpointBuilder {
            public JmsEndpointBuilderImpl(String path) {
                super("jms", path);
            }
        }
        return new JmsEndpointBuilderImpl(path);
    }
}