/*
 * 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.security.KeyPair;
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 sftp (FTP over SSH) component is used for uploading or downloading files
 * from SFTP servers.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface SftpEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the SFTP component.
     */
    public interface SftpEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedSftpEndpointConsumerBuilder advanced() {
            return (AdvancedSftpEndpointConsumerBuilder) 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * The logging level to use for JSCH activity logging. As JSCH is
         * verbose at by default at INFO level the threshold is WARN by default.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default SftpEndpointConsumerBuilder jschLoggingLevel(
                LoggingLevel jschLoggingLevel) {
            doSetProperty("jschLoggingLevel", jschLoggingLevel);
            return this;
        }
        /**
         * The logging level to use for JSCH activity logging. As JSCH is
         * verbose at by default at INFO level the threshold is WARN by default.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default SftpEndpointConsumerBuilder jschLoggingLevel(
                String jschLoggingLevel) {
            doSetProperty("jschLoggingLevel", jschLoggingLevel);
            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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder separator(String separator) {
            doSetProperty("separator", separator);
            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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder recursive(String recursive) {
            doSetProperty("recursive", recursive);
            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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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.camel.component.file.remote.SftpRemoteFile&gt;</code> type.
         * 
         * Group: filter
         */
        default SftpEndpointConsumerBuilder 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.camel.component.file.remote.SftpRemoteFile&gt;</code> type.
         * 
         * Group: filter
         */
        default SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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.camel.component.file.remote.SftpRemoteFile&gt;</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder 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.camel.component.file.remote.SftpRemoteFile&gt;</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder readLockDeleteOrphanLockFiles(
                String readLockDeleteOrphanLockFiles) {
            doSetProperty("readLockDeleteOrphanLockFiles", readLockDeleteOrphanLockFiles);
            return this;
        }
        /**
         * Whether the delayed release task should be synchronous or
         * asynchronous. See more details at the readLockIdempotentReleaseDelay
         * option.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder readLockIdempotentReleaseAsync(
                boolean readLockIdempotentReleaseAsync) {
            doSetProperty("readLockIdempotentReleaseAsync", readLockIdempotentReleaseAsync);
            return this;
        }
        /**
         * Whether the delayed release task should be synchronous or
         * asynchronous. See more details at the readLockIdempotentReleaseDelay
         * option.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder readLockIdempotentReleaseAsync(
                String readLockIdempotentReleaseAsync) {
            doSetProperty("readLockIdempotentReleaseAsync", readLockIdempotentReleaseAsync);
            return this;
        }
        /**
         * The number of threads in the scheduled thread pool when using
         * asynchronous release tasks. Using a default of 1 core threads should
         * be sufficient in almost all use-cases, only set this to a higher
         * value if either updating the idempotent repository is slow, or there
         * are a lot of files to process. This option is not in-use if you use a
         * shared thread pool by configuring the
         * readLockIdempotentReleaseExecutorService option. See more details at
         * the readLockIdempotentReleaseDelay option.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder readLockIdempotentReleaseAsyncPoolSize(
                int readLockIdempotentReleaseAsyncPoolSize) {
            doSetProperty("readLockIdempotentReleaseAsyncPoolSize", readLockIdempotentReleaseAsyncPoolSize);
            return this;
        }
        /**
         * The number of threads in the scheduled thread pool when using
         * asynchronous release tasks. Using a default of 1 core threads should
         * be sufficient in almost all use-cases, only set this to a higher
         * value if either updating the idempotent repository is slow, or there
         * are a lot of files to process. This option is not in-use if you use a
         * shared thread pool by configuring the
         * readLockIdempotentReleaseExecutorService option. See more details at
         * the readLockIdempotentReleaseDelay option.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder readLockIdempotentReleaseAsyncPoolSize(
                String readLockIdempotentReleaseAsyncPoolSize) {
            doSetProperty("readLockIdempotentReleaseAsyncPoolSize", readLockIdempotentReleaseAsyncPoolSize);
            return this;
        }
        /**
         * Whether to delay the release task for a period of millis. This can be
         * used to delay the release tasks to expand the window when a file is
         * regarded as read-locked, in an active/active cluster scenario with a
         * shared idempotent repository, to ensure other nodes cannot
         * potentially scan and acquire the same file, due to race-conditions.
         * By expanding the time-window of the release tasks helps prevents
         * these situations. Note delaying is only needed if you have configured
         * readLockRemoveOnCommit to true.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder readLockIdempotentReleaseDelay(
                int readLockIdempotentReleaseDelay) {
            doSetProperty("readLockIdempotentReleaseDelay", readLockIdempotentReleaseDelay);
            return this;
        }
        /**
         * Whether to delay the release task for a period of millis. This can be
         * used to delay the release tasks to expand the window when a file is
         * regarded as read-locked, in an active/active cluster scenario with a
         * shared idempotent repository, to ensure other nodes cannot
         * potentially scan and acquire the same file, due to race-conditions.
         * By expanding the time-window of the release tasks helps prevents
         * these situations. Note delaying is only needed if you have configured
         * readLockRemoveOnCommit to true.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder readLockIdempotentReleaseDelay(
                String readLockIdempotentReleaseDelay) {
            doSetProperty("readLockIdempotentReleaseDelay", readLockIdempotentReleaseDelay);
            return this;
        }
        /**
         * To use a custom and shared thread pool for asynchronous release
         * tasks. See more details at the readLockIdempotentReleaseDelay option.
         * 
         * The option is a:
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder readLockIdempotentReleaseExecutorService(
                ScheduledExecutorService readLockIdempotentReleaseExecutorService) {
            doSetProperty("readLockIdempotentReleaseExecutorService", readLockIdempotentReleaseExecutorService);
            return this;
        }
        /**
         * To use a custom and shared thread pool for asynchronous release
         * tasks. See more details at the readLockIdempotentReleaseDelay option.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: lock
         */
        default SftpEndpointConsumerBuilder readLockIdempotentReleaseExecutorService(
                String readLockIdempotentReleaseExecutorService) {
            doSetProperty("readLockIdempotentReleaseExecutorService", readLockIdempotentReleaseExecutorService);
            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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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 SftpEndpointConsumerBuilder 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.camel.component.file.remote.SftpRemoteFile&gt;&gt;</code> type.
         * 
         * Group: sort
         */
        default SftpEndpointConsumerBuilder 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.camel.component.file.remote.SftpRemoteFile&gt;&gt;</code> type.
         * 
         * Group: sort
         */
        default SftpEndpointConsumerBuilder sorter(String sorter) {
            doSetProperty("sorter", sorter);
            return this;
        }
        /**
         * Set a comma separated list of ciphers that will be used in order of
         * preference. Possible cipher names are defined by JCraft JSCH. Some
         * examples include:
         * aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc. If not specified the default list from JSCH will be used.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder ciphers(String ciphers) {
            doSetProperty("ciphers", ciphers);
            return this;
        }
        /**
         * Sets a key pair of the public and private key so to that the SFTP
         * endpoint can do public/private key verification.
         * 
         * The option is a: <code>java.security.KeyPair</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder keyPair(KeyPair keyPair) {
            doSetProperty("keyPair", keyPair);
            return this;
        }
        /**
         * Sets a key pair of the public and private key so to that the SFTP
         * endpoint can do public/private key verification.
         * 
         * The option will be converted to a <code>java.security.KeyPair</code>
         * type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder keyPair(String keyPair) {
            doSetProperty("keyPair", keyPair);
            return this;
        }
        /**
         * Sets the known_hosts from the byte array, so that the SFTP endpoint
         * can do host key verification.
         * 
         * The option is a: <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder knownHosts(Byte[] knownHosts) {
            doSetProperty("knownHosts", knownHosts);
            return this;
        }
        /**
         * Sets the known_hosts from the byte array, so that the SFTP endpoint
         * can do host key verification.
         * 
         * The option will be converted to a <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder knownHosts(String knownHosts) {
            doSetProperty("knownHosts", knownHosts);
            return this;
        }
        /**
         * Sets the known_hosts file, so that the SFTP endpoint can do host key
         * verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder knownHostsFile(String knownHostsFile) {
            doSetProperty("knownHostsFile", knownHostsFile);
            return this;
        }
        /**
         * Sets the known_hosts file (loaded from classpath by default), so that
         * the SFTP endpoint can do host key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder knownHostsUri(String knownHostsUri) {
            doSetProperty("knownHostsUri", knownHostsUri);
            return this;
        }
        /**
         * Password to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the preferred authentications which SFTP endpoint will used. Some
         * example include:password,publickey. If not specified the default list
         * from JSCH will be used.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder preferredAuthentications(
                String preferredAuthentications) {
            doSetProperty("preferredAuthentications", preferredAuthentications);
            return this;
        }
        /**
         * Set the private key as byte so that the SFTP endpoint can do private
         * key verification.
         * 
         * The option is a: <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder privateKey(Byte[] privateKey) {
            doSetProperty("privateKey", privateKey);
            return this;
        }
        /**
         * Set the private key as byte so that the SFTP endpoint can do private
         * key verification.
         * 
         * The option will be converted to a <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder privateKey(String privateKey) {
            doSetProperty("privateKey", privateKey);
            return this;
        }
        /**
         * Set the private key file so that the SFTP endpoint can do private key
         * verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder privateKeyFile(String privateKeyFile) {
            doSetProperty("privateKeyFile", privateKeyFile);
            return this;
        }
        /**
         * Set the private key file passphrase so that the SFTP endpoint can do
         * private key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder privateKeyPassphrase(
                String privateKeyPassphrase) {
            doSetProperty("privateKeyPassphrase", privateKeyPassphrase);
            return this;
        }
        /**
         * Set the private key file (loaded from classpath by default) so that
         * the SFTP endpoint can do private key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder privateKeyUri(String privateKeyUri) {
            doSetProperty("privateKeyUri", privateKeyUri);
            return this;
        }
        /**
         * Sets whether to use strict host key checking.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder strictHostKeyChecking(
                String strictHostKeyChecking) {
            doSetProperty("strictHostKeyChecking", strictHostKeyChecking);
            return this;
        }
        /**
         * Username to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * If knownHostFile has not been explicit configured then use the host
         * file from System.getProperty(user.home)/.ssh/known_hosts.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder useUserKnownHostsFile(
                boolean useUserKnownHostsFile) {
            doSetProperty("useUserKnownHostsFile", useUserKnownHostsFile);
            return this;
        }
        /**
         * If knownHostFile has not been explicit configured then use the host
         * file from System.getProperty(user.home)/.ssh/known_hosts.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default SftpEndpointConsumerBuilder useUserKnownHostsFile(
                String useUserKnownHostsFile) {
            doSetProperty("useUserKnownHostsFile", useUserKnownHostsFile);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the SFTP component.
     */
    public interface AdvancedSftpEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default SftpEndpointConsumerBuilder basic() {
            return (SftpEndpointConsumerBuilder) 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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.camel.component.file.remote.SftpRemoteFile&gt;</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSftpEndpointConsumerBuilder 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.camel.component.file.remote.SftpRemoteFile&gt;</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder useList(String useList) {
            doSetProperty("useList", useList);
            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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Specifies the address of the local interface against which the
         * connection should bind.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder bindAddress(
                String bindAddress) {
            doSetProperty("bindAddress", bindAddress);
            return this;
        }
        /**
         * Specifies how many requests may be outstanding at any one time.
         * Increasing this value may slightly improve file transfer speed but
         * will increase memory usage.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder bulkRequests(
                Integer bulkRequests) {
            doSetProperty("bulkRequests", bulkRequests);
            return this;
        }
        /**
         * Specifies how many requests may be outstanding at any one time.
         * Increasing this value may slightly improve file transfer speed but
         * will increase memory usage.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder bulkRequests(
                String bulkRequests) {
            doSetProperty("bulkRequests", bulkRequests);
            return this;
        }
        /**
         * To use compression. Specify a level from 1 to 10. Important: You must
         * manually add the needed JSCH zlib JAR to the classpath for
         * compression support.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder compression(int compression) {
            doSetProperty("compression", compression);
            return this;
        }
        /**
         * To use compression. Specify a level from 1 to 10. Important: You must
         * manually add the needed JSCH zlib JAR to the classpath for
         * compression support.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder compression(
                String compression) {
            doSetProperty("compression", compression);
            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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder connectTimeout(
                String connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder maximumReconnectAttempts(
                String maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * To use a custom configured com.jcraft.jsch.Proxy. This proxy is used
         * to consume/send messages from the target SFTP host.
         * 
         * The option is a: <code>com.jcraft.jsch.Proxy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder proxy(Object proxy) {
            doSetProperty("proxy", proxy);
            return this;
        }
        /**
         * To use a custom configured com.jcraft.jsch.Proxy. This proxy is used
         * to consume/send messages from the target SFTP host.
         * 
         * The option will be converted to a <code>com.jcraft.jsch.Proxy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder proxy(String proxy) {
            doSetProperty("proxy", proxy);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder reconnectDelay(
                String reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Allows you to set the serverAliveCountMax of the sftp session.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder serverAliveCountMax(
                int serverAliveCountMax) {
            doSetProperty("serverAliveCountMax", serverAliveCountMax);
            return this;
        }
        /**
         * Allows you to set the serverAliveCountMax of the sftp session.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder serverAliveCountMax(
                String serverAliveCountMax) {
            doSetProperty("serverAliveCountMax", serverAliveCountMax);
            return this;
        }
        /**
         * Allows you to set the serverAliveInterval of the sftp session.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder serverAliveInterval(
                int serverAliveInterval) {
            doSetProperty("serverAliveInterval", serverAliveInterval);
            return this;
        }
        /**
         * Allows you to set the serverAliveInterval of the sftp session.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointConsumerBuilder serverAliveInterval(
                String serverAliveInterval) {
            doSetProperty("serverAliveInterval", serverAliveInterval);
            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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder 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 AdvancedSftpEndpointConsumerBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the SFTP component.
     */
    public interface SftpEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedSftpEndpointProducerBuilder advanced() {
            return (AdvancedSftpEndpointProducerBuilder) 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * The logging level to use for JSCH activity logging. As JSCH is
         * verbose at by default at INFO level the threshold is WARN by default.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default SftpEndpointProducerBuilder jschLoggingLevel(
                LoggingLevel jschLoggingLevel) {
            doSetProperty("jschLoggingLevel", jschLoggingLevel);
            return this;
        }
        /**
         * The logging level to use for JSCH activity logging. As JSCH is
         * verbose at by default at INFO level the threshold is WARN by default.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default SftpEndpointProducerBuilder jschLoggingLevel(
                String jschLoggingLevel) {
            doSetProperty("jschLoggingLevel", jschLoggingLevel);
            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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder separator(String separator) {
            doSetProperty("separator", separator);
            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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder 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 SftpEndpointProducerBuilder tempPrefix(String tempPrefix) {
            doSetProperty("tempPrefix", tempPrefix);
            return this;
        }
        /**
         * Set a comma separated list of ciphers that will be used in order of
         * preference. Possible cipher names are defined by JCraft JSCH. Some
         * examples include:
         * aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc. If not specified the default list from JSCH will be used.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder ciphers(String ciphers) {
            doSetProperty("ciphers", ciphers);
            return this;
        }
        /**
         * Sets a key pair of the public and private key so to that the SFTP
         * endpoint can do public/private key verification.
         * 
         * The option is a: <code>java.security.KeyPair</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder keyPair(KeyPair keyPair) {
            doSetProperty("keyPair", keyPair);
            return this;
        }
        /**
         * Sets a key pair of the public and private key so to that the SFTP
         * endpoint can do public/private key verification.
         * 
         * The option will be converted to a <code>java.security.KeyPair</code>
         * type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder keyPair(String keyPair) {
            doSetProperty("keyPair", keyPair);
            return this;
        }
        /**
         * Sets the known_hosts from the byte array, so that the SFTP endpoint
         * can do host key verification.
         * 
         * The option is a: <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder knownHosts(Byte[] knownHosts) {
            doSetProperty("knownHosts", knownHosts);
            return this;
        }
        /**
         * Sets the known_hosts from the byte array, so that the SFTP endpoint
         * can do host key verification.
         * 
         * The option will be converted to a <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder knownHosts(String knownHosts) {
            doSetProperty("knownHosts", knownHosts);
            return this;
        }
        /**
         * Sets the known_hosts file, so that the SFTP endpoint can do host key
         * verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder knownHostsFile(String knownHostsFile) {
            doSetProperty("knownHostsFile", knownHostsFile);
            return this;
        }
        /**
         * Sets the known_hosts file (loaded from classpath by default), so that
         * the SFTP endpoint can do host key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder knownHostsUri(String knownHostsUri) {
            doSetProperty("knownHostsUri", knownHostsUri);
            return this;
        }
        /**
         * Password to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the preferred authentications which SFTP endpoint will used. Some
         * example include:password,publickey. If not specified the default list
         * from JSCH will be used.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder preferredAuthentications(
                String preferredAuthentications) {
            doSetProperty("preferredAuthentications", preferredAuthentications);
            return this;
        }
        /**
         * Set the private key as byte so that the SFTP endpoint can do private
         * key verification.
         * 
         * The option is a: <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder privateKey(Byte[] privateKey) {
            doSetProperty("privateKey", privateKey);
            return this;
        }
        /**
         * Set the private key as byte so that the SFTP endpoint can do private
         * key verification.
         * 
         * The option will be converted to a <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder privateKey(String privateKey) {
            doSetProperty("privateKey", privateKey);
            return this;
        }
        /**
         * Set the private key file so that the SFTP endpoint can do private key
         * verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder privateKeyFile(String privateKeyFile) {
            doSetProperty("privateKeyFile", privateKeyFile);
            return this;
        }
        /**
         * Set the private key file passphrase so that the SFTP endpoint can do
         * private key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder privateKeyPassphrase(
                String privateKeyPassphrase) {
            doSetProperty("privateKeyPassphrase", privateKeyPassphrase);
            return this;
        }
        /**
         * Set the private key file (loaded from classpath by default) so that
         * the SFTP endpoint can do private key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder privateKeyUri(String privateKeyUri) {
            doSetProperty("privateKeyUri", privateKeyUri);
            return this;
        }
        /**
         * Sets whether to use strict host key checking.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder strictHostKeyChecking(
                String strictHostKeyChecking) {
            doSetProperty("strictHostKeyChecking", strictHostKeyChecking);
            return this;
        }
        /**
         * Username to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * If knownHostFile has not been explicit configured then use the host
         * file from System.getProperty(user.home)/.ssh/known_hosts.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder useUserKnownHostsFile(
                boolean useUserKnownHostsFile) {
            doSetProperty("useUserKnownHostsFile", useUserKnownHostsFile);
            return this;
        }
        /**
         * If knownHostFile has not been explicit configured then use the host
         * file from System.getProperty(user.home)/.ssh/known_hosts.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default SftpEndpointProducerBuilder useUserKnownHostsFile(
                String useUserKnownHostsFile) {
            doSetProperty("useUserKnownHostsFile", useUserKnownHostsFile);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the SFTP component.
     */
    public interface AdvancedSftpEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default SftpEndpointProducerBuilder basic() {
            return (SftpEndpointProducerBuilder) 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder sendNoop(String sendNoop) {
            doSetProperty("sendNoop", sendNoop);
            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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Specifies the address of the local interface against which the
         * connection should bind.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder bindAddress(
                String bindAddress) {
            doSetProperty("bindAddress", bindAddress);
            return this;
        }
        /**
         * Specifies how many requests may be outstanding at any one time.
         * Increasing this value may slightly improve file transfer speed but
         * will increase memory usage.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder bulkRequests(
                Integer bulkRequests) {
            doSetProperty("bulkRequests", bulkRequests);
            return this;
        }
        /**
         * Specifies how many requests may be outstanding at any one time.
         * Increasing this value may slightly improve file transfer speed but
         * will increase memory usage.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder bulkRequests(
                String bulkRequests) {
            doSetProperty("bulkRequests", bulkRequests);
            return this;
        }
        /**
         * To use compression. Specify a level from 1 to 10. Important: You must
         * manually add the needed JSCH zlib JAR to the classpath for
         * compression support.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder compression(int compression) {
            doSetProperty("compression", compression);
            return this;
        }
        /**
         * To use compression. Specify a level from 1 to 10. Important: You must
         * manually add the needed JSCH zlib JAR to the classpath for
         * compression support.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder compression(
                String compression) {
            doSetProperty("compression", compression);
            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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder connectTimeout(
                String connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder maximumReconnectAttempts(
                String maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * To use a custom configured com.jcraft.jsch.Proxy. This proxy is used
         * to consume/send messages from the target SFTP host.
         * 
         * The option is a: <code>com.jcraft.jsch.Proxy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder proxy(Object proxy) {
            doSetProperty("proxy", proxy);
            return this;
        }
        /**
         * To use a custom configured com.jcraft.jsch.Proxy. This proxy is used
         * to consume/send messages from the target SFTP host.
         * 
         * The option will be converted to a <code>com.jcraft.jsch.Proxy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder proxy(String proxy) {
            doSetProperty("proxy", proxy);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder reconnectDelay(
                String reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Allows you to set the serverAliveCountMax of the sftp session.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder serverAliveCountMax(
                int serverAliveCountMax) {
            doSetProperty("serverAliveCountMax", serverAliveCountMax);
            return this;
        }
        /**
         * Allows you to set the serverAliveCountMax of the sftp session.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder serverAliveCountMax(
                String serverAliveCountMax) {
            doSetProperty("serverAliveCountMax", serverAliveCountMax);
            return this;
        }
        /**
         * Allows you to set the serverAliveInterval of the sftp session.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder serverAliveInterval(
                int serverAliveInterval) {
            doSetProperty("serverAliveInterval", serverAliveInterval);
            return this;
        }
        /**
         * Allows you to set the serverAliveInterval of the sftp session.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointProducerBuilder serverAliveInterval(
                String serverAliveInterval) {
            doSetProperty("serverAliveInterval", serverAliveInterval);
            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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder 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 AdvancedSftpEndpointProducerBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
    }

    /**
     * Builder for endpoint for the SFTP component.
     */
    public interface SftpEndpointBuilder
            extends
                SftpEndpointConsumerBuilder, SftpEndpointProducerBuilder {
        default AdvancedSftpEndpointBuilder advanced() {
            return (AdvancedSftpEndpointBuilder) 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 SftpEndpointBuilder 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 SftpEndpointBuilder 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 SftpEndpointBuilder 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 SftpEndpointBuilder 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 SftpEndpointBuilder 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 SftpEndpointBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * The logging level to use for JSCH activity logging. As JSCH is
         * verbose at by default at INFO level the threshold is WARN by default.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default SftpEndpointBuilder jschLoggingLevel(
                LoggingLevel jschLoggingLevel) {
            doSetProperty("jschLoggingLevel", jschLoggingLevel);
            return this;
        }
        /**
         * The logging level to use for JSCH activity logging. As JSCH is
         * verbose at by default at INFO level the threshold is WARN by default.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: common
         */
        default SftpEndpointBuilder jschLoggingLevel(String jschLoggingLevel) {
            doSetProperty("jschLoggingLevel", jschLoggingLevel);
            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 SftpEndpointBuilder 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 SftpEndpointBuilder separator(String separator) {
            doSetProperty("separator", separator);
            return this;
        }
        /**
         * Set a comma separated list of ciphers that will be used in order of
         * preference. Possible cipher names are defined by JCraft JSCH. Some
         * examples include:
         * aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc. If not specified the default list from JSCH will be used.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder ciphers(String ciphers) {
            doSetProperty("ciphers", ciphers);
            return this;
        }
        /**
         * Sets a key pair of the public and private key so to that the SFTP
         * endpoint can do public/private key verification.
         * 
         * The option is a: <code>java.security.KeyPair</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder keyPair(KeyPair keyPair) {
            doSetProperty("keyPair", keyPair);
            return this;
        }
        /**
         * Sets a key pair of the public and private key so to that the SFTP
         * endpoint can do public/private key verification.
         * 
         * The option will be converted to a <code>java.security.KeyPair</code>
         * type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder keyPair(String keyPair) {
            doSetProperty("keyPair", keyPair);
            return this;
        }
        /**
         * Sets the known_hosts from the byte array, so that the SFTP endpoint
         * can do host key verification.
         * 
         * The option is a: <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder knownHosts(Byte[] knownHosts) {
            doSetProperty("knownHosts", knownHosts);
            return this;
        }
        /**
         * Sets the known_hosts from the byte array, so that the SFTP endpoint
         * can do host key verification.
         * 
         * The option will be converted to a <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder knownHosts(String knownHosts) {
            doSetProperty("knownHosts", knownHosts);
            return this;
        }
        /**
         * Sets the known_hosts file, so that the SFTP endpoint can do host key
         * verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder knownHostsFile(String knownHostsFile) {
            doSetProperty("knownHostsFile", knownHostsFile);
            return this;
        }
        /**
         * Sets the known_hosts file (loaded from classpath by default), so that
         * the SFTP endpoint can do host key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder knownHostsUri(String knownHostsUri) {
            doSetProperty("knownHostsUri", knownHostsUri);
            return this;
        }
        /**
         * Password to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the preferred authentications which SFTP endpoint will used. Some
         * example include:password,publickey. If not specified the default list
         * from JSCH will be used.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder preferredAuthentications(
                String preferredAuthentications) {
            doSetProperty("preferredAuthentications", preferredAuthentications);
            return this;
        }
        /**
         * Set the private key as byte so that the SFTP endpoint can do private
         * key verification.
         * 
         * The option is a: <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder privateKey(Byte[] privateKey) {
            doSetProperty("privateKey", privateKey);
            return this;
        }
        /**
         * Set the private key as byte so that the SFTP endpoint can do private
         * key verification.
         * 
         * The option will be converted to a <code>byte[]</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder privateKey(String privateKey) {
            doSetProperty("privateKey", privateKey);
            return this;
        }
        /**
         * Set the private key file so that the SFTP endpoint can do private key
         * verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder privateKeyFile(String privateKeyFile) {
            doSetProperty("privateKeyFile", privateKeyFile);
            return this;
        }
        /**
         * Set the private key file passphrase so that the SFTP endpoint can do
         * private key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder privateKeyPassphrase(
                String privateKeyPassphrase) {
            doSetProperty("privateKeyPassphrase", privateKeyPassphrase);
            return this;
        }
        /**
         * Set the private key file (loaded from classpath by default) so that
         * the SFTP endpoint can do private key verification.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder privateKeyUri(String privateKeyUri) {
            doSetProperty("privateKeyUri", privateKeyUri);
            return this;
        }
        /**
         * Sets whether to use strict host key checking.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder strictHostKeyChecking(
                String strictHostKeyChecking) {
            doSetProperty("strictHostKeyChecking", strictHostKeyChecking);
            return this;
        }
        /**
         * Username to use for login.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * If knownHostFile has not been explicit configured then use the host
         * file from System.getProperty(user.home)/.ssh/known_hosts.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder useUserKnownHostsFile(
                boolean useUserKnownHostsFile) {
            doSetProperty("useUserKnownHostsFile", useUserKnownHostsFile);
            return this;
        }
        /**
         * If knownHostFile has not been explicit configured then use the host
         * file from System.getProperty(user.home)/.ssh/known_hosts.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default SftpEndpointBuilder useUserKnownHostsFile(
                String useUserKnownHostsFile) {
            doSetProperty("useUserKnownHostsFile", useUserKnownHostsFile);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the SFTP component.
     */
    public interface AdvancedSftpEndpointBuilder
            extends
                AdvancedSftpEndpointConsumerBuilder, AdvancedSftpEndpointProducerBuilder {
        default SftpEndpointBuilder basic() {
            return (SftpEndpointBuilder) 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder fastExistsCheck(
                String fastExistsCheck) {
            doSetProperty("fastExistsCheck", fastExistsCheck);
            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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Specifies the address of the local interface against which the
         * connection should bind.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder bindAddress(String bindAddress) {
            doSetProperty("bindAddress", bindAddress);
            return this;
        }
        /**
         * Specifies how many requests may be outstanding at any one time.
         * Increasing this value may slightly improve file transfer speed but
         * will increase memory usage.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder bulkRequests(Integer bulkRequests) {
            doSetProperty("bulkRequests", bulkRequests);
            return this;
        }
        /**
         * Specifies how many requests may be outstanding at any one time.
         * Increasing this value may slightly improve file transfer speed but
         * will increase memory usage.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder bulkRequests(String bulkRequests) {
            doSetProperty("bulkRequests", bulkRequests);
            return this;
        }
        /**
         * To use compression. Specify a level from 1 to 10. Important: You must
         * manually add the needed JSCH zlib JAR to the classpath for
         * compression support.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder compression(int compression) {
            doSetProperty("compression", compression);
            return this;
        }
        /**
         * To use compression. Specify a level from 1 to 10. Important: You must
         * manually add the needed JSCH zlib JAR to the classpath for
         * compression support.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder compression(String compression) {
            doSetProperty("compression", compression);
            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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder connectTimeout(String connectTimeout) {
            doSetProperty("connectTimeout", connectTimeout);
            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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder maximumReconnectAttempts(
                String maximumReconnectAttempts) {
            doSetProperty("maximumReconnectAttempts", maximumReconnectAttempts);
            return this;
        }
        /**
         * To use a custom configured com.jcraft.jsch.Proxy. This proxy is used
         * to consume/send messages from the target SFTP host.
         * 
         * The option is a: <code>com.jcraft.jsch.Proxy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder proxy(Object proxy) {
            doSetProperty("proxy", proxy);
            return this;
        }
        /**
         * To use a custom configured com.jcraft.jsch.Proxy. This proxy is used
         * to consume/send messages from the target SFTP host.
         * 
         * The option will be converted to a <code>com.jcraft.jsch.Proxy</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder proxy(String proxy) {
            doSetProperty("proxy", proxy);
            return this;
        }
        /**
         * Delay in millis Camel will wait before performing a reconnect
         * attempt.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder reconnectDelay(String reconnectDelay) {
            doSetProperty("reconnectDelay", reconnectDelay);
            return this;
        }
        /**
         * Allows you to set the serverAliveCountMax of the sftp session.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder serverAliveCountMax(
                int serverAliveCountMax) {
            doSetProperty("serverAliveCountMax", serverAliveCountMax);
            return this;
        }
        /**
         * Allows you to set the serverAliveCountMax of the sftp session.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder serverAliveCountMax(
                String serverAliveCountMax) {
            doSetProperty("serverAliveCountMax", serverAliveCountMax);
            return this;
        }
        /**
         * Allows you to set the serverAliveInterval of the sftp session.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder serverAliveInterval(
                int serverAliveInterval) {
            doSetProperty("serverAliveInterval", serverAliveInterval);
            return this;
        }
        /**
         * Allows you to set the serverAliveInterval of the sftp session.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSftpEndpointBuilder serverAliveInterval(
                String serverAliveInterval) {
            doSetProperty("serverAliveInterval", serverAliveInterval);
            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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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 AdvancedSftpEndpointBuilder 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;
    }
    /**
     * SFTP (camel-ftp)
     * The sftp (FTP over SSH) component is used for uploading or downloading
     * files from SFTP servers.
     * 
     * Category: file
     * Since: 1.1
     * Maven coordinates: org.apache.camel:camel-ftp
     * 
     * Syntax: <code>sftp: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 SftpEndpointBuilder sftp(String path) {
        class SftpEndpointBuilderImpl extends AbstractEndpointBuilder implements SftpEndpointBuilder, AdvancedSftpEndpointBuilder {
            public SftpEndpointBuilderImpl(String path) {
                super("sftp", path);
            }
        }
        return new SftpEndpointBuilderImpl(path);
    }
}