CAMEL-1452,CAMEL-1387: Added IsSingleton to allow Injector to return shared instances. Added methods for tooling on CamelContext.

git-svn-id: https://svn.apache.org/repos/asf/camel/trunk@752893 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/camel-core/src/main/java/org/apache/camel/CamelContext.java b/camel-core/src/main/java/org/apache/camel/CamelContext.java
index 4dfee05..abc5fce 100644
--- a/camel-core/src/main/java/org/apache/camel/CamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/CamelContext.java
@@ -79,6 +79,13 @@
     <T extends Component> T getComponent(String name, Class<T> componentType);
 
     /**
+     * Gets a readonly list of names of the components currently registered
+     *
+     * @return a readonly list with the names of the the componens.
+     */
+    List<String> getComponentNames();
+
+    /**
      * Removes a previously added component.
      *
      * @param componentName the component name to remove
@@ -280,6 +287,13 @@
     Language resolveLanguage(String language);
 
     /**
+     * Gets a readonly list with the names of the languages currently registered.
+     *
+     * @return a readonly list with the names of the the languages. 
+     */
+    List<String> getLanguageNames();
+
+    /**
      * Creates a new ProducerTemplate.
      * <p/>
      * See this FAQ before use: <a href="http://camel.apache.org/why-does-camel-use-too-many-threads-with-producertemplate.html">
diff --git a/camel-core/src/main/java/org/apache/camel/Endpoint.java b/camel-core/src/main/java/org/apache/camel/Endpoint.java
index 7019002..e298322 100644
--- a/camel-core/src/main/java/org/apache/camel/Endpoint.java
+++ b/camel-core/src/main/java/org/apache/camel/Endpoint.java
@@ -29,15 +29,7 @@
  * @see Message
  * @version $Revision$
  */
