You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gn...@apache.org on 2020/03/13 14:40:01 UTC

[camel] branch master updated (fbe6416 -> 1024317)

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

gnodet pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from fbe6416  Camel-AWS2-SNS: Fixed CS
     new b003736  Remove some warnings
     new 69e2d9f  Remove unused call / variable
     new edce21d  Remove reference to the RouteDefinition in ErrorHandlerReifier
     new c9a2aca  Introduce an immutable CamelContext with limited features
     new 369b61a  Remove a call to toString as the value is always a String
     new 61f964a  Remove reference to UUID and use UuidGenerator instead
     new 171a2dd  CS: Fix imports
     new bf4f3ee  Add a test for the immutable context
     new 1024317  [CAMEL-14712] Provide an immutable lightweight camel context Merge remote-tracking branch 'origin/master' into immutable

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../kinesis/KinesisComponentConfigurationTest.java |    1 -
 .../KinesisConsumerClosedShardWithFailTest.java    |    4 +-
 .../KinesisConsumerClosedShardWithSilentTest.java  |    3 +-
 .../KinesisComponentIntegrationTest.java           |    2 +-
 .../camel/component/aws2/s3/AWS2S3Producer.java    |    1 +
 .../S3CopyObjectOperationIntegrationTest.java      |    1 -
 .../S3DeleteBucketOperationIntegrationTest.java    |    1 -
 .../component/azure/blob/BlobServiceComponent.java |    1 -
 .../azure/queue/QueueServiceComponent.java         |    1 -
 ...lobServiceComponentConfigurationClientTest.java |    2 -
 .../BlobServiceComponentConfigurationTest.java     |    1 -
 .../azure/common/AzureCredentialsTest.java         |   26 +-
 .../azure/common/AzureServiceCommonTestUtil.java   |    1 -
 .../azure/common/MissingCredentialsTest.java       |    9 +-
 .../azure/queue/QueueServiceUtilTest.java          |    1 -
 .../cdi/transaction/JtaTransactionPolicy.java      |    2 +-
 .../component/infinispan/InfinispanManager.java    |    1 -
 .../camel/spring/spi/SpringTransactionPolicy.java  |    2 +-
 .../camel/spring/bind/ProcessorAsEndpointTest.java |    1 -
 .../undertow/rest/RestUndertowHttpGetTest.java     |    3 -
 .../main/java/org/apache/camel/CamelContext.java   |   19 +-
 .../org/apache/camel/ExtendedCamelContext.java     |    7 +
 .../{ServiceSupport.java => BaseService.java}      |   85 +-
 .../camel/support/service/ServiceSupport.java      |  379 +---
 .../impl/converter/BaseTypeConverterRegistry.java  |  631 +------
 ...egistry.java => CoreTypeConverterRegistry.java} |  352 +---
 .../camel/impl/converter/DefaultTypeConverter.java |    5 -
 .../camel/impl/engine/AbstractCamelContext.java    |  512 +++---
 .../org/apache/camel/impl/engine/DefaultRoute.java |    3 +-
 .../camel/impl/engine/DefaultRouteController.java  |   31 +-
 .../impl/engine/DefaultStreamCachingStrategy.java  |    3 +-
 .../org/apache/camel/impl/engine/EndpointKey.java  |    3 +-
 .../org/apache/camel/impl/engine/RouteService.java |   11 +-
 .../camel/impl/engine/SimpleCamelContext.java      |   45 +-
 .../org/apache/camel/impl/DefaultCamelContext.java |   31 +-
 .../java/org/apache/camel/impl/DefaultModel.java   |   57 +-
 .../camel/impl/lw/ImmutableCamelContext.java       | 1657 ++++++++++++++++++
 .../impl/lw/RuntimeImmutableCamelContext.java      | 1820 ++++++++++++++++++++
 .../main/java/org/apache/camel/model/Model.java    |    5 -
 .../org/apache/camel/model/ModelCamelContext.java  |    9 +
 .../reifier/errorhandler/ErrorHandlerReifier.java  |    5 +-
 .../java/org/apache/camel/ContextTestSupport.java  |   34 +-
 .../impl/RouteWithMistypedComponentNameTest.java   |    1 -
 .../lw/ImmutableContextTest.java}                  |   28 +-
 .../org/apache/camel/main/BaseMainSupport.java     |    4 +-
 .../org/apache/camel/support/EndpointHelper.java   |   23 +-
 .../java/org/apache/camel/support/EventHelper.java |    1 +
 .../org/apache/camel/support/ExchangeHelper.java   |    1 -
 48 files changed, 4072 insertions(+), 1754 deletions(-)
 copy core/camel-api/src/main/java/org/apache/camel/support/service/{ServiceSupport.java => BaseService.java} (90%)
 copy core/camel-base/src/main/java/org/apache/camel/impl/converter/{BaseTypeConverterRegistry.java => CoreTypeConverterRegistry.java} (67%)
 create mode 100644 core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
 create mode 100644 core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
 copy core/camel-core/src/test/java/org/apache/camel/{processor/CBRWithWireTapTest.java => impl/lw/ImmutableContextTest.java} (72%)


[camel] 04/09: Introduce an immutable CamelContext with limited features

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c9a2acad290e134e291f0badf8f3ae5fb91c7e65
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Fri Mar 13 15:06:26 2020 +0100

    Introduce an immutable CamelContext with limited features
---
 .../main/java/org/apache/camel/CamelContext.java   |   19 +-
 .../org/apache/camel/ExtendedCamelContext.java     |    7 +
 .../{ServiceSupport.java => BaseService.java}      |   85 +-
 .../camel/support/service/ServiceSupport.java      |  379 +---
 .../impl/converter/BaseTypeConverterRegistry.java  |  631 +------
 ...egistry.java => CoreTypeConverterRegistry.java} |  352 +---
 .../camel/impl/converter/DefaultTypeConverter.java |    5 -
 .../camel/impl/engine/AbstractCamelContext.java    |  512 +++---
 .../camel/impl/engine/DefaultRouteController.java  |   31 +-
 .../org/apache/camel/impl/engine/EndpointKey.java  |    3 +-
 .../org/apache/camel/impl/engine/RouteService.java |   11 +-
 .../camel/impl/engine/SimpleCamelContext.java      |   45 +-
 .../org/apache/camel/impl/DefaultCamelContext.java |   31 +-
 .../java/org/apache/camel/impl/DefaultModel.java   |   57 +-
 .../camel/impl/lw/ImmutableCamelContext.java       | 1657 ++++++++++++++++++
 .../impl/lw/RuntimeImmutableCamelContext.java      | 1820 ++++++++++++++++++++
 .../main/java/org/apache/camel/model/Model.java    |    5 -
 .../org/apache/camel/model/ModelCamelContext.java  |    9 +
 .../java/org/apache/camel/ContextTestSupport.java  |   34 +-
 .../org/apache/camel/main/BaseMainSupport.java     |    4 +-
 .../org/apache/camel/support/EndpointHelper.java   |   23 +-
 21 files changed, 4026 insertions(+), 1694 deletions(-)

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 cc63828..96471ca 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
@@ -16,6 +16,7 @@
  */
 package org.apache.camel;
 
+import java.io.IOException;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
@@ -79,7 +80,20 @@ import org.apache.camel.support.jsse.SSLContextParameters;
  * <p/>
  * For more advanced APIs with {@link CamelContext} see {@link ExtendedCamelContext}, which you can obtain via the adapt method.
  */
