CAMEL-14064: Add missing language docs from camel-base to tooling
diff --git a/docs/components/modules/ROOT/pages/constant-language.adoc b/docs/components/modules/ROOT/pages/constant-language.adoc
new file mode 100644
index 0000000..a0b600d
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/constant-language.adoc
@@ -0,0 +1,72 @@
+[[constant-language]]
+= Constant Language
+:page-source: core/camel-base/src/main/docs/constant-language.adoc
+
+*Available as of Camel version 1.5*
+
+The Constant Expression Language is really just a way to specify
+constant strings as a type of expression.
+
+NOTE: This is a fixed constant value that is only set once during starting up the route,
+      do not use this if you want dynamic values during routing.
+
+== Constant Options
+
+
+// language options: START
+The Constant language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+
+== Example usage
+
+The setHeader element of the Spring DSL can utilize a constant
+expression like:
+
+[source,xml]
+----
+<route>
+  <from uri="seda:a"/>
+  <setHeader name="theHeader">
+    <constant>the value</constant>
+  </setHeader>
+  <to uri="mock:b"/>
+</route>
+----
+
+in this case, the Message coming from the seda:a
+Endpoint will have 'theHeader' header set to the
+constant value 'the value'.
+
+And the same example using Java DSL:
+
+[source,java]
+----
+from("seda:a")
+  .setHeader("theHeader", constant("the value"))
+  .to("mock:b");
+----
+
+== Loading constant from external resource
+
+You can externalize the constant and have Camel load it from a resource
+such as `"classpath:"`, `"file:"`, or `"http:"`. +
+ This is done using the following syntax: `"resource:scheme:location"`,
+eg to refer to a file on the classpath you can do:
+
+[source,java]
+----
+.setHeader("myHeader").constant("resource:classpath:constant.txt")
+----
+
+== Dependencies
+
+The Constant language is part of *camel-core*.
\ No newline at end of file
diff --git a/docs/components/modules/ROOT/pages/exchangeProperty-language.adoc b/docs/components/modules/ROOT/pages/exchangeProperty-language.adoc
new file mode 100644
index 0000000..9f5645e
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/exchangeProperty-language.adoc
@@ -0,0 +1,61 @@
+[[exchangeProperty-language]]
+= ExchangeProperty Language
+:page-source: core/camel-base/src/main/docs/exchangeProperty-language.adoc
+
+*Available as of Camel version 2.0*
+
+The ExchangeProperty Expression Language allows you to extract values of
+named exchange properties.
+
+== Exchange Property Options
+
+// language options: START
+The ExchangeProperty language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+== Example usage
+
+The recipientList element of the Spring DSL can utilize a
+exchangeProperty expression like:
+
+In this case, the list of recipients are contained in the property
+'myProperty'.
+
+[source,xml]
+----
+<route>
+  <from uri="direct:a" />
+  <recipientList>
+    <exchangeProperty>myProperty</exchangeProperty>
+  </recipientList>
+</route>
+----
+
+And the same example in Java DSL:
+
+[source,java]
+----
+from("direct:a").recipientList(exchangeProperty("myProperty"));
+----
+
+And with a slightly different syntax where you use the builder to the
+fullest (i.e. avoid using parameters but using stacked operations,
+notice that exchangeProperty is not a parameter but a stacked method
+call)
+
+[source,java]
+----
+from("direct:a").recipientList().exchangeProperty("myProperty");
+----
+
+== Dependencies
+
+The ExchangeProperty language is part of *camel-core*.
\ No newline at end of file
diff --git a/docs/components/modules/ROOT/pages/file-language.adoc b/docs/components/modules/ROOT/pages/file-language.adoc
new file mode 100644
index 0000000..ddc7cb3
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/file-language.adoc
@@ -0,0 +1,295 @@
+[[file-language]]
+= File Language
+:page-source: core/camel-base/src/main/docs/file-language.adoc
+
+*Available as of Camel version 1.1*
+
+The file language is merged with
+xref:simple-language.adoc[Simple] language which means you can use all the file
+syntax directly within the simple language.
+
+The File Expression Language is an extension to the
+xref:simple-language.adoc[Simple] language, adding file related capabilities.
+These capabilities are related to common use cases working with file
+path and names. The goal is to allow expressions to be used with the
+File and FTP components for setting
+dynamic file patterns for both consumer and producer.
+
+== File Language options
+
+// language options: START
+The File language supports 2 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| resultType |  | String | Sets the class name of the result type (type from output)
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+== Syntax
+
+This language is an *extension* to the xref:simple-language.adoc[Simple] language
+so the xref:simple-language.adoc[Simple] syntax applies also. So the table below
+only lists the additional.  +
+ As opposed to xref:simple-language.adoc[Simple] language
+xref:file-language.adoc[File Language] also supports
+xref:constant-language.adoc[Constant] expressions so you can enter a fixed
+filename.
+
+All the file tokens use the same expression name as the method on the
+`java.io.File` object, for instance `file:absolute` refers to the
+`java.io.File.getAbsolute()` method. Notice that not all expressions are
+supported by the current Exchange. For instance the xref:components::ftp-component.adoc[FTP]
+component supports some of the options, where as the
+File component supports all of them.
+
+
+[width="100%",cols="10%,10%,10%,10%,10%,25%,25%",options="header",]
+|===
+|Expression |Type |File Consumer |File Producer |FTP Consumer |FTP Producer |Description
+
+|file:name |String |yes |no |yes |no |refers to the file name (is relative to the starting directory, see note
+below)
+
+|file:name.ext |String |yes |no |yes |no |refers to the file extension only
+
+|file:name.ext.single |String |yes |no |yes |no |refers to the file extension. If the file
+extension has mutiple dots, then this expression strips and only returns
+the last part.
+
+|file:name.noext |String |yes |no |yes |no |refers to the file name with no extension (is relative to the starting
+directory, see note below)
+
+|file:name.noext.single |String |yes |no |yes |no |refers to the file name with no extension (is
+relative to the starting directory, see note below). If the file
+extension has multiple dots, then this expression strips only the last
+part, and keep the others.
+
+|file:onlyname |String |yes |no |yes |no |refers to the file name only with no leading paths.
+
+|file:onlyname.noext |String |yes |no |yes |no |refers to the file name only with no extension and with no leading
+paths.
+
+|file:onlyname.noext.single |String |yes |no |yes |no |refers to the file name only with no extension and
+with no leading paths. If the file extension has multiple dots, then
+this expression strips only the last part, and keep the others.
+
+|file:ext |String |yes |no |yes |no |refers to the file extension only
+
+|file:parent |String |yes |no |yes |no |refers to the file parent
+
+|file:path |String |yes |no |yes |no |refers to the file path
+
+|file:absolute |Boolean |yes |no |no |no |refers to whether the file is regarded as absolute or relative
+
+|file:absolute.path |String |yes |no |no |no |refers to the absolute file path
+
+|file:length |Long |yes |no |yes |no |refers to the file length returned as a Long type
+
+|file:size |Long |yes |no |yes |no |refers to the file length returned as a Long type
+
+|file:modified |Date |yes |no |yes |no |Refers to the file last modified returned as a Date type
+
+|date:_command:pattern_ |String |yes |yes |yes |yes |for date formatting using the `java.text.SimpleDateFormat` patterns. Is
+an *extension* to the xref:simple-language.adoc[Simple] language. Additional
+command is: *file* (consumers only) for the last modified timestamp of
+the file. Notice: all the commands from the xref:simple-language.adoc[Simple]
+language can also be used.
+|===
+
+== File token example
+
+=== Relative paths
+
+We have a `java.io.File` handle for the file `hello.txt` in the
+following *relative* directory: `.\filelanguage\test`. And we configure
+our endpoint to use this starting directory `.\filelanguage`. The file
+tokens will return as:
+
+[width="100%",cols="50%,50%",options="header",]
+|===
+|Expression |Returns
+
+|file:name |test\hello.txt
+
+|file:name.ext |txt
+
+|file:name.noext |test\hello
+
+|file:onlyname |hello.txt
+
+|file:onlyname.noext |hello
+
+|file:ext |txt
+
+|file:parent |filelanguage\test
+
+|file:path |filelanguage\test\hello.txt
+
+|file:absolute |false
+
+|file:absolute.path |\workspace\camel\camel-core\target\filelanguage\test\hello.txt
+|===
+
+=== Absolute paths
+
+We have a `java.io.File` handle for the file `hello.txt` in the
+following *absolute* directory:
+`\workspace\camel\camel-core\target\filelanguage\test`. And we configure
+out endpoint to use the absolute starting directory
+`\workspace\camel\camel-core\target\filelanguage`. The file tokens will
+return as:
+
+[width="100%",cols="50%,50%",options="header",]
+|===
+|Expression |Returns
+
+|file:name |test\hello.txt 
+
+|file:name.ext |txt
+
+|file:name.noext |test\hello
+
+|file:onlyname |hello.txt
+
+|file:onlyname.noext |hello
+
+|file:ext |txt
+
+|file:parent |\workspace\camel\camel-core\target\filelanguage\test
+
+|file:path |\workspace\camel\camel-core\target\filelanguage\test\hello.txt
+
+|file:absolute |true
+
+|file:absolute.path |\workspace\camel\camel-core\target\filelanguage\test\hello.txt
+|===
+
+== Samples
+
+You can enter a fixed xref:constant-language.adoc[Constant] expression such as
+`myfile.txt`:
+
+[source]
+----
+fileName="myfile.txt"
+----
+
+Lets assume we use the file consumer to read files and want to move the
+read files to backup folder with the current date as a sub folder. This
+can be archieved using an expression like:
+
+[source]
+----
+fileName="backup/${date:now:yyyyMMdd}/${file:name.noext}.bak"
+----
+
+relative folder names are also supported so suppose the backup folder
+should be a sibling folder then you can append .. as:
+
+[source]
+----
+fileName="../backup/${date:now:yyyyMMdd}/${file:name.noext}.bak"
+----
+
+As this is an extension to the xref:simple-language.adoc[Simple] language we have
+access to all the goodies from this language also, so in this use case
+we want to use the in.header.type as a parameter in the dynamic
+expression:
+
+[source]
+----
+fileName="../backup/${date:now:yyyyMMdd}/type-${in.header.type}/backup-of-${file:name.noext}.bak"
+----
+
+If you have a custom Date you want to use in the expression then Camel
+supports retrieving dates from the message header.
+
+[source]
+----
+fileName="orders/order-${in.header.customerId}-${date:in.header.orderDate:yyyyMMdd}.xml"
+----
+
+And finally we can also use a bean expression to invoke a POJO class
+that generates some String output (or convertible to String) to be used:
+
+[source]
+----
+fileName="uniquefile-${bean:myguidgenerator.generateid}.txt"
+----
+
+And of course all this can be combined in one expression where you can
+use the xref:file-language.adoc[File Language], xref:file-language.adoc[Simple]
+and the xref:components::bean-component.adoc[Bean] language in one combined expression. This
+is pretty powerful for those common file path patterns.
+
+== Using Spring PropertyPlaceholderConfigurer together with the File component
+
+In Camel you can use the xref:file-language.adoc[File Language] directly
+from the xref:simple-language.adoc[Simple] language which makes a
+Content Based Router easier to do in
+Spring XML, where we can route based on file extensions as shown below:
+
+[source,xml]
+----
+<from uri="file://input/orders"/>
+   <choice>
+     <when>
+         <simple>${file:ext} == 'txt'</simple>
+         <to uri="bean:orderService?method=handleTextFiles"/>
+     </when>
+     <when>
+         <simple>${file:ext} == 'xml'</simple>
+         <to uri="bean:orderService?method=handleXmlFiles"/>
+     </when>
+     <otherwise>
+         <to uri="bean:orderService?method=handleOtherFiles"/>
+     </otherwise>
+  </choice>
+----
+
+If you use the `fileName` option on the File endpoint
+to set a dynamic filename using the xref:file-language.adoc[File Language] then make sure you  +
+ use the alternative syntax to avoid
+clashing with Springs `PropertyPlaceholderConfigurer`.
+
+*bundle-context.xml*
+
+[source,xml]
+----
+<bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+    <property name="location" value="classpath:bundle-context.cfg" />
+</bean>
+
+<bean id="sampleRoute" class="SampleRoute">
+    <property name="fromEndpoint" value="${fromEndpoint}" />
+    <property name="toEndpoint" value="${toEndpoint}" />
+</bean>
+----
+
+*bundle-context.cfg*
+
+[source]
+----
+fromEndpoint=activemq:queue:test
+toEndpoint=file://fileRoute/out?fileName=test-$simple{date:now:yyyyMMdd}.txt
+----
+
+Notice how we use the $simple\{ } syntax in the `toEndpoint` above. +
+ If you don't do this, there is a clash and Spring will throw an
+exception like
+
+[source,java]
+----------------------------------------------------------------------------------------------------
+org.springframework.beans.factory.BeanDefinitionStoreException:
+Invalid bean definition with name 'sampleRoute' defined in class path resource [bundle-context.xml]:
+Could not resolve placeholder 'date:now:yyyyMMdd'
+----------------------------------------------------------------------------------------------------
+
+== Dependencies
+
+The File language is part of *camel-core*.
diff --git a/docs/components/modules/ROOT/pages/header-language.adoc b/docs/components/modules/ROOT/pages/header-language.adoc
new file mode 100644
index 0000000..a855648
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/header-language.adoc
@@ -0,0 +1,45 @@
+[[header-language]]
+= Header Language
+:page-source: core/camel-base/src/main/docs/header-language.adoc
+
+*Available as of Camel version 1.5*
+
+The Header Expression Language allows you to extract values of named
+headers.
+
+== Header Options
+
+// language options: START
+The Header language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+== Example usage
+
+The recipientList element of the Spring DSL can utilize a header
+expression like:
+
+In this case, the list of recipients are contained in the header
+'myHeader'.
+
+And the same example in Java DSL:
+
+And with a slightly different syntax where you use the builder to the
+fullest (i.e. avoid using parameters but using stacked operations,
+notice that header is not a parameter but a stacked method call)
+
+[source,java]
+----
+from("direct:a").recipientList().header("myHeader");
+----
+
+== Dependencies
+
+The Header language is part of *camel-core*.
\ No newline at end of file
diff --git a/docs/components/modules/ROOT/pages/ref-language.adoc b/docs/components/modules/ROOT/pages/ref-language.adoc
new file mode 100644
index 0000000..4cdd314
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/ref-language.adoc
@@ -0,0 +1,58 @@
+[[ref-language]]
+= Ref Language
+:page-source: core/camel-base/src/main/docs/ref-language.adoc
+
+*Available as of Camel version 2.8*
+
+The Ref Expression Language is really just a way to lookup a custom
+Expression or Predicate from the Registry.
+
+This is particular useable in XML DSLs.
+
+== Ref Language options
+
+// language options: START
+The Ref language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+== Example usage
+
+The Splitter in XML DSL can utilize a custom
+expression using `<ref>` like:
+
+[source,xml]
+----
+<bean id="myExpression" class="com.mycompany.MyCustomExpression"/>
+
+<route>
+  <from uri="seda:a"/>
+  <split>
+    <ref>myExpression</ref>   
+    <to uri="mock:b"/>
+  </split>     
+</route>
+----
+
+in this case, the Message coming from the seda:a
+Endpoint will be splitted using a custom
+Expression which has the id `myExpression` in the
+Registry.
+
+And the same example using Java DSL:
+
+[source,java]
+----
+from("seda:a").split().ref("myExpression").to("seda:b");
+----
+
+== Dependencies
+
+The Ref language is part of *camel-core*.
\ No newline at end of file
diff --git a/docs/components/modules/ROOT/pages/simple-language.adoc b/docs/components/modules/ROOT/pages/simple-language.adoc
new file mode 100644
index 0000000..5ce16e6
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/simple-language.adoc
@@ -0,0 +1,878 @@
+[[simple-language]]
+= Simple Language
+:page-source: core/camel-base/src/main/docs/simple-language.adoc
+
+*Available as of Camel version 1.1*
+
+The Simple Expression Language was a really simple language when it was
+created, but has since grown more powerful. It is primarily intended for
+being a really small and simple language for evaluating
+Expressions and Predicates
+without requiring any new dependencies or knowledge of
+xref:components::xpath-language.adoc[XPath]; so it is ideal for testing in camel-core. The
+idea was to cover 95% of the common use cases when you need a little bit
+of expression based script in your Camel routes.
+
+However for much more complex use cases you are generally recommended to
+choose a more expressive and powerful language such as:
+
+* xref:components::groovy-language.adoc[Groovy]
+* xref:components::spel-language.adoc[SpEL]
+* xref:components::mvel-component.adoc[MVEL]
+* xref:components::ognl-language.adoc[OGNL]
+
+The simple language uses `${body`} placeholders for complex expressions
+where the expression contains constant literals. The $\{ } placeholders
+can be omitted if the expression is only the token itself.
+
+TIP: *Alternative syntax* You can also use the alternative syntax which
+uses `$simple{ }` as placeholders. This can be used in situations to avoid clashes when using for example
+Spring property placeholder together with Camel.
+
+
+== Simple Language options
+
+// language options: START
+The Simple language supports 2 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| resultType |  | String | Sets the class name of the result type (type from output)
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+== Variables
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Variable |Type |Description
+
+|camelId |String |the CamelContext name
+
+|camelContext.*OGNL* |Object |the CamelContext invoked using a Camel OGNL expression.
+
+|exchange |Exchange |the Exchange
+
+|exchange.*OGNL* |Object |the Exchange invoked using a Camel
+OGNL expression.
+
+|exchangeId |String |the exchange id
+
+|id |String |the input message id
+
+|body |Object |the input body
+
+|in.body |Object |*deprecated* the input body
+
+|body.*OGNL* |Object |the input body invoked using a Camel OGNL expression.
+
+|in.body.*OGNL* |Object |*deprecated* the input body invoked using a Camel OGNL expression.
+
+|bodyAs(_type_) |Type |Converts the body to the given type determined by its
+classname. The converted body can be null.
+
+|bodyAs(_type_).*OGNL* |Object |Converts the body to the given type determined by its
+classname and then invoke methods using a Camel OGNL expression. The
+converted body can be null.
+
+|bodyOneLine | String | Converts the body to a String and removes all line-breaks so the string is in one line.
+
+|mandatoryBodyAs(_type_) |Type |Converts the body to the given type determined by its
+classname, and expects the body to be not null.
+
+|mandatoryBodyAs(_type_).*OGNL* |Object |Converts the body to the given type determined by its
+classname and then invoke methods using a Camel OGNL expression.
+
+|header.foo |Object |refer to the input foo header
+
+|header:foo |Object |refer to the input foo header
+
+|header[foo] |Object |refer to the input foo header
+
+|headers.foo |Object |refer to the input foo header
+
+|headers:foo |Object |refer to the input foo header
+
+|headers[foo] |Object |refer to the input foo header
+
+|in.header.foo |Object |*deprecated* refer to the input foo header
+
+|in.header:foo |Object |*deprecated* refer to the input foo header
+
+|in.header[foo] |Object |*deprecated* refer to the input foo header
+
+|in.headers.foo |Object |*deprecated* refer to the input foo header
+
+|in.headers:foo |Object |*deprecated* refer to the input foo header
+
+|in.headers[foo] |Object |*deprecated* refer to the input foo header
+
+|header.foo[bar] |Object |regard input foo header as a map and perform lookup on the
+map with bar as key
+
+|in.header.foo[bar] |Object |*deprecated* regard input foo header as a map and perform lookup on the
+map with bar as key
+
+|in.headers.foo[bar] |Object |*deprecated* regard input foo header as a map and perform lookup on the
+map with bar as key
+
+|header.foo.*OGNL* |Object |refer to the input foo header and invoke its value using a
+Camel OGNL expression.
+
+|in.header.foo.*OGNL* |Object |*deprecated* refer to the input foo header and invoke its value using a
+Camel OGNL expression.
+
+|in.headers.foo.*OGNL* |Object |*deprecated* refer to the input foo header and invoke its value using a
+Camel OGNL expression.
+
+|headerAs(_key_,_type_) |Type |converts the header to the given type determined by its
+classname
+
+|headers |Map |refer to the input headers
+
+|in.headers |Map |*deprecated* refer to the input headers
+
+|exchangeProperty.foo |Object |refer to the foo property on the exchange
+
+|exchangeProperty[foo] |Object |refer to the foo property on the exchange
+
+|exchangeProperty.foo.*OGNL* |Object |refer to the foo property on the exchange and invoke its
+value using a Camel OGNL expression.
+
+|sys.foo |String |refer to the JVM system property
+
+|sysenv.foo |String |refer to the system environment variable
+
+|env.foo |String |refer to the system environment variable
+
+|exception |Object |refer to the exception object on the exchange, is *null* if
+no exception set on exchange. Will fallback and grab caught exceptions
+(`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.
+
+|exception.*OGNL* |Object |refer to the exchange exception invoked using a Camel OGNL
+expression object
+
+|exception.message |String |refer to the exception.message on the exchange, is *null* if no
+exception set on exchange. Will fallback and grab caught exceptions
+(`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.
+
+|exception.stacktrace |String |refer to the exception.stracktrace on the exchange, is
+*null* if no exception set on exchange. Will fallback and grab caught
+exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any.
+
+|date:_command_ |Date |evaluates to a Date object.
+Supported commands are: *now* for current timestamp, *in.header.xxx* or
+*header.xxx* to use the Date object header with the key xxx.
+*exchangeProperty.xxx* to use the Date object in the exchange property with the key xxx.
+*file* for the last modified timestamp of the file (available with a File consumer).
+Command accepts offsets such as: *now-24h* or *in.header.xxx+1h* or even *now+1h30m-100*.
+
+|date:_command:pattern_ |String |Date formatting using `java.text.SimpleDataFormat` patterns.
+
+|date-with-timezone:_command:timezone:pattern_ |String |Date formatting using `java.text.SimpleDataFormat` timezones and patterns.
+
+|bean:_bean expression_ |Object |Invoking a bean expression using the xref:components::bean-component.adoc[Bean] language.
+Specifying a method name you must use dot as separator. We also support
+the ?method=methodname syntax that is used by the xref:components::bean-component.adoc[Bean]
+component.
+
+|`properties:key:default` |String |Lookup a property with the given key. If the key does
+not exists or has no value, then an optional default value can be
+specified.
+
+|routeId |String |Returns the id of the current route the
+Exchange is being routed.
+
+|stepId |String |Returns the id of the current step the
+Exchange is being routed.
+
+|threadName |String |Returns the name of the current thread. Can be used for
+logging purpose.
+
+|ref:xxx |Object |To lookup a bean from the Registry with
+the given id.
+
+|type:name.field |Object |To refer to a type or field by its FQN name. To refer to a
+field you can append .FIELD_NAME. For example you can refer to the
+constant field from Exchange as: `org.apache.camel.Exchange.FILE_NAME`
+
+|null |null |represents a *null*
+
+|random_(value)_ |Integer |returns a random Integer between 0 (included) and _value_
+(excluded)
+
+|random_(min,max)_ |Integer |returns a random Integer between _min_ (included) and
+_max_ (excluded)
+
+|collate(group) |List |The collate function iterates the message body and groups
+the data into sub lists of specified size. This can be used with the
+Splitter EIP to split a message body and group/batch
+the splitted sub message into a group of N sub lists. This method works
+similar to the collate method in Groovy.
+
+|skip(number) |Iterator |The skip function iterates the message body and skips
+the first number of items. This can be used with the
+Splitter EIP to split a message body and skip the first N number of items.
+
+|messageHistory |String |The message history of the current exchange how it has
+been routed. This is similar to the route stack-trace message history
+the error handler logs in case of an unhandled exception.
+
+|messageHistory(false) |String |As messageHistory but without the exchange details (only
+includes the route strack-trace). This can be used if you do not want to
+log sensitive data from the message itself.
+|=======================================================================
+
+== OGNL expression support
+
+INFO:Camel's OGNL support is for invoking methods only. You cannot access
+fields. Camel support accessing the length field of Java arrays.
+
+
+The xref:simple-language.adoc[Simple] and xref:simple-language.adoc[Bean] language now
+supports a Camel OGNL notation for invoking beans in a chain like
+fashion. Suppose the Message IN body contains a POJO which has a `getAddress()`
+method.
+
+Then you can use Camel OGNL notation to access the address object:
+
+[source,java]
+--------------------------------
+simple("${body.address}")
+simple("${body.address.street}")
+simple("${body.address.zip}")
+--------------------------------
+
+Camel understands the shorthand names for getters, but you can invoke
+any method or use the real name such as:
+
+[source,java]
+--------------------------------------
+simple("${body.address}")
+simple("${body.getAddress.getStreet}")
+simple("${body.address.getZip}")
+simple("${body.doSomething}")
+--------------------------------------
+
+You can also use the null safe operator (`?.`) to avoid NPE if for
+example the body does NOT have an address
+
+[source,java]
+----------------------------------
+simple("${body?.address?.street}")
+----------------------------------
+
+It is also possible to index in `Map` or `List` types, so you can do:
+
+[source,java]
+---------------------------
+simple("${body[foo].name}")
+---------------------------
+
+To assume the body is `Map` based and lookup the value with `foo` as
+key, and invoke the `getName` method on that value.
+
+If the key has space, then you *must* enclose the key with quotes, for
+example 'foo bar':
+
+[source,java]
+---------------------------------
+simple("${body['foo bar'].name}")
+---------------------------------
+
+You can access the `Map` or `List` objects directly using their key name
+(with or without dots) :
+
+[source,java]
+------------------------------
+simple("${body[foo]}")
+simple("${body[this.is.foo]}")
+------------------------------
+
+Suppose there was no value with the key `foo` then you can use the null
+safe operator to avoid the NPE as shown:
+
+[source,java]
+----------------------------
+simple("${body[foo]?.name}")
+----------------------------
+
+You can also access `List` types, for example to get lines from the
+address you can do:
+
+[source,java]
+----------------------------------
+simple("${body.address.lines[0]}")
+simple("${body.address.lines[1]}")
+simple("${body.address.lines[2]}")
+----------------------------------
+
+There is a special `last` keyword which can be used to get the last
+value from a list.
+
+[source,java]
+-------------------------------------
+simple("${body.address.lines[last]}")
+-------------------------------------
+
+And to get the 2nd last you can subtract a number, so we can use
+`last-1` to indicate this:
+
+[source,java]
+---------------------------------------
+simple("${body.address.lines[last-1]}")
+---------------------------------------
+
+And the 3rd last is of course:
+
+[source,java]
+---------------------------------------
+simple("${body.address.lines[last-2]}")
+---------------------------------------
+
+And you can call the size method on the list with
+
+[source,java]
+------------------------------------
+simple("${body.address.lines.size}")
+------------------------------------
+
+Camel supports the length field for Java arrays as well, eg:
+
+[source,java]
+---------------------------------------------------
+String[] lines = new String[]{"foo", "bar", "cat"};
+exchange.getIn().setBody(lines);
+
+simple("There are ${body.length} lines")
+---------------------------------------------------
+
+And yes you can combine this with the operator support as shown below:
+
+[source,java]
+------------------------------------
+simple("${body.address.zip} > 1000")
+------------------------------------
+
+== Operator support
+
+The parser is limited to only support a single operator.
+
+To enable it the left value must be enclosed in $\{ }. The syntax is:
+
+[source]
+--------------------------
+${leftValue} OP rightValue
+--------------------------
+
+Where the `rightValue` can be a String literal enclosed in `' '`,
+`null`, a constant value or another expression enclosed in $\{ }.
+
+IMPORTANT: There *must* be spaces around the operator.
+
+Camel will automatically type convert the rightValue type to the
+leftValue type, so it is able to eg. convert a string into a numeric so
+you can use > comparison for numeric values.
+
+The following operators are supported:
+
+[width="100%",cols="50%,50%",options="header",]
+|===
+|Operator |Description
+
+|== |equals
+
+|=~ |equals ignore case (will ignore case when comparing String values)
+
+|> |greater than
+
+|>= |greater than or equals
+
+|< |less than
+
+|<= |less than or equals
+
+|!=~ |not equals
+
+|!=~ |not equals ignore case (will ignore case when comparing String values)
+
+|contains |For testing if contains in a string based value
+
+|!contains |For testing if not contains in a string based value
+
+|~~ |For testing if contains by ignoring case sensitivity in a string based value
+
+|!~~ |For testing if not contains by ignoring case sensitivity in a string based value
+
+|regex |For matching against a given regular expression pattern defined as a
+String value
+
+|!regex |For not matching against a given regular expression pattern defined as a
+String value
+
+|in |For matching if in a set of values, each element must be separated by
+comma. If you want to include an empty value, then it must be defined using double comma, eg ',,bronze,silver,gold', which
+is a set of four values with an empty value and then the three medals.
+
+|!in |For matching if not in a set of values, each element must be separated
+by comma. If you want to include an empty value, then it must be defined using double comma, eg ',,bronze,silver,gold', which
+is a set of four values with an empty value and then the three medals.
+
+|is |For matching if the left hand side type is an instanceof the value.
+
+|!is |For matching if the left hand side type is not an instanceof the value.
+
+|range |For matching if the left hand side is within a range of values defined
+as numbers: `from..to`..
+
+|!range |For matching if the left hand side is not within a range of values
+defined as numbers: `from..to`. .
+
+|startsWith |For testing if the left hand side string starts
+with the right hand string.
+
+|endsWith |For testing if the left hand side string ends with
+the right hand string.
+|===
+
+And the following unary operators can be used:
+
+[width="100%",cols="50%,50%",options="header",]
+|===
+|Operator |Description
+
+|++ |To increment a number by one. The left hand side must be a
+function, otherwise parsed as literal.
+
+|-- |To decrement a number by one. The left hand side must be a
+function, otherwise parsed as literal.
+
+|\ |To escape a value, eg \$, to indicate a $ sign.
+Special: Use \n for new line, \t for tab, and \r for carriage return.
+*Notice:* Escaping is *not* supported using the
+xref:file-language.adoc[File Language]. *Notice:* The escape character is not supported, use the
+following three special escaping instead.
+
+|\n |To use newline character.
+
+|\t |To use tab character.
+
+|\r |To use carriage return character.
+
+|\} |To use the } character as text
+|===
+
+And the following logical operators can be used to group expressions:
+
+[width="100%",cols="50%,50%",options="header",]
+|===
+|Operator |Description
+
+|&& |The logical and operator is used to group two expressions.
+
+| \|\| |The logical or operator is used to group two expressions.
+|===
+
+The syntax for AND is:
+
+[source]
+----------------------------------------------------------
+${leftValue} OP rightValue && ${leftValue} OP rightValue
+----------------------------------------------------------
+
+And the syntax for OR is:
+
+[source]
+---------------------------------------------------------
+${leftValue} OP rightValue || ${leftValue} OP rightValue
+---------------------------------------------------------
+
+Some examples:
+
+[source,java]
+----
+// exact equals match
+simple("${in.header.foo} == 'foo'")
+
+// ignore case when comparing, so if the header has value FOO this will match
+simple("${in.header.foo} =~ 'foo'")
+
+// here Camel will type convert '100' into the type of in.header.bar and if it is an Integer '100' will also be converter to an Integer
+simple("${in.header.bar} == '100'")
+
+simple("${in.header.bar} == 100")
+
+// 100 will be converter to the type of in.header.bar so we can do > comparison
+simple("${in.header.bar} > 100")
+----
+
+=== Comparing with different types
+
+When you compare with different types such as String and int, then you
+have to take a bit care. Camel will use the type from the left hand side
+as 1st priority. And fallback to the right hand side type if both values
+couldn't be compared based on that type. +
+ This means you can flip the values to enforce a specific type. Suppose
+the bar value above is a String. Then you can flip the equation:
+
+[source,java]
+----
+simple("100 < ${in.header.bar}")
+----
+
+which then ensures the int type is used as 1st priority.
+
+This may change in the future if the Camel team improves the binary
+comparison operations to prefer numeric types over String based. It's
+most often the String type which causes problem when comparing with
+numbers.
+
+[source,java]
+----
+// testing for null
+simple("${in.header.baz} == null")
+
+// testing for not null
+simple("${in.header.baz} != null")
+----
+
+And a bit more advanced example where the right value is another
+expression
+
+[source,java]
+----
+simple("${in.header.date} == ${date:now:yyyyMMdd}")
+
+simple("${in.header.type} == ${bean:orderService?method=getOrderType}")
+----
+
+And an example with contains, testing if the title contains the word
+Camel
+
+[source,java]
+----
+simple("${in.header.title} contains 'Camel'")
+----
+
+And an example with regex, testing if the number header is a 4 digit
+value:
+
+[source,java]
+----
+simple("${in.header.number} regex '\\d{4}'")
+----
+
+And finally an example if the header equals any of the values in the
+list. Each element must be separated by comma, and no space around. +
+ This also works for numbers etc, as Camel will convert each element
+into the type of the left hand side.
+
+[source,java]
+----
+simple("${in.header.type} in 'gold,silver'")
+----
+
+And for all the last 3 we also support the negate test using not:
+
+[source,java]
+----
+simple("${in.header.type} !in 'gold,silver'")
+----
+
+And you can test if the type is a certain instance, eg for instance a
+String
+
+[source,java]
+----
+simple("${in.header.type} is 'java.lang.String'")
+----
+
+We have added a shorthand for all `java.lang` types so you can write it
+as:
+
+[source,java]
+----
+simple("${in.header.type} is 'String'")
+----
+
+Ranges are also supported. The range interval requires numbers and both
+from and end are inclusive. For instance to test whether a value is
+between 100 and 199:
+
+[source,java]
+----
+simple("${in.header.number} range 100..199")
+----
+
+Notice we use `..` in the range without spaces. It is based on the same
+syntax as Groovy.
+
+From *Camel 2.9* onwards the range value must be in single quotes
+
+[source,java]
+----
+simple("${in.header.number} range '100..199'")
+----
+
+=== Using Spring XML
+
+As the Spring XML does not have all the power as the Java DSL with all
+its various builder methods, you have to resort to use some other
+languages for testing with simple operators. Now you can do this with the simple
+language. In the sample below we want to test if the header is a widget
+order:
+
+[source,xml]
+----
+<from uri="seda:orders">
+   <filter>
+       <simple>${in.header.type} == 'widget'</simple>
+       <to uri="bean:orderService?method=handleWidget"/>
+   </filter>
+</from>
+----
+
+== Using and / or
+
+If you have two expressions you can combine them with the `&&` or `||`
+operator.
+
+For instance:
+
+[source,java]
+-----
+simple("${in.header.title} contains 'Camel' && ${in.header.type'} == 'gold'")
+-----
+
+And of course the `||` is also supported. The sample would be:
+
+[source,java]
+-----
+simple("${in.header.title} contains 'Camel' || ${in.header.type'} == 'gold'")
+-----
+
+*Notice:* Currently `&&` or `||` can only be used *once* in a simple
+language expression. This might change in the future. +
+ So you *cannot* do:
+
+[source,java]
+-----
+simple("${in.header.title} contains 'Camel' && ${in.header.type'} == 'gold' && ${in.header.number} range 100..200")
+-----
+
+
+== Samples
+
+In the Spring XML sample below we filter based on a header value:
+
+[source,xml]
+--------------------------------------------
+<from uri="seda:orders">
+   <filter>
+       <simple>${in.header.foo}</simple>
+       <to uri="mock:fooOrders"/>
+   </filter>
+</from>
+--------------------------------------------
+
+The Simple language can be used for the predicate test above in the
+Message Filter pattern, where we test if the
+in message has a `foo` header (a header with the key `foo` exists). If
+the expression evaluates to *true* then the message is routed to the
+`mock:fooOrders` endpoint, otherwise the message is dropped.
+
+The same example in Java DSL:
+
+[source,java]
+----
+from("seda:orders")
+    .filter().simple("${in.header.foo}")
+        .to("seda:fooOrders");
+----
+
+You can also use the simple language for simple text concatenations such
+as:
+
+[source,java]
+----
+from("direct:hello")
+    .transform().simple("Hello ${in.header.user} how are you?")
+    .to("mock:reply");
+----
+
+Notice that we must use $\{ } placeholders in the expression now to
+allow Camel to parse it correctly.
+
+And this sample uses the date command to output current date.
+
+[source,java]
+----
+from("direct:hello")
+    .transform().simple("The today is ${date:now:yyyyMMdd} and it is a great day.")
+    .to("mock:reply");
+----
+
+And in the sample below we invoke the bean language to invoke a method
+on a bean to be included in the returned string:
+
+[source,java]
+----
+from("direct:order")
+    .transform().simple("OrderId: ${bean:orderIdGenerator}")
+    .to("mock:reply");
+----
+
+Where `orderIdGenerator` is the id of the bean registered in the
+Registry. If using Spring then it is the Spring bean
+id.
+
+If we want to declare which method to invoke on the order id generator
+bean we must prepend `.method name` such as below where we invoke the
+`generateId` method.
+
+[source,java]
+----
+from("direct:order")
+    .transform().simple("OrderId: ${bean:orderIdGenerator.generateId}")
+    .to("mock:reply");
+----
+
+We can use the `?method=methodname` option that we are familiar with the
+xref:components::bean-component.adoc[Bean] component itself:
+
+[source,java]
+----
+from("direct:order")
+    .transform().simple("OrderId: ${bean:orderIdGenerator?method=generateId}")
+    .to("mock:reply");
+----
+
+You can also convert the body to a given
+type, for example to ensure that it is a String you can do:
+
+[source,xml]
+----
+<transform>
+  <simple>Hello ${bodyAs(String)} how are you?</simple>
+</transform>
+----
+
+There are a few types which have a shorthand notation, so we can use
+`String` instead of `java.lang.String`. These are:
+`byte[], String, Integer, Long`. All other types must use their FQN
+name, e.g. `org.w3c.dom.Document`.
+
+It is also possible to lookup a value from a header `Map`:
+
+[source,xml]
+----
+<transform>
+  <simple>The gold value is ${header.type[gold]}</simple>
+</transform>
+----
+
+In the code above we lookup the header with name `type` and regard it as
+a `java.util.Map` and we then lookup with the key `gold` and return the
+value. If the header is not convertible to Map an exception is thrown. If the
+header with name `type` does not exist `null` is returned.
+
+You can nest functions, such as shown below:
+
+[source,xml]
+----
+<setHeader name="myHeader">
+  <simple>${properties:${header.someKey}}</simple>
+</setHeader>
+----
+
+== Referring to constants or enums
+
+Suppose you have an enum for customers
+
+And in a Content Based Router we can use
+the xref:simple-language.adoc[Simple] language to refer to this enum, to check
+the message which enum it matches.
+
+== Using new lines or tabs in XML DSLs
+
+It is easier to specify new lines or tabs in
+XML DSLs as you can escape the value now
+
+[source,xml]
+----
+<transform>
+  <simple>The following text\nis on a new line</simple>
+</transform>
+----
+
+== Leading and trailing whitespace handling
+
+The trim attribute of the expression can be
+used to control whether the leading and trailing whitespace characters
+are removed or preserved. The default value is true, which removes the
+whitespace characters.
+
+[source,xml]
+----
+<setBody>
+  <simple trim="false">You get some trailing whitespace characters.     </simple>
+</setBody>
+----
+
+== Setting result type
+
+You can now provide a result type to the xref:simple-language.adoc[Simple]
+expression, which means the result of the evaluation will be converted
+to the desired type. This is most usable to define types such as
+booleans, integers, etc.
+
+For example to set a header as a boolean type you can do:
+
+[source,java]
+----
+.setHeader("cool", simple("true", Boolean.class))
+----
+
+And in XML DSL
+
+[source,xml]
+----
+<setHeader name="cool">
+  <!-- use resultType to indicate that the type should be a java.lang.Boolean -->
+  <simple resultType="java.lang.Boolean">true</simple>
+</setHeader>
+----
+
+== Loading script from external resource
+
+You can externalize the script and have Camel load it from a resource
+such as `"classpath:"`, `"file:"`, or `"http:"`. +
+ This is done using the following syntax: `"resource:scheme:location"`,
+eg to refer to a file on the classpath you can do:
+
+[source,java]
+----
+.setHeader("myHeader").simple("resource:classpath:mysimple.txt")
+----
+
+== Setting Spring beans to Exchange properties
+
+You can set a spring bean into an exchange property as shown below:
+
+[source,xml]
+----
+<bean id="myBeanId" class="my.package.MyCustomClass" />
+...
+<route>
+  ...
+  <setProperty name="monitoring.message">
+    <simple>ref:myBeanId</simple>
+  </setProperty>
+  ...
+</route>
+----
+
diff --git a/docs/components/modules/ROOT/pages/tokenize-language.adoc b/docs/components/modules/ROOT/pages/tokenize-language.adoc
new file mode 100644
index 0000000..9054657
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/tokenize-language.adoc
@@ -0,0 +1,40 @@
+[[tokenize-language]]
+= Tokenize Language
+:page-source: core/camel-base/src/main/docs/tokenize-language.adoc
+
+*Available as of Camel version 2.0*
+
+The tokenizer language is a built-in language in camel-core, which is
+most often used only with the Splitter EIP to split
+a message using a token-based strategy. +
+The tokenizer language is intended to tokenize text documents using a
+specified delimiter pattern. It can also be used to tokenize XML
+documents with some limited capability. For a truly XML-aware
+tokenization, the use of the XMLTokenizer
+language is recommended as it offers a faster, more efficient
+tokenization specifically for XML documents. For more details
+see Splitter.
+
+== Tokenize Options
+
+// language options: START
+The Tokenize language supports 11 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| token |  | String | The (start) token to use as tokenizer, for example you can use the new line token. You can use simple language as the token to support dynamic tokens.
+| endToken |  | String | The end token to use as tokenizer if using start/end token pairs. You can use simple language as the token to support dynamic tokens.
+| inheritNamespaceTagName |  | String | To inherit namespaces from a root/parent tag name when using XML You can use simple language as the tag name to support dynamic names.
+| headerName |  | String | Name of header to tokenize instead of using the message body.
+| regex | false | Boolean | If the token is a regular expression pattern. The default value is false
+| xml | false | Boolean | Whether the input is XML messages. This option must be set to true if working with XML payloads.
+| includeTokens | false | Boolean | Whether to include the tokens in the parts when using pairs The default value is false
+| group |  | String | To group N parts together, for example to split big files into chunks of 1000 lines. You can use simple language as the group to support dynamic group sizes.
+| groupDelimiter |  | String | Sets the delimiter to use when grouping. If this has not been set then token will be used as the delimiter.
+| skipFirst | false | Boolean | To skip the very first element
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
diff --git a/docs/gulpfile.js b/docs/gulpfile.js
index bb90a24..4622918 100644
--- a/docs/gulpfile.js
+++ b/docs/gulpfile.js
@@ -35,7 +35,7 @@
 }
 
 function createComponentSymlinks() {
-    return src(['../core/camel-base/src/main/docs/*-component.adoc', '../components/{*,*/*}/src/main/docs/*.adoc'])
+    return src(['../core/camel-base/src/main/docs/*.adoc', '../components/{*,*/*}/src/main/docs/*.adoc'])
         .pipe(map((file, done) => {
             // this flattens the output to just .../pages/....adoc
             // instead of .../pages/camel-.../src/main/docs/....adoc
@@ -80,7 +80,7 @@
 }
 
 function createUserManualSymlinks() {
-    return src(['../core/camel-base/src/main/docs/*-language.adoc', '../core/camel-core-engine/src/main/docs/eips/*.adoc'])
+    return src(['../core/camel-base/src/main/docs/*.adoc', '../core/camel-core-engine/src/main/docs/eips/*.adoc'])
         // Antora disabled symlinks, there is an issue open
         // https://gitlab.com/antora/antora/issues/188
         // to reinstate symlink support, until that's resolved
@@ -122,7 +122,7 @@
 function createUserManualNav() {
     return src('user-manual-nav.adoc.template')
         .pipe(insertGeneratedNotice())
-        .pipe(inject(src('../core/camel-base/src/main/docs/*-language.adoc').pipe(sort()), {
+        .pipe(inject(src('../core/camel-base/src/main/docs/*.adoc').pipe(sort()), {
             removeTags: true,
             name: 'languages',
             transform: (filename, file) => {
diff --git a/docs/user-manual/modules/ROOT/nav.adoc b/docs/user-manual/modules/ROOT/nav.adoc
index 65fd2ec..99559a2 100644
--- a/docs/user-manual/modules/ROOT/nav.adoc
+++ b/docs/user-manual/modules/ROOT/nav.adoc
@@ -55,6 +55,7 @@
  ** xref:exchangeProperty-language.adoc[ExchangeProperty Language]
  ** xref:file-language.adoc[File Language]
  ** xref:header-language.adoc[Header Language]
+ ** xref:properties-component.adoc[Properties Component]
  ** xref:ref-language.adoc[Ref Language]
  ** xref:simple-language.adoc[Simple Language]
  ** xref:tokenize-language.adoc[Tokenize Language]
diff --git a/docs/user-manual/modules/ROOT/pages/index.adoc b/docs/user-manual/modules/ROOT/pages/index.adoc
index 6a4763d..5e112e2 100644
--- a/docs/user-manual/modules/ROOT/pages/index.adoc
+++ b/docs/user-manual/modules/ROOT/pages/index.adoc
@@ -424,7 +424,7 @@
 ** xref:components::leveldb.adoc[LevelDB]
 ** xref:components::lra.adoc[Lra]
 ** xref:components::opentracing.adoc[OpenTracing]
-** xref:components::reactor-component.adoc[Reactor]
+** xref:components::reactor.adoc[Reactor]
 ** xref:components::ribbon.adoc[Ribbon]
 ** xref:components::rxjava.adoc[Rxjava]
 ** xref:components::shiro.adoc[Shiro]
diff --git a/docs/user-manual/modules/ROOT/pages/properties-component.adoc b/docs/user-manual/modules/ROOT/pages/properties-component.adoc
new file mode 100644
index 0000000..7cd2bc8
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/pages/properties-component.adoc
@@ -0,0 +1,833 @@
+[[properties-component]]
+= Properties Component
+:page-source: core/camel-base/src/main/docs/properties-component.adoc
+
+*Available as of Camel version 2.3*
+
+The properties component is used for property placeholders in your Camel application, such as endpoint URIs.
+It is *not* a regular Camel component with producer and consumer for routing messages. However for historical
+reasons it was named `PropertiesComponent` and this name is commonly known and therfore we keep using it.
+
+== Spring Boot Auto-Configuration
+
+The component supports 10 options, which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *camel.component.properties.auto-discover-properties-sources* | Whether to automatically discovery instances of PropertiesSource from registry and service factory. | true | Boolean
+| *camel.component.properties.default-fallback-enabled* | If false, the component does not attempt to find a default for the key by looking after the colon separator. | true | Boolean
+| *camel.component.properties.encoding* | Encoding to use when loading properties file from the file system or classpath. If no encoding has been set, then the properties files is loaded using ISO-8859-1 encoding (latin-1) as documented by java.util.Properties#load(java.io.InputStream) |  | String
+| *camel.component.properties.environment-variable-mode* | Sets the OS environment variables mode (0 = never, 1 = fallback, 2 = override). The default mode (override) is to use OS environment variables if present, and override any existing properties. OS environment variable mode is checked before JVM system property mode | 2 | Integer
+| *camel.component.properties.ignore-missing-location* | Whether to silently ignore if a location cannot be located, such as a properties file not found. | false | Boolean
+| *camel.component.properties.initial-properties* | Sets initial properties which will be used before any locations are resolved. The option is a java.util.Properties type. |  | String
+| *camel.component.properties.location* | A list of locations to load properties. You can use comma to separate multiple locations. This option will override any default locations and only use the locations from this option. |  | String
+| *camel.component.properties.override-properties* | Sets a special list of override properties that take precedence and will use first, if a property exist. The option is a java.util.Properties type. |  | String
+| *camel.component.properties.properties-parser* | To use a custom PropertiesParser. The option is a org.apache.camel.component.properties.PropertiesParser type. |  | String
+| *camel.component.properties.system-properties-mode* | Sets the JVM system property mode (0 = never, 1 = fallback, 2 = override). The default mode (override) is to use system properties if present, and override any existing properties. OS environment variable mode is checked before JVM system property mode | 2 | Integer
+|===
+
+[TIP]
+**Resolving property from Java code** +
+You can use the method `resolvePropertyPlaceholders` on the
+`CamelContext` to resolve a property from any Java code.
+
+== Using PropertyPlaceholder
+
+Camel now provides a new `PropertiesComponent` in *camel-core* which
+allows you to use property placeholders when defining Camel
+Endpoint URIs.
+
+This works much like you would do if using Spring's
+`<property-placeholder>` tag. However Spring have a limitation which
+prevents 3rd party frameworks to leverage Spring property placeholders
+to the fullest. See more at
+xref:manual::faq/how-do-i-use-spring-property-placeholder-with-camel-xml.adoc[How do
+I use Spring Property Placeholder with Camel XML].
+
+[TIP]
+**Bridging Spring and Camel property placeholders** +
+You can bridge the Spring property placeholder
+with Camel, see further below for more details.
+
+The property placeholder is generally in use when doing:
+
+* lookup or creating endpoints
+* lookup of beans in the Registry
+* additional supported in Spring XML (see below in examples)
+* using Blueprint PropertyPlaceholder with Camel
+xref:properties-component.adoc[Properties] component
+* using `@PropertyInject` to inject a property in a POJO
+* Using default value if a property does not exists
+* Include out of the box functions, to lookup property
+values from OS environment variables, JVM system properties, or the
+service idiom.
+* Using custom functions, which can be plugged into the
+property component.
+
+== Syntax
+
+The syntax to use Camel's property placeholder is to use `{\{key\}}` for
+example `{{file.uri}}` where `file.uri` is the property key.
+
+You can use property placeholders in parts of the endpoint URI's which
+for example you can use placeholders for parameters in the URIs.
+
+You can specify a default value to use if
+a property with the key does not exists, eg `file.url:/some/path` where
+the default value is the text after the colon (eg /some/path).
+
+NOTE: Do not use colon in the property key. The colon is used as a separator
+token when you are providing a default value.
+
+== Defining location
+
+The properties component need to know a location(s) where to resolve the
+properties. You can define 1 to many locations. If you define the
+location in a single String property you can separate multiple locations
+with comma such as:
+
+[source,java]
+----
+pc.setLocation("com/mycompany/myprop.properties,com/mycompany/other.properties");
+----
+
+You can set which location can be discarded if missing by by setting the ``optional`` attribute, which is false by default, i.e:
+
+[source,java]
+----
+pc.setLocations(
+    "com/mycompany/override.properties;optional=true"
+    "com/mycompany/defaults.properties");
+----
+
+== Using system and environment variables in locations
+
+The location now supports using placeholders for JVM system properties
+and OS environments variables.
+
+For example:
+
+[source]
+----
+location=file:${karaf.home}/etc/foo.properties
+----
+
+In the location above we defined a location using the file scheme using
+the JVM system property with key `karaf.home`.
+
+To use an OS environment variable instead you would have to prefix with
+env:
+
+[source]
+----
+location=file:${env:APP_HOME}/etc/foo.properties
+----
+
+Where `APP_HOME` is an OS environment.
+
+NOTE: Some OS'es (such as Linux) do not support dashes in environment variable names,
+so here we are using `APP_HOME`. But if you specify `APP-HOME` then Camel 3 will automatic lookup
+the value as `APP_HOME` (with underscore) as fallback.
+
+You can have multiple placeholders in the same location, such as:
+
+[source]
+----
+location=file:${env:APP_HOME}/etc/${prop.name}.properties
+----
+
+== Configuring in Java DSL
+
+You have to create and register the `PropertiesComponent` under the name
+`properties` such as:
+
+[source,java]
+----
+PropertiesComponent pc = camelContext.getPropertiesComponent();
+pc.setLocation("classpath:com/mycompany/myprop.properties");
+----
+
+== Configuring in Spring XML
+
+Spring XML offers two variations to configure. You can define a spring
+bean as a `PropertiesComponent` which resembles the way done in Java
+DSL. Or you can use the `<propertyPlaceholder>` tag.
+
+[source,xml]
+----
+<bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent">
+    <property name="location" value="classpath:com/mycompany/myprop.properties"/>
+</bean>
+----
+
+Using the `<propertyPlaceholder>` tag makes the configuration a bit more
+fresh such as:
+
+[source,xml]
+----
+<camelContext ...>
+   <propertyPlaceholder id="properties" location="com/mycompany/myprop.properties"/>
+</camelContext>
+----
+
+Setting the properties location through the location tag works just fine but sometime you have a number of resources to take into account and starting from *Camel 2.19.0* you can set the properties location with a dedicated propertiesLocation:
+
+[source,xml]
+----
+<camelContext ...>
+  <propertyPlaceholder id="myPropertyPlaceholder">
+    <propertiesLocation
+      resolver = "classpath"
+      path     = "com/my/company/something/my-properties-1.properties"
+      optional = "false"/>
+    <propertiesLocation
+      resolver = "classpath"
+      path     = "com/my/company/something/my-properties-2.properties"
+      optional = "false"/>
+    <propertiesLocation
+      resolver = "file"
+      path     = "${karaf.home}/etc/my-override.properties"
+      optional = "true"/>
+   </propertyPlaceholder>
+</camelContext>
+----
+
+[TIP]
+**Specifying the cache option inside XML** +
+Camel supports specifying a value for the cache option both
+inside the Spring as well as the Blueprint XML.
+
+== Using a Properties from the Registry
+
+For example in OSGi you may want to expose a service which returns the
+properties as a `java.util.Properties` object.
+
+Then you could setup the xref:properties-component.adoc[Properties] component as
+follows:
+
+[source,xml]
+----
+ <propertyPlaceholder id="properties" location="ref:myProperties"/>
+----
+
+Where `myProperties` is the id to use for lookup in the OSGi registry.
+Notice we use the `ref:` prefix to tell Camel that it should lookup the
+properties for the Registry.
+
+== Examples using properties component
+
+When using property placeholders in the endpoint URIs you can either use
+the `properties:` component or define the placeholders directly in the
+URI. We will show example of both cases, starting with the former.
+
+[source,java]
+----
+// properties
+cool.end=mock:result
+
+// route
+from("direct:start").to("{{cool.end}}");
+----
+
+You can also use placeholders as a part of the endpoint uri:
+
+[source,java]
+----
+// properties
+cool.foo=result
+
+// route
+from("direct:start").to("mock:{{cool.foo}}");
+----
+
+In the example above the to endpoint will be resolved to `mock:result`.
+
+You can also have properties with refer to each other such as:
+
+[source,java]
+----
+// properties
+cool.foo=result
+cool.concat=mock:{{cool.foo}}
+
+// route
+from("direct:start").to("mock:{{cool.concat}}");
+----
+
+Notice how `cool.concat` refer to another property.
+
+And you can use placeholders several times:
+
+[source,java]
+----
+// properties
+cool.start=direct:start
+cool.showid=true
+cool.result=result
+
+// route
+from("{{cool.start}}")
+    .to("log:{{cool.start}}?showBodyType=false&showExchangeId={{cool.showid}}")
+    .to("mock:{{cool.result}}");
+----
+
+You can also your property placeholders when using
+ProducerTemplate for example:
+
+[source,java]
+----
+template.sendBody("{{cool.start}}", "Hello World");
+----
+
+== Example with xref:manual::simple-language.adoc[Simple] language
+
+The xref:manual::simple-language.adoc[Simple] language now also support using property
+placeholders, for example in the route below:
+
+[source,java]
+----
+// properties
+cheese.quote=Camel rocks
+
+// route
+from("direct:start")
+    .transform().simple("Hi ${body} do you think ${properties:cheese.quote}?");
+----
+
+== Additional property placeholder supported in Spring XML
+
+The property placeholders is also supported in many of the Camel Spring
+XML tags such as
+`<package>, <packageScan>, <contextScan>, <jmxAgent>, <endpoint>, <routeBuilder>, <proxy>`
+and the others.
+
+The example below has property placeholder in the `<jmxAgent>` tag:
+
+You can also define property placeholders in the various attributes on
+the `<camelContext>` tag such as `trace` as shown here:
+
+== Using JVM system properties or Environment variables as override or fallback values
+
+The properties components supports using JVM system properties and also OS environment variables
+as values which can either be used as override or fallback values.
+
+The default mode is that both of them are in override mode, and they are check in the following order:
+
+1. OS environment variable (override mode)
+2. JVM system property  (override mode)
+3. Property files and other locations
+4. OS environment variable (fallback mode)
+5. JVM system property  (fallback mode)
+
+The check stops at first found property value for the key.
+
+You can control these modes using the `systemPropertiesMode` and `environmentVariableMode`
+options on the properties component.
+
+== Using property placeholders for any kind of attribute in the XML DSL
+
+In the example below we use the `prop` prefix for the namespace
+camel.apache.org/schema/placeholder by which we can use the
+`prop` prefix in the attributes in the XML DSLs. Notice how we use that
+in the Multicast to indicate that the option
+`stopOnException` should be the value of the placeholder with the key
+"stop".
+
+In our properties file we have the value defined as
+
+[source]
+----
+stop=true
+----
+
+== Using Blueprint property placeholder with Camel routes
+
+Camel supports Blueprint
+which also offers a property placeholder service. Camel supports
+convention over configuration, so all you have to do is to define the
+OSGi Blueprint property placeholder in the XML file as shown below:
+
+[source,xml]
+----
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
+           xsi:schemaLocation="
+           http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+    <!-- OSGI blueprint property placeholder -->
+    <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint">
+        <!-- list some properties as needed -->
+        <cm:default-properties>
+            <cm:property name="result" value="mock:result"/>
+        </cm:default-properties>
+    </cm:property-placeholder>
+
+    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
+        <!-- in the route we can use {{ }} placeholders which will lookup in blueprint
+             as Camel will auto detect the OSGi blueprint property placeholder and use it -->
+        <route>
+            <from uri="direct:start"/>
+            <to uri="mock:foo"/>
+            <to uri="{{result}}"/>
+        </route>
+    </camelContext>
+</blueprint>
+----
+
+=== Using OSGi blueprint property placeholders in Camel routes
+
+By default Camel detects and uses OSGi blueprint property placeholder
+service. You can disable this by setting the attribute
+`useBlueprintPropertyResolver` to false on the `<camelContext>`
+definition.
+
+=== About placeholder syntax
+
+Notice how we can use the Camel syntax for placeholders `{{` and `}}` in the
+Camel route, which will lookup the value from OSGi blueprint.
+
+The blueprint syntax for placeholders is `${ }`. So outside the
+`<camelContext>` you must use the `${ }` syntax. Where as inside
+`<camelContext>` you must use `{{` and `}}` syntax.
+
+OSGi blueprint allows you to configure the syntax, so you can actually
+align those if you want.
+
+You can also explicit refer to a specific OSGi blueprint property
+placeholder by its id. For that you need to use the Camel's
+`<propertyPlaceholder>` as shown in the example below:
+
+[source,xml]
+----
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
+           xsi:schemaLocation="
+           http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+    <!-- OSGI blueprint property placeholder -->
+    <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint">
+        <!-- list some properties as needed -->
+        <cm:default-properties>
+            <cm:property name="prefix.result" value="mock:result"/>
+        </cm:default-properties>
+    </cm:property-placeholder>
+
+    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
+        <!-- using Camel properties component and refer to the blueprint property placeholder by its id -->
+        <propertyPlaceholder id="properties" location="blueprint:myblueprint.placeholder"/>
+
+        <!-- in the route we can use {{ }} placeholders which will lookup in blueprint -->
+        <route>
+            <from uri="direct:start"/>
+            <to uri="mock:foo"/>
+            <to uri="{{prefix.result}}"/>
+        </route>
+    </camelContext>
+</blueprint>
+----
+
+
+== Explicit referring to a OSGi blueprint placeholder in Camel
+
+Notice how we use the `blueprint` scheme to refer to the OSGi blueprint
+placeholder by its id. This allows you to mix and match, for example you
+can also have additional schemes in the location. For example to load a
+file from the classpath you can do:
+
+[source]
+----
+location="blueprint:myblueprint.placeholder,classpath:myproperties.properties"
+----
+
+Each location is separated by comma.
+
+== Overriding Blueprint property placeholders outside CamelContext
+
+When using Blueprint property placeholder in the Blueprint XML file, you
+can declare the properties directly in the XML file as shown below:
+
+Notice that we have a `<bean>` which refers to one of the properties. And
+in the Camel route we refer to the other using the `{{` and `}}` notation.
+
+Now if you want to override these Blueprint properties from an unit
+test, you can do this as shown below:
+
+To do this we override and implement the
+`useOverridePropertiesWithConfigAdmin` method. We can then put the
+properties we want to override on the given props parameter. And the
+return value *must* be the `persistence-id` of the
+`<cm:property-placeholder>` tag, which you define in the blueprint XML
+file.
+
+== Using .cfg or .properties file for Blueprint property placeholders
+
+When using Blueprint property placeholder in the Blueprint XML file, you
+can declare the properties in a `.properties` or `.cfg` file. If you use
+Apache ServieMix / Karaf then this container has a convention that it
+loads the properties from a file in the etc directory with the naming
+`etc/pid.cfg`, where `pid` is the `persistence-id`.
+
+For example in the blueprint XML file we have the
+`persistence-id="stuff"`, which mean it will load the configuration file
+as `etc/stuff.cfg`.
+
+Now if you want to unit test this blueprint XML file, then you can
+override the `loadConfigAdminConfigurationFile` and tell Camel which
+file to load as shown below:
+
+Notice that this method requires to return a `String[]` with 2 values. The
+1st value is the path for the configuration file to load.
+The 2nd value is the `persistence-id` of the `<cm:property-placeholder>`
+tag.
+
+The `stuff.cfg` file is just a plain properties file with the property
+placeholders such as:
+
+[source]
+----
+== this is a comment
+greeting=Bye
+----
+
+== Using .cfg file and overriding properties for Blueprint property placeholders
+
+You can do both as well. Here is a complete example. First we have the
+Blueprint XML file:
+
+And in the unit test class we do as follows:
+
+And the `etc/stuff.cfg` configuration file contains
+
+[source]
+----
+greeting=Bye
+echo=Yay
+destination=mock:result
+----
+
+== Bridging Spring and Camel property placeholders
+
+The Spring Framework does not allow 3rd party frameworks such as Apache
+Camel to seamless hook into the Spring property placeholder mechanism.
+However you can easily bridge Spring and Camel by declaring a Spring
+bean with the type
+`org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer`, which
+is a Spring
+`org.springframework.beans.factory.config.PropertyPlaceholderConfigurer`
+type.
+
+To bridge Spring and Camel you must define a single bean as shown below:
+
+*Bridging Spring and Camel property placeholders*
+
+You *must not* use the spring <context:property-placeholder> namespace
+at the same time; this is not possible.
+
+After declaring this bean, you can define property placeholders using
+both the Spring style, and the Camel style within the <camelContext> tag
+as shown below:
+
+*Using bridge property placeholders*
+
+Notice how the hello bean is using pure Spring property placeholders
+using the `${ }` notation. And in the Camel routes we use the Camel
+placeholder notation with `{{` and `}}`.
+
+== Clashing Spring property placeholders with Camels Simple language
+
+Take notice when using Spring bridging placeholder then the spring `${ }`
+syntax clashes with the xref:manual::simple-language.adoc[Simple] in Camel, and therefore
+take care. For example:
+
+[source,xml]
+----
+<setHeader name="Exchange.FILE_NAME">
+  <simple>{{file.rootdir}}/${in.header.CamelFileName}</simple>
+</setHeader>
+----
+
+clashes with Spring property placeholders, and you should use `$simple{ }`
+to indicate using the xref:manual::simple-language.adoc[Simple] language in Camel.
+
+[source,xml]
+----
+<setHeader name="Exchange.FILE_NAME">
+  <simple>{{file.rootdir}}/$simple{in.header.CamelFileName}</simple>
+</setHeader>
+----
+
+An alternative is to configure the `PropertyPlaceholderConfigurer` with
+`ignoreUnresolvablePlaceholders` option to `true`.
+
+== Overriding properties from Camel test kit
+
+When Testing with Camel and using the
+xref:properties-component.adoc[Properties] component, you may want to be able to
+provide the properties to be used from directly within the unit test
+source code. +
+Camel test kits, eg `CamelTestSupport` class offers the following methods
+
+* `useOverridePropertiesWithPropertiesComponent`
+* `ignoreMissingLocationWithPropertiesComponent`
+
+So for example in your unit test classes, you can override the
+`useOverridePropertiesWithPropertiesComponent` method and return a
+`java.util.Properties` that contains the properties which should be
+preferred to be used.
+
+=== Providing properties from within unit test source
+
+This can be done from any of the Camel Test kits, such as camel-test,
+camel-test-spring, and camel-test-blueprint.
+
+The `ignoreMissingLocationWithPropertiesComponent` can be used to
+instruct Camel to ignore any locations which was not discoverable, for
+example if you run the unit test, in an environment that does not have
+access to the location of the properties.
+
+== Using @PropertyInject
+
+Camel allows to inject property placeholders in POJOs using the
+`@PropertyInject` annotation which can be set on fields and setter
+methods.
+
+For example you can use that with `RouteBuilder` classes, such as shown
+below:
+
+[source,java]
+----
+public class MyRouteBuilder extends RouteBuilder {
+
+    @PropertyInject("hello")
+    private String greeting;
+
+    @Override
+    public void configure() throws Exception {
+        from("direct:start")
+            .transform().constant(greeting)
+            .to("{{result}}");
+    }
+
+}
+----
+
+Notice we have annotated the greeting field with `@PropertyInject` and
+define it to use the key `"hello"`. Camel will then lookup the property
+with this key and inject its value, converted to a String type.
+
+You can also use multiple placeholders and text in the key, for example
+we can do:
+
+[source,java]
+----
+@PropertyInject("Hello {{name}} how are you?")
+private String greeting;
+----
+
+This will lookup the placeholder with they key `"name"`.
+
+You can also add a default value if the key does not exists, such as:
+
+[source,java]
+----
+@PropertyInject(value = "myTimeout", defaultValue = "5000")
+private int timeout;
+----
+
+== Using out of the box functions
+
+The xref:properties-component.adoc[Properties] component includes the following
+functions out of the box
+
+* `env` - A function to lookup the property from OS environment variables
+* `sys` - A function to lookup the property from Java JVM system
+properties
+* `service` - A function to lookup the property from OS environment
+variables using the service naming idiom
+* `service.name` - A function to lookup the
+property from OS environment variables using the service naming idiom
+returning the hostname part only
+* `service.port` - A function to lookup the
+property from OS environment variables using the service naming idiom
+returning the port part only
+
+As you can see these functions is intended to make it easy to lookup
+values from the environment. As they are provided out of the box, they
+can easily be used as shown below:
+
+[source,xml]
+----
+  <camelContext xmlns="http://camel.apache.org/schema/blueprint">
+
+    <route>
+      <from uri="direct:start"/>
+      <to uri="{`{env:SOMENAME}`}"/>
+      <to uri="{`{sys:MyJvmPropertyName}`}"/>
+    </route>
+  </camelContext>
+----
+
+You can use default values as well, so if the property does not exists,
+you can define a default value as shown below, where the default value
+is a `log:foo` and `log:bar` value.
+
+[source,xml]
+----
+  <camelContext xmlns="http://camel.apache.org/schema/blueprint">
+
+    <route>
+      <from uri="direct:start"/>
+      <to uri="{`{env:SOMENAME:log:foo}`}"/>
+      <to uri="{`{sys:MyJvmPropertyName:log:bar}`}"/>
+    </route>
+  </camelContext>
+----
+
+ 
+
+The service function is for looking up a service which is defined using
+OS environment variables using the service naming idiom, to refer to a
+service location using `hostname : port`
+
+* __NAME__**_SERVICE_HOST**
+* __NAME__**_SERVICE_PORT**
+
+in other words the service uses `_SERVICE_HOST` and `_SERVICE_PORT` as
+prefix. So if the service is named FOO, then the OS environment
+variables should be set as
+
+[source]
+----
+export $FOO_SERVICE_HOST=myserver
+export $FOO_SERVICE_PORT=8888
+----
+
+For example if the FOO service a remote HTTP service, then we can refer
+to the service in the Camel endpoint uri, and use
+the HTTP component to make the HTTP call:
+
+[source,xml]
+----
+<camelContext xmlns="http://camel.apache.org/schema/blueprint">
+  <route>
+    <from uri="direct:start"/>
+    <to uri="http://{`{service:FOO}`}/myapp"/>
+  </route>
+</camelContext>
+----
+
+And we can use default values if the service has not been defined, for
+example to call a service on localhost, maybe for unit testing etc
+
+[source,xml]
+----
+<camelContext xmlns="http://camel.apache.org/schema/blueprint">
+  <route>
+    <from uri="direct:start"/>
+    <to uri="http://{`{service:FOO:localhost:8080}`}/myapp"/>
+  </route>
+</camelContext>
+----
+
+== Using custom functions (advanced)
+
+The xref:properties-component.adoc[Properties] component allow to plugin 3rd party
+functions which can be used during parsing of the property placeholders.
+These functions are then able to do custom logic to resolve the
+placeholders, such as looking up in databases, do custom computations,
+or whatnot. The name of the function becomes the prefix used in the
+placeholder. This is best illustrated in the example code below
+
+[source,xml]
+----
+<bean id="beerFunction" class="MyBeerFunction"/>
+
+<camelContext xmlns="http://camel.apache.org/schema/blueprint">
+  <propertyPlaceholder id="properties">
+    <propertiesFunction ref="beerFunction"/>
+  </propertyPlaceholder>
+
+  <route>
+    <from uri="direct:start"/>
+    <to uri="{`{beer:FOO}`}"/>
+    <to uri="{`{beer:BAR}`}"/>
+  </route>
+</camelContext>
+----
+
+NOTE: The location attribute (on propertyPlaceholder tag) is not mandatory
+
+Here we have a Camel XML route where we have defined the
+`<propertyPlaceholder>` to use a custom function, which we refer to be the
+bean id - eg the `beerFunction`. As the beer function uses `"beer"` as its
+name, then the placeholder syntax can trigger the beer function by
+starting with `beer:value`.
+
+The implementation of the function is only two methods as shown below:
+
+[source,java]
+----
+public static final class MyBeerFunction implements PropertiesFunction {
+
+    @Override
+    public String getName() {
+        return "beer";
+    }
+
+    @Override
+    public String apply(String remainder) {
+        return "mock:" + remainder.toLowerCase();
+    }
+}
+----
+
+The function must implement
+the `org.apache.camel.component.properties.PropertiesFunction`
+interface. The method `getName` is  the name of the function, eg beer.
+And the `apply` method is where we implement the custom logic to do. As
+the sample code is from an unit test, it just returns a value to refer
+to a mock endpoint.
+
+To register a custom function from Java code is as shown below:
+
+[source,java]
+----
+PropertiesComponent pc = (org.apache.camel.componennt.properties.PropertiesComponent) context.getPropertiesComponent();
+pc.addFunction(new MyBeerFunction());
+----
+ 
+
+== Using 3rd-party properties sources
+
+The properties component allows to plugin 3rd party sources to load and lookup properties via the `PropertySource`
+API from camel-api. For example the `camel-microprofile-config` component is implemented using this.
+The 3rd-party `PropertySource` can automatic be discoverd from classpath when Camel is starting up.
+This is done by include the file `META-INF/services/org/apache/camel/property-source-factory` file
+which refers to the fully qualified class name of the `PropertySource` implementation.
+See the `camel-microprofile-config` for an example.
+
+You can also register 3rd-part property sources via Java API
+
+[source,java]
+----
+PropertiesComponent pc = ...
+pc.addPropertySource(myPropertySource);
+----
+
+=== LoadablePropertySource
+
+A `PropertySource` can define that it supports loading all its properties from the source at once,
+for example from file system. This allows Camel properties component to load these properties at once
+during startup.
+
+=== PropertySource
+
+The regular `PropertySource` will lookup the property on-demand, for example to lookup
+values from a backend source such as a database or HashiCorp Vault etc.
+
+