/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.builder.endpoint.dsl;

import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Generated;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Expression;
import org.apache.camel.LoggingLevel;
import org.apache.camel.Predicate;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.builder.EndpointProducerBuilder;
import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
import org.apache.camel.spi.ExceptionHandler;
import org.apache.camel.spi.IdempotentRepository;
import org.apache.camel.spi.PollingConsumerPollStrategy;

/**
 * The file component is used for reading or writing files.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface FileEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the File component.
     */
    public interface FileEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedFileEndpointConsumerBuilder advanced() {
            return (AdvancedFileEndpointConsumerBuilder) 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 FileEndpointConsumerBuilder charset(String charset) {
            doSetProperty("charset", charset);
            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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                String sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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;java.io.File&gt;</code> type.
         * 
         * Group: filter
         */
        default FileEndpointConsumerBuilder 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;java.io.File&gt;</code> type.
         * 
         * Group: filter
         */
        default FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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;java.io.File&gt;</code> type.
         * 
         * Group: lock
         */
        default FileEndpointConsumerBuilder 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;java.io.File&gt;</code> type.
         * 
         * Group: lock
         */
        default FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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 FileEndpointConsumerBuilder 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;java.io.File&gt;&gt;</code> type.
         * 
         * Group: sort
         */
        default FileEndpointConsumerBuilder 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;java.io.File&gt;&gt;</code> type.
         * 
         * Group: sort
         */
        default FileEndpointConsumerBuilder sorter(String sorter) {
            doSetProperty("sorter", sorter);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the File component.
     */
    public interface AdvancedFileEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default FileEndpointConsumerBuilder basic() {
            return (FileEndpointConsumerBuilder) this;
        }
        /**
         * Similar to the startingDirectoryMustExist option but this applies
         * during polling (after starting the consumer).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder directoryMustExist(
                boolean directoryMustExist) {
            doSetProperty("directoryMustExist", directoryMustExist);
            return this;
        }
        /**
         * Similar to the startingDirectoryMustExist option but this applies
         * during polling (after starting the consumer).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder directoryMustExist(
                String directoryMustExist) {
            doSetProperty("directoryMustExist", directoryMustExist);
            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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * To define which file attributes of interest. Like
         * posix:permissions,posix:owner,basic:lastAccessTime, it supports basic
         * wildcard like posix:, basic:lastAccessTime.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder extendedAttributes(
                String extendedAttributes) {
            doSetProperty("extendedAttributes", extendedAttributes);
            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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder pollStrategy(
                String pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * Whether to enable probing of the content type. If enable then the
         * consumer uses Files#probeContentType(java.nio.file.Path) to determine
         * the content-type of the file, and store that as a header with key
         * Exchange#FILE_CONTENT_TYPE on the Message.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder probeContentType(
                boolean probeContentType) {
            doSetProperty("probeContentType", probeContentType);
            return this;
        }
        /**
         * Whether to enable probing of the content type. If enable then the
         * consumer uses Files#probeContentType(java.nio.file.Path) to determine
         * the content-type of the file, and store that as a header with key
         * Exchange#FILE_CONTENT_TYPE on the Message.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder probeContentType(
                String probeContentType) {
            doSetProperty("probeContentType", probeContentType);
            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;java.io.File&gt;</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder 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;java.io.File&gt;</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder processStrategy(
                String processStrategy) {
            doSetProperty("processStrategy", processStrategy);
            return this;
        }
        /**
         * Whether the starting directory must exist. Mind that the autoCreate
         * option is default enabled, which means the starting directory is
         * normally auto created if it doesn't exist. You can disable autoCreate
         * and enable this to ensure the starting directory must exist. Will
         * thrown an exception if the directory doesn't exist.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder startingDirectoryMustExist(
                boolean startingDirectoryMustExist) {
            doSetProperty("startingDirectoryMustExist", startingDirectoryMustExist);
            return this;
        }
        /**
         * Whether the starting directory must exist. Mind that the autoCreate
         * option is default enabled, which means the starting directory is
         * normally auto created if it doesn't exist. You can disable autoCreate
         * and enable this to ensure the starting directory must exist. Will
         * thrown an exception if the directory doesn't exist.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder startingDirectoryMustExist(
                String startingDirectoryMustExist) {
            doSetProperty("startingDirectoryMustExist", startingDirectoryMustExist);
            return this;
        }
        /**
         * Whether the starting directory has access permissions. Mind that the
         * startingDirectoryMustExist parameter must be set to true in order to
         * verify that the directory exists. Will thrown an exception if the
         * directory doesn't have read and write permissions.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder startingDirectoryMustHaveAccess(
                boolean startingDirectoryMustHaveAccess) {
            doSetProperty("startingDirectoryMustHaveAccess", startingDirectoryMustHaveAccess);
            return this;
        }
        /**
         * Whether the starting directory has access permissions. Mind that the
         * startingDirectoryMustExist parameter must be set to true in order to
         * verify that the directory exists. Will thrown an exception if the
         * directory doesn't have read and write permissions.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedFileEndpointConsumerBuilder startingDirectoryMustHaveAccess(
                String startingDirectoryMustHaveAccess) {
            doSetProperty("startingDirectoryMustHaveAccess", startingDirectoryMustHaveAccess);
            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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointConsumerBuilder bufferSize(int bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointConsumerBuilder bufferSize(String bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Whether to fallback and do a copy and delete file, in case the file
         * could not be renamed directly. This option is not available for the
         * FTP component.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointConsumerBuilder copyAndDeleteOnRenameFail(
                boolean copyAndDeleteOnRenameFail) {
            doSetProperty("copyAndDeleteOnRenameFail", copyAndDeleteOnRenameFail);
            return this;
        }
        /**
         * Whether to fallback and do a copy and delete file, in case the file
         * could not be renamed directly. This option is not available for the
         * FTP component.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointConsumerBuilder copyAndDeleteOnRenameFail(
                String copyAndDeleteOnRenameFail) {
            doSetProperty("copyAndDeleteOnRenameFail", copyAndDeleteOnRenameFail);
            return this;
        }
        /**
         * Perform rename operations using a copy and delete strategy. This is
         * primarily used in environments where the regular rename operation is
         * unreliable (e.g. across different file systems or networks). This
         * option takes precedence over the copyAndDeleteOnRenameFail parameter
         * that will automatically fall back to the copy and delete strategy,
         * but only after additional delays.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointConsumerBuilder renameUsingCopy(
                boolean renameUsingCopy) {
            doSetProperty("renameUsingCopy", renameUsingCopy);
            return this;
        }
        /**
         * Perform rename operations using a copy and delete strategy. This is
         * primarily used in environments where the regular rename operation is
         * unreliable (e.g. across different file systems or networks). This
         * option takes precedence over the copyAndDeleteOnRenameFail parameter
         * that will automatically fall back to the copy and delete strategy,
         * but only after additional delays.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointConsumerBuilder renameUsingCopy(
                String renameUsingCopy) {
            doSetProperty("renameUsingCopy", renameUsingCopy);
            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 AdvancedFileEndpointConsumerBuilder 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 AdvancedFileEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the File component.
     */
    public interface FileEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedFileEndpointProducerBuilder advanced() {
            return (AdvancedFileEndpointProducerBuilder) 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 FileEndpointProducerBuilder charset(String charset) {
            doSetProperty("charset", charset);
            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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
        /**
         * Used to append characters (text) after writing files. This can for
         * example be used to add new lines or other separators when writing and
         * appending to existing files. To specify new-line (slash-n or slash-r)
         * or tab (slash-t) characters then escape with an extra slash, eg
         * slash-slash-n.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default FileEndpointProducerBuilder appendChars(String appendChars) {
            doSetProperty("appendChars", appendChars);
            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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder 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 FileEndpointProducerBuilder tempPrefix(String tempPrefix) {
            doSetProperty("tempPrefix", tempPrefix);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the File component.
     */
    public interface AdvancedFileEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default FileEndpointProducerBuilder basic() {
            return (FileEndpointProducerBuilder) 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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder allowNullBody(
                String allowNullBody) {
            doSetProperty("allowNullBody", allowNullBody);
            return this;
        }
        /**
         * Specify the file permissions which is sent by the producer, the chmod
         * value must be between 000 and 777; If there is a leading digit like
         * in 0755 we will ignore it.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFileEndpointProducerBuilder chmod(String chmod) {
            doSetProperty("chmod", chmod);
            return this;
        }
        /**
         * Specify the directory permissions used when the producer creates
         * missing directories, the chmod value must be between 000 and 777; If
         * there is a leading digit like in 0755 we will ignore it.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFileEndpointProducerBuilder chmodDirectory(
                String chmodDirectory) {
            doSetProperty("chmodDirectory", chmodDirectory);
            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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder eagerDeleteTargetFile(
                String eagerDeleteTargetFile) {
            doSetProperty("eagerDeleteTargetFile", eagerDeleteTargetFile);
            return this;
        }
        /**
         * Whether to force syncing writes to the file system. You can turn this
         * off if you do not want this level of guarantee, for example if
         * writing to logs / audit logs etc; this would yield better
         * performance.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFileEndpointProducerBuilder forceWrites(
                boolean forceWrites) {
            doSetProperty("forceWrites", forceWrites);
            return this;
        }
        /**
         * Whether to force syncing writes to the file system. You can turn this
         * off if you do not want this level of guarantee, for example if
         * writing to logs / audit logs etc; this would yield better
         * performance.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedFileEndpointProducerBuilder forceWrites(
                String forceWrites) {
            doSetProperty("forceWrites", forceWrites);
            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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder moveExistingFileStrategy(
                String moveExistingFileStrategy) {
            doSetProperty("moveExistingFileStrategy", moveExistingFileStrategy);
            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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointProducerBuilder bufferSize(int bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointProducerBuilder bufferSize(String bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Whether to fallback and do a copy and delete file, in case the file
         * could not be renamed directly. This option is not available for the
         * FTP component.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointProducerBuilder copyAndDeleteOnRenameFail(
                boolean copyAndDeleteOnRenameFail) {
            doSetProperty("copyAndDeleteOnRenameFail", copyAndDeleteOnRenameFail);
            return this;
        }
        /**
         * Whether to fallback and do a copy and delete file, in case the file
         * could not be renamed directly. This option is not available for the
         * FTP component.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointProducerBuilder copyAndDeleteOnRenameFail(
                String copyAndDeleteOnRenameFail) {
            doSetProperty("copyAndDeleteOnRenameFail", copyAndDeleteOnRenameFail);
            return this;
        }
        /**
         * Perform rename operations using a copy and delete strategy. This is
         * primarily used in environments where the regular rename operation is
         * unreliable (e.g. across different file systems or networks). This
         * option takes precedence over the copyAndDeleteOnRenameFail parameter
         * that will automatically fall back to the copy and delete strategy,
         * but only after additional delays.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointProducerBuilder renameUsingCopy(
                boolean renameUsingCopy) {
            doSetProperty("renameUsingCopy", renameUsingCopy);
            return this;
        }
        /**
         * Perform rename operations using a copy and delete strategy. This is
         * primarily used in environments where the regular rename operation is
         * unreliable (e.g. across different file systems or networks). This
         * option takes precedence over the copyAndDeleteOnRenameFail parameter
         * that will automatically fall back to the copy and delete strategy,
         * but only after additional delays.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointProducerBuilder renameUsingCopy(
                String renameUsingCopy) {
            doSetProperty("renameUsingCopy", renameUsingCopy);
            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 AdvancedFileEndpointProducerBuilder 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 AdvancedFileEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint for the File component.
     */
    public interface FileEndpointBuilder
            extends
                FileEndpointConsumerBuilder, FileEndpointProducerBuilder {
        default AdvancedFileEndpointBuilder advanced() {
            return (AdvancedFileEndpointBuilder) 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 FileEndpointBuilder charset(String charset) {
            doSetProperty("charset", charset);
            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 FileEndpointBuilder 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 FileEndpointBuilder 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 FileEndpointBuilder fileName(String fileName) {
            doSetProperty("fileName", fileName);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the File component.
     */
    public interface AdvancedFileEndpointBuilder
            extends
                AdvancedFileEndpointConsumerBuilder, AdvancedFileEndpointProducerBuilder {
        default FileEndpointBuilder basic() {
            return (FileEndpointBuilder) 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 AdvancedFileEndpointBuilder 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 AdvancedFileEndpointBuilder 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 AdvancedFileEndpointBuilder 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 AdvancedFileEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointBuilder bufferSize(int bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Buffer size in bytes used for writing files (or in case of FTP for
         * downloading and uploading files).
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointBuilder bufferSize(String bufferSize) {
            doSetProperty("bufferSize", bufferSize);
            return this;
        }
        /**
         * Whether to fallback and do a copy and delete file, in case the file
         * could not be renamed directly. This option is not available for the
         * FTP component.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointBuilder copyAndDeleteOnRenameFail(
                boolean copyAndDeleteOnRenameFail) {
            doSetProperty("copyAndDeleteOnRenameFail", copyAndDeleteOnRenameFail);
            return this;
        }
        /**
         * Whether to fallback and do a copy and delete file, in case the file
         * could not be renamed directly. This option is not available for the
         * FTP component.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointBuilder copyAndDeleteOnRenameFail(
                String copyAndDeleteOnRenameFail) {
            doSetProperty("copyAndDeleteOnRenameFail", copyAndDeleteOnRenameFail);
            return this;
        }
        /**
         * Perform rename operations using a copy and delete strategy. This is
         * primarily used in environments where the regular rename operation is
         * unreliable (e.g. across different file systems or networks). This
         * option takes precedence over the copyAndDeleteOnRenameFail parameter
         * that will automatically fall back to the copy and delete strategy,
         * but only after additional delays.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointBuilder renameUsingCopy(
                boolean renameUsingCopy) {
            doSetProperty("renameUsingCopy", renameUsingCopy);
            return this;
        }
        /**
         * Perform rename operations using a copy and delete strategy. This is
         * primarily used in environments where the regular rename operation is
         * unreliable (e.g. across different file systems or networks). This
         * option takes precedence over the copyAndDeleteOnRenameFail parameter
         * that will automatically fall back to the copy and delete strategy,
         * but only after additional delays.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedFileEndpointBuilder renameUsingCopy(
                String renameUsingCopy) {
            doSetProperty("renameUsingCopy", renameUsingCopy);
            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 AdvancedFileEndpointBuilder 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 AdvancedFileEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.file.GenericFileExist</code> enum.
     */
    enum GenericFileExist {
        Override,
        Append,
        Fail,
        Ignore,
        Move,
        TryRename;
    }
    /**
     * File (camel-file)
     * The file component is used for reading or writing files.
     * 
     * Category: core,file
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-file
     * 
     * Syntax: <code>file:directoryName</code>
     * 
     * Path parameter: directoryName (required)
     * The starting directory
     */
    default FileEndpointBuilder file(String path) {
        class FileEndpointBuilderImpl extends AbstractEndpointBuilder implements FileEndpointBuilder, AdvancedFileEndpointBuilder {
            public FileEndpointBuilderImpl(String path) {
                super("file", path);
            }
        }
        return new FileEndpointBuilderImpl(path);
    }
}