You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/06/09 09:31:09 UTC

[camel] branch main updated: CAMEL-19307: camel-yaml-io - YAML route dumper (#10291)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 8c895d93d62 CAMEL-19307: camel-yaml-io - YAML route dumper (#10291)
8c895d93d62 is described below

commit 8c895d93d62a036e377c78049056810930387108
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Jun 9 11:30:52 2023 +0200

    CAMEL-19307: camel-yaml-io - YAML route dumper (#10291)
    
    CAMEL-19307: camel-yaml-io - dumping routes to yaml
---
 apache-camel/pom.xml                               |   4 +
 bom/camel-bom/pom.xml                              |   5 +
 .../main/camel-main-configuration-metadata.json    |   2 +-
 .../org/apache/camel/catalog/models/resumable.json |   9 +-
 .../org/apache/camel/catalog/others.properties     |   1 +
 .../org/apache/camel/catalog/others/yaml-io.json   |  15 +
 .../apache/camel/catalog/schemas/camel-spring.xsd  |   2 +-
 .../component/kamelet/KameletRouteDumpTest.java    |   2 +-
 .../main/java/org/apache/camel/CamelContext.java   |  14 +-
 .../org/apache/camel/ExtendedCamelContext.java     |   5 +
 .../org/apache/camel/spi/ModelToYAMLDumper.java    |  58 +++
 .../camel/impl/engine/AbstractCamelContext.java    |  18 +-
 .../impl/engine/DefaultCamelContextExtension.java  |   5 +
 .../camel/impl/engine/SimpleCamelContext.java      |  18 +-
 .../org/apache/camel/dev-console/route-dump        |   2 +
 .../camel/impl/console/RouteDumpDevConsole.java    | 168 ++++++
 .../catalog/impl/DefaultRuntimeCamelCatalog.java   |  14 +
 .../org/apache/camel/catalog/impl/URISupport.java  |  14 +
 .../apache/camel/impl/CamelContextConfigurer.java  |   6 +-
 .../camel/impl/ExtendedCamelContextConfigurer.java |   6 +
 .../org/apache/camel/impl/DefaultCamelContext.java |  53 ++
 .../org/apache/camel/model/resumable.json          |   9 +-
 .../org/apache/camel/model/CatchDefinition.java    |  21 +-
 .../apache/camel/model/ResumableDefinition.java    |   1 +
 .../model/dataformat/YAMLTypeFilterDefinition.java |   2 +-
 .../org/apache/camel/reifier/AggregateReifier.java |   5 +
 .../core/xml/AbstractCamelContextFactoryBean.java  |   2 +-
 core/camel-core/pom.xml                            |   4 +
 .../camel/util/DumpModelAsXmlNamespaceTest.java    |  11 +-
 .../util/DumpModelAsYamlSourceLocationTest.java    |  76 +++
 ...mpModelAsYamlSplitNestedChoiceEndRouteTest.java |  51 ++
 .../camel/util/DumpModelAsYamlTestSupport.java     |  42 ++
 .../util/DumpModelAsYamlTransformRouteTest.java    |  49 ++
 .../org/apache/camel/util/split-choice.yaml        |  41 ++
 .../resources/org/apache/camel/util/transform.yaml |  12 +
 .../MainConfigurationPropertiesConfigurer.java     |   6 +-
 .../camel-main-configuration-metadata.json         |   2 +-
 core/camel-main/src/main/docs/main.adoc            |   2 +-
 .../camel/main/DefaultConfigurationConfigurer.java |   2 +-
 .../camel/main/DefaultConfigurationProperties.java |  21 +-
 .../java/org/apache/camel/main/MainHelper.java     |  12 +-
 .../management/mbean/ManagedCamelContextMBean.java |   9 +
 .../api/management/mbean/ManagedRouteMBean.java    |   9 +
 .../management/mbean/ManagedCamelContext.java      |  25 +
 .../camel/management/mbean/ManagedRoute.java       |  22 +
 .../ManagedCamelContextDumpRoutesAsYamlTest.java   | 122 +++++
 .../org/apache/camel/support/PluginHelper.java     |  15 +
 .../java/org/apache/camel/util/StringHelper.java   |  25 +
 core/camel-xml-io/pom.xml                          |  11 +
 .../java/org/apache/camel/xml/in/ModelParser.java  |   9 +-
 .../java/org/apache/camel/xml/out/ModelWriter.java | 568 ++++++++++----------
 .../org/apache/camel/xml/LwModelToXMLDumper.java   |  29 +-
 .../java/org/apache/camel/xml/io/XMLWriter.java    |   2 +-
 .../java/org/apache/camel/xml/out/BaseWriter.java  |  28 +-
 .../org/apache/camel/xml/in/ModelParserTest.java   |   3 +-
 .../src/test/resources/log4j2.properties           |  26 +-
 core/camel-xml-io/src/test/resources/loop.xml      |   3 +-
 core/{camel-xml-io => camel-yaml-io}/pom.xml       |  41 +-
 .../org/apache/camel/yaml}/out/ModelWriter.java    | 570 +++++++++++----------
 .../services/org/apache/camel/modelyaml-dumper     |   2 +
 .../services/org/apache/camel/other.properties     |   7 +
 .../src/generated/resources/yaml-io.json           |  15 +
 .../apache/camel/yaml/LwModelToYAMLDumper.java}    |  63 +--
 .../java/org/apache/camel/yaml/io/EipNode.java     | 187 +++++++
 .../camel/yaml/io/ModelJSonSchemaResolver.java     |  93 ++++
 .../java/org/apache/camel/yaml/io/YamlWriter.java  | 418 +++++++++++++++
 .../java/org/apache/camel/yaml/out/BaseWriter.java |  74 +++
 .../src/main/resources/META-INF/LICENSE.txt        | 203 ++++++++
 .../src/main/resources/META-INF/NOTICE.txt         |  15 +
 .../org/apache/camel/yaml/out/ModelWriterTest.java | 299 +++++++++++
 .../org/apache/camel/yaml/out/XmlToYamlTest.java   |  78 +++
 .../src/test/resources/log4j2.properties           |  26 +-
 core/camel-yaml-io/src/test/resources/route0.yaml  |  13 +
 core/camel-yaml-io/src/test/resources/route1.yaml  |  10 +
 core/camel-yaml-io/src/test/resources/route2.yaml  |  15 +
 core/camel-yaml-io/src/test/resources/route3.yaml  |  21 +
 core/camel-yaml-io/src/test/resources/route4.yaml  |  13 +
 core/camel-yaml-io/src/test/resources/route5.yaml  |  13 +
 core/camel-yaml-io/src/test/resources/route6.yaml  |  25 +
 core/camel-yaml-io/src/test/resources/route7.yaml  |  27 +
 core/camel-yaml-io/src/test/resources/route8.yaml  |  22 +
 core/camel-yaml-io/src/test/resources/route9.yaml  |   9 +
 core/pom.xml                                       |   1 +
 .../ROOT/pages/camel-4-migration-guide.adoc        |   1 +
 .../camel/cli/connector/LocalCliConnector.java     |  11 +
 .../dsl/jbang/core/commands/CamelJBangMain.java    |   2 +
 .../core/commands/action/CamelRouteDumpAction.java | 270 ++++++++++
 .../java/org/apache/camel/main/KameletMain.java    |  15 +-
 .../camel-main-known-dependencies.properties       |   4 +-
 .../dsl/yaml/deserializers/ModelDeserializers.java |   6 +
 dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml          |   1 +
 .../generated/resources/schema/camel-yaml-dsl.json |   4 +
 .../generated/resources/schema/camelYamlDsl.json   |   4 +
 parent/pom.xml                                     |   5 +
 .../org/apache/camel/tooling/model/BaseModel.java  |  15 +-
 .../camel/tooling/model/BaseOptionModel.java       |   4 +
 .../apache/camel/tooling/model/ExampleModel.java   |   1 -
 ...atorMojo.java => ModelWriterGeneratorMojo.java} | 386 +++++++-------
 .../packaging/XmlModelWriterGeneratorMojo.java     |  69 +++
 .../packaging/YamlModelWriterGeneratorMojo.java    |  70 +++
 100 files changed, 3901 insertions(+), 925 deletions(-)

diff --git a/apache-camel/pom.xml b/apache-camel/pom.xml
index 5ee0a9b6010..dcc3334a557 100644
--- a/apache-camel/pom.xml
+++ b/apache-camel/pom.xml
@@ -152,6 +152,10 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-xml-jaxb</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-yaml-io</artifactId>
+        </dependency>
 
         <!-- all components, languages and dataformats -->
         <dependency>
diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index 950d79d83ed..82d40599f96 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -2092,6 +2092,11 @@
         <artifactId>camel-yaml-dsl-deserializers</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-yaml-io</artifactId>