-public interface Endpoint {
-
-    /**
-     * Returns if the endpoint should be a CamelContext singleton. If the
-     * endpoint is a Singleton, then a single Endpoint instance will be shared
-     * by all routes with the same URI. Because the endpoint is shared, it
-     * should be treated as an immutable.
-     */
-    boolean isSingleton();
+public interface Endpoint extends IsSingleton {
 
     /**
      * Returns the string representation of the endpoint URI
diff --git a/camel-core/src/main/java/org/apache/camel/IsSingleton.java b/camel-core/src/main/java/org/apache/camel/IsSingleton.java
new file mode 100644
index 0000000..d489a799c
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/IsSingleton.java
@@ -0,0 +1,35 @@
+/**
+ * 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;
+
+/**
+ * Used for defining if a given class is singleton or not.
+ * If the class is a Singleton, then a single instance will be shared. Because the class is shared, it
+ * should be treated as an immutable and be thread safe.
+ *
+ * @version $Revision$
+ */
+public interface IsSingleton {
+
+    /**
+     * Wheter this class supports being singleton or not.
+     *  
+     * @return <tt>true</tt> to be a single shared instance, <tt>false</tt> to create new instances.
+     */
+    boolean isSingleton();
+
+}
diff --git a/camel-core/src/main/java/org/apache/camel/builder/PredicateBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/PredicateBuilder.java
index 0d3975b..01fcfd6 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/PredicateBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/PredicateBuilder.java
@@ -45,7 +45,7 @@
      * Converts the given expression into an {@link Predicate}
      */
     public static Predicate toPredicate(final Expression expression) {
-        return new PredicateSupport() {
+        return new Predicate() {
             public boolean matches(Exchange exchange) {
                 Object value = expression.evaluate(exchange);
                 return ObjectHelper.evaluateValuePredicate(value);
@@ -63,7 +63,7 @@
      */
     public static Predicate not(final Predicate predicate) {
         notNull(predicate, "predicate");
-        return new PredicateSupport() {
+        return new Predicate() {
             public boolean matches(Exchange exchange) {
                 return !predicate.matches(exchange);
             }
@@ -81,7 +81,7 @@
     public static Predicate and(final Predicate left, final Predicate right) {
         notNull(left, "left");
         notNull(right, "right");
-        return new PredicateSupport() {
+        return new Predicate() {
             public boolean matches(Exchange exchange) {
                 return left.matches(exchange) && right.matches(exchange);
             }
@@ -99,7 +99,7 @@
     public static Predicate or(final Predicate left, final Predicate right) {
         notNull(left, "left");
         notNull(right, "right");
-        return new PredicateSupport() {
+        return new Predicate() {
             public boolean matches(Exchange exchange) {
                 return left.matches(exchange) || right.matches(exchange);
             }
@@ -117,7 +117,7 @@
     public static Predicate in(final Predicate... predicates) {
         notNull(predicates, "predicates");
 
-        return new PredicateSupport() {
+        return new Predicate() {
             public boolean matches(Exchange exchange) {
                 for (Predicate in : predicates) {
                     if (in.matches(exchange)) {
@@ -237,7 +237,7 @@
         notNull(expression, "expression");
         notNull(type, "type");
 
-        return new PredicateSupport() {
+        return new Predicate() {
             public boolean matches(Exchange exchange) {
                 Object value = expression.evaluate(exchange);
                 return type.isInstance(value);
@@ -274,7 +274,7 @@
         notNull(expression, "expression");
         notNull(pattern, "pattern");
 
-        return new PredicateSupport() {
+        return new Predicate() {
             public boolean matches(Exchange exchange) {
                 Object value = expression.evaluate(exchange);
                 if (value != null) {
diff --git a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
index 3cedd09..5ed1f7c 100644
--- a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
+++ b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
@@ -211,7 +211,6 @@
             }
             processStrategy.commit(operations, endpoint, exchange, file);
         } catch (Exception e) {
-            log.warn("Error committing remote file strategy: " + processStrategy, e);
             handleException(e);
         }
     }
@@ -232,7 +231,6 @@
         try {
             processStrategy.rollback(operations, endpoint, exchange, file);
         } catch (Exception e) {
-            log.warn("Error rolling back remote file strategy: " + processStrategy, e);
             handleException(e);
         }
     }
diff --git a/camel-core/src/main/java/org/apache/camel/component/mock/AssertionClause.java b/camel-core/src/main/java/org/apache/camel/component/mock/AssertionClause.java
index 60c0604..a5b43fc 100644
--- a/camel-core/src/main/java/org/apache/camel/component/mock/AssertionClause.java
+++ b/camel-core/src/main/java/org/apache/camel/component/mock/AssertionClause.java
@@ -24,8 +24,8 @@
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionClause;
-import org.apache.camel.builder.PredicateSupport;
 import org.apache.camel.builder.ValueBuilder;
+import org.apache.camel.util.PredicateAssertHelper;
 import static org.apache.camel.builder.ExpressionBuilder.bodyExpression;
 import static org.apache.camel.builder.ExpressionBuilder.headerExpression;
 import static org.apache.camel.builder.ExpressionBuilder.propertyExpression;
@@ -112,7 +112,7 @@
      */
     protected void applyAssertionOn(MockEndpoint endpoint, int index, Exchange exchange) {
         for (Predicate predicate : predicates) {
-            PredicateSupport.assertMatches(predicate, endpoint.getEndpointUri() + " ", exchange);
+            PredicateAssertHelper.assertMatches(predicate, endpoint.getEndpointUri() + " ", exchange);
         }
     }
 
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 45be4ba..20ef26a 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -30,6 +30,7 @@
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.Endpoint;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.NoFactoryAvailableException;
 import org.apache.camel.Processor;
 import org.apache.camel.ProducerTemplate;
@@ -93,6 +94,7 @@
     private ComponentResolver componentResolver;
     private boolean autoCreateComponents = true;
     private LanguageResolver languageResolver = new DefaultLanguageResolver();
+    private final Map<String, Language> languages = new HashMap<String, Language>();
     private Registry registry;
     private LifecycleStrategy lifecycleStrategy;
     private final List<RouteDefinition> routeDefinitions = new ArrayList<RouteDefinition>();
@@ -514,7 +516,27 @@
     // -----------------------------------------------------------------------
 
     public Language resolveLanguage(String language) {
-        return getLanguageResolver().resolveLanguage(language, this);
+        Language answer;
+        synchronized (languages) {
+            answer = languages.get(language);
+
+            // check if the language is singleton, if so return the shared instance
+            if (answer != null && 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, this);
+            if (answer != null) {
+                languages.put(language, answer);
+            }
+        }
+
+        // no language resolved
+        return answer;
     }
 
     // Properties
@@ -953,6 +975,26 @@
         this.packageScanClassResolver = packageScanClassResolver;
     }
 
+    public List<String> getComponentNames() {
+        synchronized (components) {
+            List<String> answer = new ArrayList<String>();
+            for (String name : components.keySet()) {
+                answer.add(name);
+            }
+            return answer;
+        }
+    }
+
+    public List<String> getLanguageNames() {
+        synchronized (languages) {
+            List<String> answer = new ArrayList<String>();
+            for (String name : languages.keySet()) {
+                answer.add(name);
+            }
+            return answer;
+        }
+    }
+
     protected synchronized String getEndpointKey(String uri, Endpoint endpoint) {
         if (endpoint.isSingleton()) {
             return uri;
@@ -966,5 +1008,5 @@
             }
         }
     }
-    
+
 }
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultLanguageResolver.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultLanguageResolver.java
index 498c99e..41120ae 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultLanguageResolver.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultLanguageResolver.java
@@ -41,6 +41,7 @@
     protected Log getLog() {
         return LOG;
     }
+
     @SuppressWarnings("unchecked")
     public Language resolveLanguage(String name, CamelContext context) {
         Object bean = null;
diff --git a/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java b/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
index e6bff65..b44a81a 100644
--- a/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
@@ -17,6 +17,7 @@
 package org.apache.camel.language.bean;
 
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.PredicateBuilder;
 import org.apache.camel.spi.Language;
@@ -37,7 +38,7 @@
  *
  * @version $Revision$
  */
-public class BeanLanguage implements Language {
+public class BeanLanguage implements Language, IsSingleton {
 
     /**
      * Creates the expression based on the string syntax.
@@ -104,4 +105,7 @@
         return new BeanExpression(bean, method);
     }
 
+    public boolean isSingleton() {
+        return true;
+    }
 }
\ No newline at end of file
diff --git a/camel-core/src/main/java/org/apache/camel/language/constant/ConstantLanguage.java b/camel-core/src/main/java/org/apache/camel/language/constant/ConstantLanguage.java
index 6c98d93..3e39196 100644
--- a/camel-core/src/main/java/org/apache/camel/language/constant/ConstantLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/constant/ConstantLanguage.java
@@ -17,6 +17,7 @@
 package org.apache.camel.language.constant;
 
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.builder.PredicateBuilder;
@@ -25,7 +26,7 @@
 /**
  * A language for constant expressions.
  */
-public class ConstantLanguage implements Language {
+public class ConstantLanguage implements Language, IsSingleton {
 
     public static Expression constant(Object value) {        
         return ExpressionBuilder.constantExpression(value);
@@ -38,4 +39,8 @@
     public Expression createExpression(String expression) {
         return ConstantLanguage.constant(expression);
     }
+
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/camel-core/src/main/java/org/apache/camel/language/header/HeaderLanguage.java b/camel-core/src/main/java/org/apache/camel/language/header/HeaderLanguage.java
index ddc777b..df2a7d3 100644
--- a/camel-core/src/main/java/org/apache/camel/language/header/HeaderLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/header/HeaderLanguage.java
@@ -17,6 +17,7 @@
 package org.apache.camel.language.header;
 
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.builder.PredicateBuilder;
@@ -25,7 +26,7 @@
 /**
  * A language for header expressions.
  */
-public class HeaderLanguage implements Language {
+public class HeaderLanguage implements Language, IsSingleton {
 
     public static Expression header(String headerName) {        
         return ExpressionBuilder.headerExpression(headerName);
@@ -38,4 +39,8 @@
     public Expression createExpression(String expression) {
         return HeaderLanguage.header(expression);
     }
+
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/camel-core/src/main/java/org/apache/camel/language/property/PropertyLanguage.java b/camel-core/src/main/java/org/apache/camel/language/property/PropertyLanguage.java
index 9c0ebf5..8c59a3e 100644
--- a/camel-core/src/main/java/org/apache/camel/language/property/PropertyLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/property/PropertyLanguage.java
@@ -17,6 +17,7 @@
 package org.apache.camel.language.property;
 
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.builder.PredicateBuilder;
@@ -25,7 +26,7 @@
 /**
  * A language for property expressions.
  */
-public class PropertyLanguage implements Language {
+public class PropertyLanguage implements Language, IsSingleton {
 
     public static Expression property(String propertyName) {        
         return ExpressionBuilder.propertyExpression(propertyName);
@@ -38,4 +39,8 @@
     public Expression createExpression(String expression) {
         return PropertyLanguage.property(expression);
     }
+
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/camel-core/src/main/java/org/apache/camel/language/simple/FileLanguage.java b/camel-core/src/main/java/org/apache/camel/language/simple/FileLanguage.java
index 45a1878..69072bd 100644
--- a/camel-core/src/main/java/org/apache/camel/language/simple/FileLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/simple/FileLanguage.java
@@ -105,4 +105,7 @@
         return FileExpressionBuilder.simpleExpression(expression);
     }
 
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
index 7343c3a..caef1c5 100644
--- a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
@@ -120,4 +120,7 @@
         throw new ExpressionIllegalSyntaxException(expression);
     }
 
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java
index ecbaf4f..c66fec8 100644
--- a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java
+++ b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguageSupport.java
@@ -24,6 +24,7 @@
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.builder.PredicateBuilder;
@@ -37,7 +38,7 @@
 /**
  * Abstract base class for Simple languages.
  */
-public abstract class SimpleLanguageSupport implements Language {
+public abstract class SimpleLanguageSupport implements Language, IsSingleton {
 
     protected static final Pattern PATTERN = Pattern.compile(
             "^\\$\\{(.+)\\}\\s+(==|>|>=|<|<=|!=|contains|not contains|regex|not regex|in|not in)\\s+(.+)$");
diff --git a/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java b/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
index 51d8bd4..c116154 100644
--- a/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
@@ -17,6 +17,7 @@
 package org.apache.camel.language.tokenizer;
 
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.builder.PredicateBuilder;
@@ -26,7 +27,7 @@
 /**
  * A language for tokenizer expressions.
  */
-public class TokenizeLanguage implements Language {
+public class TokenizeLanguage implements Language, IsSingleton {
 
     private String token;
     private String headerName;
@@ -102,4 +103,8 @@
     public void setRegex(boolean regex) {
         this.regex = regex;
     }
+
+    public boolean isSingleton() {
+        return false;
+    }
 }
\ No newline at end of file
diff --git a/camel-core/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java b/camel-core/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
index 4a09c26..58cb3b9 100644
--- a/camel-core/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
@@ -19,6 +19,7 @@
 import javax.xml.namespace.QName;
 
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.xml.XPathBuilder;
 import org.apache.camel.spi.Language;
@@ -28,7 +29,7 @@
  *
  * @version $Revision$
  */
-public class XPathLanguage implements Language {
+public class XPathLanguage implements Language, IsSingleton {
     private QName resultType;
 
     public Predicate createPredicate(String expression) {
@@ -56,4 +57,8 @@
             builder.setResultQName(resultType);
         }
     }
+
+    public boolean isSingleton() {
+        return false;
+    }
 }
diff --git a/camel-core/src/main/java/org/apache/camel/spi/Injector.java b/camel-core/src/main/java/org/apache/camel/spi/Injector.java
index 6bb795f..cb9e94a 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/Injector.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/Injector.java
@@ -33,4 +33,14 @@
      * @return a newly created instance
      */
     <T> T newInstance(Class<T> type);
+
+    /**
+     * Instantiates a new instance of the given object type possibly injecting values
+     * into the object in the process
+     *
+     * @param instance an instance of the type to create
+     * @return a newly created instance
+     */
+    <T> T newInstance(Class<T> type, Object instance);
+
 }
diff --git a/camel-core/src/main/java/org/apache/camel/builder/PredicateSupport.java b/camel-core/src/main/java/org/apache/camel/util/PredicateAssertHelper.java
similarity index 86%
rename from camel-core/src/main/java/org/apache/camel/builder/PredicateSupport.java
rename to camel-core/src/main/java/org/apache/camel/util/PredicateAssertHelper.java
index 2db1b88..be7dc93 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/PredicateSupport.java
+++ b/camel-core/src/main/java/org/apache/camel/util/PredicateAssertHelper.java
@@ -14,17 +14,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.builder;
+package org.apache.camel.util;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Predicate;
 
 /**
- * A useful base class for {@link Predicate} implementations
+ * A helper for doing {@link Predicate} assertions.
  *
  * @version $Revision$
  */
-public abstract class PredicateSupport implements Predicate {
+public final class PredicateAssertHelper {
+
+    private PredicateAssertHelper() {
+        // Utility class
+    }
 
     public static void assertMatches(Predicate predicate, String text, Exchange exchange) {
         if (!predicate.matches(exchange)) {
@@ -36,4 +40,5 @@
         }
 
     }
-}
+
+}
\ No newline at end of file
diff --git a/camel-core/src/main/java/org/apache/camel/util/ReflectionInjector.java b/camel-core/src/main/java/org/apache/camel/util/ReflectionInjector.java
index c37c695..bf690c7 100644
--- a/camel-core/src/main/java/org/apache/camel/util/ReflectionInjector.java
+++ b/camel-core/src/main/java/org/apache/camel/util/ReflectionInjector.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.util;
 
+import org.apache.camel.IsSingleton;
 import org.apache.camel.spi.Injector;
 
 /**
@@ -30,4 +31,14 @@
     public <T> T newInstance(Class<T> type) {
         return ObjectHelper.newInstance(type);
     }
+
+    public <T> T newInstance(Class<T> type, Object instance) {
+        if (instance instanceof IsSingleton) {
+            boolean singleton = ((IsSingleton) instance).isSingleton();
+            if (singleton) {
+                return type.cast(instance);
+            }
+        }
+        return newInstance(type);
+    }
 }
diff --git a/camel-core/src/test/java/org/apache/camel/InjectorDefaultsToReflectionTest.java b/camel-core/src/test/java/org/apache/camel/InjectorDefaultsToReflectionTest.java
index a85846d..ae7cccb 100644
--- a/camel-core/src/test/java/org/apache/camel/InjectorDefaultsToReflectionTest.java
+++ b/camel-core/src/test/java/org/apache/camel/InjectorDefaultsToReflectionTest.java
@@ -16,23 +16,44 @@
  */
 package org.apache.camel;
 
-import junit.framework.TestCase;
-import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.spi.Injector;
 import org.apache.camel.util.ReflectionInjector;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * @version $Revision$
  */
-public class InjectorDefaultsToReflectionTest extends TestCase {
-    private static final transient Log LOG = LogFactory.getLog(InjectorDefaultsToReflectionTest.class);
-    
+public class InjectorDefaultsToReflectionTest extends ContextTestSupport {
+
     public void testInjectorIsReflectionByDefault() throws Exception {
-        Injector injector = new DefaultCamelContext().getInjector();
-        assertTrue("Injector should be reflection based but was: " + injector,
-                   injector instanceof ReflectionInjector);
-        LOG.debug("Found injector: " + injector);
+        Injector injector = context.getInjector();
+        assertIsInstanceOf(ReflectionInjector.class, injector);
     }
+
+    public void testNewInstance() throws Exception {
+        Injector injector = context.getInjector();
+
+        MyFoo foo = injector.newInstance(MyFoo.class);
+        foo.setName("Claus");
+
+        MyFoo foo2 = injector.newInstance(MyFoo.class);
+        assertNotSame(foo, foo2);
+
+        assertEquals("Claus", foo.getName());
+        assertNull(foo2.getName());
+    }
+
+    public void testSharedInstance() throws Exception {
+        Injector injector = context.getInjector();
+
+        MyBarSingleton bar = injector.newInstance(MyBarSingleton.class, new MyBarSingleton());
+        bar.setName("Claus");
+
+        MyBarSingleton bar2 = injector.newInstance(MyBarSingleton.class, bar);
+        assertSame(bar, bar2);
+
+        assertEquals("Claus", bar.getName());
+        assertEquals("Claus", bar2.getName());
+    }
+
+
 }
diff --git a/camel-core/src/test/java/org/apache/camel/MyBarSingleton.java b/camel-core/src/test/java/org/apache/camel/MyBarSingleton.java
new file mode 100644
index 0000000..9583c1c
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/MyBarSingleton.java
@@ -0,0 +1,45 @@
+/**
+ * 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;
+
+/**
+ * @version $Revision$
+ */
+public class MyBarSingleton implements IsSingleton {
+
+    private String name;
+
+    public MyBarSingleton() {
+    }
+
+    public MyBarSingleton(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isSingleton() {
+        return true;
+    }
+
+}
diff --git a/camel-core/src/test/java/org/apache/camel/MyFoo.java b/camel-core/src/test/java/org/apache/camel/MyFoo.java
new file mode 100644
index 0000000..6aae27d
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/MyFoo.java
@@ -0,0 +1,40 @@
+/**
+ * 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;
+
+/**
+ * @version $Revision$
+ */
+public class MyFoo {
+
+    private String name;
+
+    public MyFoo() {
+    }
+
+    public MyFoo(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/camel-core/src/test/java/org/apache/camel/TestSupport.java b/camel-core/src/test/java/org/apache/camel/TestSupport.java
index e27dd65..c832f99 100644
--- a/camel-core/src/test/java/org/apache/camel/TestSupport.java
+++ b/camel-core/src/test/java/org/apache/camel/TestSupport.java
@@ -22,7 +22,6 @@
 
 import junit.framework.TestCase;
 import org.apache.camel.builder.Builder;
-import org.apache.camel.builder.PredicateSupport;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.builder.ValueBuilder;
 import org.apache.camel.impl.DefaultCamelContext;
@@ -30,6 +29,7 @@
 import org.apache.camel.processor.DelegateAsyncProcessor;
 import org.apache.camel.processor.DelegateProcessor;
 import org.apache.camel.util.ExchangeHelper;
+import org.apache.camel.util.PredicateAssertHelper;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -228,7 +228,7 @@
      */
     protected void assertPredicateDoesNotMatch(Predicate predicate, Exchange exchange) {
         try {
-            PredicateSupport.assertMatches(predicate, "Predicate should match: ", exchange);
+            PredicateAssertHelper.assertMatches(predicate, "Predicate should match: ", exchange);
         } catch (AssertionError e) {
             log.debug("Caught expected assertion error: " + e);
         }
@@ -240,7 +240,7 @@
      */
     protected boolean assertPredicate(final Predicate predicate, Exchange exchange, boolean expected) {
         if (expected) {
-            PredicateSupport.assertMatches(predicate, "Predicate failed: ", exchange);
+            PredicateAssertHelper.assertMatches(predicate, "Predicate failed: ", exchange);
         }
         boolean value = predicate.matches(exchange);
 
diff --git a/camel-core/src/test/java/org/apache/camel/component/dataset/CustomDataSetTest.java b/camel-core/src/test/java/org/apache/camel/component/dataset/CustomDataSetTest.java
index 2749101..5d0aa6c 100644
--- a/camel-core/src/test/java/org/apache/camel/component/dataset/CustomDataSetTest.java
+++ b/camel-core/src/test/java/org/apache/camel/component/dataset/CustomDataSetTest.java
@@ -24,10 +24,10 @@
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.builder.PredicateBuilder;
-import org.apache.camel.builder.PredicateSupport;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.builder.xml.XPathBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.util.PredicateAssertHelper;
 
 /**
  * @version $Revision$
@@ -41,7 +41,7 @@
             // lets compare the XPath result
             Predicate predicate = PredicateBuilder.isEqualTo(expression, ExpressionBuilder.constantExpression(index));
             log.debug("evaluating predicate: " + predicate);
-            PredicateSupport.assertMatches(predicate, "Actual: " + actual, actual);
+            PredicateAssertHelper.assertMatches(predicate, "Actual: " + actual, actual);
         }
 
         protected Object createMessageBody(long messageIndex) {
diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java
index 8756fff..af1f115 100644
--- a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java
+++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.impl;
 
+import java.util.List;
+
 import junit.framework.TestCase;
 import org.apache.camel.Component;
 import org.apache.camel.component.bean.BeanComponent;
@@ -39,4 +41,14 @@
         assertNull(component);
     }
 
+    public void testGetComponents() throws Exception {
+        DefaultCamelContext ctx = new DefaultCamelContext();
+        Component component = ctx.getComponent("bean");
+        assertNotNull(component);
+
+        List<String> list = ctx.getComponentNames();
+        assertEquals(1, list.size());
+        assertEquals("bean", list.get(0));
+    }
+
 }
diff --git a/camel-core/src/test/java/org/apache/camel/language/SimpleTest.java b/camel-core/src/test/java/org/apache/camel/language/SimpleTest.java
index 917e9c6..d405fb2 100644
--- a/camel-core/src/test/java/org/apache/camel/language/SimpleTest.java
+++ b/camel-core/src/test/java/org/apache/camel/language/SimpleTest.java
@@ -16,8 +16,9 @@
  */
 package org.apache.camel.language;
 
-import org.apache.camel.LanguageTestSupport;
 import org.apache.camel.ExpressionIllegalSyntaxException;
+import org.apache.camel.LanguageTestSupport;
+import org.apache.camel.language.simple.SimpleLanguage;
 
 /**
  * @version $Revision$
@@ -41,6 +42,14 @@
         assertExpression("header.foo", "abc");
     }
 
+    public void testLanguagesInContext() throws Exception {
+        // evaluate so we know there is 1 language in the context
+        assertExpression("id", exchange.getIn().getMessageId());
+
+        assertEquals(1, context.getLanguageNames().size());
+        assertEquals("simple", context.getLanguageNames().get(0));
+    }
+
     public void testComplexExpressions() throws Exception {
         assertExpression("hey ${in.header.foo}", "hey abc");
         assertExpression("hey ${in.header.foo}!", "hey abc!");
@@ -51,7 +60,6 @@
         assertExpression("${in.header.foo}!", "abc!");
     }
 
-
     public void testInvalidComplexExpression() throws Exception {
         try {
             assertExpression("hey ${foo", "bad expression!");
diff --git a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
index 3c4eb0f..3198d5b 100644
--- a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
+++ b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
@@ -18,12 +18,13 @@
 
 import groovy.lang.GroovyClassLoader;
 import groovy.lang.Script;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.spi.Language;
 
 /**
  * @version $Revision$
  */
-public class GroovyLanguage implements Language  {
+public class GroovyLanguage implements Language, IsSingleton {
 
     public static GroovyExpression groovy(String expression) {
         return new GroovyLanguage().createExpression(expression);
@@ -38,7 +39,12 @@
         return new GroovyExpression(scriptType, expression);
     }
 
+    @SuppressWarnings("unchecked")
     protected Class<Script> parseExpression(String expression) {
         return new GroovyClassLoader().parseClass(expression);
     }
+
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/components/camel-guice/src/main/java/org/apache/camel/guice/impl/GuiceInjector.java b/components/camel-guice/src/main/java/org/apache/camel/guice/impl/GuiceInjector.java
index bf9dc84..c46db02 100644
--- a/components/camel-guice/src/main/java/org/apache/camel/guice/impl/GuiceInjector.java
+++ b/components/camel-guice/src/main/java/org/apache/camel/guice/impl/GuiceInjector.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.guice.impl;
 
+import org.apache.camel.IsSingleton;
 import org.apache.camel.spi.Injector;
 
 /**
@@ -36,4 +37,14 @@
         return injector.getInstance(type);
     }
 
+    public <T> T newInstance(Class<T> type, Object instance) {
+        if (instance instanceof IsSingleton) {
+            boolean singleton = ((IsSingleton) instance).isSingleton();
+            if (singleton) {
+                return type.cast(instance);
+            }
+        }
+        return newInstance(type);
+    }
+
 }
diff --git a/components/camel-jxpath/src/main/java/org/apache/camel/language/jxpath/JXPathLanguage.java b/components/camel-jxpath/src/main/java/org/apache/camel/language/jxpath/JXPathLanguage.java
index 4dc7391..f23e7c6 100644
--- a/components/camel-jxpath/src/main/java/org/apache/camel/language/jxpath/JXPathLanguage.java
+++ b/components/camel-jxpath/src/main/java/org/apache/camel/language/jxpath/JXPathLanguage.java
@@ -17,6 +17,7 @@
 package org.apache.camel.language.jxpath;
 
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.spi.Language;
 
@@ -24,7 +25,7 @@
  * <a href="http://commons.apache.org/jxpath/">JXPath</a> {@link Language}
  * provider
  */
-public class JXPathLanguage implements Language {
+public class JXPathLanguage implements Language, IsSingleton {
 
     public Expression createExpression(String expression) {
         return new JXPathExpression(expression, Object.class);
@@ -34,4 +35,7 @@
         return new JXPathExpression(predicate, Boolean.class);
     }
 
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/components/camel-mvel/src/main/java/org/apache/camel/language/mvel/MvelLanguage.java b/components/camel-mvel/src/main/java/org/apache/camel/language/mvel/MvelLanguage.java
index 6906bd1..c8780b2 100644
--- a/components/camel-mvel/src/main/java/org/apache/camel/language/mvel/MvelLanguage.java
+++ b/components/camel-mvel/src/main/java/org/apache/camel/language/mvel/MvelLanguage.java
@@ -18,6 +18,7 @@
 
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.spi.Language;
 
 /**
@@ -25,7 +26,7 @@
  * 
  * @version $Revision$
  */
-public class MvelLanguage implements Language {
+public class MvelLanguage implements Language, IsSingleton {
 
     public Predicate createPredicate(String expression) {
         return new MvelExpression(this, expression, Boolean.class);
@@ -34,4 +35,8 @@
     public Expression createExpression(String expression) {
         return new MvelExpression(this, expression, Object.class);
     }
+
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/components/camel-ognl/src/main/java/org/apache/camel/language/ognl/OgnlLanguage.java b/components/camel-ognl/src/main/java/org/apache/camel/language/ognl/OgnlLanguage.java
index e4037fb..1ca4596 100644
--- a/components/camel-ognl/src/main/java/org/apache/camel/language/ognl/OgnlLanguage.java
+++ b/components/camel-ognl/src/main/java/org/apache/camel/language/ognl/OgnlLanguage.java
@@ -17,6 +17,7 @@
 package org.apache.camel.language.ognl;
 
 import org.apache.camel.Expression;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.Predicate;
 import org.apache.camel.spi.Language;
 
@@ -25,7 +26,7 @@
  *
  * @version $Revision$
  */
-public class OgnlLanguage implements Language {
+public class OgnlLanguage implements Language, IsSingleton {
 
     public Predicate createPredicate(String expression) {
         return new OgnlExpression(this, expression, Boolean.class);
@@ -34,4 +35,8 @@
     public Expression createExpression(String expression) {
         return new OgnlExpression(this, expression, Object.class);
     }
+
+    public boolean isSingleton() {
+        return true;
+    }
 }
diff --git a/components/camel-script/src/main/java/org/apache/camel/builder/script/ScriptLanguage.java b/components/camel-script/src/main/java/org/apache/camel/builder/script/ScriptLanguage.java
index 65d49cb..5d8cddd 100644
--- a/components/camel-script/src/main/java/org/apache/camel/builder/script/ScriptLanguage.java
+++ b/components/camel-script/src/main/java/org/apache/camel/builder/script/ScriptLanguage.java
@@ -18,12 +18,13 @@
 
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
+import org.apache.camel.IsSingleton;
 import org.apache.camel.spi.Language;
 
 /**
  * @version $Revision$
  */
-public class ScriptLanguage implements Language {
+public class ScriptLanguage implements Language, IsSingleton {
     private final String language;
 
     public ScriptLanguage(String language) {
@@ -37,4 +38,8 @@
     public Expression createExpression(String expression) {
         return new ScriptBuilder(language, expression);
     }
+
+    public boolean isSingleton() {
+        return false;
+    }
 }
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringInjector.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringInjector.java
index 70bbb05..1eb1a95 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringInjector.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringInjector.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.spring.spi;
 
+import org.apache.camel.IsSingleton;
 import org.apache.camel.spi.Injector;
 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 import org.springframework.context.ConfigurableApplicationContext;
@@ -40,6 +41,16 @@
         return type.cast(value);
     }
 
+    public <T> T newInstance(Class<T> type, Object instance) {
+        if (instance instanceof IsSingleton) {
+            boolean singleton = ((IsSingleton) instance).isSingleton();
+            if (singleton) {
+                return type.cast(instance);
+            }
+        }
+        return newInstance(type);
+    }
+
     public int getAutowireMode() {
         return autowireMode;
     }
diff --git a/components/camel-test/src/main/java/org/apache/camel/test/TestSupport.java b/components/camel-test/src/main/java/org/apache/camel/test/TestSupport.java
index 0c34a59b..460342b 100644
--- a/components/camel-test/src/main/java/org/apache/camel/test/TestSupport.java
+++ b/components/camel-test/src/main/java/org/apache/camel/test/TestSupport.java
@@ -30,7 +30,6 @@
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.builder.Builder;
-import org.apache.camel.builder.PredicateSupport;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.builder.ValueBuilder;
 import org.apache.camel.impl.DefaultCamelContext;
@@ -38,6 +37,7 @@
 import org.apache.camel.processor.DelegateAsyncProcessor;
 import org.apache.camel.processor.DelegateProcessor;
 import org.apache.camel.util.ExchangeHelper;
+import org.apache.camel.util.PredicateAssertHelper;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -229,7 +229,7 @@
      */
     protected void assertPredicateDoesNotMatch(Predicate predicate, Exchange exchange) {
         try {
-            PredicateSupport.assertMatches(predicate, "Predicate should match", exchange);
+            PredicateAssertHelper.assertMatches(predicate, "Predicate should match", exchange);
         } catch (AssertionError e) {
             log.debug("Caught expected assertion error: " + e);
         }
@@ -241,7 +241,7 @@
      */
     protected boolean assertPredicate(Predicate predicate, Exchange exchange, boolean expected) {
         if (expected) {
-            PredicateSupport.assertMatches(predicate, "Predicate failed", exchange);
+            PredicateAssertHelper.assertMatches(predicate, "Predicate failed", exchange);
         }
         boolean value = predicate.matches(exchange);