/*
 * 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 activemq component allows messages to be sent to (or consumed from)
 * Apache ActiveMQ. This component extends the Camel JMS component.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface ActiveMQEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the ActiveMQ component.
     */
    public interface ActiveMQEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedActiveMQEndpointConsumerBuilder advanced() {
            return (AdvancedActiveMQEndpointConsumerBuilder) 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder 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 ActiveMQEndpointConsumerBuilder transacted(String transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the ActiveMQ component.
     */
    public interface AdvancedActiveMQEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default ActiveMQEndpointConsumerBuilder basic() {
            return (ActiveMQEndpointConsumerBuilder) 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder 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 AdvancedActiveMQEndpointConsumerBuilder transactionTimeout(
                String transactionTimeout) {
            doSetProperty("transactionTimeout", transactionTimeout);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the ActiveMQ component.
     */
    public interface ActiveMQEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedActiveMQEndpointProducerBuilder advanced() {
            return (AdvancedActiveMQEndpointProducerBuilder) 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder 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 ActiveMQEndpointProducerBuilder transacted(String transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the ActiveMQ component.
     */
    public interface AdvancedActiveMQEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default ActiveMQEndpointProducerBuilder basic() {
            return (ActiveMQEndpointProducerBuilder) 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder 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 AdvancedActiveMQEndpointProducerBuilder transactionTimeout(
                String transactionTimeout) {
            doSetProperty("transactionTimeout", transactionTimeout);
            return this;
        }
    }

    /**
     * Builder for endpoint for the ActiveMQ component.
     */
    public interface ActiveMQEndpointBuilder
            extends
                ActiveMQEndpointConsumerBuilder, ActiveMQEndpointProducerBuilder {
        default AdvancedActiveMQEndpointBuilder advanced() {
            return (AdvancedActiveMQEndpointBuilder) 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder 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 ActiveMQEndpointBuilder transacted(String transacted) {
            doSetProperty("transacted", transacted);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the ActiveMQ component.
     */
    public interface AdvancedActiveMQEndpointBuilder
            extends
                AdvancedActiveMQEndpointConsumerBuilder, AdvancedActiveMQEndpointProducerBuilder {
        default ActiveMQEndpointBuilder basic() {
            return (ActiveMQEndpointBuilder) 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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 AdvancedActiveMQEndpointBuilder 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;
    }
    /**
     * ActiveMQ (camel-activemq)
     * The activemq component allows messages to be sent to (or consumed from)
     * Apache ActiveMQ. This component extends the Camel JMS component.
     * 
     * Category: messaging
     * Available as of version: 1.0
     * Maven coordinates: org.apache.camel:camel-activemq
     * 
     * Syntax: <code>activemq: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 ActiveMQEndpointBuilder activemq(String path) {
        class ActiveMQEndpointBuilderImpl extends AbstractEndpointBuilder implements ActiveMQEndpointBuilder, AdvancedActiveMQEndpointBuilder {
            public ActiveMQEndpointBuilderImpl(String path) {
                super("activemq", path);
            }
        }
        return new ActiveMQEndpointBuilderImpl(path);
    }
}