/*
 * 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.Comparator;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Generated;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Expression;
import org.apache.camel.LoggingLevel;
import org.apache.camel.Predicate;
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.IdempotentRepository;
import org.apache.camel.spi.PollingConsumerPollStrategy;

/**
 * The ftps (FTP secure SSL/TLS) component is used for uploading or downloading
 * files from FTP servers.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface FtpsEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the FTPS component.
     */
    public interface FtpsEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedFtpsEndpointConsumerBuilder advanced() {
            return (AdvancedFtpsEndpointConsumerBuilder) this;
        }
        /**
         * Specifies the file transfer mode, BINARY or ASCII. Default is ASCII
         * (false).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder binary(boolean binary) {
            doSetProperty("binary", binary);
            return this;
        }
        /**
         * Specifies the file transfer mode, BINARY or ASCII. Default is ASCII
         * (false).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder binary(String binary) {
            doSetProperty("binary", binary);
            return this;
        }
        /**
         * This option is used to specify the encoding of the file. You can use
         * this on the consumer, to specify the encodings of the files, which
         * allow Camel to know the charset it should load the file content in
         * case the file content is being accessed. Likewise when writing a
         * file, you can use this option to specify which charset to write the
         * file as well. Do mind that when writing the file Camel may have to
         * read the message content into memory to be able to convert the data
         * into the configured charset, so do not use this if you have big
         * messages.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder charset(String charset) {
            doSetProperty("charset", charset);
            return this;
        }
        /**
         * Whether or not to disconnect from remote FTP server right after use.
         * Disconnect will only disconnect the current connection to the FTP
         * server. If you have a consumer which you want to stop, then you need
         * to stop the consumer/route instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder disconnect(boolean disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Whether or not to disconnect from remote FTP server right after use.
         * Disconnect will only disconnect the current connection to the FTP
         * server. If you have a consumer which you want to stop, then you need
         * to stop the consumer/route instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder disconnect(String disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Producer: If provided, then Camel will write a 2nd done file when the
         * original file has been written. The done file will be empty. This
         * option configures what file name to use. Either you can specify a
         * fixed name. Or you can use dynamic placeholders. The done file will
         * always be written in the same folder as the original file. Consumer:
         * If provided, Camel will only consume files if a done file exists.
         * This option configures what file name to use. Either you can specify
         * a fixed name. Or you can use dynamic placeholders.The done file is
         * always expected in the same folder as the original file. Only
         * ${file.name} and ${file.name.noext} is supported as dynamic
         * placeholders.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder doneFileName(String doneFileName) {
            doSetProperty("doneFileName", doneFileName);
            return this;
        }
        /**
         * Use Expression such as File Language to dynamically set the filename.
         * For consumers, it's used as a filename filter. For producers, it's
         * used to evaluate the filename to write. If an expression is set, it
         * take precedence over the CamelFileName header. (Note: The header
         * itself can also be an Expression). The expression options support
         * both String and Expression types. If the expression is a String type,
         * it is always evaluated using the File Language. If the expression is
         * an Expression type, the specified Expression type is used - this
         * allows you, for instance, to use OGNL expressions. For the consumer,
         * you can use it to filter filenames, so you can for instance consume
         * today's file using the File Language syntax:
         * mydata-${date:now:yyyyMMdd}.txt. The producers support the
         * CamelOverruleFileName header which takes precedence over any existing
         * CamelFileName header; the CamelOverruleFileName is a header that is
         * used only once, and makes it easier as this avoids to temporary store
         * CamelFileName and have to restore it afterwards.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder fileName(Expression fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * Use Expression such as File Language to dynamically set the filename.
         * For consumers, it's used as a filename filter. For producers, it's
         * used to evaluate the filename to write. If an expression is set, it
         * take precedence over the CamelFileName header. (Note: The header
         * itself can also be an Expression). The expression options support
         * both String and Expression types. If the expression is a String type,
         * it is always evaluated using the File Language. If the expression is
         * an Expression type, the specified Expression type is used - this
         * allows you, for instance, to use OGNL expressions. For the consumer,
         * you can use it to filter filenames, so you can for instance consume
         * today's file using the File Language syntax:
         * mydata-${date:now:yyyyMMdd}.txt. The producers support the
         * CamelOverruleFileName header which takes precedence over any existing
         * CamelFileName header; the CamelOverruleFileName is a header that is
         * used only once, and makes it easier as this avoids to temporary store
         * CamelFileName and have to restore it afterwards.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * Sets passive mode connections. Default is active mode connections.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder passiveMode(boolean passiveMode) {
            doSetProperty("passiveMode", passiveMode);
            return this;
        }
        /**
         * Sets passive mode connections. Default is active mode connections.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder passiveMode(String passiveMode) {
            doSetProperty("passiveMode", passiveMode);
            return this;
        }
        /**
         * Sets the path separator to be used. UNIX = Uses unix style path
         * separator Windows = Uses windows style path separator Auto = (is
         * default) Use existing path separator in file name.
         * 
         * The option is a:
         * <code>org.apache.camel.component.file.remote.RemoteFileConfiguration$PathSeparator</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder separator(PathSeparator separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Sets the path separator to be used. UNIX = Uses unix style path
         * separator Windows = Uses windows style path separator Auto = (is
         * default) Use existing path separator in file name.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.file.remote.RemoteFileConfiguration$PathSeparator</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder separator(String separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Configures the interval in seconds to use when logging the progress
         * of upload and download operations that are in-flight. This is used
         * for logging progress when operations takes longer time.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder transferLoggingIntervalSeconds(
                int transferLoggingIntervalSeconds) {
            doSetProperty("transferLoggingIntervalSeconds", transferLoggingIntervalSeconds);
            return this;
        }
        /**
         * Configures the interval in seconds to use when logging the progress
         * of upload and download operations that are in-flight. This is used
         * for logging progress when operations takes longer time.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder transferLoggingIntervalSeconds(
                String transferLoggingIntervalSeconds) {
            doSetProperty("transferLoggingIntervalSeconds", transferLoggingIntervalSeconds);
            return this;
        }
        /**
         * Configure the logging level to use when logging the progress of
         * upload and download operations.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder transferLoggingLevel(
                LoggingLevel transferLoggingLevel) {
            doSetProperty("transferLoggingLevel", transferLoggingLevel);
            return this;
        }
        /**
         * Configure the logging level to use when logging the progress of
         * upload and download operations.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder transferLoggingLevel(
                String transferLoggingLevel) {
            doSetProperty("transferLoggingLevel", transferLoggingLevel);
            return this;
        }
        /**
         * Configures whether the perform verbose (fine grained) logging of the
         * progress of upload and download operations.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder transferLoggingVerbose(
                boolean transferLoggingVerbose) {
            doSetProperty("transferLoggingVerbose", transferLoggingVerbose);
            return this;
        }
        /**
         * Configures whether the perform verbose (fine grained) logging of the
         * progress of upload and download operations.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointConsumerBuilder transferLoggingVerbose(
                String transferLoggingVerbose) {
            doSetProperty("transferLoggingVerbose", transferLoggingVerbose);
            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 is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * If true, the file will be deleted after it is processed successfully.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder delete(boolean delete) {
            doSetProperty("delete", delete);
            return this;
        }
        /**
         * If true, the file will be deleted after it is processed successfully.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder delete(String delete) {
            doSetProperty("delete", delete);
            return this;
        }
        /**
         * Sets the move failure expression based on Simple language. For
         * example, to move files into a .error subdirectory use: .error. Note:
         * When moving the files to the fail location Camel will handle the
         * error and will not pick up the file again.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder moveFailed(Expression moveFailed) {
            doSetProperty("moveFailed", moveFailed);
            return this;
        }
        /**
         * Sets the move failure expression based on Simple language. For
         * example, to move files into a .error subdirectory use: .error. Note:
         * When moving the files to the fail location Camel will handle the
         * error and will not pick up the file again.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder moveFailed(String moveFailed) {
            doSetProperty("moveFailed", moveFailed);
            return this;
        }
        /**
         * If true, the file is not moved or deleted in any way. This option is
         * good for readonly data, or for ETL type requirements. If noop=true,
         * Camel will set idempotent=true as well, to avoid consuming the same
         * files over and over again.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder noop(boolean noop) {
            doSetProperty("noop", noop);
            return this;
        }
        /**
         * If true, the file is not moved or deleted in any way. This option is
         * good for readonly data, or for ETL type requirements. If noop=true,
         * Camel will set idempotent=true as well, to avoid consuming the same
         * files over and over again.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder noop(String noop) {
            doSetProperty("noop", noop);
            return this;
        }
        /**
         * Expression (such as File Language) used to dynamically set the
         * filename when moving it before processing. For example to move
         * in-progress files into the order directory set this value to order.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder preMove(Expression preMove) {
            doSetProperty("preMove", preMove);
            return this;
        }
        /**
         * Expression (such as File Language) used to dynamically set the
         * filename when moving it before processing. For example to move
         * in-progress files into the order directory set this value to order.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder preMove(String preMove) {
            doSetProperty("preMove", preMove);
            return this;
        }
        /**
         * When pre-sort is enabled then the consumer will sort the file and
         * directory names during polling, that was retrieved from the file
         * system. You may want to do this in case you need to operate on the
         * files in a sorted order. The pre-sort is executed before the consumer
         * starts to filter, and accept files to process by Camel. This option
         * is default=false meaning disabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder preSort(boolean preSort) {
            doSetProperty("preSort", preSort);
            return this;
        }
        /**
         * When pre-sort is enabled then the consumer will sort the file and
         * directory names during polling, that was retrieved from the file
         * system. You may want to do this in case you need to operate on the
         * files in a sorted order. The pre-sort is executed before the consumer
         * starts to filter, and accept files to process by Camel. This option
         * is default=false meaning disabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder preSort(String preSort) {
            doSetProperty("preSort", preSort);
            return this;
        }
        /**
         * If a directory, will look for files in all the sub-directories as
         * well.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder recursive(boolean recursive) {
            doSetProperty("recursive", recursive);
            return this;
        }
        /**
         * If a directory, will look for files in all the sub-directories as
         * well.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder recursive(String recursive) {
            doSetProperty("recursive", recursive);
            return this;
        }
        /**
         * Configures whether resume download is enabled. This must be supported
         * by the FTP server (almost all FTP servers support it). In addition
         * the options localWorkDirectory must be configured so downloaded files
         * are stored in a local directory, and the option binary must be
         * enabled, which is required to support resuming of downloads.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder resumeDownload(
                boolean resumeDownload) {
            doSetProperty("resumeDownload", resumeDownload);
            return this;
        }
        /**
         * Configures whether resume download is enabled. This must be supported
         * by the FTP server (almost all FTP servers support it). In addition
         * the options localWorkDirectory must be configured so downloaded files
         * are stored in a local directory, and the option binary must be
         * enabled, which is required to support resuming of downloads.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder resumeDownload(String resumeDownload) {
            doSetProperty("resumeDownload", resumeDownload);
            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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                String sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * Sets the download method to use when not using a local working
         * directory. If set to true, the remote files are streamed to the route
         * as they are read. When set to false, the remote files are loaded into
         * memory before being sent into the route.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder streamDownload(
                boolean streamDownload) {
            doSetProperty("streamDownload", streamDownload);
            return this;
        }
        /**
         * Sets the download method to use when not using a local working
         * directory. If set to true, the remote files are streamed to the route
         * as they are read. When set to false, the remote files are loaded into
         * memory before being sent into the route.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default FtpsEndpointConsumerBuilder streamDownload(String streamDownload) {
            doSetProperty("streamDownload", streamDownload);
            return this;
        }
        /**
         * Ant style filter exclusion. If both antInclude and antExclude are
         * used, antExclude takes precedence over antInclude. Multiple
         * exclusions may be specified in comma-delimited format.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder antExclude(String antExclude) {
            doSetProperty("antExclude", antExclude);
            return this;
        }
        /**
         * Sets case sensitive flag on ant filter.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder antFilterCaseSensitive(
                boolean antFilterCaseSensitive) {
            doSetProperty("antFilterCaseSensitive", antFilterCaseSensitive);
            return this;
        }
        /**
         * Sets case sensitive flag on ant filter.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder antFilterCaseSensitive(
                String antFilterCaseSensitive) {
            doSetProperty("antFilterCaseSensitive", antFilterCaseSensitive);
            return this;
        }
        /**
         * Ant style filter inclusion. Multiple inclusions may be specified in
         * comma-delimited format.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder antInclude(String antInclude) {
            doSetProperty("antInclude", antInclude);
            return this;
        }
        /**
         * Allows for controlling whether the limit from maxMessagesPerPoll is
         * eager or not. If eager then the limit is during the scanning of
         * files. Where as false would scan all files, and then perform sorting.
         * Setting this option to false allows for sorting all files first, and
         * then limit the poll. Mind that this requires a higher memory usage as
         * all file details are in memory to perform the sorting.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder eagerMaxMessagesPerPoll(
                boolean eagerMaxMessagesPerPoll) {
            doSetProperty("eagerMaxMessagesPerPoll", eagerMaxMessagesPerPoll);
            return this;
        }
        /**
         * Allows for controlling whether the limit from maxMessagesPerPoll is
         * eager or not. If eager then the limit is during the scanning of
         * files. Where as false would scan all files, and then perform sorting.
         * Setting this option to false allows for sorting all files first, and
         * then limit the poll. Mind that this requires a higher memory usage as
         * all file details are in memory to perform the sorting.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder eagerMaxMessagesPerPoll(
                String eagerMaxMessagesPerPoll) {
            doSetProperty("eagerMaxMessagesPerPoll", eagerMaxMessagesPerPoll);
            return this;
        }
        /**
         * Is used to exclude files, if filename matches the regex pattern
         * (matching is case in-senstive). Notice if you use symbols such as
         * plus sign and others you would need to configure this using the RAW()
         * syntax if configuring this as an endpoint uri. See more details at
         * configuring endpoint uris.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder exclude(String exclude) {
            doSetProperty("exclude", exclude);
            return this;
        }
        /**
         * Pluggable filter as a
         * org.apache.camel.component.file.GenericFileFilter class. Will skip
         * files if filter returns false in its accept() method.
         * 
         * The option is a:
         * <code>org.apache.camel.component.file.GenericFileFilter&lt;org.apache.commons.net.ftp.FTPFile&gt;</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder filter(Object filter) {
            doSetProperty("filter", filter);
            return this;
        }
        /**
         * Pluggable filter as a
         * org.apache.camel.component.file.GenericFileFilter class. Will skip
         * files if filter returns false in its accept() method.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.file.GenericFileFilter&lt;org.apache.commons.net.ftp.FTPFile&gt;</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder filter(String filter) {
            doSetProperty("filter", filter);
            return this;
        }
        /**
         * Filters the directory based on Simple language. For example to filter
         * on current date, you can use a simple date pattern such as
         * ${date:now:yyyMMdd}.
         * 
         * The option is a: <code>org.apache.camel.Predicate</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder filterDirectory(
                Predicate filterDirectory) {
            doSetProperty("filterDirectory", filterDirectory);
            return this;
        }
        /**
         * Filters the directory based on Simple language. For example to filter
         * on current date, you can use a simple date pattern such as
         * ${date:now:yyyMMdd}.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Predicate</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder filterDirectory(
                String filterDirectory) {
            doSetProperty("filterDirectory", filterDirectory);
            return this;
        }
        /**
         * Filters the file based on Simple language. For example to filter on
         * file size, you can use ${file:size} 5000.
         * 
         * The option is a: <code>org.apache.camel.Predicate</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder filterFile(Predicate filterFile) {
            doSetProperty("filterFile", filterFile);
            return this;
        }
        /**
         * Filters the file based on Simple language. For example to filter on
         * file size, you can use ${file:size} 5000.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Predicate</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder filterFile(String filterFile) {
            doSetProperty("filterFile", filterFile);
            return this;
        }
        /**
         * Option to use the Idempotent Consumer EIP pattern to let Camel skip
         * already processed files. Will by default use a memory based LRUCache
         * that holds 1000 entries. If noop=true then idempotent will be enabled
         * as well to avoid consuming the same files over and over again.
         * 
         * The option is a: <code>java.lang.Boolean</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder idempotent(Boolean idempotent) {
            doSetProperty("idempotent", idempotent);
            return this;
        }
        /**
         * Option to use the Idempotent Consumer EIP pattern to let Camel skip
         * already processed files. Will by default use a memory based LRUCache
         * that holds 1000 entries. If noop=true then idempotent will be enabled
         * as well to avoid consuming the same files over and over again.
         * 
         * The option will be converted to a <code>java.lang.Boolean</code>
         * type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder idempotent(String idempotent) {
            doSetProperty("idempotent", idempotent);
            return this;
        }
        /**
         * To use a custom idempotent key. By default the absolute path of the
         * file is used. You can use the File Language, for example to use the
         * file name and file size, you can do:
         * idempotentKey=${file:name}-${file:size}.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder idempotentKey(
                Expression idempotentKey) {
            doSetProperty("idempotentKey", idempotentKey);
            return this;
        }
        /**
         * To use a custom idempotent key. By default the absolute path of the
         * file is used. You can use the File Language, for example to use the
         * file name and file size, you can do:
         * idempotentKey=${file:name}-${file:size}.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder idempotentKey(String idempotentKey) {
            doSetProperty("idempotentKey", idempotentKey);
            return this;
        }
        /**
         * A pluggable repository org.apache.camel.spi.IdempotentRepository
         * which by default use MemoryMessageIdRepository if none is specified
         * and idempotent is true.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.IdempotentRepository</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder idempotentRepository(
                IdempotentRepository idempotentRepository) {
            doSetProperty("idempotentRepository", idempotentRepository);
            return this;
        }
        /**
         * A pluggable repository org.apache.camel.spi.IdempotentRepository
         * which by default use MemoryMessageIdRepository if none is specified
         * and idempotent is true.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.IdempotentRepository</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder idempotentRepository(
                String idempotentRepository) {
            doSetProperty("idempotentRepository", idempotentRepository);
            return this;
        }
        /**
         * Is used to include files, if filename matches the regex pattern
         * (matching is case in-sensitive). Notice if you use symbols such as
         * plus sign and others you would need to configure this using the RAW()
         * syntax if configuring this as an endpoint uri. See more details at
         * configuring endpoint uris.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder include(String include) {
            doSetProperty("include", include);
            return this;
        }
        /**
         * The maximum depth to traverse when recursively processing a
         * directory.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder maxDepth(int maxDepth) {
            doSetProperty("maxDepth", maxDepth);
            return this;
        }
        /**
         * The maximum depth to traverse when recursively processing a
         * directory.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder maxDepth(String maxDepth) {
            doSetProperty("maxDepth", maxDepth);
            return this;
        }
        /**
         * To define a maximum messages to gather per poll. By default no
         * maximum is set. Can be used to set a limit of e.g. 1000 to avoid when
         * starting up the server that there are thousands of files. Set a value
         * of 0 or negative to disabled it. Notice: If this option is in use
         * then the File and FTP components will limit before any sorting. For
         * example if you have 100000 files and use maxMessagesPerPoll=500, then
         * only the first 500 files will be picked up, and then sorted. You can
         * use the eagerMaxMessagesPerPoll option and set this to false to allow
         * to scan all files first and then sort afterwards.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder maxMessagesPerPoll(
                int maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * To define a maximum messages to gather per poll. By default no
         * maximum is set. Can be used to set a limit of e.g. 1000 to avoid when
         * starting up the server that there are thousands of files. Set a value
         * of 0 or negative to disabled it. Notice: If this option is in use
         * then the File and FTP components will limit before any sorting. For
         * example if you have 100000 files and use maxMessagesPerPoll=500, then
         * only the first 500 files will be picked up, and then sorted. You can
         * use the eagerMaxMessagesPerPoll option and set this to false to allow
         * to scan all files first and then sort afterwards.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder maxMessagesPerPoll(
                String maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * The minimum depth to start processing when recursively processing a
         * directory. Using minDepth=1 means the base directory. Using
         * minDepth=2 means the first sub directory.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder minDepth(int minDepth) {
            doSetProperty("minDepth", minDepth);
            return this;
        }
        /**
         * The minimum depth to start processing when recursively processing a
         * directory. Using minDepth=1 means the base directory. Using
         * minDepth=2 means the first sub directory.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder minDepth(String minDepth) {
            doSetProperty("minDepth", minDepth);
            return this;
        }
        /**
         * Expression (such as Simple Language) used to dynamically set the
         * filename when moving it after processing. To move files into a .done
         * subdirectory just enter .done.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder move(Expression move) {
            doSetProperty("move", move);
            return this;
        }
        /**
         * Expression (such as Simple Language) used to dynamically set the
         * filename when moving it after processing. To move files into a .done
         * subdirectory just enter .done.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: filter
         */
        default FtpsEndpointConsumerBuilder move(String move) {
            doSetProperty("move", move);
            return this;
        }
        /**
         * Pluggable read-lock as a
         * org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy
         * implementation.
         * 
         * The option is a:
         * <code>org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy&lt;org.apache.commons.net.ftp.FTPFile&gt;</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder exclusiveReadLockStrategy(
                Object exclusiveReadLockStrategy) {
            doSetProperty("exclusiveReadLockStrategy", exclusiveReadLockStrategy);
            return this;
        }
        /**
         * Pluggable read-lock as a
         * org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy
         * implementation.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy&lt;org.apache.commons.net.ftp.FTPFile&gt;</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder exclusiveReadLockStrategy(
                String exclusiveReadLockStrategy) {
            doSetProperty("exclusiveReadLockStrategy", exclusiveReadLockStrategy);
            return this;
        }
        /**
         * Used by consumer, to only poll the files if it has exclusive
         * read-lock on the file (i.e. the file is not in-progress or being
         * written). Camel will wait until the file lock is granted. This option
         * provides the build in strategies: - none - No read lock is in use -
         * markerFile - Camel creates a marker file (fileName.camelLock) and
         * then holds a lock on it. This option is not available for the FTP
         * component - changed - Changed is using file length/modification
         * timestamp to detect whether the file is currently being copied or
         * not. Will at least use 1 sec to determine this, so this option cannot
         * consume files as fast as the others, but can be more reliable as the
         * JDK IO API cannot always determine whether a file is currently being
         * used by another process. The option readLockCheckInterval can be used
         * to set the check frequency. - fileLock - is for using
         * java.nio.channels.FileLock. This option is not avail for Windows OS
         * and the FTP component. This approach should be avoided when accessing
         * a remote file system via a mount/share unless that file system
         * supports distributed file locks. - rename - rename is for using a try
         * to rename the file as a test if we can get exclusive read-lock. -
         * idempotent - (only for file component) idempotent is for using a
         * idempotentRepository as the read-lock. This allows to use read locks
         * that supports clustering if the idempotent repository implementation
         * supports that. - idempotent-changed - (only for file component)
         * idempotent-changed is for using a idempotentRepository and changed as
         * the combined read-lock. This allows to use read locks that supports
         * clustering if the idempotent repository implementation supports that.
         * - idempotent-rename - (only for file component) idempotent-rename is
         * for using a idempotentRepository and rename as the combined
         * read-lock. This allows to use read locks that supports clustering if
         * the idempotent repository implementation supports that. Notice: The
         * various read locks is not all suited to work in clustered mode, where
         * concurrent consumers on different nodes is competing for the same
         * files on a shared file system. The markerFile using a close to atomic
         * operation to create the empty marker file, but its not guaranteed to
         * work in a cluster. The fileLock may work better but then the file
         * system need to support distributed file locks, and so on. Using the
         * idempotent read lock can support clustering if the idempotent
         * repository supports clustering, such as Hazelcast Component or
         * Infinispan.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLock(String readLock) {
            doSetProperty("readLock", readLock);
            return this;
        }
        /**
         * Interval in millis for the read-lock, if supported by the read lock.
         * This interval is used for sleeping between attempts to acquire the
         * read lock. For example when using the changed read lock, you can set
         * a higher interval period to cater for slow writes. The default of 1
         * sec. may be too fast if the producer is very slow writing the file.
         * Notice: For FTP the default readLockCheckInterval is 5000. The
         * readLockTimeout value must be higher than readLockCheckInterval, but
         * a rule of thumb is to have a timeout that is at least 2 or more times
         * higher than the readLockCheckInterval. This is needed to ensure that
         * amble time is allowed for the read lock process to try to grab the
         * lock before the timeout was hit.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockCheckInterval(
                long readLockCheckInterval) {
            doSetProperty("readLockCheckInterval", readLockCheckInterval);
            return this;
        }
        /**
         * Interval in millis for the read-lock, if supported by the read lock.
         * This interval is used for sleeping between attempts to acquire the
         * read lock. For example when using the changed read lock, you can set
         * a higher interval period to cater for slow writes. The default of 1
         * sec. may be too fast if the producer is very slow writing the file.
         * Notice: For FTP the default readLockCheckInterval is 5000. The
         * readLockTimeout value must be higher than readLockCheckInterval, but
         * a rule of thumb is to have a timeout that is at least 2 or more times
         * higher than the readLockCheckInterval. This is needed to ensure that
         * amble time is allowed for the read lock process to try to grab the
         * lock before the timeout was hit.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockCheckInterval(
                String readLockCheckInterval) {
            doSetProperty("readLockCheckInterval", readLockCheckInterval);
            return this;
        }
        /**
         * Whether or not read lock with marker files should upon startup delete
         * any orphan read lock files, which may have been left on the file
         * system, if Camel was not properly shutdown (such as a JVM crash). If
         * turning this option to false then any orphaned lock file will cause
         * Camel to not attempt to pickup that file, this could also be due
         * another node is concurrently reading files from the same shared
         * directory.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockDeleteOrphanLockFiles(
                boolean readLockDeleteOrphanLockFiles) {
            doSetProperty("readLockDeleteOrphanLockFiles", readLockDeleteOrphanLockFiles);
            return this;
        }
        /**
         * Whether or not read lock with marker files should upon startup delete
         * any orphan read lock files, which may have been left on the file
         * system, if Camel was not properly shutdown (such as a JVM crash). If
         * turning this option to false then any orphaned lock file will cause
         * Camel to not attempt to pickup that file, this could also be due
         * another node is concurrently reading files from the same shared
         * directory.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockDeleteOrphanLockFiles(
                String readLockDeleteOrphanLockFiles) {
            doSetProperty("readLockDeleteOrphanLockFiles", readLockDeleteOrphanLockFiles);
            return this;
        }
        /**
         * Logging level used when a read lock could not be acquired. By default
         * a DEBUG is logged. You can change this level, for example to OFF to
         * not have any logging. This option is only applicable for readLock of
         * types: changed, fileLock, idempotent, idempotent-changed,
         * idempotent-rename, rename.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockLoggingLevel(
                LoggingLevel readLockLoggingLevel) {
            doSetProperty("readLockLoggingLevel", readLockLoggingLevel);
            return this;
        }
        /**
         * Logging level used when a read lock could not be acquired. By default
         * a DEBUG is logged. You can change this level, for example to OFF to
         * not have any logging. This option is only applicable for readLock of
         * types: changed, fileLock, idempotent, idempotent-changed,
         * idempotent-rename, rename.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockLoggingLevel(
                String readLockLoggingLevel) {
            doSetProperty("readLockLoggingLevel", readLockLoggingLevel);
            return this;
        }
        /**
         * Whether to use marker file with the changed, rename, or exclusive
         * read lock types. By default a marker file is used as well to guard
         * against other processes picking up the same files. This behavior can
         * be turned off by setting this option to false. For example if you do
         * not want to write marker files to the file systems by the Camel
         * application.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockMarkerFile(
                boolean readLockMarkerFile) {
            doSetProperty("readLockMarkerFile", readLockMarkerFile);
            return this;
        }
        /**
         * Whether to use marker file with the changed, rename, or exclusive
         * read lock types. By default a marker file is used as well to guard
         * against other processes picking up the same files. This behavior can
         * be turned off by setting this option to false. For example if you do
         * not want to write marker files to the file systems by the Camel
         * application.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockMarkerFile(
                String readLockMarkerFile) {
            doSetProperty("readLockMarkerFile", readLockMarkerFile);
            return this;
        }
        /**
         * This option is applied only for readLock=changed. It allows to
         * specify a minimum age the file must be before attempting to acquire
         * the read lock. For example use readLockMinAge=300s to require the
         * file is at last 5 minutes old. This can speedup the changed read lock
         * as it will only attempt to acquire files which are at least that
         * given age.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockMinAge(long readLockMinAge) {
            doSetProperty("readLockMinAge", readLockMinAge);
            return this;
        }
        /**
         * This option is applied only for readLock=changed. It allows to
         * specify a minimum age the file must be before attempting to acquire
         * the read lock. For example use readLockMinAge=300s to require the
         * file is at last 5 minutes old. This can speedup the changed read lock
         * as it will only attempt to acquire files which are at least that
         * given age.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockMinAge(String readLockMinAge) {
            doSetProperty("readLockMinAge", readLockMinAge);
            return this;
        }
        /**
         * This option is applied only for readLock=changed. It allows you to
         * configure a minimum file length. By default Camel expects the file to
         * contain data, and thus the default value is 1. You can set this
         * option to zero, to allow consuming zero-length files.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockMinLength(
                long readLockMinLength) {
            doSetProperty("readLockMinLength", readLockMinLength);
            return this;
        }
        /**
         * This option is applied only for readLock=changed. It allows you to
         * configure a minimum file length. By default Camel expects the file to
         * contain data, and thus the default value is 1. You can set this
         * option to zero, to allow consuming zero-length files.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockMinLength(
                String readLockMinLength) {
            doSetProperty("readLockMinLength", readLockMinLength);
            return this;
        }
        /**
         * This option is applied only for readLock=idempotent. It allows to
         * specify whether to remove the file name entry from the idempotent
         * repository when processing the file is succeeded and a commit
         * happens. By default the file is not removed which ensures that any
         * race-condition do not occur so another active node may attempt to
         * grab the file. Instead the idempotent repository may support eviction
         * strategies that you can configure to evict the file name entry after
         * X minutes - this ensures no problems with race conditions. See more
         * details at the readLockIdempotentReleaseDelay option.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockRemoveOnCommit(
                boolean readLockRemoveOnCommit) {
            doSetProperty("readLockRemoveOnCommit", readLockRemoveOnCommit);
            return this;
        }
        /**
         * This option is applied only for readLock=idempotent. It allows to
         * specify whether to remove the file name entry from the idempotent
         * repository when processing the file is succeeded and a commit
         * happens. By default the file is not removed which ensures that any
         * race-condition do not occur so another active node may attempt to
         * grab the file. Instead the idempotent repository may support eviction
         * strategies that you can configure to evict the file name entry after
         * X minutes - this ensures no problems with race conditions. See more
         * details at the readLockIdempotentReleaseDelay option.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockRemoveOnCommit(
                String readLockRemoveOnCommit) {
            doSetProperty("readLockRemoveOnCommit", readLockRemoveOnCommit);
            return this;
        }
        /**
         * This option is applied only for readLock=idempotent. It allows to
         * specify whether to remove the file name entry from the idempotent
         * repository when processing the file failed and a rollback happens. If
         * this option is false, then the file name entry is confirmed (as if
         * the file did a commit).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockRemoveOnRollback(
                boolean readLockRemoveOnRollback) {
            doSetProperty("readLockRemoveOnRollback", readLockRemoveOnRollback);
            return this;
        }
        /**
         * This option is applied only for readLock=idempotent. It allows to
         * specify whether to remove the file name entry from the idempotent
         * repository when processing the file failed and a rollback happens. If
         * this option is false, then the file name entry is confirmed (as if
         * the file did a commit).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockRemoveOnRollback(
                String readLockRemoveOnRollback) {
            doSetProperty("readLockRemoveOnRollback", readLockRemoveOnRollback);
            return this;
        }
        /**
         * Optional timeout in millis for the read-lock, if supported by the
         * read-lock. If the read-lock could not be granted and the timeout
         * triggered, then Camel will skip the file. At next poll Camel, will
         * try the file again, and this time maybe the read-lock could be
         * granted. Use a value of 0 or lower to indicate forever. Currently
         * fileLock, changed and rename support the timeout. Notice: For FTP the
         * default readLockTimeout value is 20000 instead of 10000. The
         * readLockTimeout value must be higher than readLockCheckInterval, but
         * a rule of thumb is to have a timeout that is at least 2 or more times
         * higher than the readLockCheckInterval. This is needed to ensure that
         * amble time is allowed for the read lock process to try to grab the
         * lock before the timeout was hit.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockTimeout(long readLockTimeout) {
            doSetProperty("readLockTimeout", readLockTimeout);
            return this;
        }
        /**
         * Optional timeout in millis for the read-lock, if supported by the
         * read-lock. If the read-lock could not be granted and the timeout
         * triggered, then Camel will skip the file. At next poll Camel, will
         * try the file again, and this time maybe the read-lock could be
         * granted. Use a value of 0 or lower to indicate forever. Currently
         * fileLock, changed and rename support the timeout. Notice: For FTP the
         * default readLockTimeout value is 20000 instead of 10000. The
         * readLockTimeout value must be higher than readLockCheckInterval, but
         * a rule of thumb is to have a timeout that is at least 2 or more times
         * higher than the readLockCheckInterval. This is needed to ensure that
         * amble time is allowed for the read lock process to try to grab the
         * lock before the timeout was hit.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: lock
         */
        default FtpsEndpointConsumerBuilder readLockTimeout(
                String readLockTimeout) {
            doSetProperty("readLockTimeout", readLockTimeout);
            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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder backoffMultiplier(
                String backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * Milliseconds before the next poll. 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 FtpsEndpointConsumerBuilder delay(long delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * Milliseconds before the next poll. 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder 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 FtpsEndpointConsumerBuilder useFixedDelay(String useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
        /**
         * To shuffle the list of files (sort in random order).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: sort
         */
        default FtpsEndpointConsumerBuilder shuffle(boolean shuffle) {
            doSetProperty("shuffle", shuffle);
            return this;
        }
        /**
         * To shuffle the list of files (sort in random order).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: sort
         */
        default FtpsEndpointConsumerBuilder shuffle(String shuffle) {
            doSetProperty("shuffle", shuffle);
            return this;
        }
        /**
         * Built-in sort by using the File Language. Supports nested sorts, so
         * you can have a sort by file name and as a 2nd group sort by modified
         * date.
         * 
         * The option is a:
         * <code>java.util.Comparator&lt;org.apache.camel.Exchange&gt;</code>
         * type.
         * 
         * Group: sort
         */
        default FtpsEndpointConsumerBuilder sortBy(Comparator<Exchange> sortBy) {
            doSetProperty("sortBy", sortBy);
            return this;
        }
        /**
         * Built-in sort by using the File Language. Supports nested sorts, so
         * you can have a sort by file name and as a 2nd group sort by modified
         * date.
         * 
         * The option will be converted to a
         * <code>java.util.Comparator&lt;org.apache.camel.Exchange&gt;</code>
         * type.
         * 
         * Group: sort
         */
        default FtpsEndpointConsumerBuilder sortBy(String sortBy) {
            doSetProperty("sortBy", sortBy);
            return this;
        }
        /**
         * Pluggable sorter as a java.util.Comparator class.
         * 
         * The option is a:
         * <code>java.util.Comparator&lt;org.apache.camel.component.file.GenericFile&lt;org.apache.commons.net.ftp.FTPFile&gt;&gt;</code> type.
         * 
         * Group: sort
         */
        default FtpsEndpointConsumerBuilder sorter(Comparator<Object> sorter) {
            doSetProperty("sorter", sorter);
            return this;
        }
        /**
         * Pluggable sorter as a java.util.Comparator class.
         * 
         * The option will be converted to a
         * <code>java.util.Comparator&lt;org.apache.camel.component.file.GenericFile&lt;org.apache.commons.net.ftp.FTPFile&gt;&gt;</code> type.
         * 
         * Group: sort
         */
        default FtpsEndpointConsumerBuilder sorter(String sorter) {
            doSetProperty("sorter", sorter);
            return this;
        }
        /**
         * Account to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder account(String account) {
            doSetProperty("account", account);
            return this;
        }
        /**
         * Use this option to disable default options when using secure data
         * channel. This allows you to be in full control what the execPbsz and
         * execProt setting should be used. Default is false.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder disableSecureDataChannelDefaults(
                boolean disableSecureDataChannelDefaults) {
            doSetProperty("disableSecureDataChannelDefaults", disableSecureDataChannelDefaults);
            return this;
        }
        /**
         * Use this option to disable default options when using secure data
         * channel. This allows you to be in full control what the execPbsz and
         * execProt setting should be used. Default is false.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder disableSecureDataChannelDefaults(
                String disableSecureDataChannelDefaults) {
            doSetProperty("disableSecureDataChannelDefaults", disableSecureDataChannelDefaults);
            return this;
        }
        /**
         * When using secure data channel you can set the exec protection buffer
         * size.
         * 
         * The option is a: <code>java.lang.Long</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder execPbsz(Long execPbsz) {
            doSetProperty("execPbsz", execPbsz);
            return this;
        }
        /**
         * When using secure data channel you can set the exec protection buffer
         * size.
         * 
         * The option will be converted to a <code>java.lang.Long</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder execPbsz(String execPbsz) {
            doSetProperty("execPbsz", execPbsz);
            return this;
        }
        /**
         * The exec protection level PROT command. C - Clear S - Safe(SSL
         * protocol only) E - Confidential(SSL protocol only) P - Private.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder execProt(String execProt) {
            doSetProperty("execProt", execProt);
            return this;
        }
        /**
         * Set the key store parameters.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder ftpClientKeyStoreParameters(
                Map<String, Object> ftpClientKeyStoreParameters) {
            doSetProperty("ftpClientKeyStoreParameters", ftpClientKeyStoreParameters);
            return this;
        }
        /**
         * Set the key store parameters.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder ftpClientKeyStoreParameters(
                String ftpClientKeyStoreParameters) {
            doSetProperty("ftpClientKeyStoreParameters", ftpClientKeyStoreParameters);
            return this;
        }
        /**
         * Set the trust store parameters.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder ftpClientTrustStoreParameters(
                Map<String, Object> ftpClientTrustStoreParameters) {
            doSetProperty("ftpClientTrustStoreParameters", ftpClientTrustStoreParameters);
            return this;
        }
        /**
         * Set the trust store parameters.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder ftpClientTrustStoreParameters(
                String ftpClientTrustStoreParameters) {
            doSetProperty("ftpClientTrustStoreParameters", ftpClientTrustStoreParameters);
            return this;
        }
        /**
         * Set the security mode (Implicit/Explicit). true - Implicit Mode /
         * False - Explicit Mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder implicit(boolean implicit) {
            doSetProperty("implicit", implicit);
            return this;
        }
        /**
         * Set the security mode (Implicit/Explicit). true - Implicit Mode /
         * False - Explicit Mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder implicit(String implicit) {
            doSetProperty("implicit", implicit);
            return this;
        }
        /**
         * Password to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the underlying security protocol.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder securityProtocol(
                String securityProtocol) {
            doSetProperty("securityProtocol", securityProtocol);
            return this;
        }
        /**
         * Gets the JSSE configuration that overrides any settings in
         * FtpsEndpoint#ftpClientKeyStoreParameters,
         * ftpClientTrustStoreParameters, and
         * FtpsConfiguration#getSecurityProtocol().
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * Gets the JSSE configuration that overrides any settings in
         * FtpsEndpoint#ftpClientKeyStoreParameters,
         * ftpClientTrustStoreParameters, and
         * FtpsConfiguration#getSecurityProtocol().
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * Username to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointConsumerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the FTPS component.
     */
    public interface AdvancedFtpsEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default FtpsEndpointConsumerBuilder basic() {
            return (FtpsEndpointConsumerBuilder) this;
        }
        /**
         * If set this option to be true, camel-ftp will use the list file
         * directly to check if the file exists. Since some FTP server may not
         * support to list the file directly, if the option is false, camel-ftp
         * will use the old way to list the directory and check if the file
         * exists. This option also influences readLock=changed to control
         * whether it performs a fast check to update file information or not.
         * This can be used to speed up the process if the FTP server has a lot
         * of files.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder fastExistsCheck(
                boolean fastExistsCheck) {
            doSetProperty("fastExistsCheck", fastExistsCheck);
            return this;
        }
        /**
         * If set this option to be true, camel-ftp will use the list file
         * directly to check if the file exists. Since some FTP server may not
         * support to list the file directly, if the option is false, camel-ftp
         * will use the old way to list the directory and check if the file
         * exists. This option also influences readLock=changed to control
         * whether it performs a fast check to update file information or not.
         * This can be used to speed up the process if the FTP server has a lot
         * of files.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder fastExistsCheck(
                String fastExistsCheck) {
            doSetProperty("fastExistsCheck", fastExistsCheck);
            return this;
        }
        /**
         * Whether the FTP consumer should download the file. If this option is
         * set to false, then the message body will be null, but the consumer
         * will still trigger a Camel Exchange that has details about the file
         * such as file name, file size, etc. It's just that the file will not
         * be downloaded.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder download(boolean download) {
            doSetProperty("download", download);
            return this;
        }
        /**
         * Whether the FTP consumer should download the file. If this option is
         * set to false, then the message body will be null, but the consumer
         * will still trigger a Camel Exchange that has details about the file
         * such as file name, file size, etc. It's just that the file will not
         * be downloaded.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder download(String download) {
            doSetProperty("download", download);
            return this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option is a: <code>org.apache.camel.spi.ExceptionHandler</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder 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 AdvancedFtpsEndpointConsumerBuilder 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 AdvancedFtpsEndpointConsumerBuilder 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 AdvancedFtpsEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * Allows you to set how the consumer will handle subfolders and files
         * in the path if the directory parser results in with absolute paths
         * The reason for this is that some FTP servers may return file names
         * with absolute paths, and if so then the FTP component needs to handle
         * this by converting the returned path into a relative path.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder handleDirectoryParserAbsoluteResult(
                boolean handleDirectoryParserAbsoluteResult) {
            doSetProperty("handleDirectoryParserAbsoluteResult", handleDirectoryParserAbsoluteResult);
            return this;
        }
        /**
         * Allows you to set how the consumer will handle subfolders and files
         * in the path if the directory parser results in with absolute paths
         * The reason for this is that some FTP servers may return file names
         * with absolute paths, and if so then the FTP component needs to handle
         * this by converting the returned path into a relative path.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder handleDirectoryParserAbsoluteResult(
                String handleDirectoryParserAbsoluteResult) {
            doSetProperty("handleDirectoryParserAbsoluteResult", handleDirectoryParserAbsoluteResult);
            return this;
        }
        /**
         * Whether to ignore when (trying to list files in directories or when
         * downloading a file), which does not exist or due to permission error.
         * By default when a directory or file does not exists or insufficient
         * permission, then an exception is thrown. Setting this option to true
         * allows to ignore that instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder ignoreFileNotFoundOrPermissionError(
                boolean ignoreFileNotFoundOrPermissionError) {
            doSetProperty("ignoreFileNotFoundOrPermissionError", ignoreFileNotFoundOrPermissionError);
            return this;
        }
        /**
         * Whether to ignore when (trying to list files in directories or when
         * downloading a file), which does not exist or due to permission error.
         * By default when a directory or file does not exists or insufficient
         * permission, then an exception is thrown. Setting this option to true
         * allows to ignore that instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder ignoreFileNotFoundOrPermissionError(
                String ignoreFileNotFoundOrPermissionError) {
            doSetProperty("ignoreFileNotFoundOrPermissionError", ignoreFileNotFoundOrPermissionError);
            return this;
        }
        /**
         * A pluggable in-progress repository
         * org.apache.camel.spi.IdempotentRepository. The in-progress repository
         * is used to account the current in progress files being consumed. By
         * default a memory based repository is used.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.IdempotentRepository</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder inProgressRepository(
                IdempotentRepository inProgressRepository) {
            doSetProperty("inProgressRepository", inProgressRepository);
            return this;
        }
        /**
         * A pluggable in-progress repository
         * org.apache.camel.spi.IdempotentRepository. The in-progress repository
         * is used to account the current in progress files being consumed. By
         * default a memory based repository is used.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.IdempotentRepository</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder inProgressRepository(
                String inProgressRepository) {
            doSetProperty("inProgressRepository", inProgressRepository);
            return this;
        }
        /**
         * When consuming, a local work directory can be used to store the
         * remote file content directly in local files, to avoid loading the
         * content into memory. This is beneficial, if you consume a very big
         * remote file and thus can conserve memory.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder localWorkDirectory(
                String localWorkDirectory) {
            doSetProperty("localWorkDirectory", localWorkDirectory);
            return this;
        }
        /**
         * To use a custom org.apache.camel.spi.ExceptionHandler to handle any
         * thrown exceptions that happens during the file on completion process
         * where the consumer does either a commit or rollback. The default
         * implementation will log any exception at WARN level and ignore.
         * 
         * The option is a: <code>org.apache.camel.spi.ExceptionHandler</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder onCompletionExceptionHandler(
                ExceptionHandler onCompletionExceptionHandler) {
            doSetProperty("onCompletionExceptionHandler", onCompletionExceptionHandler);
            return this;
        }
        /**
         * To use a custom org.apache.camel.spi.ExceptionHandler to handle any
         * thrown exceptions that happens during the file on completion process
         * where the consumer does either a commit or rollback. The default
         * implementation will log any exception at WARN level and ignore.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.ExceptionHandler</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder onCompletionExceptionHandler(
                String onCompletionExceptionHandler) {
            doSetProperty("onCompletionExceptionHandler", onCompletionExceptionHandler);
            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 AdvancedFtpsEndpointConsumerBuilder 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 AdvancedFtpsEndpointConsumerBuilder pollStrategy(
                String pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * A pluggable
         * org.apache.camel.component.file.GenericFileProcessStrategy allowing
         * you to implement your own readLock option or similar. Can also be
         * used when special conditions must be met before a file can be
         * consumed, such as a special ready file exists. If this option is set
         * then the readLock option does not apply.
         * 
         * The option is a:
         * <code>org.apache.camel.component.file.GenericFileProcessStrategy&lt;org.apache.commons.net.ftp.FTPFile&gt;</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder processStrategy(
                Object processStrategy) {
            doSetProperty("processStrategy", processStrategy);
            return this;
        }
        /**
         * A pluggable
         * org.apache.camel.component.file.GenericFileProcessStrategy allowing
         * you to implement your own readLock option or similar. Can also be
         * used when special conditions must be met before a file can be
         * consumed, such as a special ready file exists. If this option is set
         * then the readLock option does not apply.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.file.GenericFileProcessStrategy&lt;org.apache.commons.net.ftp.FTPFile&gt;</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder processStrategy(
                String processStrategy) {
            doSetProperty("processStrategy", processStrategy);
            return this;
        }
        /**
         * Whether to allow using LIST command when downloading a file. Default
         * is true. In some use cases you may want to download a specific file
         * and are not allowed to use the LIST command, and therefore you can
         * set this option to false. Notice when using this option, then the
         * specific file to download does not include meta-data information such
         * as file size, timestamp, permissions etc, because those information
         * is only possible to retrieve when LIST command is in use.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder useList(boolean useList) {
            doSetProperty("useList", useList);
            return this;
        }
        /**
         * Whether to allow using LIST command when downloading a file. Default
         * is true. In some use cases you may want to download a specific file
         * and are not allowed to use the LIST command, and therefore you can
         * set this option to false. Notice when using this option, then the
         * specific file to download does not include meta-data information such
         * as file size, timestamp, permissions etc, because those information
         * is only possible to retrieve when LIST command is in use.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFtpsEndpointConsumerBuilder useList(String useList) {
            doSetProperty("useList", useList);
            return this;
        }
        /**
         * Set the client side port range in active mode. The syntax is:
         * minPort-maxPort Both port numbers are inclusive, eg 10000-19999 to
         * include all 1xxxx ports.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder activePortRange(
                String activePortRange) {
            doSetProperty("activePortRange", activePortRange);
            return this;
        }
        /**
         * Automatically create missing directories in the file's pathname. For
         * the file consumer, that means creating the starting directory. For
         * the file producer, it means the directory the files should be written
         * to.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder autoCreate(
                boolean autoCreate) {
            doSetProperty("autoCreate", autoCreate);
            return this;
        }
        /**
         * Automatically create missing directories in the file's pathname. For
         * the file consumer, that means creating the starting directory. For
         * the file producer, it means the directory the files should be written
         * to.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder autoCreate(String autoCreate) {
            doSetProperty("autoCreate", autoCreate);
            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 AdvancedFtpsEndpointConsumerBuilder 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 AdvancedFtpsEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder bufferSize(int bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder bufferSize(String bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Sets the connect timeout for waiting for a connection to be
         * established Used by both FTPClient and JSCH.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder connectTimeout(
                int connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            return this;
        }
        /**
         * Sets the connect timeout for waiting for a connection to be
         * established Used by both FTPClient and JSCH.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder connectTimeout(
                String connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            return this;
        }
        /**
         * To use a custom instance of FTPClient.
         * 
         * The option is a: <code>org.apache.commons.net.ftp.FTPClient</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder ftpClient(Object ftpClient) {
            doSetProperty("ftpClient", ftpClient);
            return this;
        }
        /**
         * To use a custom instance of FTPClient.
         * 
         * The option will be converted to a
         * <code>org.apache.commons.net.ftp.FTPClient</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder ftpClient(String ftpClient) {
            doSetProperty("ftpClient", ftpClient);
            return this;
        }
        /**
         * To use a custom instance of FTPClientConfig to configure the FTP
         * client the endpoint should use.
         * 
         * The option is a:
         * <code>org.apache.commons.net.ftp.FTPClientConfig</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder ftpClientConfig(
                Object ftpClientConfig) {
            doSetProperty("ftpClientConfig", ftpClientConfig);
            return this;
        }
        /**
         * To use a custom instance of FTPClientConfig to configure the FTP
         * client the endpoint should use.
         * 
         * The option will be converted to a
         * <code>org.apache.commons.net.ftp.FTPClientConfig</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder ftpClientConfig(
                String ftpClientConfig) {
            doSetProperty("ftpClientConfig", ftpClientConfig);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClientConfig.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder ftpClientConfigParameters(
                Map<String, Object> ftpClientConfigParameters) {
            doSetProperty("ftpClientConfigParameters", ftpClientConfigParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClientConfig.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder ftpClientConfigParameters(
                String ftpClientConfigParameters) {
            doSetProperty("ftpClientConfigParameters", ftpClientConfigParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClient.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder ftpClientParameters(
                Map<String, Object> ftpClientParameters) {
            doSetProperty("ftpClientParameters", ftpClientParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClient.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder ftpClientParameters(
                String ftpClientParameters) {
            doSetProperty("ftpClientParameters", ftpClientParameters);
            return this;
        }
        /**
         * Specifies the maximum reconnect attempts Camel performs when it tries
         * to connect to the remote FTP server. Use 0 to disable this behavior.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder maximumReconnectAttempts(
                int maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * Specifies the maximum reconnect attempts Camel performs when it tries
         * to connect to the remote FTP server. Use 0 to disable this behavior.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder maximumReconnectAttempts(
                String maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder reconnectDelay(
                long reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder reconnectDelay(
                String reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Sets optional site command(s) to be executed after successful login.
         * Multiple site commands can be separated using a new line character.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder siteCommand(
                String siteCommand) {
            doSetProperty("siteCommand", siteCommand);
            return this;
        }
        /**
         * Sets the so timeout FTP and FTPS Only for Camel 2.4. SFTP for Camel
         * 2.14.3/2.15.3/2.16 onwards. Is the SocketOptions.SO_TIMEOUT value in
         * millis. Recommended option is to set this to 300000 so as not have a
         * hanged connection. On SFTP this option is set as timeout on the JSCH
         * Session instance.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder soTimeout(int soTimeout) {
            doSetProperty("soTimeout", soTimeout);
            return this;
        }
        /**
         * Sets the so timeout FTP and FTPS Only for Camel 2.4. SFTP for Camel
         * 2.14.3/2.15.3/2.16 onwards. Is the SocketOptions.SO_TIMEOUT value in
         * millis. Recommended option is to set this to 300000 so as not have a
         * hanged connection. On SFTP this option is set as timeout on the JSCH
         * Session instance.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder soTimeout(String soTimeout) {
            doSetProperty("soTimeout", soTimeout);
            return this;
        }
        /**
         * Sets whether we should stepwise change directories while traversing
         * file structures when downloading files, or as well when uploading a
         * file to a directory. You can disable this if you for example are in a
         * situation where you cannot change directory on the FTP server due
         * security reasons.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder stepwise(boolean stepwise) {
            doSetProperty("stepwise", stepwise);
            return this;
        }
        /**
         * Sets whether we should stepwise change directories while traversing
         * file structures when downloading files, or as well when uploading a
         * file to a directory. You can disable this if you for example are in a
         * situation where you cannot change directory on the FTP server due
         * security reasons.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder stepwise(String stepwise) {
            doSetProperty("stepwise", stepwise);
            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 AdvancedFtpsEndpointConsumerBuilder 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 AdvancedFtpsEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Should an exception be thrown if connection failed (exhausted) By
         * default exception is not thrown and a WARN is logged. You can use
         * this to enable exception being thrown and handle the thrown exception
         * from the org.apache.camel.spi.PollingConsumerPollStrategy rollback
         * method.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder throwExceptionOnConnectFailed(
                boolean throwExceptionOnConnectFailed) {
            doSetProperty("throwExceptionOnConnectFailed", throwExceptionOnConnectFailed);
            return this;
        }
        /**
         * Should an exception be thrown if connection failed (exhausted) By
         * default exception is not thrown and a WARN is logged. You can use
         * this to enable exception being thrown and handle the thrown exception
         * from the org.apache.camel.spi.PollingConsumerPollStrategy rollback
         * method.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder throwExceptionOnConnectFailed(
                String throwExceptionOnConnectFailed) {
            doSetProperty("throwExceptionOnConnectFailed", throwExceptionOnConnectFailed);
            return this;
        }
        /**
         * Sets the data timeout for waiting for reply Used only by FTPClient.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder timeout(int timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * Sets the data timeout for waiting for reply Used only by FTPClient.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointConsumerBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the FTPS component.
     */
    public interface FtpsEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedFtpsEndpointProducerBuilder advanced() {
            return (AdvancedFtpsEndpointProducerBuilder) this;
        }
        /**
         * Specifies the file transfer mode, BINARY or ASCII. Default is ASCII
         * (false).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder binary(boolean binary) {
            doSetProperty("binary", binary);
            return this;
        }
        /**
         * Specifies the file transfer mode, BINARY or ASCII. Default is ASCII
         * (false).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder binary(String binary) {
            doSetProperty("binary", binary);
            return this;
        }
        /**
         * This option is used to specify the encoding of the file. You can use
         * this on the consumer, to specify the encodings of the files, which
         * allow Camel to know the charset it should load the file content in
         * case the file content is being accessed. Likewise when writing a
         * file, you can use this option to specify which charset to write the
         * file as well. Do mind that when writing the file Camel may have to
         * read the message content into memory to be able to convert the data
         * into the configured charset, so do not use this if you have big
         * messages.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder charset(String charset) {
            doSetProperty("charset", charset);
            return this;
        }
        /**
         * Whether or not to disconnect from remote FTP server right after use.
         * Disconnect will only disconnect the current connection to the FTP
         * server. If you have a consumer which you want to stop, then you need
         * to stop the consumer/route instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder disconnect(boolean disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Whether or not to disconnect from remote FTP server right after use.
         * Disconnect will only disconnect the current connection to the FTP
         * server. If you have a consumer which you want to stop, then you need
         * to stop the consumer/route instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder disconnect(String disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Producer: If provided, then Camel will write a 2nd done file when the
         * original file has been written. The done file will be empty. This
         * option configures what file name to use. Either you can specify a
         * fixed name. Or you can use dynamic placeholders. The done file will
         * always be written in the same folder as the original file. Consumer:
         * If provided, Camel will only consume files if a done file exists.
         * This option configures what file name to use. Either you can specify
         * a fixed name. Or you can use dynamic placeholders.The done file is
         * always expected in the same folder as the original file. Only
         * ${file.name} and ${file.name.noext} is supported as dynamic
         * placeholders.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder doneFileName(String doneFileName) {
            doSetProperty("doneFileName", doneFileName);
            return this;
        }
        /**
         * Use Expression such as File Language to dynamically set the filename.
         * For consumers, it's used as a filename filter. For producers, it's
         * used to evaluate the filename to write. If an expression is set, it
         * take precedence over the CamelFileName header. (Note: The header
         * itself can also be an Expression). The expression options support
         * both String and Expression types. If the expression is a String type,
         * it is always evaluated using the File Language. If the expression is
         * an Expression type, the specified Expression type is used - this
         * allows you, for instance, to use OGNL expressions. For the consumer,
         * you can use it to filter filenames, so you can for instance consume
         * today's file using the File Language syntax:
         * mydata-${date:now:yyyyMMdd}.txt. The producers support the
         * CamelOverruleFileName header which takes precedence over any existing
         * CamelFileName header; the CamelOverruleFileName is a header that is
         * used only once, and makes it easier as this avoids to temporary store
         * CamelFileName and have to restore it afterwards.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder fileName(Expression fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * Use Expression such as File Language to dynamically set the filename.
         * For consumers, it's used as a filename filter. For producers, it's
         * used to evaluate the filename to write. If an expression is set, it
         * take precedence over the CamelFileName header. (Note: The header
         * itself can also be an Expression). The expression options support
         * both String and Expression types. If the expression is a String type,
         * it is always evaluated using the File Language. If the expression is
         * an Expression type, the specified Expression type is used - this
         * allows you, for instance, to use OGNL expressions. For the consumer,
         * you can use it to filter filenames, so you can for instance consume
         * today's file using the File Language syntax:
         * mydata-${date:now:yyyyMMdd}.txt. The producers support the
         * CamelOverruleFileName header which takes precedence over any existing
         * CamelFileName header; the CamelOverruleFileName is a header that is
         * used only once, and makes it easier as this avoids to temporary store
         * CamelFileName and have to restore it afterwards.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * Sets passive mode connections. Default is active mode connections.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder passiveMode(boolean passiveMode) {
            doSetProperty("passiveMode", passiveMode);
            return this;
        }
        /**
         * Sets passive mode connections. Default is active mode connections.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder passiveMode(String passiveMode) {
            doSetProperty("passiveMode", passiveMode);
            return this;
        }
        /**
         * Sets the path separator to be used. UNIX = Uses unix style path
         * separator Windows = Uses windows style path separator Auto = (is
         * default) Use existing path separator in file name.
         * 
         * The option is a:
         * <code>org.apache.camel.component.file.remote.RemoteFileConfiguration$PathSeparator</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder separator(PathSeparator separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Sets the path separator to be used. UNIX = Uses unix style path
         * separator Windows = Uses windows style path separator Auto = (is
         * default) Use existing path separator in file name.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.file.remote.RemoteFileConfiguration$PathSeparator</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder separator(String separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Configures the interval in seconds to use when logging the progress
         * of upload and download operations that are in-flight. This is used
         * for logging progress when operations takes longer time.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder transferLoggingIntervalSeconds(
                int transferLoggingIntervalSeconds) {
            doSetProperty("transferLoggingIntervalSeconds", transferLoggingIntervalSeconds);
            return this;
        }
        /**
         * Configures the interval in seconds to use when logging the progress
         * of upload and download operations that are in-flight. This is used
         * for logging progress when operations takes longer time.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder transferLoggingIntervalSeconds(
                String transferLoggingIntervalSeconds) {
            doSetProperty("transferLoggingIntervalSeconds", transferLoggingIntervalSeconds);
            return this;
        }
        /**
         * Configure the logging level to use when logging the progress of
         * upload and download operations.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder transferLoggingLevel(
                LoggingLevel transferLoggingLevel) {
            doSetProperty("transferLoggingLevel", transferLoggingLevel);
            return this;
        }
        /**
         * Configure the logging level to use when logging the progress of
         * upload and download operations.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder transferLoggingLevel(
                String transferLoggingLevel) {
            doSetProperty("transferLoggingLevel", transferLoggingLevel);
            return this;
        }
        /**
         * Configures whether the perform verbose (fine grained) logging of the
         * progress of upload and download operations.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder transferLoggingVerbose(
                boolean transferLoggingVerbose) {
            doSetProperty("transferLoggingVerbose", transferLoggingVerbose);
            return this;
        }
        /**
         * Configures whether the perform verbose (fine grained) logging of the
         * progress of upload and download operations.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointProducerBuilder transferLoggingVerbose(
                String transferLoggingVerbose) {
            doSetProperty("transferLoggingVerbose", transferLoggingVerbose);
            return this;
        }
        /**
         * What to do if a file already exists with the same name. Override,
         * which is the default, replaces the existing file. - Append - adds
         * content to the existing file. - Fail - throws a
         * GenericFileOperationException, indicating that there is already an
         * existing file. - Ignore - silently ignores the problem and does not
         * override the existing file, but assumes everything is okay. - Move -
         * option requires to use the moveExisting option to be configured as
         * well. The option eagerDeleteTargetFile can be used to control what to
         * do if an moving the file, and there exists already an existing file,
         * otherwise causing the move operation to fail. The Move option will
         * move any existing files, before writing the target file. - TryRename
         * is only applicable if tempFileName option is in use. This allows to
         * try renaming the file from the temporary name to the actual name,
         * without doing any exists check. This check may be faster on some file
         * systems and especially FTP servers.
         * 
         * The option is a:
         * <code>org.apache.camel.component.file.GenericFileExist</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder fileExist(GenericFileExist fileExist) {
            doSetProperty("fileExist", fileExist);
            return this;
        }
        /**
         * What to do if a file already exists with the same name. Override,
         * which is the default, replaces the existing file. - Append - adds
         * content to the existing file. - Fail - throws a
         * GenericFileOperationException, indicating that there is already an
         * existing file. - Ignore - silently ignores the problem and does not
         * override the existing file, but assumes everything is okay. - Move -
         * option requires to use the moveExisting option to be configured as
         * well. The option eagerDeleteTargetFile can be used to control what to
         * do if an moving the file, and there exists already an existing file,
         * otherwise causing the move operation to fail. The Move option will
         * move any existing files, before writing the target file. - TryRename
         * is only applicable if tempFileName option is in use. This allows to
         * try renaming the file from the temporary name to the actual name,
         * without doing any exists check. This check may be faster on some file
         * systems and especially FTP servers.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.file.GenericFileExist</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder fileExist(String fileExist) {
            doSetProperty("fileExist", fileExist);
            return this;
        }
        /**
         * Flatten is used to flatten the file name path to strip any leading
         * paths, so it's just the file name. This allows you to consume
         * recursively into sub-directories, but when you eg write the files to
         * another directory they will be written in a single directory. Setting
         * this to true on the producer enforces that any file name in
         * CamelFileName header will be stripped for any leading paths.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder flatten(boolean flatten) {
            doSetProperty("flatten", flatten);
            return this;
        }
        /**
         * Flatten is used to flatten the file name path to strip any leading
         * paths, so it's just the file name. This allows you to consume
         * recursively into sub-directories, but when you eg write the files to
         * another directory they will be written in a single directory. Setting
         * this to true on the producer enforces that any file name in
         * CamelFileName header will be stripped for any leading paths.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder flatten(String flatten) {
            doSetProperty("flatten", flatten);
            return this;
        }
        /**
         * Used for jailing (restricting) writing files to the starting
         * directory (and sub) only. This is enabled by default to not allow
         * Camel to write files to outside directories (to be more secured out
         * of the box). You can turn this off to allow writing files to
         * directories outside the starting directory, such as parent or root
         * folders.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder jailStartingDirectory(
                boolean jailStartingDirectory) {
            doSetProperty("jailStartingDirectory", jailStartingDirectory);
            return this;
        }
        /**
         * Used for jailing (restricting) writing files to the starting
         * directory (and sub) only. This is enabled by default to not allow
         * Camel to write files to outside directories (to be more secured out
         * of the box). You can turn this off to allow writing files to
         * directories outside the starting directory, such as parent or root
         * folders.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder jailStartingDirectory(
                String jailStartingDirectory) {
            doSetProperty("jailStartingDirectory", jailStartingDirectory);
            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 FtpsEndpointProducerBuilder 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 FtpsEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Expression (such as File Language) used to compute file name to use
         * when fileExist=Move is configured. To move files into a backup
         * subdirectory just enter backup. This option only supports the
         * following File Language tokens: file:name, file:name.ext,
         * file:name.noext, file:onlyname, file:onlyname.noext, file:ext, and
         * file:parent. Notice the file:parent is not supported by the FTP
         * component, as the FTP component can only move any existing files to a
         * relative directory based on current dir as base.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder moveExisting(Expression moveExisting) {
            doSetProperty("moveExisting", moveExisting);
            return this;
        }
        /**
         * Expression (such as File Language) used to compute file name to use
         * when fileExist=Move is configured. To move files into a backup
         * subdirectory just enter backup. This option only supports the
         * following File Language tokens: file:name, file:name.ext,
         * file:name.noext, file:onlyname, file:onlyname.noext, file:ext, and
         * file:parent. Notice the file:parent is not supported by the FTP
         * component, as the FTP component can only move any existing files to a
         * relative directory based on current dir as base.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder moveExisting(String moveExisting) {
            doSetProperty("moveExisting", moveExisting);
            return this;
        }
        /**
         * The same as tempPrefix option but offering a more fine grained
         * control on the naming of the temporary filename as it uses the File
         * Language. The location for tempFilename is relative to the final file
         * location in the option 'fileName', not the target directory in the
         * base uri. For example if option fileName includes a directory prefix:
         * dir/finalFilename then tempFileName is relative to that subdirectory
         * dir.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder tempFileName(Expression tempFileName) {
            doSetProperty("tempFileName", tempFileName);
            return this;
        }
        /**
         * The same as tempPrefix option but offering a more fine grained
         * control on the naming of the temporary filename as it uses the File
         * Language. The location for tempFilename is relative to the final file
         * location in the option 'fileName', not the target directory in the
         * base uri. For example if option fileName includes a directory prefix:
         * dir/finalFilename then tempFileName is relative to that subdirectory
         * dir.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder tempFileName(String tempFileName) {
            doSetProperty("tempFileName", tempFileName);
            return this;
        }
        /**
         * This option is used to write the file using a temporary name and
         * then, after the write is complete, rename it to the real name. Can be
         * used to identify files being written and also avoid consumers (not
         * using exclusive read locks) reading in progress files. Is often used
         * by FTP when uploading big files.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default FtpsEndpointProducerBuilder tempPrefix(String tempPrefix) {
            doSetProperty("tempPrefix", tempPrefix);
            return this;
        }
        /**
         * Account to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder account(String account) {
            doSetProperty("account", account);
            return this;
        }
        /**
         * Use this option to disable default options when using secure data
         * channel. This allows you to be in full control what the execPbsz and
         * execProt setting should be used. Default is false.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder disableSecureDataChannelDefaults(
                boolean disableSecureDataChannelDefaults) {
            doSetProperty("disableSecureDataChannelDefaults", disableSecureDataChannelDefaults);
            return this;
        }
        /**
         * Use this option to disable default options when using secure data
         * channel. This allows you to be in full control what the execPbsz and
         * execProt setting should be used. Default is false.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder disableSecureDataChannelDefaults(
                String disableSecureDataChannelDefaults) {
            doSetProperty("disableSecureDataChannelDefaults", disableSecureDataChannelDefaults);
            return this;
        }
        /**
         * When using secure data channel you can set the exec protection buffer
         * size.
         * 
         * The option is a: <code>java.lang.Long</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder execPbsz(Long execPbsz) {
            doSetProperty("execPbsz", execPbsz);
            return this;
        }
        /**
         * When using secure data channel you can set the exec protection buffer
         * size.
         * 
         * The option will be converted to a <code>java.lang.Long</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder execPbsz(String execPbsz) {
            doSetProperty("execPbsz", execPbsz);
            return this;
        }
        /**
         * The exec protection level PROT command. C - Clear S - Safe(SSL
         * protocol only) E - Confidential(SSL protocol only) P - Private.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder execProt(String execProt) {
            doSetProperty("execProt", execProt);
            return this;
        }
        /**
         * Set the key store parameters.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder ftpClientKeyStoreParameters(
                Map<String, Object> ftpClientKeyStoreParameters) {
            doSetProperty("ftpClientKeyStoreParameters", ftpClientKeyStoreParameters);
            return this;
        }
        /**
         * Set the key store parameters.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder ftpClientKeyStoreParameters(
                String ftpClientKeyStoreParameters) {
            doSetProperty("ftpClientKeyStoreParameters", ftpClientKeyStoreParameters);
            return this;
        }
        /**
         * Set the trust store parameters.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder ftpClientTrustStoreParameters(
                Map<String, Object> ftpClientTrustStoreParameters) {
            doSetProperty("ftpClientTrustStoreParameters", ftpClientTrustStoreParameters);
            return this;
        }
        /**
         * Set the trust store parameters.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder ftpClientTrustStoreParameters(
                String ftpClientTrustStoreParameters) {
            doSetProperty("ftpClientTrustStoreParameters", ftpClientTrustStoreParameters);
            return this;
        }
        /**
         * Set the security mode (Implicit/Explicit). true - Implicit Mode /
         * False - Explicit Mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder implicit(boolean implicit) {
            doSetProperty("implicit", implicit);
            return this;
        }
        /**
         * Set the security mode (Implicit/Explicit). true - Implicit Mode /
         * False - Explicit Mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder implicit(String implicit) {
            doSetProperty("implicit", implicit);
            return this;
        }
        /**
         * Password to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the underlying security protocol.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder securityProtocol(
                String securityProtocol) {
            doSetProperty("securityProtocol", securityProtocol);
            return this;
        }
        /**
         * Gets the JSSE configuration that overrides any settings in
         * FtpsEndpoint#ftpClientKeyStoreParameters,
         * ftpClientTrustStoreParameters, and
         * FtpsConfiguration#getSecurityProtocol().
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * Gets the JSSE configuration that overrides any settings in
         * FtpsEndpoint#ftpClientKeyStoreParameters,
         * ftpClientTrustStoreParameters, and
         * FtpsConfiguration#getSecurityProtocol().
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * Username to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointProducerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the FTPS component.
     */
    public interface AdvancedFtpsEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default FtpsEndpointProducerBuilder basic() {
            return (FtpsEndpointProducerBuilder) this;
        }
        /**
         * If set this option to be true, camel-ftp will use the list file
         * directly to check if the file exists. Since some FTP server may not
         * support to list the file directly, if the option is false, camel-ftp
         * will use the old way to list the directory and check if the file
         * exists. This option also influences readLock=changed to control
         * whether it performs a fast check to update file information or not.
         * This can be used to speed up the process if the FTP server has a lot
         * of files.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder fastExistsCheck(
                boolean fastExistsCheck) {
            doSetProperty("fastExistsCheck", fastExistsCheck);
            return this;
        }
        /**
         * If set this option to be true, camel-ftp will use the list file
         * directly to check if the file exists. Since some FTP server may not
         * support to list the file directly, if the option is false, camel-ftp
         * will use the old way to list the directory and check if the file
         * exists. This option also influences readLock=changed to control
         * whether it performs a fast check to update file information or not.
         * This can be used to speed up the process if the FTP server has a lot
         * of files.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder fastExistsCheck(
                String fastExistsCheck) {
            doSetProperty("fastExistsCheck", fastExistsCheck);
            return this;
        }
        /**
         * Used to specify if a null body is allowed during file writing. If set
         * to true then an empty file will be created, when set to false, and
         * attempting to send a null body to the file component, a
         * GenericFileWriteException of 'Cannot write null body to file.' will
         * be thrown. If the fileExist option is set to 'Override', then the
         * file will be truncated, and if set to append the file will remain
         * unchanged.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder allowNullBody(
                boolean allowNullBody) {
            doSetProperty("allowNullBody", allowNullBody);
            return this;
        }
        /**
         * Used to specify if a null body is allowed during file writing. If set
         * to true then an empty file will be created, when set to false, and
         * attempting to send a null body to the file component, a
         * GenericFileWriteException of 'Cannot write null body to file.' will
         * be thrown. If the fileExist option is set to 'Override', then the
         * file will be truncated, and if set to append the file will remain
         * unchanged.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder allowNullBody(
                String allowNullBody) {
            doSetProperty("allowNullBody", allowNullBody);
            return this;
        }
        /**
         * Allows you to set chmod on the stored file. For example chmod=640.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder chmod(String chmod) {
            doSetProperty("chmod", chmod);
            return this;
        }
        /**
         * Whether or not to disconnect from remote FTP server right after a
         * Batch upload is complete. disconnectOnBatchComplete will only
         * disconnect the current connection to the FTP server.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder disconnectOnBatchComplete(
                boolean disconnectOnBatchComplete) {
            doSetProperty("disconnectOnBatchComplete", disconnectOnBatchComplete);
            return this;
        }
        /**
         * Whether or not to disconnect from remote FTP server right after a
         * Batch upload is complete. disconnectOnBatchComplete will only
         * disconnect the current connection to the FTP server.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder disconnectOnBatchComplete(
                String disconnectOnBatchComplete) {
            doSetProperty("disconnectOnBatchComplete", disconnectOnBatchComplete);
            return this;
        }
        /**
         * Whether or not to eagerly delete any existing target file. This
         * option only applies when you use fileExists=Override and the
         * tempFileName option as well. You can use this to disable (set it to
         * false) deleting the target file before the temp file is written. For
         * example you may write big files and want the target file to exists
         * during the temp file is being written. This ensure the target file is
         * only deleted until the very last moment, just before the temp file is
         * being renamed to the target filename. This option is also used to
         * control whether to delete any existing files when fileExist=Move is
         * enabled, and an existing file exists. If this option
         * copyAndDeleteOnRenameFails false, then an exception will be thrown if
         * an existing file existed, if its true, then the existing file is
         * deleted before the move operation.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder eagerDeleteTargetFile(
                boolean eagerDeleteTargetFile) {
            doSetProperty("eagerDeleteTargetFile", eagerDeleteTargetFile);
            return this;
        }
        /**
         * Whether or not to eagerly delete any existing target file. This
         * option only applies when you use fileExists=Override and the
         * tempFileName option as well. You can use this to disable (set it to
         * false) deleting the target file before the temp file is written. For
         * example you may write big files and want the target file to exists
         * during the temp file is being written. This ensure the target file is
         * only deleted until the very last moment, just before the temp file is
         * being renamed to the target filename. This option is also used to
         * control whether to delete any existing files when fileExist=Move is
         * enabled, and an existing file exists. If this option
         * copyAndDeleteOnRenameFails false, then an exception will be thrown if
         * an existing file existed, if its true, then the existing file is
         * deleted before the move operation.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder eagerDeleteTargetFile(
                String eagerDeleteTargetFile) {
            doSetProperty("eagerDeleteTargetFile", eagerDeleteTargetFile);
            return this;
        }
        /**
         * Will keep the last modified timestamp from the source file (if any).
         * Will use the Exchange.FILE_LAST_MODIFIED header to located the
         * timestamp. This header can contain either a java.util.Date or long
         * with the timestamp. If the timestamp exists and the option is enabled
         * it will set this timestamp on the written file. Note: This option
         * only applies to the file producer. You cannot use this option with
         * any of the ftp producers.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder keepLastModified(
                boolean keepLastModified) {
            doSetProperty("keepLastModified", keepLastModified);
            return this;
        }
        /**
         * Will keep the last modified timestamp from the source file (if any).
         * Will use the Exchange.FILE_LAST_MODIFIED header to located the
         * timestamp. This header can contain either a java.util.Date or long
         * with the timestamp. If the timestamp exists and the option is enabled
         * it will set this timestamp on the written file. Note: This option
         * only applies to the file producer. You cannot use this option with
         * any of the ftp producers.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder keepLastModified(
                String keepLastModified) {
            doSetProperty("keepLastModified", keepLastModified);
            return this;
        }
        /**
         * Strategy (Custom Strategy) used to move file with special naming
         * token to use when fileExist=Move is configured. By default, there is
         * an implementation used if no custom strategy is provided.
         * 
         * The option is a:
         * <code>org.apache.camel.component.file.strategy.FileMoveExistingStrategy</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder moveExistingFileStrategy(
                Object moveExistingFileStrategy) {
            doSetProperty("moveExistingFileStrategy", moveExistingFileStrategy);
            return this;
        }
        /**
         * Strategy (Custom Strategy) used to move file with special naming
         * token to use when fileExist=Move is configured. By default, there is
         * an implementation used if no custom strategy is provided.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.file.strategy.FileMoveExistingStrategy</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder moveExistingFileStrategy(
                String moveExistingFileStrategy) {
            doSetProperty("moveExistingFileStrategy", moveExistingFileStrategy);
            return this;
        }
        /**
         * Whether to send a noop command as a pre-write check before uploading
         * files to the FTP server. This is enabled by default as a validation
         * of the connection is still valid, which allows to silently re-connect
         * to be able to upload the file. However if this causes problems, you
         * can turn this option off.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder sendNoop(boolean sendNoop) {
            doSetProperty("sendNoop", sendNoop);
            return this;
        }
        /**
         * Whether to send a noop command as a pre-write check before uploading
         * files to the FTP server. This is enabled by default as a validation
         * of the connection is still valid, which allows to silently re-connect
         * to be able to upload the file. However if this causes problems, you
         * can turn this option off.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFtpsEndpointProducerBuilder sendNoop(String sendNoop) {
            doSetProperty("sendNoop", sendNoop);
            return this;
        }
        /**
         * Set the client side port range in active mode. The syntax is:
         * minPort-maxPort Both port numbers are inclusive, eg 10000-19999 to
         * include all 1xxxx ports.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder activePortRange(
                String activePortRange) {
            doSetProperty("activePortRange", activePortRange);
            return this;
        }
        /**
         * Automatically create missing directories in the file's pathname. For
         * the file consumer, that means creating the starting directory. For
         * the file producer, it means the directory the files should be written
         * to.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder autoCreate(
                boolean autoCreate) {
            doSetProperty("autoCreate", autoCreate);
            return this;
        }
        /**
         * Automatically create missing directories in the file's pathname. For
         * the file consumer, that means creating the starting directory. For
         * the file producer, it means the directory the files should be written
         * to.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder autoCreate(String autoCreate) {
            doSetProperty("autoCreate", autoCreate);
            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 AdvancedFtpsEndpointProducerBuilder 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 AdvancedFtpsEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder bufferSize(int bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder bufferSize(String bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Sets the connect timeout for waiting for a connection to be
         * established Used by both FTPClient and JSCH.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder connectTimeout(
                int connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            return this;
        }
        /**
         * Sets the connect timeout for waiting for a connection to be
         * established Used by both FTPClient and JSCH.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder connectTimeout(
                String connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            return this;
        }
        /**
         * To use a custom instance of FTPClient.
         * 
         * The option is a: <code>org.apache.commons.net.ftp.FTPClient</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder ftpClient(Object ftpClient) {
            doSetProperty("ftpClient", ftpClient);
            return this;
        }
        /**
         * To use a custom instance of FTPClient.
         * 
         * The option will be converted to a
         * <code>org.apache.commons.net.ftp.FTPClient</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder ftpClient(String ftpClient) {
            doSetProperty("ftpClient", ftpClient);
            return this;
        }
        /**
         * To use a custom instance of FTPClientConfig to configure the FTP
         * client the endpoint should use.
         * 
         * The option is a:
         * <code>org.apache.commons.net.ftp.FTPClientConfig</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder ftpClientConfig(
                Object ftpClientConfig) {
            doSetProperty("ftpClientConfig", ftpClientConfig);
            return this;
        }
        /**
         * To use a custom instance of FTPClientConfig to configure the FTP
         * client the endpoint should use.
         * 
         * The option will be converted to a
         * <code>org.apache.commons.net.ftp.FTPClientConfig</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder ftpClientConfig(
                String ftpClientConfig) {
            doSetProperty("ftpClientConfig", ftpClientConfig);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClientConfig.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder ftpClientConfigParameters(
                Map<String, Object> ftpClientConfigParameters) {
            doSetProperty("ftpClientConfigParameters", ftpClientConfigParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClientConfig.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder ftpClientConfigParameters(
                String ftpClientConfigParameters) {
            doSetProperty("ftpClientConfigParameters", ftpClientConfigParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClient.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder ftpClientParameters(
                Map<String, Object> ftpClientParameters) {
            doSetProperty("ftpClientParameters", ftpClientParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClient.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder ftpClientParameters(
                String ftpClientParameters) {
            doSetProperty("ftpClientParameters", ftpClientParameters);
            return this;
        }
        /**
         * Specifies the maximum reconnect attempts Camel performs when it tries
         * to connect to the remote FTP server. Use 0 to disable this behavior.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder maximumReconnectAttempts(
                int maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * Specifies the maximum reconnect attempts Camel performs when it tries
         * to connect to the remote FTP server. Use 0 to disable this behavior.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder maximumReconnectAttempts(
                String maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder reconnectDelay(
                long reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder reconnectDelay(
                String reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Sets optional site command(s) to be executed after successful login.
         * Multiple site commands can be separated using a new line character.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder siteCommand(
                String siteCommand) {
            doSetProperty("siteCommand", siteCommand);
            return this;
        }
        /**
         * Sets the so timeout FTP and FTPS Only for Camel 2.4. SFTP for Camel
         * 2.14.3/2.15.3/2.16 onwards. Is the SocketOptions.SO_TIMEOUT value in
         * millis. Recommended option is to set this to 300000 so as not have a
         * hanged connection. On SFTP this option is set as timeout on the JSCH
         * Session instance.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder soTimeout(int soTimeout) {
            doSetProperty("soTimeout", soTimeout);
            return this;
        }
        /**
         * Sets the so timeout FTP and FTPS Only for Camel 2.4. SFTP for Camel
         * 2.14.3/2.15.3/2.16 onwards. Is the SocketOptions.SO_TIMEOUT value in
         * millis. Recommended option is to set this to 300000 so as not have a
         * hanged connection. On SFTP this option is set as timeout on the JSCH
         * Session instance.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder soTimeout(String soTimeout) {
            doSetProperty("soTimeout", soTimeout);
            return this;
        }
        /**
         * Sets whether we should stepwise change directories while traversing
         * file structures when downloading files, or as well when uploading a
         * file to a directory. You can disable this if you for example are in a
         * situation where you cannot change directory on the FTP server due
         * security reasons.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder stepwise(boolean stepwise) {
            doSetProperty("stepwise", stepwise);
            return this;
        }
        /**
         * Sets whether we should stepwise change directories while traversing
         * file structures when downloading files, or as well when uploading a
         * file to a directory. You can disable this if you for example are in a
         * situation where you cannot change directory on the FTP server due
         * security reasons.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder stepwise(String stepwise) {
            doSetProperty("stepwise", stepwise);
            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 AdvancedFtpsEndpointProducerBuilder 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 AdvancedFtpsEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Should an exception be thrown if connection failed (exhausted) By
         * default exception is not thrown and a WARN is logged. You can use
         * this to enable exception being thrown and handle the thrown exception
         * from the org.apache.camel.spi.PollingConsumerPollStrategy rollback
         * method.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder throwExceptionOnConnectFailed(
                boolean throwExceptionOnConnectFailed) {
            doSetProperty("throwExceptionOnConnectFailed", throwExceptionOnConnectFailed);
            return this;
        }
        /**
         * Should an exception be thrown if connection failed (exhausted) By
         * default exception is not thrown and a WARN is logged. You can use
         * this to enable exception being thrown and handle the thrown exception
         * from the org.apache.camel.spi.PollingConsumerPollStrategy rollback
         * method.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder throwExceptionOnConnectFailed(
                String throwExceptionOnConnectFailed) {
            doSetProperty("throwExceptionOnConnectFailed", throwExceptionOnConnectFailed);
            return this;
        }
        /**
         * Sets the data timeout for waiting for reply Used only by FTPClient.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder timeout(int timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * Sets the data timeout for waiting for reply Used only by FTPClient.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointProducerBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
    }

    /**
     * Builder for endpoint for the FTPS component.
     */
    public interface FtpsEndpointBuilder
            extends
                FtpsEndpointConsumerBuilder, FtpsEndpointProducerBuilder {
        default AdvancedFtpsEndpointBuilder advanced() {
            return (AdvancedFtpsEndpointBuilder) this;
        }
        /**
         * Specifies the file transfer mode, BINARY or ASCII. Default is ASCII
         * (false).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder binary(boolean binary) {
            doSetProperty("binary", binary);
            return this;
        }
        /**
         * Specifies the file transfer mode, BINARY or ASCII. Default is ASCII
         * (false).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder binary(String binary) {
            doSetProperty("binary", binary);
            return this;
        }
        /**
         * This option is used to specify the encoding of the file. You can use
         * this on the consumer, to specify the encodings of the files, which
         * allow Camel to know the charset it should load the file content in
         * case the file content is being accessed. Likewise when writing a
         * file, you can use this option to specify which charset to write the
         * file as well. Do mind that when writing the file Camel may have to
         * read the message content into memory to be able to convert the data
         * into the configured charset, so do not use this if you have big
         * messages.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder charset(String charset) {
            doSetProperty("charset", charset);
            return this;
        }
        /**
         * Whether or not to disconnect from remote FTP server right after use.
         * Disconnect will only disconnect the current connection to the FTP
         * server. If you have a consumer which you want to stop, then you need
         * to stop the consumer/route instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder disconnect(boolean disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Whether or not to disconnect from remote FTP server right after use.
         * Disconnect will only disconnect the current connection to the FTP
         * server. If you have a consumer which you want to stop, then you need
         * to stop the consumer/route instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder disconnect(String disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Producer: If provided, then Camel will write a 2nd done file when the
         * original file has been written. The done file will be empty. This
         * option configures what file name to use. Either you can specify a
         * fixed name. Or you can use dynamic placeholders. The done file will
         * always be written in the same folder as the original file. Consumer:
         * If provided, Camel will only consume files if a done file exists.
         * This option configures what file name to use. Either you can specify
         * a fixed name. Or you can use dynamic placeholders.The done file is
         * always expected in the same folder as the original file. Only
         * ${file.name} and ${file.name.noext} is supported as dynamic
         * placeholders.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder doneFileName(String doneFileName) {
            doSetProperty("doneFileName", doneFileName);
            return this;
        }
        /**
         * Use Expression such as File Language to dynamically set the filename.
         * For consumers, it's used as a filename filter. For producers, it's
         * used to evaluate the filename to write. If an expression is set, it
         * take precedence over the CamelFileName header. (Note: The header
         * itself can also be an Expression). The expression options support
         * both String and Expression types. If the expression is a String type,
         * it is always evaluated using the File Language. If the expression is
         * an Expression type, the specified Expression type is used - this
         * allows you, for instance, to use OGNL expressions. For the consumer,
         * you can use it to filter filenames, so you can for instance consume
         * today's file using the File Language syntax:
         * mydata-${date:now:yyyyMMdd}.txt. The producers support the
         * CamelOverruleFileName header which takes precedence over any existing
         * CamelFileName header; the CamelOverruleFileName is a header that is
         * used only once, and makes it easier as this avoids to temporary store
         * CamelFileName and have to restore it afterwards.
         * 
         * The option is a: <code>org.apache.camel.Expression</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder fileName(Expression fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * Use Expression such as File Language to dynamically set the filename.
         * For consumers, it's used as a filename filter. For producers, it's
         * used to evaluate the filename to write. If an expression is set, it
         * take precedence over the CamelFileName header. (Note: The header
         * itself can also be an Expression). The expression options support
         * both String and Expression types. If the expression is a String type,
         * it is always evaluated using the File Language. If the expression is
         * an Expression type, the specified Expression type is used - this
         * allows you, for instance, to use OGNL expressions. For the consumer,
         * you can use it to filter filenames, so you can for instance consume
         * today's file using the File Language syntax:
         * mydata-${date:now:yyyyMMdd}.txt. The producers support the
         * CamelOverruleFileName header which takes precedence over any existing
         * CamelFileName header; the CamelOverruleFileName is a header that is
         * used only once, and makes it easier as this avoids to temporary store
         * CamelFileName and have to restore it afterwards.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.Expression</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * Sets passive mode connections. Default is active mode connections.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder passiveMode(boolean passiveMode) {
            doSetProperty("passiveMode", passiveMode);
            return this;
        }
        /**
         * Sets passive mode connections. Default is active mode connections.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder passiveMode(String passiveMode) {
            doSetProperty("passiveMode", passiveMode);
            return this;
        }
        /**
         * Sets the path separator to be used. UNIX = Uses unix style path
         * separator Windows = Uses windows style path separator Auto = (is
         * default) Use existing path separator in file name.
         * 
         * The option is a:
         * <code>org.apache.camel.component.file.remote.RemoteFileConfiguration$PathSeparator</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder separator(PathSeparator separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Sets the path separator to be used. UNIX = Uses unix style path
         * separator Windows = Uses windows style path separator Auto = (is
         * default) Use existing path separator in file name.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.file.remote.RemoteFileConfiguration$PathSeparator</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder separator(String separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Configures the interval in seconds to use when logging the progress
         * of upload and download operations that are in-flight. This is used
         * for logging progress when operations takes longer time.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder transferLoggingIntervalSeconds(
                int transferLoggingIntervalSeconds) {
            doSetProperty("transferLoggingIntervalSeconds", transferLoggingIntervalSeconds);
            return this;
        }
        /**
         * Configures the interval in seconds to use when logging the progress
         * of upload and download operations that are in-flight. This is used
         * for logging progress when operations takes longer time.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder transferLoggingIntervalSeconds(
                String transferLoggingIntervalSeconds) {
            doSetProperty("transferLoggingIntervalSeconds", transferLoggingIntervalSeconds);
            return this;
        }
        /**
         * Configure the logging level to use when logging the progress of
         * upload and download operations.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder transferLoggingLevel(
                LoggingLevel transferLoggingLevel) {
            doSetProperty("transferLoggingLevel", transferLoggingLevel);
            return this;
        }
        /**
         * Configure the logging level to use when logging the progress of
         * upload and download operations.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder transferLoggingLevel(
                String transferLoggingLevel) {
            doSetProperty("transferLoggingLevel", transferLoggingLevel);
            return this;
        }
        /**
         * Configures whether the perform verbose (fine grained) logging of the
         * progress of upload and download operations.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder transferLoggingVerbose(
                boolean transferLoggingVerbose) {
            doSetProperty("transferLoggingVerbose", transferLoggingVerbose);
            return this;
        }
        /**
         * Configures whether the perform verbose (fine grained) logging of the
         * progress of upload and download operations.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default FtpsEndpointBuilder transferLoggingVerbose(
                String transferLoggingVerbose) {
            doSetProperty("transferLoggingVerbose", transferLoggingVerbose);
            return this;
        }
        /**
         * Account to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder account(String account) {
            doSetProperty("account", account);
            return this;
        }
        /**
         * Use this option to disable default options when using secure data
         * channel. This allows you to be in full control what the execPbsz and
         * execProt setting should be used. Default is false.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder disableSecureDataChannelDefaults(
                boolean disableSecureDataChannelDefaults) {
            doSetProperty("disableSecureDataChannelDefaults", disableSecureDataChannelDefaults);
            return this;
        }
        /**
         * Use this option to disable default options when using secure data
         * channel. This allows you to be in full control what the execPbsz and
         * execProt setting should be used. Default is false.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder disableSecureDataChannelDefaults(
                String disableSecureDataChannelDefaults) {
            doSetProperty("disableSecureDataChannelDefaults", disableSecureDataChannelDefaults);
            return this;
        }
        /**
         * When using secure data channel you can set the exec protection buffer
         * size.
         * 
         * The option is a: <code>java.lang.Long</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder execPbsz(Long execPbsz) {
            doSetProperty("execPbsz", execPbsz);
            return this;
        }
        /**
         * When using secure data channel you can set the exec protection buffer
         * size.
         * 
         * The option will be converted to a <code>java.lang.Long</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder execPbsz(String execPbsz) {
            doSetProperty("execPbsz", execPbsz);
            return this;
        }
        /**
         * The exec protection level PROT command. C - Clear S - Safe(SSL
         * protocol only) E - Confidential(SSL protocol only) P - Private.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder execProt(String execProt) {
            doSetProperty("execProt", execProt);
            return this;
        }
        /**
         * Set the key store parameters.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder ftpClientKeyStoreParameters(
                Map<String, Object> ftpClientKeyStoreParameters) {
            doSetProperty("ftpClientKeyStoreParameters", ftpClientKeyStoreParameters);
            return this;
        }
        /**
         * Set the key store parameters.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder ftpClientKeyStoreParameters(
                String ftpClientKeyStoreParameters) {
            doSetProperty("ftpClientKeyStoreParameters", ftpClientKeyStoreParameters);
            return this;
        }
        /**
         * Set the trust store parameters.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder ftpClientTrustStoreParameters(
                Map<String, Object> ftpClientTrustStoreParameters) {
            doSetProperty("ftpClientTrustStoreParameters", ftpClientTrustStoreParameters);
            return this;
        }
        /**
         * Set the trust store parameters.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder ftpClientTrustStoreParameters(
                String ftpClientTrustStoreParameters) {
            doSetProperty("ftpClientTrustStoreParameters", ftpClientTrustStoreParameters);
            return this;
        }
        /**
         * Set the security mode (Implicit/Explicit). true - Implicit Mode /
         * False - Explicit Mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder implicit(boolean implicit) {
            doSetProperty("implicit", implicit);
            return this;
        }
        /**
         * Set the security mode (Implicit/Explicit). true - Implicit Mode /
         * False - Explicit Mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder implicit(String implicit) {
            doSetProperty("implicit", implicit);
            return this;
        }
        /**
         * Password to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the underlying security protocol.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder securityProtocol(String securityProtocol) {
            doSetProperty("securityProtocol", securityProtocol);
            return this;
        }
        /**
         * Gets the JSSE configuration that overrides any settings in
         * FtpsEndpoint#ftpClientKeyStoreParameters,
         * ftpClientTrustStoreParameters, and
         * FtpsConfiguration#getSecurityProtocol().
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * Gets the JSSE configuration that overrides any settings in
         * FtpsEndpoint#ftpClientKeyStoreParameters,
         * ftpClientTrustStoreParameters, and
         * FtpsConfiguration#getSecurityProtocol().
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * Username to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default FtpsEndpointBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the FTPS component.
     */
    public interface AdvancedFtpsEndpointBuilder
            extends
                AdvancedFtpsEndpointConsumerBuilder, AdvancedFtpsEndpointProducerBuilder {
        default FtpsEndpointBuilder basic() {
            return (FtpsEndpointBuilder) this;
        }
        /**
         * If set this option to be true, camel-ftp will use the list file
         * directly to check if the file exists. Since some FTP server may not
         * support to list the file directly, if the option is false, camel-ftp
         * will use the old way to list the directory and check if the file
         * exists. This option also influences readLock=changed to control
         * whether it performs a fast check to update file information or not.
         * This can be used to speed up the process if the FTP server has a lot
         * of files.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common (advanced)
         */
        default AdvancedFtpsEndpointBuilder fastExistsCheck(
                boolean fastExistsCheck) {
            doSetProperty("fastExistsCheck", fastExistsCheck);
            return this;
        }
        /**
         * If set this option to be true, camel-ftp will use the list file
         * directly to check if the file exists. Since some FTP server may not
         * support to list the file directly, if the option is false, camel-ftp
         * will use the old way to list the directory and check if the file
         * exists. This option also influences readLock=changed to control
         * whether it performs a fast check to update file information or not.
         * This can be used to speed up the process if the FTP server has a lot
         * of files.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common (advanced)
         */
        default AdvancedFtpsEndpointBuilder fastExistsCheck(
                String fastExistsCheck) {
            doSetProperty("fastExistsCheck", fastExistsCheck);
            return this;
        }
        /**
         * Set the client side port range in active mode. The syntax is:
         * minPort-maxPort Both port numbers are inclusive, eg 10000-19999 to
         * include all 1xxxx ports.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder activePortRange(
                String activePortRange) {
            doSetProperty("activePortRange", activePortRange);
            return this;
        }
        /**
         * Automatically create missing directories in the file's pathname. For
         * the file consumer, that means creating the starting directory. For
         * the file producer, it means the directory the files should be written
         * to.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder autoCreate(boolean autoCreate) {
            doSetProperty("autoCreate", autoCreate);
            return this;
        }
        /**
         * Automatically create missing directories in the file's pathname. For
         * the file consumer, that means creating the starting directory. For
         * the file producer, it means the directory the files should be written
         * to.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder autoCreate(String autoCreate) {
            doSetProperty("autoCreate", autoCreate);
            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 AdvancedFtpsEndpointBuilder 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 AdvancedFtpsEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder bufferSize(int bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder bufferSize(String bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Sets the connect timeout for waiting for a connection to be
         * established Used by both FTPClient and JSCH.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder connectTimeout(int connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            return this;
        }
        /**
         * Sets the connect timeout for waiting for a connection to be
         * established Used by both FTPClient and JSCH.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder connectTimeout(String connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            return this;
        }
        /**
         * To use a custom instance of FTPClient.
         * 
         * The option is a: <code>org.apache.commons.net.ftp.FTPClient</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder ftpClient(Object ftpClient) {
            doSetProperty("ftpClient", ftpClient);
            return this;
        }
        /**
         * To use a custom instance of FTPClient.
         * 
         * The option will be converted to a
         * <code>org.apache.commons.net.ftp.FTPClient</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder ftpClient(String ftpClient) {
            doSetProperty("ftpClient", ftpClient);
            return this;
        }
        /**
         * To use a custom instance of FTPClientConfig to configure the FTP
         * client the endpoint should use.
         * 
         * The option is a:
         * <code>org.apache.commons.net.ftp.FTPClientConfig</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder ftpClientConfig(
                Object ftpClientConfig) {
            doSetProperty("ftpClientConfig", ftpClientConfig);
            return this;
        }
        /**
         * To use a custom instance of FTPClientConfig to configure the FTP
         * client the endpoint should use.
         * 
         * The option will be converted to a
         * <code>org.apache.commons.net.ftp.FTPClientConfig</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder ftpClientConfig(
                String ftpClientConfig) {
            doSetProperty("ftpClientConfig", ftpClientConfig);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClientConfig.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder ftpClientConfigParameters(
                Map<String, Object> ftpClientConfigParameters) {
            doSetProperty("ftpClientConfigParameters", ftpClientConfigParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClientConfig.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder ftpClientConfigParameters(
                String ftpClientConfigParameters) {
            doSetProperty("ftpClientConfigParameters", ftpClientConfigParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClient.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder ftpClientParameters(
                Map<String, Object> ftpClientParameters) {
            doSetProperty("ftpClientParameters", ftpClientParameters);
            return this;
        }
        /**
         * Used by FtpComponent to provide additional parameters for the
         * FTPClient.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder ftpClientParameters(
                String ftpClientParameters) {
            doSetProperty("ftpClientParameters", ftpClientParameters);
            return this;
        }
        /**
         * Specifies the maximum reconnect attempts Camel performs when it tries
         * to connect to the remote FTP server. Use 0 to disable this behavior.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder maximumReconnectAttempts(
                int maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * Specifies the maximum reconnect attempts Camel performs when it tries
         * to connect to the remote FTP server. Use 0 to disable this behavior.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder maximumReconnectAttempts(
                String maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder reconnectDelay(long reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder reconnectDelay(String reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Sets optional site command(s) to be executed after successful login.
         * Multiple site commands can be separated using a new line character.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder siteCommand(String siteCommand) {
            doSetProperty("siteCommand", siteCommand);
            return this;
        }
        /**
         * Sets the so timeout FTP and FTPS Only for Camel 2.4. SFTP for Camel
         * 2.14.3/2.15.3/2.16 onwards. Is the SocketOptions.SO_TIMEOUT value in
         * millis. Recommended option is to set this to 300000 so as not have a
         * hanged connection. On SFTP this option is set as timeout on the JSCH
         * Session instance.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder soTimeout(int soTimeout) {
            doSetProperty("soTimeout", soTimeout);
            return this;
        }
        /**
         * Sets the so timeout FTP and FTPS Only for Camel 2.4. SFTP for Camel
         * 2.14.3/2.15.3/2.16 onwards. Is the SocketOptions.SO_TIMEOUT value in
         * millis. Recommended option is to set this to 300000 so as not have a
         * hanged connection. On SFTP this option is set as timeout on the JSCH
         * Session instance.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder soTimeout(String soTimeout) {
            doSetProperty("soTimeout", soTimeout);
            return this;
        }
        /**
         * Sets whether we should stepwise change directories while traversing
         * file structures when downloading files, or as well when uploading a
         * file to a directory. You can disable this if you for example are in a
         * situation where you cannot change directory on the FTP server due
         * security reasons.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder stepwise(boolean stepwise) {
            doSetProperty("stepwise", stepwise);
            return this;
        }
        /**
         * Sets whether we should stepwise change directories while traversing
         * file structures when downloading files, or as well when uploading a
         * file to a directory. You can disable this if you for example are in a
         * situation where you cannot change directory on the FTP server due
         * security reasons.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder stepwise(String stepwise) {
            doSetProperty("stepwise", stepwise);
            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 AdvancedFtpsEndpointBuilder 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 AdvancedFtpsEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Should an exception be thrown if connection failed (exhausted) By
         * default exception is not thrown and a WARN is logged. You can use
         * this to enable exception being thrown and handle the thrown exception
         * from the org.apache.camel.spi.PollingConsumerPollStrategy rollback
         * method.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder throwExceptionOnConnectFailed(
                boolean throwExceptionOnConnectFailed) {
            doSetProperty("throwExceptionOnConnectFailed", throwExceptionOnConnectFailed);
            return this;
        }
        /**
         * Should an exception be thrown if connection failed (exhausted) By
         * default exception is not thrown and a WARN is logged. You can use
         * this to enable exception being thrown and handle the thrown exception
         * from the org.apache.camel.spi.PollingConsumerPollStrategy rollback
         * method.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder throwExceptionOnConnectFailed(
                String throwExceptionOnConnectFailed) {
            doSetProperty("throwExceptionOnConnectFailed", throwExceptionOnConnectFailed);
            return this;
        }
        /**
         * Sets the data timeout for waiting for reply Used only by FTPClient.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder timeout(int timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * Sets the data timeout for waiting for reply Used only by FTPClient.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFtpsEndpointBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.file.remote.RemoteFileConfiguration$PathSeparator</code> enum.
     */
    enum PathSeparator {
        UNIX,
        Windows,
        Auto;
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.file.GenericFileExist</code> enum.
     */
    enum GenericFileExist {
        Override,
        Append,
        Fail,
        Ignore,
        Move,
        TryRename;
    }
    /**
     * FTPS (camel-ftp)
     * The ftps (FTP secure SSL/TLS) component is used for uploading or
     * downloading files from FTP servers.
     * 
     * Category: file
     * Since: 2.2
     * Maven coordinates: org.apache.camel:camel-ftp
     * 
     * Syntax: <code>ftps:host:port/directoryName</code>
     * 
     * Path parameter: host (required)
     * Hostname of the FTP server
     * 
     * Path parameter: port
     * Port of the FTP server
     * 
     * Path parameter: directoryName
     * The starting directory
     */
    default FtpsEndpointBuilder ftps(String path) {
        class FtpsEndpointBuilderImpl extends AbstractEndpointBuilder implements FtpsEndpointBuilder, AdvancedFtpsEndpointBuilder {
            public FtpsEndpointBuilderImpl(String path) {
                super("ftps", path);
            }
        }
        return new FtpsEndpointBuilderImpl(path);
    }
}