/*
 * 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 java.util.Map;
import java.util.Properties;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
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;
import org.apache.camel.spi.IdempotentRepository;
import org.apache.camel.spi.PollingConsumerPollStrategy;

/**
 * To send or receive emails using imap/pop3 or smtp protocols.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface MailEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the IMAP component.
     */
    public interface MailEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedMailEndpointConsumerBuilder advanced() {
            return (AdvancedMailEndpointConsumerBuilder) this;
        }
        /**
         * Allows for bridging the consumer to the Camel routing Error Handler,
         * which mean any exceptions occurred while the consumer is trying to
         * pickup incoming messages, or the likes, will now be processed as a
         * message and handled by the routing Error Handler. By default the
         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
         * with exceptions, that will be logged at WARN or ERROR level and
         * ignored.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder bridgeErrorHandler(
                boolean bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * Allows for bridging the consumer to the Camel routing Error Handler,
         * which mean any exceptions occurred while the consumer is trying to
         * pickup incoming messages, or the likes, will now be processed as a
         * message and handled by the routing Error Handler. By default the
         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
         * with exceptions, that will be logged at WARN or ERROR level and
         * ignored.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * Whether the consumer should close the folder after polling. Setting
         * this option to false and having disconnect=false as well, then the
         * consumer keep the folder open between polls.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder closeFolder(boolean closeFolder) {
            doSetProperty("closeFolder", closeFolder);
            return this;
        }
        /**
         * Whether the consumer should close the folder after polling. Setting
         * this option to false and having disconnect=false as well, then the
         * consumer keep the folder open between polls.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder closeFolder(String closeFolder) {
            doSetProperty("closeFolder", closeFolder);
            return this;
        }
        /**
         * After processing a mail message, it can be copied to a mail folder
         * with the given name. You can override this configuration value, with
         * a header with the key copyTo, allowing you to copy messages to folder
         * names configured at runtime.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder copyTo(String copyTo) {
            doSetProperty("copyTo", copyTo);
            return this;
        }
        /**
         * Deletes the messages after they have been processed. This is done by
         * setting the DELETED flag on the mail message. If false, the SEEN flag
         * is set instead. As of Camel 2.10 you can override this configuration
         * option by setting a header with the key delete to determine if the
         * mail should be deleted or not.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder delete(boolean delete) {
            doSetProperty("delete", delete);
            return this;
        }
        /**
         * Deletes the messages after they have been processed. This is done by
         * setting the DELETED flag on the mail message. If false, the SEEN flag
         * is set instead. As of Camel 2.10 you can override this configuration
         * option by setting a header with the key delete to determine if the
         * mail should be deleted or not.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder delete(String delete) {
            doSetProperty("delete", delete);
            return this;
        }
        /**
         * Whether the consumer should disconnect after polling. If enabled this
         * forces Camel to connect on each poll.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder disconnect(boolean disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Whether the consumer should disconnect after polling. If enabled this
         * forces Camel to connect on each poll.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder disconnect(String disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * If the mail consumer cannot retrieve a given mail message, then this
         * option allows to handle the caused exception by the consumer's error
         * handler. By enable the bridge error handler on the consumer, then the
         * Camel routing error handler can handle the exception instead. The
         * default behavior would be the consumer throws an exception and no
         * mails from the batch would be able to be routed by Camel.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder handleFailedMessage(
                boolean handleFailedMessage) {
            doSetProperty("handleFailedMessage", handleFailedMessage);
            return this;
        }
        /**
         * If the mail consumer cannot retrieve a given mail message, then this
         * option allows to handle the caused exception by the consumer's error
         * handler. By enable the bridge error handler on the consumer, then the
         * Camel routing error handler can handle the exception instead. The
         * default behavior would be the consumer throws an exception and no
         * mails from the batch would be able to be routed by Camel.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder handleFailedMessage(
                String handleFailedMessage) {
            doSetProperty("handleFailedMessage", handleFailedMessage);
            return this;
        }
        /**
         * Specifies the maximum number of messages to gather per poll. By
         * default, no maximum is set. Can be used to set a limit of e.g. 1000
         * to avoid downloading thousands of files when the server starts up.
         * Set a value of 0 or negative to disable this option.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder maxMessagesPerPoll(
                int maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * Specifies the maximum number of messages to gather per poll. By
         * default, no maximum is set. Can be used to set a limit of e.g. 1000
         * to avoid downloading thousands of files when the server starts up.
         * Set a value of 0 or negative to disable this option.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder maxMessagesPerPoll(
                String maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * This option enables transparent MIME decoding and unfolding for mail
         * headers.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder mimeDecodeHeaders(
                boolean mimeDecodeHeaders) {
            doSetProperty("mimeDecodeHeaders", mimeDecodeHeaders);
            return this;
        }
        /**
         * This option enables transparent MIME decoding and unfolding for mail
         * headers.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder mimeDecodeHeaders(
                String mimeDecodeHeaders) {
            doSetProperty("mimeDecodeHeaders", mimeDecodeHeaders);
            return this;
        }
        /**
         * Will mark the javax.mail.Message as peeked before processing the mail
         * message. This applies to IMAPMessage messages types only. By using
         * peek the mail will not be eager marked as SEEN on the mail server,
         * which allows us to rollback the mail message if there is an error
         * processing in Camel.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder peek(boolean peek) {
            doSetProperty("peek", peek);
            return this;
        }
        /**
         * Will mark the javax.mail.Message as peeked before processing the mail
         * message. This applies to IMAPMessage messages types only. By using
         * peek the mail will not be eager marked as SEEN on the mail server,
         * which allows us to rollback the mail message if there is an error
         * processing in Camel.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder peek(String peek) {
            doSetProperty("peek", peek);
            return this;
        }
        /**
         * If the polling consumer did not poll any files, you can enable this
         * option to send an empty message (no body) instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                boolean sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * If the polling consumer did not poll any files, you can enable this
         * option to send an empty message (no body) instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                String sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * If the mail consumer cannot retrieve a given mail message, then this
         * option allows to skip the message and move on to retrieve the next
         * mail message. The default behavior would be the consumer throws an
         * exception and no mails from the batch would be able to be routed by
         * Camel.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder skipFailedMessage(
                boolean skipFailedMessage) {
            doSetProperty("skipFailedMessage", skipFailedMessage);
            return this;
        }
        /**
         * If the mail consumer cannot retrieve a given mail message, then this
         * option allows to skip the message and move on to retrieve the next
         * mail message. The default behavior would be the consumer throws an
         * exception and no mails from the batch would be able to be routed by
         * Camel.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder skipFailedMessage(
                String skipFailedMessage) {
            doSetProperty("skipFailedMessage", skipFailedMessage);
            return this;
        }
        /**
         * Whether to limit by unseen mails only.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder unseen(boolean unseen) {
            doSetProperty("unseen", unseen);
            return this;
        }
        /**
         * Whether to limit by unseen mails only.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MailEndpointConsumerBuilder unseen(String unseen) {
            doSetProperty("unseen", unseen);
            return this;
        }
        /**
         * A pluggable repository org.apache.camel.spi.IdempotentRepository
         * which allows to cluster consuming from the same mailbox, and let the
         * repository coordinate whether a mail message is valid for the
         * consumer to process. By default no repository is in use.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.IdempotentRepository</code> type.
         * 
         * Group: filter
         */
        default MailEndpointConsumerBuilder idempotentRepository(
                IdempotentRepository idempotentRepository) {
            doSetProperty("idempotentRepository", idempotentRepository);
            return this;
        }
        /**
         * A pluggable repository org.apache.camel.spi.IdempotentRepository
         * which allows to cluster consuming from the same mailbox, and let the
         * repository coordinate whether a mail message is valid for the
         * consumer to process. By default no repository is in use.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.IdempotentRepository</code> type.
         * 
         * Group: filter
         */
        default MailEndpointConsumerBuilder idempotentRepository(
                String idempotentRepository) {
            doSetProperty("idempotentRepository", idempotentRepository);
            return this;
        }
        /**
         * When using idempotent repository, then when the mail message has been
         * successfully processed and is committed, should the message id be
         * removed from the idempotent repository (default) or be kept in the
         * repository. By default its assumed the message id is unique and has
         * no value to be kept in the repository, because the mail message will
         * be marked as seen/moved or deleted to prevent it from being consumed
         * again. And therefore having the message id stored in the idempotent
         * repository has little value. However this option allows to store the
         * message id, for whatever reason you may have.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: filter
         */
        default MailEndpointConsumerBuilder idempotentRepositoryRemoveOnCommit(
                boolean idempotentRepositoryRemoveOnCommit) {
            doSetProperty("idempotentRepositoryRemoveOnCommit", idempotentRepositoryRemoveOnCommit);
            return this;
        }
        /**
         * When using idempotent repository, then when the mail message has been
         * successfully processed and is committed, should the message id be
         * removed from the idempotent repository (default) or be kept in the
         * repository. By default its assumed the message id is unique and has
         * no value to be kept in the repository, because the mail message will
         * be marked as seen/moved or deleted to prevent it from being consumed
         * again. And therefore having the message id stored in the idempotent
         * repository has little value. However this option allows to store the
         * message id, for whatever reason you may have.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: filter
         */
        default MailEndpointConsumerBuilder idempotentRepositoryRemoveOnCommit(
                String idempotentRepositoryRemoveOnCommit) {
            doSetProperty("idempotentRepositoryRemoveOnCommit", idempotentRepositoryRemoveOnCommit);
            return this;
        }
        /**
         * Refers to a javax.mail.search.SearchTerm which allows to filter mails
         * based on search criteria such as subject, body, from, sent after a
         * certain date etc.
         * 
         * The option is a: <code>javax.mail.search.SearchTerm</code> type.
         * 
         * Group: filter
         */
        default MailEndpointConsumerBuilder searchTerm(Object searchTerm) {
            doSetProperty("searchTerm", searchTerm);
            return this;
        }
        /**
         * Refers to a javax.mail.search.SearchTerm which allows to filter mails
         * based on search criteria such as subject, body, from, sent after a
         * certain date etc.
         * 
         * The option will be converted to a
         * <code>javax.mail.search.SearchTerm</code> type.
         * 
         * Group: filter
         */
        default MailEndpointConsumerBuilder searchTerm(String searchTerm) {
            doSetProperty("searchTerm", searchTerm);
            return this;
        }
        /**
         * The number of subsequent error polls (failed due some error) that
         * should happen before the backoffMultipler should kick-in.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder backoffErrorThreshold(
                int backoffErrorThreshold) {
            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
            return this;
        }
        /**
         * The number of subsequent error polls (failed due some error) that
         * should happen before the backoffMultipler should kick-in.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder backoffErrorThreshold(
                String backoffErrorThreshold) {
            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
            return this;
        }
        /**
         * The number of subsequent idle polls that should happen before the
         * backoffMultipler should kick-in.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder backoffIdleThreshold(
                int backoffIdleThreshold) {
            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
            return this;
        }
        /**
         * The number of subsequent idle polls that should happen before the
         * backoffMultipler should kick-in.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder backoffIdleThreshold(
                String backoffIdleThreshold) {
            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
            return this;
        }
        /**
         * To let the scheduled polling consumer backoff if there has been a
         * number of subsequent idles/errors in a row. The multiplier is then
         * the number of polls that will be skipped before the next actual
         * attempt is happening again. When this option is in use then
         * backoffIdleThreshold and/or backoffErrorThreshold must also be
         * configured.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder backoffMultiplier(
                int backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * To let the scheduled polling consumer backoff if there has been a
         * number of subsequent idles/errors in a row. The multiplier is then
         * the number of polls that will be skipped before the next actual
         * attempt is happening again. When this option is in use then
         * backoffIdleThreshold and/or backoffErrorThreshold must also be
         * configured.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder backoffMultiplier(
                String backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * Milliseconds before the next poll.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder delay(long delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * Milliseconds before the next poll.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder delay(String delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * If greedy is enabled, then the ScheduledPollConsumer will run
         * immediately again, if the previous run polled 1 or more messages.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder greedy(boolean greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * If greedy is enabled, then the ScheduledPollConsumer will run
         * immediately again, if the previous run polled 1 or more messages.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder greedy(String greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * Milliseconds before the first poll starts. You can also specify time
         * values using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder initialDelay(long initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Milliseconds before the first poll starts. You can also specify time
         * values using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder initialDelay(String initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Specifies a maximum limit of number of fires. So if you set it to 1,
         * the scheduler will only fire once. If you set it to 5, it will only
         * fire five times. A value of zero or negative means fire forever.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder repeatCount(long repeatCount) {
            doSetProperty("repeatCount", repeatCount);
            return this;
        }
        /**
         * Specifies a maximum limit of number of fires. So if you set it to 1,
         * the scheduler will only fire once. If you set it to 5, it will only
         * fire five times. A value of zero or negative means fire forever.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder repeatCount(String repeatCount) {
            doSetProperty("repeatCount", repeatCount);
            return this;
        }
        /**
         * The consumer logs a start/complete log line when it polls. This
         * option allows you to configure the logging level for that.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder runLoggingLevel(
                LoggingLevel runLoggingLevel) {
            doSetProperty("runLoggingLevel", runLoggingLevel);
            return this;
        }
        /**
         * The consumer logs a start/complete log line when it polls. This
         * option allows you to configure the logging level for that.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder runLoggingLevel(
                String runLoggingLevel) {
            doSetProperty("runLoggingLevel", runLoggingLevel);
            return this;
        }
        /**
         * Allows for configuring a custom/shared thread pool to use for the
         * consumer. By default each consumer has its own single threaded thread
         * pool.
         * 
         * The option is a:
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder scheduledExecutorService(
                ScheduledExecutorService scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * Allows for configuring a custom/shared thread pool to use for the
         * consumer. By default each consumer has its own single threaded thread
         * pool.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder scheduledExecutorService(
                String scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * To use a cron scheduler from either camel-spring or camel-quartz
         * component.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder scheduler(String scheduler) {
            doSetProperty("scheduler", scheduler);
            return this;
        }
        /**
         * To configure additional properties when using a custom scheduler or
         * any of the Quartz, Spring based scheduler.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder schedulerProperties(
                Map<String, Object> schedulerProperties) {
            doSetProperty("schedulerProperties", schedulerProperties);
            return this;
        }
        /**
         * To configure additional properties when using a custom scheduler or
         * any of the Quartz, Spring based scheduler.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder schedulerProperties(
                String schedulerProperties) {
            doSetProperty("schedulerProperties", schedulerProperties);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder startScheduler(
                boolean startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder startScheduler(String startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option is a: <code>java.util.concurrent.TimeUnit</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder timeUnit(TimeUnit timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.TimeUnit</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder timeUnit(String timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Controls if fixed delay or fixed rate is used. See
         * ScheduledExecutorService in JDK for details.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder useFixedDelay(boolean useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
        /**
         * Controls if fixed delay or fixed rate is used. See
         * ScheduledExecutorService in JDK for details.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default MailEndpointConsumerBuilder useFixedDelay(String useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
        /**
         * Sorting order for messages. Only natively supported for IMAP.
         * Emulated to some degree when using POP3 or when IMAP server does not
         * have the SORT capability.
         * 
         * The option is a: <code>com.sun.mail.imap.SortTerm[]</code> type.
         * 
         * Group: sort
         */
        default MailEndpointConsumerBuilder sortTerm(Object[] sortTerm) {
            doSetProperty("sortTerm", sortTerm);
            return this;
        }
        /**
         * Sorting order for messages. Only natively supported for IMAP.
         * Emulated to some degree when using POP3 or when IMAP server does not
         * have the SORT capability.
         * 
         * The option will be converted to a
         * <code>com.sun.mail.imap.SortTerm[]</code> type.
         * 
         * Group: sort
         */
        default MailEndpointConsumerBuilder sortTerm(String sortTerm) {
            doSetProperty("sortTerm", sortTerm);
            return this;
        }
        /**
         * The password for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MailEndpointConsumerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * To configure security using SSLContextParameters.
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MailEndpointConsumerBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * To configure security using SSLContextParameters.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MailEndpointConsumerBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * The username for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MailEndpointConsumerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the IMAP component.
     */
    public interface AdvancedMailEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default MailEndpointConsumerBuilder basic() {
            return (MailEndpointConsumerBuilder) 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 AdvancedMailEndpointConsumerBuilder 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 AdvancedMailEndpointConsumerBuilder 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 AdvancedMailEndpointConsumerBuilder 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 AdvancedMailEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * Sets the maximum number of messages to consume during a poll. This
         * can be used to avoid overloading a mail server, if a mailbox folder
         * contains a lot of messages. Default value of -1 means no fetch size
         * and all messages will be consumed. Setting the value to 0 is a
         * special corner case, where Camel will not consume any messages at
         * all.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder fetchSize(int fetchSize) {
            doSetProperty("fetchSize", fetchSize);
            return this;
        }
        /**
         * Sets the maximum number of messages to consume during a poll. This
         * can be used to avoid overloading a mail server, if a mailbox folder
         * contains a lot of messages. Default value of -1 means no fetch size
         * and all messages will be consumed. Setting the value to 0 is a
         * special corner case, where Camel will not consume any messages at
         * all.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder fetchSize(String fetchSize) {
            doSetProperty("fetchSize", fetchSize);
            return this;
        }
        /**
         * The folder to poll.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder folderName(String folderName) {
            doSetProperty("folderName", folderName);
            return this;
        }
        /**
         * A pluggable MailUidGenerator that allows to use custom logic to
         * generate UUID of the mail message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.MailUidGenerator</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder mailUidGenerator(
                Object mailUidGenerator) {
            doSetProperty("mailUidGenerator", mailUidGenerator);
            return this;
        }
        /**
         * A pluggable MailUidGenerator that allows to use custom logic to
         * generate UUID of the mail message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.MailUidGenerator</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder mailUidGenerator(
                String mailUidGenerator) {
            doSetProperty("mailUidGenerator", mailUidGenerator);
            return this;
        }
        /**
         * Specifies whether Camel should map the received mail message to Camel
         * body/headers/attachments. If set to true, the body of the mail
         * message is mapped to the body of the Camel IN message, the mail
         * headers are mapped to IN headers, and the attachments to Camel IN
         * attachment message. If this option is set to false then the IN
         * message contains a raw javax.mail.Message. You can retrieve this raw
         * message by calling
         * exchange.getIn().getBody(javax.mail.Message.class).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder mapMailMessage(
                boolean mapMailMessage) {
            doSetProperty("mapMailMessage", mapMailMessage);
            return this;
        }
        /**
         * Specifies whether Camel should map the received mail message to Camel
         * body/headers/attachments. If set to true, the body of the mail
         * message is mapped to the body of the Camel IN message, the mail
         * headers are mapped to IN headers, and the attachments to Camel IN
         * attachment message. If this option is set to false then the IN
         * message contains a raw javax.mail.Message. You can retrieve this raw
         * message by calling
         * exchange.getIn().getBody(javax.mail.Message.class).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder mapMailMessage(
                String mapMailMessage) {
            doSetProperty("mapMailMessage", mapMailMessage);
            return this;
        }
        /**
         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
         * you to provide your custom implementation to control error handling
         * usually occurred during the poll operation before an Exchange have
         * been created and being routed in Camel.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder pollStrategy(
                PollingConsumerPollStrategy pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
         * you to provide your custom implementation to control error handling
         * usually occurred during the poll operation before an Exchange have
         * been created and being routed in Camel.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder pollStrategy(
                String pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * Refers to an MailBoxPostProcessAction for doing post processing tasks
         * on the mailbox once the normal processing ended.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.MailBoxPostProcessAction</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder postProcessAction(
                Object postProcessAction) {
            doSetProperty("postProcessAction", postProcessAction);
            return this;
        }
        /**
         * Refers to an MailBoxPostProcessAction for doing post processing tasks
         * on the mailbox once the normal processing ended.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.MailBoxPostProcessAction</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMailEndpointConsumerBuilder postProcessAction(
                String postProcessAction) {
            doSetProperty("postProcessAction", postProcessAction);
            return this;
        }
        /**
         * Sets additional java mail properties, that will append/override any
         * default properties that is set based on all the other options. This
         * is useful if you need to add some special options but want to keep
         * the others as is.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder additionalJavaMailProperties(
                Properties additionalJavaMailProperties) {
            doSetProperty("additionalJavaMailProperties", additionalJavaMailProperties);
            return this;
        }
        /**
         * Sets additional java mail properties, that will append/override any
         * default properties that is set based on all the other options. This
         * is useful if you need to add some special options but want to keep
         * the others as is.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder additionalJavaMailProperties(
                String additionalJavaMailProperties) {
            doSetProperty("additionalJavaMailProperties", additionalJavaMailProperties);
            return this;
        }
        /**
         * Specifies the key to an IN message header that contains an
         * alternative email body. For example, if you send emails in text/html
         * format and want to provide an alternative mail body for non-HTML
         * email clients, set the alternative mail body with this key as a
         * header.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder alternativeBodyHeader(
                String alternativeBodyHeader) {
            doSetProperty("alternativeBodyHeader", alternativeBodyHeader);
            return this;
        }
        /**
         * To use a custom AttachmentsContentTransferEncodingResolver to resolve
         * what content-type-encoding to use for attachments.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.AttachmentsContentTransferEncodingResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder attachmentsContentTransferEncodingResolver(
                Object attachmentsContentTransferEncodingResolver) {
            doSetProperty("attachmentsContentTransferEncodingResolver", attachmentsContentTransferEncodingResolver);
            return this;
        }
        /**
         * To use a custom AttachmentsContentTransferEncodingResolver to resolve
         * what content-type-encoding to use for attachments.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.AttachmentsContentTransferEncodingResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder attachmentsContentTransferEncodingResolver(
                String attachmentsContentTransferEncodingResolver) {
            doSetProperty("attachmentsContentTransferEncodingResolver", attachmentsContentTransferEncodingResolver);
            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 AdvancedMailEndpointConsumerBuilder 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 AdvancedMailEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets the binding used to convert from a Camel message to and from a
         * Mail message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.MailBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder binding(Object binding) {
            doSetProperty("binding", binding);
            return this;
        }
        /**
         * Sets the binding used to convert from a Camel message to and from a
         * Mail message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.MailBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder binding(String binding) {
            doSetProperty("binding", binding);
            return this;
        }
        /**
         * The connection timeout in milliseconds.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder connectionTimeout(
                int connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * The connection timeout in milliseconds.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder connectionTimeout(
                String connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * The mail message content type. Use text/html for HTML mails.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder contentType(
                String contentType) {
            doSetProperty("contentType", contentType);
            return this;
        }
        /**
         * Resolver to determine Content-Type for file attachments.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.ContentTypeResolver</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder contentTypeResolver(
                Object contentTypeResolver) {
            doSetProperty("contentTypeResolver", contentTypeResolver);
            return this;
        }
        /**
         * Resolver to determine Content-Type for file attachments.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.ContentTypeResolver</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder contentTypeResolver(
                String contentTypeResolver) {
            doSetProperty("contentTypeResolver", contentTypeResolver);
            return this;
        }
        /**
         * Enable debug mode on the underlying mail framework. The SUN Mail
         * framework logs the debug messages to System.out by default.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder debugMode(boolean debugMode) {
            doSetProperty("debugMode", debugMode);
            return this;
        }
        /**
         * Enable debug mode on the underlying mail framework. The SUN Mail
         * framework logs the debug messages to System.out by default.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder debugMode(String debugMode) {
            doSetProperty("debugMode", debugMode);
            return this;
        }
        /**
         * To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter
         * headers.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter
         * headers.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder ignoreUnsupportedCharset(
                boolean ignoreUnsupportedCharset) {
            doSetProperty("ignoreUnsupportedCharset", ignoreUnsupportedCharset);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder ignoreUnsupportedCharset(
                String ignoreUnsupportedCharset) {
            doSetProperty("ignoreUnsupportedCharset", ignoreUnsupportedCharset);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder ignoreUriScheme(
                boolean ignoreUriScheme) {
            doSetProperty("ignoreUriScheme", ignoreUriScheme);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder ignoreUriScheme(
                String ignoreUriScheme) {
            doSetProperty("ignoreUriScheme", ignoreUriScheme);
            return this;
        }
        /**
         * Specifies the mail session that camel should use for all mail
         * interactions. Useful in scenarios where mail sessions are created and
         * managed by some other resource, such as a JavaEE container. When
         * using a custom mail session, then the hostname and port from the mail
         * session will be used (if configured on the session).
         * 
         * The option is a: <code>javax.mail.Session</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder session(Object session) {
            doSetProperty("session", session);
            return this;
        }
        /**
         * Specifies the mail session that camel should use for all mail
         * interactions. Useful in scenarios where mail sessions are created and
         * managed by some other resource, such as a JavaEE container. When
         * using a custom mail session, then the hostname and port from the mail
         * session will be used (if configured on the session).
         * 
         * The option will be converted to a <code>javax.mail.Session</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder session(String session) {
            doSetProperty("session", session);
            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 AdvancedMailEndpointConsumerBuilder 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 AdvancedMailEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Whether to use disposition inline or attachment.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder useInlineAttachments(
                boolean useInlineAttachments) {
            doSetProperty("useInlineAttachments", useInlineAttachments);
            return this;
        }
        /**
         * Whether to use disposition inline or attachment.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointConsumerBuilder useInlineAttachments(
                String useInlineAttachments) {
            doSetProperty("useInlineAttachments", useInlineAttachments);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the IMAP component.
     */
    public interface MailEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedMailEndpointProducerBuilder advanced() {
            return (AdvancedMailEndpointProducerBuilder) this;
        }
        /**
         * Sets the BCC email address. Separate multiple email addresses with
         * comma.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default MailEndpointProducerBuilder bcc(String bcc) {
            doSetProperty("bcc", bcc);
            return this;
        }
        /**
         * Sets the CC email address. Separate multiple email addresses with
         * comma.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default MailEndpointProducerBuilder cc(String cc) {
            doSetProperty("cc", cc);
            return this;
        }
        /**
         * The from email address.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default MailEndpointProducerBuilder from(String from) {
            doSetProperty("from", from);
            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 MailEndpointProducerBuilder 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 MailEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * The Reply-To recipients (the receivers of the response mail).
         * Separate multiple email addresses with a comma.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default MailEndpointProducerBuilder replyTo(String replyTo) {
            doSetProperty("replyTo", replyTo);
            return this;
        }
        /**
         * The Subject of the message being sent. Note: Setting the subject in
         * the header takes precedence over this option.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default MailEndpointProducerBuilder subject(String subject) {
            doSetProperty("subject", subject);
            return this;
        }
        /**
         * Sets the To email address. Separate multiple email addresses with
         * comma.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default MailEndpointProducerBuilder to(String to) {
            doSetProperty("to", to);
            return this;
        }
        /**
         * The password for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MailEndpointProducerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * To configure security using SSLContextParameters.
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MailEndpointProducerBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * To configure security using SSLContextParameters.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MailEndpointProducerBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * The username for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MailEndpointProducerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the IMAP component.
     */
    public interface AdvancedMailEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default MailEndpointProducerBuilder basic() {
            return (MailEndpointProducerBuilder) this;
        }
        /**
         * To use a custom org.apache.camel.component.mail.JavaMailSender for
         * sending emails.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.JavaMailSender</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedMailEndpointProducerBuilder javaMailSender(
                Object javaMailSender) {
            doSetProperty("javaMailSender", javaMailSender);
            return this;
        }
        /**
         * To use a custom org.apache.camel.component.mail.JavaMailSender for
         * sending emails.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.JavaMailSender</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedMailEndpointProducerBuilder javaMailSender(
                String javaMailSender) {
            doSetProperty("javaMailSender", javaMailSender);
            return this;
        }
        /**
         * Sets additional java mail properties, that will append/override any
         * default properties that is set based on all the other options. This
         * is useful if you need to add some special options but want to keep
         * the others as is.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder additionalJavaMailProperties(
                Properties additionalJavaMailProperties) {
            doSetProperty("additionalJavaMailProperties", additionalJavaMailProperties);
            return this;
        }
        /**
         * Sets additional java mail properties, that will append/override any
         * default properties that is set based on all the other options. This
         * is useful if you need to add some special options but want to keep
         * the others as is.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder additionalJavaMailProperties(
                String additionalJavaMailProperties) {
            doSetProperty("additionalJavaMailProperties", additionalJavaMailProperties);
            return this;
        }
        /**
         * Specifies the key to an IN message header that contains an
         * alternative email body. For example, if you send emails in text/html
         * format and want to provide an alternative mail body for non-HTML
         * email clients, set the alternative mail body with this key as a
         * header.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder alternativeBodyHeader(
                String alternativeBodyHeader) {
            doSetProperty("alternativeBodyHeader", alternativeBodyHeader);
            return this;
        }
        /**
         * To use a custom AttachmentsContentTransferEncodingResolver to resolve
         * what content-type-encoding to use for attachments.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.AttachmentsContentTransferEncodingResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder attachmentsContentTransferEncodingResolver(
                Object attachmentsContentTransferEncodingResolver) {
            doSetProperty("attachmentsContentTransferEncodingResolver", attachmentsContentTransferEncodingResolver);
            return this;
        }
        /**
         * To use a custom AttachmentsContentTransferEncodingResolver to resolve
         * what content-type-encoding to use for attachments.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.AttachmentsContentTransferEncodingResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder attachmentsContentTransferEncodingResolver(
                String attachmentsContentTransferEncodingResolver) {
            doSetProperty("attachmentsContentTransferEncodingResolver", attachmentsContentTransferEncodingResolver);
            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 AdvancedMailEndpointProducerBuilder 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 AdvancedMailEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets the binding used to convert from a Camel message to and from a
         * Mail message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.MailBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder binding(Object binding) {
            doSetProperty("binding", binding);
            return this;
        }
        /**
         * Sets the binding used to convert from a Camel message to and from a
         * Mail message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.MailBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder binding(String binding) {
            doSetProperty("binding", binding);
            return this;
        }
        /**
         * The connection timeout in milliseconds.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder connectionTimeout(
                int connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * The connection timeout in milliseconds.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder connectionTimeout(
                String connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * The mail message content type. Use text/html for HTML mails.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder contentType(
                String contentType) {
            doSetProperty("contentType", contentType);
            return this;
        }
        /**
         * Resolver to determine Content-Type for file attachments.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.ContentTypeResolver</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder contentTypeResolver(
                Object contentTypeResolver) {
            doSetProperty("contentTypeResolver", contentTypeResolver);
            return this;
        }
        /**
         * Resolver to determine Content-Type for file attachments.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.ContentTypeResolver</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder contentTypeResolver(
                String contentTypeResolver) {
            doSetProperty("contentTypeResolver", contentTypeResolver);
            return this;
        }
        /**
         * Enable debug mode on the underlying mail framework. The SUN Mail
         * framework logs the debug messages to System.out by default.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder debugMode(boolean debugMode) {
            doSetProperty("debugMode", debugMode);
            return this;
        }
        /**
         * Enable debug mode on the underlying mail framework. The SUN Mail
         * framework logs the debug messages to System.out by default.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder debugMode(String debugMode) {
            doSetProperty("debugMode", debugMode);
            return this;
        }
        /**
         * To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter
         * headers.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter
         * headers.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder ignoreUnsupportedCharset(
                boolean ignoreUnsupportedCharset) {
            doSetProperty("ignoreUnsupportedCharset", ignoreUnsupportedCharset);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder ignoreUnsupportedCharset(
                String ignoreUnsupportedCharset) {
            doSetProperty("ignoreUnsupportedCharset", ignoreUnsupportedCharset);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder ignoreUriScheme(
                boolean ignoreUriScheme) {
            doSetProperty("ignoreUriScheme", ignoreUriScheme);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder ignoreUriScheme(
                String ignoreUriScheme) {
            doSetProperty("ignoreUriScheme", ignoreUriScheme);
            return this;
        }
        /**
         * Specifies the mail session that camel should use for all mail
         * interactions. Useful in scenarios where mail sessions are created and
         * managed by some other resource, such as a JavaEE container. When
         * using a custom mail session, then the hostname and port from the mail
         * session will be used (if configured on the session).
         * 
         * The option is a: <code>javax.mail.Session</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder session(Object session) {
            doSetProperty("session", session);
            return this;
        }
        /**
         * Specifies the mail session that camel should use for all mail
         * interactions. Useful in scenarios where mail sessions are created and
         * managed by some other resource, such as a JavaEE container. When
         * using a custom mail session, then the hostname and port from the mail
         * session will be used (if configured on the session).
         * 
         * The option will be converted to a <code>javax.mail.Session</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder session(String session) {
            doSetProperty("session", session);
            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 AdvancedMailEndpointProducerBuilder 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 AdvancedMailEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Whether to use disposition inline or attachment.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder useInlineAttachments(
                boolean useInlineAttachments) {
            doSetProperty("useInlineAttachments", useInlineAttachments);
            return this;
        }
        /**
         * Whether to use disposition inline or attachment.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointProducerBuilder useInlineAttachments(
                String useInlineAttachments) {
            doSetProperty("useInlineAttachments", useInlineAttachments);
            return this;
        }
    }

    /**
     * Builder for endpoint for the IMAP component.
     */
    public interface MailEndpointBuilder
            extends
                MailEndpointConsumerBuilder, MailEndpointProducerBuilder {
        default AdvancedMailEndpointBuilder advanced() {
            return (AdvancedMailEndpointBuilder) this;
        }
        /**
         * The password for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MailEndpointBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * To configure security using SSLContextParameters.
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MailEndpointBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * To configure security using SSLContextParameters.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MailEndpointBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * The username for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MailEndpointBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the IMAP component.
     */
    public interface AdvancedMailEndpointBuilder
            extends
                AdvancedMailEndpointConsumerBuilder, AdvancedMailEndpointProducerBuilder {
        default MailEndpointBuilder basic() {
            return (MailEndpointBuilder) this;
        }
        /**
         * Sets additional java mail properties, that will append/override any
         * default properties that is set based on all the other options. This
         * is useful if you need to add some special options but want to keep
         * the others as is.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder additionalJavaMailProperties(
                Properties additionalJavaMailProperties) {
            doSetProperty("additionalJavaMailProperties", additionalJavaMailProperties);
            return this;
        }
        /**
         * Sets additional java mail properties, that will append/override any
         * default properties that is set based on all the other options. This
         * is useful if you need to add some special options but want to keep
         * the others as is.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder additionalJavaMailProperties(
                String additionalJavaMailProperties) {
            doSetProperty("additionalJavaMailProperties", additionalJavaMailProperties);
            return this;
        }
        /**
         * Specifies the key to an IN message header that contains an
         * alternative email body. For example, if you send emails in text/html
         * format and want to provide an alternative mail body for non-HTML
         * email clients, set the alternative mail body with this key as a
         * header.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder alternativeBodyHeader(
                String alternativeBodyHeader) {
            doSetProperty("alternativeBodyHeader", alternativeBodyHeader);
            return this;
        }
        /**
         * To use a custom AttachmentsContentTransferEncodingResolver to resolve
         * what content-type-encoding to use for attachments.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.AttachmentsContentTransferEncodingResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder attachmentsContentTransferEncodingResolver(
                Object attachmentsContentTransferEncodingResolver) {
            doSetProperty("attachmentsContentTransferEncodingResolver", attachmentsContentTransferEncodingResolver);
            return this;
        }
        /**
         * To use a custom AttachmentsContentTransferEncodingResolver to resolve
         * what content-type-encoding to use for attachments.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.AttachmentsContentTransferEncodingResolver</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder attachmentsContentTransferEncodingResolver(
                String attachmentsContentTransferEncodingResolver) {
            doSetProperty("attachmentsContentTransferEncodingResolver", attachmentsContentTransferEncodingResolver);
            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 AdvancedMailEndpointBuilder 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 AdvancedMailEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets the binding used to convert from a Camel message to and from a
         * Mail message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.MailBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder binding(Object binding) {
            doSetProperty("binding", binding);
            return this;
        }
        /**
         * Sets the binding used to convert from a Camel message to and from a
         * Mail message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.MailBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder binding(String binding) {
            doSetProperty("binding", binding);
            return this;
        }
        /**
         * The connection timeout in milliseconds.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder connectionTimeout(
                int connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * The connection timeout in milliseconds.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder connectionTimeout(
                String connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * The mail message content type. Use text/html for HTML mails.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder contentType(String contentType) {
            doSetProperty("contentType", contentType);
            return this;
        }
        /**
         * Resolver to determine Content-Type for file attachments.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mail.ContentTypeResolver</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder contentTypeResolver(
                Object contentTypeResolver) {
            doSetProperty("contentTypeResolver", contentTypeResolver);
            return this;
        }
        /**
         * Resolver to determine Content-Type for file attachments.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mail.ContentTypeResolver</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder contentTypeResolver(
                String contentTypeResolver) {
            doSetProperty("contentTypeResolver", contentTypeResolver);
            return this;
        }
        /**
         * Enable debug mode on the underlying mail framework. The SUN Mail
         * framework logs the debug messages to System.out by default.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder debugMode(boolean debugMode) {
            doSetProperty("debugMode", debugMode);
            return this;
        }
        /**
         * Enable debug mode on the underlying mail framework. The SUN Mail
         * framework logs the debug messages to System.out by default.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder debugMode(String debugMode) {
            doSetProperty("debugMode", debugMode);
            return this;
        }
        /**
         * To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter
         * headers.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter
         * headers.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder ignoreUnsupportedCharset(
                boolean ignoreUnsupportedCharset) {
            doSetProperty("ignoreUnsupportedCharset", ignoreUnsupportedCharset);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder ignoreUnsupportedCharset(
                String ignoreUnsupportedCharset) {
            doSetProperty("ignoreUnsupportedCharset", ignoreUnsupportedCharset);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder ignoreUriScheme(
                boolean ignoreUriScheme) {
            doSetProperty("ignoreUriScheme", ignoreUriScheme);
            return this;
        }
        /**
         * Option to let Camel ignore unsupported charset in the local JVM when
         * sending mails. If the charset is unsupported then charset=XXX (where
         * XXX represents the unsupported charset) is removed from the
         * content-type and it relies on the platform default instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder ignoreUriScheme(
                String ignoreUriScheme) {
            doSetProperty("ignoreUriScheme", ignoreUriScheme);
            return this;
        }
        /**
         * Specifies the mail session that camel should use for all mail
         * interactions. Useful in scenarios where mail sessions are created and
         * managed by some other resource, such as a JavaEE container. When
         * using a custom mail session, then the hostname and port from the mail
         * session will be used (if configured on the session).
         * 
         * The option is a: <code>javax.mail.Session</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder session(Object session) {
            doSetProperty("session", session);
            return this;
        }
        /**
         * Specifies the mail session that camel should use for all mail
         * interactions. Useful in scenarios where mail sessions are created and
         * managed by some other resource, such as a JavaEE container. When
         * using a custom mail session, then the hostname and port from the mail
         * session will be used (if configured on the session).
         * 
         * The option will be converted to a <code>javax.mail.Session</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder session(String session) {
            doSetProperty("session", session);
            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 AdvancedMailEndpointBuilder 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 AdvancedMailEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Whether to use disposition inline or attachment.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder useInlineAttachments(
                boolean useInlineAttachments) {
            doSetProperty("useInlineAttachments", useInlineAttachments);
            return this;
        }
        /**
         * Whether to use disposition inline or attachment.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMailEndpointBuilder useInlineAttachments(
                String useInlineAttachments) {
            doSetProperty("useInlineAttachments", useInlineAttachments);
            return this;
        }
    }
    /**
     * IMAP (camel-mail)
     * To send or receive emails using imap/pop3 or smtp protocols.
     * 
     * Category: mail
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-mail
     * 
     * Syntax: <code>imap:host:port</code>
     * 
     * Path parameter: host (required)
     * The mail server host name
     * 
     * Path parameter: port
     * The port number of the mail server
     */
    default MailEndpointBuilder imap(String path) {
        return imap("imap", path);
    }
    /**
     * IMAPS (Secure) (camel-mail)
     * To send or receive emails using imap/pop3 or smtp protocols.
     * 
     * Category: mail
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-mail
     * 
     * Syntax: <code>imaps:host:port</code>
     * 
     * Path parameter: host (required)
     * The mail server host name
     * 
     * Path parameter: port
     * The port number of the mail server
     */
    default MailEndpointBuilder imaps(String path) {
        return imap("imaps", path);
    }
    /**
     * POP3 (camel-mail)
     * To send or receive emails using imap/pop3 or smtp protocols.
     * 
     * Category: mail
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-mail
     * 
     * Syntax: <code>pop3:host:port</code>
     * 
     * Path parameter: host (required)
     * The mail server host name
     * 
     * Path parameter: port
     * The port number of the mail server
     */
    default MailEndpointBuilder pop3(String path) {
        return imap("pop3", path);
    }
    /**
     * POP3S (camel-mail)
     * To send or receive emails using imap/pop3 or smtp protocols.
     * 
     * Category: mail
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-mail
     * 
     * Syntax: <code>pop3s:host:port</code>
     * 
     * Path parameter: host (required)
     * The mail server host name
     * 
     * Path parameter: port
     * The port number of the mail server
     */
    default MailEndpointBuilder pop3s(String path) {
        return imap("pop3s", path);
    }
    /**
     * SMTP (camel-mail)
     * To send or receive emails using imap/pop3 or smtp protocols.
     * 
     * Category: mail
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-mail
     * 
     * Syntax: <code>smtp:host:port</code>
     * 
     * Path parameter: host (required)
     * The mail server host name
     * 
     * Path parameter: port
     * The port number of the mail server
     */
    default MailEndpointBuilder smtp(String path) {
        return imap("smtp", path);
    }
    /**
     * SMTPS (camel-mail)
     * To send or receive emails using imap/pop3 or smtp protocols.
     * 
     * Category: mail
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-mail
     * 
     * Syntax: <code>smtps:host:port</code>
     * 
     * Path parameter: host (required)
     * The mail server host name
     * 
     * Path parameter: port
     * The port number of the mail server
     */
    default MailEndpointBuilder smtps(String path) {
        return imap("smtps", path);
    }
    /**
     * IMAP (camel-mail)
     * To send or receive emails using imap/pop3 or smtp protocols.
     * 
     * Category: mail
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-mail
     */
    default MailEndpointBuilder imap(String scheme, String path) {
        class MailEndpointBuilderImpl extends AbstractEndpointBuilder implements MailEndpointBuilder, AdvancedMailEndpointBuilder {
            public MailEndpointBuilderImpl(String scheme, String path) {
                super(scheme, path);
            }
        }
        return new MailEndpointBuilderImpl(scheme, path);
    }
}