+        <version>${project.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-zeebe</artifactId>
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index d608e6d195d..b0ef1361e58 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -37,7 +37,7 @@
     { "name": "camel.main.debugging", "description": "Sets whether debugging is enabled or not. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.description", "description": "Sets the description (intended for humans) of the Camel application.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "name": "camel.main.devConsoleEnabled", "description": "Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
-    { "name": "camel.main.dumpRoutes", "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-jaxb  [...]
+    { "name": "camel.main.dumpRoutes", "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml [...]
     { "name": "camel.main.durationHitExitCode", "description": "Sets the exit code for the application if duration was hit", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "integer", "javaType": "int" },
     { "name": "camel.main.durationMaxAction", "description": "Controls whether the Camel application should shutdown the JVM, or stop all routes, when duration max is triggered.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "shutdown", "enum": [ "shutdown", "stop" ] },
     { "name": "camel.main.durationMaxIdleSeconds", "description": "To specify for how long time in seconds Camel can be idle before automatic terminating the JVM. You can use this to run Camel for a short while.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int" },
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resumable.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resumable.json
index c558592bbd8..3fa19c41bd7 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resumable.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resumable.json
@@ -13,9 +13,10 @@
   },
   "properties": {
     "resumeStrategy": { "index": 0, "kind": "attribute", "displayName": "Resume Strategy", "required": true, "type": "object", "javaType": "org.apache.camel.resume.ResumeStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the resume strategy to use" },
-    "intermittent": { "index": 1, "kind": "attribute", "displayName": "Intermittent", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether the offsets will be intermittently present or whether they must be present in every exchange" },
-    "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "id": { "index": 3, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
-    "description": { "index": 4, "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
+    "loggingLevel": { "index": 1, "kind": "attribute", "displayName": "Logging Level", "label": "advanced", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "ERROR" },
+    "intermittent": { "index": 2, "kind": "attribute", "displayName": "Intermittent", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether the offsets will be intermittently present or whether they must be present in every exchange" },
+    "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
+    "id": { "index": 4, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
+    "description": { "index": 5, "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
index ae3a8d69eeb..be14f57f52d 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties
@@ -55,3 +55,4 @@ wal
 xml-io-dsl
 xml-jaxb-dsl
 yaml-dsl
+yaml-io
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/yaml-io.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/yaml-io.json
new file mode 100644
index 00000000000..85ae50b23c4
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/yaml-io.json
@@ -0,0 +1,15 @@
+{
+  "other": {
+    "kind": "other",
+    "name": "yaml-io",
+    "title": "Yaml Io",
+    "description": "Camel YAML IO",
+    "deprecated": false,
+    "firstVersion": "4.0.0",
+    "label": "dsl",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-yaml-io",
+    "version": "4.0.0-SNAPSHOT"
+  }
+}
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index 8f271236a0b..21689220767 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -11575,7 +11575,7 @@ Set whether recursive keys are allowed. Default value: false
       
   </xs:complexType>
     
-  <xs:complexType final="extension restriction" name="yamlTypeFilterDefinition">
+  <xs:complexType name="yamlTypeFilterDefinition">
         
     <xs:sequence/>
         
diff --git a/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletRouteDumpTest.java b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletRouteDumpTest.java
index fdb2e922752..27822b7cfcd 100644
--- a/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletRouteDumpTest.java
+++ b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletRouteDumpTest.java
@@ -29,7 +29,7 @@ public class KameletRouteDumpTest extends CamelTestSupport {
 
     @Override
     protected void postProcessTest() throws Exception {
-        context().setDumpRoutes(true);
+        context().setDumpRoutes("xml");
         super.postProcessTest();
     }
 
diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
index 22fe97e2853..33cf3735b90 100644
--- a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
@@ -1388,22 +1388,22 @@ public interface CamelContext extends CamelContextLifecycle, RuntimeConfiguratio
      *
      * This requires to have camel-xml-jaxb on the classpath to be able to dump the routes as XML.
      *
-     * @return <tt>true</tt> if dumping is enabled
+     * @return <tt>xml</tt>, or <tt>yaml</tt> if dumping is enabled
      */
-    Boolean isDumpRoutes();
+    String getDumpRoutes();
 
     /**
      * If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates)
-     * represented as XML DSL into the log. This is intended for trouble shooting or to assist during development.
+     * represented as XML/YAML DSL into the log. This is intended for trouble shooting or to assist during development.
      *
      * Sensitive information that may be configured in the route endpoints could potentially be included in the dump
-     * output and is therefore not recommended to be used for production usage.
+     * output and is therefore not recommended being used for production usage.
      *
-     * This requires to have camel-xml-jaxb on the classpath to be able to dump the routes as XML.
+     * This requires to have camel-xml-io/camel-yaml-io on the classpath to be able to dump the routes as XML/YAML.
      *
-     * @param dumpRoutes <tt>true</tt> to enable dumping routes.
+     * @param format xml or yaml
      */
-    void setDumpRoutes(Boolean dumpRoutes);
+    void setDumpRoutes(String format);
 
     /**
      * Whether to enable using data type on Camel messages.
diff --git a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
index 27b39b61576..cc994fdf988 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
@@ -267,6 +267,11 @@ public interface ExtendedCamelContext {
      */
     FactoryFinder getDefaultFactoryFinder();
 
+    /**
+     * Sets the default FactoryFinder which will be used for the loading the factory class from META-INF
+     */
+    void setDefaultFactoryFinder(FactoryFinder factoryFinder);
+
     /**
      * Gets the bootstrap FactoryFinder which will be used for the loading the factory class from META-INF. This
      * bootstrap factory finder is only intended to be used during bootstrap (starting) CamelContext.
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java
new file mode 100644
index 00000000000..ceb87c48270
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java
@@ -0,0 +1,58 @@
+/*
+ * 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.spi;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.NamedNode;
+
+/**
+ * SPI for dumping model definitions into YAML representation.
+ */
+public interface ModelToYAMLDumper {
+
+    /**
+     * Service factory key.
+     */
+    String FACTORY = "modelyaml-dumper";
+
+    /**
+     * Dumps the definition as YAML
+     *
+     * @param  context    the CamelContext
+     * @param  definition the definition, such as a {@link NamedNode}
+     * @return            the output in YAML (is formatted)
+     * @throws Exception  is throw if error marshalling to YAML
+     */
+    String dumpModelAsYaml(CamelContext context, NamedNode definition) throws Exception;
+
+    /**
+     * Dumps the definition as YAML
+     *
+     * @param  context                  the CamelContext
+     * @param  definition               the definition, such as a {@link NamedNode}
+     * @param  resolvePlaceholders      whether to resolve property placeholders in the dumped YAML
+     * @param  resolveDelegateEndpoints whether to resolve delegate endpoints in the dumped YAML (limited to endpoints
+     *                                  used in uri attributes in the model)
+     * @return                          the output in YAML (is formatted)
+     * @throws Exception                is throw if error marshalling to YAML
+     */
+    String dumpModelAsYaml(
+            CamelContext context, NamedNode definition,
+            boolean resolvePlaceholders, boolean resolveDelegateEndpoints)
+            throws Exception;
+
+}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 6781a3ed56c..c67cadb0387 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -125,6 +125,7 @@ import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.spi.MessageHistoryFactory;
 import org.apache.camel.spi.ModelJAXBContextFactory;
 import org.apache.camel.spi.ModelToXMLDumper;
+import org.apache.camel.spi.ModelToYAMLDumper;
 import org.apache.camel.spi.ModelineFactory;
 import org.apache.camel.spi.NodeIdFactory;
 import org.apache.camel.spi.PackageScanClassResolver;
@@ -251,7 +252,7 @@ public abstract class AbstractCamelContext extends BaseService
     private Boolean devConsole = Boolean.FALSE;
     private Boolean sourceLocationEnabled = Boolean.FALSE;
     private Boolean typeConverterStatisticsEnabled = Boolean.FALSE;
-    private Boolean dumpRoutes = Boolean.FALSE;
+    private String dumpRoutes;
     private Boolean useMDCLogging = Boolean.FALSE;
     private String mdcLoggingKeysPattern;
     private Boolean useDataType = Boolean.FALSE;
@@ -380,6 +381,7 @@ public abstract class AbstractCamelContext extends BaseService
         camelContextExtension.lazyAddContextPlugin(ResourceLoader.class, this::createResourceLoader);
         camelContextExtension.lazyAddContextPlugin(BeanProcessorFactory.class, this::createBeanProcessorFactory);
         camelContextExtension.lazyAddContextPlugin(ModelToXMLDumper.class, this::createModelToXMLDumper);
+        camelContextExtension.lazyAddContextPlugin(ModelToYAMLDumper.class, this::createModelToYAMLDumper);
         camelContextExtension.lazyAddContextPlugin(DeferServiceFactory.class, this::createDeferServiceFactory);
         camelContextExtension.lazyAddContextPlugin(AnnotationBasedProcessorFactory.class,
                 this::createAnnotationBasedProcessorFactory);
@@ -1482,9 +1484,11 @@ public abstract class AbstractCamelContext extends BaseService
     public String getEipParameterJsonSchema(String eipName) throws IOException {
         // the eip json schema may be in some of the sub-packages so look until
         // we find it
-        String[] subPackages = new String[] { "", "/config", "/dataformat", "/language", "/loadbalancer", "/rest" };
+        String[] subPackages = new String[] {
+                "", "cloud/", "config/", "dataformat/", "errorhandler/", "language/", "loadbalancer/", "rest/", "transformer/",
+                "validator/" };
         for (String sub : subPackages) {
-            String path = CamelContextHelper.MODEL_DOCUMENTATION_PREFIX + sub + "/" + eipName + ".json";
+            String path = CamelContextHelper.MODEL_DOCUMENTATION_PREFIX + sub + eipName + ".json";
             String inputStream = doLoadResource(eipName, path, "eip");
             if (inputStream != null) {
                 return inputStream;
@@ -2783,7 +2787,7 @@ public abstract class AbstractCamelContext extends BaseService
             LOG.debug("Skip starting routes as CamelContext has been configured with autoStartup=false");
         }
 
-        if (isDumpRoutes() != null && isDumpRoutes()) {
+        if (getDumpRoutes() != null && !"false".equals(getDumpRoutes())) {
             doDumpRoutes();
         }
 
@@ -3467,12 +3471,12 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     @Override
-    public Boolean isDumpRoutes() {
+    public String getDumpRoutes() {
         return dumpRoutes;
     }
 
     @Override
-    public void setDumpRoutes(Boolean dumpRoutes) {
+    public void setDumpRoutes(String dumpRoutes) {
         this.dumpRoutes = dumpRoutes;
     }
 
@@ -4045,6 +4049,8 @@ public abstract class AbstractCamelContext extends BaseService
 
     protected abstract ModelToXMLDumper createModelToXMLDumper();
 
+    protected abstract ModelToYAMLDumper createModelToYAMLDumper();
+
     protected abstract RestBindingJaxbDataFormatFactory createRestBindingJaxbDataFormatFactory();
 
     protected abstract RuntimeCamelCatalog createRuntimeCamelCatalog();
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
index 5d37f197259..f2d77c0aac2 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
@@ -335,6 +335,11 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
         return getFactoryFinder(FactoryFinder.DEFAULT_PATH);
     }
 
+    @Override
+    public void setDefaultFactoryFinder(FactoryFinder factoryFinder) {
+        factories.put(FactoryFinder.DEFAULT_PATH, factoryFinder);
+    }
+
     @Override
     public FactoryFinder getBootstrapFactoryFinder() {
         if (bootstrapFactoryFinder == null) {
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index d9a6e3a2e72..6bc6a1437a8 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -63,6 +63,7 @@ import org.apache.camel.spi.ManagementNameStrategy;
 import org.apache.camel.spi.MessageHistoryFactory;
 import org.apache.camel.spi.ModelJAXBContextFactory;
 import org.apache.camel.spi.ModelToXMLDumper;
+import org.apache.camel.spi.ModelToYAMLDumper;
 import org.apache.camel.spi.ModelineFactory;
 import org.apache.camel.spi.NodeIdFactory;
 import org.apache.camel.spi.PackageScanClassResolver;
@@ -546,7 +547,22 @@ public class SimpleCamelContext extends AbstractCamelContext {
         if (result.isPresent()) {
             return result.get();
         } else {
-            throw new IllegalArgumentException("Cannot find ModelToXMLDumper on classpath. Add camel-xml-jaxb to classpath.");
+            throw new IllegalArgumentException("Cannot find ModelToXMLDumper on classpath. Add camel-xml-io to classpath.");
+        }
+    }
+
+    @Override
+    protected ModelToYAMLDumper createModelToYAMLDumper() {
+        Optional<ModelToYAMLDumper> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                ModelToYAMLDumper.FACTORY,
+                ModelToYAMLDumper.class);
+
+        if (result.isPresent()) {
+            return result.get();
+        } else {
+            throw new IllegalArgumentException("Cannot find ModelToYAMLDumper on classpath. Add camel-yaml-io to classpath.");
         }
     }
 
diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/route-dump b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/route-dump
new file mode 100644
index 00000000000..8644d875400
--- /dev/null
+++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/route-dump
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.impl.console.RouteDumpDevConsole
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
new file mode 100644
index 00000000000..f4e2d2001ab
--- /dev/null
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
@@ -0,0 +1,168 @@
+/*
+ * 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.impl.console;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Route;
+import org.apache.camel.api.management.ManagedCamelContext;
+import org.apache.camel.api.management.mbean.ManagedRouteMBean;
+import org.apache.camel.spi.annotations.DevConsole;
+import org.apache.camel.support.PatternHelper;
+import org.apache.camel.support.console.AbstractDevConsole;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.json.JsonObject;
+
+@DevConsole("route-dump")
+public class RouteDumpDevConsole extends AbstractDevConsole {
+
+    /**
+     * To use either xml or yaml output format
+     */
+    public static final String FORMAT = "format";
+
+    /**
+     * Filters the routes matching by route id, route uri, and source location
+     */
+    public static final String FILTER = "filter";
+
+    /**
+     * Limits the number of entries displayed
+     */
+    public static final String LIMIT = "limit";
+
+    public RouteDumpDevConsole() {
+        super("camel", "route-dump", "Route Dump", "Dump route structure in XML or YAML format");
+    }
+
+    @Override
+    protected String doCallText(Map<String, Object> options) {
+        final StringBuilder sb = new StringBuilder();
+        Function<ManagedRouteMBean, Object> task = mrb -> {
+            String dump = null;
+            try {
+                String format = (String) options.get(FORMAT);
+                if (format == null || "xml".equals(format)) {
+                    dump = mrb.dumpRouteAsXml();
+                } else if ("yaml".equals(format)) {
+                    dump = mrb.dumpRouteAsYaml();
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+            sb.append(String.format("    Id: %s", mrb.getRouteId()));
+            if (mrb.getSourceLocation() != null) {
+                sb.append(String.format("\n    Source: %s", mrb.getSourceLocation()));
+            }
+            if (dump != null && dump.length() > 0) {
+                sb.append("\n\n");
+                for (String line : dump.split("\n")) {
+                    sb.append("    ").append(line).append("\n");
+                }
+                sb.append("\n");
+            }
+
+            sb.append("\n");
+            return null;
+        };
+        doCall(options, task);
+        return sb.toString();
+    }
+
+    @Override
+    protected JsonObject doCallJson(Map<String, Object> options) {
+        final JsonObject root = new JsonObject();
+        final List<JsonObject> list = new ArrayList<>();
+
+        Function<ManagedRouteMBean, Object> task = mrb -> {
+            JsonObject jo = new JsonObject();
+            list.add(jo);
+
+            jo.put("routeId", mrb.getRouteId());
+            jo.put("from", mrb.getEndpointUri());
+            if (mrb.getSourceLocation() != null) {
+                jo.put("source", mrb.getSourceLocation());
+            }
+
+            try {
+                String dump = null;
+                String format = (String) options.get(FORMAT);
+                if (format == null || "xml".equals(format)) {
+                    jo.put("format", "xml");
+                    dump = mrb.dumpRouteAsXml();
+                } else if ("yaml".equals(format)) {
+                    jo.put("format", "yaml");
+                    dump = mrb.dumpRouteAsYaml();
+                }
+                if (dump != null) {
+                    List<JsonObject> code = ConsoleHelper.loadSourceAsJson(new StringReader(dump), null);
+                    if (code != null) {
+                        jo.put("code", code);
+                    }
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+            return null;
+        };
+        doCall(options, task);
+        root.put("routes", list);
+        return root;
+    }
+
+    protected void doCall(Map<String, Object> options, Function<ManagedRouteMBean, Object> task) {
+        String path = (String) options.get(Exchange.HTTP_PATH);
+        String subPath = path != null ? StringHelper.after(path, "/") : null;
+        String filter = (String) options.get(FILTER);
+        String limit = (String) options.get(LIMIT);
+        final int max = limit == null ? Integer.MAX_VALUE : Integer.parseInt(limit);
+
+        ManagedCamelContext mcc = getCamelContext().getCamelContextExtension().getContextPlugin(ManagedCamelContext.class);
+        if (mcc != null) {
+            List<Route> routes = getCamelContext().getRoutes();
+            routes.sort((o1, o2) -> o1.getRouteId().compareToIgnoreCase(o2.getRouteId()));
+            routes.stream()
+                    .map(route -> mcc.getManagedRoute(route.getRouteId()))
+                    .filter(r -> accept(r, filter))
+                    .filter(r -> accept(r, subPath))
+                    .sorted(RouteDumpDevConsole::sort)
+                    .limit(max)
+                    .forEach(task::apply);
+        }
+    }
+
+    private static boolean accept(ManagedRouteMBean mrb, String filter) {
+        if (filter == null || filter.isBlank()) {
+            return true;
+        }
+
+        return PatternHelper.matchPattern(mrb.getRouteId(), filter)
+                || PatternHelper.matchPattern(mrb.getEndpointUri(), filter)
+                || PatternHelper.matchPattern(mrb.getSourceLocationShort(), filter);
+    }
+
+    private static int sort(ManagedRouteMBean o1, ManagedRouteMBean o2) {
+        // sort by id
+        return o1.getRouteId().compareTo(o2.getRouteId());
+    }
+
+}
diff --git a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/DefaultRuntimeCamelCatalog.java b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/DefaultRuntimeCamelCatalog.java
index 8ab4630e554..f88a7b1bf9b 100644
--- a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/DefaultRuntimeCamelCatalog.java
+++ b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/DefaultRuntimeCamelCatalog.java
@@ -52,6 +52,20 @@ public class DefaultRuntimeCamelCatalog extends AbstractCamelCatalog implements
         this.setJSonSchemaResolver(new CamelContextJSonSchemaResolver(camelContext));
     }
 
+    /**
+     * To turn caching on or off
+     */
+    public boolean isCaching() {
+        return caching;
+    }
+
+    /**
+     * To turn caching on or off
+     */
+    public void setCaching(boolean caching) {
+        this.caching = caching;
+    }
+
     @Override
     public void start() {
         // noop
diff --git a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/URISupport.java b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/URISupport.java
index 4e9fe2d0e3b..4673106bd08 100644
--- a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/URISupport.java
+++ b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/URISupport.java
@@ -87,6 +87,20 @@ public final class URISupport {
         return uri;
     }
 
+    /**
+     * Extracts the query parameters from the uri
+     *
+     * @param  uri the uri
+     * @return     query parameters, or <tt>null</tt> if no parameters
+     */
+    public static String extractQuery(String uri) {
+        int idx = uri.indexOf('?');
+        if (idx > -1) {
+            return uri.substring(idx + 1);
+        }
+        return null;
+    }
+
     /**
      * Parses the query parameters of the uri (eg the query part).
      *
diff --git a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/CamelContextConfigurer.java b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/CamelContextConfigurer.java
index 903b657713f..43067b7d8e7 100644
--- a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/CamelContextConfigurer.java
+++ b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/CamelContextConfigurer.java
@@ -48,7 +48,7 @@ public class CamelContextConfigurer extends org.apache.camel.support.component.P
         case "devconsole":
         case "DevConsole": target.setDevConsole(property(camelContext, java.lang.Boolean.class, value)); return true;
         case "dumproutes":
-        case "DumpRoutes": target.setDumpRoutes(property(camelContext, java.lang.Boolean.class, value)); return true;
+        case "DumpRoutes": target.setDumpRoutes(property(camelContext, java.lang.String.class, value)); return true;
         case "executorservicemanager":
         case "ExecutorServiceManager": target.setExecutorServiceManager(property(camelContext, org.apache.camel.spi.ExecutorServiceManager.class, value)); return true;
         case "globaloptions":
@@ -167,7 +167,7 @@ public class CamelContextConfigurer extends org.apache.camel.support.component.P
         case "devconsole":
         case "DevConsole": return java.lang.Boolean.class;
         case "dumproutes":
-        case "DumpRoutes": return java.lang.Boolean.class;
+        case "DumpRoutes": return java.lang.String.class;
         case "executorservicemanager":
         case "ExecutorServiceManager": return org.apache.camel.spi.ExecutorServiceManager.class;
         case "globaloptions":
@@ -287,7 +287,7 @@ public class CamelContextConfigurer extends org.apache.camel.support.component.P
         case "devconsole":
         case "DevConsole": return target.isDevConsole();
         case "dumproutes":
-        case "DumpRoutes": return target.isDumpRoutes();
+        case "DumpRoutes": return target.getDumpRoutes();
         case "executorservicemanager":
         case "ExecutorServiceManager": return target.getExecutorServiceManager();
         case "globaloptions":
diff --git a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
index f1074957424..e383a105ae6 100644
--- a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
+++ b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
@@ -25,6 +25,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "BasePackageScan": target.setBasePackageScan(property(camelContext, java.lang.String.class, value)); return true;
         case "bootstrapfactoryfinder":
         case "BootstrapFactoryFinder": target.setBootstrapFactoryFinder(property(camelContext, org.apache.camel.spi.FactoryFinder.class, value)); return true;
+        case "defaultfactoryfinder":
+        case "DefaultFactoryFinder": target.setDefaultFactoryFinder(property(camelContext, org.apache.camel.spi.FactoryFinder.class, value)); return true;
         case "description":
         case "Description": target.setDescription(property(camelContext, java.lang.String.class, value)); return true;
         case "errorhandlerfactory":
@@ -58,6 +60,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "BasePackageScan": return java.lang.String.class;
         case "bootstrapfactoryfinder":
         case "BootstrapFactoryFinder": return org.apache.camel.spi.FactoryFinder.class;
+        case "defaultfactoryfinder":
+        case "DefaultFactoryFinder": return org.apache.camel.spi.FactoryFinder.class;
         case "description":
         case "Description": return java.lang.String.class;
         case "errorhandlerfactory":
@@ -92,6 +96,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "BasePackageScan": return target.getBasePackageScan();
         case "bootstrapfactoryfinder":
         case "BootstrapFactoryFinder": return target.getBootstrapFactoryFinder();
+        case "defaultfactoryfinder":
+        case "DefaultFactoryFinder": return target.getDefaultFactoryFinder();
         case "description":
         case "Description": return target.getDescription();
         case "errorhandlerfactory":
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 4e5217c4b45..e6d7e035fd0 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -71,6 +71,7 @@ import org.apache.camel.spi.ExecutorServiceManager;
 import org.apache.camel.spi.LocalBeanRepositoryAware;
 import org.apache.camel.spi.ModelReifierFactory;
 import org.apache.camel.spi.ModelToXMLDumper;
+import org.apache.camel.spi.ModelToYAMLDumper;
 import org.apache.camel.spi.PackageScanClassResolver;
 import org.apache.camel.spi.PropertiesComponent;
 import org.apache.camel.spi.Registry;
@@ -153,6 +154,15 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
 
     @Override
     protected void doDumpRoutes() {
+        if ("yaml".equalsIgnoreCase(getDumpRoutes())) {
+            doDumpRoutesAsYaml();
+        } else {
+            // xml is default
+            doDumpRoutesAsXml();
+        }
+    }
+
+    protected void doDumpRoutesAsXml() {
         final ModelToXMLDumper dumper = PluginHelper.getModelToXMLDumper(this);
 
         int size = getRouteDefinitions().size();
@@ -210,6 +220,49 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
         }
     }
 
+    protected void doDumpRoutesAsYaml() {
+        final ModelToYAMLDumper dumper = PluginHelper.getModelToYAMLDumper(this);
+
+        int size = getRouteDefinitions().size();
+        if (size > 0) {
+            LOG.info("Dumping {} routes as YAML", size);
+            RoutesDefinition def = new RoutesDefinition();
+            def.setRoutes(getRouteDefinitions());
+            try {
+                String yaml = dumper.dumpModelAsYaml(this, def, true, true);
+                LOG.info("\n\n{}\n", yaml);
+            } catch (Exception e) {
+                LOG.warn("Error dumping routes to YAML due to {}. This exception is ignored.", e.getMessage(), e);
+            }
+        }
+
+        size = getRestDefinitions().size();
+        if (size > 0) {
+            LOG.info("Dumping {} rests as YAML", size);
+            RestsDefinition def = new RestsDefinition();
+            def.setRests(getRestDefinitions());
+            try {
+                String taml = dumper.dumpModelAsYaml(this, def, true, true);
+                LOG.info("\n\n{}\n", taml);
+            } catch (Exception e) {
+                LOG.warn("Error dumping rests to YAML due to {}. This exception is ignored.", e.getMessage(), e);
+            }
+        }
+
+        size = getRouteTemplateDefinitions().size();
+        if (size > 0) {
+            LOG.info("Dumping {} route templates as YAML", size);
+            RouteTemplatesDefinition def = new RouteTemplatesDefinition();
+            def.setRouteTemplates(getRouteTemplateDefinitions());
+            try {
+                String yaml = dumper.dumpModelAsYaml(this, def, true, true);
+                LOG.info("\n\n{}\n", yaml);
+            } catch (Exception e) {
+                LOG.warn("Error dumping route-templates to YAML due to {}. This exception is ignored.", e.getMessage(), e);
+            }
+        }
+    }
+
     public static void setNoStart(boolean b) {
         getOptions().put(OPTION_NO_START, b);
     }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/resumable.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/resumable.json
index c558592bbd8..3fa19c41bd7 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/resumable.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/resumable.json
@@ -13,9 +13,10 @@
   },
   "properties": {
     "resumeStrategy": { "index": 0, "kind": "attribute", "displayName": "Resume Strategy", "required": true, "type": "object", "javaType": "org.apache.camel.resume.ResumeStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the resume strategy to use" },
-    "intermittent": { "index": 1, "kind": "attribute", "displayName": "Intermittent", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether the offsets will be intermittently present or whether they must be present in every exchange" },
-    "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "id": { "index": 3, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
-    "description": { "index": 4, "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
+    "loggingLevel": { "index": 1, "kind": "attribute", "displayName": "Logging Level", "label": "advanced", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "ERROR" },
+    "intermittent": { "index": 2, "kind": "attribute", "displayName": "Intermittent", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether the offsets will be intermittently present or whether they must be present in every exchange" },
+    "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
+    "id": { "index": 4, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
+    "description": { "index": 5, "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
   }
 }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/CatchDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/CatchDefinition.java
index 17335d3154c..7ebba65904a 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/CatchDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/CatchDefinition.java
@@ -17,7 +17,6 @@
 package org.apache.camel.model;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 import jakarta.xml.bind.annotation.XmlAccessType;
@@ -52,12 +51,11 @@ public class CatchDefinition extends OutputDefinition<CatchDefinition> {
     }
 
     public CatchDefinition(List<Class<? extends Throwable>> exceptionClasses) {
-        this.exceptionClasses = exceptionClasses;
+        exception(exceptionClasses);
     }
 
     public CatchDefinition(Class<? extends Throwable> exceptionType) {
-        exceptionClasses = new ArrayList<>();
-        exceptionClasses.add(exceptionType);
+        exception(exceptionType);
     }
 
     @Override
@@ -104,11 +102,22 @@ public class CatchDefinition extends OutputDefinition<CatchDefinition> {
      * @return            the builder
      */
     public CatchDefinition exception(Class<? extends Throwable>... exceptions) {
+        return exception(List.of(exceptions));
+    }
+
+    /**
+     * The exception(s) to catch.
+     *
+     * @param  exceptions one or more exceptions
+     * @return            the builder
+     */
+    public CatchDefinition exception(List<Class<? extends Throwable>> exceptions) {
         if (exceptionClasses == null) {
             exceptionClasses = new ArrayList<>();
         }
-        if (exceptions != null) {
-            exceptionClasses.addAll(Arrays.asList(exceptions));
+        for (Class<? extends Throwable> c : exceptions) {
+            this.exceptionClasses.add(c);
+            this.exceptions.add(c.getName());
         }
         return this;
     }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ResumableDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ResumableDefinition.java
index b889607c8e4..05235185106 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/ResumableDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ResumableDefinition.java
@@ -42,6 +42,7 @@ public class ResumableDefinition extends NoOutputDefinition<ResumableDefinition>
     @Metadata(required = true, javaType = "org.apache.camel.resume.ResumeStrategy")
     private String resumeStrategy;
 
+    @XmlAttribute
     @Metadata(label = "advanced", javaType = "org.apache.camel.LoggingLevel", defaultValue = "ERROR",
               enums = "TRACE,DEBUG,INFO,WARN,ERROR,OFF")
     private String loggingLevel;
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterDefinition.java
index 329cf8e5fde..ee61b427283 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterDefinition.java
@@ -26,7 +26,7 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "dataformat,transformation,yaml", title = "YAML Type Filter")
 @XmlRootElement(name = "typeFilter")
 @XmlAccessorType(XmlAccessType.FIELD)
-public final class YAMLTypeFilterDefinition {
+public class YAMLTypeFilterDefinition {
 
     @XmlAttribute
     private String value;
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AggregateReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AggregateReifier.java
index 228157e413b..5a5910d381a 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AggregateReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AggregateReifier.java
@@ -57,6 +57,11 @@ public class AggregateReifier extends ProcessorReifier<AggregateDefinition> {
         AsyncProcessor target = PluginHelper.getInternalProcessorFactory(camelContext)
                 .addUnitOfWorkProcessorAdvice(camelContext, childProcessor, route);
 
+        // correlation expression is required
+        if (definition.getExpression() == null) {
+            throw new IllegalArgumentException("CorrelationExpression must be set on " + definition);
+        }
+
         Expression correlation = createExpression(definition.getExpression());
         AggregationStrategy strategy = getConfiguredAggregationStrategy(definition);
         // strategy is required
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index 5e73b4a300d..fea2e9c2cae 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -1215,7 +1215,7 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
             context.setMDCLoggingKeysPattern(CamelContextHelper.parseText(context, getMDCLoggingKeysPattern()));
         }
         if (getDumpRoutes() != null) {
-            context.setDumpRoutes(CamelContextHelper.parseBoolean(context, getDumpRoutes()));
+            context.setDumpRoutes(CamelContextHelper.parseText(context, getDumpRoutes()));
         }
         if (getUseDataType() != null) {
             context.setUseDataType(CamelContextHelper.parseBoolean(context, getUseDataType()));
diff --git a/core/camel-core/pom.xml b/core/camel-core/pom.xml
index 149b1f82874..12a2221ec67 100644
--- a/core/camel-core/pom.xml
+++ b/core/camel-core/pom.xml
@@ -150,6 +150,10 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-xml-jaxp</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-yaml-io</artifactId>
+        </dependency>
 
         <!-- required logging api dependency by camel-core -->
         <dependency>
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java
index 3007fd1897c..a5a72c9f259 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.util;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
 
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.builder.RouteBuilder;
@@ -39,14 +40,16 @@ public class DumpModelAsXmlNamespaceTest extends ContextTestSupport {
         assertNotNull(xml);
 
         Document dom = context.getTypeConverter().convertTo(Document.class, xml);
-        Element rootNode = dom.getDocumentElement();
-        assertNotNull(rootNode);
+        NodeList nl = dom.getElementsByTagName("xpath");
+        assertEquals(2, nl.getLength());
 
-        String attributeFoo = rootNode.getAttribute("xmlns:foo");
+        Element n1 = (Element) nl.item(0);
+        String attributeFoo = n1.getAttribute("xmlns:foo");
         assertNotNull(attributeFoo);
         assertEquals(URL_FOO, attributeFoo);
 
-        String attributeBar = rootNode.getAttribute("xmlns:bar");
+        Element n2 = (Element) nl.item(1);
+        String attributeBar = n2.getAttribute("xmlns:bar");
         assertNotNull(attributeBar);
         assertEquals(URL_BAR, attributeBar);
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSourceLocationTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSourceLocationTest.java
new file mode 100644
index 00000000000..6273e3ade86
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSourceLocationTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.util;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.support.PluginHelper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class DumpModelAsYamlSourceLocationTest extends DumpModelAsYamlTestSupport {
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        context.setDebugging(true);
+        return context;
+    }
+
+    @Test
+    public void testDumpModelAsYaml() throws Exception {
+        String yaml
+                = PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, context.getRouteDefinition("myRoute"));
+        assertNotNull(yaml);
+        log.info(yaml);
+
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 67"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 68"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 69"));
+        Assertions.assertTrue(yaml.contains("sourceLocation: DumpModelAsYamlSourceLocationTest.java"));
+    }
+
+    @Test
+    public void testDumpModelAsYamlExternal() throws Exception {
+        String yaml = PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, context.getRouteDefinition("cool"));
+        assertNotNull(yaml);
+        log.info(yaml);
+
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 25"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 26"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 27"));
+        Assertions.assertTrue(yaml.contains("sourceLocation: MyCoolRoute.java"));
+    }
+
+    @Override
+    protected RouteBuilder[] createRouteBuilders() throws Exception {
+        return new RouteBuilder[] {
+                new RouteBuilder() {
+                    @Override
+                    public void configure() throws Exception {
+                        from("direct:start").routeId("myRoute")
+                                .filter(simple("${body} > 10"))
+                                .to("mock:result");
+                    }
+                },
+                new MyCoolRoute()
+        };
+    }
+
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSplitNestedChoiceEndRouteTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSplitNestedChoiceEndRouteTest.java
new file mode 100644
index 00000000000..8db57bf39ca
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSplitNestedChoiceEndRouteTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util;
+
+import java.io.FileInputStream;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.support.PluginHelper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class DumpModelAsYamlSplitNestedChoiceEndRouteTest extends DumpModelAsYamlTestSupport {
+
+    @Test
+    public void testDumpModelAsYaml() throws Exception {
+        String out = PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, context.getRouteDefinition("myRoute"));
+        assertNotNull(out);
+        log.info(out);
+
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/org/apache/camel/util/split-choice.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").routeId("myRoute").split().body().to("mock:sub").id("myMock").choice().when(header("foo"))
+                        .to("mock:foo").when(header("bar")).to("mock:bar")
+                        .otherwise().to("mock:other").end().end().to("mock:last");
+            }
+        };
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTestSupport.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTestSupport.java
new file mode 100644
index 00000000000..df04a21e7ef
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTestSupport.java
@@ -0,0 +1,42 @@
+/*
+ * 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.util;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.NamedNode;
+import org.apache.camel.spi.NodeIdFactory;
+
+public abstract class DumpModelAsYamlTestSupport extends ContextTestSupport {
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext ctx = super.createCamelContext();
+        ctx.getCamelContextExtension().addContextPlugin(NodeIdFactory.class, buildNodeIdFactory());
+        return ctx;
+    }
+
+    private static NodeIdFactory buildNodeIdFactory() {
+        return new NodeIdFactory() {
+            @Override
+            public String createId(NamedNode definition) {
+                return definition.getShortName(); // do not use counter
+            }
+        };
+    }
+
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTransformRouteTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTransformRouteTest.java
new file mode 100644
index 00000000000..7ae7efd684d
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTransformRouteTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.util;
+
+import java.io.FileInputStream;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.support.PluginHelper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class DumpModelAsYamlTransformRouteTest extends DumpModelAsYamlTestSupport {
+
+    @Test
+    public void testDumpModelAsYaml() throws Exception {
+        String out = PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, context.getRouteDefinition("myRoute"));
+        assertNotNull(out);
+        log.info(out);
+
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/org/apache/camel/util/transform.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").routeId("myRoute").transform().simple("Hello ${body}").to("mock:result").id("myMock");
+            }
+        };
+    }
+}
diff --git a/core/camel-core/src/test/resources/org/apache/camel/util/split-choice.yaml b/core/camel-core/src/test/resources/org/apache/camel/util/split-choice.yaml
new file mode 100644
index 00000000000..77d63dc8ea2
--- /dev/null
+++ b/core/camel-core/src/test/resources/org/apache/camel/util/split-choice.yaml
@@ -0,0 +1,41 @@
+- route:
+    id: myRoute
+    from:
+      uri: direct:start
+      steps:
+        - split:
+            id: split
+            simple:
+              expression: "${body}"
+            steps:
+              - to:
+                  id: myMock
+                  uri: mock:sub
+              - choice:
+                  id: choice
+                  steps:
+                    - when:
+                        id: when
+                        header:
+                          expression: foo
+                        steps:
+                          - to:
+                              id: to
+                              uri: mock:foo
+                    - when:
+                        id: when
+                        header:
+                          expression: bar
+                        steps:
+                          - to:
+                              id: to
+                              uri: mock:bar
+                    - otherwise:
+                        id: otherwise
+                        steps:
+                          - to:
+                              id: to
+                              uri: mock:other
+        - to:
+            id: to
+            uri: mock:last
diff --git a/core/camel-core/src/test/resources/org/apache/camel/util/transform.yaml b/core/camel-core/src/test/resources/org/apache/camel/util/transform.yaml
new file mode 100644
index 00000000000..5051e915aaf
--- /dev/null
+++ b/core/camel-core/src/test/resources/org/apache/camel/util/transform.yaml
@@ -0,0 +1,12 @@
+- route:
+    id: myRoute
+    from:
+      uri: direct:start
+      steps:
+        - transform:
+            id: transform
+            simple:
+              expression: "Hello ${body}"
+        - to:
+            id: myMock
+            uri: mock:result
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
index 24f2bb7a78f..d9d958ccc81 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
@@ -72,7 +72,7 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "devconsoleenabled":
         case "DevConsoleEnabled": target.setDevConsoleEnabled(property(camelContext, boolean.class, value)); return true;
         case "dumproutes":
-        case "DumpRoutes": target.setDumpRoutes(property(camelContext, boolean.class, value)); return true;
+        case "DumpRoutes": target.setDumpRoutes(property(camelContext, java.lang.String.class, value)); return true;
         case "durationhitexitcode":
         case "DurationHitExitCode": target.setDurationHitExitCode(property(camelContext, int.class, value)); return true;
         case "durationmaxaction":
@@ -315,7 +315,7 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "devconsoleenabled":
         case "DevConsoleEnabled": return boolean.class;
         case "dumproutes":
-        case "DumpRoutes": return boolean.class;
+        case "DumpRoutes": return java.lang.String.class;
         case "durationhitexitcode":
         case "DurationHitExitCode": return int.class;
         case "durationmaxaction":
@@ -559,7 +559,7 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "devconsoleenabled":
         case "DevConsoleEnabled": return target.isDevConsoleEnabled();
         case "dumproutes":
-        case "DumpRoutes": return target.isDumpRoutes();
+        case "DumpRoutes": return target.getDumpRoutes();
         case "durationhitexitcode":
         case "DurationHitExitCode": return target.getDurationHitExitCode();
         case "durationmaxaction":
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index d608e6d195d..b0ef1361e58 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -37,7 +37,7 @@
     { "name": "camel.main.debugging", "description": "Sets whether debugging is enabled or not. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.description", "description": "Sets the description (intended for humans) of the Camel application.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "name": "camel.main.devConsoleEnabled", "description": "Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
-    { "name": "camel.main.dumpRoutes", "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-jaxb  [...]
+    { "name": "camel.main.dumpRoutes", "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml [...]
     { "name": "camel.main.durationHitExitCode", "description": "Sets the exit code for the application if duration was hit", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "integer", "javaType": "int" },
     { "name": "camel.main.durationMaxAction", "description": "Controls whether the Camel application should shutdown the JVM, or stop all routes, when duration max is triggered.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "shutdown", "enum": [ "shutdown", "stop" ] },
     { "name": "camel.main.durationMaxIdleSeconds", "description": "To specify for how long time in seconds Camel can be idle before automatic terminating the JVM. You can use this to run Camel for a short while.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index 5481c32a19e..85969008130 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -49,7 +49,7 @@ The camel.main supports 118 options, which are listed below.
 | *camel.main.debugging* | Sets whether debugging is enabled or not. Default is false. | false | boolean
 | *camel.main.description* | Sets the description (intended for humans) of the Camel application. |  | String
 | *camel.main.devConsoleEnabled* | Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage. | false | boolean
-| *camel.main.dumpRoutes* | If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-jaxb on the classpath to be able [...]
+| *camel.main.dumpRoutes* | If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-io/camel-yaml-io on the cla [...]
 | *camel.main.durationHitExitCode* | Sets the exit code for the application if duration was hit |  | int
 | *camel.main.durationMaxAction* | Controls whether the Camel application should shutdown the JVM, or stop all routes, when duration max is triggered. | shutdown | String
 | *camel.main.durationMaxIdle{zwsp}Seconds* | To specify for how long time in seconds Camel can be idle before automatic terminating the JVM. You can use this to run Camel for a short while. |  | int
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index 626e5aec44c..772a0d3fa42 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -238,7 +238,7 @@ public final class DefaultConfigurationConfigurer {
         camelContext.setAutowiredEnabled(config.isAutowiredEnabled());
         camelContext.setUseBreadcrumb(config.isUseBreadcrumb());
         camelContext.setUseDataType(config.isUseDataType());
-        camelContext.setDumpRoutes(config.isDumpRoutes());
+        camelContext.setDumpRoutes(config.getDumpRoutes());
         camelContext.setUseMDCLogging(config.isUseMdcLogging());
         camelContext.setMDCLoggingKeysPattern(config.getMdcLoggingKeysPattern());
         camelContext.setLoadTypeConverters(config.isLoadTypeConverters());
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 593e983995f..b664348f418 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -127,7 +127,8 @@ public abstract class DefaultConfigurationProperties<T> {
     private String exchangeFactory = "default";
     private int exchangeFactoryCapacity = 100;
     private boolean exchangeFactoryStatisticsEnabled;
-    private boolean dumpRoutes;
+    @Metadata(enums = "xml,yaml")
+    private String dumpRoutes;
     private Map<String, String> globalOptions;
     // route controller
     private boolean routeControllerSuperviseEnabled;
@@ -1342,20 +1343,20 @@ public abstract class DefaultConfigurationProperties<T> {
         this.exchangeFactoryStatisticsEnabled = exchangeFactoryStatisticsEnabled;
     }
 
-    public boolean isDumpRoutes() {
+    public String getDumpRoutes() {
         return dumpRoutes;
     }
 
     /**
      * If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates)
-     * represented as XML DSL into the log. This is intended for trouble shooting or to assist during development.
+     * represented as XML/YAML DSL into the log. This is intended for trouble shooting or to assist during development.
      *
      * Sensitive information that may be configured in the route endpoints could potentially be included in the dump
      * output and is therefore not recommended being used for production usage.
      *
-     * This requires to have camel-xml-jaxb on the classpath to be able to dump the routes as XML.
+     * This requires to have camel-xml-io/camel-yaml-io on the classpath to be able to dump the routes as XML/YAML.
      */
-    public void setDumpRoutes(boolean dumpRoutes) {
+    public void setDumpRoutes(String dumpRoutes) {
         this.dumpRoutes = dumpRoutes;
     }
 
@@ -2520,15 +2521,15 @@ public abstract class DefaultConfigurationProperties<T> {
     }
 
     /**
-     * If enable then Camel will during startup dump all loaded routes (incl rests and route templates) represented as
-     * XML DSL into the log. This is intended for trouble shooting or to assist during development.
+     * If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates)
+     * represented as XML/YAML DSL into the log. This is intended for trouble shooting or to assist during development.
      *
      * Sensitive information that may be configured in the route endpoints could potentially be included in the dump
-     * output and is therefore not recommended to be used for production usage.
+     * output and is therefore not recommended being used for production usage.
      *
-     * This requires to have camel-xml-jaxb on the classpath to be able to dump the routes as XML.
+     * This requires to have camel-xml-io/camel-yaml-io on the classpath to be able to dump the routes as XML/YAML.
      */
-    public T withDumpRoutes(boolean dumpRoutes) {
+    public T withDumpRoutes(String dumpRoutes) {
         this.dumpRoutes = dumpRoutes;
         return (T) this;
     }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java b/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
index f0e41beee80..a1ff0c1da8a 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
@@ -440,11 +440,13 @@ public final class MainHelper {
      * Warning, don't use for crazy big streams :)
      */
     private static void loadLines(InputStream in, Set<String> lines, Function<String, String> func) throws IOException {
-        try (final InputStreamReader isr = new InputStreamReader(in);
-             final BufferedReader reader = new LineNumberReader(isr)) {
-            String line;
-            while ((line = reader.readLine()) != null) {
-                lines.add(func.apply(line));
+        if (in != null) {
+            try (final InputStreamReader isr = new InputStreamReader(in);
+                 final BufferedReader reader = new LineNumberReader(isr)) {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    lines.add(func.apply(line));
+                }
             }
         }
     }
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
index fab50c0579d..9f71a946cdc 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
@@ -210,6 +210,15 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
     @ManagedOperation(description = "Dumps the route templates as XML")
     String dumpRouteTemplatesAsXml() throws Exception;
 
+    @ManagedOperation(description = "Dumps the routes as YAML")
+    String dumpRoutesAsYaml() throws Exception;
+
+    @ManagedOperation(description = "Dumps the routes as YAML")
+    String dumpRoutesAsYaml(boolean resolvePlaceholders) throws Exception;
+
+    @ManagedOperation(description = "Dumps the routes as YAML")
+    String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean resolveDelegateEndpoints) throws Exception;
+
     /**
      * Creates the endpoint by the given uri
      *
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
index ce73585d0bd..1908180f2a4 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
@@ -124,6 +124,15 @@ public interface ManagedRouteMBean extends ManagedPerformanceCounterMBean {
     @ManagedOperation(description = "Dumps the route as XML")
     String dumpRouteAsXml(boolean resolvePlaceholders, boolean resolveDelegateEndpoints) throws Exception;
 
+    @ManagedOperation(description = "Dumps the route as YAML")
+    String dumpRouteAsYaml() throws Exception;
+
+    @ManagedOperation(description = "Dumps the route as YAML")
+    String dumpRouteAsYaml(boolean resolvePlaceholders) throws Exception;
+
+    @ManagedOperation(description = "Dumps the route as YAML")
+    String dumpRouteAsYaml(boolean resolvePlaceholders, boolean resolveDelegateEndpoints) throws Exception;
+
     @ManagedOperation(description = "Dumps the route stats as XML")
     String dumpRouteStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception;
 
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index aed7adf4875..1684cf344b2 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -493,6 +493,31 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
                 resolveDelegateEndpoints);
     }
 
+    @Override
+    public String dumpRoutesAsYaml() throws Exception {
+        return dumpRoutesAsYaml(false, false);
+    }
+
+    @Override
+    public String dumpRoutesAsYaml(boolean resolvePlaceholders) throws Exception {
+        return dumpRoutesAsYaml(resolvePlaceholders, false);
+    }
+
+    @Override
+    public String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean resolveDelegateEndpoints) throws Exception {
+        List<RouteDefinition> routes = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
+        if (routes.isEmpty()) {
+            return null;
+        }
+
+        // use routes definition to dump the routes
+        RoutesDefinition def = new RoutesDefinition();
+        def.setRoutes(routes);
+
+        return PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, resolvePlaceholders,
+                resolveDelegateEndpoints);
+    }
+
     @Override
     public String dumpRouteTemplatesAsXml() throws Exception {
         List<RouteTemplateDefinition> templates
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
index 4b914e79d71..6387afd1c7b 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
@@ -403,6 +403,28 @@ public class ManagedRoute extends ManagedPerformanceCounter implements TimerList
         return null;
     }
 
+    @Override
+    public String dumpRouteAsYaml() throws Exception {
+        return dumpRouteAsYaml(false, false);
+    }
+
+    @Override
+    public String dumpRouteAsYaml(boolean resolvePlaceholders) throws Exception {
+        return dumpRouteAsYaml(resolvePlaceholders, false);
+    }
+
+    @Override
+    public String dumpRouteAsYaml(boolean resolvePlaceholders, boolean resolveDelegateEndpoints) throws Exception {
+        String id = route.getId();
+        RouteDefinition def = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(id);
+        if (def != null) {
+            return PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, resolvePlaceholders,
+                    resolveDelegateEndpoints);
+        }
+
+        return null;
+    }
+
     @Override
     public String dumpRouteStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception {
         // in this logic we need to calculate the accumulated processing time for the processor in the route
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRoutesAsYamlTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRoutesAsYamlTest.java
new file mode 100644
index 00000000000..a7a27c5055e
--- /dev/null
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRoutesAsYamlTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.management;
+
+import java.util.Properties;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisabledOnOs(OS.AIX)
+public class ManagedCamelContextDumpRoutesAsYamlTest extends ManagementTestSupport {
+
+    @Test
+    public void testDumpAsYaml() throws Exception {
+        MBeanServer mbeanServer = getMBeanServer();
+
+        ObjectName on = getContextObjectName();
+
+        String yaml = (String) mbeanServer.invoke(on, "dumpRoutesAsYaml", null, null);
+        assertNotNull(yaml);
+        log.info(yaml);
+
+        assertTrue(yaml.contains("route"));
+        assertTrue(yaml.contains("myRoute"));
+        assertTrue(yaml.contains("myOtherRoute"));
+        assertTrue(yaml.contains("direct:start"));
+        assertTrue(yaml.contains("{{result}}"));
+        assertTrue(yaml.contains("seda:bar"));
+        assertTrue(yaml.contains("ref:bar"));
+        assertTrue(yaml.contains("expression: bar"));
+    }
+
+    @Test
+    public void testDumpAsYamlResolvePlaceholder() throws Exception {
+        MBeanServer mbeanServer = getMBeanServer();
+
+        ObjectName on = getContextObjectName();
+
+        String yaml = (String) mbeanServer.invoke(on, "dumpRoutesAsYaml", new Object[] { true }, new String[] { "boolean" });
+        assertNotNull(yaml);
+        log.info(yaml);
+
+        assertTrue(yaml.contains("route"));
+        assertTrue(yaml.contains("myRoute"));
+        assertTrue(yaml.contains("myOtherRoute"));
+        assertTrue(yaml.contains("direct:start"));
+        assertTrue(yaml.contains("mock:result"));
+        assertTrue(yaml.contains("seda:bar"));
+        assertTrue(yaml.contains("ref:bar"));
+        assertTrue(yaml.contains("expression: bar"));
+    }
+
+    @Test
+    public void testDumpAsYamlResolvePlaceholderDelegateEndpoint() throws Exception {
+        MBeanServer mbeanServer = getMBeanServer();
+
+        ObjectName on = getContextObjectName();
+
+        String yaml = (String) mbeanServer.invoke(on, "dumpRoutesAsYaml", new Object[] { true, true },
+                new String[] { "boolean", "boolean" });
+        assertNotNull(yaml);
+        log.info(yaml);
+
+        assertTrue(yaml.contains("route"));
+        assertTrue(yaml.contains("myRoute"));
+        assertTrue(yaml.contains("myOtherRoute"));
+        assertTrue(yaml.contains("direct:start"));
+        assertTrue(yaml.contains("mock:result"));
+        assertTrue(yaml.contains("bar"));
+        assertTrue(yaml.contains("seda:bar"));
+        assertTrue(yaml.contains("mock://bar"));
+        assertTrue(yaml.contains("expression: bar"));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                Properties props = new Properties();
+                props.put("result", "mock:result");
+                context.getPropertiesComponent().setOverrideProperties(props);
+
+                Endpoint bar = context.getEndpoint("mock:bar");
+                bindToRegistry("bar", bar);
+
+                from("direct:start").routeId("myRoute")
+                        .log("Got ${body}")
+                        .to("{{result}}");
+
+                from("seda:bar").routeId("myOtherRoute")
+                        .filter().header("bar")
+                        .to("ref:bar")
+                        .end();
+            }
+        };
+    }
+
+}
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PluginHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/PluginHelper.java
index 37e6ac4679b..0d79ac7789a 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/PluginHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/PluginHelper.java
@@ -42,6 +42,7 @@ import org.apache.camel.spi.InternalProcessorFactory;
 import org.apache.camel.spi.LanguageResolver;
 import org.apache.camel.spi.ModelJAXBContextFactory;
 import org.apache.camel.spi.ModelToXMLDumper;
+import org.apache.camel.spi.ModelToYAMLDumper;
 import org.apache.camel.spi.ModelineFactory;
 import org.apache.camel.spi.PackageScanClassResolver;
 import org.apache.camel.spi.PackageScanResourceResolver;
@@ -579,6 +580,20 @@ public final class PluginHelper {
         return extendedCamelContext.getContextPlugin(ModelToXMLDumper.class);
     }
 
+    /**
+     * Gets the {@link ModelToXMLDumper} to be used.
+     */
+    public static ModelToYAMLDumper getModelToYAMLDumper(CamelContext camelContext) {
+        return getModelToYAMLDumper(camelContext.getCamelContextExtension());
+    }
+
+    /**
+     * Gets the {@link ModelToXMLDumper} to be used.
+     */
+    public static ModelToYAMLDumper getModelToYAMLDumper(ExtendedCamelContext extendedCamelContext) {
+        return extendedCamelContext.getContextPlugin(ModelToYAMLDumper.class);
+    }
+
     /**
      * Gets the {@link DeferServiceFactory} to use.
      */
diff --git a/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java b/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
index b3d44e3920c..f91ba31c4a7 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
@@ -168,6 +168,16 @@ public final class StringHelper {
      * @return   <tt>true</tt> if the string starts and ends with either single or double quotes.
      */
     public static boolean isQuoted(String s) {
+        return isSingleQuoted(s) || isDoubleQuoted(s);
+    }
+
+    /**
+     * Whether the string starts and ends with single quotes.
+     *
+     * @param  s the string
+     * @return   <tt>true</tt> if the string starts and ends with single quotes.
+     */
+    public static boolean isSingleQuoted(String s) {
         if (ObjectHelper.isEmpty(s)) {
             return false;
         }
@@ -175,6 +185,21 @@ public final class StringHelper {
         if (s.startsWith("'") && s.endsWith("'")) {
             return true;
         }
+
+        return false;
+    }
+
+    /**
+     * Whether the string starts and ends with double quotes.
+     *
+     * @param  s the string
+     * @return   <tt>true</tt> if the string starts and ends with double quotes.
+     */
+    public static boolean isDoubleQuoted(String s) {
+        if (ObjectHelper.isEmpty(s)) {
+            return false;
+        }
+
         if (s.startsWith("\"") && s.endsWith("\"")) {
             return true;
         }
diff --git a/core/camel-xml-io/pom.xml b/core/camel-xml-io/pom.xml
index 6a29601d2a6..8aa7b4cdd26 100644
--- a/core/camel-xml-io/pom.xml
+++ b/core/camel-xml-io/pom.xml
@@ -54,6 +54,17 @@
             <artifactId>junit-jupiter</artifactId>
             <scope>test</scope>
         </dependency>
+        <!-- logging -->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j2-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 68a33cda6a7..102ed75482a 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -911,17 +911,12 @@ public class ModelParser extends BaseParser {
         return doParse(new ResumableDefinition(), (def, key, val) -> {
             switch (key) {
                 case "intermittent": def.setIntermittent(val); break;
+                case "loggingLevel": def.setLoggingLevel(val); break;
                 case "resumeStrategy": def.setResumeStrategy(val); break;
                 default: return processorDefinitionAttributeHandler().accept(def, key, val);
             }
             return true;
-        }, (def, key) -> {
-            if ("loggingLevel".equals(key)) {
-                def.setLoggingLevel(doParseText());
-                return true;
-            }
-            return optionalIdentifiedDefinitionElementHandler().accept(def, key);
-        }, noValueHandler());
+        }, optionalIdentifiedDefinitionElementHandler(), noValueHandler());
     }
     protected RollbackDefinition doParseRollbackDefinition() throws IOException, XmlPullParserException {
         return doParse(new RollbackDefinition(), (def, key, val) -> {
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index 35a5d650473..28bd49d589c 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
@@ -28,6 +28,7 @@ import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
+import org.apache.camel.Expression;
 import org.apache.camel.model.*;
 import org.apache.camel.model.app.*;
 import org.apache.camel.model.cloud.*;
@@ -1049,13 +1050,13 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("completionTimeoutCheckerInterval", def.getCompletionTimeoutCheckerInterval());
         doWriteAttribute("optimisticLocking", def.getOptimisticLocking());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("optimisticLockRetryPolicy", def.getOptimisticLockRetryPolicyDefinition(), this::doWriteOptimisticLockRetryPolicyDefinition);
         doWriteElement("correlationExpression", def.getCorrelationExpression(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("completionPredicate", def.getCompletionPredicate(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("completionSizeExpression", def.getCompletionSizeExpression(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("completionTimeoutExpression", def.getCompletionTimeoutExpression(), this::doWriteExpressionSubElementDefinition);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteBeanDefinition(
             String name,
@@ -1068,7 +1069,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("scope", def.getScope());
         doWriteAttribute("beanType", def.getBeanType());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBeanFactoryDefinitionAttributes(
             BeanFactoryDefinition<?, ?> def)
@@ -1091,7 +1092,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteBeanFactoryDefinitionAttributes(def);
         doWriteBeanFactoryDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCatchDefinition(
             String name,
@@ -1100,10 +1101,10 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("onWhen", def.getOnWhen(), this::doWriteWhenDefinition);
         doWriteList(null, "exception", def.getExceptions(), this::doWriteString);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteChoiceDefinition(
             String name,
@@ -1115,7 +1116,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteElement("otherwise", def.getOtherwise(), this::doWriteOtherwiseDefinition);
         doWriteList(null, null, def.getWhenClauses(), this::doWriteWhenDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCircuitBreakerDefinition(
             String name,
@@ -1126,10 +1127,10 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("configuration", def.getConfiguration());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteElement("faultToleranceConfiguration", def.getFaultToleranceConfiguration(), this::doWriteFaultToleranceConfigurationDefinition);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("resilience4jConfiguration", def.getResilience4jConfiguration(), this::doWriteResilience4jConfigurationDefinition);
         doWriteElement("onFallback", def.getOnFallback(), this::doWriteOnFallbackDefinition);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteClaimCheckDefinition(
             String name,
@@ -1143,7 +1144,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("operation", def.getOperation());
         doWriteAttribute("key", def.getKey());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteContextScanDefinition(
             String name,
@@ -1153,7 +1154,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("includeNonSingletons", def.getIncludeNonSingletons());
         doWriteList(null, "excludes", def.getExcludes(), this::doWriteString);
         doWriteList(null, "includes", def.getIncludes(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteConvertBodyDefinition(
             String name,
@@ -1165,7 +1166,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("type", def.getType());
         doWriteAttribute("mandatory", def.getMandatory());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDataFormatDefinitionAttributes(
             DataFormatDefinition def)
@@ -1178,7 +1179,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteDataFormatDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDelayDefinition(
             String name,
@@ -1190,7 +1191,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("callerRunsWhenRejected", def.getCallerRunsWhenRejected());
         doWriteAttribute("asyncDelayed", def.getAsyncDelayed());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDescriptionDefinition(
             String name,
@@ -1198,7 +1199,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteValue(def.getText());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDynamicRouterDefinition(
             String name,
@@ -1210,7 +1211,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints());
         doWriteAttribute("cacheSize", def.getCacheSize());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteEnrichDefinition(
             String name,
@@ -1227,7 +1228,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("shareUnitOfWork", def.getShareUnitOfWork());
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteErrorHandlerDefinition(
             String name,
@@ -1244,7 +1245,7 @@ public class ModelWriter extends BaseWriter {
                 case "SpringTransactionErrorHandlerDefinition" -> doWriteSpringTransactionErrorHandlerDefinition("springTransactionErrorHandler", (SpringTransactionErrorHandlerDefinition) def.getErrorHandlerType());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteExpressionNodeAttributes(
             ExpressionNode def)
@@ -1264,15 +1265,15 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteExpressionNodeAttributes(def);
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteExpressionSubElementDefinition(
             String name,
             ExpressionSubElementDefinition def)
             throws IOException {
-        startElement(name);
+        startExpressionElement(name);
         doWriteElement(null, def.getExpressionType(), this::doWriteExpressionDefinitionRef);
-        endElement();
+        endExpressionElement(name);
     }
     protected void doWriteFaultToleranceConfigurationCommonAttributes(
             FaultToleranceConfigurationCommon def)
@@ -1298,7 +1299,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFaultToleranceConfigurationCommonAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFaultToleranceConfigurationDefinition(
             String name,
@@ -1306,7 +1307,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFaultToleranceConfigurationCommonAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFilterDefinition(
             String name,
@@ -1316,7 +1317,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("statusPropertyName", def.getStatusPropertyName());
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFinallyDefinition(
             String name,
@@ -1326,7 +1327,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFromDefinition(
             String name,
@@ -1336,7 +1337,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteAttribute("uri", def.getUri());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteGlobalOptionDefinition(
             String name,
@@ -1345,7 +1346,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("value", def.getValue());
         doWriteAttribute("key", def.getKey());
-        endElement();
+        endElement(name);
     }
     protected void doWriteGlobalOptionsDefinition(
             String name,
@@ -1353,7 +1354,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteList(null, "globalOption", def.getGlobalOptions(), this::doWriteGlobalOptionDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteIdempotentConsumerDefinition(
             String name,
@@ -1367,7 +1368,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("idempotentRepository", def.getIdempotentRepository());
         doWriteAttribute("removeOnFailure", def.getRemoveOnFailure());
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteIdentifiedTypeAttributes(
             IdentifiedType def)
@@ -1380,7 +1381,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteInputTypeDefinition(
             String name,
@@ -1391,7 +1392,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("urn", def.getUrn());
         doWriteAttribute("validate", def.getValidate());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteInterceptDefinitionAttributes(
             InterceptDefinition def)
@@ -1411,7 +1412,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteInterceptDefinitionAttributes(def);
         doWriteInterceptDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteInterceptFromDefinition(
             String name,
@@ -1421,7 +1422,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("uri", def.getUri());
         doWriteInterceptDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteInterceptSendToEndpointDefinition(
             String name,
@@ -1434,7 +1435,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("skipSendToOriginalEndpoint", def.getSkipSendToOriginalEndpoint());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteKameletDefinition(
             String name,
@@ -1445,7 +1446,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("name", def.getName());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteLoadBalanceDefinition(
             String name,
@@ -1454,7 +1455,6 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement(null, def.getLoadBalancerType(), (n, v) -> {
             switch (v.getClass().getSimpleName()) {
                 case "CustomLoadBalancerDefinition" -> doWriteCustomLoadBalancerDefinition("customLoadBalancer", (CustomLoadBalancerDefinition) def.getLoadBalancerType());
@@ -1466,7 +1466,8 @@ public class ModelWriter extends BaseWriter {
                 case "WeightedLoadBalancerDefinition" -> doWriteWeightedLoadBalancerDefinition("weighted", (WeightedLoadBalancerDefinition) def.getLoadBalancerType());
             }
         });
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteLoadBalancerDefinitionAttributes(
             LoadBalancerDefinition def)
@@ -1479,7 +1480,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteLoadBalancerDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteLogDefinition(
             String name,
@@ -1493,7 +1494,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("message", def.getMessage());
         doWriteAttribute("loggingLevel", def.getLoggingLevel());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteLoopDefinition(
             String name,
@@ -1505,7 +1506,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("breakOnShutdown", def.getBreakOnShutdown());
         doWriteAttribute("copy", def.getCopy());
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteMarshalDefinition(
             String name,
@@ -1558,7 +1559,7 @@ public class ModelWriter extends BaseWriter {
                 case "ZipFileDataFormat" -> doWriteZipFileDataFormat("zipFile", (ZipFileDataFormat) def.getDataFormatType());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteMulticastDefinition(
             String name,
@@ -1579,7 +1580,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOnCompletionDefinition(
             String name,
@@ -1596,7 +1597,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteElement("onWhen", def.getOnWhen(), this::doWriteWhenDefinition);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOnExceptionDefinition(
             String name,
@@ -1610,14 +1611,14 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("onExceptionOccurredRef", def.getOnExceptionOccurredRef());
         doWriteAttribute("redeliveryPolicyRef", def.getRedeliveryPolicyRef());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("continued", def.getContinued(), this::doWriteExpressionSubElementDefinition);
         doWriteList(null, "exception", def.getExceptions(), this::doWriteString);
         doWriteElement("retryWhile", def.getRetryWhile(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("redeliveryPolicy", def.getRedeliveryPolicyType(), this::doWriteRedeliveryPolicyDefinition);
         doWriteElement("handled", def.getHandled(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("onWhen", def.getOnWhen(), this::doWriteWhenDefinition);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteOnFallbackDefinition(
             String name,
@@ -1628,7 +1629,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("fallbackViaNetwork", def.getFallbackViaNetwork());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOptimisticLockRetryPolicyDefinition(
             String name,
@@ -1640,7 +1641,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("maximumRetries", def.getMaximumRetries());
         doWriteAttribute("exponentialBackOff", def.getExponentialBackOff());
         doWriteAttribute("maximumRetryDelay", def.getMaximumRetryDelay());
-        endElement();
+        endElement(name);
     }
     protected void doWriteOptionalIdentifiedDefinitionAttributes(
             OptionalIdentifiedDefinition<?> def)
@@ -1660,7 +1661,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOtherwiseDefinition(
             String name,
@@ -1670,7 +1671,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOutputExpressionNodeAttributes(
             OutputExpressionNode def)
@@ -1690,7 +1691,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteOutputExpressionNodeAttributes(def);
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOutputTypeDefinition(
             String name,
@@ -1701,7 +1702,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("urn", def.getUrn());
         doWriteAttribute("validate", def.getValidate());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePackageScanDefinition(
             String name,
@@ -1711,7 +1712,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "excludes", def.getExcludes(), this::doWriteString);
         doWriteList(null, "includes", def.getIncludes(), this::doWriteString);
         doWriteList(null, "package", def.getPackages(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWritePausableDefinition(
             String name,
@@ -1722,7 +1723,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("untilCheck", def.getUntilCheck());
         doWriteAttribute("consumerListener", def.getConsumerListener());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePipelineDefinition(
             String name,
@@ -1732,7 +1733,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWritePolicyDefinition(
             String name,
@@ -1743,7 +1744,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ref", def.getRef());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWritePollEnrichDefinition(
             String name,
@@ -1759,7 +1760,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("timeout", def.getTimeout());
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteProcessDefinition(
             String name,
@@ -1769,7 +1770,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteProcessorDefinitionAttributes(
             ProcessorDefinition<?> def)
@@ -1790,7 +1791,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteProcessorDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePropertyDefinition(
             String name,
@@ -1799,7 +1800,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("value", def.getValue());
         doWriteAttribute("key", def.getKey());
-        endElement();
+        endElement(name);
     }
     protected void doWritePropertyDefinitions(
             String name,
@@ -1807,7 +1808,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteList(null, "property", def.getProperties(), this::doWritePropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWritePropertyExpressionDefinition(
             String name,
@@ -1816,7 +1817,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("key", def.getKey());
         doWriteElement(null, def.getExpression(), this::doWriteExpressionDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRecipientListDefinition(
             String name,
@@ -1839,7 +1840,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("shareUnitOfWork", def.getShareUnitOfWork());
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRedeliveryPolicyDefinition(
             String name,
@@ -1871,7 +1872,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("maximumRedeliveries", def.getMaximumRedeliveries());
         doWriteAttribute("logExhausted", def.getLogExhausted());
         doWriteAttribute("useCollisionAvoidance", def.getUseCollisionAvoidance());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRemoveHeaderDefinition(
             String name,
@@ -1881,7 +1882,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("name", def.getName());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRemoveHeadersDefinition(
             String name,
@@ -1892,7 +1893,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("excludePattern", def.getExcludePattern());
         doWriteAttribute("pattern", def.getPattern());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRemovePropertiesDefinition(
             String name,
@@ -1903,7 +1904,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("excludePattern", def.getExcludePattern());
         doWriteAttribute("pattern", def.getPattern());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRemovePropertyDefinition(
             String name,
@@ -1913,7 +1914,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("name", def.getName());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteResequenceDefinition(
             String name,
@@ -1922,7 +1923,6 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement(null, def.getExpression(), this::doWriteExpressionDefinitionRef);
         doWriteElement(null, def.getResequencerConfig(), (n, v) -> {
             switch (v.getClass().getSimpleName()) {
@@ -1930,7 +1930,8 @@ public class ModelWriter extends BaseWriter {
                 case "StreamResequencerConfig" -> doWriteStreamResequencerConfig("stream-config", (StreamResequencerConfig) def.getResequencerConfig());
             }
         });
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteResilience4jConfigurationCommonAttributes(
             Resilience4jConfigurationCommon def)
@@ -1963,7 +1964,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteResilience4jConfigurationCommonAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteResilience4jConfigurationDefinition(
             String name,
@@ -1971,7 +1972,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteResilience4jConfigurationCommonAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestContextRefDefinition(
             String name,
@@ -1979,7 +1980,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteResumableDefinition(
             String name,
@@ -1989,9 +1990,9 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("resumeStrategy", def.getResumeStrategy());
         doWriteAttribute("intermittent", def.getIntermittent());
+        doWriteAttribute("loggingLevel", def.getLoggingLevel());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteElement("loggingLevel", def.getLoggingLevel(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRollbackDefinition(
             String name,
@@ -2003,7 +2004,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("message", def.getMessage());
         doWriteAttribute("markRollbackOnlyLast", def.getMarkRollbackOnlyLast());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteBuilderDefinition(
             String name,
@@ -2012,7 +2013,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteConfigurationContextRefDefinition(
             String name,
@@ -2020,7 +2021,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteConfigurationDefinition(
             String name,
@@ -2036,7 +2037,7 @@ public class ModelWriter extends BaseWriter {
         doWriteElement("errorHandler", def.getErrorHandler(), this::doWriteErrorHandlerDefinition);
         doWriteList(null, "interceptFrom", def.getInterceptFroms(), this::doWriteInterceptFromDefinition);
         doWriteList(null, "intercept", def.getIntercepts(), this::doWriteInterceptDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteConfigurationsDefinition(
             String name,
@@ -2044,7 +2045,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteList(null, null, def.getRouteConfigurations(), this::doWriteRouteConfigurationDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteContextRefDefinition(
             String name,
@@ -2052,7 +2053,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteDefinition(
             String name,
@@ -2083,7 +2084,7 @@ public class ModelWriter extends BaseWriter {
         doWriteElement(null, def.getInputType(), this::doWriteInputTypeDefinitionRef);
         doWriteElement(null, def.getOutputType(), this::doWriteOutputTypeDefinitionRef);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplateBeanDefinition(
             String name,
@@ -2092,7 +2093,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteBeanFactoryDefinitionAttributes(def);
         doWriteBeanFactoryDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplateContextRefDefinition(
             String name,
@@ -2100,7 +2101,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplateDefinition(
             String name,
@@ -2112,7 +2113,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "templateParameter", def.getTemplateParameters(), this::doWriteRouteTemplateParameterDefinition);
         doWriteElement("route", def.getRoute(), this::doWriteRouteDefinition);
         doWriteList(null, "templateBean", def.getTemplateBeans(), this::doWriteRouteTemplateBeanDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplateParameterDefinition(
             String name,
@@ -2123,7 +2124,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("name", def.getName());
         doWriteAttribute("description", def.getDescription());
         doWriteAttribute("required", toString(def.getRequired()));
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplatesDefinition(
             String name,
@@ -2133,7 +2134,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getRouteTemplates(), this::doWriteRouteTemplateDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRoutesDefinition(
             String name,
@@ -2143,7 +2144,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getRoutes(), this::doWriteRouteDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRoutingSlipDefinition(
             String name,
@@ -2155,7 +2156,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints());
         doWriteAttribute("cacheSize", def.getCacheSize());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSagaActionUriDefinition(
             String name,
@@ -2164,7 +2165,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSendDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSagaDefinition(
             String name,
@@ -2177,11 +2178,11 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("sagaService", def.getSagaService());
         doWriteAttribute("timeout", def.getTimeout());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("completion", def.getCompletion(), this::doWriteSagaActionUriDefinition);
         doWriteList(null, "option", def.getOptions(), this::doWritePropertyExpressionDefinition);
         doWriteElement("compensation", def.getCompensation(), this::doWriteSagaActionUriDefinition);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteSamplingDefinition(
             String name,
@@ -2192,7 +2193,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("messageFrequency", def.getMessageFrequency());
         doWriteAttribute("samplePeriod", def.getSamplePeriod());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteScriptDefinition(
             String name,
@@ -2201,7 +2202,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSendDefinitionAttributes(
             SendDefinition<?> def)
@@ -2221,7 +2222,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSendDefinitionAttributes(def);
         doWriteSendDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSetBodyDefinition(
             String name,
@@ -2230,7 +2231,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSetExchangePatternDefinition(
             String name,
@@ -2240,7 +2241,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("pattern", def.getPattern());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSetHeaderDefinition(
             String name,
@@ -2250,7 +2251,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("name", def.getName());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSetPropertyDefinition(
             String name,
@@ -2260,7 +2261,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("name", def.getName());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSortDefinition(
             String name,
@@ -2270,7 +2271,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("comparator", def.getComparator());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSplitDefinition(
             String name,
@@ -2291,7 +2292,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("shareUnitOfWork", def.getShareUnitOfWork());
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStepDefinition(
             String name,
@@ -2301,7 +2302,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStopDefinition(
             String name,
@@ -2310,7 +2311,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTemplatedRouteBeanDefinition(
             String name,
@@ -2319,7 +2320,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteBeanFactoryDefinitionAttributes(def);
         doWriteBeanFactoryDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTemplatedRouteDefinition(
             String name,
@@ -2331,7 +2332,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("prefixId", def.getPrefixId());
         doWriteList(null, "bean", def.getBeans(), this::doWriteTemplatedRouteBeanDefinition);
         doWriteList(null, "parameter", def.getParameters(), this::doWriteTemplatedRouteParameterDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTemplatedRouteParameterDefinition(
             String name,
@@ -2340,7 +2341,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("name", def.getName());
         doWriteAttribute("value", def.getValue());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTemplatedRoutesDefinition(
             String name,
@@ -2350,7 +2351,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getTemplatedRoutes(), this::doWriteTemplatedRouteDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteThreadPoolProfileDefinition(
             String name,
@@ -2367,7 +2368,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("rejectedPolicy", def.getRejectedPolicy());
         doWriteAttribute("timeUnit", def.getTimeUnit());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteThreadsDefinition(
             String name,
@@ -2386,7 +2387,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("rejectedPolicy", def.getRejectedPolicy());
         doWriteAttribute("timeUnit", def.getTimeUnit());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteThrottleDefinition(
             String name,
@@ -2401,7 +2402,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("asyncDelayed", def.getAsyncDelayed());
         doWriteExpressionNodeElements(def);
         doWriteElement("correlationExpression", def.getCorrelationExpression(), this::doWriteExpressionSubElementDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteThrowExceptionDefinition(
             String name,
@@ -2413,7 +2414,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("message", def.getMessage());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteToDefinition(
             String name,
@@ -2423,7 +2424,7 @@ public class ModelWriter extends BaseWriter {
         doWriteSendDefinitionAttributes(def);
         doWriteAttribute("pattern", def.getPattern());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteToDynamicDefinitionAttributes(
             ToDynamicDefinition def)
@@ -2448,7 +2449,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteToDynamicDefinitionAttributes(def);
         doWriteToDynamicDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransactedDefinition(
             String name,
@@ -2459,7 +2460,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ref", def.getRef());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransformDefinition(
             String name,
@@ -2468,7 +2469,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTryDefinition(
             String name,
@@ -2478,7 +2479,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteUnmarshalDefinition(
             String name,
@@ -2532,7 +2533,7 @@ public class ModelWriter extends BaseWriter {
                 case "ZipFileDataFormat" -> doWriteZipFileDataFormat("zipFile", (ZipFileDataFormat) def.getDataFormatType());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteValidateDefinition(
             String name,
@@ -2542,7 +2543,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("predicateExceptionFactory", def.getPredicateExceptionFactory());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteValueDefinition(
             String name,
@@ -2550,7 +2551,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteValue(def.getValue());
-        endElement();
+        endElement(name);
     }
     protected void doWriteWhenDefinition(
             String name,
@@ -2559,7 +2560,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteWireTapDefinition(
             String name,
@@ -2572,7 +2573,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("executorService", def.getExecutorService());
         doWriteAttribute("copy", def.getCopy());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteApplicationDefinition(
             String name,
@@ -2580,7 +2581,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteBeansDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBeanPropertiesDefinition(
             String name,
@@ -2588,7 +2589,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteList(null, "property", def.getProperties(), this::doWriteBeanPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBeanPropertyDefinition(
             String name,
@@ -2598,7 +2599,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("value", def.getValue());
         doWriteAttribute("key", def.getKey());
         doWriteElement("properties", def.getProperties(), this::doWriteBeanPropertiesDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBeansDefinitionElements(
             BeansDefinition def)
@@ -2618,7 +2619,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteBeansDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteComponentScanDefinition(
             String name,
@@ -2626,7 +2627,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("base-package", def.getBasePackage());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRegistryBeanDefinition(
             String name,
@@ -2636,7 +2637,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("name", def.getName());
         doWriteAttribute("type", def.getType());
         doWriteElement("properties", new BeanPropertiesAdapter().marshal(def.getProperties()), this::doWriteBeanPropertiesDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBlacklistServiceCallServiceFilterConfiguration(
             String name,
@@ -2646,7 +2647,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
         doWriteList(null, "servers", def.getServers(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCachingServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2666,7 +2667,7 @@ public class ModelWriter extends BaseWriter {
                 case "StaticServiceCallServiceDiscoveryConfiguration" -> doWriteStaticServiceCallServiceDiscoveryConfiguration("staticServiceDiscovery", (StaticServiceCallServiceDiscoveryConfiguration) def.getServiceDiscoveryConfiguration());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteCombinedServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2684,7 +2685,7 @@ public class ModelWriter extends BaseWriter {
                 case "CachingServiceCallServiceDiscoveryConfiguration" -> doWriteCachingServiceCallServiceDiscoveryConfiguration("cachingServiceDiscovery", (CachingServiceCallServiceDiscoveryConfiguration) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteCombinedServiceCallServiceFilterConfiguration(
             String name,
@@ -2701,7 +2702,7 @@ public class ModelWriter extends BaseWriter {
                 case "PassThroughServiceCallServiceFilterConfiguration" -> doWritePassThroughServiceCallServiceFilterConfiguration("passThroughServiceFilter", (PassThroughServiceCallServiceFilterConfiguration) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteConsulServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2719,7 +2720,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("blockSeconds", def.getBlockSeconds());
         doWriteAttribute("url", def.getUrl());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomServiceCallServiceFilterConfiguration(
             String name,
@@ -2729,7 +2730,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getServiceFilterRef());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDefaultServiceCallServiceLoadBalancerConfiguration(
             String name,
@@ -2738,7 +2739,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDnsServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2749,7 +2750,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("domain", def.getDomain());
         doWriteAttribute("proto", def.getProto());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteHealthyServiceCallServiceFilterConfiguration(
             String name,
@@ -2758,7 +2759,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteKubernetesServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2786,7 +2787,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("trustCerts", def.getTrustCerts());
         doWriteAttribute("username", def.getUsername());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePassThroughServiceCallServiceFilterConfiguration(
             String name,
@@ -2795,7 +2796,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallConfigurationAttributes(
             ServiceCallConfiguration def)
@@ -2814,7 +2815,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteServiceCallConfigurationAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallConfigurationDefinition(
             String name,
@@ -2856,7 +2857,7 @@ public class ModelWriter extends BaseWriter {
             }
         });
         doWriteElement("expression", def.getExpressionConfiguration(), this::doWriteServiceCallExpressionConfiguration);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallDefinition(
             String name,
@@ -2901,7 +2902,7 @@ public class ModelWriter extends BaseWriter {
             }
         });
         doWriteElement("expression", def.getExpressionConfiguration(), this::doWriteServiceCallExpressionConfiguration);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallExpressionConfiguration(
             String name,
@@ -2913,7 +2914,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("portHeader", def.getPortHeader());
         doWriteServiceCallConfigurationElements(def);
         doWriteElement(null, def.getExpressionType(), this::doWriteExpressionDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallServiceChooserConfiguration(
             String name,
@@ -2922,7 +2923,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallServiceDiscoveryConfigurationAttributes(
             ServiceCallServiceDiscoveryConfiguration def)
@@ -2941,7 +2942,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteServiceCallServiceDiscoveryConfigurationAttributes(def);
         doWriteServiceCallServiceDiscoveryConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallServiceFilterConfigurationAttributes(
             ServiceCallServiceFilterConfiguration def)
@@ -2960,7 +2961,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteServiceCallServiceFilterConfigurationAttributes(def);
         doWriteServiceCallServiceFilterConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallServiceLoadBalancerConfigurationAttributes(
             ServiceCallServiceLoadBalancerConfiguration def)
@@ -2979,7 +2980,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteServiceCallServiceLoadBalancerConfigurationAttributes(def);
         doWriteServiceCallServiceLoadBalancerConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStaticServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2989,7 +2990,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
         doWriteList(null, "servers", def.getServers(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteZooKeeperServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -3006,7 +3007,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("sessionTimeout", def.getSessionTimeout());
         doWriteAttribute("connectionTimeout", def.getConnectionTimeout());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBatchResequencerConfig(
             String name,
@@ -3018,14 +3019,14 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("allowDuplicates", def.getAllowDuplicates());
         doWriteAttribute("batchTimeout", def.getBatchTimeout());
         doWriteAttribute("ignoreInvalidExchanges", def.getIgnoreInvalidExchanges());
-        endElement();
+        endElement(name);
     }
     protected void doWriteResequencerConfig(
             String name,
             ResequencerConfig def)
             throws IOException {
         startElement(name);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStreamResequencerConfig(
             String name,
@@ -3038,7 +3039,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ignoreInvalidExchanges", def.getIgnoreInvalidExchanges());
         doWriteAttribute("deliveryAttemptInterval", def.getDeliveryAttemptInterval());
         doWriteAttribute("capacity", def.getCapacity());
-        endElement();
+        endElement(name);
     }
     protected void doWriteASN1DataFormat(
             String name,
@@ -3048,7 +3049,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("unmarshalType", def.getUnmarshalTypeName());
         doWriteAttribute("usingIterator", def.getUsingIterator());
-        endElement();
+        endElement(name);
     }
     protected void doWriteAvroDataFormat(
             String name,
@@ -3076,7 +3077,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("objectMapper", def.getObjectMapper());
         doWriteAttribute("library", toString(def.getLibrary()));
         doWriteAttribute("autoDiscoverObjectMapper", def.getAutoDiscoverObjectMapper());
-        endElement();
+        endElement(name);
     }
     protected void doWriteBarcodeDataFormat(
             String name,
@@ -3088,7 +3089,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("width", def.getWidth());
         doWriteAttribute("imageType", def.getImageType());
         doWriteAttribute("height", def.getHeight());
-        endElement();
+        endElement(name);
     }
     protected void doWriteBase64DataFormat(
             String name,
@@ -3099,7 +3100,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("urlSafe", def.getUrlSafe());
         doWriteAttribute("lineSeparator", def.getLineSeparator());
         doWriteAttribute("lineLength", def.getLineLength());
-        endElement();
+        endElement(name);
     }
     protected void doWriteBindyDataFormat(
             String name,
@@ -3112,7 +3113,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("locale", def.getLocale());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("allowEmptyStream", def.getAllowEmptyStream());
-        endElement();
+        endElement(name);
     }
     protected void doWriteCBORDataFormat(
             String name,
@@ -3130,7 +3131,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("enableFeatures", def.getEnableFeatures());
         doWriteAttribute("useList", def.getUseList());
         doWriteAttribute("disableFeatures", def.getDisableFeatures());
-        endElement();
+        endElement(name);
     }
     protected void doWriteCryptoDataFormat(
             String name,
@@ -3147,7 +3148,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("keyRef", def.getKeyRef());
         doWriteAttribute("bufferSize", def.getBufferSize());
         doWriteAttribute("algorithm", def.getAlgorithm());
-        endElement();
+        endElement(name);
     }
     protected void doWriteCsvDataFormat(
             String name,
@@ -3184,7 +3185,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("marshallerFactoryRef", def.getMarshallerFactoryRef());
         doWriteAttribute("recordSeparator", def.getRecordSeparator());
         doWriteList(null, "header", def.getHeader(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomDataFormat(
             String name,
@@ -3193,7 +3194,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDataFormatsDefinition(
             String name,
@@ -3243,7 +3244,7 @@ public class ModelWriter extends BaseWriter {
                 case "ZipFileDataFormat" -> doWriteZipFileDataFormat("zipFile", (ZipFileDataFormat) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteFhirDataformatAttributes(
             FhirDataformat def)
@@ -3274,7 +3275,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFhirDataformatAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFhirJsonDataFormat(
             String name,
@@ -3282,7 +3283,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFhirDataformatAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFhirXmlDataFormat(
             String name,
@@ -3290,7 +3291,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFhirDataformatAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFlatpackDataFormat(
             String name,
@@ -3306,7 +3307,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("parserFactoryRef", def.getParserFactoryRef());
         doWriteAttribute("textQualifier", def.getTextQualifier());
         doWriteAttribute("ignoreExtraColumns", def.getIgnoreExtraColumns());
-        endElement();
+        endElement(name);
     }
     protected void doWriteGrokDataFormat(
             String name,
@@ -3318,7 +3319,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("namedOnly", def.getNamedOnly());
         doWriteAttribute("pattern", def.getPattern());
         doWriteAttribute("allowMultipleMatchesPerLine", def.getAllowMultipleMatchesPerLine());
-        endElement();
+        endElement(name);
     }
     protected void doWriteGzipDeflaterDataFormat(
             String name,
@@ -3326,7 +3327,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteHL7DataFormat(
             String name,
@@ -3335,7 +3336,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("validate", def.getValidate());
-        endElement();
+        endElement(name);
     }
     protected void doWriteIcalDataFormat(
             String name,
@@ -3344,7 +3345,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("validating", def.getValidating());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJacksonXMLDataFormat(
             String name,
@@ -3368,7 +3369,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("moduleRefs", def.getModuleRefs());
         doWriteAttribute("enableJaxbAnnotationModule", def.getEnableJaxbAnnotationModule());
         doWriteAttribute("xmlMapper", def.getXmlMapper());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJaxbDataFormat(
             String name,
@@ -3396,7 +3397,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("partClass", def.getPartClass());
         doWriteAttribute("jaxbProviderProperties", def.getJaxbProviderProperties());
         doWriteAttribute("partNamespace", def.getPartNamespace());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJsonApiDataFormat(
             String name,
@@ -3406,7 +3407,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("dataFormatTypes", def.getDataFormatTypes());
         doWriteAttribute("mainFormatType", def.getMainFormatType());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJsonDataFormat(
             String name,
@@ -3436,7 +3437,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("useDefaultObjectMapper", def.getUseDefaultObjectMapper());
         doWriteAttribute("objectMapper", def.getObjectMapper());
         doWriteAttribute("namingStrategy", def.getNamingStrategy());
-        endElement();
+        endElement(name);
     }
     protected void doWriteLZFDataFormat(
             String name,
@@ -3445,7 +3446,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("usingParallelCompression", def.getUsingParallelCompression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteMimeMultipartDataFormat(
             String name,
@@ -3458,7 +3459,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("multipartSubType", def.getMultipartSubType());
         doWriteAttribute("includeHeaders", def.getIncludeHeaders());
         doWriteAttribute("binaryContent", def.getBinaryContent());
-        endElement();
+        endElement(name);
     }
     protected void doWritePGPDataFormat(
             String name,
@@ -3480,7 +3481,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("signatureKeyFileName", def.getSignatureKeyFileName());
         doWriteAttribute("hashAlgorithm", def.getHashAlgorithm());
         doWriteAttribute("algorithm", def.getAlgorithm());
-        endElement();
+        endElement(name);
     }
     protected void doWriteParquetAvroDataFormat(
             String name,
@@ -3489,7 +3490,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("unmarshalType", def.getUnmarshalTypeName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteProtobufDataFormat(
             String name,
@@ -3518,7 +3519,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("schemaResolver", def.getSchemaResolver());
         doWriteAttribute("useDefaultObjectMapper", def.getUseDefaultObjectMapper());
         doWriteAttribute("objectMapper", def.getObjectMapper());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRssDataFormat(
             String name,
@@ -3526,7 +3527,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSoapDataFormat(
             String name,
@@ -3540,7 +3541,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("contextPath", def.getContextPath());
         doWriteAttribute("encoding", def.getEncoding());
         doWriteAttribute("version", def.getVersion());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSwiftMtDataFormat(
             String name,
@@ -3549,7 +3550,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("writeInJson", def.getWriteInJson());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSwiftMxDataFormat(
             String name,
@@ -3561,7 +3562,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("writeInJson", def.getWriteInJson());
         doWriteAttribute("writeConfigRef", def.getWriteConfigRef());
         doWriteAttribute("readConfigRef", def.getReadConfigRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSyslogDataFormat(
             String name,
@@ -3569,7 +3570,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTarFileDataFormat(
             String name,
@@ -3581,7 +3582,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("usingIterator", def.getUsingIterator());
         doWriteAttribute("preservePathElements", def.getPreservePathElements());
         doWriteAttribute("allowEmptyDirectory", def.getAllowEmptyDirectory());
-        endElement();
+        endElement(name);
     }
     protected void doWriteThriftDataFormat(
             String name,
@@ -3592,7 +3593,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("contentTypeHeader", def.getContentTypeHeader());
         doWriteAttribute("contentTypeFormat", def.getContentTypeFormat());
         doWriteAttribute("instanceClass", def.getInstanceClass());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTidyMarkupDataFormat(
             String name,
@@ -3602,7 +3603,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("omitXmlDeclaration", def.getOmitXmlDeclaration());
         doWriteAttribute("dataObjectType", def.getDataObjectTypeName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityAbstractDataFormatAttributes(
             UniVocityAbstractDataFormat def)
@@ -3634,7 +3635,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteUniVocityAbstractDataFormatAttributes(def);
         doWriteUniVocityAbstractDataFormatElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityCsvDataFormat(
             String name,
@@ -3647,7 +3648,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("delimiter", def.getDelimiter());
         doWriteAttribute("quoteAllFields", def.getQuoteAllFields());
         doWriteUniVocityAbstractDataFormatElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityFixedDataFormat(
             String name,
@@ -3659,7 +3660,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("padding", def.getPadding());
         doWriteAttribute("skipTrailingCharsUntilNewline", def.getSkipTrailingCharsUntilNewline());
         doWriteUniVocityAbstractDataFormatElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityHeader(
             String name,
@@ -3668,7 +3669,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("length", def.getLength());
         doWriteValue(def.getName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityTsvDataFormat(
             String name,
@@ -3678,7 +3679,7 @@ public class ModelWriter extends BaseWriter {
         doWriteUniVocityAbstractDataFormatAttributes(def);
         doWriteAttribute("escapeChar", def.getEscapeChar());
         doWriteUniVocityAbstractDataFormatElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteXMLSecurityDataFormat(
             String name,
@@ -3698,7 +3699,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("secureTag", def.getSecureTag());
         doWriteAttribute("xmlCipherAlgorithm", def.getXmlCipherAlgorithm());
         doWriteAttribute("passPhrase", def.getPassPhrase());
-        endElement();
+        endElement(name);
     }
     protected void doWriteYAMLDataFormat(
             String name,
@@ -3718,7 +3719,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("useApplicationContextClassLoader", def.getUseApplicationContextClassLoader());
         doWriteAttribute("allowRecursiveKeys", def.getAllowRecursiveKeys());
         doWriteList(null, "typeFilter", def.getTypeFilters(), this::doWriteYAMLTypeFilterDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteYAMLTypeFilterDefinition(
             String name,
@@ -3727,7 +3728,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("type", def.getType());
         doWriteAttribute("value", def.getValue());
-        endElement();
+        endElement(name);
     }
     protected void doWriteZipDeflaterDataFormat(
             String name,
@@ -3736,7 +3737,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("compressionLevel", def.getCompressionLevel());
-        endElement();
+        endElement(name);
     }
     protected void doWriteZipFileDataFormat(
             String name,
@@ -3748,7 +3749,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("usingIterator", def.getUsingIterator());
         doWriteAttribute("preservePathElements", def.getPreservePathElements());
         doWriteAttribute("allowEmptyDirectory", def.getAllowEmptyDirectory());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDeadLetterChannelDefinition(
             String name,
@@ -3759,7 +3760,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("deadLetterHandleNewException", def.getDeadLetterHandleNewException());
         doWriteAttribute("deadLetterUri", def.getDeadLetterUri());
         doWriteDefaultErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDefaultErrorHandlerDefinitionAttributes(
             DefaultErrorHandlerDefinition def)
@@ -3789,7 +3790,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteDefaultErrorHandlerDefinitionAttributes(def);
         doWriteDefaultErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteJtaTransactionErrorHandlerDefinition(
             String name,
@@ -3798,7 +3799,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTransactionErrorHandlerDefinitionAttributes(def);
         doWriteDefaultErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteNoErrorHandlerDefinition(
             String name,
@@ -3806,7 +3807,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRefErrorHandlerDefinition(
             String name,
@@ -3815,7 +3816,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSpringTransactionErrorHandlerDefinition(
             String name,
@@ -3824,7 +3825,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTransactionErrorHandlerDefinitionAttributes(def);
         doWriteDefaultErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransactionErrorHandlerDefinitionAttributes(
             TransactionErrorHandlerDefinition def)
@@ -3845,7 +3846,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTransactionErrorHandlerDefinitionAttributes(def);
         doWriteTransactionErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCSimpleExpression(
             String name,
@@ -3854,7 +3855,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteConstantExpression(
             String name,
@@ -3863,7 +3864,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDatasonnetExpression(
             String name,
@@ -3874,7 +3875,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("outputMediaType", def.getOutputMediaType());
         doWriteAttribute("bodyMediaType", def.getBodyMediaType());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteExchangePropertyExpression(
             String name,
@@ -3883,7 +3884,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteExpressionDefinitionAttributes(
             ExpressionDefinition def)
@@ -3898,7 +3899,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteGroovyExpression(
             String name,
@@ -3907,7 +3908,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteHeaderExpression(
             String name,
@@ -3916,7 +3917,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteHl7TerserExpression(
             String name,
@@ -3925,7 +3926,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSingleInputTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJavaScriptExpression(
             String name,
@@ -3934,7 +3935,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJoorExpression(
             String name,
@@ -3945,7 +3946,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("preCompile", def.getPreCompile());
         doWriteAttribute("singleQuotes", def.getSingleQuotes());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJqExpression(
             String name,
@@ -3954,7 +3955,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSingleInputTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJsonPathExpression(
             String name,
@@ -3969,7 +3970,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("allowEasyPredicate", def.getAllowEasyPredicate());
         doWriteAttribute("option", def.getOption());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteLanguageExpression(
             String name,
@@ -3979,7 +3980,7 @@ public class ModelWriter extends BaseWriter {
         doWriteExpressionDefinitionAttributes(def);
         doWriteAttribute("language", def.getLanguage());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteMethodCallExpression(
             String name,
@@ -3992,7 +3993,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("scope", def.getScope());
         doWriteAttribute("beanType", def.getBeanTypeName());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteMvelExpression(
             String name,
@@ -4001,7 +4002,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteNamespaceAwareExpressionAttributes(
             NamespaceAwareExpression def)
@@ -4021,7 +4022,7 @@ public class ModelWriter extends BaseWriter {
         doWriteNamespaceAwareExpressionAttributes(def);
         doWriteValue(def.getExpression());
         doWriteNamespaceAwareExpressionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOgnlExpression(
             String name,
@@ -4030,7 +4031,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWritePythonExpression(
             String name,
@@ -4039,7 +4040,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRefExpression(
             String name,
@@ -4048,7 +4049,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSimpleExpression(
             String name,
@@ -4057,7 +4058,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSingleInputExpressionDefinitionAttributes(
             SingleInputExpressionDefinition def)
@@ -4073,7 +4074,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSingleInputExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSingleInputTypedExpressionDefinitionAttributes(
             SingleInputTypedExpressionDefinition def)
@@ -4089,7 +4090,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSingleInputTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSpELExpression(
             String name,
@@ -4098,7 +4099,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTokenizerExpression(
             String name,
@@ -4116,7 +4117,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("group", def.getGroup());
         doWriteAttribute("token", def.getToken());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTypedExpressionDefinitionAttributes(
             TypedExpressionDefinition def)
@@ -4131,7 +4132,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteXMLTokenizerExpression(
             String name,
@@ -4141,9 +4142,9 @@ public class ModelWriter extends BaseWriter {
         doWriteSingleInputExpressionDefinitionAttributes(def);
         doWriteAttribute("mode", def.getMode());
         doWriteAttribute("group", def.getGroup());
+        doWriteNamespaces(def);
         doWriteValue(def.getExpression());
-        doWriteNamespaceAwareExpressionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteXPathExpression(
             String name,
@@ -4159,9 +4160,9 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("saxon", def.getSaxon());
         doWriteAttribute("documentType", def.getDocumentTypeName());
         doWriteAttribute("resultType", def.getResultTypeName());
+        doWriteNamespaces(def);
         doWriteValue(def.getExpression());
-        doWriteNamespaceAwareExpressionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteXQueryExpression(
             String name,
@@ -4172,9 +4173,9 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("configurationRef", def.getConfigurationRef());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("resultType", def.getResultTypeName());
+        doWriteNamespaces(def);
         doWriteValue(def.getExpression());
-        doWriteNamespaceAwareExpressionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomLoadBalancerDefinition(
             String name,
@@ -4183,7 +4184,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteFailoverLoadBalancerDefinition(
             String name,
@@ -4195,7 +4196,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("maximumFailoverAttempts", def.getMaximumFailoverAttempts());
         doWriteAttribute("roundRobin", def.getRoundRobin());
         doWriteList(null, "exception", def.getExceptions(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRandomLoadBalancerDefinition(
             String name,
@@ -4203,7 +4204,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRoundRobinLoadBalancerDefinition(
             String name,
@@ -4211,7 +4212,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStickyLoadBalancerDefinition(
             String name,
@@ -4220,7 +4221,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteElement("correlationExpression", def.getCorrelationExpression(), this::doWriteExpressionSubElementDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTopicLoadBalancerDefinition(
             String name,
@@ -4228,7 +4229,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteWeightedLoadBalancerDefinition(
             String name,
@@ -4239,7 +4240,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("distributionRatioDelimiter", def.getDistributionRatioDelimiter());
         doWriteAttribute("distributionRatio", def.getDistributionRatio());
         doWriteAttribute("roundRobin", def.getRoundRobin());
-        endElement();
+        endElement(name);
     }
     protected void doWriteApiKeyDefinition(
             String name,
@@ -4251,7 +4252,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("inCookie", def.getInCookie());
         doWriteAttribute("name", def.getName());
         doWriteAttribute("inQuery", def.getInQuery());
-        endElement();
+        endElement(name);
     }
     protected void doWriteBasicAuthDefinition(
             String name,
@@ -4259,7 +4260,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBearerTokenDefinition(
             String name,
@@ -4268,7 +4269,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
         doWriteAttribute("format", def.getFormat());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDeleteDefinition(
             String name,
@@ -4277,7 +4278,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteGetDefinition(
             String name,
@@ -4286,7 +4287,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteHeadDefinition(
             String name,
@@ -4295,7 +4296,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteMutualTLSDefinition(
             String name,
@@ -4303,7 +4304,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOAuth2Definition(
             String name,
@@ -4316,7 +4317,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("refreshUrl", def.getRefreshUrl());
         doWriteAttribute("flow", def.getFlow());
         doWriteList(null, "scopes", def.getScopes(), this::doWriteRestPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOpenIdConnectDefinition(
             String name,
@@ -4325,7 +4326,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
         doWriteAttribute("url", def.getUrl());
-        endElement();
+        endElement(name);
     }
     protected void doWriteParamDefinition(
             String name,
@@ -4343,7 +4344,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("required", toString(def.getRequired()));
         doWriteList("allowableValues", "value", def.getAllowableValues(), this::doWriteValueDefinition);
         doWriteList(null, "examples", def.getExamples(), this::doWriteRestPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWritePatchDefinition(
             String name,
@@ -4352,7 +4353,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePostDefinition(
             String name,
@@ -4361,7 +4362,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePutDefinition(
             String name,
@@ -4370,7 +4371,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteResponseHeaderDefinition(
             String name,
@@ -4385,7 +4386,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("collectionFormat", toString(def.getCollectionFormat()));
         doWriteAttribute("example", def.getExample());
         doWriteList("allowableValues", "value", def.getAllowableValues(), this::doWriteValueDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteResponseMessageDefinition(
             String name,
@@ -4397,7 +4398,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("message", def.getMessage());
         doWriteList(null, "header", def.getHeaders(), this::doWriteResponseHeaderDefinition);
         doWriteList(null, "examples", def.getExamples(), this::doWriteRestPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestBindingDefinition(
             String name,
@@ -4415,7 +4416,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("produces", def.getProduces());
         doWriteAttribute("consumes", def.getConsumes());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestConfigurationDefinition(
             String name,
@@ -4449,7 +4450,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "apiProperty", def.getApiProperties(), this::doWriteRestPropertyDefinition);
         doWriteList(null, "endpointProperty", def.getEndpointProperties(), this::doWriteRestPropertyDefinition);
         doWriteList(null, "dataFormatProperty", def.getDataFormatProperties(), this::doWriteRestPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestDefinition(
             String name,
@@ -4471,7 +4472,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "securityRequirements", def.getSecurityRequirements(), this::doWriteSecurityDefinition);
         doWriteList(null, null, def.getVerbs(), this::doWriteVerbDefinitionRef);
         doWriteElement("securityDefinitions", def.getSecurityDefinitions(), this::doWriteRestSecuritiesDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestPropertyDefinition(
             String name,
@@ -4480,7 +4481,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("value", def.getValue());
         doWriteAttribute("key", def.getKey());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestSecuritiesDefinition(
             String name,
@@ -4497,7 +4498,7 @@ public class ModelWriter extends BaseWriter {
                 case "MutualTLSDefinition" -> doWriteMutualTLSDefinition("mutualTLS", (MutualTLSDefinition) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestSecurityDefinitionAttributes(
             RestSecurityDefinition def)
@@ -4511,7 +4512,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestsDefinition(
             String name,
@@ -4521,7 +4522,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getRests(), this::doWriteRestDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSecurityDefinition(
             String name,
@@ -4530,7 +4531,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("scopes", def.getScopes());
         doWriteAttribute("key", def.getKey());
-        endElement();
+        endElement(name);
     }
     protected void doWriteVerbDefinitionAttributes(
             VerbDefinition def)
@@ -4566,7 +4567,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomTransformerDefinition(
             String name,
@@ -4576,7 +4577,7 @@ public class ModelWriter extends BaseWriter {
         doWriteTransformerDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("className", def.getClassName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDataFormatTransformerDefinition(
             String name,
@@ -4628,7 +4629,7 @@ public class ModelWriter extends BaseWriter {
                 case "ZipFileDataFormat" -> doWriteZipFileDataFormat("zipFile", (ZipFileDataFormat) def.getDataFormatType());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteEndpointTransformerDefinition(
             String name,
@@ -4638,7 +4639,7 @@ public class ModelWriter extends BaseWriter {
         doWriteTransformerDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("uri", def.getUri());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransformerDefinitionAttributes(
             TransformerDefinition def)
@@ -4653,7 +4654,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteTransformerDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransformersDefinition(
             String name,
@@ -4667,7 +4668,7 @@ public class ModelWriter extends BaseWriter {
                 case "CustomTransformerDefinition" -> doWriteCustomTransformerDefinition("customTransformer", (CustomTransformerDefinition) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomValidatorDefinition(
             String name,
@@ -4677,7 +4678,7 @@ public class ModelWriter extends BaseWriter {
         doWriteValidatorDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("className", def.getClassName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteEndpointValidatorDefinition(
             String name,
@@ -4687,7 +4688,7 @@ public class ModelWriter extends BaseWriter {
         doWriteValidatorDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("uri", def.getUri());
-        endElement();
+        endElement(name);
     }
     protected void doWritePredicateValidatorDefinition(
             String name,
@@ -4696,7 +4697,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteValidatorDefinitionAttributes(def);
         doWriteElement(null, def.getExpression(), this::doWriteExpressionDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteValidatorDefinitionAttributes(
             ValidatorDefinition def)
@@ -4709,7 +4710,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteValidatorDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteValidatorsDefinition(
             String name,
@@ -4723,7 +4724,7 @@ public class ModelWriter extends BaseWriter {
                 case "CustomValidatorDefinition" -> doWriteCustomValidatorDefinition("customValidator", (CustomValidatorDefinition) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteFromDefinitionRef(
             String n,
@@ -5071,7 +5072,7 @@ public class ModelWriter extends BaseWriter {
     }
     protected void doWriteAttribute(
             String attribute,
-            String value)
+            Object value)
             throws IOException {
         if (value != null) {
             attribute(attribute, value);
@@ -5079,7 +5080,7 @@ public class ModelWriter extends BaseWriter {
     }
     protected void doWriteValue(String value) throws IOException {
         if (value != null) {
-            text(value);
+            value(value);
         }
     }
     protected <T> void doWriteList(String wrapperName, String name, List<T> list, ElementSerializer<T> elementSerializer) throws IOException {
@@ -5091,7 +5092,7 @@ public class ModelWriter extends BaseWriter {
                 elementSerializer.doWriteElement(name, v);
             }
             if (wrapperName != null) {
-                endElement();
+                endElement(wrapperName);
             }
         }
     }
@@ -5115,8 +5116,17 @@ public class ModelWriter extends BaseWriter {
     protected void doWriteString(String name, String value) throws IOException {
         if (value != null) {
             startElement(name);
-            text(value);
-            endElement();
+            text(name, value);
+            endElement(name);
+        }
+    }
+    protected void doWriteNamespaces(
+            NamespaceAwareExpression def)
+            throws IOException {
+        if (def.getNamespaceAsMap() != null) {
+            for (var e : def.getNamespaceAsMap().entrySet()) {
+                doWriteAttribute("xmlns:" + e.getKey(), e.getValue());
+            }
         }
     }
 
diff --git a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
index 7f02740836b..5fc74f2664f 100644
--- a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
+++ b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
@@ -120,30 +120,35 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
             @Override
             protected void doWriteValue(String value) throws IOException {
                 if (value != null && !value.isEmpty()) {
+                    if (resolvePlaceholders) {
+                        value = resolve(value, properties);
+                    }
                     super.doWriteValue(value);
                 }
             }
 
             @Override
-            protected void text(String text) throws IOException {
+            protected void text(String name, String text) throws IOException {
                 if (resolvePlaceholders) {
                     text = resolve(text, properties);
                 }
-                super.text(text);
+                super.text(name, text);
             }
 
             @Override
-            protected void attribute(String name, String value) throws IOException {
-                if (resolveDelegateEndpoints && "uri".equals(name)) {
-                    String uri = resolve(value, properties);
-                    Endpoint endpoint = context.hasEndpoint(uri);
-                    if (endpoint instanceof DelegateEndpoint) {
-                        endpoint = ((DelegateEndpoint) endpoint).getEndpoint();
-                        value = endpoint.getEndpointUri();
+            protected void attribute(String name, Object value) throws IOException {
+                if (value != null) {
+                    if (resolveDelegateEndpoints && "uri".equals(name)) {
+                        String uri = resolve(value.toString(), properties);
+                        Endpoint endpoint = context.hasEndpoint(uri);
+                        if (endpoint instanceof DelegateEndpoint) {
+                            endpoint = ((DelegateEndpoint) endpoint).getEndpoint();
+                            value = endpoint.getEndpointUri();
+                        }
+                    }
+                    if (resolvePlaceholders) {
+                        value = resolve(value.toString(), properties);
                     }
-                }
-                if (resolvePlaceholders) {
-                    value = resolve(value, properties);
                 }
                 super.attribute(name, value);
             }
diff --git a/core/camel-xml-io/src/main/java/org/apache/camel/xml/io/XMLWriter.java b/core/camel-xml-io/src/main/java/org/apache/camel/xml/io/XMLWriter.java
index 943bb9ff678..51d67d259d4 100644
--- a/core/camel-xml-io/src/main/java/org/apache/camel/xml/io/XMLWriter.java
+++ b/core/camel-xml-io/src/main/java/org/apache/camel/xml/io/XMLWriter.java
@@ -201,7 +201,7 @@ public class XMLWriter {
     /**
      * {@inheritDoc}
      */
-    public void endElement() throws IOException {
+    public void endElement(String name) throws IOException {
         depth--;
 
         if (tagIsEmpty) {
diff --git a/core/camel-xml-io/src/main/java/org/apache/camel/xml/out/BaseWriter.java b/core/camel-xml-io/src/main/java/org/apache/camel/xml/out/BaseWriter.java
index 57d7b40a7ac..decb63f7058 100644
--- a/core/camel-xml-io/src/main/java/org/apache/camel/xml/out/BaseWriter.java
+++ b/core/camel-xml-io/src/main/java/org/apache/camel/xml/out/BaseWriter.java
@@ -58,8 +58,20 @@ public class BaseWriter {
         }
     }
 
+    protected void startOutputElement(String name) throws IOException {
+        startElement(name);
+    }
+
+    protected void startExpressionElement(String name) throws IOException {
+        startElement(name);
+    }
+
+    protected void endExpressionElement(String name) throws IOException {
+        writer.endElement(name);
+    }
+
     protected void endElement() throws IOException {
-        writer.endElement();
+        writer.endElement(null);
     }
 
     protected void endElement(String namespace) throws IOException {
@@ -73,8 +85,18 @@ public class BaseWriter {
         writer.writeText(text);
     }
 
-    protected void attribute(String name, String value) throws IOException {
-        writer.addAttribute(name, value);
+    protected void text(String name, String text) throws IOException {
+        writer.writeText(text);
+    }
+
+    protected void value(String value) throws IOException {
+        writer.writeText(value);
+    }
+
+    protected void attribute(String name, Object value) throws IOException {
+        if (value != null) {
+            writer.addAttribute(name, value.toString());
+        }
     }
 
     protected void domElements(List<Element> elements) throws IOException {
diff --git a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
index c6521a2fbd3..1497a2186f9 100644
--- a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
+++ b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
@@ -26,7 +26,6 @@ import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import javax.xml.transform.TransformerFactory;
@@ -100,7 +99,7 @@ public class ModelParserTest {
     public void testFiles() throws Exception {
         Path dir = getResourceFolder();
         try (Stream<Path> list = Files.list(dir)) {
-            List<Path> files = list.sorted().filter(Files::isRegularFile).collect(Collectors.toList());
+            List<Path> files = list.sorted().filter(Files::isRegularFile).filter(f -> f.endsWith("xml")).toList();
             for (Path path : files) {
                 ModelParser parser = new ModelParser(Files.newInputStream(path), NAMESPACE);
                 boolean isRest = REST_XMLS.contains(path.getFileName().toString());
diff --git a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties b/core/camel-xml-io/src/test/resources/log4j2.properties
similarity index 53%
copy from dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
copy to core/camel-xml-io/src/test/resources/log4j2.properties
index 976cc8357c1..02b1bc1eec6 100644
--- a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
+++ b/core/camel-xml-io/src/test/resources/log4j2.properties
@@ -14,15 +14,19 @@
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
+appender.console.type = Console
+appender.console.name = console
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
 
-com.amazon.redshift.jdbc.Driver = com.amazon.redshift:redshift-jdbc42:2.1.0.14
-com.microsoft.sqlserver.jdbc.SQLServerDriver = com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre11
-com.mysql.cj.jdbc.Driver = mysql:mysql-connector-java:8.0.33
-net.sf.saxon.xpath.XPathFactoryImpl = camel:saxon
-org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory = org.apache.activemq:artemis-jms-client-all:2.28.0
-org.apache.commons.dbcp2.BasicDataSource = org.apache.commons:commons-dbcp2:2.9.0
-org.apache.qpid.jms.JmsConnectionFactory = org.apache.qpid:qpid-jms-client:2.3.0
-org.postgresql.Driver = org.postgresql:postgresql:42.6.0
-org.apache.camel.component.cxf.jaxws.CxfEndpoint = camel:cxf-soap
-org.apache.camel.component.cxf.jaxrs.CxfRsEndpoint = camel:cxf-rest
-META-INF/services/org/apache/camel/restapi/openapi = camel:openapi-java
\ No newline at end of file
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-xml-io-test.log
+appender.file.append = true
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+rootLogger.level = INFO
+
+rootLogger.appenderRef.file.ref = file
+#rootLogger.appenderRef.console.ref = console
diff --git a/core/camel-xml-io/src/test/resources/loop.xml b/core/camel-xml-io/src/test/resources/loop.xml
index 9aa92142370..8c0e7645a5d 100644
--- a/core/camel-xml-io/src/test/resources/loop.xml
+++ b/core/camel-xml-io/src/test/resources/loop.xml
@@ -19,9 +19,10 @@
 -->
 <routes id="camel" xmlns="http://camel.apache.org/schema/spring">
   <route>
-    <from uri="direct:a"/>
+    <from uri="timer:a"/>
     <loop>
       <constant>8</constant>
+      <log message="looping"/>
     </loop>
   </route>
 </routes>
diff --git a/core/camel-xml-io/pom.xml b/core/camel-yaml-io/pom.xml
similarity index 64%
copy from core/camel-xml-io/pom.xml
copy to core/camel-yaml-io/pom.xml
index 6a29601d2a6..df414c9b87f 100644
--- a/core/camel-xml-io/pom.xml
+++ b/core/camel-yaml-io/pom.xml
@@ -26,15 +26,14 @@
         <version>4.0.0-SNAPSHOT</version>
     </parent>
 
-    <artifactId>camel-xml-io</artifactId>
-    <name>Camel :: XML IO</name>
-    <description>Camel XML IO</description>
+    <artifactId>camel-yaml-io</artifactId>
+    <name>Camel :: YAML IO</name>
+    <description>Camel YAML IO</description>
 
     <properties>
-        <firstVersion>3.1.0</firstVersion>
+        <firstVersion>4.0.0</firstVersion>
         <label>dsl</label>
-        <camel-generate-xml-parser>true</camel-generate-xml-parser>
-        <camel-generate-xml-writer>true</camel-generate-xml-writer>
+        <camel-generate-yaml-writer>true</camel-generate-yaml-writer>
     </properties>
 
     <dependencies>
@@ -45,15 +44,40 @@
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-xml-io-util</artifactId>
+            <artifactId>camel-core-catalog</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-util-json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-yaml</artifactId>
+            <version>${jackson2-version}</version>
         </dependency>
 
         <!-- testing -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-xml-io</artifactId>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter</artifactId>
             <scope>test</scope>
         </dependency>
+        <!-- logging -->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j2-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -66,8 +90,7 @@
                         <id>generate-sources</id>
                         <phase>generate-sources</phase>
                         <goals>
-                            <goal>generate-xml-parser</goal>
-                            <goal>generate-xml-writer</goal>
+                            <goal>generate-yaml-writer</goal>
                         </goals>
                     </execution>
                 </executions>
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
similarity index 97%
copy from core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
copy to core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
index 35a5d650473..e67f7440221 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
@@ -21,13 +21,14 @@
 /**
  * Generated by Camel build tools - do NOT edit this file!
  */
-package org.apache.camel.xml.out;
+package org.apache.camel.yaml.out;
 
 import java.io.IOException;
 import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
+import org.apache.camel.Expression;
 import org.apache.camel.model.*;
 import org.apache.camel.model.app.*;
 import org.apache.camel.model.cloud.*;
@@ -1049,13 +1050,13 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("completionTimeoutCheckerInterval", def.getCompletionTimeoutCheckerInterval());
         doWriteAttribute("optimisticLocking", def.getOptimisticLocking());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("optimisticLockRetryPolicy", def.getOptimisticLockRetryPolicyDefinition(), this::doWriteOptimisticLockRetryPolicyDefinition);
         doWriteElement("correlationExpression", def.getCorrelationExpression(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("completionPredicate", def.getCompletionPredicate(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("completionSizeExpression", def.getCompletionSizeExpression(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("completionTimeoutExpression", def.getCompletionTimeoutExpression(), this::doWriteExpressionSubElementDefinition);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteBeanDefinition(
             String name,
@@ -1068,7 +1069,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("scope", def.getScope());
         doWriteAttribute("beanType", def.getBeanType());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBeanFactoryDefinitionAttributes(
             BeanFactoryDefinition<?, ?> def)
@@ -1091,7 +1092,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteBeanFactoryDefinitionAttributes(def);
         doWriteBeanFactoryDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCatchDefinition(
             String name,
@@ -1100,10 +1101,10 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("onWhen", def.getOnWhen(), this::doWriteWhenDefinition);
         doWriteList(null, "exception", def.getExceptions(), this::doWriteString);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteChoiceDefinition(
             String name,
@@ -1115,7 +1116,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteElement("otherwise", def.getOtherwise(), this::doWriteOtherwiseDefinition);
         doWriteList(null, null, def.getWhenClauses(), this::doWriteWhenDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCircuitBreakerDefinition(
             String name,
@@ -1126,10 +1127,10 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("configuration", def.getConfiguration());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteElement("faultToleranceConfiguration", def.getFaultToleranceConfiguration(), this::doWriteFaultToleranceConfigurationDefinition);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("resilience4jConfiguration", def.getResilience4jConfiguration(), this::doWriteResilience4jConfigurationDefinition);
         doWriteElement("onFallback", def.getOnFallback(), this::doWriteOnFallbackDefinition);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteClaimCheckDefinition(
             String name,
@@ -1143,7 +1144,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("operation", def.getOperation());
         doWriteAttribute("key", def.getKey());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteContextScanDefinition(
             String name,
@@ -1153,7 +1154,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("includeNonSingletons", def.getIncludeNonSingletons());
         doWriteList(null, "excludes", def.getExcludes(), this::doWriteString);
         doWriteList(null, "includes", def.getIncludes(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteConvertBodyDefinition(
             String name,
@@ -1165,7 +1166,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("type", def.getType());
         doWriteAttribute("mandatory", def.getMandatory());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDataFormatDefinitionAttributes(
             DataFormatDefinition def)
@@ -1178,7 +1179,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteDataFormatDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDelayDefinition(
             String name,
@@ -1190,7 +1191,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("callerRunsWhenRejected", def.getCallerRunsWhenRejected());
         doWriteAttribute("asyncDelayed", def.getAsyncDelayed());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDescriptionDefinition(
             String name,
@@ -1198,7 +1199,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteValue(def.getText());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDynamicRouterDefinition(
             String name,
@@ -1210,7 +1211,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints());
         doWriteAttribute("cacheSize", def.getCacheSize());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteEnrichDefinition(
             String name,
@@ -1227,7 +1228,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("shareUnitOfWork", def.getShareUnitOfWork());
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteErrorHandlerDefinition(
             String name,
@@ -1244,7 +1245,7 @@ public class ModelWriter extends BaseWriter {
                 case "SpringTransactionErrorHandlerDefinition" -> doWriteSpringTransactionErrorHandlerDefinition("springTransactionErrorHandler", (SpringTransactionErrorHandlerDefinition) def.getErrorHandlerType());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteExpressionNodeAttributes(
             ExpressionNode def)
@@ -1264,15 +1265,15 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteExpressionNodeAttributes(def);
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteExpressionSubElementDefinition(
             String name,
             ExpressionSubElementDefinition def)
             throws IOException {
-        startElement(name);
+        startExpressionElement(name);
         doWriteElement(null, def.getExpressionType(), this::doWriteExpressionDefinitionRef);
-        endElement();
+        endExpressionElement(name);
     }
     protected void doWriteFaultToleranceConfigurationCommonAttributes(
             FaultToleranceConfigurationCommon def)
@@ -1298,7 +1299,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFaultToleranceConfigurationCommonAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFaultToleranceConfigurationDefinition(
             String name,
@@ -1306,7 +1307,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFaultToleranceConfigurationCommonAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFilterDefinition(
             String name,
@@ -1316,7 +1317,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("statusPropertyName", def.getStatusPropertyName());
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFinallyDefinition(
             String name,
@@ -1326,7 +1327,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFromDefinition(
             String name,
@@ -1336,7 +1337,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteAttribute("uri", def.getUri());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteGlobalOptionDefinition(
             String name,
@@ -1345,7 +1346,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("value", def.getValue());
         doWriteAttribute("key", def.getKey());
-        endElement();
+        endElement(name);
     }
     protected void doWriteGlobalOptionsDefinition(
             String name,
@@ -1353,7 +1354,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteList(null, "globalOption", def.getGlobalOptions(), this::doWriteGlobalOptionDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteIdempotentConsumerDefinition(
             String name,
@@ -1367,7 +1368,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("idempotentRepository", def.getIdempotentRepository());
         doWriteAttribute("removeOnFailure", def.getRemoveOnFailure());
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteIdentifiedTypeAttributes(
             IdentifiedType def)
@@ -1380,7 +1381,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteInputTypeDefinition(
             String name,
@@ -1391,7 +1392,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("urn", def.getUrn());
         doWriteAttribute("validate", def.getValidate());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteInterceptDefinitionAttributes(
             InterceptDefinition def)
@@ -1411,7 +1412,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteInterceptDefinitionAttributes(def);
         doWriteInterceptDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteInterceptFromDefinition(
             String name,
@@ -1421,7 +1422,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("uri", def.getUri());
         doWriteInterceptDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteInterceptSendToEndpointDefinition(
             String name,
@@ -1434,7 +1435,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("skipSendToOriginalEndpoint", def.getSkipSendToOriginalEndpoint());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteKameletDefinition(
             String name,
@@ -1445,7 +1446,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("name", def.getName());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteLoadBalanceDefinition(
             String name,
@@ -1454,7 +1455,6 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement(null, def.getLoadBalancerType(), (n, v) -> {
             switch (v.getClass().getSimpleName()) {
                 case "CustomLoadBalancerDefinition" -> doWriteCustomLoadBalancerDefinition("customLoadBalancer", (CustomLoadBalancerDefinition) def.getLoadBalancerType());
@@ -1466,7 +1466,8 @@ public class ModelWriter extends BaseWriter {
                 case "WeightedLoadBalancerDefinition" -> doWriteWeightedLoadBalancerDefinition("weighted", (WeightedLoadBalancerDefinition) def.getLoadBalancerType());
             }
         });
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteLoadBalancerDefinitionAttributes(
             LoadBalancerDefinition def)
@@ -1479,7 +1480,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteLoadBalancerDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteLogDefinition(
             String name,
@@ -1493,7 +1494,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("message", def.getMessage());
         doWriteAttribute("loggingLevel", def.getLoggingLevel());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteLoopDefinition(
             String name,
@@ -1505,7 +1506,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("breakOnShutdown", def.getBreakOnShutdown());
         doWriteAttribute("copy", def.getCopy());
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteMarshalDefinition(
             String name,
@@ -1558,7 +1559,7 @@ public class ModelWriter extends BaseWriter {
                 case "ZipFileDataFormat" -> doWriteZipFileDataFormat("zipFile", (ZipFileDataFormat) def.getDataFormatType());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteMulticastDefinition(
             String name,
@@ -1579,7 +1580,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOnCompletionDefinition(
             String name,
@@ -1596,7 +1597,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteElement("onWhen", def.getOnWhen(), this::doWriteWhenDefinition);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOnExceptionDefinition(
             String name,
@@ -1610,14 +1611,14 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("onExceptionOccurredRef", def.getOnExceptionOccurredRef());
         doWriteAttribute("redeliveryPolicyRef", def.getRedeliveryPolicyRef());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("continued", def.getContinued(), this::doWriteExpressionSubElementDefinition);
         doWriteList(null, "exception", def.getExceptions(), this::doWriteString);
         doWriteElement("retryWhile", def.getRetryWhile(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("redeliveryPolicy", def.getRedeliveryPolicyType(), this::doWriteRedeliveryPolicyDefinition);
         doWriteElement("handled", def.getHandled(), this::doWriteExpressionSubElementDefinition);
         doWriteElement("onWhen", def.getOnWhen(), this::doWriteWhenDefinition);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteOnFallbackDefinition(
             String name,
@@ -1628,7 +1629,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("fallbackViaNetwork", def.getFallbackViaNetwork());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOptimisticLockRetryPolicyDefinition(
             String name,
@@ -1640,7 +1641,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("maximumRetries", def.getMaximumRetries());
         doWriteAttribute("exponentialBackOff", def.getExponentialBackOff());
         doWriteAttribute("maximumRetryDelay", def.getMaximumRetryDelay());
-        endElement();
+        endElement(name);
     }
     protected void doWriteOptionalIdentifiedDefinitionAttributes(
             OptionalIdentifiedDefinition<?> def)
@@ -1660,7 +1661,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOtherwiseDefinition(
             String name,
@@ -1670,7 +1671,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOutputExpressionNodeAttributes(
             OutputExpressionNode def)
@@ -1690,7 +1691,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteOutputExpressionNodeAttributes(def);
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOutputTypeDefinition(
             String name,
@@ -1701,7 +1702,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("urn", def.getUrn());
         doWriteAttribute("validate", def.getValidate());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePackageScanDefinition(
             String name,
@@ -1711,7 +1712,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "excludes", def.getExcludes(), this::doWriteString);
         doWriteList(null, "includes", def.getIncludes(), this::doWriteString);
         doWriteList(null, "package", def.getPackages(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWritePausableDefinition(
             String name,
@@ -1722,7 +1723,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("untilCheck", def.getUntilCheck());
         doWriteAttribute("consumerListener", def.getConsumerListener());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePipelineDefinition(
             String name,
@@ -1732,7 +1733,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWritePolicyDefinition(
             String name,
@@ -1743,7 +1744,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ref", def.getRef());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWritePollEnrichDefinition(
             String name,
@@ -1759,7 +1760,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("timeout", def.getTimeout());
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteProcessDefinition(
             String name,
@@ -1769,7 +1770,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteProcessorDefinitionAttributes(
             ProcessorDefinition<?> def)
@@ -1790,7 +1791,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteProcessorDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePropertyDefinition(
             String name,
@@ -1799,7 +1800,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("value", def.getValue());
         doWriteAttribute("key", def.getKey());
-        endElement();
+        endElement(name);
     }
     protected void doWritePropertyDefinitions(
             String name,
@@ -1807,7 +1808,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteList(null, "property", def.getProperties(), this::doWritePropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWritePropertyExpressionDefinition(
             String name,
@@ -1816,7 +1817,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("key", def.getKey());
         doWriteElement(null, def.getExpression(), this::doWriteExpressionDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRecipientListDefinition(
             String name,
@@ -1839,7 +1840,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("shareUnitOfWork", def.getShareUnitOfWork());
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRedeliveryPolicyDefinition(
             String name,
@@ -1871,7 +1872,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("maximumRedeliveries", def.getMaximumRedeliveries());
         doWriteAttribute("logExhausted", def.getLogExhausted());
         doWriteAttribute("useCollisionAvoidance", def.getUseCollisionAvoidance());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRemoveHeaderDefinition(
             String name,
@@ -1881,7 +1882,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("name", def.getName());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRemoveHeadersDefinition(
             String name,
@@ -1892,7 +1893,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("excludePattern", def.getExcludePattern());
         doWriteAttribute("pattern", def.getPattern());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRemovePropertiesDefinition(
             String name,
@@ -1903,7 +1904,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("excludePattern", def.getExcludePattern());
         doWriteAttribute("pattern", def.getPattern());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRemovePropertyDefinition(
             String name,
@@ -1913,7 +1914,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("name", def.getName());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteResequenceDefinition(
             String name,
@@ -1922,7 +1923,6 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement(null, def.getExpression(), this::doWriteExpressionDefinitionRef);
         doWriteElement(null, def.getResequencerConfig(), (n, v) -> {
             switch (v.getClass().getSimpleName()) {
@@ -1930,7 +1930,8 @@ public class ModelWriter extends BaseWriter {
                 case "StreamResequencerConfig" -> doWriteStreamResequencerConfig("stream-config", (StreamResequencerConfig) def.getResequencerConfig());
             }
         });
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteResilience4jConfigurationCommonAttributes(
             Resilience4jConfigurationCommon def)
@@ -1963,7 +1964,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteResilience4jConfigurationCommonAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteResilience4jConfigurationDefinition(
             String name,
@@ -1971,7 +1972,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteResilience4jConfigurationCommonAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestContextRefDefinition(
             String name,
@@ -1979,7 +1980,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteResumableDefinition(
             String name,
@@ -1989,9 +1990,9 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("resumeStrategy", def.getResumeStrategy());
         doWriteAttribute("intermittent", def.getIntermittent());
+        doWriteAttribute("loggingLevel", def.getLoggingLevel());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteElement("loggingLevel", def.getLoggingLevel(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRollbackDefinition(
             String name,
@@ -2003,7 +2004,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("message", def.getMessage());
         doWriteAttribute("markRollbackOnlyLast", def.getMarkRollbackOnlyLast());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteBuilderDefinition(
             String name,
@@ -2012,7 +2013,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteConfigurationContextRefDefinition(
             String name,
@@ -2020,7 +2021,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteConfigurationDefinition(
             String name,
@@ -2036,7 +2037,7 @@ public class ModelWriter extends BaseWriter {
         doWriteElement("errorHandler", def.getErrorHandler(), this::doWriteErrorHandlerDefinition);
         doWriteList(null, "interceptFrom", def.getInterceptFroms(), this::doWriteInterceptFromDefinition);
         doWriteList(null, "intercept", def.getIntercepts(), this::doWriteInterceptDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteConfigurationsDefinition(
             String name,
@@ -2044,7 +2045,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteList(null, null, def.getRouteConfigurations(), this::doWriteRouteConfigurationDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteContextRefDefinition(
             String name,
@@ -2052,7 +2053,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteDefinition(
             String name,
@@ -2083,7 +2084,7 @@ public class ModelWriter extends BaseWriter {
         doWriteElement(null, def.getInputType(), this::doWriteInputTypeDefinitionRef);
         doWriteElement(null, def.getOutputType(), this::doWriteOutputTypeDefinitionRef);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplateBeanDefinition(
             String name,
@@ -2092,7 +2093,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteBeanFactoryDefinitionAttributes(def);
         doWriteBeanFactoryDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplateContextRefDefinition(
             String name,
@@ -2100,7 +2101,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplateDefinition(
             String name,
@@ -2112,7 +2113,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "templateParameter", def.getTemplateParameters(), this::doWriteRouteTemplateParameterDefinition);
         doWriteElement("route", def.getRoute(), this::doWriteRouteDefinition);
         doWriteList(null, "templateBean", def.getTemplateBeans(), this::doWriteRouteTemplateBeanDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplateParameterDefinition(
             String name,
@@ -2123,7 +2124,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("name", def.getName());
         doWriteAttribute("description", def.getDescription());
         doWriteAttribute("required", toString(def.getRequired()));
-        endElement();
+        endElement(name);
     }
     protected void doWriteRouteTemplatesDefinition(
             String name,
@@ -2133,7 +2134,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getRouteTemplates(), this::doWriteRouteTemplateDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRoutesDefinition(
             String name,
@@ -2143,7 +2144,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getRoutes(), this::doWriteRouteDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRoutingSlipDefinition(
             String name,
@@ -2155,7 +2156,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints());
         doWriteAttribute("cacheSize", def.getCacheSize());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSagaActionUriDefinition(
             String name,
@@ -2164,7 +2165,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSendDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSagaDefinition(
             String name,
@@ -2177,11 +2178,11 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("sagaService", def.getSagaService());
         doWriteAttribute("timeout", def.getTimeout());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
         doWriteElement("completion", def.getCompletion(), this::doWriteSagaActionUriDefinition);
         doWriteList(null, "option", def.getOptions(), this::doWritePropertyExpressionDefinition);
         doWriteElement("compensation", def.getCompensation(), this::doWriteSagaActionUriDefinition);
-        endElement();
+        doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
+        endElement(name);
     }
     protected void doWriteSamplingDefinition(
             String name,
@@ -2192,7 +2193,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("messageFrequency", def.getMessageFrequency());
         doWriteAttribute("samplePeriod", def.getSamplePeriod());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteScriptDefinition(
             String name,
@@ -2201,7 +2202,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSendDefinitionAttributes(
             SendDefinition<?> def)
@@ -2221,7 +2222,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSendDefinitionAttributes(def);
         doWriteSendDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSetBodyDefinition(
             String name,
@@ -2230,7 +2231,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSetExchangePatternDefinition(
             String name,
@@ -2240,7 +2241,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("pattern", def.getPattern());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSetHeaderDefinition(
             String name,
@@ -2250,7 +2251,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("name", def.getName());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSetPropertyDefinition(
             String name,
@@ -2260,7 +2261,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("name", def.getName());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSortDefinition(
             String name,
@@ -2270,7 +2271,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("comparator", def.getComparator());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSplitDefinition(
             String name,
@@ -2291,7 +2292,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("shareUnitOfWork", def.getShareUnitOfWork());
         doWriteAttribute("aggregationStrategyMethodAllowNull", def.getAggregationStrategyMethodAllowNull());
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStepDefinition(
             String name,
@@ -2301,7 +2302,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStopDefinition(
             String name,
@@ -2310,7 +2311,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTemplatedRouteBeanDefinition(
             String name,
@@ -2319,7 +2320,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteBeanFactoryDefinitionAttributes(def);
         doWriteBeanFactoryDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTemplatedRouteDefinition(
             String name,
@@ -2331,7 +2332,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("prefixId", def.getPrefixId());
         doWriteList(null, "bean", def.getBeans(), this::doWriteTemplatedRouteBeanDefinition);
         doWriteList(null, "parameter", def.getParameters(), this::doWriteTemplatedRouteParameterDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTemplatedRouteParameterDefinition(
             String name,
@@ -2340,7 +2341,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("name", def.getName());
         doWriteAttribute("value", def.getValue());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTemplatedRoutesDefinition(
             String name,
@@ -2350,7 +2351,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getTemplatedRoutes(), this::doWriteTemplatedRouteDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteThreadPoolProfileDefinition(
             String name,
@@ -2367,7 +2368,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("rejectedPolicy", def.getRejectedPolicy());
         doWriteAttribute("timeUnit", def.getTimeUnit());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteThreadsDefinition(
             String name,
@@ -2386,7 +2387,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("rejectedPolicy", def.getRejectedPolicy());
         doWriteAttribute("timeUnit", def.getTimeUnit());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteThrottleDefinition(
             String name,
@@ -2401,7 +2402,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("asyncDelayed", def.getAsyncDelayed());
         doWriteExpressionNodeElements(def);
         doWriteElement("correlationExpression", def.getCorrelationExpression(), this::doWriteExpressionSubElementDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteThrowExceptionDefinition(
             String name,
@@ -2413,7 +2414,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("message", def.getMessage());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteToDefinition(
             String name,
@@ -2423,7 +2424,7 @@ public class ModelWriter extends BaseWriter {
         doWriteSendDefinitionAttributes(def);
         doWriteAttribute("pattern", def.getPattern());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteToDynamicDefinitionAttributes(
             ToDynamicDefinition def)
@@ -2448,7 +2449,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteToDynamicDefinitionAttributes(def);
         doWriteToDynamicDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransactedDefinition(
             String name,
@@ -2459,7 +2460,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ref", def.getRef());
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransformDefinition(
             String name,
@@ -2468,7 +2469,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTryDefinition(
             String name,
@@ -2478,7 +2479,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getOutputs(), this::doWriteProcessorDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteUnmarshalDefinition(
             String name,
@@ -2532,7 +2533,7 @@ public class ModelWriter extends BaseWriter {
                 case "ZipFileDataFormat" -> doWriteZipFileDataFormat("zipFile", (ZipFileDataFormat) def.getDataFormatType());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteValidateDefinition(
             String name,
@@ -2542,7 +2543,7 @@ public class ModelWriter extends BaseWriter {
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("predicateExceptionFactory", def.getPredicateExceptionFactory());
         doWriteExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteValueDefinition(
             String name,
@@ -2550,7 +2551,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteValue(def.getValue());
-        endElement();
+        endElement(name);
     }
     protected void doWriteWhenDefinition(
             String name,
@@ -2559,7 +2560,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteOutputExpressionNodeElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteWireTapDefinition(
             String name,
@@ -2572,7 +2573,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("executorService", def.getExecutorService());
         doWriteAttribute("copy", def.getCopy());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteApplicationDefinition(
             String name,
@@ -2580,7 +2581,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteBeansDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBeanPropertiesDefinition(
             String name,
@@ -2588,7 +2589,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteList(null, "property", def.getProperties(), this::doWriteBeanPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBeanPropertyDefinition(
             String name,
@@ -2598,7 +2599,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("value", def.getValue());
         doWriteAttribute("key", def.getKey());
         doWriteElement("properties", def.getProperties(), this::doWriteBeanPropertiesDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBeansDefinitionElements(
             BeansDefinition def)
@@ -2618,7 +2619,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteBeansDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteComponentScanDefinition(
             String name,
@@ -2626,7 +2627,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteAttribute("base-package", def.getBasePackage());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRegistryBeanDefinition(
             String name,
@@ -2636,7 +2637,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("name", def.getName());
         doWriteAttribute("type", def.getType());
         doWriteElement("properties", new BeanPropertiesAdapter().marshal(def.getProperties()), this::doWriteBeanPropertiesDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBlacklistServiceCallServiceFilterConfiguration(
             String name,
@@ -2646,7 +2647,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
         doWriteList(null, "servers", def.getServers(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCachingServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2666,7 +2667,7 @@ public class ModelWriter extends BaseWriter {
                 case "StaticServiceCallServiceDiscoveryConfiguration" -> doWriteStaticServiceCallServiceDiscoveryConfiguration("staticServiceDiscovery", (StaticServiceCallServiceDiscoveryConfiguration) def.getServiceDiscoveryConfiguration());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteCombinedServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2684,7 +2685,7 @@ public class ModelWriter extends BaseWriter {
                 case "CachingServiceCallServiceDiscoveryConfiguration" -> doWriteCachingServiceCallServiceDiscoveryConfiguration("cachingServiceDiscovery", (CachingServiceCallServiceDiscoveryConfiguration) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteCombinedServiceCallServiceFilterConfiguration(
             String name,
@@ -2701,7 +2702,7 @@ public class ModelWriter extends BaseWriter {
                 case "PassThroughServiceCallServiceFilterConfiguration" -> doWritePassThroughServiceCallServiceFilterConfiguration("passThroughServiceFilter", (PassThroughServiceCallServiceFilterConfiguration) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteConsulServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2719,7 +2720,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("blockSeconds", def.getBlockSeconds());
         doWriteAttribute("url", def.getUrl());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomServiceCallServiceFilterConfiguration(
             String name,
@@ -2729,7 +2730,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getServiceFilterRef());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDefaultServiceCallServiceLoadBalancerConfiguration(
             String name,
@@ -2738,7 +2739,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDnsServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2749,7 +2750,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("domain", def.getDomain());
         doWriteAttribute("proto", def.getProto());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteHealthyServiceCallServiceFilterConfiguration(
             String name,
@@ -2758,7 +2759,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteKubernetesServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2786,7 +2787,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("trustCerts", def.getTrustCerts());
         doWriteAttribute("username", def.getUsername());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePassThroughServiceCallServiceFilterConfiguration(
             String name,
@@ -2795,7 +2796,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallConfigurationAttributes(
             ServiceCallConfiguration def)
@@ -2814,7 +2815,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteServiceCallConfigurationAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallConfigurationDefinition(
             String name,
@@ -2856,7 +2857,7 @@ public class ModelWriter extends BaseWriter {
             }
         });
         doWriteElement("expression", def.getExpressionConfiguration(), this::doWriteServiceCallExpressionConfiguration);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallDefinition(
             String name,
@@ -2901,7 +2902,7 @@ public class ModelWriter extends BaseWriter {
             }
         });
         doWriteElement("expression", def.getExpressionConfiguration(), this::doWriteServiceCallExpressionConfiguration);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallExpressionConfiguration(
             String name,
@@ -2913,7 +2914,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("portHeader", def.getPortHeader());
         doWriteServiceCallConfigurationElements(def);
         doWriteElement(null, def.getExpressionType(), this::doWriteExpressionDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallServiceChooserConfiguration(
             String name,
@@ -2922,7 +2923,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallServiceDiscoveryConfigurationAttributes(
             ServiceCallServiceDiscoveryConfiguration def)
@@ -2941,7 +2942,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteServiceCallServiceDiscoveryConfigurationAttributes(def);
         doWriteServiceCallServiceDiscoveryConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallServiceFilterConfigurationAttributes(
             ServiceCallServiceFilterConfiguration def)
@@ -2960,7 +2961,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteServiceCallServiceFilterConfigurationAttributes(def);
         doWriteServiceCallServiceFilterConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteServiceCallServiceLoadBalancerConfigurationAttributes(
             ServiceCallServiceLoadBalancerConfiguration def)
@@ -2979,7 +2980,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteServiceCallServiceLoadBalancerConfigurationAttributes(def);
         doWriteServiceCallServiceLoadBalancerConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStaticServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -2989,7 +2990,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteServiceCallConfigurationElements(def);
         doWriteList(null, "servers", def.getServers(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteZooKeeperServiceCallServiceDiscoveryConfiguration(
             String name,
@@ -3006,7 +3007,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("sessionTimeout", def.getSessionTimeout());
         doWriteAttribute("connectionTimeout", def.getConnectionTimeout());
         doWriteServiceCallConfigurationElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBatchResequencerConfig(
             String name,
@@ -3018,14 +3019,14 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("allowDuplicates", def.getAllowDuplicates());
         doWriteAttribute("batchTimeout", def.getBatchTimeout());
         doWriteAttribute("ignoreInvalidExchanges", def.getIgnoreInvalidExchanges());
-        endElement();
+        endElement(name);
     }
     protected void doWriteResequencerConfig(
             String name,
             ResequencerConfig def)
             throws IOException {
         startElement(name);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStreamResequencerConfig(
             String name,
@@ -3038,7 +3039,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("ignoreInvalidExchanges", def.getIgnoreInvalidExchanges());
         doWriteAttribute("deliveryAttemptInterval", def.getDeliveryAttemptInterval());
         doWriteAttribute("capacity", def.getCapacity());
-        endElement();
+        endElement(name);
     }
     protected void doWriteASN1DataFormat(
             String name,
@@ -3048,7 +3049,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("unmarshalType", def.getUnmarshalTypeName());
         doWriteAttribute("usingIterator", def.getUsingIterator());
-        endElement();
+        endElement(name);
     }
     protected void doWriteAvroDataFormat(
             String name,
@@ -3076,7 +3077,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("objectMapper", def.getObjectMapper());
         doWriteAttribute("library", toString(def.getLibrary()));
         doWriteAttribute("autoDiscoverObjectMapper", def.getAutoDiscoverObjectMapper());
-        endElement();
+        endElement(name);
     }
     protected void doWriteBarcodeDataFormat(
             String name,
@@ -3088,7 +3089,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("width", def.getWidth());
         doWriteAttribute("imageType", def.getImageType());
         doWriteAttribute("height", def.getHeight());
-        endElement();
+        endElement(name);
     }
     protected void doWriteBase64DataFormat(
             String name,
@@ -3099,7 +3100,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("urlSafe", def.getUrlSafe());
         doWriteAttribute("lineSeparator", def.getLineSeparator());
         doWriteAttribute("lineLength", def.getLineLength());
-        endElement();
+        endElement(name);
     }
     protected void doWriteBindyDataFormat(
             String name,
@@ -3112,7 +3113,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("locale", def.getLocale());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("allowEmptyStream", def.getAllowEmptyStream());
-        endElement();
+        endElement(name);
     }
     protected void doWriteCBORDataFormat(
             String name,
@@ -3130,7 +3131,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("enableFeatures", def.getEnableFeatures());
         doWriteAttribute("useList", def.getUseList());
         doWriteAttribute("disableFeatures", def.getDisableFeatures());
-        endElement();
+        endElement(name);
     }
     protected void doWriteCryptoDataFormat(
             String name,
@@ -3147,7 +3148,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("keyRef", def.getKeyRef());
         doWriteAttribute("bufferSize", def.getBufferSize());
         doWriteAttribute("algorithm", def.getAlgorithm());
-        endElement();
+        endElement(name);
     }
     protected void doWriteCsvDataFormat(
             String name,
@@ -3184,7 +3185,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("marshallerFactoryRef", def.getMarshallerFactoryRef());
         doWriteAttribute("recordSeparator", def.getRecordSeparator());
         doWriteList(null, "header", def.getHeader(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomDataFormat(
             String name,
@@ -3193,7 +3194,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDataFormatsDefinition(
             String name,
@@ -3243,7 +3244,7 @@ public class ModelWriter extends BaseWriter {
                 case "ZipFileDataFormat" -> doWriteZipFileDataFormat("zipFile", (ZipFileDataFormat) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteFhirDataformatAttributes(
             FhirDataformat def)
@@ -3274,7 +3275,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFhirDataformatAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFhirJsonDataFormat(
             String name,
@@ -3282,7 +3283,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFhirDataformatAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFhirXmlDataFormat(
             String name,
@@ -3290,7 +3291,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteFhirDataformatAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteFlatpackDataFormat(
             String name,
@@ -3306,7 +3307,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("parserFactoryRef", def.getParserFactoryRef());
         doWriteAttribute("textQualifier", def.getTextQualifier());
         doWriteAttribute("ignoreExtraColumns", def.getIgnoreExtraColumns());
-        endElement();
+        endElement(name);
     }
     protected void doWriteGrokDataFormat(
             String name,
@@ -3318,7 +3319,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("namedOnly", def.getNamedOnly());
         doWriteAttribute("pattern", def.getPattern());
         doWriteAttribute("allowMultipleMatchesPerLine", def.getAllowMultipleMatchesPerLine());
-        endElement();
+        endElement(name);
     }
     protected void doWriteGzipDeflaterDataFormat(
             String name,
@@ -3326,7 +3327,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteHL7DataFormat(
             String name,
@@ -3335,7 +3336,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("validate", def.getValidate());
-        endElement();
+        endElement(name);
     }
     protected void doWriteIcalDataFormat(
             String name,
@@ -3344,7 +3345,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("validating", def.getValidating());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJacksonXMLDataFormat(
             String name,
@@ -3368,7 +3369,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("moduleRefs", def.getModuleRefs());
         doWriteAttribute("enableJaxbAnnotationModule", def.getEnableJaxbAnnotationModule());
         doWriteAttribute("xmlMapper", def.getXmlMapper());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJaxbDataFormat(
             String name,
@@ -3396,7 +3397,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("partClass", def.getPartClass());
         doWriteAttribute("jaxbProviderProperties", def.getJaxbProviderProperties());
         doWriteAttribute("partNamespace", def.getPartNamespace());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJsonApiDataFormat(
             String name,
@@ -3406,7 +3407,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("dataFormatTypes", def.getDataFormatTypes());
         doWriteAttribute("mainFormatType", def.getMainFormatType());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJsonDataFormat(
             String name,
@@ -3436,7 +3437,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("useDefaultObjectMapper", def.getUseDefaultObjectMapper());
         doWriteAttribute("objectMapper", def.getObjectMapper());
         doWriteAttribute("namingStrategy", def.getNamingStrategy());
-        endElement();
+        endElement(name);
     }
     protected void doWriteLZFDataFormat(
             String name,
@@ -3445,7 +3446,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("usingParallelCompression", def.getUsingParallelCompression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteMimeMultipartDataFormat(
             String name,
@@ -3458,7 +3459,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("multipartSubType", def.getMultipartSubType());
         doWriteAttribute("includeHeaders", def.getIncludeHeaders());
         doWriteAttribute("binaryContent", def.getBinaryContent());
-        endElement();
+        endElement(name);
     }
     protected void doWritePGPDataFormat(
             String name,
@@ -3480,7 +3481,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("signatureKeyFileName", def.getSignatureKeyFileName());
         doWriteAttribute("hashAlgorithm", def.getHashAlgorithm());
         doWriteAttribute("algorithm", def.getAlgorithm());
-        endElement();
+        endElement(name);
     }
     protected void doWriteParquetAvroDataFormat(
             String name,
@@ -3489,7 +3490,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("unmarshalType", def.getUnmarshalTypeName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteProtobufDataFormat(
             String name,
@@ -3518,7 +3519,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("schemaResolver", def.getSchemaResolver());
         doWriteAttribute("useDefaultObjectMapper", def.getUseDefaultObjectMapper());
         doWriteAttribute("objectMapper", def.getObjectMapper());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRssDataFormat(
             String name,
@@ -3526,7 +3527,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSoapDataFormat(
             String name,
@@ -3540,7 +3541,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("contextPath", def.getContextPath());
         doWriteAttribute("encoding", def.getEncoding());
         doWriteAttribute("version", def.getVersion());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSwiftMtDataFormat(
             String name,
@@ -3549,7 +3550,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("writeInJson", def.getWriteInJson());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSwiftMxDataFormat(
             String name,
@@ -3561,7 +3562,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("writeInJson", def.getWriteInJson());
         doWriteAttribute("writeConfigRef", def.getWriteConfigRef());
         doWriteAttribute("readConfigRef", def.getReadConfigRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSyslogDataFormat(
             String name,
@@ -3569,7 +3570,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTarFileDataFormat(
             String name,
@@ -3581,7 +3582,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("usingIterator", def.getUsingIterator());
         doWriteAttribute("preservePathElements", def.getPreservePathElements());
         doWriteAttribute("allowEmptyDirectory", def.getAllowEmptyDirectory());
-        endElement();
+        endElement(name);
     }
     protected void doWriteThriftDataFormat(
             String name,
@@ -3592,7 +3593,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("contentTypeHeader", def.getContentTypeHeader());
         doWriteAttribute("contentTypeFormat", def.getContentTypeFormat());
         doWriteAttribute("instanceClass", def.getInstanceClass());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTidyMarkupDataFormat(
             String name,
@@ -3602,7 +3603,7 @@ public class ModelWriter extends BaseWriter {
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("omitXmlDeclaration", def.getOmitXmlDeclaration());
         doWriteAttribute("dataObjectType", def.getDataObjectTypeName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityAbstractDataFormatAttributes(
             UniVocityAbstractDataFormat def)
@@ -3634,7 +3635,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteUniVocityAbstractDataFormatAttributes(def);
         doWriteUniVocityAbstractDataFormatElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityCsvDataFormat(
             String name,
@@ -3647,7 +3648,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("delimiter", def.getDelimiter());
         doWriteAttribute("quoteAllFields", def.getQuoteAllFields());
         doWriteUniVocityAbstractDataFormatElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityFixedDataFormat(
             String name,
@@ -3659,7 +3660,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("padding", def.getPadding());
         doWriteAttribute("skipTrailingCharsUntilNewline", def.getSkipTrailingCharsUntilNewline());
         doWriteUniVocityAbstractDataFormatElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityHeader(
             String name,
@@ -3668,7 +3669,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("length", def.getLength());
         doWriteValue(def.getName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteUniVocityTsvDataFormat(
             String name,
@@ -3678,7 +3679,7 @@ public class ModelWriter extends BaseWriter {
         doWriteUniVocityAbstractDataFormatAttributes(def);
         doWriteAttribute("escapeChar", def.getEscapeChar());
         doWriteUniVocityAbstractDataFormatElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteXMLSecurityDataFormat(
             String name,
@@ -3698,7 +3699,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("secureTag", def.getSecureTag());
         doWriteAttribute("xmlCipherAlgorithm", def.getXmlCipherAlgorithm());
         doWriteAttribute("passPhrase", def.getPassPhrase());
-        endElement();
+        endElement(name);
     }
     protected void doWriteYAMLDataFormat(
             String name,
@@ -3718,7 +3719,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("useApplicationContextClassLoader", def.getUseApplicationContextClassLoader());
         doWriteAttribute("allowRecursiveKeys", def.getAllowRecursiveKeys());
         doWriteList(null, "typeFilter", def.getTypeFilters(), this::doWriteYAMLTypeFilterDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteYAMLTypeFilterDefinition(
             String name,
@@ -3727,7 +3728,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("type", def.getType());
         doWriteAttribute("value", def.getValue());
-        endElement();
+        endElement(name);
     }
     protected void doWriteZipDeflaterDataFormat(
             String name,
@@ -3736,7 +3737,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("compressionLevel", def.getCompressionLevel());
-        endElement();
+        endElement(name);
     }
     protected void doWriteZipFileDataFormat(
             String name,
@@ -3748,7 +3749,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("usingIterator", def.getUsingIterator());
         doWriteAttribute("preservePathElements", def.getPreservePathElements());
         doWriteAttribute("allowEmptyDirectory", def.getAllowEmptyDirectory());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDeadLetterChannelDefinition(
             String name,
@@ -3759,7 +3760,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("deadLetterHandleNewException", def.getDeadLetterHandleNewException());
         doWriteAttribute("deadLetterUri", def.getDeadLetterUri());
         doWriteDefaultErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteDefaultErrorHandlerDefinitionAttributes(
             DefaultErrorHandlerDefinition def)
@@ -3789,7 +3790,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteDefaultErrorHandlerDefinitionAttributes(def);
         doWriteDefaultErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteJtaTransactionErrorHandlerDefinition(
             String name,
@@ -3798,7 +3799,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTransactionErrorHandlerDefinitionAttributes(def);
         doWriteDefaultErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteNoErrorHandlerDefinition(
             String name,
@@ -3806,7 +3807,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRefErrorHandlerDefinition(
             String name,
@@ -3815,7 +3816,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSpringTransactionErrorHandlerDefinition(
             String name,
@@ -3824,7 +3825,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTransactionErrorHandlerDefinitionAttributes(def);
         doWriteDefaultErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransactionErrorHandlerDefinitionAttributes(
             TransactionErrorHandlerDefinition def)
@@ -3845,7 +3846,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTransactionErrorHandlerDefinitionAttributes(def);
         doWriteTransactionErrorHandlerDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCSimpleExpression(
             String name,
@@ -3854,7 +3855,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteConstantExpression(
             String name,
@@ -3863,7 +3864,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDatasonnetExpression(
             String name,
@@ -3874,7 +3875,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("outputMediaType", def.getOutputMediaType());
         doWriteAttribute("bodyMediaType", def.getBodyMediaType());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteExchangePropertyExpression(
             String name,
@@ -3883,7 +3884,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteExpressionDefinitionAttributes(
             ExpressionDefinition def)
@@ -3898,7 +3899,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteGroovyExpression(
             String name,
@@ -3907,7 +3908,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteHeaderExpression(
             String name,
@@ -3916,7 +3917,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteHl7TerserExpression(
             String name,
@@ -3925,7 +3926,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSingleInputTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJavaScriptExpression(
             String name,
@@ -3934,7 +3935,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJoorExpression(
             String name,
@@ -3945,7 +3946,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("preCompile", def.getPreCompile());
         doWriteAttribute("singleQuotes", def.getSingleQuotes());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJqExpression(
             String name,
@@ -3954,7 +3955,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSingleInputTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteJsonPathExpression(
             String name,
@@ -3969,7 +3970,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("allowEasyPredicate", def.getAllowEasyPredicate());
         doWriteAttribute("option", def.getOption());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteLanguageExpression(
             String name,
@@ -3979,7 +3980,7 @@ public class ModelWriter extends BaseWriter {
         doWriteExpressionDefinitionAttributes(def);
         doWriteAttribute("language", def.getLanguage());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteMethodCallExpression(
             String name,
@@ -3992,7 +3993,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("scope", def.getScope());
         doWriteAttribute("beanType", def.getBeanTypeName());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteMvelExpression(
             String name,
@@ -4001,7 +4002,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteNamespaceAwareExpressionAttributes(
             NamespaceAwareExpression def)
@@ -4021,7 +4022,7 @@ public class ModelWriter extends BaseWriter {
         doWriteNamespaceAwareExpressionAttributes(def);
         doWriteValue(def.getExpression());
         doWriteNamespaceAwareExpressionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOgnlExpression(
             String name,
@@ -4030,7 +4031,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWritePythonExpression(
             String name,
@@ -4039,7 +4040,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRefExpression(
             String name,
@@ -4048,7 +4049,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSimpleExpression(
             String name,
@@ -4057,7 +4058,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSingleInputExpressionDefinitionAttributes(
             SingleInputExpressionDefinition def)
@@ -4073,7 +4074,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSingleInputExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSingleInputTypedExpressionDefinitionAttributes(
             SingleInputTypedExpressionDefinition def)
@@ -4089,7 +4090,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteSingleInputTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteSpELExpression(
             String name,
@@ -4098,7 +4099,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTokenizerExpression(
             String name,
@@ -4116,7 +4117,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("group", def.getGroup());
         doWriteAttribute("token", def.getToken());
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTypedExpressionDefinitionAttributes(
             TypedExpressionDefinition def)
@@ -4131,7 +4132,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteTypedExpressionDefinitionAttributes(def);
         doWriteValue(def.getExpression());
-        endElement();
+        endElement(name);
     }
     protected void doWriteXMLTokenizerExpression(
             String name,
@@ -4141,9 +4142,9 @@ public class ModelWriter extends BaseWriter {
         doWriteSingleInputExpressionDefinitionAttributes(def);
         doWriteAttribute("mode", def.getMode());
         doWriteAttribute("group", def.getGroup());
+        doWriteNamespaces(def);
         doWriteValue(def.getExpression());
-        doWriteNamespaceAwareExpressionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteXPathExpression(
             String name,
@@ -4159,9 +4160,9 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("saxon", def.getSaxon());
         doWriteAttribute("documentType", def.getDocumentTypeName());
         doWriteAttribute("resultType", def.getResultTypeName());
+        doWriteNamespaces(def);
         doWriteValue(def.getExpression());
-        doWriteNamespaceAwareExpressionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteXQueryExpression(
             String name,
@@ -4172,9 +4173,9 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("configurationRef", def.getConfigurationRef());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("resultType", def.getResultTypeName());
+        doWriteNamespaces(def);
         doWriteValue(def.getExpression());
-        doWriteNamespaceAwareExpressionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomLoadBalancerDefinition(
             String name,
@@ -4183,7 +4184,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteAttribute("ref", def.getRef());
-        endElement();
+        endElement(name);
     }
     protected void doWriteFailoverLoadBalancerDefinition(
             String name,
@@ -4195,7 +4196,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("maximumFailoverAttempts", def.getMaximumFailoverAttempts());
         doWriteAttribute("roundRobin", def.getRoundRobin());
         doWriteList(null, "exception", def.getExceptions(), this::doWriteString);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRandomLoadBalancerDefinition(
             String name,
@@ -4203,7 +4204,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRoundRobinLoadBalancerDefinition(
             String name,
@@ -4211,7 +4212,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteStickyLoadBalancerDefinition(
             String name,
@@ -4220,7 +4221,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
         doWriteElement("correlationExpression", def.getCorrelationExpression(), this::doWriteExpressionSubElementDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTopicLoadBalancerDefinition(
             String name,
@@ -4228,7 +4229,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteIdentifiedTypeAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteWeightedLoadBalancerDefinition(
             String name,
@@ -4239,7 +4240,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("distributionRatioDelimiter", def.getDistributionRatioDelimiter());
         doWriteAttribute("distributionRatio", def.getDistributionRatio());
         doWriteAttribute("roundRobin", def.getRoundRobin());
-        endElement();
+        endElement(name);
     }
     protected void doWriteApiKeyDefinition(
             String name,
@@ -4251,7 +4252,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("inCookie", def.getInCookie());
         doWriteAttribute("name", def.getName());
         doWriteAttribute("inQuery", def.getInQuery());
-        endElement();
+        endElement(name);
     }
     protected void doWriteBasicAuthDefinition(
             String name,
@@ -4259,7 +4260,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteBearerTokenDefinition(
             String name,
@@ -4268,7 +4269,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
         doWriteAttribute("format", def.getFormat());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDeleteDefinition(
             String name,
@@ -4277,7 +4278,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteGetDefinition(
             String name,
@@ -4286,7 +4287,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteHeadDefinition(
             String name,
@@ -4295,7 +4296,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteMutualTLSDefinition(
             String name,
@@ -4303,7 +4304,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOAuth2Definition(
             String name,
@@ -4316,7 +4317,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("refreshUrl", def.getRefreshUrl());
         doWriteAttribute("flow", def.getFlow());
         doWriteList(null, "scopes", def.getScopes(), this::doWriteRestPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteOpenIdConnectDefinition(
             String name,
@@ -4325,7 +4326,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
         doWriteAttribute("url", def.getUrl());
-        endElement();
+        endElement(name);
     }
     protected void doWriteParamDefinition(
             String name,
@@ -4343,7 +4344,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("required", toString(def.getRequired()));
         doWriteList("allowableValues", "value", def.getAllowableValues(), this::doWriteValueDefinition);
         doWriteList(null, "examples", def.getExamples(), this::doWriteRestPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWritePatchDefinition(
             String name,
@@ -4352,7 +4353,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePostDefinition(
             String name,
@@ -4361,7 +4362,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWritePutDefinition(
             String name,
@@ -4370,7 +4371,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteResponseHeaderDefinition(
             String name,
@@ -4385,7 +4386,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("collectionFormat", toString(def.getCollectionFormat()));
         doWriteAttribute("example", def.getExample());
         doWriteList("allowableValues", "value", def.getAllowableValues(), this::doWriteValueDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteResponseMessageDefinition(
             String name,
@@ -4397,7 +4398,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("message", def.getMessage());
         doWriteList(null, "header", def.getHeaders(), this::doWriteResponseHeaderDefinition);
         doWriteList(null, "examples", def.getExamples(), this::doWriteRestPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestBindingDefinition(
             String name,
@@ -4415,7 +4416,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("produces", def.getProduces());
         doWriteAttribute("consumes", def.getConsumes());
         doWriteOptionalIdentifiedDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestConfigurationDefinition(
             String name,
@@ -4449,7 +4450,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "apiProperty", def.getApiProperties(), this::doWriteRestPropertyDefinition);
         doWriteList(null, "endpointProperty", def.getEndpointProperties(), this::doWriteRestPropertyDefinition);
         doWriteList(null, "dataFormatProperty", def.getDataFormatProperties(), this::doWriteRestPropertyDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestDefinition(
             String name,
@@ -4471,7 +4472,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "securityRequirements", def.getSecurityRequirements(), this::doWriteSecurityDefinition);
         doWriteList(null, null, def.getVerbs(), this::doWriteVerbDefinitionRef);
         doWriteElement("securityDefinitions", def.getSecurityDefinitions(), this::doWriteRestSecuritiesDefinition);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestPropertyDefinition(
             String name,
@@ -4480,7 +4481,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("value", def.getValue());
         doWriteAttribute("key", def.getKey());
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestSecuritiesDefinition(
             String name,
@@ -4497,7 +4498,7 @@ public class ModelWriter extends BaseWriter {
                 case "MutualTLSDefinition" -> doWriteMutualTLSDefinition("mutualTLS", (MutualTLSDefinition) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestSecurityDefinitionAttributes(
             RestSecurityDefinition def)
@@ -4511,7 +4512,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteRestSecurityDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteRestsDefinition(
             String name,
@@ -4521,7 +4522,7 @@ public class ModelWriter extends BaseWriter {
         doWriteOptionalIdentifiedDefinitionAttributes(def);
         doWriteOptionalIdentifiedDefinitionElements(def);
         doWriteList(null, null, def.getRests(), this::doWriteRestDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteSecurityDefinition(
             String name,
@@ -4530,7 +4531,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteAttribute("scopes", def.getScopes());
         doWriteAttribute("key", def.getKey());
-        endElement();
+        endElement(name);
     }
     protected void doWriteVerbDefinitionAttributes(
             VerbDefinition def)
@@ -4566,7 +4567,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteVerbDefinitionAttributes(def);
         doWriteVerbDefinitionElements(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomTransformerDefinition(
             String name,
@@ -4576,7 +4577,7 @@ public class ModelWriter extends BaseWriter {
         doWriteTransformerDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("className", def.getClassName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteDataFormatTransformerDefinition(
             String name,
@@ -4628,7 +4629,7 @@ public class ModelWriter extends BaseWriter {
                 case "ZipFileDataFormat" -> doWriteZipFileDataFormat("zipFile", (ZipFileDataFormat) def.getDataFormatType());
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteEndpointTransformerDefinition(
             String name,
@@ -4638,7 +4639,7 @@ public class ModelWriter extends BaseWriter {
         doWriteTransformerDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("uri", def.getUri());
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransformerDefinitionAttributes(
             TransformerDefinition def)
@@ -4653,7 +4654,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteTransformerDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteTransformersDefinition(
             String name,
@@ -4667,7 +4668,7 @@ public class ModelWriter extends BaseWriter {
                 case "CustomTransformerDefinition" -> doWriteCustomTransformerDefinition("customTransformer", (CustomTransformerDefinition) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteCustomValidatorDefinition(
             String name,
@@ -4677,7 +4678,7 @@ public class ModelWriter extends BaseWriter {
         doWriteValidatorDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("className", def.getClassName());
-        endElement();
+        endElement(name);
     }
     protected void doWriteEndpointValidatorDefinition(
             String name,
@@ -4687,7 +4688,7 @@ public class ModelWriter extends BaseWriter {
         doWriteValidatorDefinitionAttributes(def);
         doWriteAttribute("ref", def.getRef());
         doWriteAttribute("uri", def.getUri());
-        endElement();
+        endElement(name);
     }
     protected void doWritePredicateValidatorDefinition(
             String name,
@@ -4696,7 +4697,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteValidatorDefinitionAttributes(def);
         doWriteElement(null, def.getExpression(), this::doWriteExpressionDefinitionRef);
-        endElement();
+        endElement(name);
     }
     protected void doWriteValidatorDefinitionAttributes(
             ValidatorDefinition def)
@@ -4709,7 +4710,7 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         startElement(name);
         doWriteValidatorDefinitionAttributes(def);
-        endElement();
+        endElement(name);
     }
     protected void doWriteValidatorsDefinition(
             String name,
@@ -4723,7 +4724,7 @@ public class ModelWriter extends BaseWriter {
                 case "CustomValidatorDefinition" -> doWriteCustomValidatorDefinition("customValidator", (CustomValidatorDefinition) v);
             }
         });
-        endElement();
+        endElement(name);
     }
     protected void doWriteFromDefinitionRef(
             String n,
@@ -5071,7 +5072,7 @@ public class ModelWriter extends BaseWriter {
     }
     protected void doWriteAttribute(
             String attribute,
-            String value)
+            Object value)
             throws IOException {
         if (value != null) {
             attribute(attribute, value);
@@ -5079,7 +5080,7 @@ public class ModelWriter extends BaseWriter {
     }
     protected void doWriteValue(String value) throws IOException {
         if (value != null) {
-            text(value);
+            value(value);
         }
     }
     protected <T> void doWriteList(String wrapperName, String name, List<T> list, ElementSerializer<T> elementSerializer) throws IOException {
@@ -5091,7 +5092,7 @@ public class ModelWriter extends BaseWriter {
                 elementSerializer.doWriteElement(name, v);
             }
             if (wrapperName != null) {
-                endElement();
+                endElement(wrapperName);
             }
         }
     }
@@ -5115,8 +5116,17 @@ public class ModelWriter extends BaseWriter {
     protected void doWriteString(String name, String value) throws IOException {
         if (value != null) {
             startElement(name);
-            text(value);
-            endElement();
+            text(name, value);
+            endElement(name);
+        }
+    }
+    protected void doWriteNamespaces(
+            NamespaceAwareExpression def)
+            throws IOException {
+        if (def.getNamespaceAsMap() != null) {
+            for (var e : def.getNamespaceAsMap().entrySet()) {
+                doWriteAttribute("xmlns:" + e.getKey(), e.getValue());
+            }
         }
     }
 
diff --git a/core/camel-yaml-io/src/generated/resources/META-INF/services/org/apache/camel/modelyaml-dumper b/core/camel-yaml-io/src/generated/resources/META-INF/services/org/apache/camel/modelyaml-dumper
new file mode 100644
index 00000000000..fa16d633613
--- /dev/null
+++ b/core/camel-yaml-io/src/generated/resources/META-INF/services/org/apache/camel/modelyaml-dumper
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.yaml.LwModelToYAMLDumper
diff --git a/core/camel-yaml-io/src/generated/resources/META-INF/services/org/apache/camel/other.properties b/core/camel-yaml-io/src/generated/resources/META-INF/services/org/apache/camel/other.properties
new file mode 100644
index 00000000000..a65a3ab855d
--- /dev/null
+++ b/core/camel-yaml-io/src/generated/resources/META-INF/services/org/apache/camel/other.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+name=yaml-io
+groupId=org.apache.camel
+artifactId=camel-yaml-io
+version=4.0.0-SNAPSHOT
+projectName=Camel :: YAML IO
+projectDescription=Camel YAML IO
diff --git a/core/camel-yaml-io/src/generated/resources/yaml-io.json b/core/camel-yaml-io/src/generated/resources/yaml-io.json
new file mode 100644
index 00000000000..85ae50b23c4
--- /dev/null
+++ b/core/camel-yaml-io/src/generated/resources/yaml-io.json
@@ -0,0 +1,15 @@
+{
+  "other": {
+    "kind": "other",
+    "name": "yaml-io",
+    "title": "Yaml Io",
+    "description": "Camel YAML IO",
+    "deprecated": false,
+    "firstVersion": "4.0.0",
+    "label": "dsl",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-yaml-io",
+    "version": "4.0.0-SNAPSHOT"
+  }
+}
diff --git a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
similarity index 82%
copy from core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
copy to core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
index 7f02740836b..d111e5c27b1 100644
--- a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
+++ b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.xml;
+package org.apache.camel.yaml;
 
 import java.io.IOException;
 import java.io.StringWriter;
@@ -40,30 +40,29 @@ import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.SendDefinition;
 import org.apache.camel.model.ToDynamicDefinition;
 import org.apache.camel.model.language.ExpressionDefinition;
-import org.apache.camel.spi.ModelToXMLDumper;
+import org.apache.camel.spi.ModelToYAMLDumper;
 import org.apache.camel.spi.NamespaceAware;
 import org.apache.camel.spi.annotations.JdkService;
 import org.apache.camel.util.KeyValueHolder;
-import org.apache.camel.xml.out.ModelWriter;
+import org.apache.camel.yaml.out.ModelWriter;
 
 import static org.apache.camel.model.ProcessorDefinitionHelper.filterTypeInOutputs;
 
 /**
- * Lightweight {@link ModelToXMLDumper} based on the generated {@link ModelWriter}.
+ * Lightweight {@link org.apache.camel.spi.ModelToYAMLDumper} based on the generated {@link ModelWriter}.
  */
-@JdkService(ModelToXMLDumper.FACTORY)
-public class LwModelToXMLDumper implements ModelToXMLDumper {
+@JdkService(ModelToYAMLDumper.FACTORY)
+public class LwModelToYAMLDumper implements ModelToYAMLDumper {
 
     @Override
-    public String dumpModelAsXml(CamelContext context, NamedNode definition) throws Exception {
-        return dumpModelAsXml(context, definition, false, false);
+    public String dumpModelAsYaml(CamelContext context, NamedNode definition) throws Exception {
+        return dumpModelAsYaml(context, definition, false, false);
     }
 
     @Override
-    public String dumpModelAsXml(
+    public String dumpModelAsYaml(
             CamelContext context, NamedNode definition, boolean resolvePlaceholders, boolean resolveDelegateEndpoints)
             throws Exception {
-
         Properties properties = new Properties();
         Map<String, String> namespaces = new LinkedHashMap<>();
         Map<String, KeyValueHolder<Integer, String>> locations = new HashMap<>();
@@ -82,7 +81,7 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
         };
 
         StringWriter buffer = new StringWriter();
-        ModelWriter writer = new ModelWriter(buffer, "http://camel.apache.org/schema/spring") {
+        ModelWriter writer = new ModelWriter(buffer) {
             @Override
             protected void doWriteOptionalIdentifiedDefinitionAttributes(OptionalIdentifiedDefinition<?> def)
                     throws IOException {
@@ -103,20 +102,6 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
                 }
             }
 
-            @Override
-            protected void startElement(String name) throws IOException {
-                boolean namespaceWritten = this.namespaceWritten;
-                super.startElement(name);
-                if (!namespaceWritten) {
-                    for (Map.Entry<String, String> entry : namespaces.entrySet()) {
-                        // TODO: check duplicate xmlns="xxx" attribute ?
-                        String nsPrefix = entry.getKey();
-                        String prefix = nsPrefix.equals("xmlns") ? nsPrefix : "xmlns:" + nsPrefix;
-                        writer.addAttribute(prefix, entry.getValue());
-                    }
-                }
-            }
-
             @Override
             protected void doWriteValue(String value) throws IOException {
                 if (value != null && !value.isEmpty()) {
@@ -125,25 +110,27 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
             }
 
             @Override
-            protected void text(String text) throws IOException {
+            protected void text(String name, String text) throws IOException {
                 if (resolvePlaceholders) {
                     text = resolve(text, properties);
                 }
-                super.text(text);
+                super.text(name, text);
             }
 
             @Override
-            protected void attribute(String name, String value) throws IOException {
-                if (resolveDelegateEndpoints && "uri".equals(name)) {
-                    String uri = resolve(value, properties);
-                    Endpoint endpoint = context.hasEndpoint(uri);
-                    if (endpoint instanceof DelegateEndpoint) {
-                        endpoint = ((DelegateEndpoint) endpoint).getEndpoint();
-                        value = endpoint.getEndpointUri();
+            protected void attribute(String name, Object value) throws IOException {
+                if (value != null) {
+                    if (resolveDelegateEndpoints && "uri".equals(name)) {
+                        String uri = resolve(value.toString(), properties);
+                        Endpoint endpoint = context.hasEndpoint(uri);
+                        if (endpoint instanceof DelegateEndpoint) {
+                            endpoint = ((DelegateEndpoint) endpoint).getEndpoint();
+                            value = endpoint.getEndpointUri();
+                        }
+                    }
+                    if (resolvePlaceholders) {
+                        value = resolve(value.toString(), properties);
                     }
-                }
-                if (resolvePlaceholders) {
-                    value = resolve(value, properties);
                 }
                 super.attribute(name, value);
             }
@@ -222,7 +209,7 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
 
     /**
      * If the route has been built with endpoint-dsl, then the model will not have uri set which then cannot be included
-     * in the JAXB model dump
+     * in the model dump
      */
     @SuppressWarnings("rawtypes")
     private static void resolveEndpointDslUris(RouteDefinition route) {
diff --git a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/EipNode.java b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/EipNode.java
new file mode 100644
index 00000000000..df70acc4d9f
--- /dev/null
+++ b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/EipNode.java
@@ -0,0 +1,187 @@
+/*
+ * 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.yaml.io;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+
+/**
+ * Represents a node during dumping model to Yaml DSL.
+ */
+class EipNode {
+
+    private final String name;
+    private final EipNode parent;
+    private final boolean output;
+    private final boolean expression;
+    private EipNode input;
+    private List<EipNode> outputs;
+    private List<EipNode> expressions;
+    private String text;
+    private Map<String, Object> properties;
+
+    public EipNode(String name, EipNode parent, boolean output, boolean expression) {
+        this.name = name;
+        this.parent = parent;
+        this.output = output;
+        this.expression = expression;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public EipNode getParent() {
+        return parent;
+    }
+
+    public EipNode getInput() {
+        return input;
+    }
+
+    public void setInput(EipNode input) {
+        this.input = input;
+    }
+
+    public boolean isOutput() {
+        return output;
+    }
+
+    public boolean isExpression() {
+        return expression;
+    }
+
+    public List<EipNode> getOutputs() {
+        if (outputs == null) {
+            return Collections.emptyList();
+        }
+        return outputs;
+    }
+
+    public void addOutput(EipNode output) {
+        if (outputs == null) {
+            outputs = new ArrayList<>();
+        }
+        outputs.add(output);
+    }
+
+    public List<EipNode> getExpressions() {
+        if (expressions == null) {
+            return Collections.emptyList();
+        }
+        return expressions;
+    }
+
+    public void addExpression(EipNode output) {
+        if (expressions == null) {
+            expressions = new ArrayList<>();
+        }
+        expressions.add(output);
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public Map<String, Object> getProperties() {
+        if (properties == null) {
+            return Collections.emptyMap();
+        }
+        return properties;
+    }
+
+    public void addProperty(String key, Object value) {
+        if (properties == null) {
+            properties = new LinkedHashMap<>();
+        }
+        properties.put(key, value);
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    /**
+     * Converts this node to JSon
+     */
+    JsonObject asJsonObject() {
+        JsonObject answer = new JsonObject();
+
+        if (properties != null) {
+            answer.putAll(properties);
+        }
+
+        if (expressions != null) {
+            for (EipNode o : expressions) {
+                String key = o.getName();
+                String language = (String) o.getProperties().remove("language");
+                JsonObject r = o.asJsonObject();
+                if (!key.equals(o.getName())) {
+                    // need to wrap if sub element such as aggregate with correlationExpression
+                    JsonObject wrap = new JsonObject();
+                    wrap.put(o.getName(), r);
+                    answer.put(key, wrap);
+                } else if (language != null && !key.equals(language)) {
+                    JsonObject wrap = new JsonObject();
+                    wrap.put(language, r);
+                    answer.put(key, wrap);
+                } else {
+                    answer.put(key, r);
+                }
+            }
+        }
+        if (outputs != null) {
+            // sort so otherwise is last
+            outputs.sort((o1, o2) -> {
+                if ("otherwise".equals(o1.name)) {
+                    return 1;
+                } else if ("otherwise".equals(o2.name)) {
+                    return -1;
+                }
+                return 0;
+            });
+            if (("marshal".equals(name) || "unmarshal".equals(name)) && outputs.size() == 1) {
+                EipNode o = outputs.get(0);
+                JsonObject jo = o.asJsonObject();
+                answer.put(o.getName(), jo);
+            } else {
+                JsonArray arr = new JsonArray();
+                for (EipNode o : outputs) {
+                    JsonObject r = o.asJsonObject();
+                    JsonObject wrap = new JsonObject();
+                    wrap.put(o.getName(), r);
+                    arr.add(wrap);
+                }
+                answer.put("steps", arr);
+            }
+        }
+
+        return answer;
+    }
+
+}
diff --git a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/ModelJSonSchemaResolver.java b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/ModelJSonSchemaResolver.java
new file mode 100644
index 00000000000..46187cfc463
--- /dev/null
+++ b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/ModelJSonSchemaResolver.java
@@ -0,0 +1,93 @@
+/*
+ * 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.yaml.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.camel.catalog.JSonSchemaResolver;
+import org.apache.camel.support.CamelContextHelper;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * To load model json metadata
+ */
+class ModelJSonSchemaResolver implements JSonSchemaResolver {
+
+    @Override
+    public void setClassLoader(ClassLoader classLoader) {
+        // not in use
+    }
+
+    @Override
+    public String getComponentJSonSchema(String name) {
+        throw new UnsupportedOperationException("Only getModelJSonSchema is in use");
+    }
+
+    @Override
+    public String getDataFormatJSonSchema(String name) {
+        throw new UnsupportedOperationException("Only getModelJSonSchema is in use");
+    }
+
+    @Override
+    public String getLanguageJSonSchema(String name) {
+        throw new UnsupportedOperationException("Only getModelJSonSchema is in use");
+    }
+
+    @Override
+    public String getOtherJSonSchema(String name) {
+        throw new UnsupportedOperationException("Only getModelJSonSchema is in use");
+    }
+
+    @Override
+    public String getModelJSonSchema(String name) {
+        try {
+            String[] subPackages = new String[] {
+                    "", "cloud/", "config/", "dataformat/", "errorhandler/", "language/", "loadbalancer/", "rest/",
+                    "transformer/", "validator/" };
+            for (String sub : subPackages) {
+                String path = CamelContextHelper.MODEL_DOCUMENTATION_PREFIX + sub + name + ".json";
+                String inputStream = doLoadResource(path);
+                if (inputStream != null) {
+                    return inputStream;
+                }
+            }
+        } catch (Throwable e) {
+            // ignore
+        }
+        return null;
+    }
+
+    @Override
+    public String getMainJsonSchema() {
+        throw new UnsupportedOperationException("Only getModelJSonSchema is in use");
+    }
+
+    private static String doLoadResource(String path) throws IOException {
+        InputStream inputStream = ObjectHelper.loadResourceAsStream(path, Thread.currentThread().getContextClassLoader());
+        if (inputStream != null) {
+            try {
+                return IOHelper.loadText(inputStream);
+            } finally {
+                IOHelper.close(inputStream);
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/YamlWriter.java b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/YamlWriter.java
new file mode 100644
index 00000000000..0ab60e15869
--- /dev/null
+++ b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/YamlWriter.java
@@ -0,0 +1,418 @@
+/*
+ * 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.yaml.io;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.StringJoiner;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
+import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+import org.apache.camel.catalog.impl.DefaultRuntimeCamelCatalog;
+import org.apache.camel.catalog.impl.URISupport;
+import org.apache.camel.tooling.model.BaseOptionModel;
+import org.apache.camel.tooling.model.EipModel;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+
+/**
+ * YAML writer which uses Jackson to dump to yaml format.
+ *
+ * Implementation notes:
+ *
+ * This writer is based on the same principle for the XML writer which parses the Camel routes (model classes) and emit
+ * a StAX based events for start/end elements.
+ *
+ * However since the YAML DSL is not as easy to dump as XML, then we need to enrich with additional metadata from the
+ * runtime catalog ({@link EipModel}). We then abuse the {@link EipModel} and store the route details in its metadata.
+ * After this we transform from {@link EipModel} to {@link EipNode} to have a List/Map structure that we then transform
+ * to JSon, and then from JSon to YAML.
+ */
+public class YamlWriter {
+
+    private final Writer writer;
+    private final DefaultRuntimeCamelCatalog catalog;
+    private final List<EipModel> roots = new ArrayList<>();
+    private boolean routesIsRoot;
+    private final Stack<EipModel> models = new Stack<>();
+    private String expression;
+
+    public YamlWriter(Writer writer) {
+        this.writer = writer;
+        this.catalog = new DefaultRuntimeCamelCatalog();
+        this.catalog.setCaching(false); // turn cache off as we store state per node
+        this.catalog.setJSonSchemaResolver(new ModelJSonSchemaResolver());
+        this.catalog.start();
+    }
+
+    public void startElement(String name) throws IOException {
+        if ("routes".equals(name)) {
+            routesIsRoot = true;
+            return;
+        }
+
+        EipModel model = catalog.eipModel(name);
+        if (model == null) {
+            // not an EIP model
+            return;
+        }
+
+        EipModel parent = models.isEmpty() ? null : models.peek();
+        model.getMetadata().put("_parent", parent);
+        models.push(model);
+        if (parent == null) {
+            // its a root element
+            roots.add(model);
+        }
+    }
+
+    public void startExpressionElement(String name) throws IOException {
+        // currently building an expression
+        this.expression = name;
+    }
+
+    public void endExpressionElement(String name) throws IOException {
+        // expression complete, back to normal mode
+        this.expression = null;
+    }
+
+    public void endElement(String name) throws IOException {
+        if ("routes".equals(name)) {
+            // we are done
+            writer.write(toYaml());
+            return;
+        }
+
+        EipModel model = catalog.eipModel(name);
+        if (model == null) {
+            // not an EIP model
+            return;
+        }
+
+        EipModel last = models.isEmpty() ? null : models.peek();
+        if (last != null && isLanguage(last)) {
+            if (!models.isEmpty()) {
+                models.pop();
+            }
+            // okay we ended a language which we need to set on a parent EIP
+            EipModel parent = models.isEmpty() ? null : models.peek();
+            if (parent != null) {
+                String key = expressionName(parent, expression);
+                if (key != null) {
+                    parent.getMetadata().put(key, last);
+                }
+            }
+            return;
+        }
+
+        if (last != null) {
+            if (!models.isEmpty()) {
+                models.pop();
+            }
+            // is this input/output on the parent
+            EipModel parent = models.isEmpty() ? null : models.peek();
+            if (parent != null) {
+                if ("from".equals(name) && parent.isInput()) {
+                    // only set input once
+                    parent.getMetadata().put("_input", last);
+                } else if ("choice".equals(parent.getName())) {
+                    // special for choice/doCatch/doFinally
+                    setMetadata(parent, name, last);
+                } else if (parent.isOutput()) {
+                    List<EipModel> list = (List<EipModel>) parent.getMetadata().get("_output");
+                    if (list == null) {
+                        list = new ArrayList<>();
+                        parent.getMetadata().put("_output", list);
+                    }
+                    list.add(last);
+                } else if ("marshal".equals(parent.getName()) || "unmarshal".equals(parent.getName())) {
+                    parent.getMetadata().put("_dataFormatType", last);
+                }
+            }
+        }
+
+        if (models.isEmpty() && !routesIsRoot) {
+            // we are done
+            writer.write(toYaml());
+        }
+    }
+
+    public void writeText(String name, String text) throws IOException {
+        EipModel last = models.isEmpty() ? null : models.peek();
+        if (last != null) {
+            // special as writeText can be used for list of string values
+            setMetadata(last, name, text);
+        }
+    }
+
+    public void writeValue(String value) throws IOException {
+        EipModel last = models.isEmpty() ? null : models.peek();
+        if (last != null) {
+            String key = valueName(last);
+            if (key != null) {
+                last.getMetadata().put(key, value);
+            }
+        }
+    }
+
+    public void addAttribute(String name, Object value) throws IOException {
+        EipModel last = models.isEmpty() ? null : models.peek();
+        if (last != null) {
+            // uri should be expanded into more human-readable with parameters
+            if ("uri".equals(name) && value != null) {
+                try {
+                    String base = URISupport.stripQuery(value.toString());
+                    String query = URISupport.extractQuery(value.toString());
+                    if (base != null && query != null) {
+                        Map<String, Object> parameters = parseQuery(query);
+                        if (!parameters.isEmpty()) {
+                            last.getMetadata().put("uri", base);
+                            last.getMetadata().put("parameters", parameters);
+                            return;
+                        }
+                    }
+                } catch (Exception e) {
+                    // ignore
+                }
+            }
+
+            last.getMetadata().put(name, value);
+        }
+    }
+
+    private static Map<String, Object> parseQuery(String query) throws URISyntaxException {
+        Map<String, Object> parameters = URISupport.parseQuery(query);
+        // convert "true" / "false" to boolean values
+        parameters.forEach((k, v) -> {
+            if ("true".equals(v) || "false".equals(v)) {
+                parameters.replace(k, Boolean.valueOf(v.toString()));
+            }
+        });
+        return parameters;
+    }
+
+    private EipNode asExpressionNode(EipModel model, String name) {
+        EipNode node = new EipNode(name, null, false, true);
+        doAsNode(model, node);
+        return node;
+    }
+
+    private EipNode asNode(EipModel model) {
+        EipNode node = new EipNode(model.getName(), null, false, false);
+        doAsNode(model, node);
+        return node;
+    }
+
+    private void doAsNode(EipModel model, EipNode node) {
+        for (Map.Entry<String, Object> entry : model.getMetadata().entrySet()) {
+            String key = entry.getKey();
+            if ("_input".equals(key)) {
+                EipModel m = (EipModel) entry.getValue();
+                node.setInput(asNode(m));
+            } else if ("_output".equals(key)) {
+                List<EipModel> list = (List) entry.getValue();
+                for (EipModel m : list) {
+                    node.addOutput(asNode(m));
+                }
+            } else if ("choice".equals(node.getName()) && "otherwise".equals(key)) {
+                EipModel other = (EipModel) entry.getValue();
+                node.addOutput(asNode(other));
+            } else if ("choice".equals(node.getName()) && "when".equals(key)) {
+                Object v = entry.getValue();
+                if (v instanceof List) {
+                    // can be a list in choice
+                    List<EipModel> list = (List) v;
+                    for (EipModel m : list) {
+                        node.addOutput(asNode(m));
+                    }
+                } else {
+                    node.addOutput(asNode((EipModel) v));
+                }
+            } else if (("marshal".equals(node.getName()) || "unmarshal".equals(node.getName()))
+                    && "_dataFormatType".equals(key)) {
+                EipModel other = (EipModel) entry.getValue();
+                node.addOutput(asNode(other));
+            } else {
+                boolean skip = key.startsWith("_") || key.equals("customId");
+                if (skip) {
+                    continue;
+                }
+                String exp = null;
+                if (!isLanguage(model)) {
+                    // special for expressions that are a property where we need to use expression name as key
+                    exp = expressionName(model, key);
+                }
+                Object v = entry.getValue();
+                if (v instanceof EipModel) {
+                    EipModel m = (EipModel) entry.getValue();
+                    if (exp == null || "expression".equals(exp)) {
+                        v = asExpressionNode(m, m.getName());
+                    } else {
+                        v = asExpressionNode(m, exp);
+                    }
+                }
+                if (exp != null && v instanceof EipNode) {
+                    node.addExpression((EipNode) v);
+                } else {
+                    node.addProperty(key, v);
+                    if ("expression".equals(key)) {
+                        node.addProperty("language", model.getName());
+                    }
+                }
+            }
+        }
+    }
+
+    public String toYaml() {
+        try {
+            // model to json
+            JsonArray arr = transformToJson(roots);
+            // load into jackson
+            JsonNode jsonNodeTree = new ObjectMapper().readTree(arr.toJson());
+            // map to yaml via jackson
+            YAMLMapper mapper = new YAMLMapper();
+            mapper.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
+            mapper.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES);
+            mapper.enable(YAMLGenerator.Feature.INDENT_ARRAYS_WITH_INDICATOR);
+            String jsonAsYaml = mapper.writeValueAsString(jsonNodeTree);
+            // strip leading yaml indent of 2 spaces (because INDENT_ARRAYS_WITH_INDICATOR is enabled)
+            StringJoiner sj = new StringJoiner("\n");
+            for (String line : jsonAsYaml.split("\n")) {
+                if (line.startsWith("  ")) {
+                    line = line.substring(2);
+                }
+                sj.add(line);
+            }
+            sj.add(""); // end with empty line
+            jsonAsYaml = sj.toString();
+            return jsonAsYaml;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private JsonArray transformToJson(List<EipModel> models) {
+        JsonArray arr = new JsonArray();
+        for (EipModel model : models) {
+            JsonObject jo = asJSonNode(model);
+            arr.add(jo);
+        }
+        return arr;
+    }
+
+    @SuppressWarnings("unchecked")
+    private JsonObject asJSonNode(EipModel model) {
+        JsonObject answer = new JsonObject();
+        JsonObject jo = new JsonObject();
+        answer.put(model.getName(), jo);
+
+        for (Map.Entry<String, Object> entry : model.getMetadata().entrySet()) {
+            String key = entry.getKey();
+            boolean skip = key.equals("customId");
+            if (skip) {
+                continue;
+            }
+            Object value = entry.getValue();
+            if (value != null) {
+                if (value instanceof Collection<?>) {
+                    Collection<?> col = (Collection<?>) value;
+                    List list = new ArrayList<>();
+                    for (Object v : col) {
+                        Object r = v;
+                        if (r instanceof EipModel) {
+                            EipNode en = asNode((EipModel) r);
+                            value = en.asJsonObject();
+                            JsonObject wrap = new JsonObject();
+                            wrap.put(en.getName(), value);
+                            r = wrap;
+                        }
+                        list.add(r);
+                    }
+                    if ("_output".equals(key)) {
+                        key = "steps";
+                    }
+                    // special with "from" where outputs needs to be embedded
+                    if (jo.containsKey("from")) {
+                        jo = jo.getMap("from");
+                    }
+                    jo.put(key, list);
+                } else {
+                    if (value instanceof EipModel) {
+                        EipNode r = asNode((EipModel) value);
+                        value = r.asJsonObject();
+                        jo.put(r.getName(), value);
+                    } else {
+                        jo.put(key, value);
+                    }
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void setMetadata(EipModel model, String name, Object value) {
+        // special for choice
+        boolean array = isArray(model, name);
+        if (array) {
+            List list = (List) model.getMetadata().get(name);
+            if (list == null) {
+                list = new ArrayList<>();
+                model.getMetadata().put(name, list);
+            }
+            list.add(value);
+        } else {
+            model.getMetadata().put(name, value);
+        }
+    }
+
+    private static String valueName(EipModel model) {
+        return model.getOptions().stream()
+                .filter(o -> "value".equals(o.getKind()))
+                .map(BaseOptionModel::getName)
+                .findFirst().orElse(null);
+    }
+
+    private static String expressionName(EipModel model, String name) {
+        return model.getOptions().stream()
+                .filter(o -> "expression".equals(o.getKind()))
+                .map(BaseOptionModel::getName)
+                .filter(oName -> name == null || oName.equalsIgnoreCase(name))
+                .findFirst().orElse(null);
+    }
+
+    private static boolean isArray(EipModel model, String name) {
+        return model.getOptions().stream()
+                .filter(o -> o.getName().equalsIgnoreCase(name))
+                .map(o -> "array".equals(o.getType()))
+                .findFirst().orElse(false);
+    }
+
+    private static boolean isLanguage(EipModel model) {
+        return model.getJavaType().startsWith("org.apache.camel.model.language");
+    }
+
+}
diff --git a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/out/BaseWriter.java b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/out/BaseWriter.java
new file mode 100644
index 00000000000..4b751c4bc59
--- /dev/null
+++ b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/out/BaseWriter.java
@@ -0,0 +1,74 @@
+/*
+ * 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.yaml.out;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import org.apache.camel.yaml.io.YamlWriter;
+
+public class BaseWriter {
+
+    protected final YamlWriter writer;
+
+    public BaseWriter(Writer writer, String namespace) throws IOException {
+        this.writer = new YamlWriter(writer);
+        // namespace is only for XML
+    }
+
+    public String toYaml() {
+        return writer.toYaml();
+    }
+
+    protected void startElement(String name) throws IOException {
+        writer.startElement(name);
+    }
+
+    protected void startExpressionElement(String name) throws IOException {
+        writer.startExpressionElement(name);
+    }
+
+    protected void endElement(String name) throws IOException {
+        writer.endElement(name);
+    }
+
+    protected void endExpressionElement(String name) throws IOException {
+        writer.endExpressionElement(name);
+    }
+
+    protected void text(String name, String text) throws IOException {
+        writer.writeText(name, text);
+    }
+
+    protected void value(String value) throws IOException {
+        writer.writeValue(value);
+    }
+
+    protected void attribute(String name, Object value) throws IOException {
+        if (value != null) {
+            writer.addAttribute(name, value);
+        }
+    }
+
+    protected void domElements(List<Element> elements) throws IOException {
+        // not in use for yaml-dsl
+    }
+
+}
diff --git a/core/camel-yaml-io/src/main/resources/META-INF/LICENSE.txt b/core/camel-yaml-io/src/main/resources/META-INF/LICENSE.txt
new file mode 100644
index 00000000000..6b0b1270ff0
--- /dev/null
+++ b/core/camel-yaml-io/src/main/resources/META-INF/LICENSE.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
diff --git a/core/camel-yaml-io/src/main/resources/META-INF/NOTICE.txt b/core/camel-yaml-io/src/main/resources/META-INF/NOTICE.txt
new file mode 100644
index 00000000000..8547fe70e40
--- /dev/null
+++ b/core/camel-yaml-io/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,15 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Apache Camel distribution.                    ==
+   =========================================================================
+
+   This product includes software developed by
+   The Apache Software Foundation (http://www.apache.org/).
+
+   This product includes software developed by the Indiana
+   University Extreme! Lab.  For further information please visit
+   http://www.extreme.indiana.edu/.
+
+   Please read the different LICENSE files present in the licenses directory of
+   this distribution.
diff --git a/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/ModelWriterTest.java b/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/ModelWriterTest.java
new file mode 100644
index 00000000000..c50e4031b63
--- /dev/null
+++ b/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/ModelWriterTest.java
@@ -0,0 +1,299 @@
+/*
+ * 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.yaml.out;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.AggregateDefinition;
+import org.apache.camel.model.ChoiceDefinition;
+import org.apache.camel.model.ExpressionSubElementDefinition;
+import org.apache.camel.model.FromDefinition;
+import org.apache.camel.model.LogDefinition;
+import org.apache.camel.model.MarshalDefinition;
+import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.SetBodyDefinition;
+import org.apache.camel.model.SplitDefinition;
+import org.apache.camel.model.ToDefinition;
+import org.apache.camel.model.dataformat.CsvDataFormat;
+import org.apache.camel.model.language.ConstantExpression;
+import org.apache.camel.model.language.HeaderExpression;
+import org.apache.camel.model.language.SimpleExpression;
+import org.apache.camel.util.IOHelper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ModelWriterTest {
+
+    @Test
+    public void testTimerLog() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute0");
+        route.setInput(new FromDefinition("timer:yaml?period=1234&includeMetadata=true"));
+        SetBodyDefinition sb = new SetBodyDefinition();
+        sb.setExpression(new ConstantExpression("Hello from yaml"));
+        route.addOutput(sb);
+        route.addOutput(new LogDefinition("${body}"));
+
+        writer.writeRouteDefinition(route);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route0.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testFromTo() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute1");
+        route.setInput(new FromDefinition("direct:start"));
+        ToDefinition to = new ToDefinition("log:input");
+        route.addOutput(to);
+        ToDefinition to2 = new ToDefinition("mock:result");
+        to2.setPattern("InOut");
+        route.addOutput(to2);
+
+        writer.writeRouteDefinition(route);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route1.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testFromSplitTo() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute2");
+        route.setInput(new FromDefinition("direct:start2"));
+        SplitDefinition sp = new SplitDefinition();
+        SimpleExpression e = new SimpleExpression("${body}");
+        e.setResultTypeName("int.class");
+        sp.setExpression(e);
+        sp.setStreaming("true");
+        route.addOutput(sp);
+        ToDefinition to = new ToDefinition("kafka:line");
+        sp.addOutput(to);
+        to = new ToDefinition("mock:result2");
+        route.addOutput(to);
+
+        writer.writeRouteDefinition(route);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route2.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testFromAggregateTo() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute3");
+        route.setInput(new FromDefinition("direct:start2"));
+        AggregateDefinition ag = new AggregateDefinition();
+        SimpleExpression e = new SimpleExpression("${body}");
+        e.setResultTypeName("int.class");
+        ag.setExpression(e);
+        ag.setCorrelationExpression(new ExpressionSubElementDefinition(new HeaderExpression("myHeader")));
+        ConstantExpression cons = new ConstantExpression("5");
+        cons.setResultTypeName("int.class");
+        ag.setCompletionSizeExpression(new ExpressionSubElementDefinition(cons));
+        ag.setCompletionTimeoutExpression(new ExpressionSubElementDefinition(new ConstantExpression("4000")));
+        route.addOutput(ag);
+        ToDefinition to = new ToDefinition("kafka:line");
+        ag.addOutput(to);
+        to = new ToDefinition("mock:result2");
+        route.addOutput(to);
+
+        writer.writeRouteDefinition(route);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route3.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testFromSetBodyTo() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute4");
+        route.setInput(new FromDefinition("direct:start"));
+        SetBodyDefinition body = new SetBodyDefinition();
+        body.setExpression(new ConstantExpression("{\n key: '123'\n}"));
+        route.addOutput(body);
+        ToDefinition to = new ToDefinition("mock:result");
+        route.addOutput(to);
+
+        writer.writeRouteDefinition(route);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route4.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testFromLogSetBodyTo() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute5");
+        route.setInput(new FromDefinition("direct:start"));
+        LogDefinition log = new LogDefinition();
+        log.setLoggingLevel("WARN");
+        log.setLogName("myLogger");
+        route.addOutput(log);
+        SetBodyDefinition body = new SetBodyDefinition();
+        body.setExpression(new SimpleExpression("${body}"));
+        route.addOutput(body);
+        ToDefinition to = new ToDefinition("mock:result");
+        route.addOutput(to);
+
+        writer.writeRouteDefinition(route);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route5.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testFromChoice() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute6");
+        route.setInput(new FromDefinition("direct:start6"));
+        ChoiceDefinition choice = new ChoiceDefinition();
+        route.addOutput(choice);
+        choice.when().simple("${header.age} < 21").to("mock:young");
+        choice.when().simple("${header.age} > 21 && ${header.age} < 70").to("mock:work");
+        choice.otherwise().to("mock:senior");
+        ToDefinition to = new ToDefinition("mock:result");
+        route.addOutput(to);
+
+        writer.writeRouteDefinition(route);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route6.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testFromTryCatch() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        CamelContext context = new DefaultCamelContext();
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start7").routeId("myRoute7")
+                    .doTry()
+                        .to("mock:try1")
+                        .to("mock:try2")
+                    .doCatch(IOException.class)
+                        .to("mock:io1")
+                        .to("mock:io2")
+                    .doFinally()
+                        .to("mock:finally1")
+                        .to("mock:finally2")
+                    .end()
+                    .to("mock:result");
+            }
+        });
+
+        ModelCamelContext mcc = (ModelCamelContext) context;
+        writer.writeRouteDefinition(mcc.getRouteDefinition("myRoute7"));
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route7.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testTwoRoutes() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RoutesDefinition routes = new RoutesDefinition();
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute0");
+        route.setInput(new FromDefinition("timer:yaml?period=1234"));
+        SetBodyDefinition sb = new SetBodyDefinition();
+        sb.setExpression(new ConstantExpression("Hello from yaml"));
+        route.addOutput(sb);
+        route.addOutput(new LogDefinition("${body}"));
+        routes.getRoutes().add(route);
+
+        route = new RouteDefinition();
+        route.setId("myRoute1");
+        route.setInput(new FromDefinition("direct:start"));
+        ToDefinition to = new ToDefinition("log:input");
+        route.addOutput(to);
+        ToDefinition to2 = new ToDefinition("mock:result");
+        to2.setPattern("InOut");
+        route.addOutput(to2);
+        routes.getRoutes().add(route);
+
+        writer.writeRoutesDefinition(routes);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route8.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+    @Test
+    public void testMarshal() throws Exception {
+        StringWriter sw = new StringWriter();
+        ModelWriter writer = new ModelWriter(sw);
+
+        RouteDefinition route = new RouteDefinition();
+        route.setId("myRoute9");
+        route.setInput(new FromDefinition("timer:foo"));
+        MarshalDefinition mar = new MarshalDefinition();
+        mar.setDataFormatType(new CsvDataFormat());
+        route.addOutput(mar);
+        route.addOutput(new LogDefinition("${body}"));
+
+        writer.writeRouteDefinition(route);
+
+        String out = sw.toString();
+        String expected = IOHelper.loadText(new FileInputStream("src/test/resources/route9.yaml"));
+        Assertions.assertEquals(expected, out);
+    }
+
+}
diff --git a/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/XmlToYamlTest.java b/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/XmlToYamlTest.java
new file mode 100644
index 00000000000..484fa4e16fb
--- /dev/null
+++ b/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/XmlToYamlTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.yaml.out;
+
+import java.io.FileInputStream;
+import java.io.IOError;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.stream.Stream;
+
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.xml.in.ModelParser;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class XmlToYamlTest {
+
+    public static final String NAMESPACE = "http://camel.apache.org/schema/spring";
+
+    private static final Logger LOG = LoggerFactory.getLogger(XmlToYamlTest.class);
+
+    @ParameterizedTest
+    @MethodSource("routes")
+    @DisplayName("Test xml to yaml for <routes>")
+    void testRoutes(String xml) throws Exception {
+        try (InputStream is = new FileInputStream("../camel-xml-io/src/test/resources/" + xml)) {
+            RoutesDefinition expected = new ModelParser(is, NAMESPACE).parseRoutesDefinition().get();
+            StringWriter sw = new StringWriter();
+            new ModelWriter(sw).writeRoutesDefinition(expected);
+            LOG.info("xml={}\n{}\n", xml, sw);
+        }
+    }
+
+    private static Stream<Arguments> routes() {
+        return definitions("routes");
+    }
+
+    private static Stream<Arguments> definitions(String xml) {
+        try {
+            return Files.list(Paths.get("../camel-xml-io/src/test/resources"))
+                    .filter(p -> {
+                        try {
+                            return Files.isRegularFile(p)
+                                    && p.getFileName().toString().endsWith(".xml")
+                                    && Files.readString(p).contains("<" + xml);
+                        } catch (IOException e) {
+                            throw new IOError(e);
+                        }
+                    })
+                    .map(p -> p.getFileName().toString())
+                    .flatMap(p -> Stream.of(Arguments.of(p, NAMESPACE)));
+        } catch (IOException e) {
+            throw new IOError(e);
+        }
+    }
+
+}
diff --git a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties b/core/camel-yaml-io/src/test/resources/log4j2.properties
similarity index 53%
copy from dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
copy to core/camel-yaml-io/src/test/resources/log4j2.properties
index 976cc8357c1..6b3ad16aa3f 100644
--- a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
+++ b/core/camel-yaml-io/src/test/resources/log4j2.properties
@@ -14,15 +14,19 @@
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
+appender.console.type = Console
+appender.console.name = console
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
 
-com.amazon.redshift.jdbc.Driver = com.amazon.redshift:redshift-jdbc42:2.1.0.14
-com.microsoft.sqlserver.jdbc.SQLServerDriver = com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre11
-com.mysql.cj.jdbc.Driver = mysql:mysql-connector-java:8.0.33
-net.sf.saxon.xpath.XPathFactoryImpl = camel:saxon
-org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory = org.apache.activemq:artemis-jms-client-all:2.28.0
-org.apache.commons.dbcp2.BasicDataSource = org.apache.commons:commons-dbcp2:2.9.0
-org.apache.qpid.jms.JmsConnectionFactory = org.apache.qpid:qpid-jms-client:2.3.0
-org.postgresql.Driver = org.postgresql:postgresql:42.6.0
-org.apache.camel.component.cxf.jaxws.CxfEndpoint = camel:cxf-soap
-org.apache.camel.component.cxf.jaxrs.CxfRsEndpoint = camel:cxf-rest
-META-INF/services/org/apache/camel/restapi/openapi = camel:openapi-java
\ No newline at end of file
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-yaml-io-test.log
+appender.file.append = true
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+rootLogger.level = INFO
+
+rootLogger.appenderRef.file.ref = file
+#rootLogger.appenderRef.console.ref = console
diff --git a/core/camel-yaml-io/src/test/resources/route0.yaml b/core/camel-yaml-io/src/test/resources/route0.yaml
new file mode 100644
index 00000000000..e0b04c64f2b
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route0.yaml
@@ -0,0 +1,13 @@
+- route:
+    id: myRoute0
+    from:
+      uri: timer:yaml
+      parameters:
+        period: 1234
+        includeMetadata: true
+      steps:
+        - setBody:
+            constant:
+              expression: Hello from yaml
+        - log:
+            message: "${body}"
\ No newline at end of file
diff --git a/core/camel-yaml-io/src/test/resources/route1.yaml b/core/camel-yaml-io/src/test/resources/route1.yaml
new file mode 100644
index 00000000000..3094d245c41
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route1.yaml
@@ -0,0 +1,10 @@
+- route:
+    id: myRoute1
+    from:
+      uri: direct:start
+      steps:
+        - to:
+            uri: log:input
+        - to:
+            uri: mock:result
+            pattern: InOut
\ No newline at end of file
diff --git a/core/camel-yaml-io/src/test/resources/route2.yaml b/core/camel-yaml-io/src/test/resources/route2.yaml
new file mode 100644
index 00000000000..4aa45e9a760
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route2.yaml
@@ -0,0 +1,15 @@
+- route:
+    id: myRoute2
+    from:
+      uri: direct:start2
+      steps:
+        - split:
+            streaming: "true"
+            simple:
+              resultType: int.class
+              expression: "${body}"
+            steps:
+              - to:
+                  uri: kafka:line
+        - to:
+            uri: mock:result2
diff --git a/core/camel-yaml-io/src/test/resources/route3.yaml b/core/camel-yaml-io/src/test/resources/route3.yaml
new file mode 100644
index 00000000000..270f99b3360
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route3.yaml
@@ -0,0 +1,21 @@
+- route:
+    id: myRoute3
+    from:
+      uri: direct:start2
+      steps:
+        - aggregate:
+            correlationExpression:
+              header:
+                expression: myHeader
+            completionSizeExpression:
+              constant:
+                resultType: int.class
+                expression: 5
+            completionTimeoutExpression:
+              constant:
+                expression: 4000
+            steps:
+              - to:
+                  uri: kafka:line
+        - to:
+            uri: mock:result2
diff --git a/core/camel-yaml-io/src/test/resources/route4.yaml b/core/camel-yaml-io/src/test/resources/route4.yaml
new file mode 100644
index 00000000000..340bf477e6c
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route4.yaml
@@ -0,0 +1,13 @@
+- route:
+    id: myRoute4
+    from:
+      uri: direct:start
+      steps:
+        - setBody:
+            constant:
+              expression: |-
+                {
+                 key: '123'
+                }
+        - to:
+            uri: mock:result
diff --git a/core/camel-yaml-io/src/test/resources/route5.yaml b/core/camel-yaml-io/src/test/resources/route5.yaml
new file mode 100644
index 00000000000..442ff2907e4
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route5.yaml
@@ -0,0 +1,13 @@
+- route:
+    id: myRoute5
+    from:
+      uri: direct:start
+      steps:
+        - log:
+            logName: myLogger
+            loggingLevel: WARN
+        - setBody:
+            simple:
+              expression: "${body}"
+        - to:
+            uri: mock:result
diff --git a/core/camel-yaml-io/src/test/resources/route6.yaml b/core/camel-yaml-io/src/test/resources/route6.yaml
new file mode 100644
index 00000000000..4e7d61fe0e5
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route6.yaml
@@ -0,0 +1,25 @@
+- route:
+    id: myRoute6
+    from:
+      uri: direct:start6
+      steps:
+        - choice:
+            steps:
+              - when:
+                  simple:
+                    expression: "${header.age} < 21"
+                  steps:
+                    - to:
+                        uri: mock:young
+              - when:
+                  simple:
+                    expression: "${header.age} > 21 && ${header.age} < 70"
+                  steps:
+                    - to:
+                        uri: mock:work
+              - otherwise:
+                  steps:
+                    - to:
+                        uri: mock:senior
+        - to:
+            uri: mock:result
diff --git a/core/camel-yaml-io/src/test/resources/route7.yaml b/core/camel-yaml-io/src/test/resources/route7.yaml
new file mode 100644
index 00000000000..51b87a2e8f6
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route7.yaml
@@ -0,0 +1,27 @@
+- route:
+    id: myRoute7
+    from:
+      uri: direct:start7
+      steps:
+        - doTry:
+            steps:
+              - to:
+                  uri: mock:try1
+              - to:
+                  uri: mock:try2
+              - doCatch:
+                  exception:
+                    - java.io.IOException
+                  steps:
+                    - to:
+                        uri: mock:io1
+                    - to:
+                        uri: mock:io2
+              - doFinally:
+                  steps:
+                    - to:
+                        uri: mock:finally1
+                    - to:
+                        uri: mock:finally2
+        - to:
+            uri: mock:result
diff --git a/core/camel-yaml-io/src/test/resources/route8.yaml b/core/camel-yaml-io/src/test/resources/route8.yaml
new file mode 100644
index 00000000000..a78cf12fb91
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route8.yaml
@@ -0,0 +1,22 @@
+- route:
+    id: myRoute0
+    from:
+      uri: timer:yaml
+      parameters:
+        period: 1234
+      steps:
+        - setBody:
+            constant:
+              expression: Hello from yaml
+        - log:
+            message: "${body}"
+- route:
+    id: myRoute1
+    from:
+      uri: direct:start
+      steps:
+        - to:
+            uri: log:input
+        - to:
+            uri: mock:result
+            pattern: InOut
diff --git a/core/camel-yaml-io/src/test/resources/route9.yaml b/core/camel-yaml-io/src/test/resources/route9.yaml
new file mode 100644
index 00000000000..1f02c067d7a
--- /dev/null
+++ b/core/camel-yaml-io/src/test/resources/route9.yaml
@@ -0,0 +1,9 @@
+- route:
+    id: myRoute9
+    from:
+      uri: timer:foo
+      steps:
+        - marshal:
+            csv: {}
+        - log:
+            message: "${body}"
diff --git a/core/pom.xml b/core/pom.xml
index 1e42308cf30..11ac39b293e 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -52,6 +52,7 @@
         <module>camel-core-reifier</module>
         <module>camel-xml-io</module>
         <module>camel-xml-jaxb</module>
+        <module>camel-yaml-io</module>
         <module>camel-core</module>
         <module>camel-core-xml</module>
         <module>camel-cloud</module>
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4-migration-guide.adoc b/docs/user-manual/modules/ROOT/pages/camel-4-migration-guide.adoc
index 6eca6c77299..4d709ce4a4d 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4-migration-guide.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4-migration-guide.adoc
@@ -87,6 +87,7 @@ We have removed deprecated APIs such as the following:
 - Added `position` method to `org.apache.camel.StreamCache`.
 - The method `configure` from the interface `org.apache.camel.main.Listener` was removed
 - The `org.apache.camel.support.EventNotifierSupport` abstract class now implements `CamelContextAware`.
+- The type for `dumpRoutes` on `CamelContext` has changed from `boolean` to `String` to allow specifying either xml or yaml.
 
 == EIP Changes
 
diff --git a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
index 9f06e120dea..2459a6cf476 100644
--- a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
+++ b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
@@ -303,6 +303,17 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C
                     LOG.trace("Updating output file: {}", outputFile);
                     IOHelper.writeText(json.toJson(), outputFile);
                 }
+            } else if ("route-dump".equals(action)) {
+                DevConsole dc = camelContext.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class)
+                        .resolveById("route-dump");
+                if (dc != null) {
+                    String filter = root.getString("filter");
+                    String format = root.getString("format");
+                    JsonObject json
+                            = (JsonObject) dc.call(DevConsole.MediaType.JSON, Map.of("filter", filter, "format", format));
+                    LOG.trace("Updating output file: {}", outputFile);
+                    IOHelper.writeText(json.toJson(), outputFile);
+                }
             } else if ("route-controller".equals(action)) {
                 DevConsole dc = camelContext.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class)
                         .resolveById("route-controller");
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
index f536129e90d..220f3907b9d 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
@@ -25,6 +25,7 @@ import org.apache.camel.dsl.jbang.core.commands.action.CamelGCAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelLogAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelReloadAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelResetStatsAction;
+import org.apache.camel.dsl.jbang.core.commands.action.CamelRouteDumpAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelRouteStartAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelRouteStopAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelSendAction;
@@ -104,6 +105,7 @@ public class CamelJBangMain implements Callable<Integer> {
                         .addSubcommand("metric", new CommandLine(new ListMetric(main)))
                         .addSubcommand("service", new CommandLine(new ListService(main)))
                         .addSubcommand("source", new CommandLine(new CamelSourceAction(main)))
+                        .addSubcommand("route-dump", new CommandLine(new CamelRouteDumpAction(main)))
                         .addSubcommand("vault", new CommandLine(new ListVault(main))))
                 .addSubcommand("top", new CommandLine(new CamelTop(main))
                         .addSubcommand("context", new CommandLine(new CamelContextTop(main)))
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
new file mode 100644
index 00000000000..8365f894323
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
@@ -0,0 +1,270 @@
+/*
+ * 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.dsl.jbang.core.commands.action;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.support.PatternHelper;
+import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.StopWatch;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+
+import static org.apache.camel.support.LoggerHelper.stripSourceLocationLineNumber;
+
+@Command(name = "route-dump", description = "Dump Camel route in XML or YAML format")
+public class CamelRouteDumpAction extends ActionBaseCommand {
+
+    public static class NameIdCompletionCandidates implements Iterable<String> {
+
+        public NameIdCompletionCandidates() {
+        }
+
+        @Override
+        public Iterator<String> iterator() {
+            return List.of("name", "id").iterator();
+        }
+
+    }
+
+    @CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "1")
+    String name;
+
+    @CommandLine.Option(names = { "--format" },
+                        description = "Output format (xml or yaml)", defaultValue = "xml")
+    String format;
+
+    @CommandLine.Option(names = { "--raw" },
+                        description = "To output raw without metadata")
+    boolean raw;
+
+    @CommandLine.Option(names = { "--filter" },
+                        description = "Filter route by filename (multiple names can be separated by comma)")
+    String filter;
+
+    @CommandLine.Option(names = { "--sort" }, completionCandidates = NameIdCompletionCandidates.class,
+                        description = "Sort route by name or id", defaultValue = "name")
+    String sort;
+
+    private volatile long pid;
+
+    public CamelRouteDumpAction(CamelJBangMain main) {
+        super(main);
+    }
+
+    @Override
+    public Integer doCall() throws Exception {
+        List<Row> rows = new ArrayList<>();
+
+        List<Long> pids = findPids(name);
+        if (pids.isEmpty()) {
+            return 0;
+        } else if (pids.size() > 1) {
+            System.out.println("Name or pid " + name + " matches " + pids.size()
+                               + " running Camel integrations. Specify a name or PID that matches exactly one.");
+            return 0;
+        }
+
+        this.pid = pids.get(0);
+
+        // ensure output file is deleted before executing action
+        File outputFile = getOutputFile(Long.toString(pid));
+        FileUtil.deleteFile(outputFile);
+
+        JsonObject root = new JsonObject();
+        root.put("action", "route-dump");
+        root.put("filter", "*");
+        root.put("format", format);
+        File file = getActionFile(Long.toString(pid));
+        try {
+            IOHelper.writeText(root.toJson(), file);
+        } catch (Exception e) {
+            // ignore
+        }
+
+        JsonObject jo = waitForOutputFile(outputFile);
+        if (jo != null) {
+            JsonArray arr = (JsonArray) jo.get("routes");
+            for (int i = 0; i < arr.size(); i++) {
+                JsonObject o = (JsonObject) arr.get(i);
+                Row row = new Row();
+                row.location = extractSourceName(o.getString("source"));
+                row.routeId = o.getString("routeId");
+                // if there are 2+ routes in the same source then we would have duplicates
+                if (!rows.contains(row)) {
+                    List<JsonObject> lines = o.getCollection("code");
+                    if (lines != null) {
+                        for (JsonObject line : lines) {
+                            Code code = new Code();
+                            code.line = line.getInteger("line");
+                            code.code = line.getString("code");
+                            row.code.add(code);
+                        }
+                    }
+                    boolean add = true;
+                    if (filter != null) {
+                        String f = filter;
+                        boolean negate = filter.startsWith("-");
+                        if (negate) {
+                            f = f.substring(1);
+                        }
+                        // make filtering easier
+                        if (!f.endsWith("*")) {
+                            f += "*";
+                        }
+                        boolean match = PatternHelper.matchPattern(row.location, f);
+                        if (negate) {
+                            match = !match;
+                        }
+                        if (!match) {
+                            add = false;
+                        }
+                    }
+                    if (add) {
+                        rows.add(row);
+                    }
+                }
+            }
+        } else {
+            System.out.println("Response from running Camel with PID " + pid + " not received within 5 seconds");
+            return 1;
+        }
+
+        // sort rows
+        rows.sort(this::sortRow);
+
+        if (!rows.isEmpty()) {
+            printSource(rows);
+        }
+
+        // delete output file after use
+        FileUtil.deleteFile(outputFile);
+
+        return 0;
+    }
+
+    protected int sortRow(Row o1, Row o2) {
+        String s = sort;
+        int negate = 1;
+        if (s.startsWith("-")) {
+            s = s.substring(1);
+            negate = -1;
+        }
+        switch (s) {
+            case "name":
+                return o1.location.compareToIgnoreCase(o2.location) * negate;
+            case "id":
+                return o1.routeId.compareToIgnoreCase(o2.routeId) * negate;
+            default:
+                return 0;
+        }
+    }
+
+    protected void printSource(List<Row> rows) {
+        for (Row row : rows) {
+            System.out.println();
+            if (!raw) {
+                System.out.printf("Source: %s%n", row.location);
+                System.out.println("--------------------------------------------------------------------------------");
+            }
+            for (int i = 0; i < row.code.size(); i++) {
+                Code code = row.code.get(i);
+                String c = Jsoner.unescape(code.code);
+                if (raw) {
+                    System.out.printf("%s%n", c);
+                } else {
+                    System.out.printf("%4d: %s%n", code.line, c);
+                }
+            }
+            System.out.println();
+        }
+    }
+
+    protected JsonObject waitForOutputFile(File outputFile) {
+        StopWatch watch = new StopWatch();
+        while (watch.taken() < 5000) {
+            try {
+                // give time for response to be ready
+                Thread.sleep(100);
+
+                if (outputFile.exists()) {
+                    FileInputStream fis = new FileInputStream(outputFile);
+                    String text = IOHelper.loadText(fis);
+                    IOHelper.close(fis);
+                    return (JsonObject) Jsoner.deserialize(text);
+                }
+
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+        return null;
+    }
+
+    public static String extractSourceName(String loc) {
+        loc = stripSourceLocationLineNumber(loc);
+        if (loc != null) {
+            if (loc.contains(":")) {
+                // strip prefix
+                loc = loc.substring(loc.indexOf(':') + 1);
+                // file based such as xml and yaml
+                loc = FileUtil.stripPath(loc);
+            }
+        }
+        return loc;
+    }
+
+    private static class Row {
+        String location;
+        String routeId;
+        List<Code> code = new ArrayList<>();
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            Row row = (Row) o;
+
+            return location.equals(row.location);
+        }
+
+        @Override
+        public int hashCode() {
+            return location.hashCode();
+        }
+    }
+
+    private static class Code {
+        int line;
+        String code;
+    }
+
+}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index 955d9fe38a6..2ea86e2cfcd 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -62,10 +62,13 @@ import org.apache.camel.main.download.TypeConverterLoaderDownloadListener;
 import org.apache.camel.main.http.VertxHttpServer;
 import org.apache.camel.main.injection.AnnotationDependencyInjection;
 import org.apache.camel.main.util.ExtraFilesClassLoader;
+import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.CliConnector;
 import org.apache.camel.spi.CliConnectorFactory;
 import org.apache.camel.spi.ComponentResolver;
 import org.apache.camel.spi.DataFormatResolver;
+import org.apache.camel.spi.FactoryFinder;
+import org.apache.camel.spi.FactoryFinderResolver;
 import org.apache.camel.spi.LanguageResolver;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.spi.ResourceLoader;
@@ -462,7 +465,17 @@ public class KameletMain extends MainCommandLineSupport {
                         .bind(DependencyDownloaderPropertyBindingListener.class.getSimpleName(), listener);
                 answer.getCamelContextExtension().getRegistry().bind(DependencyDownloaderStrategy.class.getSimpleName(),
                         new DependencyDownloaderStrategy(answer));
-                answer.setClassResolver(new DependencyDownloaderClassResolver(answer, known));
+
+                // download class-resolver
+                ClassResolver classResolver = new DependencyDownloaderClassResolver(answer, known);
+                answer.setClassResolver(classResolver);
+                // re-create factory finder with download class-resolver
+                FactoryFinderResolver ffr = PluginHelper.getFactoryFinderResolver(answer);
+                FactoryFinder ff = ffr.resolveBootstrapFactoryFinder(classResolver);
+                answer.getCamelContextExtension().setBootstrapFactoryFinder(ff);
+                ff = ffr.resolveDefaultFactoryFinder(classResolver);
+                answer.getCamelContextExtension().setDefaultFactoryFinder(ff);
+              
                 answer.getCamelContextExtension().addContextPlugin(ComponentResolver.class,
                         new DependencyDownloaderComponentResolver(answer, stub));
                 answer.getCamelContextExtension().addContextPlugin(UriFactoryResolver.class,
diff --git a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties b/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
index 976cc8357c1..bdab8481029 100644
--- a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
+++ b/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
@@ -25,4 +25,6 @@ org.apache.qpid.jms.JmsConnectionFactory = org.apache.qpid:qpid-jms-client:2.3.0
 org.postgresql.Driver = org.postgresql:postgresql:42.6.0
 org.apache.camel.component.cxf.jaxws.CxfEndpoint = camel:cxf-soap
 org.apache.camel.component.cxf.jaxrs.CxfRsEndpoint = camel:cxf-rest
-META-INF/services/org/apache/camel/restapi/openapi = camel:openapi-java
\ No newline at end of file
+META-INF/services/org/apache/camel/restapi/openapi = camel:openapi-java
+META-INF/services/org/apache/camel/modelxml-dumper = camel:xml-io
+META-INF/services/org/apache/camel/modelyaml-dumper = camel:yaml-io
\ No newline at end of file
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index f12137d665b..ca6273b7217 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -13266,6 +13266,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     @YamlProperty(name = "id", type = "string"),
                     @YamlProperty(name = "inherit-error-handler", type = "boolean"),
                     @YamlProperty(name = "intermittent", type = "boolean"),
+                    @YamlProperty(name = "logging-level", type = "enum:TRACE,DEBUG,INFO,WARN,ERROR,OFF"),
                     @YamlProperty(name = "resume-strategy", type = "string", required = true)
             }
     )
@@ -13298,6 +13299,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setIntermittent(val);
                     break;
                 }
+                case "logging-level": {
+                    String val = asText(node);
+                    target.setLoggingLevel(val);
+                    break;
+                }
                 case "resume-strategy": {
                     String val = asText(node);
                     target.setResumeStrategy(val);
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml b/dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml
index 023aed08d66..837ee0dad6b 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml
@@ -42,6 +42,7 @@
         <sourcecheckExcludesComma>
             ${sourcecheckExcludes},
         </sourcecheckExcludesComma>
+        <camel-generate-yaml-writer>true</camel-generate-yaml-writer>
     </properties>
 
     <dependencies>
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
index 497be080d40..20366b45682 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
@@ -2353,6 +2353,10 @@
           "intermittent" : {
             "type" : "boolean"
           },
+          "logging-level" : {
+            "type" : "string",
+            "enum" : [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ]
+          },
           "resume-strategy" : {
             "type" : "string"
           }
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index dcfc72d2984..829da78065b 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -2263,6 +2263,10 @@
           "intermittent" : {
             "type" : "boolean"
           },
+          "loggingLevel" : {
+            "type" : "string",
+            "enum" : [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ]
+          },
           "resumeStrategy" : {
             "type" : "string"
           }
diff --git a/parent/pom.xml b/parent/pom.xml
index 4818856138e..1430fc2c09f 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -660,6 +660,11 @@
                 <artifactId>camel-xml-jaxp</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-yaml-io</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- NOTE: auto-generated list of components when building camel catalog -->
             <!-- camel components: START -->
diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseModel.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseModel.java
index 475bf138a7f..b50c195d035 100644
--- a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseModel.java
+++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseModel.java
@@ -141,32 +141,29 @@ public abstract class BaseModel<O extends BaseOptionModel> {
     }
 
     /**
-     * @return {@code true} if the part represented by this model supports compilation to native code; {@code false}
-     *         otherwise
+     * True if the part represented by this model supports compilation to native code.
      */
     public boolean isNativeSupported() {
         return nativeSupported;
     }
 
-    /**
-     * @param nativeSupported see {@link #isNativeSupported()}
-     */
     public void setNativeSupported(boolean nativeSupported) {
         this.nativeSupported = nativeSupported;
     }
 
     /**
-     * @return a free form map of key value pair representing this {@link BaseModel}'s metadata
+     * A free form map of key value pair representing this {@link BaseModel}'s metadata
      */
     public Map<String, Object> getMetadata() {
         return metadata;
     }
 
-    /**
-     * @param metadata
-     */
     public void setMetadata(Map<String, Object> metadata) {
         this.metadata = metadata;
     }
 
+    @Override
+    public String toString() {
+        return name;
+    }
 }
diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseOptionModel.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseOptionModel.java
index 0564751a78f..7169fa9a100 100644
--- a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseOptionModel.java
+++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseOptionModel.java
@@ -313,4 +313,8 @@ public abstract class BaseOptionModel {
         return Character.toLowerCase(text.charAt(0)) + text.substring(1);
     }
 
+    @Override
+    public String toString() {
+        return name;
+    }
 }
diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/ExampleModel.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/ExampleModel.java
index 051e5f5222f..6f9e37e5e2f 100644
--- a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/ExampleModel.java
+++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/ExampleModel.java
@@ -86,7 +86,6 @@ public class ExampleModel {
         if (middleFolder == null) {
             return fileName + "/" + readmeFileName;
         }
-
         return middleFolder + "/" + fileName + "/" + readmeFileName;
     }
 }
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlWriterGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelWriterGeneratorMojo.java
similarity index 85%
rename from tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlWriterGeneratorMojo.java
rename to tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelWriterGeneratorMojo.java
index 4fa3a337388..c089518917e 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlWriterGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelWriterGeneratorMojo.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.maven.packaging;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Writer;
@@ -30,7 +29,6 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.net.URL;
-import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -69,54 +67,32 @@ import org.apache.camel.tooling.util.srcgen.GenericType;
 import org.apache.camel.tooling.util.srcgen.JavaClass;
 import org.apache.maven.artifact.DependencyResolutionRequiredException;
 import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.MavenProjectHelper;
 import org.jboss.jandex.DotName;
 import org.jboss.jandex.Index;
 import org.jboss.jandex.IndexReader;
-import org.sonatype.plexus.build.incremental.BuildContext;
 
-/**
- * Generate Model lightweight XML Writer source code.
- */
-@Mojo(name = "generate-xml-writer", threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
-      defaultPhase = LifecyclePhase.PROCESS_CLASSES)
-public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
+public abstract class ModelWriterGeneratorMojo extends AbstractGeneratorMojo {
 
-    public static final String XML_SERIALIZER_PACKAGE = "org.apache.camel.xml.io";
-    public static final String WRITER_PACKAGE = "org.apache.camel.xml.out";
     public static final String MODEL_PACKAGE = "org.apache.camel.model";
 
-    @Parameter(defaultValue = "${project.basedir}/src/generated/java")
-    protected File sourcesOutputDir;
-
-    @Parameter(defaultValue = "${camel-generate-xml-writer}")
-    protected boolean generateXmlWriter;
+    private Map<Class<?>, List<Property>> properties = new ConcurrentHashMap<>();
+    private Map<Class<?>, List<Member>> members = new ConcurrentHashMap<>();
 
-    @Override
-    public void execute(MavenProject project, MavenProjectHelper projectHelper, BuildContext buildContext)
-            throws MojoFailureException, MojoExecutionException {
-        sourcesOutputDir = new File(project.getBasedir(), "src/generated/java");
-        generateXmlWriter = Boolean.parseBoolean(project.getProperties().getProperty("camel-generate-xml-writer", "false"));
-        super.execute(project, projectHelper, buildContext);
+    private static Type type(Member member) {
+        return member instanceof Method
+                ? member.getName().startsWith("set")
+                        ? ((Method) member).getGenericParameterTypes()[0]
+                        : ((Method) member).getGenericReturnType()
+                : ((Field) member).getGenericType();
     }
 
-    @Override
-    public void execute() throws MojoExecutionException {
-        if (!generateXmlWriter) {
-            return;
-        }
-        Path javaDir = sourcesOutputDir.toPath();
-        String parser = generateWriter();
-        updateResource(javaDir, (WRITER_PACKAGE + ".ModelWriter").replace('.', '/') + ".java", parser);
+    String getModelPackage() {
+        return MODEL_PACKAGE;
     }
 
-    public String generateWriter() throws MojoExecutionException {
+    abstract String getWriterPackage();
+
+    protected String generateWriter() throws MojoExecutionException {
         ClassLoader classLoader;
         try {
             classLoader = DynamicClassLoader.createDynamicClassLoader(project.getCompileClasspathElements());
@@ -124,7 +100,8 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
             throw new MojoExecutionException("DependencyResolutionRequiredException: " + e.getMessage(), e);
         }
 
-        Class<?> routesDefinitionClass = loadClass(classLoader, MODEL_PACKAGE + ".RoutesDefinition");
+        Class<?> routesDefinitionClass
+                = loadClass(classLoader, XmlModelWriterGeneratorMojo.MODEL_PACKAGE + ".RoutesDefinition");
         String resName = routesDefinitionClass.getName().replace('.', '/') + ".class";
         String url = classLoader.getResource(resName).toExternalForm().replace(resName, JandexStore.DEFAULT_NAME);
         Index index;
@@ -206,14 +183,15 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
     private JavaClass generateWriter(List<Class<?>> model, ClassLoader classLoader) {
         JavaClass writer = new JavaClass(classLoader);
         writer.setMaxImportPerPackage(4);
-        writer.setPackage(WRITER_PACKAGE);
+        writer.setPackage(getWriterPackage());
         writer.setName("ModelWriter");
         writer.extendSuperType("BaseWriter");
-        writer.addImport(MODEL_PACKAGE + ".OptionalIdentifiedDefinition");
+        writer.addImport(XmlModelWriterGeneratorMojo.MODEL_PACKAGE + ".OptionalIdentifiedDefinition");
         writer.addImport(IOException.class);
         writer.addImport(Array.class);
         writer.addImport(List.class);
         writer.addImport(ArrayList.class);
+        writer.addImport("org.apache.camel.Expression");
         writer.addAnnotation(SuppressWarnings.class).setLiteralValue("\"all\"");
 
         writer.addMethod()
@@ -305,7 +283,14 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
             getClassAndSuper(clazz.getSuperclass())
                     .filter(c -> getProperties(c).anyMatch(Property::isElement))
                     .findFirst()
-                    .ifPresent(cl -> elements.add("doWrite" + cl.getSimpleName() + "Elements(def);"));
+                    .ifPresent(cl -> {
+                        // special for namespace
+                        if ("NamespaceAwareExpression".equals(cl.getSimpleName())) {
+                            attributes.add("doWriteNamespaces(def);");
+                        } else {
+                            elements.add("doWrite" + cl.getSimpleName() + "Elements(def);");
+                        }
+                    });
             // Loop through elements
             List<Property> elementMembers = members.stream().filter(Property::isElement).toList();
             elementMembers.forEach(member -> {
@@ -363,7 +348,7 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                         String w = member.getAnnotation(XmlElementWrapper.class) != null
                                 ? member.getAnnotation(XmlElementWrapper.class).name() : null;
                         elements.add("doWriteList(" + (w != null ? "\"" + w + "\"" : "null") + ", " +
-                                "\"" + n + "\", def." + gn + "(), this::doWrite" + t + ");");
+                                     "\"" + n + "\", def." + gn + "(), this::doWrite" + t + ");");
                     } else {
                         XmlJavaTypeAdapter adapter = member.getAnnotation(XmlJavaTypeAdapter.class);
                         if (adapter != null) {
@@ -398,7 +383,7 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                     // elements.add("// " + member);
                     if (list) {
                         elements.add("doWriteList(\"" + pn + "\", " +
-                                "\"" + n + "\", def." + gn + "(), this::doWrite" + t + ");");
+                                     "\"" + n + "\", def." + gn + "(), this::doWrite" + t + ");");
                     } else {
                         elements.add("doWriteElement(\"" + pn + "\", def." + gn + "(), this::doWrite" + t + ");");
                     }
@@ -409,8 +394,8 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
             List<String> value =
                     getClassAndSuper(clazz).flatMap(this::getProperties)
                             .filter(Property::isValue).findFirst()
-                    .map(member -> "doWriteValue(def." + member.getGetter() + "());")
-                    .stream().toList();
+                            .map(member -> "doWriteValue(def." + member.getGetter() + "());")
+                            .stream().toList();
 
             String qgname = qname;
             if (clazz.getTypeParameters().length > 0) {
@@ -418,9 +403,13 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                         .collect(Collectors.joining(", ")) + ">";
             }
             if (!attributeMembers.isEmpty() || !elementMembers.isEmpty() || isRootElement(clazz)
-                    || isReferenced(clazz, model)) {
+                || isReferenced(clazz, model)) {
                 List<String> statements = new ArrayList<>();
-                statements.add("startElement(name);");
+                if ("ExpressionSubElementDefinition".equals(name)) {
+                    statements.add("startExpressionElement(name);");
+                } else {
+                    statements.add("startElement(name);");
+                }
                 // Attributes
                 if (hasDerived && !attributes.isEmpty()) {
                     writer.addMethod()
@@ -437,6 +426,12 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                 // Value
                 statements.addAll(value);
                 // Elements
+                elements.sort((e1, e2) -> {
+                    // sort so output is last
+                    boolean l1 = e1.startsWith("doWriteList(null, null, def.getOutputs()");
+                    boolean l2 = e2.startsWith("doWriteList(null, null, def.getOutputs()");
+                    return Boolean.compare(l1, l2);
+                });
                 if (hasDerived && !elements.isEmpty()) {
                     writer.addMethod()
                             .setProtected()
@@ -449,7 +444,11 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                 } else {
                     statements.addAll(elements);
                 }
-                statements.add("endElement();");
+                if ("ExpressionSubElementDefinition".equals(name)) {
+                    statements.add("endExpressionElement(name);");
+                } else {
+                    statements.add("endElement(name);");
+                }
                 writer.addMethod()
                         .setProtected()
                         .setReturnType(Void.TYPE)
@@ -498,7 +497,7 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                 .setReturnType(Void.TYPE)
                 .setName("doWriteAttribute")
                 .addParameter(String.class, "attribute")
-                .addParameter(String.class, "value")
+                .addParameter(Object.class, "value")
                 .addThrows(IOException.class)
                 .setBody("if (value != null) {",
                         "    attribute(attribute, value);",
@@ -510,35 +509,35 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                 .addParameter(String.class, "value")
                 .addThrows(IOException.class)
                 .setBody("if (value != null) {",
-                        "    text(value);",
+                        "    value(value);",
                         "}");
         writer.addMethod()
                 .setSignature("protected <T> void doWriteList(String wrapperName, String name, List<T> list, ElementSerializer<T> elementSerializer) throws IOException")
                 .setBody("""
-                            if (list != null) {
-                                if (wrapperName != null) {
-                                    startElement(wrapperName);
-                                }
-                                for (T v : list) {
-                                    elementSerializer.doWriteElement(name, v);
-                                }
-                                if (wrapperName != null) {
-                                    endElement();
-                                }
-                            }""");
+                        if (list != null) {
+                            if (wrapperName != null) {
+                                startElement(wrapperName);
+                            }
+                            for (T v : list) {
+                                elementSerializer.doWriteElement(name, v);
+                            }
+                            if (wrapperName != null) {
+                                endElement(wrapperName);
+                            }
+                        }""");
         writer.addMethod()
                 .setSignature("protected <T> void doWriteElement(String name, T v, ElementSerializer<T> elementSerializer) throws IOException")
                 .setBody("""
-                            if (v != null) {
-                                elementSerializer.doWriteElement(name, v);
-                            }""");
+                        if (v != null) {
+                            elementSerializer.doWriteElement(name, v);
+                        }""");
         writer.addNestedType()
                 .setClass(false)
                 .setAbstract(true)
                 .setName("ElementSerializer<T>")
                 .addMethod()
-                        .setAbstract()
-                        .setSignature("void doWriteElement(String name, T value) throws IOException");
+                .setAbstract()
+                .setSignature("void doWriteElement(String name, T value) throws IOException");
 
         writer.addMethod()
                 .setProtected()
@@ -575,8 +574,20 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                 .addThrows(IOException.class)
                 .setBody("if (value != null) {",
                         "    startElement(name);",
-                        "    text(value);",
-                        "    endElement();",
+                        "    text(name, value);",
+                        "    endElement(name);",
+                        "}");
+
+        writer.addMethod()
+                .setProtected()
+                .setReturnType(Void.TYPE)
+                .setName("doWriteNamespaces")
+                .addParameter("NamespaceAwareExpression", "def")
+                .addThrows(IOException.class)
+                .setBody("if (def.getNamespaceAsMap() != null) {",
+                        "    for (var e : def.getNamespaceAsMap().entrySet()) {",
+                        "        doWriteAttribute(\"xmlns:\" + e.getKey(), e.getValue());",
+                        "    }",
                         "}");
 
         return writer;
@@ -597,8 +608,8 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
         if (rawClass == String.class) {
             return val;
         } else if (rawClass.isEnum()
-                || rawClass == Integer.class || rawClass == Long.class || rawClass == Boolean.class
-                || rawClass == Float.class) {
+                   || rawClass == Integer.class || rawClass == Long.class || rawClass == Boolean.class
+                   || rawClass == Float.class) {
             writer.addImport(rawClass);
             return "toString(" + val + ")";
         } else if (rawClass == byte[].class) {
@@ -608,108 +619,10 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
         }
     }
 
-    class Property {
-        private final Member field;
-        private final Member getter;
-        private final Member setter;
-        private final String name;
-        private final Type type;
-
-        public Property(Member field, Member getter, Member setter, String name, Type type) {
-            this.field = field;
-            this.getter = getter;
-            this.setter = setter;
-            this.name = name;
-            this.type = type;
-        }
-
-        @Override
-        public String toString() {
-            return "Property{" +
-                    "name='" + name + '\'' +
-                    ", type=" + type +
-                    ", field=" + field +
-                    ", getter=" + getter +
-                    ", setter=" + setter +
-                    '}';
-        }
-
-        private Stream<Member> members() {
-            return Stream.of(field, getter, setter).filter(Objects::nonNull);
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public Type getType() {
-            return type;
-        }
-
-        public String getGetter() {
-            return Optional.ofNullable(getter)
-                    .orElseThrow(() -> new IllegalArgumentException("No getter for property defined by " + members().toList()))
-                    .getName();
-        }
-
-        public String getSetter() {
-            return Optional.ofNullable(setter)
-                    .orElseThrow(() -> new IllegalArgumentException("No setter for property defined by " + members().toList()))
-                    .getName();
-        }
-
-        @SuppressWarnings("unchecked")
-        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-            return (T) annotations().filter(annotationClass::isInstance).findFirst().orElse(null);
-        }
-
-        public <T extends Annotation> boolean hasAnnotation(Class<T> annotationClass) {
-            return getAnnotation(annotationClass) != null;
-        }
-
-        private Stream<? extends Annotation> annotations() {
-            return members().flatMap(m -> Stream.of(((AnnotatedElement) m).getAnnotations()));
-
-        }
-
-        public boolean isAttribute() {
-            return hasAnnotation(XmlAttribute.class);
-        }
-
-        public boolean isAnyAttribute() {
-            return hasAnnotation(XmlAnyAttribute.class);
-        }
-
-        public boolean isValue() {
-            return hasAnnotation(XmlValue.class);
-        }
-
-        public boolean isElement() {
-            return !isAttribute() && !isAnyAttribute() && !isValue();
-        }
-
-        public boolean isElementRefs() {
-            return hasAnnotation(XmlElementRefs.class);
-        }
-
-        public boolean isElementRef() {
-            return hasAnnotation(XmlElementRef.class);
-            // || member.getDeclaringClass() == outputDefinitionClass && "setOutputs".equals(member.getName());
-        }
-    }
-
-    private static Type type(Member member) {
-        return member instanceof Method
-                ? member.getName().startsWith("set")
-                        ? ((Method) member).getGenericParameterTypes()[0]
-                        : ((Method) member).getGenericReturnType()
-                : ((Field) member).getGenericType();
-    }
-
-    private Map<Class<?>, List<Property>> properties = new ConcurrentHashMap<>();
     private Stream<Property> getProperties(Class<?> clazz) {
         return properties.computeIfAbsent(clazz, cl -> doGetProperties(cl)).stream();
     }
+
     private List<Property> doGetProperties(Class<?> clazz) {
         List<Member> allMembers = getClassAndSuper(clazz)
                 .flatMap(cl -> getMembers(clazz).stream())
@@ -725,29 +638,29 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
                         return null;
                     }
                     String name = l.getKey();
-                    Type type = type(members.get(0));
+                    Type type = ModelWriterGeneratorMojo.type(members.get(0));
                     Member field = members.stream()
                             .filter(this::isField)
                             .findFirst().or(() -> allMembers.stream()
                                     .filter(m -> isField(m)
-                                            && Objects.equals(propname(m), name)
-                                            && Objects.equals(type(m), type))
+                                                 && Objects.equals(propname(m), name)
+                                                 && Objects.equals(ModelWriterGeneratorMojo.type(m), type))
                                     .findFirst())
                             .orElse(null);
                     Member getter = members.stream()
                             .filter(this::isGetter)
                             .findFirst().or(() -> allMembers.stream()
                                     .filter(m -> isGetter(m)
-                                            && Objects.equals(propname(m), name)
-                                            && Objects.equals(type(m), type))
+                                                 && Objects.equals(propname(m), name)
+                                                 && Objects.equals(ModelWriterGeneratorMojo.type(m), type))
                                     .findFirst())
                             .orElse(null);
                     Member setter = members.stream()
                             .filter(this::isSetter)
                             .findFirst().or(() -> allMembers.stream()
                                     .filter(m -> isSetter(m)
-                                            && Objects.equals(propname(m), name)
-                                            && Objects.equals(type(m), type))
+                                                 && Objects.equals(propname(m), name)
+                                                 && Objects.equals(ModelWriterGeneratorMojo.type(m), type))
                                     .findFirst())
                             .orElse(null);
                     if (getter != null && setter != null) {
@@ -777,13 +690,12 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
         return properties.toList();
     }
 
-    private Map<Class<?>, List<Member>> members = new ConcurrentHashMap<>();
     private List<Member> getMembers(Class<?> clazz) {
         return members.computeIfAbsent(clazz, cl -> Stream.<Member>concat(
-                    Arrays.stream(cl.getDeclaredMethods())
-                        .filter(m -> isSetter(m) || isGetter(m))
-                        .filter(m -> !m.isSynthetic()),
-                    Arrays.stream(cl.getDeclaredFields()))
+                        Arrays.stream(cl.getDeclaredMethods())
+                                .filter(m -> isSetter(m) || isGetter(m))
+                                .filter(m -> !m.isSynthetic()),
+                        Arrays.stream(cl.getDeclaredFields()))
                 .toList());
     }
 
@@ -796,17 +708,17 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
         }
         if (accessType == XmlAccessType.PROPERTY) {
             return m -> m.getDeclaringClass() == clazz
-                    && isSetter(m) || isGetter(m) || (isField(m) && isXmlBindAnnotated(m));
+                        && isSetter(m) || isGetter(m) || (isField(m) && isXmlBindAnnotated(m));
         } else if (accessType == XmlAccessType.FIELD) {
             return m -> m.getDeclaringClass() == clazz
-                    && ((isSetter(m) || isGetter(m)) && isXmlBindAnnotated(m)
+                        && ((isSetter(m) || isGetter(m)) && isXmlBindAnnotated(m)
                             || isField(m) && !Modifier.isStatic(m.getModifiers()) && !Modifier.isTransient(m.getModifiers()));
         } else if (accessType == XmlAccessType.PUBLIC_MEMBER) {
             return m -> m.getDeclaringClass() == clazz
-                    && (Modifier.isPublic(m.getModifiers()) || isXmlBindAnnotated(m));
+                        && (Modifier.isPublic(m.getModifiers()) || isXmlBindAnnotated(m));
         } else /* if (accessType == XmlAccessType.NONE) */ {
             return m -> m.getDeclaringClass() == clazz
-                    && isXmlBindAnnotated(m);
+                        && isXmlBindAnnotated(m);
         }
     }
 
@@ -821,19 +733,19 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
 
     private boolean isSetter(Member member) {
         return (member instanceof Method m)
-                && !Modifier.isStatic(m.getModifiers())
-                && m.getName().startsWith("set") && m.getName().length() > 3
-                && m.getParameterCount() == 1
-                && m.getReturnType() == Void.TYPE;
+               && !Modifier.isStatic(m.getModifiers())
+               && m.getName().startsWith("set") && m.getName().length() > 3
+               && m.getParameterCount() == 1
+               && m.getReturnType() == Void.TYPE;
     }
 
     private boolean isGetter(Member member) {
         return (member instanceof Method m)
-                && !Modifier.isStatic(m.getModifiers())
-                && m.getParameterCount() == 0
-                && (m.getName().startsWith("get") && m.getName().length() > 3
-                        || m.getName().startsWith("is") && m.getName().length() > 2
-                                && (m.getReturnType() == Boolean.TYPE || m.getReturnType() == Boolean.class));
+               && !Modifier.isStatic(m.getModifiers())
+               && m.getParameterCount() == 0
+               && (m.getName().startsWith("get") && m.getName().length() > 3
+                   || m.getName().startsWith("is") && m.getName().length() > 2
+                      && (m.getReturnType() == Boolean.TYPE || m.getReturnType() == Boolean.class));
     }
 
     private Stream<Class<?>> getClassAndSuper(Class<?> clazz) {
@@ -868,8 +780,86 @@ public class ModelXmlWriterGeneratorMojo extends AbstractGeneratorMojo {
         return fn.substring(0, 1).toLowerCase() + fn.substring(1);
     }
 
-    private String uppercase(String fn) {
-        return fn.substring(0, 1).toUpperCase() + fn.substring(1);
-    }
+    class Property {
+        private final Member field;
+        private final Member getter;
... 231 lines suppressed ...