/*
 * 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.List;
import javax.annotation.Generated;
import org.apache.camel.ExchangePattern;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.builder.EndpointProducerBuilder;
import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
import org.apache.camel.spi.ExceptionHandler;

/**
 * Socket level networking using TCP or UDP with the Apache Mina 2.x library.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface MinaEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the Mina component.
     */
    public interface MinaEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedMinaEndpointConsumerBuilder advanced() {
            return (AdvancedMinaEndpointConsumerBuilder) this;
        }
        /**
         * Whether or not to disconnect(close) from Mina session right after
         * use. Can be used for both consumer and producer.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder disconnect(boolean disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Whether or not to disconnect(close) from Mina session right after
         * use. Can be used for both consumer and producer.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder disconnect(String disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * You can enable the Apache MINA logging filter. Apache MINA uses slf4j
         * logging at INFO level to log all input and output.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder minaLogger(boolean minaLogger) {
            doSetProperty("minaLogger", minaLogger);
            return this;
        }
        /**
         * You can enable the Apache MINA logging filter. Apache MINA uses slf4j
         * logging at INFO level to log all input and output.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder minaLogger(String minaLogger) {
            doSetProperty("minaLogger", minaLogger);
            return this;
        }
        /**
         * Setting to set endpoint as one-way or request-response.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder sync(boolean sync) {
            doSetProperty("sync", sync);
            return this;
        }
        /**
         * Setting to set endpoint as one-way or request-response.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder sync(String sync) {
            doSetProperty("sync", sync);
            return this;
        }
        /**
         * You can configure the timeout that specifies how long to wait for a
         * response from a remote server. The timeout unit is in milliseconds,
         * so 60000 is 60 seconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder timeout(long timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * You can configure the timeout that specifies how long to wait for a
         * response from a remote server. The timeout unit is in milliseconds,
         * so 60000 is 60 seconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * Maximum amount of time it should take to send data to the MINA
         * session. Default is 10000 milliseconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder writeTimeout(long writeTimeout) {
            doSetProperty("writeTimeout", writeTimeout);
            return this;
        }
        /**
         * Maximum amount of time it should take to send data to the MINA
         * session. Default is 10000 milliseconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointConsumerBuilder writeTimeout(String writeTimeout) {
            doSetProperty("writeTimeout", writeTimeout);
            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 MinaEndpointConsumerBuilder 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 MinaEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * If the clientMode is true, mina consumer will connect the address as
         * a TCP client.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MinaEndpointConsumerBuilder clientMode(boolean clientMode) {
            doSetProperty("clientMode", clientMode);
            return this;
        }
        /**
         * If the clientMode is true, mina consumer will connect the address as
         * a TCP client.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default MinaEndpointConsumerBuilder clientMode(String clientMode) {
            doSetProperty("clientMode", clientMode);
            return this;
        }
        /**
         * The mina component installs a default codec if both, codec is null
         * and textline is false. Setting allowDefaultCodec to false prevents
         * the mina component from installing a default codec as the first
         * element in the filter chain. This is useful in scenarios where
         * another filter must be the first in the filter chain, like the SSL
         * filter.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder allowDefaultCodec(
                boolean allowDefaultCodec) {
            doSetProperty("allowDefaultCodec", allowDefaultCodec);
            return this;
        }
        /**
         * The mina component installs a default codec if both, codec is null
         * and textline is false. Setting allowDefaultCodec to false prevents
         * the mina component from installing a default codec as the first
         * element in the filter chain. This is useful in scenarios where
         * another filter must be the first in the filter chain, like the SSL
         * filter.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder allowDefaultCodec(
                String allowDefaultCodec) {
            doSetProperty("allowDefaultCodec", allowDefaultCodec);
            return this;
        }
        /**
         * To use a custom minda codec implementation.
         * 
         * The option is a:
         * <code>org.apache.mina.filter.codec.ProtocolCodecFactory</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder codec(Object codec) {
            doSetProperty("codec", codec);
            return this;
        }
        /**
         * To use a custom minda codec implementation.
         * 
         * The option will be converted to a
         * <code>org.apache.mina.filter.codec.ProtocolCodecFactory</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder codec(String codec) {
            doSetProperty("codec", codec);
            return this;
        }
        /**
         * To set the textline protocol decoder max line length. By default the
         * default value of Mina itself is used which are 1024.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder decoderMaxLineLength(
                int decoderMaxLineLength) {
            doSetProperty("decoderMaxLineLength", decoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol decoder max line length. By default the
         * default value of Mina itself is used which are 1024.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder decoderMaxLineLength(
                String decoderMaxLineLength) {
            doSetProperty("decoderMaxLineLength", decoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol encoder max line length. By default the
         * default value of Mina itself is used which are Integer.MAX_VALUE.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder encoderMaxLineLength(
                int encoderMaxLineLength) {
            doSetProperty("encoderMaxLineLength", encoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol encoder max line length. By default the
         * default value of Mina itself is used which are Integer.MAX_VALUE.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder encoderMaxLineLength(
                String encoderMaxLineLength) {
            doSetProperty("encoderMaxLineLength", encoderMaxLineLength);
            return this;
        }
        /**
         * You can configure the encoding (a charset name) to use for the TCP
         * textline codec and the UDP protocol. If not provided, Camel will use
         * the JVM default Charset.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder encoding(String encoding) {
            doSetProperty("encoding", encoding);
            return this;
        }
        /**
         * You can set a list of Mina IoFilters to use.
         * 
         * The option is a:
         * <code>java.util.List&lt;org.apache.mina.core.filterchain.IoFilter&gt;</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder filters(List<Object> filters) {
            doSetProperty("filters", filters);
            return this;
        }
        /**
         * You can set a list of Mina IoFilters to use.
         * 
         * The option will be converted to a
         * <code>java.util.List&lt;org.apache.mina.core.filterchain.IoFilter&gt;</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder filters(String filters) {
            doSetProperty("filters", filters);
            return this;
        }
        /**
         * Only used for TCP. If no codec is specified, you can use this flag to
         * indicate a text line based codec; if not specified or the value is
         * false, then Object Serialization is assumed over TCP.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder textline(boolean textline) {
            doSetProperty("textline", textline);
            return this;
        }
        /**
         * Only used for TCP. If no codec is specified, you can use this flag to
         * indicate a text line based codec; if not specified or the value is
         * false, then Object Serialization is assumed over TCP.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder textline(String textline) {
            doSetProperty("textline", textline);
            return this;
        }
        /**
         * Only used for TCP and if textline=true. Sets the text line delimiter
         * to use. If none provided, Camel will use DEFAULT. This delimiter is
         * used to mark the end of text.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mina.MinaTextLineDelimiter</code>
         * type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder textlineDelimiter(
                MinaTextLineDelimiter textlineDelimiter) {
            doSetProperty("textlineDelimiter", textlineDelimiter);
            return this;
        }
        /**
         * Only used for TCP and if textline=true. Sets the text line delimiter
         * to use. If none provided, Camel will use DEFAULT. This delimiter is
         * used to mark the end of text.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mina.MinaTextLineDelimiter</code>
         * type.
         * 
         * Group: codec
         */
        default MinaEndpointConsumerBuilder textlineDelimiter(
                String textlineDelimiter) {
            doSetProperty("textlineDelimiter", textlineDelimiter);
            return this;
        }
        /**
         * Whether to auto start SSL handshake.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default MinaEndpointConsumerBuilder autoStartTls(boolean autoStartTls) {
            doSetProperty("autoStartTls", autoStartTls);
            return this;
        }
        /**
         * Whether to auto start SSL handshake.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default MinaEndpointConsumerBuilder autoStartTls(String autoStartTls) {
            doSetProperty("autoStartTls", autoStartTls);
            return this;
        }
        /**
         * To configure SSL security.
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MinaEndpointConsumerBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * To configure SSL security.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MinaEndpointConsumerBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the Mina component.
     */
    public interface AdvancedMinaEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default MinaEndpointConsumerBuilder basic() {
            return (MinaEndpointConsumerBuilder) this;
        }
        /**
         * If sync is enabled then this option dictates MinaConsumer if it
         * should disconnect where there is no reply to send back.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinaEndpointConsumerBuilder disconnectOnNoReply(
                boolean disconnectOnNoReply) {
            doSetProperty("disconnectOnNoReply", disconnectOnNoReply);
            return this;
        }
        /**
         * If sync is enabled then this option dictates MinaConsumer if it
         * should disconnect where there is no reply to send back.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinaEndpointConsumerBuilder disconnectOnNoReply(
                String disconnectOnNoReply) {
            doSetProperty("disconnectOnNoReply", disconnectOnNoReply);
            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 AdvancedMinaEndpointConsumerBuilder 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 AdvancedMinaEndpointConsumerBuilder 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 AdvancedMinaEndpointConsumerBuilder 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 AdvancedMinaEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * If sync is enabled this option dictates MinaConsumer which logging
         * level to use when logging a there is no reply to send back.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinaEndpointConsumerBuilder noReplyLogLevel(
                LoggingLevel noReplyLogLevel) {
            doSetProperty("noReplyLogLevel", noReplyLogLevel);
            return this;
        }
        /**
         * If sync is enabled this option dictates MinaConsumer which logging
         * level to use when logging a there is no reply to send back.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinaEndpointConsumerBuilder noReplyLogLevel(
                String noReplyLogLevel) {
            doSetProperty("noReplyLogLevel", noReplyLogLevel);
            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 AdvancedMinaEndpointConsumerBuilder 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 AdvancedMinaEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Number of worker threads in the worker pool for TCP and UDP.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointConsumerBuilder maximumPoolSize(
                int maximumPoolSize) {
            doSetProperty("maximumPoolSize", maximumPoolSize);
            return this;
        }
        /**
         * Number of worker threads in the worker pool for TCP and UDP.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointConsumerBuilder maximumPoolSize(
                String maximumPoolSize) {
            doSetProperty("maximumPoolSize", maximumPoolSize);
            return this;
        }
        /**
         * Whether to use ordered thread pool, to ensure events are processed
         * orderly on the same channel.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointConsumerBuilder orderedThreadPoolExecutor(
                boolean orderedThreadPoolExecutor) {
            doSetProperty("orderedThreadPoolExecutor", orderedThreadPoolExecutor);
            return this;
        }
        /**
         * Whether to use ordered thread pool, to ensure events are processed
         * orderly on the same channel.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointConsumerBuilder orderedThreadPoolExecutor(
                String orderedThreadPoolExecutor) {
            doSetProperty("orderedThreadPoolExecutor", orderedThreadPoolExecutor);
            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 AdvancedMinaEndpointConsumerBuilder 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 AdvancedMinaEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Only used for TCP. You can transfer the exchange over the wire
         * instead of just the body. The following fields are transferred: In
         * body, Out body, fault body, In headers, Out headers, fault headers,
         * exchange properties, exchange exception. This requires that the
         * objects are serializable. Camel will exclude any non-serializable
         * objects and log it at WARN level.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointConsumerBuilder transferExchange(
                boolean transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * Only used for TCP. You can transfer the exchange over the wire
         * instead of just the body. The following fields are transferred: In
         * body, Out body, fault body, In headers, Out headers, fault headers,
         * exchange properties, exchange exception. This requires that the
         * objects are serializable. Camel will exclude any non-serializable
         * objects and log it at WARN level.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointConsumerBuilder transferExchange(
                String transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the Mina component.
     */
    public interface MinaEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedMinaEndpointProducerBuilder advanced() {
            return (AdvancedMinaEndpointProducerBuilder) this;
        }
        /**
         * Whether or not to disconnect(close) from Mina session right after
         * use. Can be used for both consumer and producer.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder disconnect(boolean disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Whether or not to disconnect(close) from Mina session right after
         * use. Can be used for both consumer and producer.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder disconnect(String disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * You can enable the Apache MINA logging filter. Apache MINA uses slf4j
         * logging at INFO level to log all input and output.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder minaLogger(boolean minaLogger) {
            doSetProperty("minaLogger", minaLogger);
            return this;
        }
        /**
         * You can enable the Apache MINA logging filter. Apache MINA uses slf4j
         * logging at INFO level to log all input and output.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder minaLogger(String minaLogger) {
            doSetProperty("minaLogger", minaLogger);
            return this;
        }
        /**
         * Setting to set endpoint as one-way or request-response.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder sync(boolean sync) {
            doSetProperty("sync", sync);
            return this;
        }
        /**
         * Setting to set endpoint as one-way or request-response.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder sync(String sync) {
            doSetProperty("sync", sync);
            return this;
        }
        /**
         * You can configure the timeout that specifies how long to wait for a
         * response from a remote server. The timeout unit is in milliseconds,
         * so 60000 is 60 seconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder timeout(long timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * You can configure the timeout that specifies how long to wait for a
         * response from a remote server. The timeout unit is in milliseconds,
         * so 60000 is 60 seconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * Maximum amount of time it should take to send data to the MINA
         * session. Default is 10000 milliseconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder writeTimeout(long writeTimeout) {
            doSetProperty("writeTimeout", writeTimeout);
            return this;
        }
        /**
         * Maximum amount of time it should take to send data to the MINA
         * session. Default is 10000 milliseconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointProducerBuilder writeTimeout(String writeTimeout) {
            doSetProperty("writeTimeout", writeTimeout);
            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 MinaEndpointProducerBuilder 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 MinaEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * The mina component installs a default codec if both, codec is null
         * and textline is false. Setting allowDefaultCodec to false prevents
         * the mina component from installing a default codec as the first
         * element in the filter chain. This is useful in scenarios where
         * another filter must be the first in the filter chain, like the SSL
         * filter.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder allowDefaultCodec(
                boolean allowDefaultCodec) {
            doSetProperty("allowDefaultCodec", allowDefaultCodec);
            return this;
        }
        /**
         * The mina component installs a default codec if both, codec is null
         * and textline is false. Setting allowDefaultCodec to false prevents
         * the mina component from installing a default codec as the first
         * element in the filter chain. This is useful in scenarios where
         * another filter must be the first in the filter chain, like the SSL
         * filter.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder allowDefaultCodec(
                String allowDefaultCodec) {
            doSetProperty("allowDefaultCodec", allowDefaultCodec);
            return this;
        }
        /**
         * To use a custom minda codec implementation.
         * 
         * The option is a:
         * <code>org.apache.mina.filter.codec.ProtocolCodecFactory</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder codec(Object codec) {
            doSetProperty("codec", codec);
            return this;
        }
        /**
         * To use a custom minda codec implementation.
         * 
         * The option will be converted to a
         * <code>org.apache.mina.filter.codec.ProtocolCodecFactory</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder codec(String codec) {
            doSetProperty("codec", codec);
            return this;
        }
        /**
         * To set the textline protocol decoder max line length. By default the
         * default value of Mina itself is used which are 1024.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder decoderMaxLineLength(
                int decoderMaxLineLength) {
            doSetProperty("decoderMaxLineLength", decoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol decoder max line length. By default the
         * default value of Mina itself is used which are 1024.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder decoderMaxLineLength(
                String decoderMaxLineLength) {
            doSetProperty("decoderMaxLineLength", decoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol encoder max line length. By default the
         * default value of Mina itself is used which are Integer.MAX_VALUE.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder encoderMaxLineLength(
                int encoderMaxLineLength) {
            doSetProperty("encoderMaxLineLength", encoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol encoder max line length. By default the
         * default value of Mina itself is used which are Integer.MAX_VALUE.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder encoderMaxLineLength(
                String encoderMaxLineLength) {
            doSetProperty("encoderMaxLineLength", encoderMaxLineLength);
            return this;
        }
        /**
         * You can configure the encoding (a charset name) to use for the TCP
         * textline codec and the UDP protocol. If not provided, Camel will use
         * the JVM default Charset.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder encoding(String encoding) {
            doSetProperty("encoding", encoding);
            return this;
        }
        /**
         * You can set a list of Mina IoFilters to use.
         * 
         * The option is a:
         * <code>java.util.List&lt;org.apache.mina.core.filterchain.IoFilter&gt;</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder filters(List<Object> filters) {
            doSetProperty("filters", filters);
            return this;
        }
        /**
         * You can set a list of Mina IoFilters to use.
         * 
         * The option will be converted to a
         * <code>java.util.List&lt;org.apache.mina.core.filterchain.IoFilter&gt;</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder filters(String filters) {
            doSetProperty("filters", filters);
            return this;
        }
        /**
         * Only used for TCP. If no codec is specified, you can use this flag to
         * indicate a text line based codec; if not specified or the value is
         * false, then Object Serialization is assumed over TCP.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder textline(boolean textline) {
            doSetProperty("textline", textline);
            return this;
        }
        /**
         * Only used for TCP. If no codec is specified, you can use this flag to
         * indicate a text line based codec; if not specified or the value is
         * false, then Object Serialization is assumed over TCP.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder textline(String textline) {
            doSetProperty("textline", textline);
            return this;
        }
        /**
         * Only used for TCP and if textline=true. Sets the text line delimiter
         * to use. If none provided, Camel will use DEFAULT. This delimiter is
         * used to mark the end of text.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mina.MinaTextLineDelimiter</code>
         * type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder textlineDelimiter(
                MinaTextLineDelimiter textlineDelimiter) {
            doSetProperty("textlineDelimiter", textlineDelimiter);
            return this;
        }
        /**
         * Only used for TCP and if textline=true. Sets the text line delimiter
         * to use. If none provided, Camel will use DEFAULT. This delimiter is
         * used to mark the end of text.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mina.MinaTextLineDelimiter</code>
         * type.
         * 
         * Group: codec
         */
        default MinaEndpointProducerBuilder textlineDelimiter(
                String textlineDelimiter) {
            doSetProperty("textlineDelimiter", textlineDelimiter);
            return this;
        }
        /**
         * Whether to auto start SSL handshake.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default MinaEndpointProducerBuilder autoStartTls(boolean autoStartTls) {
            doSetProperty("autoStartTls", autoStartTls);
            return this;
        }
        /**
         * Whether to auto start SSL handshake.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default MinaEndpointProducerBuilder autoStartTls(String autoStartTls) {
            doSetProperty("autoStartTls", autoStartTls);
            return this;
        }
        /**
         * To configure SSL security.
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MinaEndpointProducerBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * To configure SSL security.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MinaEndpointProducerBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the Mina component.
     */
    public interface AdvancedMinaEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default MinaEndpointProducerBuilder basic() {
            return (MinaEndpointProducerBuilder) this;
        }
        /**
         * Whether to create the InetAddress once and reuse. Setting this to
         * false allows to pickup DNS changes in the network.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedMinaEndpointProducerBuilder cachedAddress(
                boolean cachedAddress) {
            doSetProperty("cachedAddress", cachedAddress);
            return this;
        }
        /**
         * Whether to create the InetAddress once and reuse. Setting this to
         * false allows to pickup DNS changes in the network.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedMinaEndpointProducerBuilder cachedAddress(
                String cachedAddress) {
            doSetProperty("cachedAddress", cachedAddress);
            return this;
        }
        /**
         * Sessions can be lazily created to avoid exceptions, if the remote
         * server is not up and running when the Camel producer is started.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedMinaEndpointProducerBuilder lazySessionCreation(
                boolean lazySessionCreation) {
            doSetProperty("lazySessionCreation", lazySessionCreation);
            return this;
        }
        /**
         * Sessions can be lazily created to avoid exceptions, if the remote
         * server is not up and running when the Camel producer is started.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer (advanced)
         */
        default AdvancedMinaEndpointProducerBuilder lazySessionCreation(
                String lazySessionCreation) {
            doSetProperty("lazySessionCreation", lazySessionCreation);
            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 AdvancedMinaEndpointProducerBuilder 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 AdvancedMinaEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Number of worker threads in the worker pool for TCP and UDP.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointProducerBuilder maximumPoolSize(
                int maximumPoolSize) {
            doSetProperty("maximumPoolSize", maximumPoolSize);
            return this;
        }
        /**
         * Number of worker threads in the worker pool for TCP and UDP.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointProducerBuilder maximumPoolSize(
                String maximumPoolSize) {
            doSetProperty("maximumPoolSize", maximumPoolSize);
            return this;
        }
        /**
         * Whether to use ordered thread pool, to ensure events are processed
         * orderly on the same channel.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointProducerBuilder orderedThreadPoolExecutor(
                boolean orderedThreadPoolExecutor) {
            doSetProperty("orderedThreadPoolExecutor", orderedThreadPoolExecutor);
            return this;
        }
        /**
         * Whether to use ordered thread pool, to ensure events are processed
         * orderly on the same channel.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointProducerBuilder orderedThreadPoolExecutor(
                String orderedThreadPoolExecutor) {
            doSetProperty("orderedThreadPoolExecutor", orderedThreadPoolExecutor);
            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 AdvancedMinaEndpointProducerBuilder 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 AdvancedMinaEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Only used for TCP. You can transfer the exchange over the wire
         * instead of just the body. The following fields are transferred: In
         * body, Out body, fault body, In headers, Out headers, fault headers,
         * exchange properties, exchange exception. This requires that the
         * objects are serializable. Camel will exclude any non-serializable
         * objects and log it at WARN level.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointProducerBuilder transferExchange(
                boolean transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * Only used for TCP. You can transfer the exchange over the wire
         * instead of just the body. The following fields are transferred: In
         * body, Out body, fault body, In headers, Out headers, fault headers,
         * exchange properties, exchange exception. This requires that the
         * objects are serializable. Camel will exclude any non-serializable
         * objects and log it at WARN level.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointProducerBuilder transferExchange(
                String transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
    }

    /**
     * Builder for endpoint for the Mina component.
     */
    public interface MinaEndpointBuilder
            extends
                MinaEndpointConsumerBuilder, MinaEndpointProducerBuilder {
        default AdvancedMinaEndpointBuilder advanced() {
            return (AdvancedMinaEndpointBuilder) this;
        }
        /**
         * Whether or not to disconnect(close) from Mina session right after
         * use. Can be used for both consumer and producer.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder disconnect(boolean disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Whether or not to disconnect(close) from Mina session right after
         * use. Can be used for both consumer and producer.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder disconnect(String disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * You can enable the Apache MINA logging filter. Apache MINA uses slf4j
         * logging at INFO level to log all input and output.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder minaLogger(boolean minaLogger) {
            doSetProperty("minaLogger", minaLogger);
            return this;
        }
        /**
         * You can enable the Apache MINA logging filter. Apache MINA uses slf4j
         * logging at INFO level to log all input and output.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder minaLogger(String minaLogger) {
            doSetProperty("minaLogger", minaLogger);
            return this;
        }
        /**
         * Setting to set endpoint as one-way or request-response.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder sync(boolean sync) {
            doSetProperty("sync", sync);
            return this;
        }
        /**
         * Setting to set endpoint as one-way or request-response.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder sync(String sync) {
            doSetProperty("sync", sync);
            return this;
        }
        /**
         * You can configure the timeout that specifies how long to wait for a
         * response from a remote server. The timeout unit is in milliseconds,
         * so 60000 is 60 seconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder timeout(long timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * You can configure the timeout that specifies how long to wait for a
         * response from a remote server. The timeout unit is in milliseconds,
         * so 60000 is 60 seconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * Maximum amount of time it should take to send data to the MINA
         * session. Default is 10000 milliseconds.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder writeTimeout(long writeTimeout) {
            doSetProperty("writeTimeout", writeTimeout);
            return this;
        }
        /**
         * Maximum amount of time it should take to send data to the MINA
         * session. Default is 10000 milliseconds.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: common
         */
        default MinaEndpointBuilder writeTimeout(String writeTimeout) {
            doSetProperty("writeTimeout", writeTimeout);
            return this;
        }
        /**
         * The mina component installs a default codec if both, codec is null
         * and textline is false. Setting allowDefaultCodec to false prevents
         * the mina component from installing a default codec as the first
         * element in the filter chain. This is useful in scenarios where
         * another filter must be the first in the filter chain, like the SSL
         * filter.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder allowDefaultCodec(boolean allowDefaultCodec) {
            doSetProperty("allowDefaultCodec", allowDefaultCodec);
            return this;
        }
        /**
         * The mina component installs a default codec if both, codec is null
         * and textline is false. Setting allowDefaultCodec to false prevents
         * the mina component from installing a default codec as the first
         * element in the filter chain. This is useful in scenarios where
         * another filter must be the first in the filter chain, like the SSL
         * filter.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder allowDefaultCodec(String allowDefaultCodec) {
            doSetProperty("allowDefaultCodec", allowDefaultCodec);
            return this;
        }
        /**
         * To use a custom minda codec implementation.
         * 
         * The option is a:
         * <code>org.apache.mina.filter.codec.ProtocolCodecFactory</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder codec(Object codec) {
            doSetProperty("codec", codec);
            return this;
        }
        /**
         * To use a custom minda codec implementation.
         * 
         * The option will be converted to a
         * <code>org.apache.mina.filter.codec.ProtocolCodecFactory</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder codec(String codec) {
            doSetProperty("codec", codec);
            return this;
        }
        /**
         * To set the textline protocol decoder max line length. By default the
         * default value of Mina itself is used which are 1024.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder decoderMaxLineLength(
                int decoderMaxLineLength) {
            doSetProperty("decoderMaxLineLength", decoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol decoder max line length. By default the
         * default value of Mina itself is used which are 1024.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder decoderMaxLineLength(
                String decoderMaxLineLength) {
            doSetProperty("decoderMaxLineLength", decoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol encoder max line length. By default the
         * default value of Mina itself is used which are Integer.MAX_VALUE.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder encoderMaxLineLength(
                int encoderMaxLineLength) {
            doSetProperty("encoderMaxLineLength", encoderMaxLineLength);
            return this;
        }
        /**
         * To set the textline protocol encoder max line length. By default the
         * default value of Mina itself is used which are Integer.MAX_VALUE.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder encoderMaxLineLength(
                String encoderMaxLineLength) {
            doSetProperty("encoderMaxLineLength", encoderMaxLineLength);
            return this;
        }
        /**
         * You can configure the encoding (a charset name) to use for the TCP
         * textline codec and the UDP protocol. If not provided, Camel will use
         * the JVM default Charset.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder encoding(String encoding) {
            doSetProperty("encoding", encoding);
            return this;
        }
        /**
         * You can set a list of Mina IoFilters to use.
         * 
         * The option is a:
         * <code>java.util.List&lt;org.apache.mina.core.filterchain.IoFilter&gt;</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder filters(List<Object> filters) {
            doSetProperty("filters", filters);
            return this;
        }
        /**
         * You can set a list of Mina IoFilters to use.
         * 
         * The option will be converted to a
         * <code>java.util.List&lt;org.apache.mina.core.filterchain.IoFilter&gt;</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder filters(String filters) {
            doSetProperty("filters", filters);
            return this;
        }
        /**
         * Only used for TCP. If no codec is specified, you can use this flag to
         * indicate a text line based codec; if not specified or the value is
         * false, then Object Serialization is assumed over TCP.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder textline(boolean textline) {
            doSetProperty("textline", textline);
            return this;
        }
        /**
         * Only used for TCP. If no codec is specified, you can use this flag to
         * indicate a text line based codec; if not specified or the value is
         * false, then Object Serialization is assumed over TCP.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder textline(String textline) {
            doSetProperty("textline", textline);
            return this;
        }
        /**
         * Only used for TCP and if textline=true. Sets the text line delimiter
         * to use. If none provided, Camel will use DEFAULT. This delimiter is
         * used to mark the end of text.
         * 
         * The option is a:
         * <code>org.apache.camel.component.mina.MinaTextLineDelimiter</code>
         * type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder textlineDelimiter(
                MinaTextLineDelimiter textlineDelimiter) {
            doSetProperty("textlineDelimiter", textlineDelimiter);
            return this;
        }
        /**
         * Only used for TCP and if textline=true. Sets the text line delimiter
         * to use. If none provided, Camel will use DEFAULT. This delimiter is
         * used to mark the end of text.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.mina.MinaTextLineDelimiter</code>
         * type.
         * 
         * Group: codec
         */
        default MinaEndpointBuilder textlineDelimiter(String textlineDelimiter) {
            doSetProperty("textlineDelimiter", textlineDelimiter);
            return this;
        }
        /**
         * Whether to auto start SSL handshake.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default MinaEndpointBuilder autoStartTls(boolean autoStartTls) {
            doSetProperty("autoStartTls", autoStartTls);
            return this;
        }
        /**
         * Whether to auto start SSL handshake.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default MinaEndpointBuilder autoStartTls(String autoStartTls) {
            doSetProperty("autoStartTls", autoStartTls);
            return this;
        }
        /**
         * To configure SSL security.
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MinaEndpointBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * To configure SSL security.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: security
         */
        default MinaEndpointBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the Mina component.
     */
    public interface AdvancedMinaEndpointBuilder
            extends
                AdvancedMinaEndpointConsumerBuilder, AdvancedMinaEndpointProducerBuilder {
        default MinaEndpointBuilder basic() {
            return (MinaEndpointBuilder) 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 AdvancedMinaEndpointBuilder 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 AdvancedMinaEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Number of worker threads in the worker pool for TCP and UDP.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointBuilder maximumPoolSize(int maximumPoolSize) {
            doSetProperty("maximumPoolSize", maximumPoolSize);
            return this;
        }
        /**
         * Number of worker threads in the worker pool for TCP and UDP.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointBuilder maximumPoolSize(
                String maximumPoolSize) {
            doSetProperty("maximumPoolSize", maximumPoolSize);
            return this;
        }
        /**
         * Whether to use ordered thread pool, to ensure events are processed
         * orderly on the same channel.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointBuilder orderedThreadPoolExecutor(
                boolean orderedThreadPoolExecutor) {
            doSetProperty("orderedThreadPoolExecutor", orderedThreadPoolExecutor);
            return this;
        }
        /**
         * Whether to use ordered thread pool, to ensure events are processed
         * orderly on the same channel.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointBuilder orderedThreadPoolExecutor(
                String orderedThreadPoolExecutor) {
            doSetProperty("orderedThreadPoolExecutor", orderedThreadPoolExecutor);
            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 AdvancedMinaEndpointBuilder 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 AdvancedMinaEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Only used for TCP. You can transfer the exchange over the wire
         * instead of just the body. The following fields are transferred: In
         * body, Out body, fault body, In headers, Out headers, fault headers,
         * exchange properties, exchange exception. This requires that the
         * objects are serializable. Camel will exclude any non-serializable
         * objects and log it at WARN level.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointBuilder transferExchange(
                boolean transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
        /**
         * Only used for TCP. You can transfer the exchange over the wire
         * instead of just the body. The following fields are transferred: In
         * body, Out body, fault body, In headers, Out headers, fault headers,
         * exchange properties, exchange exception. This requires that the
         * objects are serializable. Camel will exclude any non-serializable
         * objects and log it at WARN level.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedMinaEndpointBuilder transferExchange(
                String transferExchange) {
            doSetProperty("transferExchange", transferExchange);
            return this;
        }
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.mina.MinaTextLineDelimiter</code> enum.
     */
    enum MinaTextLineDelimiter {
        DEFAULT,
        AUTO,
        UNIX,
        WINDOWS,
        MAC;
    }
    /**
     * Mina (camel-mina)
     * Socket level networking using TCP or UDP with the Apache Mina 2.x
     * library.
     * 
     * Category: networking,tcp,udp
     * Since: 2.10
     * Maven coordinates: org.apache.camel:camel-mina
     * 
     * Syntax: <code>mina:protocol:host:port</code>
     * 
     * Path parameter: protocol (required)
     * Protocol to use
     * 
     * Path parameter: host (required)
     * Hostname to use. Use localhost or 0.0.0.0 for local server as consumer.
     * For producer use the hostname or ip address of the remote server.
     * 
     * Path parameter: port (required)
     * Port number
     */
    default MinaEndpointBuilder mina(String path) {
        class MinaEndpointBuilderImpl extends AbstractEndpointBuilder implements MinaEndpointBuilder, AdvancedMinaEndpointBuilder {
            public MinaEndpointBuilderImpl(String path) {
                super("mina", path);
            }
        }
        return new MinaEndpointBuilderImpl(path);
    }
}