-public interface CamelContext extends StatefulService, RuntimeConfiguration {
+public interface CamelContext extends RuntimeConfiguration, AutoCloseable {
+
+    boolean isStarted();
+    boolean isStarting();
+    boolean isStopped();
+    boolean isStopping();
+    boolean isSuspended();
+    boolean isSuspending();
+    boolean isRunAllowed();
+    void init();
+    void suspend();
+    void resume();
+    void shutdown();
+    void close() throws IOException;
 
     /**
      * Adapts this {@link org.apache.camel.CamelContext} to the specialized type.
@@ -121,7 +135,6 @@ public interface CamelContext extends StatefulService, RuntimeConfiguration {
      *
      * @throws RuntimeCamelException is thrown if starting failed
      */
-    @Override
     void start();
 
     /**
@@ -131,7 +144,6 @@ public interface CamelContext extends StatefulService, RuntimeConfiguration {
      *
      * @throws RuntimeCamelException is thrown if stopping failed
      */
-    @Override
     void stop();
 
     /**
@@ -197,7 +209,6 @@ public interface CamelContext extends StatefulService, RuntimeConfiguration {
      *
      * @return the status
      */
-    @Override
     ServiceStatus getStatus();
 
     /**
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 d1c96b7..55f92bb 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
@@ -52,6 +52,7 @@ import org.apache.camel.spi.PackageScanResourceResolver;
 import org.apache.camel.spi.ProcessorFactory;
 import org.apache.camel.spi.ReactiveExecutor;
 import org.apache.camel.spi.Registry;
+import org.apache.camel.spi.RouteController;
 import org.apache.camel.spi.RouteStartupOrder;
 import org.apache.camel.spi.UnitOfWorkFactory;
 import org.apache.camel.spi.XMLRoutesDefinitionLoader;
@@ -566,4 +567,10 @@ public interface ExtendedCamelContext extends CamelContext {
      * If references to the model are removed when Camel is started or not.
      */
     boolean isClearModelReferences();
+
+    RouteController getInternalRouteController();
+
+    void addRoute(Route route);
+
+    void removeRoute(Route route);
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceSupport.java b/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
similarity index 90%
copy from core/camel-api/src/main/java/org/apache/camel/support/service/ServiceSupport.java
copy to core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
index 8c9fc4e..d408b10 100644
--- a/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceSupport.java
+++ b/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
@@ -18,7 +18,6 @@ package org.apache.camel.support.service;
 
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.ServiceStatus;
-import org.apache.camel.StatefulService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -34,7 +33,7 @@ import org.slf4j.LoggerFactory;
  * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
  * invoke the operation in a safe manner.
  */
-public abstract class ServiceSupport implements StatefulService {
+public abstract class BaseService {
 
     protected static final byte NEW = 0;
     protected static final byte BUILDED = 1;
@@ -49,21 +48,20 @@ public abstract class ServiceSupport implements StatefulService {
     protected static final byte SHUTDOWN = 10;
     protected static final byte FAILED = 11;
 
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceSupport.class);
+    private static final Logger LOG = LoggerFactory.getLogger(BaseService.class);
 
     protected final Object lock = new Object();
     protected volatile byte status = NEW;
 
-    @Override
     public void build() {
         if (status == NEW) {
             synchronized (lock) {
                 if (status == NEW) {
                     LOG.trace("Building service: {}", this);
-                    try {
+                    try (AutoCloseable ignored = doLifecycleChange()) {
                         doBuild();
                     } catch (Exception e) {
-                        throw RuntimeCamelException.wrapRuntimeException(e);
+                        doFail(e);
                     }
                     status = BUILDED;
                     LOG.trace("Built service: {}", this);
@@ -72,17 +70,17 @@ public abstract class ServiceSupport implements StatefulService {
         }
     }
 
-    @Override
     public void init() {
         // allow to initialize again if stopped or failed
         if (status <= BUILDED || status >= STOPPED) {
             synchronized (lock) {
                 if (status <= BUILDED || status >= STOPPED) {
                     LOG.trace("Initializing service: {}", this);
-                    try {
+                    try (AutoCloseable ignored = doLifecycleChange()) {
                         doInit();
                     } catch (Exception e) {
-                        throw RuntimeCamelException.wrapRuntimeException(e);
+                        LOG.trace("Error while initializing service: " + this, e);
+                        fail(e);
                     }
                     status = INITIALIZED;
                     LOG.trace("Initialized service: {}", this);
@@ -97,7 +95,6 @@ public abstract class ServiceSupport implements StatefulService {
      * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
      * invoke the operation in a safe manner.
      */
-    @Override
     public void start() {
         synchronized (lock) {
             if (status == STARTED) {
@@ -108,14 +105,8 @@ public abstract class ServiceSupport implements StatefulService {
                 LOG.trace("Service: {} already starting", this);
                 return;
             }
-            try {
-                init();
-            } catch (Exception e) {
-                status = FAILED;
-                LOG.trace("Error while initializing service: " + this, e);
-                throw e;
-            }
-            try {
+            init();
+            try (AutoCloseable ignored = doLifecycleChange()) {
                 status = STARTING;
                 LOG.trace("Starting service: {}", this);
                 doStart();
@@ -129,9 +120,8 @@ public abstract class ServiceSupport implements StatefulService {
                     // ignore
                     LOG.trace("Error while stopping service after it failed to start: " + this + ". This exception is ignored", e);
                 }
-                status = FAILED;
                 LOG.trace("Error while starting service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
+                fail(e);
             }
         }
     }
@@ -142,7 +132,6 @@ public abstract class ServiceSupport implements StatefulService {
      * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
      * invoke the operation in a safe manner.
      */
-    @Override
     public void stop() {
         synchronized (lock) {
             if (status == FAILED) {
@@ -159,14 +148,13 @@ public abstract class ServiceSupport implements StatefulService {
             }
             status = STOPPING;
             LOG.trace("Stopping service: {}", this);
-            try {
+            try (AutoCloseable ignored = doLifecycleChange()) {
                 doStop();
                 status = STOPPED;
                 LOG.trace("Stopped: {} service", this);
             } catch (Exception e) {
-                status = FAILED;
                 LOG.trace("Error while stopping service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
+                fail(e);
             }
         }
     }
@@ -177,7 +165,6 @@ public abstract class ServiceSupport implements StatefulService {
      * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
      * invoke the operation in a safe manner.
      */
-    @Override
     public void suspend() {
         synchronized (lock) {
             if (status == SUSPENDED) {
@@ -190,14 +177,13 @@ public abstract class ServiceSupport implements StatefulService {
             }
             status = SUSPENDING;
             LOG.trace("Suspending service: {}", this);
-            try {
+            try (AutoCloseable ignored = doLifecycleChange()) {
                 doSuspend();
                 status = SUSPENDED;
                 LOG.trace("Suspended service: {}", this);
             } catch (Exception e) {
-                status = FAILED;
                 LOG.trace("Error while suspending service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
+                fail(e);
             }
         }
     }
@@ -208,7 +194,6 @@ public abstract class ServiceSupport implements StatefulService {
      * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
      * invoke the operation in a safe manner.
      */
-    @Override
     public void resume() {
         synchronized (lock) {
             if (status != SUSPENDED) {
@@ -217,14 +202,13 @@ public abstract class ServiceSupport implements StatefulService {
             }
             status = STARTING;
             LOG.trace("Resuming service: {}", this);
-            try {
+            try (AutoCloseable ignored = doLifecycleChange()) {
                 doResume();
                 status = STARTED;
                 LOG.trace("Resumed service: {}", this);
             } catch (Exception e) {
-                status = FAILED;
                 LOG.trace("Error while resuming service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
+                fail(e);
             }
         }
     }
@@ -235,7 +219,6 @@ public abstract class ServiceSupport implements StatefulService {
      * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
      * invoke the operation in a safe manner.
      */
-    @Override
     public void shutdown() {
         synchronized (lock) {
             if (status == SHUTDOWN) {
@@ -249,19 +232,17 @@ public abstract class ServiceSupport implements StatefulService {
             stop();
             status = SHUTDOWN;
             LOG.trace("Shutting down service: {}", this);
-            try {
+            try (AutoCloseable ignored = doLifecycleChange()) {
                 doShutdown();
                 LOG.trace("Shutdown service: {}", this);
                 status = SHUTDOWN;
             } catch (Exception e) {
-                status = FAILED;
                 LOG.trace("Error shutting down service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
+                fail(e);
             }
         }
     }
 
-    @Override
     public ServiceStatus getStatus() {
         switch (status) {
             case STARTING:
@@ -291,37 +272,30 @@ public abstract class ServiceSupport implements StatefulService {
         return status == INITIALIZED;
     }
 
-    @Override
     public boolean isStarted() {
         return status == STARTED;
     }
 
-    @Override
     public boolean isStarting() {
         return status == STARTING;
     }
 
-    @Override
     public boolean isStopping() {
         return status == STOPPING;
     }
 
-    @Override
     public boolean isStopped() {
         return status < STARTING || status >= STOPPED;
     }
 
-    @Override
     public boolean isSuspending() {
         return status == SUSPENDING;
     }
 
-    @Override
     public boolean isSuspended() {
         return status == SUSPENDED;
     }
 
-    @Override
     public boolean isRunAllowed() {
         return status >= STARTING && status <= SUSPENDED;
     }
@@ -351,6 +325,14 @@ public abstract class ServiceSupport implements StatefulService {
         return status == STARTING || status == STARTED;
     }
 
+    protected void fail(Exception e) {
+        try {
+            doFail(e);
+        } finally {
+            status = FAILED;
+        }
+    }
+
     /**
      * Optional build phase of the service.
      * This method will only be called by frameworks which supports pre-building projects such as camel-quarkus.
@@ -409,4 +391,19 @@ public abstract class ServiceSupport implements StatefulService {
         // noop
     }
 
+    /**
+     * Implementations override this method to perform any action upon failure.
+     */
+    protected void doFail(Exception e) {
+        throw RuntimeCamelException.wrapRuntimeException(e);
+    }
+
+    /**
+     * Implementations may return an object that will be closed
+     * when the lifecycle action is completed.
+     */
+    protected AutoCloseable doLifecycleChange() {
+        return null;
+    }
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceSupport.java b/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceSupport.java
index 8c9fc4e..06b5b4e 100644
--- a/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceSupport.java
+++ b/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceSupport.java
@@ -16,11 +16,7 @@
  */
 package org.apache.camel.support.service;
 
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.ServiceStatus;
 import org.apache.camel.StatefulService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * A useful base class which ensures that a service is only initialized once and
@@ -34,379 +30,6 @@ import org.slf4j.LoggerFactory;
  * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
  * invoke the operation in a safe manner.
  */
-public abstract class ServiceSupport implements StatefulService {
-
-    protected static final byte NEW = 0;
-    protected static final byte BUILDED = 1;
-    protected static final byte INITIALIZED = 2;
-    protected static final byte STARTING = 3;
-    protected static final byte STARTED = 4;
-    protected static final byte SUSPENDING = 5;
-    protected static final byte SUSPENDED = 6;
-    protected static final byte STOPPING = 7;
-    protected static final byte STOPPED = 8;
-    protected static final byte SHUTTINGDOWN = 9;
-    protected static final byte SHUTDOWN = 10;
-    protected static final byte FAILED = 11;
-
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceSupport.class);
-
-    protected final Object lock = new Object();
-    protected volatile byte status = NEW;
-
-    @Override
-    public void build() {
-        if (status == NEW) {
-            synchronized (lock) {
-                if (status == NEW) {
-                    LOG.trace("Building service: {}", this);
-                    try {
-                        doBuild();
-                    } catch (Exception e) {
-                        throw RuntimeCamelException.wrapRuntimeException(e);
-                    }
-                    status = BUILDED;
-                    LOG.trace("Built service: {}", this);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void init() {
-        // allow to initialize again if stopped or failed
-        if (status <= BUILDED || status >= STOPPED) {
-            synchronized (lock) {
-                if (status <= BUILDED || status >= STOPPED) {
-                    LOG.trace("Initializing service: {}", this);
-                    try {
-                        doInit();
-                    } catch (Exception e) {
-                        throw RuntimeCamelException.wrapRuntimeException(e);
-                    }
-                    status = INITIALIZED;
-                    LOG.trace("Initialized service: {}", this);
-                }
-            }
-        }
-    }
-
-    /**
-     * <b>Important: </b> You should override the lifecycle methods that start with <tt>do</tt>, eg {@link #doStart()},
-     * {@link #doStop()}, etc. where you implement your logic. The methods {@link #start()}, {@link #stop()} should
-     * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
-     * invoke the operation in a safe manner.
-     */
-    @Override
-    public void start() {
-        synchronized (lock) {
-            if (status == STARTED) {
-                LOG.trace("Service: {} already started", this);
-                return;
-            }
-            if (status == STARTING) {
-                LOG.trace("Service: {} already starting", this);
-                return;
-            }
-            try {
-                init();
-            } catch (Exception e) {
-                status = FAILED;
-                LOG.trace("Error while initializing service: " + this, e);
-                throw e;
-            }
-            try {
-                status = STARTING;
-                LOG.trace("Starting service: {}", this);
-                doStart();
-                status = STARTED;
-                LOG.trace("Started service: {}", this);
-            } catch (Exception e) {
-                // need to stop as some resources may have been started during startup
-                try {
-                    stop();
-                } catch (Exception e2) {
-                    // ignore
-                    LOG.trace("Error while stopping service after it failed to start: " + this + ". This exception is ignored", e);
-                }
-                status = FAILED;
-                LOG.trace("Error while starting service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
-            }
-        }
-    }
-
-    /**
-     * <b>Important: </b> You should override the lifecycle methods that start with <tt>do</tt>, eg {@link #doStart()},
-     * {@link #doStop()}, etc. where you implement your logic. The methods {@link #start()}, {@link #stop()} should
-     * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
-     * invoke the operation in a safe manner.
-     */
-    @Override
-    public void stop() {
-        synchronized (lock) {
-            if (status == FAILED) {
-                LOG.trace("Service: {} failed and regarded as already stopped", this);
-                return;
-            }
-            if (status == STOPPED || status == SHUTTINGDOWN || status == SHUTDOWN) {
-                LOG.trace("Service: {} already stopped", this);
-                return;
-            }
-            if (status == STOPPING) {
-                LOG.trace("Service: {} already stopping", this);
-                return;
-            }
-            status = STOPPING;
-            LOG.trace("Stopping service: {}", this);
-            try {
-                doStop();
-                status = STOPPED;
-                LOG.trace("Stopped: {} service", this);
-            } catch (Exception e) {
-                status = FAILED;
-                LOG.trace("Error while stopping service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
-            }
-        }
-    }
-
-    /**
-     * <b>Important: </b> You should override the lifecycle methods that start with <tt>do</tt>, eg {@link #doStart()},
-     * {@link #doStop()}, etc. where you implement your logic. The methods {@link #start()}, {@link #stop()} should
-     * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
-     * invoke the operation in a safe manner.
-     */
-    @Override
-    public void suspend() {
-        synchronized (lock) {
-            if (status == SUSPENDED) {
-                LOG.trace("Service: {} already suspended", this);
-                return;
-            }
-            if (status == SUSPENDING) {
-                LOG.trace("Service: {} already suspending", this);
-                return;
-            }
-            status = SUSPENDING;
-            LOG.trace("Suspending service: {}", this);
-            try {
-                doSuspend();
-                status = SUSPENDED;
-                LOG.trace("Suspended service: {}", this);
-            } catch (Exception e) {
-                status = FAILED;
-                LOG.trace("Error while suspending service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
-            }
-        }
-    }
-
-    /**
-     * <b>Important: </b> You should override the lifecycle methods that start with <tt>do</tt>, eg {@link #doStart()},
-     * {@link #doStop()}, etc. where you implement your logic. The methods {@link #start()}, {@link #stop()} should
-     * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
-     * invoke the operation in a safe manner.
-     */
-    @Override
-    public void resume() {
-        synchronized (lock) {
-            if (status != SUSPENDED) {
-                LOG.trace("Service is not suspended: {}", this);
-                return;
-            }
-            status = STARTING;
-            LOG.trace("Resuming service: {}", this);
-            try {
-                doResume();
-                status = STARTED;
-                LOG.trace("Resumed service: {}", this);
-            } catch (Exception e) {
-                status = FAILED;
-                LOG.trace("Error while resuming service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
-            }
-        }
-    }
-
-    /**
-     * <b>Important: </b> You should override the lifecycle methods that start with <tt>do</tt>, eg {@link #doStart()},
-     * {@link #doStop()}, etc. where you implement your logic. The methods {@link #start()}, {@link #stop()} should
-     * <b>NOT</b> be overridden as they are used internally to keep track of the state of this service and properly
-     * invoke the operation in a safe manner.
-     */
-    @Override
-    public void shutdown() {
-        synchronized (lock) {
-            if (status == SHUTDOWN) {
-                LOG.trace("Service: {} already shutdown", this);
-                return;
-            }
-            if (status == SHUTTINGDOWN) {
-                LOG.trace("Service: {} already shutting down", this);
-                return;
-            }
-            stop();
-            status = SHUTDOWN;
-            LOG.trace("Shutting down service: {}", this);
-            try {
-                doShutdown();
-                LOG.trace("Shutdown service: {}", this);
-                status = SHUTDOWN;
-            } catch (Exception e) {
-                status = FAILED;
-                LOG.trace("Error shutting down service: " + this, e);
-                throw RuntimeCamelException.wrapRuntimeException(e);
-            }
-        }
-    }
-
-    @Override
-    public ServiceStatus getStatus() {
-        switch (status) {
-            case STARTING:
-                return ServiceStatus.Starting;
-            case STARTED:
-                return ServiceStatus.Started;
-            case SUSPENDING:
-                return ServiceStatus.Suspending;
-            case SUSPENDED:
-                return ServiceStatus.Suspended;
-            case STOPPING:
-                return ServiceStatus.Stopping;
-            default:
-                return ServiceStatus.Stopped;
-        }
-    }
-
-    public boolean isNew() {
-        return status == NEW;
-    }
-
-    public boolean isBuild() {
-        return status == BUILDED;
-    }
-
-    public boolean isInit() {
-        return status == INITIALIZED;
-    }
-
-    @Override
-    public boolean isStarted() {
-        return status == STARTED;
-    }
-
-    @Override
-    public boolean isStarting() {
-        return status == STARTING;
-    }
-
-    @Override
-    public boolean isStopping() {
-        return status == STOPPING;
-    }
-
-    @Override
-    public boolean isStopped() {
-        return status < STARTING || status >= STOPPED;
-    }
-
-    @Override
-    public boolean isSuspending() {
-        return status == SUSPENDING;
-    }
-
-    @Override
-    public boolean isSuspended() {
-        return status == SUSPENDED;
-    }
-
-    @Override
-    public boolean isRunAllowed() {
-        return status >= STARTING && status <= SUSPENDED;
-    }
-
-    public boolean isShutdown() {
-        return status == SHUTDOWN;
-    }
-
-    /**
-     * Is the service in progress of being stopped or already stopped
-     */
-    public boolean isStoppingOrStopped() {
-        return status < STARTING || status > SUSPENDED;
-    }
-
-    /**
-     * Is the service in progress of being suspended or already suspended
-     */
-    public boolean isSuspendingOrSuspended() {
-        return status == SUSPENDING || status == SUSPENDED;
-    }
-
-    /**
-     * Is the service in progress of being suspended or already suspended
-     */
-    public boolean isStartingOrStarted() {
-        return status == STARTING || status == STARTED;
-    }
-
-    /**
-     * Optional build phase of the service.
-     * This method will only be called by frameworks which supports pre-building projects such as camel-quarkus.
-     */
-    protected void doBuild() throws Exception {
-    }
-
-    /**
-     * Initialize the service.
-     * This method will only be called once before starting.
-     */
-    protected void doInit() throws Exception {
-    }
-
-    /**
-     * Implementations override this method to support customized start/stop.
-     * <p/>
-     * <b>Important: </b> See {@link #doStop()} for more details.
-     *
-     * @see #doStop()
-     */
-    protected abstract void doStart() throws Exception;
-
-    /**
-     * Implementations override this method to support customized start/stop.
-     * <p/>
-     * <b>Important:</b> Camel will invoke this {@link #doStop()} method when
-     * the service is being stopped. This method will <b>also</b> be invoked
-     * if the service is still in <i>uninitialized</i> state (eg has not
-     * been started). The method is <b>always</b> called to allow the service
-     * to do custom logic when the service is being stopped, such as when
-     * {@link org.apache.camel.CamelContext} is shutting down.
-     *
-     * @see #doStart()
-     */
-    protected abstract void doStop() throws Exception;
-
-    /**
-     * Implementations override this method to support customized suspend/resume.
-     */
-    protected void doSuspend() throws Exception {
-        // noop
-    }
-
-    /**
-     * Implementations override this method to support customized suspend/resume.
-     */
-    protected void doResume() throws Exception {
-        // noop
-    }
-
-    /**
-     * Implementations override this method to perform customized shutdown.
-     */
-    protected void doShutdown() throws Exception {
-        // noop
-    }
+public abstract class ServiceSupport extends BaseService implements StatefulService {
 
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
index 62be24d..ee08b33 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
@@ -28,37 +28,20 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.LongAdder;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
-import org.apache.camel.CamelExecutionException;
-import org.apache.camel.Exchange;
 import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.LoggingLevel;
 import org.apache.camel.NoFactoryAvailableException;
-import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.TypeConversionException;
 import org.apache.camel.TypeConverter;
-import org.apache.camel.TypeConverterExists;
-import org.apache.camel.TypeConverterExistsException;
 import org.apache.camel.TypeConverterLoaderException;
 import org.apache.camel.TypeConverters;
-import org.apache.camel.converter.ObjectConverter;
-import org.apache.camel.spi.CamelLogger;
+import org.apache.camel.impl.converter.CoreTypeConverterRegistry.FallbackTypeConverter;
 import org.apache.camel.spi.FactoryFinder;
 import org.apache.camel.spi.Injector;
 import org.apache.camel.spi.PackageScanClassResolver;
 import org.apache.camel.spi.TypeConverterLoader;
-import org.apache.camel.spi.TypeConverterRegistry;
-import org.apache.camel.support.MessageHelper;
-import org.apache.camel.support.TypeConverterSupport;
-import org.apache.camel.support.service.ServiceSupport;
-import org.apache.camel.util.DoubleMap;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
@@ -68,35 +51,18 @@ import org.slf4j.LoggerFactory;
  * Base implementation of a type converter registry used for
  * <a href="http://camel.apache.org/type-converter.html">type converters</a> in Camel.
  */
-public abstract class BaseTypeConverterRegistry extends ServiceSupport implements TypeConverter, TypeConverterRegistry {
+public abstract class BaseTypeConverterRegistry extends CoreTypeConverterRegistry {
 
     public static final String META_INF_SERVICES_TYPE_CONVERTER_LOADER = "META-INF/services/org/apache/camel/TypeConverterLoader";
     public static final String META_INF_SERVICES_FALLBACK_TYPE_CONVERTER = "META-INF/services/org/apache/camel/FallbackTypeConverter";
 
-    protected static final TypeConverter MISS_CONVERTER = new TypeConverterSupport() {
-        @Override
-        public <T> T convertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException {
-            return (T) MISS_VALUE;
-        }
-    };
-
     private static final Logger LOG = LoggerFactory.getLogger(BaseTypeConverterRegistry.class);
 
-    protected final DoubleMap<Class<?>, Class<?>, TypeConverter> typeMappings = new DoubleMap<>(200);
     protected final List<TypeConverterLoader> typeConverterLoaders = new ArrayList<>();
-    protected final List<FallbackTypeConverter> fallbackConverters = new CopyOnWriteArrayList<>();
     protected CamelContext camelContext;
     protected PackageScanClassResolver resolver;
     protected Injector injector;
     protected final FactoryFinder factoryFinder;
-    protected TypeConverterExists typeConverterExists = TypeConverterExists.Override;
-    protected LoggingLevel typeConverterExistsLoggingLevel = LoggingLevel.WARN;
-    protected final Statistics statistics = new UtilizationStatistics();
-    protected final LongAdder noopCounter = new LongAdder();
-    protected final LongAdder attemptCounter = new LongAdder();
-    protected final LongAdder missCounter = new LongAdder();
-    protected final LongAdder hitCounter = new LongAdder();
-    protected final LongAdder failedCounter = new LongAdder();
 
     public BaseTypeConverterRegistry(CamelContext camelContext, PackageScanClassResolver resolver, Injector injector, FactoryFinder factoryFinder) {
         this.camelContext = camelContext;
@@ -120,347 +86,6 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
     }
 
     @Override
-    public <T> T convertTo(Class<T> type, Object value) {
-        return convertTo(type, null, value);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
-        // optimize for a few common conversions
-        if (value != null) {
-            if (type.isInstance(value)) {
-                // same instance
-                return (T) value;
-            }
-            if (type == boolean.class) {
-                // primitive boolean which must return a value so throw exception if not possible
-                Object answer = ObjectConverter.toBoolean(value);
-                if (answer == null) {
-                    throw new TypeConversionException(value, type, new IllegalArgumentException("Cannot convert type: " + value.getClass().getName() + " to boolean"));
-                }
-                return (T) answer;
-            } else if (type == Boolean.class && (value instanceof String)) {
-                // String -> Boolean
-                String str = (String) value;
-                if ("true".equalsIgnoreCase(str)) {
-                    return (T) Boolean.TRUE;
-                } else if ("false".equalsIgnoreCase(str)) {
-                    return (T) Boolean.FALSE;
-                }
-            } else if (type.isPrimitive()) {
-                // okay its a wrapper -> primitive then return as-is for some common types
-                Class cls = value.getClass();
-                if (cls == Integer.class || cls == Long.class) {
-                    return (T) value;
-                }
-            } else if (type == String.class) {
-                // okay its a primitive -> string then return as-is for some common types
-                Class cls = value.getClass();
-                if (cls.isPrimitive()
-                        || cls == Boolean.class || cls == boolean.class
-                        || cls == Integer.class || cls == int.class
-                        || cls == Long.class || cls == long.class) {
-                    return (T) value.toString();
-                }
-            }
-            // NOTE: we cannot optimize any more if value is String as it may be time pattern and other patterns
-        }
-
-        return (T) doConvertTo(type, exchange, value, false, false);
-    }
-
-    @Override
-    public <T> T mandatoryConvertTo(Class<T> type, Object value) throws NoTypeConversionAvailableException {
-        return mandatoryConvertTo(type, null, value);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws NoTypeConversionAvailableException {
-        // optimize for a few common conversions
-        if (value != null) {
-            if (type.isInstance(value)) {
-                // same instance
-                return (T) value;
-            }
-            if (type == boolean.class) {
-                // primitive boolean which must return a value so throw exception if not possible
-                Object answer = ObjectConverter.toBoolean(value);
-                if (answer == null) {
-                    throw new TypeConversionException(value, type, new IllegalArgumentException("Cannot convert type: " + value.getClass().getName() + " to boolean"));
-                }
-                return (T) answer;
-            } else if (type == Boolean.class && (value instanceof String)) {
-                // String -> Boolean
-                String str = (String) value;
-                if ("true".equalsIgnoreCase(str)) {
-                    return (T) Boolean.TRUE;
-                } else if ("false".equalsIgnoreCase(str)) {
-                    return (T) Boolean.FALSE;
-                }
-            } else if (type.isPrimitive()) {
-                // okay its a wrapper -> primitive then return as-is for some common types
-                Class cls = value.getClass();
-                if (cls == Integer.class || cls == Long.class) {
-                    return (T) value;
-                }
-            } else if (type == String.class) {
-                // okay its a primitive -> string then return as-is for some common types
-                Class cls = value.getClass();
-                if (cls.isPrimitive()
-                        || cls == Boolean.class || cls == boolean.class
-                        || cls == Integer.class || cls == int.class
-                        || cls == Long.class || cls == long.class) {
-                    return (T) value.toString();
-                }
-            }
-            // NOTE: we cannot optimize any more if value is String as it may be time pattern and other patterns
-        }
-
-        Object answer = doConvertTo(type, exchange, value, true, false);
-        if (answer == null) {
-            // Could not find suitable conversion
-            throw new NoTypeConversionAvailableException(value, type);
-        }
-        return (T) answer;
-    }
-
-    @Override
-    public <T> T tryConvertTo(Class<T> type, Object value) {
-        return tryConvertTo(type, null, value);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T> T tryConvertTo(Class<T> type, Exchange exchange, Object value) {
-        return (T) doConvertTo(type, exchange, value, false, true);
-    }
-
-    protected Object doConvertTo(final Class<?> type, final Exchange exchange, final Object value,
-                                 final boolean mandatory, final boolean tryConvert) {
-        Object answer;
-        try {
-            answer = doConvertTo(type, exchange, value, tryConvert);
-        } catch (Exception e) {
-            if (statistics.isStatisticsEnabled()) {
-                failedCounter.increment();
-            }
-            if (tryConvert) {
-                return null;
-            }
-
-            // if its a ExecutionException then we have rethrow it as its not due to failed conversion
-            // this is special for FutureTypeConverter
-            boolean execution = ObjectHelper.getException(ExecutionException.class, e) != null
-                    || ObjectHelper.getException(CamelExecutionException.class, e) != null;
-            if (execution) {
-                throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
-            }
-            // error occurred during type conversion
-            throw createTypeConversionException(exchange, type, value, e);
-        }
-        if (answer == MISS_VALUE) {
-            // Could not find suitable conversion
-            if (statistics.isStatisticsEnabled()) {
-                missCounter.increment();
-            }
-            return null;
-        } else {
-            if (statistics.isStatisticsEnabled()) {
-                hitCounter.increment();
-            }
-            return answer;
-        }
-    }
-
-    protected Object doConvertTo(final Class<?> type, final Exchange exchange, final Object value,
-                                 final boolean tryConvert) throws Exception {
-        boolean trace = LOG.isTraceEnabled();
-        boolean statisticsEnabled = statistics.isStatisticsEnabled();
-
-        if (trace) {
-            LOG.trace("Finding type converter to convert {} -> {} with value: {}",
-                    value == null ? "null" : value.getClass().getCanonicalName(),
-                    type.getCanonicalName(), value);
-        }
-
-
-        if (value == null) {
-            // no type conversion was needed
-            if (statisticsEnabled) {
-                noopCounter.increment();
-            }
-            // lets avoid NullPointerException when converting to primitives for null values
-            if (type.isPrimitive()) {
-                if (boolean.class == type) {
-                    return Boolean.FALSE;
-                }
-                if (int.class == type) {
-                    return 0;
-                }
-                if (long.class == type) {
-                    return 0L;
-                }
-                if (byte.class == type) {
-                    return (byte) 0;
-                }
-                if (short.class == type) {
-                    return (short) 0;
-                }
-                if (double.class == type) {
-                    return 0.0;
-                }
-                if (float.class == type) {
-                    return 0.0f;
-                }
-                if (char.class == type) {
-                    return '\0';
-                }
-            }
-            return null;
-        }
-
-        // same instance type
-        if (type.isInstance(value)) {
-            // no type conversion was needed
-            if (statisticsEnabled) {
-                noopCounter.increment();
-            }
-            return value;
-        }
-
-        // okay we need to attempt to convert
-        if (statisticsEnabled) {
-            attemptCounter.increment();
-        }
-
-        // try to find a suitable type converter
-        TypeConverter converter = getOrFindTypeConverter(type, value.getClass());
-        if (converter != null) {
-            if (trace) {
-                LOG.trace("Using converter: {} to convert [{}=>{}]", converter, value.getClass(), type);
-            }
-            Object rc;
-            if (tryConvert) {
-                rc = converter.tryConvertTo(type, exchange, value);
-            } else {
-                rc = converter.convertTo(type, exchange, value);
-            }
-            if (rc != null) {
-                return rc;
-            } else if (converter.allowNull()) {
-                return null;
-            }
-        }
-
-        // not found with that type then if it was a primitive type then try again with the wrapper type
-        if (type.isPrimitive()) {
-            Class<?> primitiveType = ObjectHelper.convertPrimitiveTypeToWrapperType(type);
-            if (primitiveType != type) {
-                Class<?> fromType = value.getClass();
-                TypeConverter tc = getOrFindTypeConverter(primitiveType, fromType);
-                if (tc != null) {
-                    // add the type as a known type converter as we can convert from primitive to object converter
-                    addTypeConverter(type, fromType, tc);
-                    Object rc;
-                    if (tryConvert) {
-                        rc = tc.tryConvertTo(primitiveType, exchange, value);
-                    } else {
-                        rc = tc.convertTo(primitiveType, exchange, value);
-                    }
-                    if (rc == null && tc.allowNull()) {
-                        return null;
-                    } else if (rc != null) {
-                        return rc;
-                    }
-                }
-            }
-        }
-
-        // fallback converters
-        for (FallbackTypeConverter fallback : fallbackConverters) {
-            TypeConverter tc = fallback.getFallbackTypeConverter();
-            Object rc;
-            if (tryConvert) {
-                rc = tc.tryConvertTo(type, exchange, value);
-            } else {
-                rc = tc.convertTo(type, exchange, value);
-            }
-            if (rc == null && tc.allowNull()) {
-                return null;
-            }
-
-            if (rc == MISS_VALUE) {
-                // it cannot be converted so give up
-                return MISS_VALUE;
-            }
-
-            if (rc != null) {
-                // if fallback can promote then let it be promoted to a first class type converter
-                if (fallback.isCanPromote()) {
-                    // add it as a known type converter since we found a fallback that could do it
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("Promoting fallback type converter as a known type converter to convert from: {} to: {} for the fallback converter: {}",
-                                type.getCanonicalName(), value.getClass().getCanonicalName(), fallback.getFallbackTypeConverter());
-                    }
-                    addTypeConverter(type, value.getClass(), fallback.getFallbackTypeConverter());
-                }
-
-                if (LOG.isTraceEnabled()) {
-                    LOG.trace("Fallback type converter {} converted type from: {} to: {}",
-                            fallback.getFallbackTypeConverter(), type.getCanonicalName(), value.getClass().getCanonicalName());
-                }
-
-                // return converted value
-                return rc;
-            }
-        }
-
-        if (!tryConvert) {
-            // Could not find suitable conversion, so remember it
-            // do not register misses for try conversions
-            typeMappings.put(type, value.getClass(), MISS_CONVERTER);
-        }
-
-        // Could not find suitable conversion, so return Void to indicate not found
-        return MISS_VALUE;
-    }
-
-    @Override
-    public void addTypeConverter(Class<?> toType, Class<?> fromType, TypeConverter typeConverter) {
-        LOG.trace("Adding type converter: {}", typeConverter);
-        TypeConverter converter = typeMappings.get(toType, fromType);
-        // only override it if its different
-        // as race conditions can lead to many threads trying to promote the same fallback converter
-
-        if (typeConverter != converter) {
-
-            // add the converter unless we should ignore
-            boolean add = true;
-
-            // if converter is not null then a duplicate exists
-            if (converter != null) {
-                if (typeConverterExists == TypeConverterExists.Override) {
-                    CamelLogger logger = new CamelLogger(LOG, typeConverterExistsLoggingLevel);
-                    logger.log("Overriding type converter from: " + converter + " to: " + typeConverter);
-                } else if (typeConverterExists == TypeConverterExists.Ignore) {
-                    CamelLogger logger = new CamelLogger(LOG, typeConverterExistsLoggingLevel);
-                    logger.log("Ignoring duplicate type converter from: " + converter + " to: " + typeConverter);
-                    add = false;
-                } else {
-                    // we should fail
-                    throw new TypeConverterExistsException(toType, fromType);
-                }
-            }
-
-            if (add) {
-                typeMappings.put(toType, fromType, typeConverter);
-            }
-        }
-    }
-
-    @Override
     public void addTypeConverters(TypeConverters typeConverters) {
         LOG.trace("Adding type converters: {}", typeConverters);
         try {
@@ -473,19 +98,8 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
     }
 
     @Override
-    public boolean removeTypeConverter(Class<?> toType, Class<?> fromType) {
-        LOG.trace("Removing type converter from: {} to: {}", fromType, toType);
-        return typeMappings.remove(toType, fromType);
-    }
-
-    @Override
     public void addFallbackTypeConverter(TypeConverter typeConverter, boolean canPromote) {
-        LOG.trace("Adding fallback type converter: {} which can promote: {}", typeConverter, canPromote);
-
-        // add in top of fallback as the toString() fallback will nearly always be able to convert
-        // the last one which is add to the FallbackTypeConverter will be called at the first place
-        fallbackConverters.add(0, new FallbackTypeConverter(typeConverter, canPromote));
-
+        super.addFallbackTypeConverter(typeConverter, canPromote);
         if (typeConverter instanceof CamelContextAware) {
             CamelContextAware camelContextAware = (CamelContextAware) typeConverter;
             if (camelContext != null) {
@@ -494,8 +108,8 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         }
     }
 
-    private void addCoreFallbackTypeConverterToList(TypeConverter typeConverter, boolean canPromote, List<
-            FallbackTypeConverter> converters) {
+    private void addCoreFallbackTypeConverterToList(TypeConverter typeConverter, boolean canPromote,
+                                                    List<FallbackTypeConverter> converters) {
         LOG.trace("Adding core fallback type converter: {} which can promote: {}", typeConverter, canPromote);
 
         // add in top of fallback as the toString() fallback will nearly always be able to convert
@@ -510,10 +124,6 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         }
     }
 
-    public TypeConverter getTypeConverter(Class<?> toType, Class<?> fromType) {
-        return typeMappings.get(toType, fromType);
-    }
-
     @Override
     public Injector getInjector() {
         return injector;
@@ -528,82 +138,6 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         return resolver;
     }
 
-    protected <T> TypeConverter getOrFindTypeConverter(Class<?> toType, Class<?> fromType) {
-        TypeConverter converter = typeMappings.get(toType, fromType);
-        if (converter == null) {
-            // converter not found, try to lookup then
-            converter = lookup(toType, fromType);
-            if (converter != null) {
-                typeMappings.put(toType, fromType, converter);
-            }
-        }
-        return converter;
-    }
-
-    @Override
-    public TypeConverter lookup(Class<?> toType, Class<?> fromType) {
-        return doLookup(toType, fromType, false);
-    }
-
-    protected TypeConverter doLookup(Class<?> toType, Class<?> fromType, boolean isSuper) {
-
-        if (fromType != null) {
-            // lets try if there is a direct match
-            TypeConverter converter = getTypeConverter(toType, fromType);
-            if (converter != null) {
-                return converter;
-            }
-
-            // try the interfaces
-            for (Class<?> type : fromType.getInterfaces()) {
-                converter = getTypeConverter(toType, type);
-                if (converter != null) {
-                    return converter;
-                }
-            }
-
-            // try super then
-            Class<?> fromSuperClass = fromType.getSuperclass();
-            if (fromSuperClass != null && !fromSuperClass.equals(Object.class)) {
-                converter = doLookup(toType, fromSuperClass, true);
-                if (converter != null) {
-                    return converter;
-                }
-            }
-        }
-
-        // only do these tests as fallback and only on the target type (eg not on its super)
-        if (!isSuper) {
-            if (fromType != null && !fromType.equals(Object.class)) {
-
-                // lets try classes derived from this toType
-                TypeConverter converter = typeMappings.getFirst(
-                    toType::isAssignableFrom,
-                    // skip Object based we do them last
-                    from -> !from.equals(Object.class) && from.isAssignableFrom(fromType));
-                if (converter != null) {
-                    return converter;
-                }
-
-                // lets test for Object based converters as last resort
-                converter = getTypeConverter(toType, Object.class);
-                if (converter != null) {
-                    return converter;
-                }
-            }
-        }
-
-        // none found
-        return null;
-    }
-
-    @Override
-    public List<Class<?>[]> listAllTypeConvertersFromTo() {
-        List<Class<?>[]> answer = new ArrayList<>();
-        typeMappings.forEach((k1, k2, v) -> answer.add(new Class<?>[]{k2, k1}));
-        return answer;
-    }
-
     /**
      * Loads the core type converters which is mandatory to use Camel,
      * and also loads the fast type converters (generated via @Converter(loader = true).
@@ -612,7 +146,7 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         Collection<String> names = findTypeConverterLoaderClasses();
         for (String name : names) {
             LOG.debug("Resolving TypeConverterLoader: {}", name);
-            Class clazz = null;
+            Class<?> clazz = null;
             for (ClassLoader loader : getResolver().getClassLoaders()) {
                 try {
                     clazz = loader.loadClass(name);
@@ -724,7 +258,7 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         Collection<String> names = findFallbackTypeConverterClasses();
         for (String name : names) {
             LOG.debug("Resolving FallbackTypeConverter: {}", name);
-            Class clazz = getResolver().getClassLoaders().stream()
+            Class<?> clazz = getResolver().getClassLoaders().stream()
                     .map(cl -> ObjectHelper.loadClass(name, cl))
                     .filter(Objects::nonNull)
                     .findAny().orElseThrow(() -> new ClassNotFoundException(name));
@@ -737,54 +271,6 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         }
     }
 
-    protected TypeConversionException createTypeConversionException(Exchange exchange, Class<?> type, Object
-            value, Throwable cause) {
-        if (cause instanceof TypeConversionException) {
-            if (((TypeConversionException) cause).getToType() == type) {
-                return (TypeConversionException) cause;
-            }
-        }
-        Object body;
-        // extract the body for logging which allows to limit the message body in the exception/stacktrace
-        // and also can be used to turn off logging sensitive message data
-        if (exchange != null) {
-            body = MessageHelper.extractValueForLogging(value, exchange.getIn());
-        } else {
-            body = value;
-        }
-        return new TypeConversionException(body, type, cause);
-    }
-
-    @Override
-    public Statistics getStatistics() {
-        return statistics;
-    }
-
-    @Override
-    public int size() {
-        return typeMappings.size();
-    }
-
-    @Override
-    public LoggingLevel getTypeConverterExistsLoggingLevel() {
-        return typeConverterExistsLoggingLevel;
-    }
-
-    @Override
-    public void setTypeConverterExistsLoggingLevel(LoggingLevel typeConverterExistsLoggingLevel) {
-        this.typeConverterExistsLoggingLevel = typeConverterExistsLoggingLevel;
-    }
-
-    @Override
-    public TypeConverterExists getTypeConverterExists() {
-        return typeConverterExists;
-    }
-
-    @Override
-    public void setTypeConverterExists(TypeConverterExists typeConverterExists) {
-        this.typeConverterExists = typeConverterExists;
-    }
-
     @Override
     protected void doInit() {
         if (injector == null && camelContext != null) {
@@ -812,107 +298,4 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         fallbackConverters.addAll(fallbacks);
     }
 
-    @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
-    protected void doStop() throws Exception {
-        // log utilization statistics when stopping, including mappings
-        if (statistics.isStatisticsEnabled()) {
-            String info = statistics.toString();
-            AtomicInteger misses = new AtomicInteger();
-            typeMappings.forEach((k1, k2, v) -> {
-                if (v == MISS_CONVERTER) {
-                    misses.incrementAndGet();
-                }
-            });
-            info += String.format(" mappings[total=%s, misses=%s]", typeMappings.size(), misses);
-            LOG.info(info);
-        }
-
-        typeMappings.clear();
-        statistics.reset();
-    }
-
-    /**
-     * Represents utilization statistics
-     */
-    private final class UtilizationStatistics implements Statistics {
-
-        private boolean statisticsEnabled;
-
-        @Override
-        public long getNoopCounter() {
-            return noopCounter.longValue();
-        }
-
-        @Override
-        public long getAttemptCounter() {
-            return attemptCounter.longValue();
-        }
-
-        @Override
-        public long getHitCounter() {
-            return hitCounter.longValue();
-        }
-
-        @Override
-        public long getMissCounter() {
-            return missCounter.longValue();
-        }
-
-        @Override
-        public long getFailedCounter() {
-            return failedCounter.longValue();
-        }
-
-        @Override
-        public void reset() {
-            noopCounter.reset();
-            attemptCounter.reset();
-            hitCounter.reset();
-            missCounter.reset();
-            failedCounter.reset();
-        }
-
-        @Override
-        public boolean isStatisticsEnabled() {
-            return statisticsEnabled;
-        }
-
-        @Override
-        public void setStatisticsEnabled(boolean statisticsEnabled) {
-            this.statisticsEnabled = statisticsEnabled;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("TypeConverterRegistry utilization[noop=%s, attempts=%s, hits=%s, misses=%s, failures=%s]",
-                    getNoopCounter(), getAttemptCounter(), getHitCounter(), getMissCounter(), getFailedCounter());
-        }
-    }
-
-    /**
-     * Represents a fallback type converter
-     */
-    protected static class FallbackTypeConverter {
-        private final boolean canPromote;
-        private final TypeConverter fallbackTypeConverter;
-
-        FallbackTypeConverter(TypeConverter fallbackTypeConverter, boolean canPromote) {
-            this.canPromote = canPromote;
-            this.fallbackTypeConverter = fallbackTypeConverter;
-        }
-
-        public boolean isCanPromote() {
-            return canPromote;
-        }
-
-        public TypeConverter getFallbackTypeConverter() {
-            return fallbackTypeConverter;
-        }
-    }
-
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
similarity index 67%
copy from core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
copy to core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
index 62be24d..c5fcef4 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
@@ -16,62 +16,36 @@
  */
 package org.apache.camel.impl.converter;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Objects;
-import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.LongAdder;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.CamelContextAware;
 import org.apache.camel.CamelExecutionException;
 import org.apache.camel.Exchange;
-import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.LoggingLevel;
-import org.apache.camel.NoFactoryAvailableException;
 import org.apache.camel.NoTypeConversionAvailableException;
-import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.TypeConversionException;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.TypeConverterExists;
 import org.apache.camel.TypeConverterExistsException;
-import org.apache.camel.TypeConverterLoaderException;
 import org.apache.camel.TypeConverters;
 import org.apache.camel.converter.ObjectConverter;
 import org.apache.camel.spi.CamelLogger;
-import org.apache.camel.spi.FactoryFinder;
 import org.apache.camel.spi.Injector;
-import org.apache.camel.spi.PackageScanClassResolver;
-import org.apache.camel.spi.TypeConverterLoader;
 import org.apache.camel.spi.TypeConverterRegistry;
 import org.apache.camel.support.MessageHelper;
 import org.apache.camel.support.TypeConverterSupport;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.DoubleMap;
-import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-/**
- * Base implementation of a type converter registry used for
- * <a href="http://camel.apache.org/type-converter.html">type converters</a> in Camel.
- */
-public abstract class BaseTypeConverterRegistry extends ServiceSupport implements TypeConverter, TypeConverterRegistry {
-
-    public static final String META_INF_SERVICES_TYPE_CONVERTER_LOADER = "META-INF/services/org/apache/camel/TypeConverterLoader";
-    public static final String META_INF_SERVICES_FALLBACK_TYPE_CONVERTER = "META-INF/services/org/apache/camel/FallbackTypeConverter";
+public class CoreTypeConverterRegistry extends ServiceSupport implements TypeConverter, TypeConverterRegistry {
 
     protected static final TypeConverter MISS_CONVERTER = new TypeConverterSupport() {
         @Override
@@ -80,15 +54,10 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         }
     };
 
-    private static final Logger LOG = LoggerFactory.getLogger(BaseTypeConverterRegistry.class);
+    private static final Logger LOG = LoggerFactory.getLogger(CoreTypeConverterRegistry.class);
 
     protected final DoubleMap<Class<?>, Class<?>, TypeConverter> typeMappings = new DoubleMap<>(200);
-    protected final List<TypeConverterLoader> typeConverterLoaders = new ArrayList<>();
     protected final List<FallbackTypeConverter> fallbackConverters = new CopyOnWriteArrayList<>();
-    protected CamelContext camelContext;
-    protected PackageScanClassResolver resolver;
-    protected Injector injector;
-    protected final FactoryFinder factoryFinder;
     protected TypeConverterExists typeConverterExists = TypeConverterExists.Override;
     protected LoggingLevel typeConverterExistsLoggingLevel = LoggingLevel.WARN;
     protected final Statistics statistics = new UtilizationStatistics();
@@ -98,34 +67,59 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
     protected final LongAdder hitCounter = new LongAdder();
     protected final LongAdder failedCounter = new LongAdder();
 
-    public BaseTypeConverterRegistry(CamelContext camelContext, PackageScanClassResolver resolver, Injector injector, FactoryFinder factoryFinder) {
-        this.camelContext = camelContext;
-        this.injector = injector;
-        this.factoryFinder = factoryFinder;
-        this.resolver = resolver;
+    public CoreTypeConverterRegistry() {
+    }
+
+    public CoreTypeConverterRegistry(TypeConverterRegistry registry) {
+        if (registry instanceof CoreTypeConverterRegistry) {
+            CoreTypeConverterRegistry reg = (CoreTypeConverterRegistry) registry;
+            reg.getTypeMappings().forEach(typeMappings::put);
+            this.fallbackConverters.addAll(reg.getFallbackConverters());
+        } else {
+            throw new UnsupportedOperationException();
+        }
+        this.typeConverterExistsLoggingLevel = registry.getTypeConverterExistsLoggingLevel();
+        this.typeConverterExists = registry.getTypeConverterExists();
     }
 
     @Override
-    public CamelContext getCamelContext() {
-        return camelContext;
+    public boolean allowNull() {
+        return false;
     }
 
     @Override
-    public void setCamelContext(CamelContext camelContext) {
-        this.camelContext = camelContext;
+    public void setInjector(Injector injector) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Injector getInjector() {
+        throw new UnsupportedOperationException();
     }
 
-    public List<TypeConverterLoader> getTypeConverterLoaders() {
-        return typeConverterLoaders;
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        throw new UnsupportedOperationException();
     }
 
     @Override
+    public CamelContext getCamelContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    public DoubleMap<Class<?>, Class<?>, TypeConverter> getTypeMappings() {
+        return typeMappings;
+    }
+
+    public List<FallbackTypeConverter> getFallbackConverters() {
+        return fallbackConverters;
+    }
+
     public <T> T convertTo(Class<T> type, Object value) {
         return convertTo(type, null, value);
     }
 
     @SuppressWarnings("unchecked")
-    @Override
     public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
         // optimize for a few common conversions
         if (value != null) {
@@ -150,13 +144,13 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
                 }
             } else if (type.isPrimitive()) {
                 // okay its a wrapper -> primitive then return as-is for some common types
-                Class cls = value.getClass();
+                Class<?> cls = value.getClass();
                 if (cls == Integer.class || cls == Long.class) {
                     return (T) value;
                 }
             } else if (type == String.class) {
                 // okay its a primitive -> string then return as-is for some common types
-                Class cls = value.getClass();
+                Class<?> cls = value.getClass();
                 if (cls.isPrimitive()
                         || cls == Boolean.class || cls == boolean.class
                         || cls == Integer.class || cls == int.class
@@ -170,13 +164,11 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         return (T) doConvertTo(type, exchange, value, false, false);
     }
 
-    @Override
     public <T> T mandatoryConvertTo(Class<T> type, Object value) throws NoTypeConversionAvailableException {
         return mandatoryConvertTo(type, null, value);
     }
 
     @SuppressWarnings("unchecked")
-    @Override
     public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws NoTypeConversionAvailableException {
         // optimize for a few common conversions
         if (value != null) {
@@ -201,13 +193,13 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
                 }
             } else if (type.isPrimitive()) {
                 // okay its a wrapper -> primitive then return as-is for some common types
-                Class cls = value.getClass();
+                Class<?> cls = value.getClass();
                 if (cls == Integer.class || cls == Long.class) {
                     return (T) value;
                 }
             } else if (type == String.class) {
                 // okay its a primitive -> string then return as-is for some common types
-                Class cls = value.getClass();
+                Class<?> cls = value.getClass();
                 if (cls.isPrimitive()
                         || cls == Boolean.class || cls == boolean.class
                         || cls == Integer.class || cls == int.class
@@ -226,13 +218,11 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         return (T) answer;
     }
 
-    @Override
     public <T> T tryConvertTo(Class<T> type, Object value) {
         return tryConvertTo(type, null, value);
     }
 
     @SuppressWarnings("unchecked")
-    @Override
     public <T> T tryConvertTo(Class<T> type, Exchange exchange, Object value) {
         return (T) doConvertTo(type, exchange, value, false, true);
     }
@@ -260,7 +250,7 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
             // error occurred during type conversion
             throw createTypeConversionException(exchange, type, value, e);
         }
-        if (answer == MISS_VALUE) {
+        if (answer == TypeConverter.MISS_VALUE) {
             // Could not find suitable conversion
             if (statistics.isStatisticsEnabled()) {
                 missCounter.increment();
@@ -391,9 +381,9 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
                 return null;
             }
 
-            if (rc == MISS_VALUE) {
+            if (rc == TypeConverter.MISS_VALUE) {
                 // it cannot be converted so give up
-                return MISS_VALUE;
+                return TypeConverter.MISS_VALUE;
             }
 
             if (rc != null) {
@@ -424,10 +414,13 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         }
 
         // Could not find suitable conversion, so return Void to indicate not found
-        return MISS_VALUE;
+        return TypeConverter.MISS_VALUE;
+    }
+
+    public TypeConverter getTypeConverter(Class<?> toType, Class<?> fromType) {
+        return typeMappings.get(toType, fromType);
     }
 
-    @Override
     public void addTypeConverter(Class<?> toType, Class<?> fromType, TypeConverter typeConverter) {
         LOG.trace("Adding type converter: {}", typeConverter);
         TypeConverter converter = typeMappings.get(toType, fromType);
@@ -460,75 +453,29 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         }
     }
 
-    @Override
-    public void addTypeConverters(TypeConverters typeConverters) {
-        LOG.trace("Adding type converters: {}", typeConverters);
-        try {
-            // scan the class for @Converter and load them into this registry
-            TypeConvertersLoader loader = new TypeConvertersLoader(typeConverters);
-            loader.load(this);
-        } catch (TypeConverterLoaderException e) {
-            throw RuntimeCamelException.wrapRuntimeCamelException(e);
-        }
-    }
-
-    @Override
     public boolean removeTypeConverter(Class<?> toType, Class<?> fromType) {
         LOG.trace("Removing type converter from: {} to: {}", fromType, toType);
         return typeMappings.remove(toType, fromType);
     }
 
     @Override
+    public void addTypeConverters(TypeConverters typeConverters) {
+        throw new UnsupportedOperationException();
+    }
+
     public void addFallbackTypeConverter(TypeConverter typeConverter, boolean canPromote) {
         LOG.trace("Adding fallback type converter: {} which can promote: {}", typeConverter, canPromote);
 
         // add in top of fallback as the toString() fallback will nearly always be able to convert
         // the last one which is add to the FallbackTypeConverter will be called at the first place
         fallbackConverters.add(0, new FallbackTypeConverter(typeConverter, canPromote));
-
-        if (typeConverter instanceof CamelContextAware) {
-            CamelContextAware camelContextAware = (CamelContextAware) typeConverter;
-            if (camelContext != null) {
-                camelContextAware.setCamelContext(camelContext);
-            }
-        }
-    }
-
-    private void addCoreFallbackTypeConverterToList(TypeConverter typeConverter, boolean canPromote, List<
-            FallbackTypeConverter> converters) {
-        LOG.trace("Adding core fallback type converter: {} which can promote: {}", typeConverter, canPromote);
-
-        // add in top of fallback as the toString() fallback will nearly always be able to convert
-        // the last one which is add to the FallbackTypeConverter will be called at the first place
-        converters.add(0, new FallbackTypeConverter(typeConverter, canPromote));
-
-        if (typeConverter instanceof CamelContextAware) {
-            CamelContextAware camelContextAware = (CamelContextAware) typeConverter;
-            if (camelContext != null) {
-                camelContextAware.setCamelContext(camelContext);
-            }
-        }
-    }
-
-    public TypeConverter getTypeConverter(Class<?> toType, Class<?> fromType) {
-        return typeMappings.get(toType, fromType);
-    }
-
-    @Override
-    public Injector getInjector() {
-        return injector;
-    }
-
-    @Override
-    public void setInjector(Injector injector) {
-        this.injector = injector;
     }
 
-    public PackageScanClassResolver getResolver() {
-        return resolver;
+    public TypeConverter lookup(Class<?> toType, Class<?> fromType) {
+        return doLookup(toType, fromType, false);
     }
 
-    protected <T> TypeConverter getOrFindTypeConverter(Class<?> toType, Class<?> fromType) {
+    protected TypeConverter getOrFindTypeConverter(Class<?> toType, Class<?> fromType) {
         TypeConverter converter = typeMappings.get(toType, fromType);
         if (converter == null) {
             // converter not found, try to lookup then
@@ -540,11 +487,6 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         return converter;
     }
 
-    @Override
-    public TypeConverter lookup(Class<?> toType, Class<?> fromType) {
-        return doLookup(toType, fromType, false);
-    }
-
     protected TypeConverter doLookup(Class<?> toType, Class<?> fromType, boolean isSuper) {
 
         if (fromType != null) {
@@ -578,9 +520,9 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
 
                 // lets try classes derived from this toType
                 TypeConverter converter = typeMappings.getFirst(
-                    toType::isAssignableFrom,
-                    // skip Object based we do them last
-                    from -> !from.equals(Object.class) && from.isAssignableFrom(fromType));
+                        toType::isAssignableFrom,
+                        // skip Object based we do them last
+                        from -> !from.equals(Object.class) && from.isAssignableFrom(fromType));
                 if (converter != null) {
                     return converter;
                 }
@@ -597,146 +539,12 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         return null;
     }
 
-    @Override
     public List<Class<?>[]> listAllTypeConvertersFromTo() {
         List<Class<?>[]> answer = new ArrayList<>();
         typeMappings.forEach((k1, k2, v) -> answer.add(new Class<?>[]{k2, k1}));
         return answer;
     }
 
-    /**
-     * Loads the core type converters which is mandatory to use Camel,
-     * and also loads the fast type converters (generated via @Converter(loader = true).
-     */
-    public void loadCoreAndFastTypeConverters() throws Exception {
-        Collection<String> names = findTypeConverterLoaderClasses();
-        for (String name : names) {
-            LOG.debug("Resolving TypeConverterLoader: {}", name);
-            Class clazz = null;
-            for (ClassLoader loader : getResolver().getClassLoaders()) {
-                try {
-                    clazz = loader.loadClass(name);
-                } catch (Throwable e) {
-                    // ignore
-                }
-                if (clazz != null) {
-                    break;
-                }
-            }
-            if (clazz == null) {
-                throw new ClassNotFoundException(name);
-            }
-            Object obj = getInjector().newInstance(clazz, false);
-            if (obj instanceof TypeConverterLoader) {
-                TypeConverterLoader loader = (TypeConverterLoader) obj;
-                LOG.debug("TypeConverterLoader: {} loading converters", name);
-                loader.load(this);
-            }
-        }
-    }
-
-    /**
-     * Finds the type converter loader classes from the classpath looking
-     * for text files on the classpath at the {@link #META_INF_SERVICES_TYPE_CONVERTER_LOADER} location.
-     */
-    protected Collection<String> findTypeConverterLoaderClasses() throws IOException {
-        Set<String> loaders = new LinkedHashSet<>();
-        Collection<URL> loaderResources = getLoaderUrls();
-        for (URL url : loaderResources) {
-            LOG.debug("Loading file {} to retrieve list of type converters, from url: {}", META_INF_SERVICES_TYPE_CONVERTER_LOADER, url);
-            BufferedReader reader = IOHelper.buffered(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8));
-            String line;
-            do {
-                line = reader.readLine();
-                if (line != null && !line.startsWith("#") && !line.isEmpty()) {
-                    loaders.add(line);
-                }
-            } while (line != null);
-            IOHelper.close(reader);
-        }
-        return loaders;
-    }
-
-    protected Collection<URL> getLoaderUrls() throws IOException {
-        List<URL> loaderResources = new ArrayList<>();
-        for (ClassLoader classLoader : resolver.getClassLoaders()) {
-            Enumeration<URL> resources = classLoader.getResources(META_INF_SERVICES_TYPE_CONVERTER_LOADER);
-            while (resources.hasMoreElements()) {
-                URL url = resources.nextElement();
-                loaderResources.add(url);
-            }
-        }
-        return loaderResources;
-    }
-
-    /**
-     * Checks if the registry is loaded and if not lazily load it
-     */
-    protected void loadTypeConverters() throws Exception {
-        for (TypeConverterLoader typeConverterLoader : getTypeConverterLoaders()) {
-            typeConverterLoader.load(this);
-        }
-
-        // lets try load any other fallback converters
-        try {
-            loadFallbackTypeConverters();
-        } catch (NoFactoryAvailableException e) {
-            // ignore its fine to have none
-        }
-    }
-
-    /**
-     * Finds the fallback type converter classes from the classpath looking
-     * for text files on the classpath at the {@link #META_INF_SERVICES_FALLBACK_TYPE_CONVERTER} location.
-     */
-    protected Collection<String> findFallbackTypeConverterClasses() throws IOException {
-        Set<String> loaders = new LinkedHashSet<>();
-        Collection<URL> loaderResources = getFallbackUrls();
-        for (URL url : loaderResources) {
-            LOG.debug("Loading file {} to retrieve list of fallback type converters, from url: {}", META_INF_SERVICES_FALLBACK_TYPE_CONVERTER, url);
-            BufferedReader reader = IOHelper.buffered(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8));
-            try {
-                reader.lines()
-                        .map(String::trim)
-                        .filter(l -> !l.isEmpty())
-                        .filter(l -> !l.startsWith("#"))
-                        .forEach(loaders::add);
-            } finally {
-                IOHelper.close(reader, url.toString(), LOG);
-            }
-        }
-        return loaders;
-    }
-
-    protected Collection<URL> getFallbackUrls() throws IOException {
-        List<URL> loaderResources = new ArrayList<>();
-        for (ClassLoader classLoader : resolver.getClassLoaders()) {
-            Enumeration<URL> resources = classLoader.getResources(META_INF_SERVICES_FALLBACK_TYPE_CONVERTER);
-            while (resources.hasMoreElements()) {
-                URL url = resources.nextElement();
-                loaderResources.add(url);
-            }
-        }
-        return loaderResources;
-    }
-
-    protected void loadFallbackTypeConverters() throws IOException, ClassNotFoundException {
-        Collection<String> names = findFallbackTypeConverterClasses();
-        for (String name : names) {
-            LOG.debug("Resolving FallbackTypeConverter: {}", name);
-            Class clazz = getResolver().getClassLoaders().stream()
-                    .map(cl -> ObjectHelper.loadClass(name, cl))
-                    .filter(Objects::nonNull)
-                    .findAny().orElseThrow(() -> new ClassNotFoundException(name));
-            Object obj = getInjector().newInstance(clazz, false);
-            if (obj instanceof TypeConverter) {
-                TypeConverter fb = (TypeConverter) obj;
-                LOG.debug("Adding loaded FallbackTypeConverter: {}", name);
-                addFallbackTypeConverter(fb, false);
-            }
-        }
-    }
-
     protected TypeConversionException createTypeConversionException(Exchange exchange, Class<?> type, Object
             value, Throwable cause) {
         if (cause instanceof TypeConversionException) {
@@ -755,69 +563,33 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         return new TypeConversionException(body, type, cause);
     }
 
-    @Override
     public Statistics getStatistics() {
         return statistics;
     }
 
-    @Override
     public int size() {
         return typeMappings.size();
     }
 
-    @Override
     public LoggingLevel getTypeConverterExistsLoggingLevel() {
         return typeConverterExistsLoggingLevel;
     }
 
-    @Override
     public void setTypeConverterExistsLoggingLevel(LoggingLevel typeConverterExistsLoggingLevel) {
         this.typeConverterExistsLoggingLevel = typeConverterExistsLoggingLevel;
     }
 
-    @Override
     public TypeConverterExists getTypeConverterExists() {
         return typeConverterExists;
     }
 
-    @Override
     public void setTypeConverterExists(TypeConverterExists typeConverterExists) {
         this.typeConverterExists = typeConverterExists;
     }
 
-    @Override
-    protected void doInit() {
-        if (injector == null && camelContext != null) {
-            injector = camelContext.getInjector();
-        }
-        if (resolver == null && camelContext != null) {
-            resolver = camelContext.adapt(ExtendedCamelContext.class).getPackageScanClassResolver();
-        }
-
-        List<FallbackTypeConverter> fallbacks = new ArrayList<>();
-        // add to string first as it will then be last in the last as to string can nearly
-        // always convert something to a string so we want it only as the last resort
-        // ToStringTypeConverter should NOT allow to be promoted
-        addCoreFallbackTypeConverterToList(new ToStringTypeConverter(), false, fallbacks);
-        // enum is okay to be promoted
-        addCoreFallbackTypeConverterToList(new EnumTypeConverter(), true, fallbacks);
-        // arrays is okay to be promoted
-        addCoreFallbackTypeConverterToList(new ArrayTypeConverter(), true, fallbacks);
-        // and future should also not allowed to be promoted
-        addCoreFallbackTypeConverterToList(new FutureTypeConverter(this), false, fallbacks);
-        // add sync processor to async processor converter is to be promoted
-        addCoreFallbackTypeConverterToList(new AsyncProcessorTypeConverter(), true, fallbacks);
-
-        // add all core fallback converters at once which is faster (profiler)
-        fallbackConverters.addAll(fallbacks);
-    }
-
-    @Override
     protected void doStart() throws Exception {
-        // noop
     }
 
-    @Override
     protected void doStop() throws Exception {
         // log utilization statistics when stopping, including mappings
         if (statistics.isStatisticsEnabled()) {
@@ -897,7 +669,7 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
     /**
      * Represents a fallback type converter
      */
-    protected static class FallbackTypeConverter {
+    public static class FallbackTypeConverter {
         private final boolean canPromote;
         private final TypeConverter fallbackTypeConverter;
 
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
index 086af3c..bc8a6a2 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
@@ -51,11 +51,6 @@ public class DefaultTypeConverter extends BaseTypeConverterRegistry implements A
     }
 
     @Override
-    public boolean allowNull() {
-        return false;
-    }
-
-    @Override
     public boolean isRunAllowed() {
         // as type converter is used during initialization then allow it to always run
         return true;
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 868bf2d..b32bbc6 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -64,6 +64,7 @@ import org.apache.camel.Processor;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.ResolveEndpointFailedException;
 import org.apache.camel.Route;
+import org.apache.camel.RouteAware;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.Service;
@@ -155,15 +156,14 @@ import org.apache.camel.support.NormalizedUri;
 import org.apache.camel.support.OrderedComparator;
 import org.apache.camel.support.ProcessorEndpoint;
 import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.support.service.BaseService;
 import org.apache.camel.support.service.ServiceHelper;
-import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StopWatch;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.TimeUtils;
 import org.apache.camel.util.URISupport;
-import org.apache.camel.util.function.ThrowingRunnable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
@@ -173,7 +173,7 @@ import static org.apache.camel.spi.UnitOfWork.MDC_CAMEL_CONTEXT_ID;
 /**
  * Represents the context used to configure routes and the policies to use.
  */
-public abstract class AbstractCamelContext extends ServiceSupport
+public abstract class AbstractCamelContext extends BaseService
         implements ExtendedCamelContext, CatalogCamelContext, Suspendable {
 
     private static final Logger LOG = LoggerFactory.getLogger(AbstractCamelContext.class);
@@ -346,6 +346,20 @@ public abstract class AbstractCamelContext extends ServiceSupport
         }
     }
 
+    public void close() throws IOException {
+        try {
+            stop();
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
+
+    public CamelContext getCamelContextReference() {
+        return this;
+    }
+
     /**
      * Whether to eager create {@link TypeConverter} during initialization of CamelContext.
      * This is enabled by default to optimize camel-core.
@@ -355,28 +369,6 @@ public abstract class AbstractCamelContext extends ServiceSupport
     }
 
     @Override
-    public void doInit() throws Exception {
-        // Initialize LRUCacheFactory as eager as possible, 
-        // to let it warm up concurrently while Camel is startup up
-        if (initialization != Initialization.Lazy) {
-            LRUCacheFactory.init();
-        }
-
-        // Setup management first since end users may use it to add event
-        // notifiers using the management strategy before the CamelContext has been started
-        setupManagement(null);
-
-        // Call all registered trackers with this context
-        // Note, this may use a partially constructed object
-        CamelContextTracker.notifyContextCreated(this);
-        
-        // Setup type converter eager as its highly in use and should not be lazy initialized
-        if (eagerCreateTypeConverter()) {
-            getOrCreateTypeConverter();
-        }
-    }
-
-    @Override
     public <T extends CamelContext> T adapt(Class<T> type) {
         return type.cast(this);
     }
@@ -486,7 +478,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
     @Override
     public void addComponent(String componentName, final Component component) {
         ObjectHelper.notNull(component, "component");
-        component.setCamelContext(this);
+        component.setCamelContext(getCamelContextReference());
         ServiceHelper.initService(component);
         Component oldValue = components.putIfAbsent(componentName, component);
         if (oldValue != null) {
@@ -599,9 +591,9 @@ public abstract class AbstractCamelContext extends ServiceSupport
                 // See https://issues.apache.org/jira/browse/CAMEL-11225
                 componentsInCreation.get().add(name);
 
-                component = getComponentResolver().resolveComponent(name, this);
+                component = getComponentResolver().resolveComponent(name, getCamelContextReference());
                 if (component != null) {
-                    component.setCamelContext(this);
+                    component.setCamelContext(getCamelContextReference());
                     ServiceHelper.initService(component);
                     postInitComponent(name, component);
                 }
@@ -758,7 +750,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
     public NormalizedEndpointUri normalizeUri(String uri) {
         try {
             uri = resolvePropertyPlaceholders(uri);
-            uri = normalizeEndpointUri(uri);
+            uri = URISupport.normalizeUri(uri);
             return new NormalizedUri(uri);
         } catch (Exception e) {
             throw new ResolveEndpointFailedException(uri, e);
@@ -808,7 +800,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
         // normalize uri so we can do endpoint hits with minor mistakes and
         // parameters is not in the same order
         if (!normalized) {
-            uri = normalizeEndpointUri(uri);
+            uri = EndpointHelper.normalizeEndpointUri(uri);
         }
 
         LOG.trace("Getting endpoint with raw uri: {}, normalized uri: {}", rawUri, uri);
@@ -921,7 +913,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
         // normalize uri so we can do endpoint hits with minor mistakes and
         // parameters is not in the same order
         if (!normalized) {
-            uri = normalizeEndpointUri(uri);
+            uri = EndpointHelper.normalizeEndpointUri(uri);
         }
 
         LOG.trace("Getting endpoint with raw uri: {}, normalized uri: {}", rawUri, uri);
@@ -1038,23 +1030,6 @@ public abstract class AbstractCamelContext extends ServiceSupport
     }
 
     /**
-     * Normalize uri so we can do endpoint hits with minor mistakes and
-     * parameters is not in the same order.
-     *
-     * @param uri the uri
-     * @return normalized uri
-     * @throws ResolveEndpointFailedException if uri cannot be normalized
-     */
-    protected static String normalizeEndpointUri(String uri) {
-        try {
-            uri = URISupport.normalizeUri(uri);
-        } catch (Exception e) {
-            throw new ResolveEndpointFailedException(uri, e);
-        }
-        return uri;
-    }
-
-    /**
      * Gets the endpoint key to use for lookup or whe adding endpoints to the
      * {@link DefaultEndpointRegistry}
      *
@@ -1103,8 +1078,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
 
     @Override
     public void setRouteController(RouteController routeController) {
-        this.routeController = routeController;
-        doAddService(routeController);
+        this.routeController = doAddService(routeController);
     }
 
     @Override
@@ -1195,10 +1169,11 @@ public abstract class AbstractCamelContext extends ServiceSupport
         if (isStarted() && !isAllowAddingNewRoutes()) {
             throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed");
         }
-
-        init();
-        LOG.debug("Adding routes from builder: {}", builder);
-        doWithDefinedClassLoader(() -> builder.addRoutesToCamelContext(AbstractCamelContext.this));
+        try (LifecycleHelper helper = new LifecycleHelper()) {
+            init();
+            LOG.debug("Adding routes from builder: {}", builder);
+            builder.addRoutesToCamelContext(AbstractCamelContext.this);
+        }
     }
 
     public ServiceStatus getRouteStatus(String key) {
@@ -1460,7 +1435,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
         // inject CamelContext
         if (object instanceof CamelContextAware) {
             CamelContextAware aware = (CamelContextAware)object;
-            aware.setCamelContext(this);
+            aware.setCamelContext(getCamelContextReference());
         }
 
         if (object instanceof Service) {
@@ -1472,7 +1447,12 @@ public abstract class AbstractCamelContext extends ServiceSupport
                         // use specialized endpoint add
                         strategy.onEndpointAdd((Endpoint) service);
                     } else {
-                        Route route = setupRoute.get();
+                        Route route;
+                        if (service instanceof RouteAware) {
+                            route = ((RouteAware)service).getRoute();
+                        } else {
+                            route = setupRoute.get();
+                        }
                         strategy.onServiceAdd(this, service, route);
                     }
                 }
@@ -1590,6 +1570,10 @@ public abstract class AbstractCamelContext extends ServiceSupport
         }
     }
 
+    protected List<StartupListener> getStartupListeners() {
+        return startupListeners;
+    }
+
     @Override
     public void addStartupListener(StartupListener listener) throws Exception {
         // either add to listener so we can invoke then later when CamelContext
@@ -1733,12 +1717,12 @@ public abstract class AbstractCamelContext extends ServiceSupport
             }
 
             // language not known or not singleton, then use resolver
-            answer = getLanguageResolver().resolveLanguage(language, this);
+            answer = getLanguageResolver().resolveLanguage(language, getCamelContextReference());
 
             // inject CamelContext if aware
             if (answer != null) {
                 if (answer instanceof CamelContextAware) {
-                    ((CamelContextAware)answer).setCamelContext(this);
+                    ((CamelContextAware)answer).setCamelContext(getCamelContextReference());
                 }
                 if (answer instanceof Service) {
                     try {
@@ -1979,7 +1963,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
     @Override
     public void setRegistry(Registry registry) {
         if (registry instanceof CamelContextAware) {
-            ((CamelContextAware)registry).setCamelContext(this);
+            ((CamelContextAware)registry).setCamelContext(getCamelContextReference());
         }
         this.registry = registry;
     }
@@ -2175,7 +2159,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
 
     @Override
     public ProducerTemplate createProducerTemplate(int maximumCacheSize) {
-        DefaultProducerTemplate answer = new DefaultProducerTemplate(this);
+        DefaultProducerTemplate answer = new DefaultProducerTemplate(getCamelContextReference());
         answer.setMaximumCacheSize(maximumCacheSize);
         // start it so its ready to use
         try {
@@ -2193,7 +2177,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
 
     @Override
     public FluentProducerTemplate createFluentProducerTemplate(int maximumCacheSize) {
-        DefaultFluentProducerTemplate answer = new DefaultFluentProducerTemplate(this);
+        DefaultFluentProducerTemplate answer = new DefaultFluentProducerTemplate(getCamelContextReference());
         answer.setMaximumCacheSize(maximumCacheSize);
         // start it so its ready to use
         try {
@@ -2211,7 +2195,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
 
     @Override
     public ConsumerTemplate createConsumerTemplate(int maximumCacheSize) {
-        DefaultConsumerTemplate answer = new DefaultConsumerTemplate(this);
+        DefaultConsumerTemplate answer = new DefaultConsumerTemplate(getCamelContextReference());
         answer.setMaximumCacheSize(maximumCacheSize);
         // start it so its ready to use
         try {
@@ -2451,181 +2435,144 @@ public abstract class AbstractCamelContext extends ServiceSupport
         }
     }
 
+    // Implementation methods
+    // -----------------------------------------------------------------------
+
     @Override
-    public void start() {
-        startDate = new Date();
-        try (MDCHelper mdcHelper = new MDCHelper()) {
-            init();
-            vetoStarted.set(false);
-            stopWatch.restart();
-            LOG.info("Apache Camel {} (CamelContext: {}) is starting", getVersion(), getName());
+    protected AutoCloseable doLifecycleChange() {
+        return new LifecycleHelper();
+    }
 
-            // Start the route controller
-            ServiceHelper.startService(this.routeController);
+    @Override
+    public void doInit() throws Exception {
+        // Initialize LRUCacheFactory as eager as possible,
+        // to let it warm up concurrently while Camel is startup up
+        if (initialization != Initialization.Lazy) {
+            LRUCacheFactory.init();
+        }
 
-            doNotStartRoutesOnFirstStart = !firstStartDone && !isAutoStartup();
+        // Setup management first since end users may use it to add event
+        // notifiers using the management strategy before the CamelContext has been started
+        setupManagement(null);
 
-            // optimize - before starting routes lets check if event notifications is possible
-            eventNotificationApplicable = EventHelper.eventsApplicable(this);
+        // Call all registered trackers with this context
+        // Note, this may use a partially constructed object
+        CamelContextTracker.notifyContextCreated(this);
 
-            // if the context was configured with auto startup = false, and we
-            // are already started,
-            // then we may need to start the routes on the 2nd start call
-            if (firstStartDone && !isAutoStartup() && isStarted()) {
-                // invoke this logic to warm up the routes and if possible also
-                // start the routes
-                try {
-                    doStartOrResumeRoutes(routeServices, true, true, false, true);
-                } catch (Exception e) {
-                    throw RuntimeCamelException.wrapRuntimeException(e);
-                }
-            }
+        // Setup type converter eager as its highly in use and should not be lazy initialized
+        if (eagerCreateTypeConverter()) {
+            getOrCreateTypeConverter();
+        }
+    }
 
-            // super will invoke doStart which will prepare internal services
-            // and start routes etc.
-            try {
-                firstStartDone = true;
-                super.start();
-            } catch (Exception e) {
-                VetoCamelContextStartException veto = ObjectHelper.getException(VetoCamelContextStartException.class, e);
-                if (veto != null) {
-                    // mark we veto against starting Camel
-                    vetoStarted.set(true);
-                    if (veto.isRethrowException()) {
-                        throw e;
-                    } else {
-                        LOG.info("CamelContext ({}) vetoed to not start due {}", getName(), e.getMessage());
-                        // swallow exception and change state of this camel context
-                        // to stopped
-                        stop();
-                        return;
-                    }
-                } else {
-                    LOG.error("Error starting CamelContext (" + getName() + ") due to exception thrown: " + e.getMessage(), e);
-                    throw RuntimeCamelException.wrapRuntimeException(e);
-                }
-            }
+    @Override
+    protected synchronized void doStart() throws Exception {
+        try {
+            doStartContext();
+        } catch (Exception e) {
+            // fire event that we failed to start
+            EventHelper.notifyCamelContextStartupFailed(AbstractCamelContext.this, e);
+            // rethrow cause
+            throw e;
+        }
+    }
 
-            if (!isAllowAddingNewRoutes()) {
-                LOG.info("Adding new routes after CamelContext has started is not allowed");
-                disallowAddingNewRoutes();
-            }
+    protected void doStartContext() throws Exception {
+        startDate = new Date();
 
-            if (isClearModelReferences()) {
-                LOG.info("Clearing model references");
-                clearModelReferences();
-            }
+        vetoStarted.set(false);
+        stopWatch.restart();
+        LOG.info("Apache Camel {} (CamelContext: {}) is starting", getVersion(), getName());
 
-            if (LOG.isInfoEnabled()) {
-                // count how many routes are actually started
-                int started = 0;
-                for (Route route : getRoutes()) {
-                    ServiceStatus status = getRouteStatus(route.getId());
-                    if (status != null && status.isStarted()) {
-                        started++;
-                    }
-                }
+        // Start the route controller
+        ServiceHelper.startService(this.routeController);
 
-                final Collection<Route> controlledRoutes = getRouteController().getControlledRoutes();
-                if (controlledRoutes.isEmpty()) {
-                    LOG.info("Total {} routes, of which {} are started", getRoutes().size(), started);
-                } else {
-                    LOG.info("Total {} routes, of which {} are started, and {} are managed by RouteController: {}", getRoutes().size(), started, controlledRoutes.size(),
-                             getRouteController().getClass().getName());
-                }
-                LOG.info("Apache Camel {} (CamelContext: {}) started in {}", getVersion(), getName(), TimeUtils.printDuration(stopWatch.taken()));
-            }
+        doNotStartRoutesOnFirstStart = !firstStartDone && !isAutoStartup();
 
-            // okay the routes has been started so emit event that CamelContext
-            // has started (here at the end)
-            EventHelper.notifyCamelContextStarted(this);
+        // optimize - before starting routes lets check if event notifications is possible
+        eventNotificationApplicable = EventHelper.eventsApplicable(this);
 
-            // now call the startup listeners where the routes has been started
-            for (StartupListener startup : startupListeners) {
-                if (startup instanceof ExtendedStartupListener) {
-                    try {
-                        ((ExtendedStartupListener)startup).onCamelContextFullyStarted(this, isStarted());
-                    } catch (Exception e) {
-                        throw RuntimeCamelException.wrapRuntimeException(e);
-                    }
-                }
+        // if the context was configured with auto startup = false, and we
+        // are already started,
+        // then we may need to start the routes on the 2nd start call
+        if (firstStartDone && !isAutoStartup() && isStarted()) {
+            // invoke this logic to warm up the routes and if possible also
+            // start the routes
+            try {
+                doStartOrResumeRoutes(routeServices, true, true, false, true);
+            } catch (Exception e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
             }
         }
-    }
-
-    /**
-     * Strategy invoked when adding new routes after CamelContext has been started is not allowed.
-     * This is used to do some internal optimizations.
-     */
-    protected void disallowAddingNewRoutes() {
-        ReifierStrategy.clearReifiers();
-    }
 
-    protected void clearModelReferences() {
-    }
-
-    @Override
-    public void init() {
-        try (MDCHelper mdcHelper = new MDCHelper()) {
-            super.init();
+        // super will invoke doStart which will prepare internal services
+        // and start routes etc.
+        try {
+            firstStartDone = true;
+            doStartCamel();
+        } catch (Exception e) {
+            VetoCamelContextStartException veto = ObjectHelper.getException(VetoCamelContextStartException.class, e);
+            if (veto != null) {
+                // mark we veto against starting Camel
+                vetoStarted.set(true);
+                if (veto.isRethrowException()) {
+                    throw e;
+                } else {
+                    LOG.info("CamelContext ({}) vetoed to not start due {}", getName(), e.getMessage());
+                    // swallow exception and change state of this camel context
+                    // to stopped
+                    stop();
+                    return;
+                }
+            } else {
+                LOG.error("Error starting CamelContext (" + getName() + ") due to exception thrown: " + e.getMessage(), e);
+                throw RuntimeCamelException.wrapRuntimeException(e);
+            }
         }
-    }
 
-    @Override
-    public void stop() {
-        try (MDCHelper mdcHelper = new MDCHelper()) {
-            super.stop();
+        if (!isAllowAddingNewRoutes()) {
+            LOG.info("Adding new routes after CamelContext has started is not allowed");
+            disallowAddingNewRoutes();
         }
-    }
 
-    @Override
-    public void suspend() {
-        try (MDCHelper mdcHelper = new MDCHelper()) {
-            super.suspend();
+        if (isClearModelReferences()) {
+            LOG.info("Clearing model references");
+            clearModelReferences();
         }
-    }
 
-    @Override
-    public void resume() {
-        try (MDCHelper mdcHelper = new MDCHelper()) {
-            super.resume();
-        }
-    }
+        if (LOG.isInfoEnabled()) {
+            // count how many routes are actually started
+            int started = 0;
+            for (Route route : getRoutes()) {
+                ServiceStatus status = getRouteStatus(route.getId());
+                if (status != null && status.isStarted()) {
+                    started++;
+                }
+            }
 
-    @Override
-    public void shutdown() {
-        try (MDCHelper mdcHelper = new MDCHelper()) {
-            super.shutdown();
+            final Collection<Route> controlledRoutes = getRouteController().getControlledRoutes();
+            if (controlledRoutes.isEmpty()) {
+                LOG.info("Total {} routes, of which {} are started", getRoutes().size(), started);
+            } else {
+                LOG.info("Total {} routes, of which {} are started, and {} are managed by RouteController: {}", getRoutes().size(), started, controlledRoutes.size(),
+                        getRouteController().getClass().getName());
+            }
+            LOG.info("Apache Camel {} (CamelContext: {}) started in {}", getVersion(), getName(), TimeUtils.printDuration(stopWatch.taken()));
         }
-    }
 
-    // Implementation methods
-    // -----------------------------------------------------------------------
+        // okay the routes has been started so emit event that CamelContext
+        // has started (here at the end)
+        EventHelper.notifyCamelContextStarted(this);
 
-    @Override
-    protected synchronized void doStart() throws Exception {
-        doWithDefinedClassLoader(() -> {
-            try {
-                doStartCamel();
-            } catch (Exception e) {
-                // fire event that we failed to start
-                EventHelper.notifyCamelContextStartupFailed(AbstractCamelContext.this, e);
-                // rethrow cause
-                throw e;
-            }
-        });
-    }
-
-    private <T extends Throwable> void doWithDefinedClassLoader(ThrowingRunnable<T> callable) throws T {
-        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
-        try {
-            // Using the ApplicationClassLoader as the default for TCCL
-            if (applicationContextClassLoader != null) {
-                Thread.currentThread().setContextClassLoader(applicationContextClassLoader);
+        // now call the startup listeners where the routes has been started
+        for (StartupListener startup : startupListeners) {
+            if (startup instanceof ExtendedStartupListener) {
+                try {
+                    ((ExtendedStartupListener)startup).onCamelContextFullyStarted(this, isStarted());
+                } catch (Exception e) {
+                    throw RuntimeCamelException.wrapRuntimeException(e);
+                }
             }
-            callable.run();
-        } finally {
-            Thread.currentThread().setContextClassLoader(tccl);
         }
     }
 
@@ -2814,16 +2761,6 @@ public abstract class AbstractCamelContext extends ServiceSupport
         // starting will continue in the start method
     }
 
-    protected void startRouteDefinitions() throws Exception {
-    }
-
-    protected boolean isStreamCachingInUse() throws Exception {
-        return isStreamCaching();
-    }
-
-    protected void bindDataFormats() throws Exception {
-    }
-
     @Override
     protected synchronized void doStop() throws Exception {
         stopWatch.restart();
@@ -2956,6 +2893,27 @@ public abstract class AbstractCamelContext extends ServiceSupport
     }
 
     /**
+     * Strategy invoked when adding new routes after CamelContext has been started is not allowed.
+     * This is used to do some internal optimizations.
+     */
+    protected void disallowAddingNewRoutes() {
+        ReifierStrategy.clearReifiers();
+    }
+
+    protected void clearModelReferences() {
+    }
+
+    public void startRouteDefinitions() throws Exception {
+    }
+
+    protected boolean isStreamCachingInUse() throws Exception {
+        return isStreamCaching();
+    }
+
+    protected void bindDataFormats() throws Exception {
+    }
+
+    /**
      * Starts or resumes the routes
      *
      * @param routeServices the routes to start (will only start a route if its
@@ -3059,7 +3017,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
 
         if (service instanceof CamelContextAware) {
             CamelContextAware aware = (CamelContextAware)service;
-            aware.setCamelContext(this);
+            aware.setCamelContext(getCamelContextReference());
         }
 
         service.start();
@@ -3079,7 +3037,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
             ServiceHelper.stopService(service);
         } catch (Exception e) {
             // fire event
-            EventHelper.notifyServiceStopFailure(this, service, e);
+            EventHelper.notifyServiceStopFailure(getCamelContextReference(), service, e);
             // rethrow to signal error with stopping
             throw e;
         }
@@ -3219,7 +3177,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
         // now call the startup listeners where the routes has been warmed up
         // (only the actual route consumer has not yet been started)
         for (StartupListener startup : startupListeners) {
-            startup.onCamelContextStarted(this, isStarted());
+            startup.onCamelContextStarted(getCamelContextReference(), isStarted());
         }
         // because the consumers may also register startup listeners we need to
         // reset
@@ -3246,7 +3204,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
         // StartupListeners (such as timer)
         // so we need to ensure they get started as well
         for (StartupListener startup : startupListeners) {
-            startup.onCamelContextStarted(this, isStarted());
+            startup.onCamelContextStarted(getCamelContextReference(), isStarted());
         }
         // and add the previous started startup listeners to the list so we have
         // them all
@@ -3397,7 +3355,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
                 } else {
                     // when starting we should invoke the lifecycle strategies
                     for (LifecycleStrategy strategy : lifecycleStrategies) {
-                        strategy.onServiceAdd(this, consumer, route);
+                        strategy.onServiceAdd(getCamelContextReference(), consumer, route);
                     }
                     try {
                         startService(consumer);
@@ -3586,7 +3544,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
         if (value instanceof Endpoint) {
             return (Endpoint)value;
         } else if (value instanceof Processor) {
-            return new ProcessorEndpoint(uri, this, (Processor)value);
+            return new ProcessorEndpoint(uri, getCamelContextReference(), (Processor)value);
         } else if (value != null) {
             return convertBeanToEndpoint(uri, value);
         }
@@ -3808,7 +3766,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
         }
 
         try {
-            ManagementStrategy strategy = factory.create(this, options);
+            ManagementStrategy strategy = factory.create(getCamelContextReference(), options);
             if (notifiers != null) {
                 notifiers.forEach(strategy::addEventNotifier);
             }
@@ -3970,11 +3928,11 @@ public abstract class AbstractCamelContext extends ServiceSupport
 
     @Override
     public DataFormat resolveDataFormat(String name) {
-        DataFormat answer = getDataFormatResolver().resolveDataFormat(name, this);
+        DataFormat answer = getDataFormatResolver().resolveDataFormat(name, getCamelContextReference());
 
         // inject CamelContext if aware
         if (answer instanceof CamelContextAware) {
-            ((CamelContextAware)answer).setCamelContext(this);
+            ((CamelContextAware)answer).setCamelContext(getCamelContextReference());
         }
 
         return answer;
@@ -3982,11 +3940,11 @@ public abstract class AbstractCamelContext extends ServiceSupport
 
     @Override
     public DataFormat createDataFormat(String name) {
-        DataFormat answer = getDataFormatResolver().createDataFormat(name, this);
+        DataFormat answer = getDataFormatResolver().createDataFormat(name, getCamelContextReference());
 
         // inject CamelContext if aware
         if (answer instanceof CamelContextAware) {
-            ((CamelContextAware)answer).setCamelContext(this);
+            ((CamelContextAware)answer).setCamelContext(getCamelContextReference());
         }
 
         return answer;
@@ -4424,10 +4382,16 @@ public abstract class AbstractCamelContext extends ServiceSupport
         return "CamelContext(" + getName() + ")";
     }
 
-    class MDCHelper implements AutoCloseable {
+    class LifecycleHelper implements AutoCloseable {
         final Map<String, String> originalContextMap;
+        final ClassLoader tccl;
 
-        MDCHelper() {
+        LifecycleHelper() {
+            // Using the ApplicationClassLoader as the default for TCCL
+            tccl = Thread.currentThread().getContextClassLoader();
+            if (applicationContextClassLoader != null) {
+                Thread.currentThread().setContextClassLoader(applicationContextClassLoader);
+            }
             if (isUseMDCLogging()) {
                 originalContextMap = MDC.getCopyOfContextMap();
                 MDC.put(MDC_CAMEL_CONTEXT_ID, getName());
@@ -4445,6 +4409,7 @@ public abstract class AbstractCamelContext extends ServiceSupport
                     MDC.clear();
                 }
             }
+            Thread.currentThread().setContextClassLoader(tccl);
         }
     }
 
@@ -4532,4 +4497,83 @@ public abstract class AbstractCamelContext extends ServiceSupport
 
     protected abstract ValidatorRegistry<ValidatorKey> createValidatorRegistry();
 
+    @Override
+    public RouteController getInternalRouteController() {
+        return new RouteController() {
+            @Override
+            public Collection<Route> getControlledRoutes() {
+                return AbstractCamelContext.this.getRoutes();
+            }
+
+            @Override
+            public void startAllRoutes() throws Exception {
+                AbstractCamelContext.this.startAllRoutes();
+            }
+
+            @Override
+            public boolean isStartingRoutes() {
+                return AbstractCamelContext.this.isStartingRoutes();
+            }
+
+            @Override
+            public ServiceStatus getRouteStatus(String routeId) {
+                return AbstractCamelContext.this.getRouteStatus(routeId);
+            }
+
+            @Override
+            public void startRoute(String routeId) throws Exception {
+                AbstractCamelContext.this.startRoute(routeId);
+            }
+
+            @Override
+            public void stopRoute(String routeId) throws Exception {
+                AbstractCamelContext.this.stopRoute(routeId);
+            }
+
+            @Override
+            public void stopRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
+                AbstractCamelContext.this.stopRoute(routeId, timeout, timeUnit);
+            }
+
+            @Override
+            public boolean stopRoute(String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception {
+                return AbstractCamelContext.this.stopRoute(routeId, timeout, timeUnit, abortAfterTimeout);
+            }
+
+            @Override
+            public void suspendRoute(String routeId) throws Exception {
+                AbstractCamelContext.this.suspendRoute(routeId);
+            }
+
+            @Override
+            public void suspendRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
+                AbstractCamelContext.this.suspendRoute(routeId, timeout, timeUnit);
+            }
+
+            @Override
+            public void resumeRoute(String routeId) throws Exception {
+                AbstractCamelContext.this.resumeRoute(routeId);
+            }
+
+            @Override
+            public void setCamelContext(CamelContext camelContext) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public CamelContext getCamelContext() {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public void start() {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public void stop() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
index 6b610f1..11d4eba 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
@@ -21,19 +21,20 @@ import java.util.Collections;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.Route;
 import org.apache.camel.ServiceStatus;
 import org.apache.camel.spi.RouteController;
 import org.apache.camel.support.service.ServiceSupport;
 
 public class DefaultRouteController extends ServiceSupport implements RouteController  {
-    private AbstractCamelContext camelContext;
+    private CamelContext camelContext;
 
     public DefaultRouteController() {
         this(null);
     }
 
-    public DefaultRouteController(AbstractCamelContext camelContext) {
+    public DefaultRouteController(CamelContext camelContext) {
         this.camelContext = camelContext;
     }
 
@@ -43,7 +44,7 @@ public class DefaultRouteController extends ServiceSupport implements RouteContr
 
     @Override
     public void setCamelContext(CamelContext camelContext) {
-        this.camelContext = (AbstractCamelContext) camelContext;
+        this.camelContext = camelContext;
     }
 
     @Override
@@ -69,54 +70,58 @@ public class DefaultRouteController extends ServiceSupport implements RouteContr
     // Route management
     // ***************************************************
 
+    protected RouteController getInternalRouteController() {
+        return camelContext.adapt(ExtendedCamelContext.class).getInternalRouteController();
+    }
+
     @Override
     public void startAllRoutes() throws Exception {
-        camelContext.startAllRoutes();
+        getInternalRouteController().startAllRoutes();
     }
 
     @Override
     public boolean isStartingRoutes() {
-        return camelContext.isStartingRoutes();
+        return getInternalRouteController().isStartingRoutes();
     }
 
     @Override
     public ServiceStatus getRouteStatus(String routeId) {
-        return camelContext.getRouteStatus(routeId);
+        return getInternalRouteController().getRouteStatus(routeId);
     }
 
     @Override
     public void startRoute(String routeId) throws Exception {
-        camelContext.startRoute(routeId);
+        getInternalRouteController().startRoute(routeId);
     }
 
     @Override
     public void stopRoute(String routeId) throws Exception {
-        camelContext.stopRoute(routeId);
+        getInternalRouteController().stopRoute(routeId);
     }
 
     @Override
     public void stopRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
-        camelContext.stopRoute(routeId, timeout, timeUnit);
+        getInternalRouteController().stopRoute(routeId, timeout, timeUnit);
     }
 
     @Override
     public boolean stopRoute(String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception {
-        return camelContext.stopRoute(routeId, timeout, timeUnit, abortAfterTimeout);
+        return getInternalRouteController().stopRoute(routeId, timeout, timeUnit, abortAfterTimeout);
     }
 
     @Override
     public void suspendRoute(String routeId) throws Exception {
-        camelContext.suspendRoute(routeId);
+        getInternalRouteController().suspendRoute(routeId);
     }
 
     @Override
     public void suspendRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
-        camelContext.suspendRoute(routeId, timeout, timeUnit);
+        getInternalRouteController().suspendRoute(routeId, timeout, timeUnit);
     }
 
     @Override
     public void resumeRoute(String routeId) throws Exception {
-        camelContext.resumeRoute(routeId);
+        getInternalRouteController().resumeRoute(routeId);
     }
 
     // ***************************************************
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/EndpointKey.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/EndpointKey.java
index 46be51c..0082110 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/EndpointKey.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/EndpointKey.java
@@ -18,6 +18,7 @@ package org.apache.camel.impl.engine;
 
 import org.apache.camel.ValueHolder;
 import org.apache.camel.spi.NormalizedEndpointUri;
+import org.apache.camel.support.EndpointHelper;
 import org.apache.camel.util.StringHelper;
 
 /**
@@ -34,7 +35,7 @@ public final class EndpointKey extends ValueHolder<String> implements Normalized
      * Optimized when the uri is already normalized.
      */
     public EndpointKey(String uri, boolean normalized) {
-        super(normalized ? uri : AbstractCamelContext.normalizeEndpointUri(uri));
+        super(normalized ? uri : EndpointHelper.normalizeEndpointUri(uri));
         StringHelper.notEmpty(uri, "uri");
     }
 
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/RouteService.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/RouteService.java
index d67ab7e..8483ab8 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/RouteService.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/RouteService.java
@@ -32,6 +32,7 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Endpoint;
 import org.apache.camel.EndpointAware;
 import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.FailedToStartRouteException;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
@@ -56,7 +57,7 @@ import static org.apache.camel.spi.UnitOfWork.MDC_ROUTE_ID;
  */
 public class RouteService extends ChildServiceSupport {
 
-    private final AbstractCamelContext camelContext;
+    private final CamelContext camelContext;
     private final Route route;
     private boolean removingRoutes;
     private final Map<Route, Consumer> inputs = new HashMap<>();
@@ -65,7 +66,7 @@ public class RouteService extends ChildServiceSupport {
 
     public RouteService(Route route) {
         this.route = route;
-        this.camelContext = this.route.getCamelContext().adapt(AbstractCamelContext.class);
+        this.camelContext = this.route.getCamelContext();
     }
 
     public String getId() {
@@ -192,7 +193,7 @@ public class RouteService extends ChildServiceSupport {
             }
 
             // add routes to camel context
-            camelContext.addRoute(route);
+            camelContext.adapt(ExtendedCamelContext.class).addRoute(route);
 
             // add the routes to the inflight registry so they are pre-installed
             camelContext.getInflightRepository().addRoute(route.getId());
@@ -253,7 +254,7 @@ public class RouteService extends ChildServiceSupport {
             EventHelper.notifyRouteStopped(camelContext, route);
         }
         if (isRemovingRoutes()) {
-            camelContext.removeRoute(route);
+            camelContext.adapt(ExtendedCamelContext.class).removeRoute(route);
         }
         // need to warm up again
         warmUpDone.set(false);
@@ -291,7 +292,7 @@ public class RouteService extends ChildServiceSupport {
         camelContext.getInflightRepository().removeRoute(route.getId());
 
         // remove the routes from the collections
-        camelContext.removeRoute(route);
+        camelContext.adapt(ExtendedCamelContext.class).removeRoute(route);
 
         // clear inputs on shutdown
         inputs.clear();
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index 1b9beac..db8eed0 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -114,7 +114,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected TypeConverter createTypeConverter() {
-        return new DefaultTypeConverter(this, getPackageScanClassResolver(), getInjector(),
+        return new DefaultTypeConverter(getCamelContextReference(), getPackageScanClassResolver(), getInjector(),
                 getDefaultFactoryFinder(), isLoadTypeConverters());
     }
 
@@ -134,19 +134,19 @@ public class SimpleCamelContext extends AbstractCamelContext {
     @Override
     protected Injector createInjector() {
         FactoryFinder finder = getDefaultFactoryFinder();
-        return finder.newInstance("Injector", Injector.class).orElse(new DefaultInjector(this));
+        return finder.newInstance("Injector", Injector.class).orElse(new DefaultInjector(getCamelContextReference()));
     }
 
     @Override
     protected PropertiesComponent createPropertiesComponent() {
         return new BaseServiceResolver<>(PropertiesComponent.FACTORY, PropertiesComponent.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseGet(org.apache.camel.component.properties.PropertiesComponent::new);
     }
 
     @Override
     protected CamelBeanPostProcessor createBeanPostProcessor() {
-        return new DefaultCamelBeanPostProcessor(this);
+        return new DefaultCamelBeanPostProcessor(getCamelContextReference());
     }
 
     @Override
@@ -167,7 +167,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
     @Override
     protected ModelJAXBContextFactory createModelJAXBContextFactory() {
         return new BaseServiceResolver<>(ModelJAXBContextFactory.FACTORY, ModelJAXBContextFactory.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseThrow(() -> new IllegalArgumentException("Cannot find ModelJAXBContextFactory on classpath. "
                         + "Add camel-xml-jaxb to classpath."));
     }
@@ -184,7 +184,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected ClassResolver createClassResolver() {
-        return new DefaultClassResolver(this);
+        return new DefaultClassResolver(getCamelContextReference());
     }
 
     @Override
@@ -214,12 +214,13 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected RouteController createRouteController() {
-        return new DefaultRouteController(this);
+        // TODO:
+        return new DefaultRouteController(getCamelContextReference());
     }
 
     @Override
     protected ShutdownStrategy createShutdownStrategy() {
-        return new DefaultShutdownStrategy(this);
+        return new DefaultShutdownStrategy(getCamelContextReference());
     }
 
     @Override
@@ -248,7 +249,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
     @Override
     protected RuntimeCamelCatalog createRuntimeCamelCatalog() {
         return new BaseServiceResolver<>(RuntimeCamelCatalog.FACTORY, RuntimeCamelCatalog.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseThrow(() -> new IllegalArgumentException("Cannot find RuntimeCamelCatalog on classpath. "
                         + "Add camel-core-catalog to classpath."));
     }
@@ -260,20 +261,20 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected ManagementNameStrategy createManagementNameStrategy() {
-        return new DefaultManagementNameStrategy(this);
+        return new DefaultManagementNameStrategy(getCamelContextReference());
     }
 
     @Override
     protected HeadersMapFactory createHeadersMapFactory() {
         return new BaseServiceResolver<>(HeadersMapFactory.FACTORY, HeadersMapFactory.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseGet(DefaultHeadersMapFactory::new);
     }
 
     @Override
     protected BeanProxyFactory createBeanProxyFactory() {
         return new BaseServiceResolver<>(BeanProxyFactory.FACTORY, BeanProxyFactory.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseThrow(() -> new IllegalArgumentException("Cannot find BeanProxyFactory on classpath. "
                         + "Add camel-bean to classpath."));
     }
@@ -281,7 +282,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
     @Override
     protected BeanProcessorFactory createBeanProcessorFactory() {
         return new BaseServiceResolver<>(BeanProcessorFactory.FACTORY, BeanProcessorFactory.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseThrow(() -> new IllegalArgumentException("Cannot find BeanProcessorFactory on classpath. "
                         + "Add camel-bean to classpath."));
     }
@@ -294,7 +295,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
     @Override
     protected XMLRoutesDefinitionLoader createXMLRoutesDefinitionLoader() {
         return new BaseServiceResolver<>(XMLRoutesDefinitionLoader.FACTORY, XMLRoutesDefinitionLoader.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseThrow(() -> new IllegalArgumentException("Cannot find XMLRoutesDefinitionLoader on classpath. "
                         + "Add either camel-xml-io or camel-xml-jaxb to classpath."));
     }
@@ -302,7 +303,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
     @Override
     protected ModelToXMLDumper createModelToXMLDumper() {
         return new BaseServiceResolver<>(ModelToXMLDumper.FACTORY, ModelToXMLDumper.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseThrow(() -> new IllegalArgumentException("Cannot find ModelToXMLDumper on classpath. "
                         + "Add camel-xml-jaxb to classpath."));
     }
@@ -340,14 +341,14 @@ public class SimpleCamelContext extends AbstractCamelContext {
     @Override
     protected RestRegistryFactory createRestRegistryFactory() {
         return new BaseServiceResolver<>(RestRegistryFactory.FACTORY, RestRegistryFactory.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseThrow(() -> new IllegalArgumentException("Cannot find RestRegistryFactory on classpath. "
                         + "Add camel-rest to classpath."));
     }
 
     @Override
     protected EndpointRegistry<EndpointKey> createEndpointRegistry(Map<EndpointKey, Endpoint> endpoints) {
-        return new DefaultEndpointRegistry(this, endpoints);
+        return new DefaultEndpointRegistry(getCamelContextReference(), endpoints);
     }
 
     @Override
@@ -358,27 +359,27 @@ public class SimpleCamelContext extends AbstractCamelContext {
     @Override
     protected ReactiveExecutor createReactiveExecutor() {
         return new BaseServiceResolver<>(ReactiveExecutor.FACTORY, ReactiveExecutor.class)
-                .resolve(this)
+                .resolve(getCamelContextReference())
                 .orElseGet(DefaultReactiveExecutor::new);
     }
 
     @Override
     public AsyncProcessor createMulticast(Collection<Processor> processors, ExecutorService executor, boolean shutdownExecutorService) {
-        return new MulticastProcessor(this, processors, null, true, executor, shutdownExecutorService, false, false, 0, null, false, false);
+        return new MulticastProcessor(getCamelContextReference(), processors, null, true, executor, shutdownExecutorService, false, false, 0, null, false, false);
     }
 
     @Override
     protected ValidatorRegistry<ValidatorKey> createValidatorRegistry() {
-        return new DefaultValidatorRegistry(this);
+        return new DefaultValidatorRegistry(getCamelContextReference());
     }
 
     @Override
     protected TransformerRegistry<TransformerKey> createTransformerRegistry() {
-        return new DefaultTransformerRegistry(this);
+        return new DefaultTransformerRegistry(getCamelContextReference());
     }
 
     @Override
     protected ExecutorServiceManager createExecutorServiceManager() {
-        return new BaseExecutorServiceManager(this);
+        return new BaseExecutorServiceManager(getCamelContextReference());
     }
 }
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 dfde2fa..17b9531 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
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.function.Function;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.FailedToStartRouteException;
 import org.apache.camel.Navigate;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
@@ -39,11 +40,13 @@ import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.Resilience4jConfigurationDefinition;
 import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RouteDefinitionHelper;
 import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.model.validator.ValidatorDefinition;
 import org.apache.camel.processor.channel.DefaultChannel;
+import org.apache.camel.reifier.RouteReifier;
 import org.apache.camel.reifier.dataformat.DataFormatReifier;
 import org.apache.camel.spi.BeanRepository;
 import org.apache.camel.spi.DataFormat;
@@ -319,7 +322,33 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
 
     @Override
     public void startRouteDefinitions() throws Exception {
-        model.startRouteDefinitions();
+        List<RouteDefinition> routeDefinitions = model.getRouteDefinitions();
+        if (routeDefinitions != null) {
+            startRouteDefinitions(routeDefinitions);
+        }
+    }
+
+    public void startRouteDefinitions(List<RouteDefinition> routeDefinitions) throws Exception {
+        RouteDefinitionHelper.forceAssignIds(getCamelContextReference(), routeDefinitions);
+        for (RouteDefinition routeDefinition : routeDefinitions) {
+            // assign ids to the routes and validate that the id's is all unique
+            String duplicate = RouteDefinitionHelper.validateUniqueIds(routeDefinition, routeDefinitions);
+            if (duplicate != null) {
+                throw new FailedToStartRouteException(routeDefinition.getId(), "duplicate id detected: " + duplicate + ". Please correct ids to be unique among all your routes.");
+            }
+
+            // must ensure route is prepared, before we can start it
+            if (!routeDefinition.isPrepared()) {
+                RouteDefinitionHelper.prepareRoute(getCamelContextReference(), routeDefinition);
+                routeDefinition.markPrepared();
+            }
+
+            // indicate we are staring the route using this thread so
+            // we are able to query this if needed
+            Route route = new RouteReifier(getCamelContextReference(), routeDefinition).createRoute();
+            RouteService routeService = new RouteService(route);
+            startRouteService(routeService, true);
+        }
     }
 
     @Override
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
index c0a786b..722dae2 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
@@ -28,24 +28,19 @@ import java.util.function.Function;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.FailedToStartRouteException;
-import org.apache.camel.Route;
-import org.apache.camel.impl.engine.AbstractCamelContext;
-import org.apache.camel.impl.engine.RouteService;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.HystrixConfigurationDefinition;
 import org.apache.camel.model.Model;
+import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.ProcessorDefinitionHelper;
 import org.apache.camel.model.Resilience4jConfigurationDefinition;
 import org.apache.camel.model.RouteDefinition;
-import org.apache.camel.model.RouteDefinitionHelper;
 import org.apache.camel.model.RouteFilters;
 import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.model.validator.ValidatorDefinition;
-import org.apache.camel.reifier.RouteReifier;
 
 public class DefaultModel implements Model {
 
@@ -84,7 +79,7 @@ public class DefaultModel implements Model {
         removeRouteDefinitions(list);
         this.routeDefinitions.addAll(list);
         if (shouldStartRoutes()) {
-            startRouteDefinitions(list);
+            getCamelContext().adapt(ModelCamelContext.class).startRouteDefinitions(list);
         }
     }
 
@@ -298,11 +293,6 @@ public class DefaultModel implements Model {
     }
 
     @Override
-    public void startRouteDefinitions() throws Exception {
-        startRouteDefinitions(routeDefinitions);
-    }
-
-    @Override
     public void setRouteFilterPattern(String include, String exclude) {
         setRouteFilter(RouteFilters.filterByPattern(include, exclude));
     }
@@ -317,49 +307,6 @@ public class DefaultModel implements Model {
         this.routeFilter = routeFilter;
     }
 
-    protected void startRouteDefinitions(Collection<RouteDefinition> list) throws Exception {
-        if (list != null) {
-            for (RouteDefinition route : list) {
-                startRoute(route);
-            }
-        }
-    }
-
-    public void startRoute(RouteDefinition routeDefinition) throws Exception {
-        prepare(routeDefinition);
-        start(routeDefinition);
-    }
-
-    protected void prepare(RouteDefinition routeDefinition) throws Exception {
-        // assign ids to the routes and validate that the id's is all unique
-        RouteDefinitionHelper.forceAssignIds(camelContext, routeDefinitions);
-        String duplicate = RouteDefinitionHelper.validateUniqueIds(routeDefinition, routeDefinitions);
-        if (duplicate != null) {
-            throw new FailedToStartRouteException(routeDefinition.getId(), "duplicate id detected: " + duplicate + ". Please correct ids to be unique among all your routes.");
-        }
-
-        // must ensure route is prepared, before we can start it
-        if (!routeDefinition.isPrepared()) {
-            RouteDefinitionHelper.prepareRoute(camelContext, routeDefinition);
-            routeDefinition.markPrepared();
-        }
-    }
-
-    protected void start(RouteDefinition routeDefinition) throws Exception {
-        // indicate we are staring the route using this thread so
-        // we are able to query this if needed
-        AbstractCamelContext mcc = camelContext.adapt(AbstractCamelContext.class);
-        mcc.setStartingRoutes(true);
-        try {
-            Route route = new RouteReifier(camelContext, routeDefinition).createRoute();
-            RouteService routeService = new RouteService(route);
-            mcc.startRouteService(routeService, true);
-        } finally {
-            // we are done staring routes
-            mcc.setStartingRoutes(false);
-        }
-    }
-
     /**
      * Should we start newly added routes?
      */
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
new file mode 100644
index 0000000..a147442
--- /dev/null
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
@@ -0,0 +1,1657 @@
+/*
+ * 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.lw;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.Function;
+
+import org.apache.camel.AsyncProcessor;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CatalogCamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.ConsumerTemplate;
+import org.apache.camel.Endpoint;
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.Experimental;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.GlobalEndpointConfiguration;
+import org.apache.camel.NoSuchLanguageException;
+import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.Route;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.ShutdownRoute;
+import org.apache.camel.ShutdownRunningTask;
+import org.apache.camel.StartupListener;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.ValueHolder;
+import org.apache.camel.catalog.RuntimeCamelCatalog;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.model.HystrixConfigurationDefinition;
+import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.model.Resilience4jConfigurationDefinition;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
+import org.apache.camel.model.rest.RestDefinition;
+import org.apache.camel.model.transformer.TransformerDefinition;
+import org.apache.camel.model.validator.ValidatorDefinition;
+import org.apache.camel.spi.AnnotationBasedProcessorFactory;
+import org.apache.camel.spi.AsyncProcessorAwaitManager;
+import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.spi.BeanProcessorFactory;
+import org.apache.camel.spi.BeanProxyFactory;
+import org.apache.camel.spi.BeanRepository;
+import org.apache.camel.spi.CamelBeanPostProcessor;
+import org.apache.camel.spi.CamelContextNameStrategy;
+import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.spi.ComponentResolver;
+import org.apache.camel.spi.ConfigurerResolver;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataFormatResolver;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Debugger;
+import org.apache.camel.spi.DeferServiceFactory;
+import org.apache.camel.spi.EndpointRegistry;
+import org.apache.camel.spi.EndpointStrategy;
+import org.apache.camel.spi.ExecutorServiceManager;
+import org.apache.camel.spi.FactoryFinder;
+import org.apache.camel.spi.FactoryFinderResolver;
+import org.apache.camel.spi.HeadersMapFactory;
+import org.apache.camel.spi.InflightRepository;
+import org.apache.camel.spi.Injector;
+import org.apache.camel.spi.InterceptStrategy;
+import org.apache.camel.spi.Language;
+import org.apache.camel.spi.LanguageResolver;
+import org.apache.camel.spi.LifecycleStrategy;
+import org.apache.camel.spi.LogListener;
+import org.apache.camel.spi.ManagementMBeanAssembler;
+import org.apache.camel.spi.ManagementNameStrategy;
+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.NodeIdFactory;
+import org.apache.camel.spi.NormalizedEndpointUri;
+import org.apache.camel.spi.PackageScanClassResolver;
+import org.apache.camel.spi.PackageScanResourceResolver;
+import org.apache.camel.spi.ProcessorFactory;
+import org.apache.camel.spi.PropertiesComponent;
+import org.apache.camel.spi.ReactiveExecutor;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.spi.RestConfiguration;
+import org.apache.camel.spi.RestRegistry;
+import org.apache.camel.spi.RouteController;
+import org.apache.camel.spi.RoutePolicyFactory;
+import org.apache.camel.spi.RouteStartupOrder;
+import org.apache.camel.spi.RuntimeEndpointRegistry;
+import org.apache.camel.spi.ShutdownStrategy;
+import org.apache.camel.spi.StreamCachingStrategy;
+import org.apache.camel.spi.Tracer;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.TransformerRegistry;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.spi.UnitOfWorkFactory;
+import org.apache.camel.spi.UuidGenerator;
+import org.apache.camel.spi.Validator;
+import org.apache.camel.spi.ValidatorRegistry;
+import org.apache.camel.spi.XMLRoutesDefinitionLoader;
+import org.apache.camel.support.DefaultRegistry;
+import org.apache.camel.support.jsse.SSLContextParameters;
+
+@Experimental
+public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamelContext, ModelCamelContext {
+
+    protected volatile CamelContext delegate;
+
+    /**
+     * Creates the {@link ModelCamelContext} using
+     * {@link org.apache.camel.support.DefaultRegistry} as registry.
+     * <p/>
+     * Use one of the other constructors to force use an explicit registry.
+     */
+    public ImmutableCamelContext() {
+        delegate = new DefaultCamelContext(false) {
+            @Override
+            public CamelContext getCamelContextReference() {
+                return ImmutableCamelContext.this;
+            }
+        };
+    }
+
+    public CamelContext getCamelContextReference() {
+        return this;
+    }
+
+    /**
+     * Creates the {@link CamelContext} using the given {@link BeanRepository}
+     * as first-choice repository, and the
+     * {@link org.apache.camel.support.SimpleRegistry} as fallback, via the
+     * {@link DefaultRegistry} implementation.
+     *
+     * @param repository the bean repository.
+     */
+    public ImmutableCamelContext(BeanRepository repository) {
+        this(new DefaultRegistry(repository));
+    }
+
+    /**
+     * Creates the {@link ModelCamelContext} using the given registry
+     *
+     * @param registry the registry
+     */
+    public ImmutableCamelContext(Registry registry) {
+        this();
+        setRegistry(registry);
+    }
+
+    protected ImmutableCamelContext(CamelContext delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public boolean isStarted() {
+        return delegate.isStarted();
+    }
+
+    @Override
+    public boolean isStarting() {
+        return delegate.isStarting();
+    }
+
+    @Override
+    public boolean isStopped() {
+        return delegate.isStopped();
+    }
+
+    @Override
+    public boolean isStopping() {
+        return delegate.isStopping();
+    }
+
+    @Override
+    public boolean isSuspended() {
+        return delegate.isSuspended();
+    }
+
+    @Override
+    public boolean isRunAllowed() {
+        return delegate.isRunAllowed();
+    }
+
+    @Override
+    public boolean isSuspending() {
+        return delegate.isSuspending();
+    }
+
+    @Override
+    public void init() {
+        delegate.init();
+    }
+
+    @Override
+    public void suspend() {
+        delegate.suspend();
+    }
+
+    @Override
+    public void resume() {
+        delegate.resume();
+    }
+
+    @Override
+    public void shutdown() {
+        delegate.shutdown();
+    }
+
+    @Override
+    public void close() throws IOException {
+        delegate.close();
+    }
+
+    @Override
+    public <T extends CamelContext> T adapt(Class<T> type) {
+        T res = delegate.adapt(type);
+        if (res == delegate) {
+            return type.cast(this);
+        } else {
+            return res;
+        }
+    }
+
+    @Override
+    public <T> T getExtension(Class<T> type) {
+        return delegate.getExtension(type);
+    }
+
+    @Override
+    public <T> void setExtension(Class<T> type, T module) {
+        delegate.setExtension(type, module);
+    }
+
+    @Override
+    public void start() {
+        delegate.start();
+    }
+
+    @Override
+    public void stop() {
+        delegate.stop();
+    }
+
+    @Override
+    public boolean isVetoStarted() {
+        return delegate.isVetoStarted();
+    }
+
+    @Override
+    public String getName() {
+        return delegate.getName();
+    }
+
+    @Override
+    public CamelContextNameStrategy getNameStrategy() {
+        return delegate.getNameStrategy();
+    }
+
+    @Override
+    public void setNameStrategy(CamelContextNameStrategy nameStrategy) {
+        delegate.setNameStrategy(nameStrategy);
+    }
+
+    @Override
+    public ManagementNameStrategy getManagementNameStrategy() {
+        return delegate.getManagementNameStrategy();
+    }
+
+    @Override
+    public void setManagementNameStrategy(ManagementNameStrategy nameStrategy) {
+        delegate.setManagementNameStrategy(nameStrategy);
+    }
+
+    @Override
+    public String getManagementName() {
+        return delegate.getManagementName();
+    }
+
+    @Override
+    public void setManagementName(String name) {
+        delegate.setManagementName(name);
+    }
+
+    @Override
+    public String getVersion() {
+        return delegate.getVersion();
+    }
+
+    @Override
+    public ServiceStatus getStatus() {
+        return delegate.getStatus();
+    }
+
+    @Override
+    public String getUptime() {
+        return delegate.getUptime();
+    }
+
+    @Override
+    public long getUptimeMillis() {
+        return delegate.getUptimeMillis();
+    }
+
+    @Override
+    public Date getStartDate() {
+        return delegate.getStartDate();
+    }
+
+    @Override
+    public void addService(Object object) throws Exception {
+        delegate.addService(object);
+    }
+
+    @Override
+    public void addService(Object object, boolean stopOnShutdown) throws Exception {
+        delegate.addService(object, stopOnShutdown);
+    }
+
+    @Override
+    public void addService(Object object, boolean stopOnShutdown, boolean forceStart) throws Exception {
+        delegate.addService(object, stopOnShutdown, forceStart);
+    }
+
+    @Override
+    public void addPrototypeService(Object object) throws Exception {
+        delegate.addPrototypeService(object);
+    }
+
+    @Override
+    public boolean removeService(Object object) throws Exception {
+        return delegate.removeService(object);
+    }
+
+    @Override
+    public boolean hasService(Object object) {
+        return delegate.hasService(object);
+    }
+
+    @Override
+    public <T> T hasService(Class<T> type) {
+        return delegate.hasService(type);
+    }
+
+    @Override
+    public <T> Set<T> hasServices(Class<T> type) {
+        return delegate.hasServices(type);
+    }
+
+    @Override
+    public void deferStartService(Object object, boolean stopOnShutdown) throws Exception {
+        delegate.deferStartService(object, stopOnShutdown);
+    }
+
+    @Override
+    public void addStartupListener(StartupListener listener) throws Exception {
+        delegate.addStartupListener(listener);
+    }
+
+    @Override
+    public void addComponent(String componentName, Component component) {
+        delegate.addComponent(componentName, component);
+    }
+
+    @Override
+    public Component hasComponent(String componentName) {
+        return delegate.hasComponent(componentName);
+    }
+
+    @Override
+    public Component getComponent(String componentName) {
+        return delegate.getComponent(componentName);
+    }
+
+    @Override
+    public Component getComponent(String name, boolean autoCreateComponents) {
+        return delegate.getComponent(name, autoCreateComponents);
+    }
+
+    @Override
+    public Component getComponent(String name, boolean autoCreateComponents, boolean autoStart) {
+        return delegate.getComponent(name, autoCreateComponents, autoStart);
+    }
+
+    @Override
+    public <T extends Component> T getComponent(String name, Class<T> componentType) {
+        return delegate.getComponent(name, componentType);
+    }
+
+    @Override
+    public List<String> getComponentNames() {
+        return delegate.getComponentNames();
+    }
+
+    @Override
+    public Component removeComponent(String componentName) {
+        return delegate.removeComponent(componentName);
+    }
+
+    @Override
+    public EndpointRegistry<? extends ValueHolder<String>> getEndpointRegistry() {
+        return delegate.getEndpointRegistry();
+    }
+
+    @Override
+    public Endpoint getEndpoint(String uri) {
+        return delegate.getEndpoint(uri);
+    }
+
+    @Override
+    public Endpoint getEndpoint(String uri, Map<String, Object> parameters) {
+        return delegate.getEndpoint(uri, parameters);
+    }
+
+    @Override
+    public <T extends Endpoint> T getEndpoint(String name, Class<T> endpointType) {
+        return delegate.getEndpoint(name, endpointType);
+    }
+
+    @Override
+    public Collection<Endpoint> getEndpoints() {
+        return delegate.getEndpoints();
+    }
+
+    @Override
+    @Deprecated
+    public Map<String, Endpoint> getEndpointMap() {
+        return delegate.getEndpointMap();
+    }
+
+    @Override
+    public Endpoint hasEndpoint(String uri) {
+        return delegate.hasEndpoint(uri);
+    }
+
+    @Override
+    public Endpoint addEndpoint(String uri, Endpoint endpoint) throws Exception {
+        return delegate.addEndpoint(uri, endpoint);
+    }
+
+    @Override
+    public void removeEndpoint(Endpoint endpoint) throws Exception {
+        delegate.removeEndpoint(endpoint);
+    }
+
+    @Override
+    public Collection<Endpoint> removeEndpoints(String pattern) throws Exception {
+        return delegate.removeEndpoints(pattern);
+    }
+
+    @Override
+    public GlobalEndpointConfiguration getGlobalEndpointConfiguration() {
+        return delegate.getGlobalEndpointConfiguration();
+    }
+
+    @Override
+    public void setRouteController(RouteController routeController) {
+        delegate.setRouteController(routeController);
+    }
+
+    @Override
+    public RouteController getRouteController() {
+        return delegate.getRouteController();
+    }
+
+    @Override
+    public List<Route> getRoutes() {
+        return delegate.getRoutes();
+    }
+
+    @Override
+    public int getRoutesSize() {
+        return delegate.getRoutesSize();
+    }
+
+    @Override
+    public Route getRoute(String id) {
+        return delegate.getRoute(id);
+    }
+
+    @Override
+    public Processor getProcessor(String id) {
+        return delegate.getProcessor(id);
+    }
+
+    @Override
+    public <T extends Processor> T getProcessor(String id, Class<T> type) {
+        return delegate.getProcessor(id, type);
+    }
+
+    @Override
+    public void addRoutes(RoutesBuilder builder) throws Exception {
+        delegate.addRoutes(builder);
+    }
+
+    @Override
+    public boolean removeRoute(String routeId) throws Exception {
+        return delegate.removeRoute(routeId);
+    }
+
+    @Override
+    public void addRoutePolicyFactory(RoutePolicyFactory routePolicyFactory) {
+        delegate.addRoutePolicyFactory(routePolicyFactory);
+    }
+
+    @Override
+    public List<RoutePolicyFactory> getRoutePolicyFactories() {
+        return delegate.getRoutePolicyFactories();
+    }
+
+    @Override
+    public void setRestConfiguration(RestConfiguration restConfiguration) {
+        delegate.setRestConfiguration(restConfiguration);
+    }
+
+    @Override
+    public RestConfiguration getRestConfiguration() {
+        return delegate.getRestConfiguration();
+    }
+
+    @Override
+    @Deprecated
+    public void addRestConfiguration(RestConfiguration restConfiguration) {
+        delegate.addRestConfiguration(restConfiguration);
+    }
+
+    @Override
+    public RestConfiguration getRestConfiguration(String component, boolean defaultIfNotFound) {
+        return delegate.getRestConfiguration(component, defaultIfNotFound);
+    }
+
+    @Override
+    @Deprecated
+    public Collection<RestConfiguration> getRestConfigurations() {
+        return delegate.getRestConfigurations();
+    }
+
+    @Override
+    public RestRegistry getRestRegistry() {
+        return delegate.getRestRegistry();
+    }
+
+    @Override
+    public void setRestRegistry(RestRegistry restRegistry) {
+        delegate.setRestRegistry(restRegistry);
+    }
+
+    @Override
+    public TypeConverter getTypeConverter() {
+        return delegate.getTypeConverter();
+    }
+
+    @Override
+    public TypeConverterRegistry getTypeConverterRegistry() {
+        return delegate.getTypeConverterRegistry();
+    }
+
+    @Override
+    public void setTypeConverterRegistry(TypeConverterRegistry typeConverterRegistry) {
+        delegate.setTypeConverterRegistry(typeConverterRegistry);
+    }
+
+    @Override
+    public Registry getRegistry() {
+        return delegate.getRegistry();
+    }
+
+    @Override
+    public <T> T getRegistry(Class<T> type) {
+        return delegate.getRegistry(type);
+    }
+
+    @Override
+    public Injector getInjector() {
+        return delegate.getInjector();
+    }
+
+    @Override
+    public void setInjector(Injector injector) {
+        delegate.setInjector(injector);
+    }
+
+    @Override
+    public List<LifecycleStrategy> getLifecycleStrategies() {
+        return delegate.getLifecycleStrategies();
+    }
+
+    @Override
+    public void addLifecycleStrategy(LifecycleStrategy lifecycleStrategy) {
+        delegate.addLifecycleStrategy(lifecycleStrategy);
+    }
+
+    @Override
+    public Language resolveLanguage(String language) throws NoSuchLanguageException {
+        return delegate.resolveLanguage(language);
+    }
+
+    @Override
+    public String resolvePropertyPlaceholders(String text) {
+        return delegate.resolvePropertyPlaceholders(text);
+    }
+
+    @Override
+    public PropertiesComponent getPropertiesComponent() {
+        return delegate.getPropertiesComponent();
+    }
+
+    @Override
+    public void setPropertiesComponent(PropertiesComponent propertiesComponent) {
+        delegate.setPropertiesComponent(propertiesComponent);
+    }
+
+    @Override
+    @Deprecated
+    public List<String> getLanguageNames() {
+        return delegate.getLanguageNames();
+    }
+
+    @Override
+    public ProducerTemplate createProducerTemplate() {
+        return delegate.createProducerTemplate();
+    }
+
+    @Override
+    public ProducerTemplate createProducerTemplate(int maximumCacheSize) {
+        return delegate.createProducerTemplate(maximumCacheSize);
+    }
+
+    @Override
+    public FluentProducerTemplate createFluentProducerTemplate() {
+        return delegate.createFluentProducerTemplate();
+    }
+
+    @Override
+    public FluentProducerTemplate createFluentProducerTemplate(int maximumCacheSize) {
+        return delegate.createFluentProducerTemplate(maximumCacheSize);
+    }
+
+    @Override
+    public ConsumerTemplate createConsumerTemplate() {
+        return delegate.createConsumerTemplate();
+    }
+
+    @Override
+    public ConsumerTemplate createConsumerTemplate(int maximumCacheSize) {
+        return delegate.createConsumerTemplate(maximumCacheSize);
+    }
+
+    @Override
+    public DataFormat resolveDataFormat(String name) {
+        return delegate.resolveDataFormat(name);
+    }
+
+    @Override
+    public DataFormat createDataFormat(String name) {
+        return delegate.createDataFormat(name);
+    }
+
+    @Override
+    public Transformer resolveTransformer(String model) {
+        return delegate.resolveTransformer(model);
+    }
+
+    @Override
+    public Transformer resolveTransformer(DataType from, DataType to) {
+        return delegate.resolveTransformer(from, to);
+    }
+
+    @Override
+    public TransformerRegistry getTransformerRegistry() {
+        return delegate.getTransformerRegistry();
+    }
+
+    @Override
+    public Validator resolveValidator(DataType type) {
+        return delegate.resolveValidator(type);
+    }
+
+    @Override
+    public ValidatorRegistry getValidatorRegistry() {
+        return delegate.getValidatorRegistry();
+    }
+
+    @Override
+    public void setGlobalOptions(Map<String, String> globalOptions) {
+        delegate.setGlobalOptions(globalOptions);
+    }
+
+    @Override
+    public Map<String, String> getGlobalOptions() {
+        return delegate.getGlobalOptions();
+    }
+
+    @Override
+    public String getGlobalOption(String key) {
+        return delegate.getGlobalOption(key);
+    }
+
+    @Override
+    public ClassResolver getClassResolver() {
+        return delegate.getClassResolver();
+    }
+
+    @Override
+    public void setClassResolver(ClassResolver resolver) {
+        delegate.setClassResolver(resolver);
+    }
+
+    @Override
+    public ManagementStrategy getManagementStrategy() {
+        return delegate.getManagementStrategy();
+    }
+
+    @Override
+    public void setManagementStrategy(ManagementStrategy strategy) {
+        delegate.setManagementStrategy(strategy);
+    }
+
+    @Override
+    public void disableJMX() throws IllegalStateException {
+        delegate.disableJMX();
+    }
+
+    @Override
+    public InflightRepository getInflightRepository() {
+        return delegate.getInflightRepository();
+    }
+
+    @Override
+    public void setInflightRepository(InflightRepository repository) {
+        delegate.setInflightRepository(repository);
+    }
+
+    @Override
+    public ClassLoader getApplicationContextClassLoader() {
+        return delegate.getApplicationContextClassLoader();
+    }
+
+    @Override
+    public void setApplicationContextClassLoader(ClassLoader classLoader) {
+        delegate.setApplicationContextClassLoader(classLoader);
+    }
+
+    @Override
+    public ShutdownStrategy getShutdownStrategy() {
+        return delegate.getShutdownStrategy();
+    }
+
+    @Override
+    public void setShutdownStrategy(ShutdownStrategy shutdownStrategy) {
+        delegate.setShutdownStrategy(shutdownStrategy);
+    }
+
+    @Override
+    public ExecutorServiceManager getExecutorServiceManager() {
+        return delegate.getExecutorServiceManager();
+    }
+
+    @Override
+    public void setExecutorServiceManager(ExecutorServiceManager executorServiceManager) {
+        delegate.setExecutorServiceManager(executorServiceManager);
+    }
+
+    @Override
+    public MessageHistoryFactory getMessageHistoryFactory() {
+        return delegate.getMessageHistoryFactory();
+    }
+
+    @Override
+    public void setMessageHistoryFactory(MessageHistoryFactory messageHistoryFactory) {
+        delegate.setMessageHistoryFactory(messageHistoryFactory);
+    }
+
+    @Override
+    public Debugger getDebugger() {
+        return delegate.getDebugger();
+    }
+
+    @Override
+    public void setDebugger(Debugger debugger) {
+        delegate.setDebugger(debugger);
+    }
+
+    @Override
+    public Tracer getTracer() {
+        return delegate.getTracer();
+    }
+
+    @Override
+    public void setTracer(Tracer tracer) {
+        delegate.setTracer(tracer);
+    }
+
+    @Override
+    public UuidGenerator getUuidGenerator() {
+        return delegate.getUuidGenerator();
+    }
+
+    @Override
+    public void setUuidGenerator(UuidGenerator uuidGenerator) {
+        delegate.setUuidGenerator(uuidGenerator);
+    }
+
+    @Override
+    public Boolean isLoadTypeConverters() {
+        return delegate.isLoadTypeConverters();
+    }
+
+    @Override
+    public void setLoadTypeConverters(Boolean loadTypeConverters) {
+        delegate.setLoadTypeConverters(loadTypeConverters);
+    }
+
+    @Override
+    public Boolean isTypeConverterStatisticsEnabled() {
+        return delegate.isTypeConverterStatisticsEnabled();
+    }
+
+    @Override
+    public void setTypeConverterStatisticsEnabled(Boolean typeConverterStatisticsEnabled) {
+        delegate.setTypeConverterStatisticsEnabled(typeConverterStatisticsEnabled);
+    }
+
+    @Override
+    public Boolean isUseMDCLogging() {
+        return delegate.isUseMDCLogging();
+    }
+
+    @Override
+    public void setUseMDCLogging(Boolean useMDCLogging) {
+        delegate.setUseMDCLogging(useMDCLogging);
+    }
+
+    @Override
+    public String getMDCLoggingKeysPattern() {
+        return delegate.getMDCLoggingKeysPattern();
+    }
+
+    @Override
+    public void setMDCLoggingKeysPattern(String pattern) {
+        delegate.setMDCLoggingKeysPattern(pattern);
+    }
+
+    @Override
+    public Boolean isUseDataType() {
+        return delegate.isUseDataType();
+    }
+
+    @Override
+    public void setUseDataType(Boolean useDataType) {
+        delegate.setUseDataType(useDataType);
+    }
+
+    @Override
+    public Boolean isUseBreadcrumb() {
+        return delegate.isUseBreadcrumb();
+    }
+
+    @Override
+    public void setUseBreadcrumb(Boolean useBreadcrumb) {
+        delegate.setUseBreadcrumb(useBreadcrumb);
+    }
+
+    @Override
+    public StreamCachingStrategy getStreamCachingStrategy() {
+        return delegate.getStreamCachingStrategy();
+    }
+
+    @Override
+    public void setStreamCachingStrategy(StreamCachingStrategy streamCachingStrategy) {
+        delegate.setStreamCachingStrategy(streamCachingStrategy);
+    }
+
+    @Override
+    public RuntimeEndpointRegistry getRuntimeEndpointRegistry() {
+        return delegate.getRuntimeEndpointRegistry();
+    }
+
+    @Override
+    public void setRuntimeEndpointRegistry(RuntimeEndpointRegistry runtimeEndpointRegistry) {
+        delegate.setRuntimeEndpointRegistry(runtimeEndpointRegistry);
+    }
+
+    @Override
+    public void setSSLContextParameters(SSLContextParameters sslContextParameters) {
+        delegate.setSSLContextParameters(sslContextParameters);
+    }
+
+    @Override
+    public SSLContextParameters getSSLContextParameters() {
+        return delegate.getSSLContextParameters();
+    }
+
+    @Override
+    public void setStreamCaching(Boolean cache) {
+        delegate.setStreamCaching(cache);
+    }
+
+    @Override
+    public Boolean isStreamCaching() {
+        return delegate.isStreamCaching();
+    }
+
+    @Override
+    public void setTracing(Boolean tracing) {
+        delegate.setTracing(tracing);
+    }
+
+    @Override
+    public Boolean isTracing() {
+        return delegate.isTracing();
+    }
+
+    @Override
+    public String getTracingPattern() {
+        return delegate.getTracingPattern();
+    }
+
+    @Override
+    public void setTracingPattern(String tracePattern) {
+        delegate.setTracingPattern(tracePattern);
+    }
+
+    @Override
+    public void setBacklogTracing(Boolean backlogTrace) {
+        delegate.setBacklogTracing(backlogTrace);
+    }
+
+    @Override
+    public Boolean isBacklogTracing() {
+        return delegate.isBacklogTracing();
+    }
+
+    @Override
+    public void setDebugging(Boolean debugging) {
+        delegate.setDebugging(debugging);
+    }
+
+    @Override
+    public Boolean isDebugging() {
+        return delegate.isDebugging();
+    }
+
+    @Override
+    public void setMessageHistory(Boolean messageHistory) {
+        delegate.setMessageHistory(messageHistory);
+    }
+
+    @Override
+    public Boolean isMessageHistory() {
+        return delegate.isMessageHistory();
+    }
+
+    @Override
+    public void setLogMask(Boolean logMask) {
+        delegate.setLogMask(logMask);
+    }
+
+    @Override
+    public Boolean isLogMask() {
+        return delegate.isLogMask();
+    }
+
+    @Override
+    public void setLogExhaustedMessageBody(Boolean logExhaustedMessageBody) {
+        delegate.setLogExhaustedMessageBody(logExhaustedMessageBody);
+    }
+
+    @Override
+    public Boolean isLogExhaustedMessageBody() {
+        return delegate.isLogExhaustedMessageBody();
+    }
+
+    @Override
+    public void setDelayer(Long delay) {
+        delegate.setDelayer(delay);
+    }
+
+    @Override
+    public Long getDelayer() {
+        return delegate.getDelayer();
+    }
+
+    @Override
+    public void setAutoStartup(Boolean autoStartup) {
+        delegate.setAutoStartup(autoStartup);
+    }
+
+    @Override
+    public Boolean isAutoStartup() {
+        return delegate.isAutoStartup();
+    }
+
+    @Override
+    public void setShutdownRoute(ShutdownRoute shutdownRoute) {
+        delegate.setShutdownRoute(shutdownRoute);
+    }
+
+    @Override
+    public ShutdownRoute getShutdownRoute() {
+        return delegate.getShutdownRoute();
+    }
+
+    @Override
+    public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) {
+        delegate.setShutdownRunningTask(shutdownRunningTask);
+    }
+
+    @Override
+    public ShutdownRunningTask getShutdownRunningTask() {
+        return delegate.getShutdownRunningTask();
+    }
+
+    @Override
+    public void setAllowUseOriginalMessage(Boolean allowUseOriginalMessage) {
+        delegate.setAllowUseOriginalMessage(allowUseOriginalMessage);
+    }
+
+    @Override
+    public Boolean isAllowUseOriginalMessage() {
+        return delegate.isAllowUseOriginalMessage();
+    }
+
+    @Override
+    public Boolean isCaseInsensitiveHeaders() {
+        return delegate.isCaseInsensitiveHeaders();
+    }
+
+    @Override
+    public void setCaseInsensitiveHeaders(Boolean caseInsensitiveHeaders) {
+        delegate.setCaseInsensitiveHeaders(caseInsensitiveHeaders);
+    }
+
+    //
+    // ExtendedCamelContext
+    //
+
+    protected ExtendedCamelContext getExtendedCamelContext() {
+        return delegate.adapt(ExtendedCamelContext.class);
+    }
+
+    @Override
+    public void setName(String name) {
+        getExtendedCamelContext().setName(name);
+    }
+
+    @Override
+    public void setRegistry(Registry registry) {
+        getExtendedCamelContext().setRegistry(registry);
+    }
+
+    @Override
+    public void setupRoutes(boolean done) {
+        getExtendedCamelContext().setupRoutes(done);
+    }
+
+    @Override
+    public boolean isSetupRoutes() {
+        return getExtendedCamelContext().isSetupRoutes();
+    }
+
+    @Override
+    public void registerEndpointCallback(EndpointStrategy strategy) {
+        getExtendedCamelContext().registerEndpointCallback(strategy);
+    }
+
+    @Override
+    public Endpoint getPrototypeEndpoint(String uri) {
+        return getExtendedCamelContext().getPrototypeEndpoint(uri);
+    }
+
+    @Override
+    public Endpoint getPrototypeEndpoint(NormalizedEndpointUri uri) {
+        return getExtendedCamelContext().getPrototypeEndpoint(uri);
+    }
+
+    @Override
+    public Endpoint hasEndpoint(NormalizedEndpointUri uri) {
+        return getExtendedCamelContext().hasEndpoint(uri);
+    }
+
+    @Override
+    public Endpoint getEndpoint(NormalizedEndpointUri uri) {
+        return getExtendedCamelContext().getEndpoint(uri);
+    }
+
+    @Override
+    public Endpoint getEndpoint(NormalizedEndpointUri uri, Map<String, Object> parameters) {
+        return getExtendedCamelContext().getEndpoint(uri, parameters);
+    }
+
+    @Override
+    public NormalizedEndpointUri normalizeUri(String uri) {
+        return getExtendedCamelContext().normalizeUri(uri);
+    }
+
+    @Override
+    public List<RouteStartupOrder> getRouteStartupOrder() {
+        return getExtendedCamelContext().getRouteStartupOrder();
+    }
+
+    @Override
+    public CamelBeanPostProcessor getBeanPostProcessor() {
+        return getExtendedCamelContext().getBeanPostProcessor();
+    }
+
+    @Override
+    public ManagementMBeanAssembler getManagementMBeanAssembler() {
+        return getExtendedCamelContext().getManagementMBeanAssembler();
+    }
+
+    @Override
+    public AsyncProcessor createMulticast(Collection<Processor> processors, ExecutorService executor, boolean shutdownExecutorService) {
+        return getExtendedCamelContext().createMulticast(processors, executor, shutdownExecutorService);
+    }
+
+    @Override
+    public ErrorHandlerFactory getErrorHandlerFactory() {
+        return getExtendedCamelContext().getErrorHandlerFactory();
+    }
+
+    @Override
+    public void setErrorHandlerFactory(ErrorHandlerFactory errorHandlerFactory) {
+        getExtendedCamelContext().setErrorHandlerFactory(errorHandlerFactory);
+    }
+
+    @Override
+    public void setNodeIdFactory(NodeIdFactory factory) {
+        getExtendedCamelContext().setNodeIdFactory(factory);
+    }
+
+    @Override
+    public NodeIdFactory getNodeIdFactory() {
+        return getExtendedCamelContext().getNodeIdFactory();
+    }
+
+    @Override
+    public ComponentResolver getComponentResolver() {
+        return getExtendedCamelContext().getComponentResolver();
+    }
+
+    @Override
+    public void setComponentResolver(ComponentResolver componentResolver) {
+        getExtendedCamelContext().setComponentResolver(componentResolver);
+    }
+
+    @Override
+    public LanguageResolver getLanguageResolver() {
+        return getExtendedCamelContext().getLanguageResolver();
+    }
+
+    @Override
+    public void setLanguageResolver(LanguageResolver languageResolver) {
+        getExtendedCamelContext().setLanguageResolver(languageResolver);
+    }
+
+    @Override
+    public DataFormatResolver getDataFormatResolver() {
+        return getExtendedCamelContext().getDataFormatResolver();
+    }
+
+    @Override
+    public void setDataFormatResolver(DataFormatResolver dataFormatResolver) {
+        getExtendedCamelContext().setDataFormatResolver(dataFormatResolver);
+    }
+
+    @Override
+    public PackageScanClassResolver getPackageScanClassResolver() {
+        return getExtendedCamelContext().getPackageScanClassResolver();
+    }
+
+    @Override
+    public void setPackageScanClassResolver(PackageScanClassResolver resolver) {
+        getExtendedCamelContext().setPackageScanClassResolver(resolver);
+    }
+
+    @Override
+    public PackageScanResourceResolver getPackageScanResourceResolver() {
+        return getExtendedCamelContext().getPackageScanResourceResolver();
+    }
+
+    @Override
+    public void setPackageScanResourceResolver(PackageScanResourceResolver resolver) {
+        getExtendedCamelContext().setPackageScanResourceResolver(resolver);
+    }
+
+    @Override
+    public FactoryFinder getDefaultFactoryFinder() {
+        return getExtendedCamelContext().getDefaultFactoryFinder();
+    }
+
+    @Override
+    public FactoryFinder getFactoryFinder(String path) {
+        return getExtendedCamelContext().getFactoryFinder(path);
+    }
+
+    @Override
+    public void setFactoryFinderResolver(FactoryFinderResolver resolver) {
+        getExtendedCamelContext().setFactoryFinderResolver(resolver);
+    }
+
+    @Override
+    public FactoryFinderResolver getFactoryFinderResolver() {
+        return getExtendedCamelContext().getFactoryFinderResolver();
+    }
+
+    @Override
+    public ProcessorFactory getProcessorFactory() {
+        return getExtendedCamelContext().getProcessorFactory();
+    }
+
+    @Override
+    public void setProcessorFactory(ProcessorFactory processorFactory) {
+        getExtendedCamelContext().setProcessorFactory(processorFactory);
+    }
+
+    @Override
+    public ModelJAXBContextFactory getModelJAXBContextFactory() {
+        return getExtendedCamelContext().getModelJAXBContextFactory();
+    }
+
+    @Override
+    public void setModelJAXBContextFactory(ModelJAXBContextFactory modelJAXBContextFactory) {
+        getExtendedCamelContext().setModelJAXBContextFactory(modelJAXBContextFactory);
+    }
+
+    @Override
+    public DeferServiceFactory getDeferServiceFactory() {
+        return getExtendedCamelContext().getDeferServiceFactory();
+    }
+
+    @Override
+    public UnitOfWorkFactory getUnitOfWorkFactory() {
+        return getExtendedCamelContext().getUnitOfWorkFactory();
+    }
+
+    @Override
+    public void setUnitOfWorkFactory(UnitOfWorkFactory unitOfWorkFactory) {
+        getExtendedCamelContext().setUnitOfWorkFactory(unitOfWorkFactory);
+    }
+
+    @Override
+    public AnnotationBasedProcessorFactory getAnnotationBasedProcessorFactory() {
+        return getExtendedCamelContext().getAnnotationBasedProcessorFactory();
+    }
+
+    @Override
+    public BeanProxyFactory getBeanProxyFactory() {
+        return getExtendedCamelContext().getBeanProxyFactory();
+    }
+
+    @Override
+    public BeanProcessorFactory getBeanProcessorFactory() {
+        return getExtendedCamelContext().getBeanProcessorFactory();
+    }
+
+    @Override
+    public ScheduledExecutorService getErrorHandlerExecutorService() {
+        return getExtendedCamelContext().getErrorHandlerExecutorService();
+    }
+
+    @Override
+    public void addInterceptStrategy(InterceptStrategy interceptStrategy) {
+        getExtendedCamelContext().addInterceptStrategy(interceptStrategy);
+    }
+
+    @Override
+    public List<InterceptStrategy> getInterceptStrategies() {
+        return getExtendedCamelContext().getInterceptStrategies();
+    }
+
+    @Override
+    public void setupManagement(Map<String, Object> options) {
+        getExtendedCamelContext().setupManagement(options);
+    }
+
+    @Override
+    public Set<LogListener> getLogListeners() {
+        return getExtendedCamelContext().getLogListeners();
+    }
+
+    @Override
+    public void addLogListener(LogListener listener) {
+        getExtendedCamelContext().addLogListener(listener);
+    }
+
+    @Override
+    public AsyncProcessorAwaitManager getAsyncProcessorAwaitManager() {
+        return getExtendedCamelContext().getAsyncProcessorAwaitManager();
+    }
+
+    @Override
+    public void setAsyncProcessorAwaitManager(AsyncProcessorAwaitManager manager) {
+        getExtendedCamelContext().setAsyncProcessorAwaitManager(manager);
+    }
+
+    @Override
+    public BeanIntrospection getBeanIntrospection() {
+        return getExtendedCamelContext().getBeanIntrospection();
+    }
+
+    @Override
+    public void setBeanIntrospection(BeanIntrospection beanIntrospection) {
+        getExtendedCamelContext().setBeanIntrospection(beanIntrospection);
+    }
+
+    @Override
+    public HeadersMapFactory getHeadersMapFactory() {
+        return getExtendedCamelContext().getHeadersMapFactory();
+    }
+
+    @Override
+    public void setHeadersMapFactory(HeadersMapFactory factory) {
+        getExtendedCamelContext().setHeadersMapFactory(factory);
+    }
+
+    @Override
+    public ReactiveExecutor getReactiveExecutor() {
+        return getExtendedCamelContext().getReactiveExecutor();
+    }
+
+    @Override
+    public void setReactiveExecutor(ReactiveExecutor reactiveExecutor) {
+        getExtendedCamelContext().setReactiveExecutor(reactiveExecutor);
+    }
+
+    @Override
+    public boolean isEventNotificationApplicable() {
+        return getExtendedCamelContext().isEventNotificationApplicable();
+    }
+
+    @Override
+    public void setEventNotificationApplicable(boolean eventNotificationApplicable) {
+        getExtendedCamelContext().setEventNotificationApplicable(eventNotificationApplicable);
+    }
+
+    @Override
+    public void setXMLRoutesDefinitionLoader(XMLRoutesDefinitionLoader xmlRoutesDefinitionLoader) {
+        getExtendedCamelContext().setXMLRoutesDefinitionLoader(xmlRoutesDefinitionLoader);
+    }
+
+    @Override
+    public XMLRoutesDefinitionLoader getXMLRoutesDefinitionLoader() {
+        return getExtendedCamelContext().getXMLRoutesDefinitionLoader();
+    }
+
+    @Override
+    public void setModelToXMLDumper(ModelToXMLDumper modelToXMLDumper) {
+        getExtendedCamelContext().setModelToXMLDumper(modelToXMLDumper);
+    }
+
+    @Override
+    public ModelToXMLDumper getModelToXMLDumper() {
+        return getExtendedCamelContext().getModelToXMLDumper();
+    }
+
+    @Override
+    public RuntimeCamelCatalog getRuntimeCamelCatalog() {
+        return getExtendedCamelContext().getRuntimeCamelCatalog();
+    }
+
+    @Override
+    public void setRuntimeCamelCatalog(RuntimeCamelCatalog runtimeCamelCatalog) {
+        getExtendedCamelContext().setRuntimeCamelCatalog(runtimeCamelCatalog);
+    }
+
+    @Override
+    public ConfigurerResolver getConfigurerResolver() {
+        return getExtendedCamelContext().getConfigurerResolver();
+    }
+
+    @Override
+    public void setConfigurerResolver(ConfigurerResolver configurerResolver) {
+        getExtendedCamelContext().setConfigurerResolver(configurerResolver);
+    }
+
+    @Override
+    public void setAllowAddingNewRoutes(boolean allowAddingNewRoutes) {
+        getExtendedCamelContext().setAllowAddingNewRoutes(allowAddingNewRoutes);
+    }
+
+    @Override
+    public boolean isAllowAddingNewRoutes() {
+        return getExtendedCamelContext().isAllowAddingNewRoutes();
+    }
+
+    @Override
+    @Experimental
+    public void setClearModelReferences(boolean clearModelReferences) {
+        getExtendedCamelContext().setClearModelReferences(clearModelReferences);
+    }
+
+    @Override
+    public boolean isClearModelReferences() {
+        return getExtendedCamelContext().isClearModelReferences();
+    }
+
+    @Override
+    public RouteController getInternalRouteController() {
+        return getExtendedCamelContext().getInternalRouteController();
+    }
+
+    @Override
+    public void addRoute(Route route) {
+        getExtendedCamelContext().addRoute(route);
+    }
+
+    @Override
+    public void removeRoute(Route route) {
+        getExtendedCamelContext().removeRoute(route);
+    }
+
+    //
+    // CatalogCamelContext
+    //
+
+    protected CatalogCamelContext getCatalogCamelContext() {
+        return delegate.adapt(CatalogCamelContext.class);
+    }
+
+    @Override
+    public String getComponentParameterJsonSchema(String componentName) throws IOException {
+        return getCatalogCamelContext().getComponentParameterJsonSchema(componentName);
+    }
+
+    @Override
+    public String getDataFormatParameterJsonSchema(String dataFormatName) throws IOException {
+        return getCatalogCamelContext().getDataFormatParameterJsonSchema(dataFormatName);
+    }
+
+    @Override
+    public String getLanguageParameterJsonSchema(String languageName) throws IOException {
+        return getCatalogCamelContext().getLanguageParameterJsonSchema(languageName);
+    }
+
+    @Override
+    public String getEipParameterJsonSchema(String eipName) throws IOException {
+        return getCatalogCamelContext().getEipParameterJsonSchema(eipName);
+    }
+
+    //
+    // ModelCamelContext
+    //
+
+    protected ModelCamelContext getModelCamelContext() {
+        return delegate.adapt(ModelCamelContext.class);
+    }
+
+    @Override
+    public List<RouteDefinition> getRouteDefinitions() {
+        return getModelCamelContext().getRouteDefinitions();
+    }
+
+    @Override
+    public RouteDefinition getRouteDefinition(String id) {
+        return getModelCamelContext().getRouteDefinition(id);
+    }
+
+    @Override
+    public void addRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception {
+        getModelCamelContext().addRouteDefinitions(routeDefinitions);
+    }
+
+    @Override
+    public void addRouteDefinition(RouteDefinition routeDefinition) throws Exception {
+        getModelCamelContext().addRouteDefinition(routeDefinition);
+    }
+
+    @Override
+    public void removeRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception {
+        getModelCamelContext().removeRouteDefinitions(routeDefinitions);
+    }
+
+    @Override
+    public void removeRouteDefinition(RouteDefinition routeDefinition) throws Exception {
+        getModelCamelContext().removeRouteDefinition(routeDefinition);
+    }
+
+    @Override
+    public List<RestDefinition> getRestDefinitions() {
+        return getModelCamelContext().getRestDefinitions();
+    }
+
+    @Override
+    public void addRestDefinitions(Collection<RestDefinition> restDefinitions, boolean addToRoutes) throws Exception {
+        getModelCamelContext().addRestDefinitions(restDefinitions, addToRoutes);
+    }
+
+    @Override
+    public void setDataFormats(Map<String, DataFormatDefinition> dataFormats) {
+        getModelCamelContext().setDataFormats(dataFormats);
+    }
+
+    @Override
+    public Map<String, DataFormatDefinition> getDataFormats() {
+        return getModelCamelContext().getDataFormats();
+    }
+
+    @Override
+    public DataFormatDefinition resolveDataFormatDefinition(String name) {
+        return getModelCamelContext().resolveDataFormatDefinition(name);
+    }
+
+    @Override
+    public ProcessorDefinition<?> getProcessorDefinition(String id) {
+        return getModelCamelContext().getProcessorDefinition(id);
+    }
+
+    @Override
+    public <T extends ProcessorDefinition<T>> T getProcessorDefinition(String id, Class<T> type) {
+        return getModelCamelContext().getProcessorDefinition(id, type);
+    }
+
+    @Override
+    public void setValidators(List<ValidatorDefinition> validators) {
+        getModelCamelContext().setValidators(validators);
+    }
+
+    @Override
+    public HystrixConfigurationDefinition getHystrixConfiguration(String id) {
+        return getModelCamelContext().getHystrixConfiguration(id);
+    }
+
+    @Override
+    public void setHystrixConfiguration(HystrixConfigurationDefinition configuration) {
+        getModelCamelContext().setHystrixConfiguration(configuration);
+    }
+
+    @Override
+    public void setHystrixConfigurations(List<HystrixConfigurationDefinition> configurations) {
+        getModelCamelContext().setHystrixConfigurations(configurations);
+    }
+
+    @Override
+    public void addHystrixConfiguration(String id, HystrixConfigurationDefinition configuration) {
+        getModelCamelContext().addHystrixConfiguration(id, configuration);
+    }
+
+    @Override
+    public Resilience4jConfigurationDefinition getResilience4jConfiguration(String id) {
+        return getModelCamelContext().getResilience4jConfiguration(id);
+    }
+
+    @Override
+    public void setResilience4jConfiguration(Resilience4jConfigurationDefinition configuration) {
+        getModelCamelContext().setResilience4jConfiguration(configuration);
+    }
+
+    @Override
+    public void setResilience4jConfigurations(List<Resilience4jConfigurationDefinition> configurations) {
+        getModelCamelContext().setResilience4jConfigurations(configurations);
+    }
+
+    @Override
+    public void addResilience4jConfiguration(String id, Resilience4jConfigurationDefinition configuration) {
+        getModelCamelContext().addResilience4jConfiguration(id, configuration);
+    }
+
+    @Override
+    public List<ValidatorDefinition> getValidators() {
+        return getModelCamelContext().getValidators();
+    }
+
+    @Override
+    public void setTransformers(List<TransformerDefinition> transformers) {
+        getModelCamelContext().setTransformers(transformers);
+    }
+
+    @Override
+    public List<TransformerDefinition> getTransformers() {
+        return getModelCamelContext().getTransformers();
+    }
+
+    @Override
+    public ServiceCallConfigurationDefinition getServiceCallConfiguration(String serviceName) {
+        return getModelCamelContext().getServiceCallConfiguration(serviceName);
+    }
+
+    @Override
+    public void setServiceCallConfiguration(ServiceCallConfigurationDefinition configuration) {
+        getModelCamelContext().setServiceCallConfiguration(configuration);
+    }
+
+    @Override
+    public void setServiceCallConfigurations(List<ServiceCallConfigurationDefinition> configurations) {
+        getModelCamelContext().setServiceCallConfigurations(configurations);
+    }
+
+    @Override
+    public void addServiceCallConfiguration(String serviceName, ServiceCallConfigurationDefinition configuration) {
+        getModelCamelContext().addServiceCallConfiguration(serviceName, configuration);
+    }
+
+    @Override
+    public void startRouteDefinitions() throws Exception {
+        getModelCamelContext().startRouteDefinitions();
+    }
+
+    @Override
+    public void startRouteDefinitions(List<RouteDefinition> routeDefinitions) throws Exception {
+        getModelCamelContext().startRouteDefinitions(routeDefinitions);
+    }
+
+    @Override
+    public void setRouteFilterPattern(String include, String exclude) {
+        getModelCamelContext().setRouteFilterPattern(include, exclude);
+    }
+
+    @Override
+    public void setRouteFilter(Function<RouteDefinition, Boolean> filter) {
+        getModelCamelContext().setRouteFilter(filter);
+    }
+
+    @Override
+    public Function<RouteDefinition, Boolean> getRouteFilter() {
+        return getModelCamelContext().getRouteFilter();
+    }
+
+    //
+    // Immutable
+    //
+
+    public void makeImmutable() {
+        if (delegate instanceof RuntimeImmutableCamelContext) {
+            throw new IllegalStateException();
+        }
+        delegate.setAutoStartup(false);
+        delegate.start();
+        delegate = new RuntimeImmutableCamelContext(this, delegate);
+    }
+
+    public void startImmutable() {
+        delegate.start();
+    }
+
+}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
new file mode 100644
index 0000000..fbabf55
--- /dev/null
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
@@ -0,0 +1,1820 @@
+/*
+ * 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.lw;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.apache.camel.AsyncProcessor;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.CatalogCamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.ConsumerTemplate;
+import org.apache.camel.Endpoint;
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.ExchangeConstantProvider;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.GlobalEndpointConfiguration;
+import org.apache.camel.IsSingleton;
+import org.apache.camel.NoSuchEndpointException;
+import org.apache.camel.NoSuchLanguageException;
+import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.ResolveEndpointFailedException;
+import org.apache.camel.Route;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.Service;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.ShutdownRoute;
+import org.apache.camel.ShutdownRunningTask;
+import org.apache.camel.StartupListener;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.ValueHolder;
+import org.apache.camel.catalog.RuntimeCamelCatalog;
+import org.apache.camel.impl.converter.CoreTypeConverterRegistry;
+import org.apache.camel.impl.engine.DefaultComponentResolver;
+import org.apache.camel.impl.engine.DefaultDataFormatResolver;
+import org.apache.camel.impl.engine.DefaultLanguageResolver;
+import org.apache.camel.impl.engine.EndpointKey;
+import org.apache.camel.spi.AnnotationBasedProcessorFactory;
+import org.apache.camel.spi.AsyncProcessorAwaitManager;
+import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.spi.BeanProcessorFactory;
+import org.apache.camel.spi.BeanProxyFactory;
+import org.apache.camel.spi.CamelBeanPostProcessor;
+import org.apache.camel.spi.CamelContextNameStrategy;
+import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.spi.ComponentResolver;
+import org.apache.camel.spi.ConfigurerResolver;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataFormatResolver;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Debugger;
+import org.apache.camel.spi.DeferServiceFactory;
+import org.apache.camel.spi.EndpointRegistry;
+import org.apache.camel.spi.EndpointStrategy;
+import org.apache.camel.spi.ExecutorServiceManager;
+import org.apache.camel.spi.FactoryFinder;
+import org.apache.camel.spi.FactoryFinderResolver;
+import org.apache.camel.spi.HeadersMapFactory;
+import org.apache.camel.spi.InflightRepository;
+import org.apache.camel.spi.Injector;
+import org.apache.camel.spi.InterceptSendToEndpoint;
+import org.apache.camel.spi.InterceptStrategy;
+import org.apache.camel.spi.Language;
+import org.apache.camel.spi.LanguageResolver;
+import org.apache.camel.spi.LifecycleStrategy;
+import org.apache.camel.spi.LogListener;
+import org.apache.camel.spi.ManagementMBeanAssembler;
+import org.apache.camel.spi.ManagementNameStrategy;
+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.NodeIdFactory;
+import org.apache.camel.spi.NormalizedEndpointUri;
+import org.apache.camel.spi.PackageScanClassResolver;
+import org.apache.camel.spi.PackageScanResourceResolver;
+import org.apache.camel.spi.ProcessorFactory;
+import org.apache.camel.spi.PropertiesComponent;
+import org.apache.camel.spi.ReactiveExecutor;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.spi.RestConfiguration;
+import org.apache.camel.spi.RestRegistry;
+import org.apache.camel.spi.RouteController;
+import org.apache.camel.spi.RoutePolicyFactory;
+import org.apache.camel.spi.RouteStartupOrder;
+import org.apache.camel.spi.RuntimeEndpointRegistry;
+import org.apache.camel.spi.ShutdownStrategy;
+import org.apache.camel.spi.StreamCachingStrategy;
+import org.apache.camel.spi.Tracer;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.TransformerRegistry;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.spi.UnitOfWorkFactory;
+import org.apache.camel.spi.UuidGenerator;
+import org.apache.camel.spi.Validator;
+import org.apache.camel.spi.ValidatorRegistry;
+import org.apache.camel.spi.XMLRoutesDefinitionLoader;
+import org.apache.camel.support.CamelContextHelper;
+import org.apache.camel.support.NormalizedUri;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.TimeUtils;
+import org.apache.camel.util.URISupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RuntimeImmutableCamelContext implements ExtendedCamelContext, CatalogCamelContext {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RuntimeImmutableCamelContext.class);
+
+    private final CamelContext reference;
+    private final Registry registry;
+    private final CoreTypeConverterRegistry typeConverter;
+    private final ModelJAXBContextFactory modelJAXBContextFactory;
+    private final RuntimeCamelCatalog camelRuntimeCatalog;
+    private final ComponentResolver componentResolver;
+    private final LanguageResolver languageResolver;
+    private final DataFormatResolver dataFormatResolver;
+    private final UuidGenerator uuidGenerator;
+    private final EndpointRegistry<EndpointKey> endpoints;
+    private final Map<String, Component> components;
+    private final Map<String, Language> languages;
+    private final PropertiesComponent propertiesComponent;
+    private final BeanIntrospection beanIntrospection;
+    private final HeadersMapFactory headersMapFactory;
+    private final ReactiveExecutor reactiveExecutor;
+    private final AsyncProcessorAwaitManager asyncProcessorAwaitManager;
+    private final ExecutorServiceManager executorServiceManager;
+    private final ShutdownStrategy shutdownStrategy;
+    private final ClassLoader applicationContextClassLoader;
+    private final UnitOfWorkFactory unitOfWorkFactory;
+    private final RouteController routeController;
+    private final InflightRepository inflightRepository;
+    private final Injector injector;
+    private final ClassResolver classResolver;
+    private final Map<String, String> globalOptions;
+    private final String name;
+    private final boolean eventNotificationApplicable;
+    private final boolean useDataType;
+    private final boolean useBreadcrumb;
+    private final String mdcLoggingKeysPattern;
+    private final boolean useMDCLogging;
+    private final List<Route> routes;
+    private final boolean messageHistory;
+    private final boolean allowUseOriginalMessage;
+    private final String version;
+    private Date startDate;
+
+    RuntimeImmutableCamelContext(CamelContext reference, CamelContext context) {
+        this.reference = reference;
+        registry = context.getRegistry();
+        typeConverter = new CoreTypeConverterRegistry(context.getTypeConverterRegistry());
+        modelJAXBContextFactory = context.adapt(ExtendedCamelContext.class).getModelJAXBContextFactory();
+        camelRuntimeCatalog = context.adapt(ExtendedCamelContext.class).getRuntimeCamelCatalog();
+        routes = Collections.unmodifiableList(context.getRoutes());
+        uuidGenerator = context.getUuidGenerator();
+        componentResolver = context.adapt(ExtendedCamelContext.class).getComponentResolver();
+        languageResolver = context.adapt(ExtendedCamelContext.class).getLanguageResolver();
+        dataFormatResolver = context.adapt(ExtendedCamelContext.class).getDataFormatResolver();
+        endpoints = (EndpointRegistry) context.getEndpointRegistry();
+        components = context.getComponentNames().stream()
+                .collect(Collectors.toMap(s -> s, s -> context.hasComponent(s)));
+        languages = context.getLanguageNames().stream()
+                .collect(Collectors.toMap(s -> s, s -> context.resolveLanguage(s)));
+        propertiesComponent = context.getPropertiesComponent();
+        beanIntrospection = context.adapt(ExtendedCamelContext.class).getBeanIntrospection();
+        headersMapFactory = context.adapt(ExtendedCamelContext.class).getHeadersMapFactory();
+        reactiveExecutor = context.adapt(ExtendedCamelContext.class).getReactiveExecutor();
+        asyncProcessorAwaitManager = context.adapt(ExtendedCamelContext.class).getAsyncProcessorAwaitManager();
+        executorServiceManager = context.getExecutorServiceManager();
+        shutdownStrategy = context.getShutdownStrategy();
+        applicationContextClassLoader = context.getApplicationContextClassLoader();
+        unitOfWorkFactory = context.adapt(ExtendedCamelContext.class).getUnitOfWorkFactory();
+        routeController = context.getRouteController();
+        inflightRepository = context.getInflightRepository();
+        globalOptions = context.getGlobalOptions();
+        injector = context.getInjector();
+        classResolver = context.getClassResolver();
+        name = context.getName();
+        eventNotificationApplicable = context.adapt(ExtendedCamelContext.class).isEventNotificationApplicable();
+        useDataType = context.isUseDataType();
+        useBreadcrumb = context.isUseBreadcrumb();
+        mdcLoggingKeysPattern = context.getMDCLoggingKeysPattern();
+        useMDCLogging = context.isUseMDCLogging();
+        messageHistory = context.isMessageHistory();
+        allowUseOriginalMessage = context.isAllowUseOriginalMessage();
+        version = context.getVersion();
+    }
+
+    public CamelContext getCamelContextReference() {
+        return reference;
+    }
+
+    //
+    // Lifecycle
+    //
+
+    @Override
+    public boolean isStarted() {
+        return false;
+    }
+
+    @Override
+    public boolean isStarting() {
+        return false;
+    }
+
+    @Override
+    public boolean isStopped() {
+        return false;
+    }
+
+    @Override
+    public boolean isStopping() {
+        return false;
+    }
+
+    @Override
+    public boolean isSuspended() {
+        return false;
+    }
+
+    @Override
+    public boolean isRunAllowed() {
+        return false;
+    }
+
+    @Override
+    public boolean isSuspending() {
+        return false;
+    }
+
+    @Override
+    public void init() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void suspend() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void resume() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void start() {
+        startDate = new Date();
+        LOG.info("Apache Camel {} (CamelContext: {}) is starting", getVersion(), getName());
+        for (Route route : routes) {
+            route.getConsumer().start();
+        }
+    }
+
+    @Override
+    public void stop() {
+        for (Route route : routes) {
+            route.getConsumer().stop();
+        }
+    }
+
+    @Override
+    public void shutdown() {
+    }
+
+    @Override
+    public void close() throws IOException {
+        stop();
+    }
+
+    //
+    // RuntimeConfig
+    //
+
+    @Override
+    public void setStreamCaching(Boolean cache) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isStreamCaching() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isTracing() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getTracingPattern() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isBacklogTracing() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isDebugging() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isMessageHistory() {
+        return messageHistory;
+    }
+
+    @Override
+    public Boolean isLogMask() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isLogExhaustedMessageBody() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Long getDelayer() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isAutoStartup() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ShutdownRoute getShutdownRoute() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ShutdownRunningTask getShutdownRunningTask() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setAllowUseOriginalMessage(Boolean allowUseOriginalMessage) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isAllowUseOriginalMessage() {
+        return allowUseOriginalMessage;
+    }
+
+    @Override
+    public Boolean isCaseInsensitiveHeaders() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setCaseInsensitiveHeaders(Boolean caseInsensitiveHeaders) {
+        throw new UnsupportedOperationException();
+    }
+
+
+    //
+    // Model
+    //
+
+    @Override
+    public Registry getRegistry() {
+        return registry;
+    }
+
+    @Override
+    public TypeConverterRegistry getTypeConverterRegistry() {
+        return typeConverter;
+    }
+
+    @Override
+    public ModelJAXBContextFactory getModelJAXBContextFactory() {
+        return modelJAXBContextFactory;
+    }
+
+    @Override
+    public ComponentResolver getComponentResolver() {
+        return componentResolver;
+    }
+
+    @Override
+    public LanguageResolver getLanguageResolver() {
+        return languageResolver;
+    }
+
+    @Override
+    public DataFormatResolver getDataFormatResolver() {
+        return dataFormatResolver;
+    }
+
+    @Override
+    public UuidGenerator getUuidGenerator() {
+        return uuidGenerator;
+    }
+
+    @Override
+    public <T extends CamelContext> T adapt(Class<T> type) {
+        if (type.isInstance(this)) {
+            return type.cast(this);
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T> T getExtension(Class<T> type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T> void setExtension(Class<T> type, T module) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isVetoStarted() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public CamelContextNameStrategy getNameStrategy() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setNameStrategy(CamelContextNameStrategy nameStrategy) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ManagementNameStrategy getManagementNameStrategy() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setManagementNameStrategy(ManagementNameStrategy nameStrategy) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getManagementName() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setManagementName(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getVersion() {
+        return version;
+    }
+
+    @Override
+    public ServiceStatus getStatus() {
+        return ServiceStatus.Started;
+    }
+
+    @Override
+    public String getUptime() {
+        long delta = getUptimeMillis();
+        if (delta == 0) {
+            return "";
+        }
+        return TimeUtils.printDuration(delta);
+    }
+
+    @Override
+    public long getUptimeMillis() {
+        if (startDate == null) {
+            return 0;
+        }
+        return new Date().getTime() - startDate.getTime();
+    }
+
+    @Override
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    @Override
+    public void addService(Object object) throws Exception {
+    }
+
+    @Override
+    public void addService(Object object, boolean stopOnShutdown) throws Exception {
+
+    }
+
+    @Override
+    public void addService(Object object, boolean stopOnShutdown, boolean forceStart) throws Exception {
+
+    }
+
+    @Override
+    public void addPrototypeService(Object object) throws Exception {
+
+    }
+
+    @Override
+    public boolean removeService(Object object) throws Exception {
+        return false;
+    }
+
+    @Override
+    public boolean hasService(Object object) {
+        return false;
+    }
+
+    @Override
+    public <T> T hasService(Class<T> type) {
+        return null;
+    }
+
+    @Override
+    public <T> Set<T> hasServices(Class<T> type) {
+        return null;
+    }
+
+    @Override
+    public void deferStartService(Object object, boolean stopOnShutdown) throws Exception {
+    }
+
+    @Override
+    public void addStartupListener(StartupListener listener) throws Exception {
+    }
+
+    @Override
+    public Component hasComponent(String componentName) {
+        return components.get(componentName);
+    }
+
+    @Override
+    public Component getComponent(String componentName) {
+        return getComponent(name, true, true);
+    }
+
+    @Override
+    public Component getComponent(String name, boolean autoCreateComponents) {
+        return getComponent(name, autoCreateComponents, true);
+    }
+
+    @Override
+    public Component getComponent(String name, boolean autoCreateComponents, boolean autoStart) {
+        return components.get(name);
+    }
+
+    @Override
+    public <T extends Component> T getComponent(String name, Class<T> componentType) {
+        return componentType.cast(hasComponent(name));
+    }
+
+    @Override
+    public List<String> getComponentNames() {
+        return new ArrayList<>(components.keySet());
+    }
+
+    @Override
+    public EndpointRegistry<? extends ValueHolder<String>> getEndpointRegistry() {
+        return endpoints;
+    }
+
+    @Override
+    public Endpoint getEndpoint(String uri) {
+        return doGetEndpoint(uri, false, false);
+    }
+
+    /**
+     * Normalize uri so we can do endpoint hits with minor mistakes and
+     * parameters is not in the same order.
+     *
+     * @param uri the uri
+     * @return normalized uri
+     * @throws ResolveEndpointFailedException if uri cannot be normalized
+     */
+    protected static String normalizeEndpointUri(String uri) {
+        try {
+            uri = URISupport.normalizeUri(uri);
+        } catch (Exception e) {
+            throw new ResolveEndpointFailedException(uri, e);
+        }
+        return uri;
+    }
+
+    @Override
+    public Endpoint getEndpoint(String uri, Map<String, Object> parameters) {
+        return doGetEndpoint(uri, parameters, false);
+    }
+
+    @Override
+    public <T extends Endpoint> T getEndpoint(String name, Class<T> endpointType) {
+        Endpoint endpoint = getEndpoint(name);
+        if (endpoint == null) {
+            throw new NoSuchEndpointException(name);
+        }
+        if (endpoint instanceof InterceptSendToEndpoint) {
+            endpoint = ((InterceptSendToEndpoint)endpoint).getOriginalEndpoint();
+        }
+        if (endpointType.isInstance(endpoint)) {
+            return endpointType.cast(endpoint);
+        } else {
+            throw new IllegalArgumentException("The endpoint is not of type: " + endpointType + " but is: " + endpoint.getClass().getCanonicalName());
+        }
+    }
+
+    @Override
+    public Collection<Endpoint> getEndpoints() {
+        return new ArrayList<>(endpoints.values());
+    }
+
+    @Override
+    public Map<String, Endpoint> getEndpointMap() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Endpoint hasEndpoint(String uri) {
+        return endpoints.get(new EndpointKey(uri));
+    }
+
+    @Override
+    public GlobalEndpointConfiguration getGlobalEndpointConfiguration() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RouteController getRouteController() {
+        return routeController;
+    }
+
+    @Override
+    public List<Route> getRoutes() {
+        return routes;
+    }
+
+    @Override
+    public int getRoutesSize() {
+        return routes.size();
+    }
+
+    @Override
+    public Route getRoute(String id) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Processor getProcessor(String id) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T extends Processor> T getProcessor(String id, Class<T> type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<RoutePolicyFactory> getRoutePolicyFactories() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RestConfiguration getRestConfiguration() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RestConfiguration getRestConfiguration(String component, boolean defaultIfNotFound) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Collection<RestConfiguration> getRestConfigurations() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RestRegistry getRestRegistry() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public TypeConverter getTypeConverter() {
+        return typeConverter;
+    }
+
+    @Override
+    public <T> T getRegistry(Class<T> type) {
+        return type.cast(registry);
+    }
+
+    @Override
+    public Injector getInjector() {
+        return injector;
+    }
+
+    @Override
+    public List<LifecycleStrategy> getLifecycleStrategies() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Language resolveLanguage(String language) throws NoSuchLanguageException {
+        Language answer;
+        synchronized (languages) {
+            answer = languages.get(language);
+            // check if the language is singleton, if so return the shared
+            // instance
+            if (answer instanceof IsSingleton) {
+                boolean singleton = ((IsSingleton)answer).isSingleton();
+                if (singleton) {
+                    return answer;
+                }
+            }
+            // language not known or not singleton, then use resolver
+            answer = getLanguageResolver().resolveLanguage(language, reference);
+            // inject CamelContext if aware
+            if (answer != null) {
+                if (answer instanceof CamelContextAware) {
+                    ((CamelContextAware)answer).setCamelContext(reference);
+                }
+                if (answer instanceof Service) {
+                    try {
+                        startService((Service)answer);
+                    } catch (Exception e) {
+                        throw RuntimeCamelException.wrapRuntimeCamelException(e);
+                    }
+                }
+                languages.put(language, answer);
+            }
+        }
+        return answer;
+    }
+
+    @Override
+    public String resolvePropertyPlaceholders(String text) {
+        if (text != null && text.contains(PropertiesComponent.PREFIX_TOKEN)) {
+            // the parser will throw exception if property key was not found
+            return getPropertiesComponent().parseUri(text);
+        }
+        // is the value a known field (currently we only support
+        // constants from Exchange.class)
+        if (text != null && text.startsWith("Exchange.")) {
+            String field = StringHelper.after(text, "Exchange.");
+            String constant = ExchangeConstantProvider.lookup(field);
+            if (constant != null) {
+                return constant;
+            } else {
+                throw new IllegalArgumentException("Constant field with name: " + field + " not found on Exchange.class");
+            }
+        }
+        // return original text as is
+        return text;
+    }
+
+    @Override
+    public PropertiesComponent getPropertiesComponent() {
+        return propertiesComponent;
+    }
+
+    @Override
+    public List<String> getLanguageNames() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ProducerTemplate createProducerTemplate() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ProducerTemplate createProducerTemplate(int maximumCacheSize) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FluentProducerTemplate createFluentProducerTemplate() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FluentProducerTemplate createFluentProducerTemplate(int maximumCacheSize) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ConsumerTemplate createConsumerTemplate() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ConsumerTemplate createConsumerTemplate(int maximumCacheSize) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DataFormat resolveDataFormat(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DataFormat createDataFormat(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Transformer resolveTransformer(String model) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Transformer resolveTransformer(DataType from, DataType to) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public TransformerRegistry getTransformerRegistry() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Validator resolveValidator(DataType type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ValidatorRegistry getValidatorRegistry() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setGlobalOptions(Map<String, String> globalOptions) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Map<String, String> getGlobalOptions() {
+        return globalOptions;
+    }
+
+    @Override
+    public String getGlobalOption(String key) {
+        String value = getGlobalOptions().get(key);
+        if (ObjectHelper.isNotEmpty(value)) {
+            try {
+                value = resolvePropertyPlaceholders(value);
+            } catch (Exception e) {
+                throw new RuntimeCamelException("Error getting global option: " + key, e);
+            }
+        }
+        return value;
+    }
+
+    @Override
+    public ClassResolver getClassResolver() {
+        return classResolver;
+    }
+
+    @Override
+    public ManagementStrategy getManagementStrategy() {
+        return null;
+    }
+
+    @Override
+    public void disableJMX() throws IllegalStateException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public InflightRepository getInflightRepository() {
+        return inflightRepository;
+    }
+
+    @Override
+    public ClassLoader getApplicationContextClassLoader() {
+        return applicationContextClassLoader;
+    }
+
+    @Override
+    public ShutdownStrategy getShutdownStrategy() {
+        return shutdownStrategy;
+    }
+
+    @Override
+    public ExecutorServiceManager getExecutorServiceManager() {
+        return executorServiceManager;
+    }
+
+    @Override
+    public MessageHistoryFactory getMessageHistoryFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Debugger getDebugger() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Tracer getTracer() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isLoadTypeConverters() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setLoadTypeConverters(Boolean loadTypeConverters) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isTypeConverterStatisticsEnabled() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setTypeConverterStatisticsEnabled(Boolean typeConverterStatisticsEnabled) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isUseMDCLogging() {
+        return useMDCLogging;
+    }
+
+    @Override
+    public void setUseMDCLogging(Boolean useMDCLogging) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getMDCLoggingKeysPattern() {
+        return mdcLoggingKeysPattern;
+    }
+
+    @Override
+    public void setMDCLoggingKeysPattern(String pattern) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isUseDataType() {
+        return useDataType;
+    }
+
+    @Override
+    public void setUseDataType(Boolean useDataType) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Boolean isUseBreadcrumb() {
+        return useBreadcrumb;
+    }
+
+    @Override
+    public void setUseBreadcrumb(Boolean useBreadcrumb) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public StreamCachingStrategy getStreamCachingStrategy() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RuntimeEndpointRegistry getRuntimeEndpointRegistry() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public SSLContextParameters getSSLContextParameters() {
+        throw new UnsupportedOperationException();
+    }
+
+    //
+    // ExtendedCamelContext
+    //
+
+    @Override
+    public Endpoint getPrototypeEndpoint(String uri) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Endpoint getPrototypeEndpoint(NormalizedEndpointUri uri) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Endpoint hasEndpoint(NormalizedEndpointUri uri) {
+        EndpointKey key;
+        if (uri instanceof EndpointKey) {
+            key = (EndpointKey) uri;
+        } else {
+            key = getEndpointKeyPreNormalized(uri.getUri());
+        }
+        return endpoints.get(key);
+    }
+
+    @Override
+    public Endpoint getEndpoint(NormalizedEndpointUri uri) {
+        return doGetEndpoint(uri.getUri(), true, false);
+    }
+
+    @Override
+    public Endpoint getEndpoint(NormalizedEndpointUri uri, Map<String, Object> parameters) {
+        return doGetEndpoint(uri.getUri(), parameters, true);
+    }
+
+    protected Endpoint doGetEndpoint(String uri, boolean normalized, boolean prototype) {
+        StringHelper.notEmpty(uri, "uri");
+        // in case path has property placeholders then try to let property
+        // component resolve those
+        if (!normalized) {
+            try {
+                uri = resolvePropertyPlaceholders(uri);
+            } catch (Exception e) {
+                throw new ResolveEndpointFailedException(uri, e);
+            }
+        }
+        final String rawUri = uri;
+        // normalize uri so we can do endpoint hits with minor mistakes and
+        // parameters is not in the same order
+        if (!normalized) {
+            uri = normalizeEndpointUri(uri);
+        }
+        String scheme;
+        Endpoint answer = null;
+        if (!prototype) {
+            // use optimized method to get the endpoint uri
+            EndpointKey key = getEndpointKeyPreNormalized(uri);
+            // only lookup and reuse existing endpoints if not prototype scoped
+            answer = endpoints.get(key);
+        }
+        // unknown scheme
+        if (answer == null) {
+            throw new NoSuchEndpointException(uri);
+        }
+        return answer;
+    }
+
+    protected Endpoint doGetEndpoint(String uri, Map<String, Object> parameters, boolean normalized) {
+        StringHelper.notEmpty(uri, "uri");
+        // in case path has property placeholders then try to let property
+        // component resolve those
+        if (!normalized) {
+            try {
+                uri = resolvePropertyPlaceholders(uri);
+            } catch (Exception e) {
+                throw new ResolveEndpointFailedException(uri, e);
+            }
+        }
+        final String rawUri = uri;
+        // normalize uri so we can do endpoint hits with minor mistakes and
+        // parameters is not in the same order
+        if (!normalized) {
+            uri = normalizeEndpointUri(uri);
+        }
+        Endpoint answer;
+        String scheme = null;
+        // use optimized method to get the endpoint uri
+        EndpointKey key = getEndpointKeyPreNormalized(uri);
+        answer = endpoints.get(key);
+        // unknown scheme
+        if (answer == null) {
+            throw new ResolveEndpointFailedException(uri, "No component found with scheme: " + scheme);
+        }
+        return answer;
+    }
+
+    protected EndpointKey getEndpointKeyPreNormalized(String uri) {
+        return new EndpointKey(uri, true);
+    }
+
+    @Override
+    public NormalizedEndpointUri normalizeUri(String uri) {
+        try {
+            uri = resolvePropertyPlaceholders(uri);
+            uri = normalizeEndpointUri(uri);
+            return new NormalizedUri(uri);
+        } catch (Exception e) {
+            throw new ResolveEndpointFailedException(uri, e);
+        }
+    }
+
+    @Override
+    public List<RouteStartupOrder> getRouteStartupOrder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CamelBeanPostProcessor getBeanPostProcessor() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ManagementMBeanAssembler getManagementMBeanAssembler() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AsyncProcessor createMulticast(Collection<Processor> processors, ExecutorService executor, boolean shutdownExecutorService) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ErrorHandlerFactory getErrorHandlerFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PackageScanClassResolver getPackageScanClassResolver() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PackageScanResourceResolver getPackageScanResourceResolver() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FactoryFinder getDefaultFactoryFinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FactoryFinder getFactoryFinder(String path) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FactoryFinderResolver getFactoryFinderResolver() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ProcessorFactory getProcessorFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DeferServiceFactory getDeferServiceFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public UnitOfWorkFactory getUnitOfWorkFactory() {
+        return unitOfWorkFactory;
+    }
+
+    @Override
+    public AnnotationBasedProcessorFactory getAnnotationBasedProcessorFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public BeanProxyFactory getBeanProxyFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public BeanProcessorFactory getBeanProcessorFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ScheduledExecutorService getErrorHandlerExecutorService() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<InterceptStrategy> getInterceptStrategies() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<LogListener> getLogListeners() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AsyncProcessorAwaitManager getAsyncProcessorAwaitManager() {
+        return asyncProcessorAwaitManager;
+    }
+
+    @Override
+    public BeanIntrospection getBeanIntrospection() {
+        return beanIntrospection;
+    }
+
+    @Override
+    public HeadersMapFactory getHeadersMapFactory() {
+        return headersMapFactory;
+    }
+
+    @Override
+    public ReactiveExecutor getReactiveExecutor() {
+        return reactiveExecutor;
+    }
+
+    @Override
+    public boolean isEventNotificationApplicable() {
+        return eventNotificationApplicable;
+    }
+
+    @Override
+    public ModelToXMLDumper getModelToXMLDumper() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RuntimeCamelCatalog getRuntimeCamelCatalog() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ConfigurerResolver getConfigurerResolver() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isAllowAddingNewRoutes() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isClearModelReferences() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addRoute(Route route) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeRoute(Route route) {
+        throw new UnsupportedOperationException();
+    }
+
+    //
+    // CatalogCamelContext
+    //
+
+    @Override
+    public String getComponentParameterJsonSchema(String componentName) throws IOException {
+        Class<?> clazz;
+        Object instance = getRegistry().lookupByNameAndType(componentName, Component.class);
+        if (instance != null) {
+            clazz = instance.getClass();
+        } else {
+            clazz = getFactoryFinder(DefaultComponentResolver.RESOURCE_PATH).findClass(componentName).orElse(null);
+            if (clazz == null) {
+                instance = hasComponent(componentName);
+                if (instance != null) {
+                    clazz = instance.getClass();
+                } else {
+                    return null;
+                }
+            }
+        }
+        // special for ActiveMQ as it is really just JMS
+        if ("ActiveMQComponent".equals(clazz.getSimpleName())) {
+            return getComponentParameterJsonSchema("jms");
+        } else {
+            return getJsonSchema(clazz.getPackage().getName(), componentName);
+        }
+    }
+
+    @Override
+    public String getDataFormatParameterJsonSchema(String dataFormatName) throws IOException {
+        Class<?> clazz;
+        Object instance = getRegistry().lookupByNameAndType(dataFormatName, DataFormat.class);
+        if (instance != null) {
+            clazz = instance.getClass();
+        } else {
+            clazz = getFactoryFinder(DefaultDataFormatResolver.DATAFORMAT_RESOURCE_PATH).findClass(dataFormatName).orElse(null);
+            if (clazz == null) {
+                return null;
+            }
+        }
+        return getJsonSchema(clazz.getPackage().getName(), dataFormatName);
+    }
+
+    @Override
+    public String getLanguageParameterJsonSchema(String languageName) throws IOException {
+        Class<?> clazz;
+        Object instance = getRegistry().lookupByNameAndType(languageName, Language.class);
+        if (instance != null) {
+            clazz = instance.getClass();
+        } else {
+            clazz = getFactoryFinder(DefaultLanguageResolver.LANGUAGE_RESOURCE_PATH).findClass(languageName).orElse(null);
+            if (clazz == null) {
+                return null;
+            }
+        }
+        return getJsonSchema(clazz.getPackage().getName(), languageName);
+    }
+
+    @Override
+    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" };
+        for (String sub : subPackages) {
+            String path = CamelContextHelper.MODEL_DOCUMENTATION_PREFIX + sub + "/" + eipName + ".json";
+            InputStream inputStream = getClassResolver().loadResourceAsStream(path);
+            if (inputStream != null) {
+                try {
+                    return IOHelper.loadText(inputStream);
+                } finally {
+                    IOHelper.close(inputStream);
+                }
+            }
+        }
+        return null;
+    }
+
+    private String getJsonSchema(String packageName, String name) throws IOException {
+        String path = packageName.replace('.', '/') + "/" + name + ".json";
+        InputStream inputStream = getClassResolver().loadResourceAsStream(path);
+        if (inputStream != null) {
+            try {
+                return IOHelper.loadText(inputStream);
+            } finally {
+                IOHelper.close(inputStream);
+            }
+        }
+        return null;
+    }
+
+    //
+    // Unsupported mutable methods
+    //
+
+    @Override
+    public void setName(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setRegistry(Registry registry) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setupRoutes(boolean done) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isSetupRoutes() {
+        return false;
+    }
+
+    @Override
+    public void setStreamCachingStrategy(StreamCachingStrategy streamCachingStrategy) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setErrorHandlerFactory(ErrorHandlerFactory errorHandlerFactory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setComponentResolver(ComponentResolver componentResolver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setLanguageResolver(LanguageResolver languageResolver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setDataFormatResolver(DataFormatResolver dataFormatResolver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPackageScanClassResolver(PackageScanClassResolver resolver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPackageScanResourceResolver(PackageScanResourceResolver resolver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setFactoryFinderResolver(FactoryFinderResolver resolver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setProcessorFactory(ProcessorFactory processorFactory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setModelJAXBContextFactory(ModelJAXBContextFactory modelJAXBContextFactory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setUnitOfWorkFactory(UnitOfWorkFactory unitOfWorkFactory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addInterceptStrategy(InterceptStrategy interceptStrategy) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setupManagement(Map<String, Object> options) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addLogListener(LogListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setAsyncProcessorAwaitManager(AsyncProcessorAwaitManager manager) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setBeanIntrospection(BeanIntrospection beanIntrospection) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setHeadersMapFactory(HeadersMapFactory factory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setReactiveExecutor(ReactiveExecutor reactiveExecutor) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setEventNotificationApplicable(boolean eventNotificationApplicable) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setXMLRoutesDefinitionLoader(XMLRoutesDefinitionLoader xmlRoutesDefinitionLoader) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setModelToXMLDumper(ModelToXMLDumper modelToXMLDumper) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setRuntimeCamelCatalog(RuntimeCamelCatalog runtimeCamelCatalog) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setConfigurerResolver(ConfigurerResolver configurerResolver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setAllowAddingNewRoutes(boolean allowAddingNewRoutes) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setClearModelReferences(boolean clearModelReferences) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public XMLRoutesDefinitionLoader getXMLRoutesDefinitionLoader() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void registerEndpointCallback(EndpointStrategy strategy) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setNodeIdFactory(NodeIdFactory factory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Endpoint addEndpoint(String uri, Endpoint endpoint) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeEndpoint(Endpoint endpoint) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Collection<Endpoint> removeEndpoints(String pattern) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeIdFactory getNodeIdFactory() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setRuntimeEndpointRegistry(RuntimeEndpointRegistry runtimeEndpointRegistry) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setSSLContextParameters(SSLContextParameters sslContextParameters) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setTracer(Tracer tracer) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setUuidGenerator(UuidGenerator uuidGenerator) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addComponent(String componentName, Component component) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Component removeComponent(String componentName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setRouteController(RouteController routeController) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addRoutes(RoutesBuilder builder) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean removeRoute(String routeId) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addRoutePolicyFactory(RoutePolicyFactory routePolicyFactory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setRestConfiguration(RestConfiguration restConfiguration) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addRestConfiguration(RestConfiguration restConfiguration) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setRestRegistry(RestRegistry restRegistry) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setDebugger(Debugger debugger) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setTracing(Boolean tracing) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setTracingPattern(String tracePattern) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setBacklogTracing(Boolean backlogTrace) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setDebugging(Boolean debugging) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setMessageHistory(Boolean messageHistory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setLogMask(Boolean logMask) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setLogExhaustedMessageBody(Boolean logExhaustedMessageBody) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setDelayer(Long delay) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setAutoStartup(Boolean autoStartup) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setShutdownRoute(ShutdownRoute shutdownRoute) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setClassResolver(ClassResolver resolver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setManagementStrategy(ManagementStrategy strategy) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setInflightRepository(InflightRepository repository) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setApplicationContextClassLoader(ClassLoader classLoader) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setShutdownStrategy(ShutdownStrategy shutdownStrategy) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setExecutorServiceManager(ExecutorServiceManager executorServiceManager) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setMessageHistoryFactory(MessageHistoryFactory messageHistoryFactory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setTypeConverterRegistry(TypeConverterRegistry typeConverterRegistry) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setInjector(Injector injector) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addLifecycleStrategy(LifecycleStrategy lifecycleStrategy) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPropertiesComponent(PropertiesComponent propertiesComponent) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RouteController getInternalRouteController() {
+        return new RouteController() {
+            @Override
+            public Collection<Route> getControlledRoutes() {
+                return routes;
+            }
+            @Override
+            public void startAllRoutes() throws Exception {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isStartingRoutes() {
+                return false;
+            }
+            @Override
+            public ServiceStatus getRouteStatus(String routeId) {
+                return ServiceStatus.Started;
+            }
+            @Override
+            public void startRoute(String routeId) throws Exception {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public void stopRoute(String routeId) throws Exception {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public void stopRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean stopRoute(String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public void suspendRoute(String routeId) throws Exception {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public void suspendRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public void resumeRoute(String routeId) throws Exception {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public void setCamelContext(CamelContext camelContext) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public CamelContext getCamelContext() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public void start() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public void stop() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    private void startService(Service service) throws Exception {
+        // and register startup aware so they can be notified when
+        // camel context has been started
+        if (service instanceof StartupListener) {
+            StartupListener listener = (StartupListener)service;
+            addStartupListener(listener);
+        }
+        if (service instanceof CamelContextAware) {
+            CamelContextAware aware = (CamelContextAware)service;
+            aware.setCamelContext(reference);
+        }
+        service.start();
+    }
+}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/Model.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/Model.java
index e03f1d2..4ac17d7 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/Model.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/Model.java
@@ -289,11 +289,6 @@ public interface Model {
     void addServiceCallConfiguration(String serviceName, ServiceCallConfigurationDefinition configuration);
 
     /**
-     * Start all routes from this model.
-     */
-    void startRouteDefinitions() throws Exception;
-
-    /**
      * Used for filtering routes routes matching the given pattern, which
      * follows the following rules: - Match by route id - Match by route input
      * endpoint uri The matching is using exact match, by wildcard and regular
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java
index 7d9fb3f..ea3eafb 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.model;
 
+import java.util.List;
+
 import org.apache.camel.CamelContext;
 
 /**
@@ -23,4 +25,11 @@ import org.apache.camel.CamelContext;
  */
 public interface ModelCamelContext extends CamelContext, Model {
 
+    /**
+     * Start all routes from this model.
+     */
+    void startRouteDefinitions() throws Exception;
+
+    void startRouteDefinitions(List<RouteDefinition> routeDefinitions) throws Exception;
+
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java b/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
index 8af9e69..cae2fed 100644
--- a/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
+++ b/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
@@ -24,6 +24,7 @@ import org.apache.camel.builder.NotifyBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.lw.ImmutableCamelContext;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.Registry;
@@ -43,6 +44,7 @@ public abstract class ContextTestSupport extends TestSupport {
     protected volatile ConsumerTemplate consumer;
     protected volatile NotifyBuilder oneExchangeDone;
     private boolean useRouteBuilder = true;
+    private boolean useImmutableContext = true;
     private Service camelContextService;
 
     /**
@@ -60,6 +62,14 @@ public abstract class ContextTestSupport extends TestSupport {
         this.useRouteBuilder = useRouteBuilder;
     }
 
+    public boolean isUseImmutableContext() {
+        return useImmutableContext;
+    }
+
+    public void setUseImmutableContext(boolean useImmutableContext) {
+        this.useImmutableContext = useImmutableContext;
+    }
+
     public Service getCamelContextService() {
         return camelContextService;
     }
@@ -170,10 +180,14 @@ public abstract class ContextTestSupport extends TestSupport {
         if (camelContextService != null) {
             camelContextService.start();
         } else {
-            if (context instanceof DefaultCamelContext) {
-                DefaultCamelContext defaultCamelContext = (DefaultCamelContext)context;
-                if (!defaultCamelContext.isStarted()) {
-                    defaultCamelContext.start();
+            if (context instanceof ImmutableCamelContext) {
+                ImmutableCamelContext ctx = (ImmutableCamelContext) context;
+                Boolean autoStartup = ctx.isAutoStartup();
+                ctx.setAutoStartup(false);
+                ctx.start();
+                ctx.makeImmutable();
+                if (autoStartup != null && autoStartup) {
+                    ctx.startImmutable();
                 }
             } else {
                 context.start();
@@ -182,11 +196,19 @@ public abstract class ContextTestSupport extends TestSupport {
     }
 
     protected CamelContext createCamelContext() throws Exception {
-        DefaultCamelContext context = new DefaultCamelContext(false);
+        CamelContext context;
+        if (useImmutableContext) {
+            ImmutableCamelContext ctx = new ImmutableCamelContext();
+            ctx.setRegistry(createRegistry());
+            context = ctx;
+        } else {
+            DefaultCamelContext ctx = new DefaultCamelContext(false);
+            ctx.setRegistry(createRegistry());
+            context = ctx;
+        }
         if (!useJmx()) {
             context.disableJMX();
         }
-        context.setRegistry(createRegistry());
         context.setLoadTypeConverters(isLoadTypeConverters());
         return context;
     }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index 3ac7b7b..0c48dee 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -53,8 +53,8 @@ import org.apache.camel.spi.PropertyConfigurer;
 import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.support.LifecycleStrategySupport;
 import org.apache.camel.support.PropertyBindingSupport;
+import org.apache.camel.support.service.BaseService;
 import org.apache.camel.support.service.ServiceHelper;
-import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
@@ -71,7 +71,7 @@ import static org.apache.camel.util.StringHelper.matches;
 /**
  * Base class for main implementations to allow bootstrapping Camel in standalone mode.
  */
-public abstract class BaseMainSupport extends ServiceSupport {
+public abstract class BaseMainSupport extends BaseService {
 
     private static final Logger LOG = LoggerFactory.getLogger(BaseMainSupport.class);
 
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/EndpointHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/EndpointHelper.java
index 11df373..71312ca 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/EndpointHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/EndpointHelper.java
@@ -55,6 +55,23 @@ public final class EndpointHelper {
     }
 
     /**
+     * Normalize uri so we can do endpoint hits with minor mistakes and
+     * parameters is not in the same order.
+     *
+     * @param uri the uri
+     * @return normalized uri
+     * @throws ResolveEndpointFailedException if uri cannot be normalized
+     */
+    public static String normalizeEndpointUri(String uri) {
+        try {
+            uri = URISupport.normalizeUri(uri);
+        } catch (Exception e) {
+            throw new ResolveEndpointFailedException(uri, e);
+        }
+        return uri;
+    }
+
+    /**
      * Creates a {@link PollingConsumer} and polls all pending messages on the endpoint
      * and invokes the given {@link Processor} to process each {@link Exchange} and then closes
      * down the consumer and throws any exceptions thrown.
@@ -120,11 +137,7 @@ public final class EndpointHelper {
         }
 
         // normalize uri so we can do endpoint hits with minor mistakes and parameters is not in the same order
-        try {
-            uri = URISupport.normalizeUri(uri);
-        } catch (Exception e) {
-            throw new ResolveEndpointFailedException(uri, e);
-        }
+        uri = normalizeEndpointUri(uri);
 
         // we need to test with and without scheme separators (//)
         boolean match = PatternHelper.matchPattern(toggleUriSchemeSeparators(uri), pattern);


[camel] 01/09: Remove some warnings

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b003736264dcf235208d45c97671fc72685c9184
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Mar 11 11:10:55 2020 +0100

    Remove some warnings
---
 .../src/main/java/org/apache/camel/support/EventHelper.java              | 1 +
 1 file changed, 1 insertion(+)

diff --git a/core/camel-support/src/main/java/org/apache/camel/support/EventHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/EventHelper.java
index c27a7a2..4dd349a 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/EventHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/EventHelper.java
@@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Helper for easily sending event notifications in a single line of code
  */
+@SuppressWarnings("UnusedReturnValue")
 public final class EventHelper {
 
     // This implementation has been optimized to be as fast and not create unnecessary objects or lambdas.


[camel] 09/09: [CAMEL-14712] Provide an immutable lightweight camel context Merge remote-tracking branch 'origin/master' into immutable

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1024317aa54a7605028b9a05623960760f82d144
Merge: bf4f3ee fbe6416
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Fri Mar 13 15:36:59 2020 +0100

    [CAMEL-14712] Provide an immutable lightweight camel context
    Merge remote-tracking branch 'origin/master' into immutable

 .../org/apache/camel/dataformat/any23/any23.json   |   1 +
 .../src/main/docs/any23-dataformat.adoc            |   3 +-
 .../any23/spring/SpringAny23DataFormatTest.xml     |   4 +-
 .../camel/component/aws2/cw/Cw2Component.java      |  23 +-
 .../camel/component/aws2/ddb/Ddb2Component.java    |  23 +-
 .../aws2/ddbstream/Ddb2StreamComponent.java        |  23 +-
 .../camel/component/aws2/ec2/AWS2EC2Component.java |  23 +-
 .../camel/component/aws2/ecs/ECS2Component.java    |  23 +-
 .../camel/component/aws2/eks/EKS2Component.java    |  23 +-
 .../camel/component/aws2/iam/IAM2Component.java    |  23 +-
 components/camel-aws2-kms/pom.xml                  |   7 +-
 .../camel/component/aws2/kms/KMS2Component.java    |  23 +-
 .../aws2/kms/KMSComponentClientRegistryTest.java   |  13 +-
 .../aws2/kms/KMSComponentConfigurationTest.java    |   6 +-
 .../kms/KMSComponentVerifierExtensionTest.java     |  11 +-
 .../component/aws2/kms/KMSProducerSpringTest.java  |   7 +-
 .../camel/component/aws2/kms/KMSProducerTest.java  |   7 +-
 components/camel-aws2-lambda/pom.xml               |   7 +-
 .../component/aws2/lambda/Lambda2Component.java    |  23 +-
 .../lambda/LambdaComponentClientRegistryTest.java  |  15 +-
 .../lambda/LambdaComponentConfigurationTest.java   |  36 +-
 .../aws2/lambda/LambdaComponentSpringTest.java     |   8 +-
 .../LambdaComponentVerifierExtensionTest.java      |  11 +-
 .../aws2/lambda/LambdaOperationsTest.java          |   4 +-
 .../lambda/LambdaProducerDefaultFunctionTest.java  |   7 +-
 .../component/aws2/lambda/LambdaProducerTest.java  |   8 +-
 .../LambdaComponentIntegrationTest.java            |  84 +---
 components/camel-aws2-mq/pom.xml                   |   7 +-
 .../camel/component/aws2/mq/MQ2Component.java      |  23 +-
 .../aws2/mq/MQComponentClientRegistryTest.java     |  13 +-
 .../aws2/mq/MQComponentConfigurationTest.java      |   6 +-
 .../aws2/mq/MQComponentVerifierExtensionTest.java  |  11 +-
 .../component/aws2/mq/MQProducerSpringTest.java    |   6 +-
 .../camel/component/aws2/mq/MQProducerTest.java    |   6 +-
 components/camel-aws2-msk/pom.xml                  |   7 +-
 .../camel/component/aws2/msk/MSK2Component.java    |  23 +-
 .../aws2/msk/MSKComponentClientRegistryTest.java   |  13 +-
 .../aws2/msk/MSKComponentConfigurationTest.java    |   6 +-
 .../msk/MSKComponentVerifierExtensionTest.java     |  11 +-
 .../component/aws2/msk/MSKProducerSpringTest.java  |   6 +-
 .../camel/component/aws2/msk/MSKProducerTest.java  |   6 +-
 .../camel/component/aws2/s3/AWS2S3Component.java   |  23 +-
 .../S3CopyObjectOperationIntegrationTest.java      |   2 +-
 .../S3DeleteBucketOperationIntegrationTest.java    |   2 +-
 .../S3ListObjectsOperationIntegrationTest.java     |   2 +-
 .../S3ObjectRangeOperationIntegrationTest.java     |   2 +-
 components/camel-aws2-ses/pom.xml                  |   7 +-
 .../camel/component/aws2/ses/Ses2Component.java    |  23 +-
 .../aws2/ses/SESComponentClientRegistryTest.java   |  13 +-
 .../aws2/ses/SesComponentConfigurationTest.java    |  35 +-
 .../component/aws2/ses/SesComponentSpringTest.java |  11 +-
 .../camel/component/aws2/ses/SesComponentTest.java |   7 +-
 .../ses/SesComponentVerifierExtensionTest.java     |  11 +-
 .../integration/SesComponentIntegrationTest.java   |  10 +-
 components/camel-aws2-sns/pom.xml                  |  24 +-
 .../camel/component/aws2/sns/Sns2Component.java    |  23 +-
 .../component/aws2/sns/AmazonSNSClientMock.java    |   9 +-
 .../aws2/sns/SNSComponentClientRegistryTest.java   |  13 +-
 .../aws2/sns/SnsComponentConfigurationTest.java    |  21 +-
 .../component/aws2/sns/SnsComponentSpringTest.java |   6 +-
 .../camel/component/aws2/sns/SnsComponentTest.java |   6 +-
 .../sns/SnsComponentVerifierExtensionTest.java     |  11 +-
 .../camel/component/aws2/sns/SnsProducerTest.java  |  14 +-
 .../integration/SnsComponentIntegrationTest.java   |  10 +-
 .../SnsTopicWithKmsEncryptionIntegrationTest.java  |  10 +-
 .../camel/component/aws2/sqs/Sqs2Component.java    |  23 +-
 .../org/apache/camel/component/bean/BeanInfo.java  |  16 -
 .../apache/camel/component/bean/MethodInfo.java    |   4 +-
 .../org/apache/camel/component/elsql/elsql.json    |   2 +-
 .../camel-elsql/src/main/docs/elsql-component.adoc |   2 +-
 components/camel-hazelcast/pom.xml                 |   7 +-
 .../component/hazelcast/HazelcastConstants.java    |   1 +
 .../HazelcastAtomicnumberProducer.java             |   4 +-
 .../instance/HazelcastInstanceConsumer.java        |  10 +-
 .../hazelcast/list/HazelcastListConsumer.java      |   2 +-
 .../hazelcast/list/HazelcastListProducer.java      |   2 +-
 .../hazelcast/listener/CamelEntryListener.java     |   7 +-
 .../hazelcast/listener/CamelItemListener.java      |   4 +-
 .../hazelcast/listener/CamelMapListener.java       |   2 +-
 .../hazelcast/listener/CamelMessageListener.java   |   4 +-
 .../hazelcast/map/HazelcastMapConsumer.java        |   2 +-
 .../hazelcast/map/HazelcastMapProducer.java        |   4 +-
 .../multimap/HazelcastMultimapConsumer.java        |   2 +-
 .../multimap/HazelcastMultimapProducer.java        |   2 +-
 .../hazelcast/policy/HazelcastRoutePolicy.java     |   2 +-
 .../hazelcast/queue/HazelcastQueueConsumer.java    |   2 +-
 .../hazelcast/queue/HazelcastQueueProducer.java    |   2 +-
 .../HazelcastReplicatedmapConsumer.java            |   2 +-
 .../HazelcastReplicatedmapProducer.java            |   2 +-
 .../hazelcast/seda/HazelcastSedaConsumer.java      |   3 +-
 .../hazelcast/set/HazelcastSetConsumer.java        |   2 +-
 .../hazelcast/set/HazelcastSetProducer.java        |   2 +-
 .../hazelcast/topic/HazelcastTopicConsumer.java    |   2 +-
 .../hazelcast/topic/HazelcastTopicProducer.java    |   2 +-
 .../hazelcast/HazelcastAggregationRepository.java  |   8 +-
 .../hazelcast/HazelcastIdempotentRepository.java   |   2 +-
 ...HazelcastAtomicnumberProducerForSpringTest.java |  17 +-
 .../HazelcastAtomicnumberProducerTest.java         |  12 +-
 .../hazelcast/HazelcastInstanceConsumerTest.java   |  13 +-
 .../hazelcast/HazelcastListConsumerTest.java       |   9 +-
 .../hazelcast/HazelcastListProducerTest.java       |   2 +-
 .../hazelcast/HazelcastMapConsumerTest.java        |   5 +-
 .../HazelcastMapProducerForSpringTest.java         |   4 +-
 .../hazelcast/HazelcastMapProducerTest.java        |   4 +-
 .../hazelcast/HazelcastMultimapConsumerTest.java   |   5 +-
 .../HazelcastMultimapProducerForSpringTest.java    |   2 +-
 .../hazelcast/HazelcastMultimapProducerTest.java   |   2 +-
 .../hazelcast/HazelcastQueueConsumerPollTest.java  |   2 +-
 .../hazelcast/HazelcastQueueConsumerTest.java      |   9 +-
 .../hazelcast/HazelcastQueueProducerTest.java      |   2 +-
 .../HazelcastReliableTopicConsumerTest.java        |   9 +-
 .../HazelcastReliableTopicProducerTest.java        |   2 +-
 .../HazelcastReplicatedmapConsumerTest.java        |   5 +-
 ...azelcastReplicatedmapProducerForSpringTest.java |   2 +-
 .../HazelcastReplicatedmapProducerTest.java        |   2 +-
 .../HazelcastSedaRecoverableConsumerTest.java      |   4 +-
 .../hazelcast/HazelcastSetConsumerTest.java        |   9 +-
 .../hazelcast/HazelcastSetProducerTest.java        |   2 +-
 .../hazelcast/HazelcastTopicConsumerTest.java      |   9 +-
 .../hazelcast/HazelcastTopicProducerTest.java      |   2 +-
 .../HazelcastIdempotentRepositoryTest.java         |   2 +-
 .../src/test/resources/hazelcast-custom.xml        |  11 +-
 .../src/test/resources/hazelcast-default.xml       |  24 +-
 .../src/test/resources/hazelcast-named.xml         |  13 +-
 .../apache/camel/component/hbase/HBaseHelper.java  |  35 --
 components/camel-infinispan/pom.xml                |   6 +
 .../InfinispanClusteredConsumerTest.java           |   2 +-
 .../InfinispanComponentEmbeddedCacheTest.java      |  92 -----
 .../infinispan/InfinispanComponentTest.java        |   4 +-
 .../infinispan/InfinispanConfigurationIT.java      |  12 +-
 .../policy/InfinispanEmbeddedRoutePolicyTest.java  |   2 +-
 .../InfinispanIdempotentRepositoryIT.java          |   9 +-
 .../InfinispanIdempotentRepositoryTest.java        |   2 +-
 .../src/test/resources/cache-configuration.xml     |  32 --
 .../policy/CacheManagerFromRegistryTest.java       |   2 +-
 .../component/jcache/policy/hazelcast-spring.xml   |   2 +-
 components/camel-mustache/pom.xml                  |   2 +-
 .../component/mustache/MustacheComponentTest.java  |   6 +-
 .../component/mustache/MustacheLetterTest.java     |   8 +-
 .../camel-mvel/src/main/docs/mvel-component.adoc   |   2 +-
 .../http/PlatformHttpEndpointConfigurer.java       |   2 +
 .../component/platform/http/platform-http.json     |   1 +
 .../src/main/docs/platform-http-component.adoc     |   3 +-
 .../platform/http/PlatformHttpEndpoint.java        |  12 +
 .../pulsar/PulsarComponentConfigurer.java          |   2 +
 .../component/pulsar/PulsarEndpointConfigurer.java |   2 +
 .../org/apache/camel/component/pulsar/pulsar.json  |  12 +-
 .../src/main/docs/pulsar-component.adoc            |  16 +-
 .../component/pulsar/PulsarConfiguration.java      |  24 +-
 .../camel/component/pulsar/PulsarEndpoint.java     |  22 ++
 .../component/pulsar/PulsarMessageListener.java    |  59 ++-
 .../camel/component/pulsar/PulsarProducer.java     |   3 +-
 .../consumers/CommonCreationStrategyImpl.java      |   2 +-
 .../consumers/ConsumerCreationStrategyFactory.java |   2 +
 .../utils/consumers/KeySharedConsumerStrategy.java |  63 +++
 .../pulsar/utils/consumers/SubscriptionType.java   |   2 +-
 .../pulsar/PulsarConsumerInAsynchronousTest.java   | 194 +++++++++
 .../pulsar/PulsarConsumerInSynchronousTest.java    | 216 ++++++++++
 .../ConsumerCreationStrategyFactoryTest.java       |   9 +
 .../rabbitmq/RabbitMQComponentConfigurer.java      |   2 +
 .../rabbitmq/RabbitMQEndpointConfigurer.java       |   4 +
 .../apache/camel/component/rabbitmq/rabbitmq.json  |   3 +
 .../src/main/docs/rabbitmq-component.adoc          |  18 +-
 .../camel/component/rabbitmq/RabbitConsumer.java   |  23 +-
 .../component/rabbitmq/RabbitMQComponent.java      |  53 ++-
 .../rabbitmq/RabbitMQConnectionFactorySupport.java |   5 +-
 .../component/rabbitmq/RabbitMQConstants.java      |   3 +-
 .../camel/component/rabbitmq/RabbitMQConsumer.java |   6 +-
 .../component/rabbitmq/RabbitMQDeclareSupport.java |  10 +-
 .../camel/component/rabbitmq/RabbitMQEndpoint.java |  29 ++
 .../rabbitmq/RabbitMQHeaderFilterStrategy.java     |  26 +-
 .../rabbitmq/RabbitMQMessageConverter.java         |  40 +-
 .../rabbitmq/RabbitMQMessagePublisher.java         |  25 +-
 .../camel/component/rabbitmq/RabbitMQProducer.java |  52 ++-
 .../rabbitmq/pool/PoolableChannelFactory.java      |   4 +-
 .../rabbitmq/reply/CorrelationTimeoutMap.java      |  10 +-
 .../rabbitmq/reply/MessageSentCallback.java        |   4 +-
 .../rabbitmq/reply/QueueReplyHandler.java          |   3 +-
 .../component/rabbitmq/reply/ReplyHandler.java     |   6 +-
 .../component/rabbitmq/reply/ReplyHolder.java      |  28 +-
 .../component/rabbitmq/reply/ReplyManager.java     |  42 +-
 .../rabbitmq/reply/ReplyManagerSupport.java        |  65 +--
 .../rabbitmq/reply/TemporaryQueueReplyHandler.java |   9 +-
 .../rabbitmq/reply/TemporaryQueueReplyManager.java |  19 +-
 ...essageIdAsCorrelationIdMessageSentCallback.java |   8 +-
 .../component/rabbitmq/RabbitConsumerHangTest.java |   3 +-
 .../component/rabbitmq/RabbitMQComponentTest.java  |   2 +-
 .../component/rabbitmq/RabbitMQConsumerTest.java   |   2 +-
 .../component/rabbitmq/RabbitMQEndpointTest.java   |   4 +-
 .../component/rabbitmq/RabbitMQProducerTest.java   |   6 +-
 .../RabbitMQSpringExceptionHandlerTest.java        |  63 +++
 .../integration/AbstractRabbitMQIntTest.java       |   8 +-
 .../rabbitmq/integration/DockerTestUtils.java      |  18 +-
 .../rabbitmq/integration/RabbitMQBasicIntTest.java |  12 +-
 .../integration/RabbitMQConsumerIntTest.java       |  14 +-
 .../RabbitMQConsumerIntTestReplyTo.java            |  29 +-
 .../RabbitMQDeadLetterRoutingKeyIntTest.java       |  44 +--
 .../rabbitmq/integration/RabbitMQInOutIntTest.java |  33 +-
 .../rabbitmq/integration/RabbitMQLoadIntTest.java  |  25 +-
 .../integration/RabbitMQProducerIntTest.java       |  60 ++-
 .../integration/RabbitMQReConnectionIntTest.java   |  40 +-
 .../RabbitMQRequeueHandledExceptionIntTest.java    |  22 +-
 .../integration/RabbitMQRequeueIntTest.java        |  44 +--
 .../RabbitMQRequeueUnhandledExceptionIntTest.java  |  22 +-
 .../integration/spring/RabbitMQSpringIntTest.java  |   5 +-
 .../qpid/RabbitMQConsumerQpidTestReplyTo.java      |   4 +-
 .../rabbitmq/qpid/RabbitMQProducerQpidTest.java    |   4 +-
 .../rabbitmq/qpid/RabbitMQRequeueQpidTest.java     |   4 +-
 .../testbeans/CustomRabbitExceptionHandler.java    |  67 ++++
 .../testbeans/TestNonSerializableObject.java       |   2 +-
 .../testbeans/TestPartiallySerializableObject.java |   2 +-
 .../rabbitmq/testbeans/TestSerializableObject.java |   2 +-
 ...bitMQSpringExceptionHandlerIntTest-context.xml} |   7 +-
 .../resources/RabbitMQSpringIntTest-context.xml    |   2 +-
 .../shiro/security/ShiroSecurityProcessor.java     |  15 +-
 .../org/apache/camel/component/sql/sql.json        |   2 +-
 .../camel-sql/src/main/docs/sql-component.adoc     |  11 +-
 .../camel/component/sql/DefaultSqlEndpoint.java    |   2 +-
 components/camel-test-junit5/pom.xml               |   5 -
 .../xstream/XStreamDataFormatConfigurer.java       |   2 +-
 .../apache/camel/dataformat/xstream/xstream.json   |   8 +-
 .../src/main/docs/xstream-dataformat.adoc          |   6 +-
 .../dataformat/xstream/AbstractXStreamWrapper.java |  41 +-
 .../xstream/XStreamConfigurationTest.java          |  24 +-
 .../xstream/XStreamDataFormatOmitFieldsTest.java   |   4 +-
 .../xstream/SpringMarshalOmitFieldsTest.xml        |   6 +-
 .../xstream/SpringXStreamConfigurationTest.xml     |  28 +-
 .../component/zookeepermaster/group/GroupTest.java |   6 +-
 .../dsl/PulsarComponentBuilderFactory.java         |  29 +-
 .../dsl/RabbitmqComponentBuilderFactory.java       |  14 +
 core/camel-core-engine/pom.xml                     |  19 +-
 .../org/apache/camel/model/dataformat/any23.json   |   1 +
 .../org/apache/camel/model/dataformat/jaxb.index   |   8 -
 .../org/apache/camel/model/dataformat/xstream.json |   8 +-
 .../camel/model/PropertyDescriptionsAdapter.java   |  50 ---
 .../org/apache/camel/model/TimeUnitAdapter.java    |  50 ---
 .../camel/model/dataformat/Any23DataFormat.java    |  45 ++-
 .../camel/model/dataformat/XStreamDataFormat.java  | 435 ++++-----------------
 .../reifier/dataformat/Any23DataFormatReifier.java |   2 +-
 .../dataformat/XStreamDataFormatReifier.java       |   8 +-
 .../xml/AbstractCamelThreadPoolFactoryBean.java    |  15 +-
 .../apache/camel/impl/JavaUuidGeneratorTest.java   |  56 ---
 .../model/dataformat/Any23DataFormatTest.java      |   8 +-
 .../endpoint/dsl/ElsqlEndpointBuilderFactory.java  |   6 +-
 .../dsl/PlatformHttpEndpointBuilderFactory.java    |  28 ++
 .../endpoint/dsl/PulsarEndpointBuilderFactory.java |  71 +++-
 .../dsl/RabbitMQEndpointBuilderFactory.java        | 104 +++++
 .../endpoint/dsl/SqlEndpointBuilderFactory.java    |   6 +-
 .../org/apache/camel/main/BaseMainSupport.java     |   8 +-
 core/camel-management-api/pom.xml                  |  12 -
 core/camel-management/pom.xml                      |  12 -
 core/camel-xml-io/pom.xml                          |   7 -
 .../java/org/apache/camel/xml/in/ModelParser.java  |  99 +----
 .../java/org/apache/camel/xml/in/BaseParser.java   |  10 -
 .../modules/ROOT/pages/any23-dataformat.adoc       |   3 +-
 .../modules/ROOT/pages/elsql-component.adoc        |   2 +-
 docs/components/modules/ROOT/pages/index.adoc      |  10 +-
 .../modules/ROOT/pages/jclouds-component.adoc      |   2 +-
 .../modules/ROOT/pages/mvel-component.adoc         |   2 +-
 .../ROOT/pages/platform-http-component.adoc        |   3 +-
 .../modules/ROOT/pages/pulsar-component.adoc       |  16 +-
 .../modules/ROOT/pages/rabbitmq-component.adoc     |  18 +-
 .../modules/ROOT/pages/sql-component.adoc          |  11 +-
 .../modules/ROOT/pages/xstream-dataformat.adoc     |   6 +-
 .../modules/ROOT/pages/camel-3x-upgrade-guide.adoc |  79 ++++
 .../modules/ROOT/pages/contributing.adoc           |   6 +-
 docs/user-manual/modules/ROOT/pages/index.adoc     |  19 +-
 docs/user-manual/modules/ROOT/pages/java-dsl.adoc  |  16 +-
 docs/user-manual/modules/ROOT/pages/team.adoc      |   1 +
 .../modules/ROOT/pages/uuidgenerator.adoc          |  46 +--
 parent/pom.xml                                     |  22 +-
 .../karaf/features/src/main/resources/features.xml |   1 -
 tooling/openapi-rest-dsl-generator/pom.xml         |   2 -
 .../generator/openapi/AppendableGenerator.java     |   4 +-
 .../camel/generator/openapi/FilerGenerator.java    |   4 +-
 .../openapi/MethodBodySourceCodeEmitter.java       |  64 +--
 .../camel/generator/openapi/OperationFilter.java   |   9 +-
 .../camel/generator/openapi/OperationVisitor.java  | 101 ++---
 .../camel/generator/openapi/PathGenerator.java     |   4 +-
 .../camel/generator/openapi/PathVisitor.java       |  41 +-
 .../generator/openapi/RestDefinitionEmitter.java   |  10 +-
 .../openapi/RestDslDefinitionGenerator.java        |   8 +-
 .../camel/generator/openapi/RestDslGenerator.java  | 230 +++++------
 .../openapi/RestDslSourceCodeGenerator.java        |  33 +-
 .../generator/openapi/RestDslXmlGenerator.java     |  10 +-
 .../SpringBootProjectSourceCodeGenerator.java      |  48 +--
 .../generator/openapi/OperationVisitorTest.java    | 220 +++++++++++
 .../PathSpringBootProjectSourceGeneratorTest.java  |   5 +-
 .../openapi/RestDefinitionEmitterTest.java         |  60 +--
 .../generator/openapi/RestDslGeneratorTest.java    | 163 ++++++--
 .../generator/openapi/RestDslGeneratorV3Test.java  |  85 ++--
 .../openapi/RestDslSourceCodeGeneratorTest.java    |  13 +-
 .../openapi/RestDslSourceCodeGeneratorV3Test.java  |  19 +-
 .../generator/openapi/RestDslXmlGeneratorTest.java |  84 ++--
 .../openapi/RestDslXmlGeneratorV3Test.java         |  86 ++--
 .../camel/generator/openapi}/openapi-spec.json     |   0
 .../camel/generator/openapi}/openapi-v2.json       |   0
 297 files changed, 3471 insertions(+), 2477 deletions(-)



[camel] 07/09: CS: Fix imports

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 171a2dd5944a257a196ead95ff65609893002673
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Fri Mar 13 15:10:45 2020 +0100

    CS: Fix imports
---
 .../kinesis/KinesisComponentConfigurationTest.java |  1 -
 .../KinesisConsumerClosedShardWithFailTest.java    |  4 ++--
 .../KinesisConsumerClosedShardWithSilentTest.java  |  3 +--
 .../KinesisComponentIntegrationTest.java           |  2 +-
 .../camel/component/aws2/s3/AWS2S3Producer.java    |  1 +
 .../S3CopyObjectOperationIntegrationTest.java      |  1 -
 .../S3DeleteBucketOperationIntegrationTest.java    |  1 -
 .../component/azure/blob/BlobServiceComponent.java |  1 -
 .../azure/queue/QueueServiceComponent.java         |  1 -
 ...lobServiceComponentConfigurationClientTest.java |  2 --
 .../BlobServiceComponentConfigurationTest.java     |  1 -
 .../azure/common/AzureCredentialsTest.java         | 26 +++++++++-------------
 .../azure/common/AzureServiceCommonTestUtil.java   |  1 -
 .../azure/common/MissingCredentialsTest.java       |  9 ++++----
 .../azure/queue/QueueServiceUtilTest.java          |  1 -
 .../component/infinispan/InfinispanManager.java    |  1 -
 .../camel/spring/bind/ProcessorAsEndpointTest.java |  1 -
 .../undertow/rest/RestUndertowHttpGetTest.java     |  3 ---
 .../reifier/errorhandler/ErrorHandlerReifier.java  |  1 -
 .../impl/RouteWithMistypedComponentNameTest.java   |  1 -
 .../org/apache/camel/support/ExchangeHelper.java   |  1 -
 21 files changed, 19 insertions(+), 44 deletions(-)

diff --git a/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisComponentConfigurationTest.java b/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisComponentConfigurationTest.java
index 4285a41..279800c 100644
--- a/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisComponentConfigurationTest.java
+++ b/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisComponentConfigurationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.component.aws2.kinesis;
 
-
 import org.apache.camel.test.junit5.CamelTestSupport;
 import org.junit.jupiter.api.Test;
 import software.amazon.awssdk.core.Protocol;
diff --git a/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisConsumerClosedShardWithFailTest.java b/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisConsumerClosedShardWithFailTest.java
index 287bb68..4a45a24 100644
--- a/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisConsumerClosedShardWithFailTest.java
+++ b/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisConsumerClosedShardWithFailTest.java
@@ -39,11 +39,11 @@ import software.amazon.awssdk.services.kinesis.model.ShardIteratorType;
 import software.amazon.awssdk.services.kinesis.model.StreamDescription;
 
 import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertThrows;
 
 @ExtendWith(MockitoExtension.class)
 public class KinesisConsumerClosedShardWithFailTest {
diff --git a/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisConsumerClosedShardWithSilentTest.java b/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisConsumerClosedShardWithSilentTest.java
index be3eba2..899ef1f 100644
--- a/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisConsumerClosedShardWithSilentTest.java
+++ b/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/KinesisConsumerClosedShardWithSilentTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.component.aws2.kinesis;
 
-import java.time.Instant;
 import java.util.ArrayList;
 
 import org.apache.camel.AsyncProcessor;
@@ -42,11 +41,11 @@ import software.amazon.awssdk.services.kinesis.model.ShardIteratorType;
 import software.amazon.awssdk.services.kinesis.model.StreamDescription;
 
 import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.hamcrest.MatcherAssert.assertThat;
 
 @ExtendWith(MockitoExtension.class)
 public class KinesisConsumerClosedShardWithSilentTest {
diff --git a/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/integration/KinesisComponentIntegrationTest.java b/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/integration/KinesisComponentIntegrationTest.java
index 11fe91a..ef48274 100644
--- a/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/integration/KinesisComponentIntegrationTest.java
+++ b/components/camel-aws2-kinesis/src/test/java/org/apache/camel/component/aws2/kinesis/integration/KinesisComponentIntegrationTest.java
@@ -31,8 +31,8 @@ import org.junit.jupiter.api.Test;
 import software.amazon.awssdk.services.kinesis.KinesisClient;
 import software.amazon.awssdk.services.kinesis.model.Record;
 
-import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 @Disabled("Must be manually tested.")
 public class KinesisComponentIntegrationTest extends CamelTestSupport {
diff --git a/components/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java b/components/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
index 52701d3..a0d1fa2 100644
--- a/components/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
+++ b/components/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
@@ -55,6 +55,7 @@ import software.amazon.awssdk.services.s3.model.ListObjectsResponse;
 import software.amazon.awssdk.services.s3.model.ObjectCannedACL;
 import software.amazon.awssdk.services.s3.model.PutObjectRequest;
 import software.amazon.awssdk.services.s3.model.PutObjectResponse;
+
 /**
  * A Producer which sends messages to the Amazon Web Service Simple Storage
  * Service <a href="http://aws.amazon.com/s3/">AWS S3</a>
diff --git a/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3CopyObjectOperationIntegrationTest.java b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3CopyObjectOperationIntegrationTest.java
index 3b83e51..7ff130a 100644
--- a/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3CopyObjectOperationIntegrationTest.java
+++ b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3CopyObjectOperationIntegrationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.component.aws2.s3.integration;
 
-
 import org.apache.camel.BindToRegistry;
 import org.apache.camel.EndpointInject;
 import org.apache.camel.Exchange;
diff --git a/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3DeleteBucketOperationIntegrationTest.java b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3DeleteBucketOperationIntegrationTest.java
index f6c11d2..6d9fc41 100644
--- a/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3DeleteBucketOperationIntegrationTest.java
+++ b/components/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3DeleteBucketOperationIntegrationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.component.aws2.s3.integration;
 
-
 import org.apache.camel.BindToRegistry;
 import org.apache.camel.EndpointInject;
 import org.apache.camel.Exchange;
diff --git a/components/camel-azure/src/main/java/org/apache/camel/component/azure/blob/BlobServiceComponent.java b/components/camel-azure/src/main/java/org/apache/camel/component/azure/blob/BlobServiceComponent.java
index 8918845..b9149ca 100644
--- a/components/camel-azure/src/main/java/org/apache/camel/component/azure/blob/BlobServiceComponent.java
+++ b/components/camel-azure/src/main/java/org/apache/camel/component/azure/blob/BlobServiceComponent.java
@@ -28,7 +28,6 @@ import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
 
-
 @Component("azure-blob")
 public class BlobServiceComponent extends DefaultComponent {
 
diff --git a/components/camel-azure/src/main/java/org/apache/camel/component/azure/queue/QueueServiceComponent.java b/components/camel-azure/src/main/java/org/apache/camel/component/azure/queue/QueueServiceComponent.java
index 70972dc..5e6a5fb 100644
--- a/components/camel-azure/src/main/java/org/apache/camel/component/azure/queue/QueueServiceComponent.java
+++ b/components/camel-azure/src/main/java/org/apache/camel/component/azure/queue/QueueServiceComponent.java
@@ -26,7 +26,6 @@ import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
 
-
 @Component("azure-queue")
 public class QueueServiceComponent extends DefaultComponent {
 
diff --git a/components/camel-azure/src/test/java/org/apache/camel/component/azure/blob/BlobServiceComponentConfigurationClientTest.java b/components/camel-azure/src/test/java/org/apache/camel/component/azure/blob/BlobServiceComponentConfigurationClientTest.java
index 948c283..435458c 100644
--- a/components/camel-azure/src/test/java/org/apache/camel/component/azure/blob/BlobServiceComponentConfigurationClientTest.java
+++ b/components/camel-azure/src/test/java/org/apache/camel/component/azure/blob/BlobServiceComponentConfigurationClientTest.java
@@ -21,8 +21,6 @@ import java.util.Collections;
 
 import com.microsoft.azure.storage.StorageCredentials;
 import com.microsoft.azure.storage.StorageCredentialsAccountAndKey;
-import com.microsoft.azure.storage.StorageCredentialsAnonymous;
-import com.microsoft.azure.storage.blob.CloudBlob;
 import com.microsoft.azure.storage.blob.CloudBlockBlob;
 import com.microsoft.azure.storage.core.Base64;
 import org.apache.camel.Endpoint;
diff --git a/components/camel-azure/src/test/java/org/apache/camel/component/azure/blob/BlobServiceComponentConfigurationTest.java b/components/camel-azure/src/test/java/org/apache/camel/component/azure/blob/BlobServiceComponentConfigurationTest.java
index fbc5b77..2084fda 100644
--- a/components/camel-azure/src/test/java/org/apache/camel/component/azure/blob/BlobServiceComponentConfigurationTest.java
+++ b/components/camel-azure/src/test/java/org/apache/camel/component/azure/blob/BlobServiceComponentConfigurationTest.java
@@ -21,7 +21,6 @@ import java.util.Collections;
 
 import com.microsoft.azure.storage.StorageCredentials;
 import com.microsoft.azure.storage.StorageCredentialsAccountAndKey;
-import com.microsoft.azure.storage.StorageCredentialsAnonymous;
 import com.microsoft.azure.storage.blob.CloudBlob;
 import com.microsoft.azure.storage.blob.CloudBlockBlob;
 import com.microsoft.azure.storage.core.Base64;
diff --git a/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/AzureCredentialsTest.java b/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/AzureCredentialsTest.java
index 9ee0d98..88a7be9 100644
--- a/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/AzureCredentialsTest.java
+++ b/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/AzureCredentialsTest.java
@@ -16,13 +16,10 @@
  */
 package org.apache.camel.component.azure.common;
 
-import com.microsoft.azure.storage.StorageCredentials;
 import com.microsoft.azure.storage.StorageCredentialsAccountAndKey;
 import com.microsoft.azure.storage.blob.CloudBlob;
 import com.microsoft.azure.storage.blob.CloudBlockBlob;
-import com.microsoft.azure.storage.core.Base64;
 import com.microsoft.azure.storage.queue.CloudQueue;
-import org.apache.camel.ResolveEndpointFailedException;
 import org.apache.camel.component.azure.blob.BlobServiceConfiguration;
 import org.apache.camel.component.azure.blob.BlobServiceEndpoint;
 import org.apache.camel.component.azure.blob.BlobServiceUtil;
@@ -30,24 +27,21 @@ import org.apache.camel.component.azure.queue.QueueServiceConfiguration;
 import org.apache.camel.component.azure.queue.QueueServiceEndpoint;
 import org.apache.camel.component.azure.queue.QueueServiceUtil;
 import org.apache.camel.test.junit4.CamelTestSupport;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.newAccountKeyCredentials;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.registerCredentials;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.registerBlockBlobClient;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.registerQueueClient;
 import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.ACCOUNT_NAME;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CONTAINER_NAME;
 import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.BLOB_NAME;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.QUEUE_NAME;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.INLINE_CREDENTIALS_ACCOUNT_NAME;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.INLINE_CREDENTIALS_ACCOUNT_KEY;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CREDENTIALS_ACCOUNT_NAME;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CREDENTIALS_ACCOUNT_KEY;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CLIENT_CREDENTIALS_ACCOUNT_NAME;
 import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CLIENT_CREDENTIALS_ACCOUNT_KEY;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CLIENT_CREDENTIALS_ACCOUNT_NAME;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CONTAINER_NAME;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CREDENTIALS_ACCOUNT_KEY;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CREDENTIALS_ACCOUNT_NAME;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.INLINE_CREDENTIALS_ACCOUNT_KEY;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.INLINE_CREDENTIALS_ACCOUNT_NAME;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.QUEUE_NAME;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.registerBlockBlobClient;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.registerCredentials;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.registerQueueClient;
 
 public class AzureCredentialsTest extends CamelTestSupport {
 
diff --git a/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/AzureServiceCommonTestUtil.java b/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/AzureServiceCommonTestUtil.java
index 6ca38e8..ab860a9 100644
--- a/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/AzureServiceCommonTestUtil.java
+++ b/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/AzureServiceCommonTestUtil.java
@@ -25,7 +25,6 @@ import com.microsoft.azure.storage.core.Base64;
 import com.microsoft.azure.storage.queue.CloudQueue;
 import org.apache.camel.CamelContext;
 
-
 public final class AzureServiceCommonTestUtil {
 
     public static final String ACCOUNT_NAME = "camelazure";
diff --git a/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/MissingCredentialsTest.java b/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/MissingCredentialsTest.java
index 7038fd4..3ba16ae 100644
--- a/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/MissingCredentialsTest.java
+++ b/components/camel-azure/src/test/java/org/apache/camel/component/azure/common/MissingCredentialsTest.java
@@ -27,16 +27,15 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 
+import static org.apache.camel.component.azure.blob.BlobServiceComponent.MISSING_BLOB_CREDNTIALS_EXCEPTION_MESSAGE;
 import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.ACCOUNT_NAME;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CONTAINER_NAME;
 import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.BLOB_NAME;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.QUEUE_NAME;
-import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.INLINE_CREDENTIALS_ACCOUNT_NAME;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.CONTAINER_NAME;
 import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.INLINE_CREDENTIALS_ACCOUNT_KEY;
-import static org.apache.camel.component.azure.blob.BlobServiceComponent.MISSING_BLOB_CREDNTIALS_EXCEPTION_MESSAGE;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.INLINE_CREDENTIALS_ACCOUNT_NAME;
+import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.QUEUE_NAME;
 import static org.apache.camel.component.azure.queue.QueueServiceComponent.MISSING_QUEUE_CREDNTIALS_EXCEPTION_MESSAGE;
 
-
 public class MissingCredentialsTest extends CamelTestSupport {
 
     @Rule
diff --git a/components/camel-azure/src/test/java/org/apache/camel/component/azure/queue/QueueServiceUtilTest.java b/components/camel-azure/src/test/java/org/apache/camel/component/azure/queue/QueueServiceUtilTest.java
index 52be8af..3d16c92 100644
--- a/components/camel-azure/src/test/java/org/apache/camel/component/azure/queue/QueueServiceUtilTest.java
+++ b/components/camel-azure/src/test/java/org/apache/camel/component/azure/queue/QueueServiceUtilTest.java
@@ -25,7 +25,6 @@ import org.junit.Test;
 import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.newAccountKeyCredentials;
 import static org.apache.camel.component.azure.common.AzureServiceCommonTestUtil.registerCredentials;
 
-
 public class QueueServiceUtilTest extends CamelTestSupport {
 
     @Test
diff --git a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanManager.java b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanManager.java
index 618c38a..f8ecdf2 100644
--- a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanManager.java
+++ b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanManager.java
@@ -36,7 +36,6 @@ import org.infinispan.manager.DefaultCacheManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 import static org.apache.camel.component.infinispan.InfinispanConstants.CACHE_MANAGER_CURRENT;
 
 public class InfinispanManager extends ServiceSupport {
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/bind/ProcessorAsEndpointTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/bind/ProcessorAsEndpointTest.java
index cd337e3..b713ab6 100644
--- a/components/camel-spring/src/test/java/org/apache/camel/spring/bind/ProcessorAsEndpointTest.java
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/bind/ProcessorAsEndpointTest.java
@@ -18,7 +18,6 @@ package org.apache.camel.spring.bind;
 
 import java.util.List;
 
-import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.NoSuchEndpointException;
 import org.apache.camel.spring.SpringTestSupport;
diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpGetTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpGetTest.java
index 061b286..2992f48 100644
--- a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpGetTest.java
+++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpGetTest.java
@@ -16,11 +16,8 @@
  */
 package org.apache.camel.component.undertow.rest;
 
-import org.apache.camel.BindToRegistry;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.undertow.BaseUndertowTest;
-import org.apache.camel.component.undertow.DefaultUndertowHttpBinding;
-import org.apache.camel.component.undertow.UndertowHttpBinding;
 import org.junit.Test;
 
 public class RestUndertowHttpGetTest extends BaseUndertowTest {
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
index 5cd85b3..5a67899 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
@@ -39,7 +39,6 @@ import org.apache.camel.builder.ErrorHandlerBuilderSupport;
 import org.apache.camel.builder.NoErrorHandlerBuilder;
 import org.apache.camel.model.OnExceptionDefinition;
 import org.apache.camel.model.RedeliveryPolicyDefinition;
-import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.processor.ErrorHandler;
 import org.apache.camel.processor.errorhandler.ErrorHandlerSupport;
 import org.apache.camel.processor.errorhandler.ExceptionPolicy;
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/RouteWithMistypedComponentNameTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/RouteWithMistypedComponentNameTest.java
index 5ee0ddb..aa192b4 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/RouteWithMistypedComponentNameTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/RouteWithMistypedComponentNameTest.java
@@ -19,7 +19,6 @@ package org.apache.camel.impl;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.NoSuchEndpointException;
-import org.apache.camel.ResolveEndpointFailedException;
 import org.apache.camel.TestSupport;
 import org.apache.camel.builder.RouteBuilder;
 import org.junit.Test;
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
index d01946a..70d79fa 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
@@ -47,7 +47,6 @@ import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.TypeConversionException;
-import org.apache.camel.TypeConverter;
 import org.apache.camel.WrappedFile;
 import org.apache.camel.spi.NormalizedEndpointUri;
 import org.apache.camel.spi.Synchronization;


[camel] 03/09: Remove reference to the RouteDefinition in ErrorHandlerReifier

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit edce21d041dbb4e0644d007fceea50bcfc93b867
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Mar 11 11:11:50 2020 +0100

    Remove reference to the RouteDefinition in ErrorHandlerReifier
---
 .../java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java   | 2 +-
 .../java/org/apache/camel/spring/spi/SpringTransactionPolicy.java     | 2 +-
 .../org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java    | 4 +---
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java
index 74ecaa3..5a2ed4e 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java
@@ -116,7 +116,7 @@ public abstract class JtaTransactionPolicy implements TransactedPolicy {
         answer = createTransactionErrorHandler(route, processor, txBuilder);
 
         // set the route to use our transacted error handler builder
-        routeDefinition.setErrorHandlerFactory(txBuilder);
+        route.setErrorHandlerFactory(txBuilder);
 
         // return with wrapped transacted error handler
         return answer;
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
index 2e3ba76..e7e3e4f 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
@@ -109,7 +109,7 @@ public class SpringTransactionPolicy implements TransactedPolicy {
             answer = createTransactionErrorHandler(route, processor, txBuilder);
 
             // set the route to use our transacted error handler builder
-            routeDefinition.setErrorHandlerFactory(txBuilder);
+            route.setErrorHandlerFactory(txBuilder);
         }
 
         // return with wrapped transacted error handler
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
index 25da846..5cd85b3 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
@@ -186,9 +186,7 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerBuilderSupport>
         // so we should use that one
         if (!isErrorHandlerFactoryConfigured(ref)) {
             // see if there has been configured a error handler builder on the route
-            // TODO: Avoid using RouteDefinition - tests should pass: https://issues.apache.org/jira/browse/CAMEL-13984
-            RouteDefinition def = (RouteDefinition) route.getRoute();
-            answer = def.getErrorHandlerFactory();
+            answer = route.getErrorHandlerFactory();
             // check if its also a ref with no error handler configuration like me
             if (answer instanceof ErrorHandlerBuilderRef) {
                 ErrorHandlerBuilderRef other = (ErrorHandlerBuilderRef)answer;


[camel] 08/09: Add a test for the immutable context

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit bf4f3ee93df66ac38f2c2d344482a68079681f03
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Fri Mar 13 15:34:44 2020 +0100

    Add a test for the immutable context
---
 .../apache/camel/impl/lw/ImmutableContextTest.java | 82 ++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/lw/ImmutableContextTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/lw/ImmutableContextTest.java
new file mode 100644
index 0000000..f4b3082
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/lw/ImmutableContextTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.lw;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ImmutableContextTest extends ContextTestSupport {
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        setUseImmutableContext(true);
+        super.setUp();
+    }
+
+    @Test
+    public void testCBRCamel() throws Exception {
+        getMockEndpoint("mock:other").expectedMessageCount(0);
+        getMockEndpoint("mock:camel").expectedMessageCount(1);
+        getMockEndpoint("mock:donkey").expectedMessageCount(0);
+
+        template.sendBody("direct:start", "Camel rules");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testCBRDonkey() throws Exception {
+        getMockEndpoint("mock:other").expectedMessageCount(0);
+        getMockEndpoint("mock:camel").expectedMessageCount(0);
+        getMockEndpoint("mock:donkey").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Donkey kong");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testCBROther() throws Exception {
+        getMockEndpoint("mock:other").expectedMessageCount(1);
+        getMockEndpoint("mock:camel").expectedMessageCount(0);
+        getMockEndpoint("mock:donkey").expectedMessageCount(0);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                        .choice()
+                            .when(body().contains("Camel"))
+                                .to("mock:camel")
+                            .when(body().contains("Donkey"))
+                                .to("mock:donkey")
+                            .otherwise()
+                                .to("mock:other");
+            }
+        };
+    }
+}


[camel] 05/09: Remove a call to toString as the value is always a String

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 369b61af69a4e6f2d233d0501e4f38352f878140
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Fri Mar 13 15:07:33 2020 +0100

    Remove a call to toString as the value is always a String
---
 .../src/main/java/org/apache/camel/impl/engine/DefaultRoute.java        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
index d3d39e7..c280ea1 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
@@ -157,7 +157,7 @@ public class DefaultRoute extends ServiceSupport implements Route {
     @Override
     public String getDescription() {
         Object value = properties.get(Route.DESCRIPTION_PROPERTY);
-        return value != null ? value.toString() : null;
+        return value != null ? (String) value : null;
     }
 
     @Override


[camel] 02/09: Remove unused call / variable

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 69e2d9fd9922fcdf04c6ed4308cb494979d96610
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Mar 11 11:11:20 2020 +0100

    Remove unused call / variable
---
 .../src/main/java/org/apache/camel/impl/engine/DefaultRoute.java         | 1 -
 1 file changed, 1 deletion(-)

diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
index 24c6076..d3d39e7 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
@@ -568,7 +568,6 @@ public class DefaultRoute extends ServiceSupport implements Route {
                 ((RouteIdAware) consumer).setRouteId(this.getId());
             }
         }
-        Processor processor = getProcessor();
         if (processor instanceof Service) {
             services.add((Service)processor);
         }


[camel] 06/09: Remove reference to UUID and use UuidGenerator instead

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 61f964a0280f6532a4a4e40784100919e8ae8484
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Fri Mar 13 15:08:20 2020 +0100

    Remove reference to UUID and use UuidGenerator instead
---
 .../org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java     | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
index bf01555..0215695 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
@@ -21,7 +21,6 @@ import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryMXBean;
 import java.util.LinkedHashSet;
 import java.util.Set;
-import java.util.UUID;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
@@ -257,7 +256,7 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
 
     protected String customResolveManagementName(String pattern) {
         if (pattern.contains("#uuid#")) {
-            String uuid = UUID.randomUUID().toString();
+            String uuid = camelContext.getUuidGenerator().generateUuid();
             pattern = StringHelper.replaceAll(pattern, "#uuid#", uuid);
         }
         return FilePathResolver.resolvePath(pattern);