You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2026/01/06 15:58:19 UTC

(juneau) branch master updated: New org.apache.juneau.commons.inject package

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

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


The following commit(s) were added to refs/heads/master by this push:
     new ef8cc57bed New org.apache.juneau.commons.inject package
ef8cc57bed is described below

commit ef8cc57bedce8cc5903bbe99032e63aaf9a08020
Author: James Bognar <ja...@salesforce.com>
AuthorDate: Tue Jan 6 10:58:15 2026 -0500

    New org.apache.juneau.commons.inject package
---
 .../apache/juneau/bean/openapi3/ui/OpenApiUI.java  |   3 +-
 .../apache/juneau/bean/swagger/ui/SwaggerUI.java   |   3 +-
 .../juneau/commons/inject/BasicBeanStore.java      | 359 ++++++++
 .../juneau/commons/inject/BasicBeanStore2.java}    |  85 +-
 .../apache/juneau/commons/inject/BeanStore.java    | 138 +++
 .../juneau/commons/inject/WritableBeanStore.java   | 113 +++
 .../juneau/commons/reflect/ConstructorInfo.java    |   5 +-
 .../apache/juneau/commons/reflect/FieldInfo.java   |  10 +-
 .../apache/juneau/commons/reflect/MethodInfo.java  |  10 +-
 .../org/apache/juneau/commons/utils/BeanUtils.java | 110 +++
 .../main/java/org/apache/juneau/BeanBuilder.java   |   7 +-
 .../java/org/apache/juneau/annotation/Name.java    |   4 +-
 .../java/org/apache/juneau/annotation/Named.java   |   6 +-
 .../apache/juneau/cp/BeanCreateMethodFinder.java   |  23 +-
 .../java/org/apache/juneau/cp/BeanCreator.java     |  24 +-
 .../main/java/org/apache/juneau/cp/FileFinder.java |   7 +-
 .../main/java/org/apache/juneau/cp/Messages.java   |   3 +-
 .../org/apache/juneau/encoders/EncoderSet.java     |   9 +-
 .../java/org/apache/juneau/parser/ParserSet.java   |   9 +-
 .../apache/juneau/serializer/SerializerSet.java    |   9 +-
 .../java/org/apache/juneau/svl/VarResolver.java    |  11 +-
 .../org/apache/juneau/svl/VarResolverSession.java  |   9 +-
 .../org/apache/juneau/rest/client/RestClient.java  |   5 +-
 .../juneau/rest/springboot/SpringBeanStore.java    |   8 +-
 .../juneau/rest/springboot/SpringRestServlet.java  |   5 +-
 .../java/org/apache/juneau/rest/RestChild.java     |   3 +-
 .../java/org/apache/juneau/rest/RestChildren.java  |   5 +-
 .../java/org/apache/juneau/rest/RestContext.java   | 123 +--
 .../java/org/apache/juneau/rest/RestOpContext.java |  73 +-
 .../java/org/apache/juneau/rest/RestOpSession.java |   3 +-
 .../org/apache/juneau/rest/RestOperations.java     |   5 +-
 .../java/org/apache/juneau/rest/RestSession.java   |   7 +-
 .../org/apache/juneau/rest/annotation/Rest.java    |   3 +-
 .../juneau/rest/annotation/RestAnnotation.java     |   9 +-
 .../apache/juneau/rest/annotation/RestInject.java  |   5 +-
 .../org/apache/juneau/rest/arg/DefaultArg.java     |   3 +-
 .../apache/juneau/rest/arg/PathRemainderArg.java   |   2 +-
 .../org/apache/juneau/rest/arg/RestOpArgList.java  |   5 +-
 .../apache/juneau/rest/arg/RestOpSessionArgs.java  |   5 +-
 .../apache/juneau/rest/config/DefaultConfig.java   |   3 +-
 .../juneau/rest/converter/RestConverterList.java   |   5 +-
 .../juneau/rest/debug/BasicDebugEnablement.java    |   5 +-
 .../apache/juneau/rest/debug/DebugEnablement.java  |  13 +-
 .../apache/juneau/rest/guard/RestGuardList.java    |   5 +-
 .../apache/juneau/rest/logger/BasicCallLogger.java |   7 +-
 .../rest/logger/BasicDisabledCallLogger.java       |   5 +-
 .../juneau/rest/logger/BasicTestCallLogger.java    |   5 +-
 .../rest/logger/BasicTestCaptureCallLogger.java    |   7 +-
 .../org/apache/juneau/rest/logger/CallLogger.java  |  15 +-
 .../apache/juneau/rest/logger/CallLoggerRule.java  |   5 +-
 .../juneau/rest/matcher/RestMatcherList.java       |   5 +-
 .../rest/processor/ResponseProcessorList.java      |   9 +-
 .../juneau/rest/staticfile/BasicStaticFiles.java   |   5 +-
 .../apache/juneau/rest/staticfile/StaticFiles.java |   5 +-
 .../apache/juneau/rest/stats/MethodExecStats.java  |   5 +-
 .../apache/juneau/rest/stats/MethodExecStore.java  |   9 +-
 .../apache/juneau/rest/stats/MethodInvoker.java    |   3 +-
 .../org/apache/juneau/rest/stats/ThrownStats.java  |   7 +-
 .../org/apache/juneau/rest/stats/ThrownStore.java  |  11 +-
 .../juneau/rest/swagger/BasicSwaggerProvider.java  |   5 +-
 .../juneau/rest/swagger/SwaggerProvider.java       |   7 +-
 .../juneau/commons/inject/BasicBeanStore_Test.java | 942 +++++++++++++++++++++
 .../java/org/apache/juneau/cp/BeanStore_Test.java  | 131 +--
 .../java/org/apache/juneau/cp/FileFinder_Test.java |   3 +-
 .../apache/juneau/mstat/MethodExecStore_Test.java  |   7 +-
 .../org/apache/juneau/mstat/ThrownStore_Test.java  |   5 +-
 .../juneau/rest/RestContext_Builder_Test.java      |  21 +-
 .../java/org/apache/juneau/rest/Swagger_Test.java  |   3 +-
 .../rest/annotation/RestAnnotation_Test.java       |  11 +-
 .../rest/springboot/SpringBeanStore_Test.java      |   2 +-
 70 files changed, 2116 insertions(+), 381 deletions(-)

diff --git a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/ui/OpenApiUI.java b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/ui/OpenApiUI.java
index f80222a968..a027e53364 100644
--- a/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/ui/OpenApiUI.java
+++ b/juneau-bean/juneau-bean-openapi-v3/src/main/java/org/apache/juneau/bean/openapi3/ui/OpenApiUI.java
@@ -30,6 +30,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.bean.html5.*;
 import org.apache.juneau.bean.openapi3.*;
 import org.apache.juneau.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.utils.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.swap.*;
@@ -55,7 +56,7 @@ public class OpenApiUI extends ObjectSwap<OpenApi,Div> {
 
 	// @formatter:off
 	static final FileFinder RESOURCES = FileFinder
-		.create(BasicBeanStore.INSTANCE)
+		.create(BasicBeanStore2.INSTANCE)
 		.cp(OpenApiUI.class, null, true)
 		.dir(",")
 		.caching(Boolean.getBoolean("RestContext.disableClasspathResourceCaching.b") ? -1 : 1_000_000)
diff --git a/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/ui/SwaggerUI.java b/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/ui/SwaggerUI.java
index 3493a8777f..88520c1756 100644
--- a/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/ui/SwaggerUI.java
+++ b/juneau-bean/juneau-bean-swagger-v2/src/main/java/org/apache/juneau/bean/swagger/ui/SwaggerUI.java
@@ -29,6 +29,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.bean.html5.*;
 import org.apache.juneau.bean.swagger.*;
 import org.apache.juneau.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.utils.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.swap.*;
@@ -54,7 +55,7 @@ public class SwaggerUI extends ObjectSwap<Swagger,Div> {
 
 	// @formatter:off
 	static final FileFinder RESOURCES = FileFinder
-		.create(BasicBeanStore.INSTANCE)
+		.create(BasicBeanStore2.INSTANCE)
 		.cp(SwaggerUI.class, null, true)
 		.dir(",")
 		.caching(Boolean.getBoolean("RestContext.disableClasspathResourceCaching.b") ? -1 : 1_000_000)
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore.java
new file mode 100644
index 0000000000..66fbf02fdc
--- /dev/null
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore.java
@@ -0,0 +1,359 @@
+/*
+ * 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.juneau.commons.inject;
+
+import static org.apache.juneau.commons.utils.CollectionUtils.*;
+import static org.apache.juneau.commons.utils.Utils.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.function.*;
+
+import org.apache.juneau.commons.collections.*;
+
+/**
+ * Basic implementation of {@link WritableBeanStore}.
+ *
+ * <p>
+ * A simple storage database for beans keyed by type and name.
+ * Used to retrieve and instantiate beans using an injection-like API.
+ * It's similar in concept to the injection framework of Spring but greatly simplified in function and not intended to implement a full-fledged injection framework.
+ *
+ * <p>
+ * Beans can be stored with or without names.  Named beans are typically resolved using
+ * the <ja>@Name</ja> or <ja>@Qualified</ja> annotations on constructor or method parameters.
+ *
+ * <p>
+ * This implementation is thread-safe and supports parent bean stores for hierarchical bean resolution.
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * 	<li class='jc'>{@link BeanStore} - Read-only bean lookup interface
+ * 	<li class='jc'>{@link WritableBeanStore} - Writable bean store interface
+ * </ul>
+ */
+public class BasicBeanStore implements WritableBeanStore {
+
+	private final ConcurrentHashMap<Class<?>, ConcurrentHashMap<String, Supplier<?>>> entries;
+	private final BeanStore parent;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param parent The parent bean store.  Can be <jk>null</jk>.  Bean searches are performed recursively up this parent chain.
+	 */
+	public BasicBeanStore(BeanStore parent) {
+		this.parent = parent;
+		entries = new ConcurrentHashMap<>();
+		addSupplier(BasicBeanStore.class, ()->this, null);
+	}
+
+	/**
+	 * Same as {@link #addBean(Class,Object)} but returns the bean instead of this object for fluent calls.
+	 *
+	 * @param <T> The class to associate this bean with.
+	 * @param beanType The class to associate this bean with.
+	 * @param bean The bean.  Can be <jk>null</jk>.
+	 * @return The bean.
+	 */
+	public <T> T add(Class<T> beanType, T bean) {
+		add(beanType, bean, null);
+		return bean;
+	}
+
+	/**
+	 * Same as {@link #addBean(Class,Object,String)} but returns the bean instead of this object for fluent calls.
+	 *
+	 * @param <T> The class to associate this bean with.
+	 * @param beanType The class to associate this bean with.
+	 * @param bean The bean.  Can be <jk>null</jk>.
+	 * @param name The bean name if this is a named bean.  Can be <jk>null</jk>.
+	 * @return The bean.
+	 */
+	public <T> T add(Class<T> beanType, T bean, String name) {
+		addBean(beanType, bean, name);
+		return bean;
+	}
+
+	/**
+	 * Adds an unnamed bean of the specified type to this store.
+	 *
+	 * @param <T> The class to associate this bean with.
+	 * @param beanType The class to associate this bean with.
+	 * @param bean The bean.  Can be <jk>null</jk>.
+	 * @return This object.
+	 */
+	@Override
+	public <T> BasicBeanStore addBean(Class<T> beanType, T bean) {
+		return addBean(beanType, bean, null);
+	}
+
+	/**
+	 * Adds a named bean of the specified type to this store.
+	 *
+	 * @param <T> The class to associate this bean with.
+	 * @param beanType The class to associate this bean with.
+	 * @param bean The bean.  Can be <jk>null</jk>.
+	 * @param name The bean name if this is a named bean.  Can be <jk>null</jk>.
+	 * @return This object.
+	 */
+	@Override
+	public <T> BasicBeanStore addBean(Class<T> beanType, T bean, String name) {
+		return addSupplier(beanType, () -> bean, name);
+	}
+
+	/**
+	 * Adds a supplier for an unnamed bean of the specified type to this store.
+	 *
+	 * <p>
+	 * The supplier will be invoked lazily when the bean is first requested.
+	 *
+	 * @param <T> The class to associate this bean with.
+	 * @param beanType The class to associate this bean with.
+	 * @param bean The bean supplier.
+	 * @return This object.
+	 */
+	@Override
+	public <T> BasicBeanStore addSupplier(Class<T> beanType, Supplier<T> bean) {
+		return addSupplier(beanType, bean, null);
+	}
+
+	/**
+	 * Adds a supplier for a named bean of the specified type to this store.
+	 *
+	 * <p>
+	 * The supplier will be invoked lazily when the bean is first requested.
+	 *
+	 * @param <T> The class to associate this bean with.
+	 * @param beanType The class to associate this bean with.
+	 * @param bean The bean supplier.
+	 * @param name The bean name if this is a named bean.  Can be <jk>null</jk>.
+	 * @return This object.
+	 */
+	@Override
+	public <T> BasicBeanStore addSupplier(Class<T> beanType, Supplier<T> bean, String name) {
+		var typeMap = entries.computeIfAbsent(beanType, k -> new ConcurrentHashMap<>());
+		var key = emptyIfNull(name);
+		typeMap.put(key, bean);
+		return this;
+	}
+
+	/**
+	 * Removes all beans from this store.
+	 *
+	 * <p>
+	 * This operation only affects this store and does not affect the parent bean store.
+	 *
+	 * @return This object.
+	 */
+	@Override
+	public BasicBeanStore clear() {
+		entries.clear();
+		return this;
+	}
+
+	/**
+	 * Returns the unnamed bean of the specified type.
+	 *
+	 * <p>
+	 * If no unnamed bean is found in this store, searches the parent store recursively.
+	 *
+	 * @param <T> The type of bean to return.
+	 * @param beanType The type of bean to return.
+	 * @return The bean, or {@link Optional#empty()} if not found.
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	public <T> Optional<T> getBean(Class<T> beanType) {
+		var typeMap = entries.get(beanType);
+		if (nn(typeMap)) {
+			var supplier = typeMap.get("");
+			if (nn(supplier))
+				return opt((T)supplier.get());
+		}
+		if (nn(parent))
+			return parent.getBean(beanType);
+		return opte();
+	}
+
+
+	/**
+	 * Returns the named bean of the specified type.
+	 *
+	 * <p>
+	 * If no bean with the specified name is found in this store, searches the parent store recursively.
+	 *
+	 * @param <T> The type of bean to return.
+	 * @param beanType The type of bean to return.
+	 * @param name The bean name.  Can be <jk>null</jk>.
+	 * @return The bean, or {@link Optional#empty()} if not found.
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	public <T> Optional<T> getBean(Class<T> beanType, String name) {
+		var typeMap = entries.get(beanType);
+		if (nn(typeMap)) {
+			var key = emptyIfNull(name);
+			var supplier = typeMap.get(key);
+			if (nn(supplier))
+				return opt((T)supplier.get());
+		}
+		if (nn(parent))
+			return parent.getBean(beanType, name);
+		return opte();
+	}
+
+	/**
+	 * Returns all beans of the specified type, keyed by bean name.
+	 *
+	 * <p>
+	 * The map keys are the bean names (empty string for unnamed beans), and the values are the bean instances.
+	 * Results from the parent store are included first, then beans from this store (which override parent beans with the same name).
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @return A map of bean names to bean instances.  Never <jk>null</jk>.
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	public <T> Map<String,T> getBeansOfType(Class<T> beanType) {
+		Map<String,T> result = map();
+		if (nn(parent)) {
+			var parentBeans = parent.getBeansOfType(beanType);
+			parentBeans.forEach((name, bean) -> result.put(name, bean));
+		}
+		var typeMap = entries.get(beanType);
+		if (nn(typeMap)) {
+			typeMap.forEach((name, supplier) -> result.put(name, (T)supplier.get()));
+		}
+		return result;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this store contains at least one unnamed bean of the specified type.
+	 *
+	 * <p>
+	 * If not found in this store, searches the parent store recursively.
+	 *
+	 * @param beanType The bean type to check.
+	 * @return <jk>true</jk> if this store contains at least one unnamed bean of the specified type.
+	 */
+	@Override
+	public boolean hasBean(Class<?> beanType) {
+		var typeMap = entries.get(beanType);
+		if (nn(typeMap) && typeMap.containsKey(""))
+			return true;
+		if (n(parent))
+			return false;
+		return parent.hasBean(beanType);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this store contains a bean of the specified type and name.
+	 *
+	 * <p>
+	 * If not found in this store, searches the parent store recursively.
+	 *
+	 * @param beanType The bean type to check.
+	 * @param name The bean name.  Can be <jk>null</jk>.
+	 * @return <jk>true</jk> if this store contains a bean of the specified type and name.
+	 */
+	@Override
+	public boolean hasBean(Class<?> beanType, String name) {
+		var typeMap = entries.get(beanType);
+		if (nn(typeMap)) {
+			var key = emptyIfNull(name);
+			if (typeMap.containsKey(key))
+				return true;
+		}
+		if (n(parent))
+			return false;
+		return parent.hasBean(beanType, name);
+	}
+
+	/**
+	 * Returns the supplier for an unnamed bean of the specified type.
+	 *
+	 * <p>
+	 * If no supplier is found in this store, searches the parent store recursively.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @return The supplier, or {@link Optional#empty()} if no supplier of the specified type exists.
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	public <T> Optional<Supplier<T>> getBeanSupplier(Class<T> beanType) {
+		var typeMap = entries.get(beanType);
+		if (nn(typeMap)) {
+			var supplier = typeMap.get("");
+			if (nn(supplier))
+				return opt((Supplier<T>)supplier);
+		}
+		if (nn(parent))
+			return parent.getBeanSupplier(beanType);
+		return opte();
+	}
+
+	/**
+	 * Returns the supplier for a named bean of the specified type.
+	 *
+	 * <p>
+	 * If no supplier with the specified name is found in this store, searches the parent store recursively.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @param name The bean name.  Can be <jk>null</jk>.
+	 * @return The supplier, or {@link Optional#empty()} if no supplier of the specified type and name exists.
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	public <T> Optional<Supplier<T>> getBeanSupplier(Class<T> beanType, String name) {
+		var typeMap = entries.get(beanType);
+		if (nn(typeMap)) {
+			var key = emptyIfNull(name);
+			var supplier = typeMap.get(key);
+			if (nn(supplier))
+				return opt((Supplier<T>)supplier);
+		}
+		if (nn(parent))
+			return parent.getBeanSupplier(beanType, name);
+		return opte();
+	}
+
+	@Override /* Overridden from Object */
+	public String toString() {
+		return r(properties());
+	}
+
+	protected FluentMap<String,Object> properties() {
+		// @formatter:off
+		var entryList = list();
+		entries.forEach((type, typeMap) -> {
+			typeMap.forEach((name, supplier) -> {
+				entryList.add(filteredBeanPropertyMap()
+					.a("type", cns(type))
+					.a("bean", id(supplier.get()))
+					.a("name", name));
+			});
+		});
+		return filteredBeanPropertyMap()
+			.a("entries", entryList)
+			.a("identity", id(this))
+			.a("parent", parent instanceof BasicBeanStore parent2 ? parent2.properties() : s(parent));
+		// @formatter:on
+	}
+}
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicBeanStore.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore2.java
similarity index 89%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicBeanStore.java
rename to juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore2.java
index 2b5149eb1f..b4ab083ddb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicBeanStore.java
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore2.java
@@ -14,11 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.juneau.cp;
+package org.apache.juneau.commons.inject;
 
 import static java.util.stream.Collectors.*;
 import static java.util.stream.Collectors.toList;
-import static org.apache.juneau.collections.JsonMap.*;
 import static org.apache.juneau.commons.reflect.ReflectionUtils.*;
 import static org.apache.juneau.commons.utils.AssertionUtils.*;
 import static org.apache.juneau.commons.utils.CollectionUtils.*;
@@ -30,7 +29,6 @@ import java.util.concurrent.*;
 
 import java.util.function.*;
 
-import org.apache.juneau.collections.*;
 import org.apache.juneau.commons.collections.*;
 import org.apache.juneau.commons.concurrent.*;
 import org.apache.juneau.commons.reflect.*;
@@ -69,28 +67,29 @@ import org.apache.juneau.commons.reflect.*;
  * <p>
  * Beans are created through the following methods:
  * <ul class='javatreec'>
- * 	<li class='jm'>{@link BeanCreator#of(Class,BasicBeanStore) BeanCreator.of(Class,BasicBeanStore)}
- * 	<li class='jc'>{@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Class,BasicBeanStore) BeanCreateMethodFinder(Class,Class,BasicBeanStore)}
- * 	<li class='jc'>{@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Object,BasicBeanStore) BeanCreateMethodFinder(Class,Object,BasicBeanStore)}
+ * 	<li class='jm'>{@link BeanCreator#of(Class,BasicBeanStore2) BeanCreator.of(Class,BasicBeanStore2)}
+ * 	<li class='jc'>{@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Class,BasicBeanStore2) BeanCreateMethodFinder(Class,Class,BasicBeanStore2)}
+ * 	<li class='jc'>{@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Object,BasicBeanStore2) BeanCreateMethodFinder(Class,Object,BasicBeanStore2)}
  * </ul>
  *
  * <h5 class='section'>Notes:</h5><ul>
- * 	<li class='note'>Bean stores can be nested using {@link Builder#parent(BasicBeanStore)}.
+ * 	<li class='note'>Bean stores can be nested using {@link Builder#parent(BasicBeanStore2)}.
  * 	<li class='note'>Bean stores can be made read-only using {@link Builder#readOnly()}.
  * 	<li class='note'>Bean stores can be made thread-safe using {@link Builder#threadSafe()}.
  * </ul>
  *
  */
-public class BasicBeanStore {
+public class BasicBeanStore2 {
+
 	/**
 	 * Builder class.
 	 */
 	public static class Builder {
 
-		BasicBeanStore parent;
+		BasicBeanStore2 parent;
 		boolean readOnly, threadSafe;
-		Class<? extends BasicBeanStore> type;
-		BasicBeanStore impl;
+		Class<? extends BasicBeanStore2> type;
+		BasicBeanStore2 impl;
 
 		/**
 		 * Constructor.
@@ -102,11 +101,11 @@ public class BasicBeanStore {
 		 *
 		 * @return A new bean store.
 		 */
-		public BasicBeanStore build() {
+		public BasicBeanStore2 build() {
 			if (nn(impl))
 				return impl;
-			if (type == null || type == BasicBeanStore.class)
-				return new BasicBeanStore(this);
+			if (type == null || type == BasicBeanStore2.class)
+				return new BasicBeanStore2(this);
 
 			var c = info(type);
 
@@ -116,16 +115,16 @@ public class BasicBeanStore {
 				&& x.getParameterCount() == 0
 				&& x.isStatic()
 				&& x.hasName("getInstance")
-			).map(m -> m.<BasicBeanStore>invoke(null));
+			).map(m -> m.<BasicBeanStore2>invoke(null));
 			// @formatter:on
 			if (result.isPresent())
 				return result.get();
 
-			result = c.getPublicConstructor(x -> x.canAccept(this)).map(ci -> ci.<BasicBeanStore>newInstance(this));
+			result = c.getPublicConstructor(x -> x.canAccept(this)).map(ci -> ci.<BasicBeanStore2>newInstance(this));
 			if (result.isPresent())
 				return result.get();
 
-			result = c.getDeclaredConstructor(x -> x.isProtected() && x.canAccept(this)).map(ci -> ci.accessible().<BasicBeanStore>newInstance(this));
+			result = c.getDeclaredConstructor(x -> x.isProtected() && x.canAccept(this)).map(ci -> ci.accessible().<BasicBeanStore2>newInstance(this));
 			if (result.isPresent())
 				return result.get();
 
@@ -138,7 +137,7 @@ public class BasicBeanStore {
 		 * @param value The bean to return from the {@link #build()} method.
 		 * @return This object.
 		 */
-		public Builder impl(BasicBeanStore value) {
+		public Builder impl(BasicBeanStore2 value) {
 			impl = value;
 			return this;
 		}
@@ -153,7 +152,7 @@ public class BasicBeanStore {
 		 * @param value The setting value.
 		 * @return  This object.
 		 */
-		public Builder parent(BasicBeanStore value) {
+		public Builder parent(BasicBeanStore2 value) {
 			parent = value;
 			return this;
 		}
@@ -162,7 +161,7 @@ public class BasicBeanStore {
 		 * Specifies that the bean store is read-only.
 		 *
 		 * <p>
-		 * This means methods such as {@link BasicBeanStore#addBean(Class, Object)} cannot be used.
+		 * This means methods such as {@link BasicBeanStore2#addBean(Class, Object)} cannot be used.
 		 *
 		 * @return  This object.
 		 */
@@ -195,7 +194,7 @@ public class BasicBeanStore {
 		 * @param value The bean store type.
 		 * @return This object.
 		 */
-		public Builder type(Class<? extends BasicBeanStore> value) {
+		public Builder type(Class<? extends BasicBeanStore2> value) {
 			type = value;
 			return this;
 		}
@@ -204,12 +203,12 @@ public class BasicBeanStore {
 	/**
 	 * Non-existent bean store.
 	 */
-	public static final class Void extends BasicBeanStore {}
+	public static final class Void extends BasicBeanStore2 {}
 
 	/**
 	 * Static read-only reusable instance.
 	 */
-	public static final BasicBeanStore INSTANCE = create().readOnly().build();
+	public static final BasicBeanStore2 INSTANCE = create().readOnly().build();
 
 	/**
 	 * Static creator.
@@ -224,16 +223,16 @@ public class BasicBeanStore {
 	 * Static creator.
 	 *
 	 * @param parent Parent bean store.  Can be <jk>null</jk> if this is the root resource.
-	 * @return A new {@link BasicBeanStore} object.
+	 * @return A new {@link BasicBeanStore2} object.
 	 */
-	public static BasicBeanStore of(BasicBeanStore parent) {
+	public static BasicBeanStore2 of(BasicBeanStore2 parent) {
 		return create().parent(parent).build();
 	}
 
 	private final Deque<Entry<?>> entries;
 	private final Map<Class<?>,Entry<?>> unnamedEntries;
 
-	final Optional<BasicBeanStore> parent;
+	final Optional<BasicBeanStore2> parent;
 	final boolean readOnly, threadSafe;
 	final SimpleReadWriteLock lock;
 
@@ -242,19 +241,19 @@ public class BasicBeanStore {
 	 *
 	 * @param builder The builder containing the settings for this bean.
 	 */
-	protected BasicBeanStore(Builder builder) {
+	protected BasicBeanStore2(Builder builder) {
 		parent = opt(builder.parent);
 		readOnly = builder.readOnly;
 		threadSafe = builder.threadSafe;
 		lock = threadSafe ? new SimpleReadWriteLock() : SimpleReadWriteLock.NO_OP;
 		entries = threadSafe ? new ConcurrentLinkedDeque<>() : new LinkedList<>();
 		unnamedEntries = threadSafe ? new ConcurrentHashMap<>() : map();
-		var e = createEntry(BasicBeanStore.class, ()->this, null);
+		var e = createEntry(BasicBeanStore2.class, ()->this, null);
 		entries.addFirst(e);
-		unnamedEntries.put(BasicBeanStore.class, e);
+		unnamedEntries.put(BasicBeanStore2.class, e);
 	}
 
-	BasicBeanStore() {
+	BasicBeanStore2() {
 		this(create());
 	}
 
@@ -293,7 +292,7 @@ public class BasicBeanStore {
 	 * @param bean The bean.  Can be <jk>null</jk>.
 	 * @return This object.
 	 */
-	public <T> BasicBeanStore addBean(Class<T> beanType, T bean) {
+	public <T> BasicBeanStore2 addBean(Class<T> beanType, T bean) {
 		return addBean(beanType, bean, null);
 	}
 
@@ -306,7 +305,7 @@ public class BasicBeanStore {
 	 * @param name The bean name if this is a named bean.  Can be <jk>null</jk>.
 	 * @return This object.
 	 */
-	public <T> BasicBeanStore addBean(Class<T> beanType, T bean, String name) {
+	public <T> BasicBeanStore2 addBean(Class<T> beanType, T bean, String name) {
 		return addSupplier(beanType, () -> bean, name);
 	}
 
@@ -318,7 +317,7 @@ public class BasicBeanStore {
 	 * @param bean The bean supplier.
 	 * @return This object.
 	 */
-	public <T> BasicBeanStore addSupplier(Class<T> beanType, Supplier<T> bean) {
+	public <T> BasicBeanStore2 addSupplier(Class<T> beanType, Supplier<T> bean) {
 		return addSupplier(beanType, bean, null);
 	}
 
@@ -331,7 +330,7 @@ public class BasicBeanStore {
 	 * @param name The bean name if this is a named bean.  Can be <jk>null</jk>.
 	 * @return This object.
 	 */
-	public <T> BasicBeanStore addSupplier(Class<T> beanType, Supplier<T> bean, String name) {
+	public <T> BasicBeanStore2 addSupplier(Class<T> beanType, Supplier<T> bean, String name) {
 		assertCanWrite();
 		var e = createEntry(beanType, bean, name);
 		try (var x = lock.write()) {
@@ -350,7 +349,7 @@ public class BasicBeanStore {
 	 *
 	 * @return This object.
 	 */
-	public BasicBeanStore clear() {
+	public BasicBeanStore2 clear() {
 		assertCanWrite();
 		try (var x = lock.write()) {
 			unnamedEntries.clear();
@@ -507,7 +506,7 @@ public class BasicBeanStore {
 		return filteredBeanPropertyMap()
 			.a("entries", entries.stream().map(Entry::properties).collect(toList()))
 			.a("identity", id(this))
-			.a("parent", parent.map(BasicBeanStore::properties).orElse(null))
+			.a("parent", parent.map(BasicBeanStore2::properties).orElse(null))
 			.ai(readOnly, "readOnly", readOnly)
 			.ai(threadSafe, "threadSafe", threadSafe);
 		// @formatter:on
@@ -520,7 +519,7 @@ public class BasicBeanStore {
 
 	private void assertCanWrite() {
 		if (readOnly)
-			throw new IllegalStateException("Method cannot be used because BasicBeanStore is read-only.");
+			throw new IllegalStateException("Method cannot be used because BasicBeanStore2 is read-only.");
 	}
 
 	/**
@@ -540,7 +539,7 @@ public class BasicBeanStore {
 	}
 
 	/**
-	 * Represents a bean in a {@link BasicBeanStore}.
+	 * Represents a bean in a {@link BasicBeanStore2}.
 	 *
 	 * <p>
 	 * A bean entry consists of the following:
@@ -633,12 +632,12 @@ public class BasicBeanStore {
 		 *
 		 * @return The properties in this object as a simple map.
 		 */
-		protected JsonMap properties() {
+		protected FluentMap<String,Object> properties() {
 			// @formatter:off
-			return filteredMap()
-				.append("type", cns(getType()))
-				.append("bean", id(get()))
-				.append("name", getName());
+			return filteredBeanPropertyMap()
+				.a("type", cns(getType()))
+				.a("bean", id(get()))
+				.a("name", getName());
 			// @formatter:on
 		}
 	}
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanStore.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanStore.java
new file mode 100644
index 0000000000..d53d7814e1
--- /dev/null
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanStore.java
@@ -0,0 +1,138 @@
+/*
+ * 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.juneau.commons.inject;
+
+import java.util.*;
+import java.util.function.Supplier;
+
+/**
+ * Spring-bean-like interface for looking up beans by type and name.
+ *
+ * <p>
+ * This interface provides a minimal contract for bean lookup operations, similar to Spring's
+ * {@link org.springframework.beans.factory.BeanFactory BeanFactory} interface.
+ *
+ * <p>
+ * Implementations of this interface can be backed by various sources:
+ * <ul>
+ * 	<li>Spring's {@link org.springframework.context.ApplicationContext ApplicationContext}
+ * 	<li>Custom in-memory stores
+ * 	<li>Other dependency injection frameworks
+ * </ul>
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * 	BeanStore <jv>beanStore</jv> = ...;
+ *
+ * 	<jc>// Get bean by type</jc>
+ * 	Optional&lt;MyService&gt; <jv>service</jv> = <jv>beanStore</jv>.getBean(MyService.<jk>class</jk>);
+ *
+ * 	<jc>// Get bean by name</jc>
+ * 	Optional&lt;Object&gt; <jv>bean</jv> = <jv>beanStore</jv>.getBean(<js>"myBean"</js>);
+ *
+ * 	<jc>// Get bean by type and name</jc>
+ * 	Optional&lt;MyService&gt; <jv>namedService</jv> = <jv>beanStore</jv>.getBean(MyService.<jk>class</jk>, <js>"primary"</js>);
+ *
+ * 	<jc>// Get all beans of a type</jc>
+ * 	Map&lt;String, MyService&gt; <jv>allServices</jv> = <jv>beanStore</jv>.getBeansOfType(MyService.<jk>class</jk>);
+ * </p>
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * 	<li class='link'><a class="doclink" href="https://docs.spring.io/spring-framework/reference/core/beans.html">Spring Framework - The IoC Container</a>
+ * </ul>
+ */
+public interface BeanStore {
+
+	/**
+	 * Returns a bean of the specified type.
+	 *
+	 * <p>
+	 * If multiple beans of the specified type exist, the behavior is implementation-dependent.
+	 * Typically, implementations will return the primary bean or throw an exception.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @return The bean, or {@link Optional#empty()} if no bean of the specified type exists.
+	 */
+	<T> Optional<T> getBean(Class<T> beanType);
+
+	/**
+	 * Returns a bean of the specified type and name.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @param name The bean name.  Can be <jk>null</jk>.
+	 * @return The bean, or {@link Optional#empty()} if no bean of the specified type and name exists.
+	 */
+	<T> Optional<T> getBean(Class<T> beanType, String name);
+
+	/**
+	 * Returns all beans of the specified type, keyed by bean name.
+	 *
+	 * <p>
+	 * The map keys are the bean names, and the values are the bean instances.
+	 * If no beans of the specified type exist, returns an empty map.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @return A map of bean names to bean instances.  Never <jk>null</jk>.
+	 */
+	<T> Map<String, T> getBeansOfType(Class<T> beanType);
+
+	/**
+	 * Returns <jk>true</jk> if this store contains at least one bean of the specified type.
+	 *
+	 * @param beanType The bean type.
+	 * @return <jk>true</jk> if this store contains at least one bean of the specified type.
+	 */
+	boolean hasBean(Class<?> beanType);
+
+	/**
+	 * Returns <jk>true</jk> if this store contains a bean of the specified type and name.
+	 *
+	 * @param beanType The bean type.
+	 * @param name The bean name.  Can be <jk>null</jk>.
+	 * @return <jk>true</jk> if this store contains a bean of the specified type and name.
+	 */
+	boolean hasBean(Class<?> beanType, String name);
+
+	/**
+	 * Returns the supplier for an unnamed bean of the specified type.
+	 *
+	 * <p>
+	 * If no supplier is found in this store, searches the parent store recursively.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @return The supplier, or {@link Optional#empty()} if no supplier of the specified type exists.
+	 */
+	<T> Optional<Supplier<T>> getBeanSupplier(Class<T> beanType);
+
+	/**
+	 * Returns the supplier for a named bean of the specified type.
+	 *
+	 * <p>
+	 * If no supplier with the specified name is found in this store, searches the parent store recursively.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @param name The bean name.  Can be <jk>null</jk>.
+	 * @return The supplier, or {@link Optional#empty()} if no supplier of the specified type and name exists.
+	 */
+	<T> Optional<Supplier<T>> getBeanSupplier(Class<T> beanType, String name);
+}
+
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/WritableBeanStore.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/WritableBeanStore.java
new file mode 100644
index 0000000000..a548948330
--- /dev/null
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/WritableBeanStore.java
@@ -0,0 +1,113 @@
+/*
+ * 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.juneau.commons.inject;
+
+import java.util.function.*;
+
+/**
+ * Extends {@link BeanStore} with methods for adding beans.
+ *
+ * <p>
+ * This interface provides write operations for bean stores, allowing beans to be added
+ * either as direct instances or as suppliers for lazy initialization.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * 	WritableBeanStore <jv>beanStore</jv> = ...;
+ *
+ * 	<jc>// Add unnamed bean</jc>
+ * 	<jv>beanStore</jv>.addBean(MyService.<jk>class</jk>, <jk>new</jk> MyService());
+ *
+ * 	<jc>// Add named bean</jc>
+ * 	<jv>beanStore</jv>.addBean(MyService.<jk>class</jk>, <jk>new</jk> MyService(), <js>"primary"</js>);
+ *
+ * 	<jc>// Add bean supplier for lazy initialization</jc>
+ * 	<jv>beanStore</jv>.addSupplier(MyService.<jk>class</jk>, () -&gt; <jk>new</jk> MyService());
+ *
+ * 	<jc>// Add named bean supplier</jc>
+ * 	<jv>beanStore</jv>.addSupplier(MyService.<jk>class</jk>, () -&gt; <jk>new</jk> MyService(), <js>"secondary"</js>);
+ *
+ * 	<jc>// Clear all beans</jc>
+ * 	<jv>beanStore</jv>.clear();
+ * </p>
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * 	<li class='jc'>{@link BeanStore} - Read-only bean lookup interface
+ * </ul>
+ */
+public interface WritableBeanStore extends BeanStore {
+
+	/**
+	 * Adds an unnamed bean of the specified type to this store.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @param bean The bean instance.  Can be <jk>null</jk>.
+	 * @return This object for method chaining.
+	 */
+	<T> WritableBeanStore addBean(Class<T> beanType, T bean);
+
+	/**
+	 * Adds a named bean of the specified type to this store.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @param bean The bean instance.  Can be <jk>null</jk>.
+	 * @param name The bean name.  Can be <jk>null</jk> for unnamed beans.
+	 * @return This object for method chaining.
+	 */
+	<T> WritableBeanStore addBean(Class<T> beanType, T bean, String name);
+
+	/**
+	 * Adds a supplier for an unnamed bean of the specified type to this store.
+	 *
+	 * <p>
+	 * The supplier will be invoked lazily when the bean is first requested.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @param supplier The bean supplier.  Must not be <jk>null</jk>.
+	 * @return This object for method chaining.
+	 */
+	<T> WritableBeanStore addSupplier(Class<T> beanType, Supplier<T> supplier);
+
+	/**
+	 * Adds a supplier for a named bean of the specified type to this store.
+	 *
+	 * <p>
+	 * The supplier will be invoked lazily when the bean is first requested.
+	 *
+	 * @param <T> The bean type.
+	 * @param beanType The bean type.
+	 * @param supplier The bean supplier.  Must not be <jk>null</jk>.
+	 * @param name The bean name.  Can be <jk>null</jk> for unnamed beans.
+	 * @return This object for method chaining.
+	 */
+	<T> WritableBeanStore addSupplier(Class<T> beanType, Supplier<T> supplier, String name);
+
+	/**
+	 * Removes all beans from this store.
+	 *
+	 * <p>
+	 * This operation only affects this store and does not affect any parent stores
+	 * that may be associated with this store.
+	 *
+	 * @return This object for method chaining.
+	 */
+	WritableBeanStore clear();
+}
+
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ConstructorInfo.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ConstructorInfo.java
index 6c9ededc5c..8cc1298b74 100644
--- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ConstructorInfo.java
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ConstructorInfo.java
@@ -215,8 +215,11 @@ public class ConstructorInfo extends ExecutableInfo implements Comparable<Constr
 	/**
 	 * Shortcut for calling the new-instance method on the underlying constructor.
 	 *
+	 * <p>
+	 * If the number of formal parameters required by the underlying constructor is 0, the supplied <c>args</c> array may be of length 0 or <jk>null</jk>.
+	 *
 	 * @param <T> The constructor class type.
-	 * @param args the arguments used for the method call.
+	 * @param args The arguments used for the constructor call.  Can be <jk>null</jk> or empty for constructors with no parameters.
 	 * @return The object returned from the constructor.
 	 * @throws ExecutableException Exception occurred on invoked constructor/method/field.
 	 */
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/FieldInfo.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/FieldInfo.java
index f30ce6889f..4e3e782624 100644
--- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/FieldInfo.java
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/FieldInfo.java
@@ -170,8 +170,11 @@ public class FieldInfo extends AccessibleInfo implements Comparable<FieldInfo>,
 	/**
 	 * Returns the field value on the specified object.
 	 *
-	 * @param o The object containing the field.
+	 * <p>
+	 * If the underlying field is static, then the specified <c>o</c> argument is ignored. It may be <jk>null</jk>.
+	 *
 	 * @param <T> The object type to retrieve.
+	 * @param o The object containing the field.  Can be <jk>null</jk> for static fields.
 	 * @return The field value.
 	 * @throws BeanRuntimeException Field was not accessible or field does not belong to object.
 	 */
@@ -420,7 +423,10 @@ public class FieldInfo extends AccessibleInfo implements Comparable<FieldInfo>,
 	/**
 	 * Sets the field value on the specified object.
 	 *
-	 * @param o The object containing the field.
+	 * <p>
+	 * If the underlying field is static, then the specified <c>o</c> argument is ignored. It may be <jk>null</jk>.
+	 *
+	 * @param o The object containing the field.  Can be <jk>null</jk> for static fields.
 	 * @param value The new field value.
 	 * @throws BeanRuntimeException Field was not accessible or field does not belong to object.
 	 */
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/MethodInfo.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/MethodInfo.java
index 38d2c9e954..455715cf06 100644
--- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/MethodInfo.java
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/MethodInfo.java
@@ -581,9 +581,15 @@ public class MethodInfo extends ExecutableInfo implements Comparable<MethodInfo>
 	/**
 	 * Shortcut for calling the invoke method on the underlying method.
 	 *
+	 * <p>
+	 * If the underlying method is static, then the specified <c>obj</c> argument is ignored. It may be <jk>null</jk>.
+	 *
+	 * <p>
+	 * If the number of formal parameters required by the underlying method is 0, the supplied <c>args</c> array may be of length 0 or <jk>null</jk>.
+	 *
 	 * @param <T> The method return type.
-	 * @param obj the object the underlying method is invoked from.
-	 * @param args the arguments used for the method call
+	 * @param obj The object the underlying method is invoked from.  Can be <jk>null</jk> for static methods.
+	 * @param args The arguments used for the method call.  Can be <jk>null</jk> or empty for methods with no parameters.
 	 * @return The object returned from the method.
 	 * @throws ExecutableException Exception occurred on invoked constructor/method/field.
 	 */
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/BeanUtils.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/BeanUtils.java
new file mode 100644
index 0000000000..f826a8497e
--- /dev/null
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/BeanUtils.java
@@ -0,0 +1,110 @@
+/*
+ * 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.juneau.commons.utils;
+
+import static java.util.stream.Collectors.*;
+import static org.apache.juneau.commons.utils.CollectionUtils.*;
+import static org.apache.juneau.commons.utils.Utils.*;
+
+import java.util.*;
+
+import org.apache.juneau.commons.inject.*;
+import org.apache.juneau.commons.reflect.*;
+
+public class BeanUtils {
+
+	/**
+	 * Given an executable, returns a list of types that are missing from this factory.
+	 *
+	 * @param executable The constructor or method to get the params for.
+	 * @param outer The outer object to use when instantiating inner classes.  Can be <jk>null</jk>.
+	 * @return A comma-delimited list of types that are missing from this factory, or <jk>null</jk> if none are missing.
+	 */
+	public String getMissingParams(ExecutableInfo executable, BeanStore beanStore, Object outer) {
+		var params = executable.getParameters();
+		List<String> l = list();
+		loop: for (int i = 0; i < params.size(); i++) {
+			var pi = params.get(i);
+			var pt = pi.getParameterType();
+			if (i == 0 && nn(outer) && pt.isInstance(outer))
+				continue loop;
+			if (pt.is(Optional.class))
+				continue loop;
+			var beanName = pi.getResolvedQualifier();  // Use @Named for bean injection
+			var ptc = pt.inner();
+			if (beanName == null && ! beanStore.hasBean(ptc))
+				l.add(pt.getNameSimple());
+			if (nn(beanName) && ! beanStore.hasBean(ptc, beanName))
+				l.add(pt.getNameSimple() + '@' + beanName);
+		}
+		return l.isEmpty() ? null : l.stream().sorted().collect(joining(","));
+	}
+
+	/**
+	 * Returns the corresponding beans in this factory for the specified param types.
+	 *
+	 * @param executable The constructor or method to get the params for.
+	 * @param outer The outer object to use when instantiating inner classes.  Can be <jk>null</jk>.
+	 * @return The corresponding beans in this factory for the specified param types.
+	 */
+	public Object[] getParams(ExecutableInfo executable, BeanStore beanStore, Object outer) {
+		var o = new Object[executable.getParameterCount()];
+		for (var i = 0; i < executable.getParameterCount(); i++) {
+			var pi = executable.getParameter(i);
+			var pt = pi.getParameterType();
+			if (i == 0 && nn(outer) && pt.isInstance(outer)) {
+				o[i] = outer;
+			} else {
+				var beanQualifier = pi.getResolvedQualifier();
+				var ptc = pt.unwrap(Optional.class).inner();
+				var o2 = beanQualifier == null ? beanStore.getBean(ptc) : beanStore.getBean(ptc, beanQualifier);
+				o[i] = pt.is(Optional.class) ? o2 : o2.orElse(null);
+			}
+		}
+		return o;
+	}
+
+	public <T> T invoke(ExecutableInfo executable, BeanStore beanStore, Object bean) {
+		var params = getParams(executable, beanStore, bean);
+		if (executable instanceof ConstructorInfo ci)
+			return ci.newInstance(params);
+		return MethodInfo.class.cast(executable).invoke(bean, params);
+	}
+
+	/**
+	 * Given the list of param types, returns <jk>true</jk> if this factory has all the parameters for the specified executable.
+	 *
+	 * @param executable The constructor or method to get the params for.
+	 * @param outer The outer object to use when instantiating inner classes.  Can be <jk>null</jk>.
+	 * @return A comma-delimited list of types that are missing from this factory.
+	 */
+	public boolean hasAllParams(ExecutableInfo executable, BeanStore beanStore, Object outer) {
+		loop: for (int i = 0; i < executable.getParameterCount(); i++) {
+			var pi = executable.getParameter(i);
+			var pt = pi.getParameterType();
+			if (i == 0 && nn(outer) && pt.isInstance(outer))
+				continue loop;
+			if (pt.is(Optional.class))
+				continue loop;
+			var beanQualifier = pi.getResolvedQualifier();
+			var ptc = pt.inner();
+			if ((beanQualifier == null && ! beanStore.hasBean(ptc)) || (nn(beanQualifier) && ! beanStore.hasBean(ptc, beanQualifier)))
+				return false;
+		}
+		return true;
+	}
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanBuilder.java
index 52579bc2b5..2ce9a514cf 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanBuilder.java
@@ -20,6 +20,7 @@ import static org.apache.juneau.commons.utils.Utils.*;
 
 import java.util.*;
 
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -32,7 +33,7 @@ public class BeanBuilder<T> {
 
 	private Class<? extends T> type, defaultType;
 	private T impl;
-	private final BasicBeanStore beanStore;
+	private final BasicBeanStore2 beanStore;
 
 	/**
 	 * Copy constructor.
@@ -51,7 +52,7 @@ public class BeanBuilder<T> {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @param defaultType The default bean type that this builder creates.
 	 */
-	protected BeanBuilder(Class<? extends T> defaultType, BasicBeanStore beanStore) {
+	protected BeanBuilder(Class<? extends T> defaultType, BasicBeanStore2 beanStore) {
 		this.defaultType = type = defaultType;
 		this.beanStore = beanStore;
 	}
@@ -61,7 +62,7 @@ public class BeanBuilder<T> {
 	 *
 	 * @return The bean store passed in through the constructor.
 	 */
-	public BasicBeanStore beanStore() {
+	public BasicBeanStore2 beanStore() {
 		return beanStore;
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Name.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Name.java
index 615ba45575..41bfeaa4aa 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Name.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Name.java
@@ -62,13 +62,13 @@ import java.lang.annotation.*;
  *
  * 	<jc>// @Named - for bean injection</jc>
  * 	<jk>public</jk> MyService(<ja>@Named</ja>(<js>"primaryDb"</js>) Database <jv>db</jv>) {
- * 		<jc>// Injects the bean named "primaryDb" from BasicBeanStore</jc>
+ * 		<jc>// Injects the bean named "primaryDb" from BasicBeanStore2</jc>
  * 	}
  * </p>
  *
  * <h5 class='section'>See Also:</h5><ul>
  * 	<li class='ja'>{@link Named}
- * 	<li class='jc'>{@link org.apache.juneau.cp.BasicBeanStore}
+ * 	<li class='jc'>{@link org.apache.juneau.commons.inject.BasicBeanStore2}
  * </ul>
  */
 @Documented
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Named.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Named.java
index f57c29d29d..90e88b124c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Named.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Named.java
@@ -28,7 +28,7 @@ import java.lang.annotation.*;
  * <h5 class='section'>Example:</h5>
  * <p class='bjava'>
  * 	<jk>public</jk> MyClass(<ja>@Named</ja>(<js>"myBean"</js>) MyBean <jv>bean</jv>) {
- * 		<jc>// Constructor will receive the bean named "myBean" from the BasicBeanStore</jc>
+ * 		<jc>// Constructor will receive the bean named "myBean" from the BasicBeanStore2</jc>
  * 	}
  * </p>
  *
@@ -45,7 +45,7 @@ import java.lang.annotation.*;
  * <p class='bjava'>
  * 	<jc>// @Named - for bean injection</jc>
  * 	<jk>public</jk> MyService(<ja>@Named</ja>(<js>"primaryDb"</js>) Database <jv>db</jv>) {
- * 		<jc>// Injects the bean named "primaryDb" from BasicBeanStore</jc>
+ * 		<jc>// Injects the bean named "primaryDb" from BasicBeanStore2</jc>
  * 	}
  *
  * 	<jc>// @Name - for parameter naming (when bytecode names unavailable)</jc>
@@ -57,7 +57,7 @@ import java.lang.annotation.*;
  *
  * <h5 class='section'>See Also:</h5><ul>
  * 	<li class='ja'>{@link Name}
- * 	<li class='jc'>{@link org.apache.juneau.cp.BasicBeanStore}
+ * 	<li class='jc'>{@link org.apache.juneau.commons.inject.BasicBeanStore2}
  * </ul>
  */
 @Documented
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
index 8450297ab3..df6c2fea8b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
@@ -24,6 +24,7 @@ import java.util.*;
 import java.util.function.*;
 
 import org.apache.juneau.annotation.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 
 /**
@@ -35,10 +36,10 @@ import org.apache.juneau.commons.reflect.*;
  * <p>
  * This class is instantiated through the following methods:
  * <ul class='javatree'>
- * 	<li class='jc'>{@link BasicBeanStore}
+ * 	<li class='jc'>{@link BasicBeanStore2}
  * 		<ul class='javatreec'>
- * 			<li class='jc'>{@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Class,BasicBeanStore) BeanCreateMethodFinder(Class,Class,BasicBeanStore)}
- * 			<li class='jc'>{@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Object,BasicBeanStore) BeanCreateMethodFinder(Class,Object,BasicBeanStore)}
+ * 			<li class='jc'>{@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Class,BasicBeanStore2) BeanCreateMethodFinder(Class,Class,BasicBeanStore2)}
+ * 			<li class='jc'>{@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Object,BasicBeanStore2) BeanCreateMethodFinder(Class,Object,BasicBeanStore2)}
  * 		</ul>
  * 	</li>
  * </ul>
@@ -62,7 +63,7 @@ import org.apache.juneau.commons.reflect.*;
  * 	B <mv>b</mv> = <jk>new</jk> B();
  *
  *  <jc>// Create a bean store with some mapped beans.</jc>
- * 	BasicBeanStore <mv>beanStore</mv> = BasicBeanStore.<jsm>create</jsm>().addBean(C.<jk>class</jk>, <jk>new</jk> C());
+ * 	BasicBeanStore2 <mv>beanStore</mv> = BasicBeanStore2.<jsm>create</jsm>().addBean(C.<jk>class</jk>, <jk>new</jk> C());
  *
  * 	<jc>// Instantiate the bean using the creator method.</jc>
  * 	A <mv>a</mv> = <mv>beanStore</mv>
@@ -74,7 +75,7 @@ import org.apache.juneau.commons.reflect.*;
  * </p>
  *
  * <h5 class='section'>See Also:</h5><ul>
- * 	<li class='jc'>{@link BasicBeanStore}
+ * 	<li class='jc'>{@link BasicBeanStore2}
  * </ul>
  *
  * @param <T> The bean type being created.
@@ -84,7 +85,7 @@ public class BeanCreateMethodFinder<T> {
 	private Class<T> beanType;
 	private final Class<?> resourceClass;
 	private final Object resource;
-	private final BasicBeanStore beanStore;
+	private final BasicBeanStore2 beanStore;
 
 	private MethodInfo method;
 	private Object[] args;
@@ -96,11 +97,11 @@ public class BeanCreateMethodFinder<T> {
 	 * @param resourceClass The resource class to search for creation methods.
 	 * @param beanStore The bean store to use for parameter resolution.
 	 */
-	public BeanCreateMethodFinder(Class<T> beanType, Class<?> resourceClass, BasicBeanStore beanStore) {
+	public BeanCreateMethodFinder(Class<T> beanType, Class<?> resourceClass, BasicBeanStore2 beanStore) {
 		this.beanType = assertArgNotNull("beanType", beanType);
 		this.resource = null;
 		this.resourceClass = assertArgNotNull("resourceClass", resourceClass);
-		this.beanStore = BasicBeanStore.of(beanStore);
+		this.beanStore = BasicBeanStore2.of(beanStore);
 	}
 
 	/**
@@ -110,11 +111,11 @@ public class BeanCreateMethodFinder<T> {
 	 * @param resource The resource object to search for creation methods.
 	 * @param beanStore The bean store to use for parameter resolution.
 	 */
-	public BeanCreateMethodFinder(Class<T> beanType, Object resource, BasicBeanStore beanStore) {
+	public BeanCreateMethodFinder(Class<T> beanType, Object resource, BasicBeanStore2 beanStore) {
 		this.beanType = assertArgNotNull("beanType", beanType);
 		this.resource = assertArgNotNull("resource", resource);
 		this.resourceClass = resource.getClass();
-		this.beanStore = BasicBeanStore.of(beanStore);
+		this.beanStore = BasicBeanStore2.of(beanStore);
 	}
 
 	/**
@@ -149,7 +150,7 @@ public class BeanCreateMethodFinder<T> {
 	 * This method can be called multiple times with different method names or required parameters until a match is found.
 	 * <br>Once a method is found, subsequent calls to this method will be no-ops.
 	 *
-	 * See {@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Object,BasicBeanStore)} for usage.
+	 * See {@link BeanCreateMethodFinder#BeanCreateMethodFinder(Class,Object,BasicBeanStore2)} for usage.
 	 *
 	 * @param filter The predicate to apply.
 	 * @return This object.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
index 411e0573ef..47aedc3091 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
@@ -25,6 +25,8 @@ import java.util.*;
 import java.util.function.*;
 
 import org.apache.juneau.annotation.*;
+//import org.apache.juneau.annotation.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.lang.*;
 import org.apache.juneau.commons.reflect.*;
 
@@ -32,14 +34,14 @@ import org.apache.juneau.commons.reflect.*;
  * Utility class for creating beans through constructors, creator methods, and builders.
  *
  * <p>
- * Uses a {@link BasicBeanStore} to find available ways to construct beans via injection of beans from the store.
+ * Uses a {@link BasicBeanStore2} to find available ways to construct beans via injection of beans from the store.
  *
  * <p>
  * This class is instantiated through the following method:
  * <ul class='javatree'>
- * 	<li class='jc'>{@link BasicBeanStore}
+ * 	<li class='jc'>{@link BasicBeanStore2}
  * 		<ul class='javatreec'>
- * 			<li class='jc'>{@link BeanCreator#of(Class,BasicBeanStore)}
+ * 			<li class='jc'>{@link BeanCreator#of(Class,BasicBeanStore2)}
  * 		</ul>
  * 	</li>
  * </ul>
@@ -47,7 +49,7 @@ import org.apache.juneau.commons.reflect.*;
  * <h5 class='section'>Example:</h5>
  * <p class='bjava'>
  * 	<jc>// Construct and throw a RuntimeException using a bean store.</jc>
- * 	<jk>throw</jk> BasicBeanStore
+ * 	<jk>throw</jk> BasicBeanStore2
  * 		.<jsm>create</jsm>()
  * 		.build()
  * 		.addBean(Throwable.<jk>class</jk>, <jv>cause</jv>)
@@ -112,7 +114,7 @@ import org.apache.juneau.commons.reflect.*;
  * </ul>
  *
  * <h5 class='section'>See Also:</h5><ul>
- * 	<li class='jc'>{@link BasicBeanStore}
+ * 	<li class='jc'>{@link BasicBeanStore2}
  * </ul>
  *
  * @param <T> The bean type being created.
@@ -139,14 +141,14 @@ public class BeanCreator<T> {
 	}
 
 	/**
-	 * Shortcut for calling <c>BeanCreator.of(beanType, BasicBeanStore.INSTANCE)</c>.
+	 * Shortcut for calling <c>BeanCreator.of(beanType, BasicBeanStore2.INSTANCE)</c>.
 	 *
 	 * @param <T> The bean type to create.
 	 * @param beanType The bean type to create.
 	 * @return A new creator.
 	 */
 	public static <T> BeanCreator<T> of(Class<T> beanType) {
-		return new BeanCreator<>(beanType, BasicBeanStore.INSTANCE);
+		return new BeanCreator<>(beanType, BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -157,11 +159,11 @@ public class BeanCreator<T> {
 	 * @param beanStore The bean store to use for parameter resolution.
 	 * @return A new creator.
 	 */
-	public static <T> BeanCreator<T> of(Class<T> beanType, BasicBeanStore beanStore) {
+	public static <T> BeanCreator<T> of(Class<T> beanType, BasicBeanStore2 beanStore) {
 		return new BeanCreator<>(beanType, beanStore);
 	}
 
-	private final BasicBeanStore store;
+	private final BasicBeanStore2 store;
 	private ClassInfo type;
 	private Object builder;
 	private T impl;
@@ -175,9 +177,9 @@ public class BeanCreator<T> {
 	 * @param type The bean type being created.
 	 * @param store The bean store creating this creator.
 	 */
-	protected BeanCreator(Class<T> type, BasicBeanStore store) {
+	protected BeanCreator(Class<T> type, BasicBeanStore2 store) {
 		this.type = info(type);
-		this.store = BasicBeanStore.of(store);
+		this.store = BasicBeanStore2.of(store);
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
index 2a5d0c6e17..9220a5e336 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/FileFinder.java
@@ -26,6 +26,7 @@ import java.util.*;
 import java.util.regex.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.io.*;
 
 /**
@@ -102,7 +103,7 @@ public interface FileFinder {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(BasicFileFinder.class, beanStore);
 			roots = set();
 			cachingLimit = -1;
@@ -214,7 +215,7 @@ public interface FileFinder {
 	 * @return A new builder for this object.
 	 */
 	static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -223,7 +224,7 @@ public interface FileFinder {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	static Builder create(BasicBeanStore beanStore) {
+	static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/Messages.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/Messages.java
index 694652e98a..60e18191df 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/Messages.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/Messages.java
@@ -30,6 +30,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.commons.collections.*;
 import org.apache.juneau.commons.function.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.utils.*;
 import org.apache.juneau.marshaller.*;
 import org.apache.juneau.parser.ParseException;
@@ -138,7 +139,7 @@ public class Messages extends ResourceBundle {
 		 * @param forClass The base class.
 		 */
 		protected Builder(Class<?> forClass) {
-			super(Messages.class, BasicBeanStore.INSTANCE);
+			super(Messages.class, BasicBeanStore2.INSTANCE);
 			this.forClass = forClass;
 			this.name = cns(forClass);
 			locations = list();
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/encoders/EncoderSet.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/encoders/EncoderSet.java
index 2968e028c2..70085e9d79 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/encoders/EncoderSet.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/encoders/EncoderSet.java
@@ -25,6 +25,7 @@ import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.cp.*;
 
@@ -97,7 +98,7 @@ public class EncoderSet {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(EncoderSet.class, beanStore);
 			entries = list();
 		}
@@ -266,7 +267,7 @@ public class EncoderSet {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -275,11 +276,11 @@ public class EncoderSet {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
-	private static Encoder instantiate(BasicBeanStore bs, Object o) {
+	private static Encoder instantiate(BasicBeanStore2 bs, Object o) {
 		if (o instanceof Encoder o2)
 			return o2;
 		try {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
index 5e24952525..a923f7dd53 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
@@ -28,6 +28,7 @@ import java.util.function.*;
 import java.util.stream.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -99,7 +100,7 @@ public class ParserSet {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(ParserSet.class, beanStore);
 			this.entries = list();
 		}
@@ -125,7 +126,7 @@ public class ParserSet {
 		 * @param copyFrom The parser group that we're copying settings and parsers from.
 		 */
 		protected Builder(ParserSet copyFrom) {
-			super(copyFrom.getClass(), BasicBeanStore.INSTANCE);
+			super(copyFrom.getClass(), BasicBeanStore2.INSTANCE);
 			this.entries = list((Object[])copyFrom.entries);
 		}
 
@@ -444,7 +445,7 @@ public class ParserSet {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -453,7 +454,7 @@ public class ParserSet {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
index e138b7d3ed..b5b34f1847 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
@@ -28,6 +28,7 @@ import java.util.function.*;
 import java.util.stream.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -98,7 +99,7 @@ public class SerializerSet {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(SerializerSet.class, beanStore);
 			this.entries = list();
 		}
@@ -124,7 +125,7 @@ public class SerializerSet {
 		 * @param copyFrom The serializer group that we're copying settings and serializers from.
 		 */
 		protected Builder(SerializerSet copyFrom) {
-			super(copyFrom.getClass(), BasicBeanStore.INSTANCE);
+			super(copyFrom.getClass(), BasicBeanStore2.INSTANCE);
 			this.entries = list((Object[])copyFrom.entries);
 		}
 
@@ -442,7 +443,7 @@ public class SerializerSet {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -451,7 +452,7 @@ public class SerializerSet {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolver.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolver.java
index df9e3d0356..3a8856bbf7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolver.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolver.java
@@ -23,6 +23,7 @@ import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.svl.vars.*;
 
@@ -79,7 +80,7 @@ public class VarResolver {
 		 * Constructor.
 		 */
 		protected Builder() {
-			super(VarResolver.class, BasicBeanStore.create().build());
+			super(VarResolver.class, BasicBeanStore2.create().build());
 			vars = VarList.create();
 		}
 
@@ -226,7 +227,7 @@ public class VarResolver {
 		return new Builder();
 	}
 
-	private static Var toVar(BasicBeanStore bs, Object o) {
+	private static Var toVar(BasicBeanStore2 bs, Object o) {
 		if (o instanceof Class o2)
 			return BeanCreator.of(Var.class, bs).type(o2).run();
 		return (Var)o;
@@ -235,7 +236,7 @@ public class VarResolver {
 	final Var[] vars;
 	private final Map<String,Var> varMap;
 
-	final BasicBeanStore beanStore;
+	final BasicBeanStore2 beanStore;
 
 	/**
 	 * Constructor.
@@ -250,7 +251,7 @@ public class VarResolver {
 			m.put(v.getName(), v);
 
 		this.varMap = u(m);
-		this.beanStore = BasicBeanStore.of(builder.beanStore());
+		this.beanStore = BasicBeanStore2.of(builder.beanStore());
 	}
 
 	/**
@@ -290,7 +291,7 @@ public class VarResolver {
 	 * @param beanStore The bean store to associate with this session.
 	 * @return A new resolver session.
 	 */
-	public VarResolverSession createSession(BasicBeanStore beanStore) {
+	public VarResolverSession createSession(BasicBeanStore2 beanStore) {
 		return new VarResolverSession(this, beanStore);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolverSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolverSession.java
index 83cd450a7e..b0cf371561 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolverSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolverSession.java
@@ -28,6 +28,7 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.commons.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.lang.*;
 import org.apache.juneau.cp.*;
 
@@ -42,7 +43,7 @@ import org.apache.juneau.cp.*;
  *
  * <p>
  * Instances of this class are created through the {@link VarResolver#createSession()} and
- * {@link VarResolver#createSession(BasicBeanStore)} methods.
+ * {@link VarResolver#createSession(BasicBeanStore2)} methods.
  *
  * <h5 class='section'>Notes:</h5><ul>
  * 	<li class='warn'>This class is not guaranteed to be thread safe.
@@ -124,7 +125,7 @@ public class VarResolverSession {
 
 	private final VarResolver context;
 
-	private final BasicBeanStore beanStore;
+	private final BasicBeanStore2 beanStore;
 
 	/**
 	 * Constructor.
@@ -135,9 +136,9 @@ public class VarResolverSession {
 	 * @param beanStore The bean store to use for resolving beans needed by vars.
 	 *
 	 */
-	public VarResolverSession(VarResolver context, BasicBeanStore beanStore) {
+	public VarResolverSession(VarResolver context, BasicBeanStore2 beanStore) {
 		this.context = context;
-		this.beanStore = BasicBeanStore.of(beanStore);
+		this.beanStore = BasicBeanStore2.of(beanStore);
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index adcaa74397..3c3ec9ebfb 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -71,6 +71,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.commons.collections.*;
 import org.apache.juneau.commons.collections.FluentMap;
 import org.apache.juneau.commons.function.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.html.*;
@@ -1057,7 +1058,7 @@ public class RestClient extends BeanContextable implements HttpClient, Closeable
 	public static class Builder extends BeanContextable.Builder {
 
 		private BeanCreator<RestCallHandler> callHandler;
-		private BasicBeanStore beanStore = BasicBeanStore.create().build();
+		private BasicBeanStore2 beanStore = BasicBeanStore2.create().build();
 		private BiPredicate<RestRequest,RestResponse> logRequestsPredicate;
 		private boolean detectLeaks;
 		private boolean executorServiceShutdownOnClose;
@@ -6178,7 +6179,7 @@ public class RestClient extends BeanContextable implements HttpClient, Closeable
 	protected final SerializerSet serializers;
 	protected final UrlEncodingSerializer urlEncodingSerializer;  // Used for form posts only.
 	Predicate<Integer> errorCodes;
-	private final BasicBeanStore beanStore;
+	private final BasicBeanStore2 beanStore;
 	private final HttpClientConnectionManager connectionManager;
 	private final Logger logger;
 	private final Map<Class<?>,HttpPartParser> partParsers = new ConcurrentHashMap<>();
diff --git a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanStore.java b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanStore.java
index 28a40ab395..b71a001f98 100644
--- a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanStore.java
+++ b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanStore.java
@@ -19,6 +19,8 @@ package org.apache.juneau.rest.springboot;
 import static org.apache.juneau.commons.utils.Utils.*;
 
 import java.util.*;
+
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.springframework.context.*;
 
@@ -29,7 +31,7 @@ import org.springframework.context.*;
  * 	<li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestServerSpringbootBasics">juneau-rest-server-springboot Basics</a>
  * </ul>
  */
-public class SpringBeanStore extends BasicBeanStore {
+public class SpringBeanStore extends BasicBeanStore2 {
 
 	private final Optional<ApplicationContext> appContext;
 
@@ -40,12 +42,12 @@ public class SpringBeanStore extends BasicBeanStore {
 	 * @param parent The parent REST object bean store.  Can be <jk>null</jk>.
 	 * @param resource The REST object.  Can be <jk>null</jk>.
 	 */
-	public SpringBeanStore(Optional<ApplicationContext> appContext, Optional<BasicBeanStore> parent, Object resource) {
+	public SpringBeanStore(Optional<ApplicationContext> appContext, Optional<BasicBeanStore2> parent, Object resource) {
 		super(create().parent(parent.orElse(null)));
 		this.appContext = appContext;
 	}
 
-	@Override /* Overridden from BasicBeanStore */
+	@Override /* Overridden from BasicBeanStore2 */
 	public SpringBeanStore clear() {
 		super.clear();
 		return this;
diff --git a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringRestServlet.java b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringRestServlet.java
index e984c3fa6b..5d51798fd4 100644
--- a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringRestServlet.java
+++ b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringRestServlet.java
@@ -18,6 +18,7 @@ package org.apache.juneau.rest.springboot;
 
 import java.util.*;
 
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.servlet.*;
@@ -51,10 +52,10 @@ public abstract class SpringRestServlet extends RestServlet {
 	 * Hook into Spring bean injection framework.
 	 *
 	 * @param parent Optional parent resource.
-	 * @return A BasicBeanStore that retrieves beans from the Spring Boot app context.
+	 * @return A BasicBeanStore2 that retrieves beans from the Spring Boot app context.
 	 */
 	@RestInject
-	public BasicBeanStore createBeanStore(Optional<BasicBeanStore> parent) {
+	public BasicBeanStore2 createBeanStore(Optional<BasicBeanStore2> parent) {
 		return new SpringBeanStore(appContext, parent, this);
 	}
 }
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
index 8568a800ed..f162d79734 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
@@ -16,6 +16,7 @@
  */
 package org.apache.juneau.rest;
 
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -52,7 +53,7 @@ public class RestChild {
 	 * @param path The child resource path relative to the parent resource URI.
 	 * @param resource
 	 * 	The child resource.
-	 * 	<br>Can either be a Class (which will be instantiated using the registered {@link BasicBeanStore})
+	 * 	<br>Can either be a Class (which will be instantiated using the registered {@link BasicBeanStore2})
 	 * 	or an already-instantiated object.
 	 */
 	public RestChild(/*UrlPathPattern path, */ String path, Object resource) {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
index e2ae46a1bd..390a58d2a9 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChildren.java
@@ -22,6 +22,7 @@ import static org.apache.juneau.commons.utils.Utils.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.util.*;
@@ -48,7 +49,7 @@ public class RestChildren {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(RestChildren.class, beanStore);
 			list = list();
 		}
@@ -98,7 +99,7 @@ public class RestChildren {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index d4de60fd64..fff30ef1df 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -49,6 +49,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.bean.swagger.Swagger;
 import org.apache.juneau.commons.collections.*;
 import org.apache.juneau.commons.collections.FluentMap;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.lang.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.commons.utils.*;
@@ -134,8 +135,8 @@ public class RestContext extends Context {
 		// @formatter:off
 		private static final Set<Class<?>> DELAYED_INJECTION = set(
 			BeanContext.Builder.class,
-			BasicBeanStore.Builder.class,
-			BasicBeanStore.class,
+			BasicBeanStore2.Builder.class,
+			BasicBeanStore2.class,
 			CallLogger.Builder.class,
 			CallLogger.class,
 			Config.class,
@@ -223,8 +224,8 @@ public class RestContext extends Context {
 		private BeanCreator<DebugEnablement> debugEnablement;
 		private BeanCreator<StaticFiles> staticFiles;
 		private BeanCreator<SwaggerProvider> swaggerProvider;
-		private BasicBeanStore beanStore;
-		private BasicBeanStore rootBeanStore;
+		private BasicBeanStore2 beanStore;
+		private BasicBeanStore2 rootBeanStore;
 		private boolean disableContentParam = env("RestContext.disableContentParam", false);
 		private boolean initialized;
 		private boolean renderResponseStackTraces = env("RestContext.renderResponseStackTraces", false);
@@ -542,14 +543,14 @@ public class RestContext extends Context {
 		 * 	<li>Class annotation:  {@link Rest#beanStore() @Rest(beanStore)}
 		 * 	<li>{@link RestInject @RestInject}-annotated methods:
 		 * 		<p class='bjava'>
-		 * 	<ja>@RestInject</ja> <jk>public</jk> [<jk>static</jk>] BasicBeanStore myMethod(<i>&lt;args&gt;</i>) {...}
+		 * 	<ja>@RestInject</ja> <jk>public</jk> [<jk>static</jk>] BasicBeanStore2 myMethod(<i>&lt;args&gt;</i>) {...}
 		 * 		</p>
-		 * 		Args can be any injected bean including {@link org.apache.juneau.cp.BasicBeanStore.Builder}, the default builder.
+		 * 		Args can be any injected bean including {@link org.apache.juneau.commons.inject.BasicBeanStore2.Builder}, the default builder.
 		 * </ul>
 		 *
 		 * @return The bean store in this builder.
 		 */
-		public BasicBeanStore beanStore() {
+		public BasicBeanStore2 beanStore() {
 			return beanStore;
 		}
 
@@ -630,7 +631,7 @@ public class RestContext extends Context {
 		 * 	<jc>// Our customized logger.</jc>
 		 * 	<jk>public class</jk> MyLogger <jk>extends</jk> BasicCallLogger {
 		 *
-		 * 		<jk>public</jk> MyLogger(BasicBeanStore <jv>beanStore</jv>) {
+		 * 		<jk>public</jk> MyLogger(BasicBeanStore2 <jv>beanStore</jv>) {
 		 *			<jk>super</jk>(<jv>beanStore</jv>);
 		 *		}
 		 *
@@ -673,7 +674,7 @@ public class RestContext extends Context {
 		 * 	<li class='note'>
 		 * 		When defined as a class, the implementation must have one of the following constructor:
 		 * 		<ul>
-		 * 			<li><code><jk>public</jk> T(BasicBeanStore)</code>
+		 * 			<li><code><jk>public</jk> T(BasicBeanStore2)</code>
 		 * 		</ul>
 		 * 	<li class='note'>
 		 * 		Inner classes of the REST resource class are allowed.
@@ -833,7 +834,7 @@ public class RestContext extends Context {
 		 * <h5 class='section'>Notes:</h5><ul>
 		 * 	<li class='note'>
 		 * 		When defined as classes, instances are resolved using the registered bean store which
-		 * 		by default is {@link BasicBeanStore} which requires the class have one of the following
+		 * 		by default is {@link BasicBeanStore2} which requires the class have one of the following
 		 * 		constructors:
 		 * 		<ul>
 		 * 			<li><code><jk>public</jk> T(RestContext.Builder)</code>
@@ -1776,11 +1777,11 @@ public class RestContext extends Context {
 
 			if (rootBeanStore == null) {
 				rootBeanStore = beanStore;
-				beanStore = BasicBeanStore.of(rootBeanStore);
+				beanStore = BasicBeanStore2.of(rootBeanStore);
 			}
 			var bs = beanStore;
 
-			beanStore.add(BasicBeanStore.class, bs);
+			beanStore.add(BasicBeanStore2.class, bs);
 			varResolver = createVarResolver(bs, r, rc);
 			beanStore.add(VarResolver.class, varResolver.build());
 			config = beanStore.add(Config.class, createConfig(bs, r, rc));
@@ -3018,7 +3019,7 @@ public class RestContext extends Context {
 		 *
 		 * 		<jc>// Override the method used to create default request attributes.</jc>
 		 * 		<ja>@Override</ja>
-		 * 		<jk>protected</jk> NamedAttributeMap createDefaultRequestAttributes(Object <jv>resource</jv>, BasicBeanStore <jv>beanStore</jv>, Method <jv>method</jv>, RestContext <jv>context</jv>) <jk>throws</jk> Exception {
+		 * 		<jk>protected</jk> NamedAttributeMap createDefaultRequestAttributes(Object <jv>resource</jv>, BasicBeanStore2 <jv>beanStore</jv>, Method <jv>method</jv>, RestContext <jv>context</jv>) <jk>throws</jk> Exception {
 		 * 			<jk>return super</jk>
 		 * 				.createDefaultRequestAttributes(<jv>resource</jv>, <jv>beanStore</jv>, <jv>method</jv>, <jv>context</jv>)
 		 * 				.append(NamedAttribute.<jsm>of</jsm>(<js>"foo"</js>, ()-&gt;<jf>fooSupplier</jf>.get());
@@ -3076,7 +3077,7 @@ public class RestContext extends Context {
 		 *
 		 * @return The root bean store.
 		 */
-		public BasicBeanStore rootBeanStore() {
+		public BasicBeanStore2 rootBeanStore() {
 			return rootBeanStore;
 		}
 
@@ -3692,7 +3693,7 @@ public class RestContext extends Context {
 		 * 	These variables affect the variable resolver returned by {@link RestRequest#getVarResolverSession()}.
 		 *
 		 * <p>
-		 * The var resolver is created by the constructor using the {@link #createVarResolver(BasicBeanStore,Supplier,Class)} method and is initialized with the following variables:
+		 * The var resolver is created by the constructor using the {@link #createVarResolver(BasicBeanStore2,Supplier,Class)} method and is initialized with the following variables:
 		 * <ul class='javatreec'>
 		 * 	<li class='jc'>{@link ArgsVar}
 		 * 	<li class='jc'>{@link CoalesceVar}
@@ -3797,7 +3798,7 @@ public class RestContext extends Context {
 			return this;
 		}
 
-		private static void runInitHooks(BasicBeanStore beanStore, Supplier<?> resource) throws ServletException {
+		private static void runInitHooks(BasicBeanStore2 beanStore, Supplier<?> resource) throws ServletException {
 
 			var r = resource.get();
 
@@ -3833,7 +3834,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new bean context sub-builder.
 		 */
-		protected BeanContext.Builder createBeanContext(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected BeanContext.Builder createBeanContext(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<BeanContext.Builder> v = Value.of(BeanContext.create());
@@ -3859,12 +3860,12 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new bean store builder.
 		 */
-		protected BasicBeanStore.Builder createBeanStore(Supplier<?> resource) {
+		protected BasicBeanStore2.Builder createBeanStore(Supplier<?> resource) {
 
 			// Default value.
 			// @formatter:off
 			var v = Value.of(
-				BasicBeanStore
+				BasicBeanStore2
 					.create()
 					.parent(rootBeanStore())
 				);
@@ -3873,10 +3874,10 @@ public class RestContext extends Context {
 			// Apply @Rest(beanStore).
 			rstream(AP.find(Rest.class, info(resourceClass))).map(x -> x.inner().beanStore()).filter(ClassUtils::isNotVoid).forEach(x -> v.get().type(x));
 
-			// Replace with bean from:  @RestInject public [static] BasicBeanStore xxx(<args>)
+			// Replace with bean from:  @RestInject public [static] BasicBeanStore2 xxx(<args>)
 			// @formatter:off
 			var bs = v.get().build();
-			new BeanCreateMethodFinder<>(BasicBeanStore.class, resource.get(), bs)
+			new BeanCreateMethodFinder<>(BasicBeanStore2.class, resource.get(), bs)
 				.find(Builder::isRestInjectMethod)
 				.run(x -> v.get().impl(x));
 			// @formatter:on
@@ -3897,7 +3898,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new call logger sub-builder.
 		 */
-		protected BeanCreator<CallLogger> createCallLogger(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected BeanCreator<CallLogger> createCallLogger(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			var creator = BeanCreator.of(CallLogger.class, beanStore).type(BasicCallLogger.class);
 
@@ -3928,7 +3929,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean type that this context is defined against.
 		 * @return A new config.
 		 */
-		protected Config createConfig(BasicBeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
+		protected Config createConfig(BasicBeanStore2 beanStore, Supplier<?> resource, Class<?> resourceClass) {
 
 			var v = Value.<Config>empty();
 
@@ -3968,7 +3969,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new debug enablement bean creator.
 		 */
-		protected BeanCreator<DebugEnablement> createDebugEnablement(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected BeanCreator<DebugEnablement> createDebugEnablement(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			var creator = BeanCreator.of(DebugEnablement.class, beanStore).type(BasicDebugEnablement.class);
 
@@ -3992,7 +3993,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new default request attributes sub-builder.
 		 */
-		protected NamedAttributeMap createDefaultRequestAttributes(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected NamedAttributeMap createDefaultRequestAttributes(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			var v = Value.of(NamedAttributeMap.create());
@@ -4014,7 +4015,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new default request headers sub-builder.
 		 */
-		protected HeaderList createDefaultRequestHeaders(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected HeaderList createDefaultRequestHeaders(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			var v = Value.of(HeaderList.create());
@@ -4037,7 +4038,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new default response headers sub-builder.
 		 */
-		protected HeaderList createDefaultResponseHeaders(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected HeaderList createDefaultResponseHeaders(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			var v = Value.of(HeaderList.create());
@@ -4060,7 +4061,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new destroy method list.
 		 */
-		protected MethodList createDestroyMethods(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected MethodList createDestroyMethods(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			var v = Value.of(MethodList.of(getAnnotatedMethods(resource, RestDestroy.class).collect(Collectors.toList())));
@@ -4086,7 +4087,7 @@ public class RestContext extends Context {
 		 * 	<br>Created by {@link RestContext.Builder#beanStore()}.
 		 * @return A new encoder group sub-builder.
 		 */
-		protected EncoderSet.Builder createEncoders(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected EncoderSet.Builder createEncoders(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<EncoderSet.Builder> v = Value.of(EncoderSet.create(beanStore).add(IdentityEncoder.INSTANCE));
@@ -4112,7 +4113,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new end call method list.
 		 */
-		protected MethodList createEndCallMethods(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected MethodList createEndCallMethods(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<MethodList> v = Value.of(MethodList.of(getAnnotatedMethods(resource, RestEndCall.class).collect(Collectors.toList())));
@@ -4136,7 +4137,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new JSON schema generator sub-builder.
 		 */
-		protected JsonSchemaGenerator.Builder createJsonSchemaGenerator(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected JsonSchemaGenerator.Builder createJsonSchemaGenerator(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			var v = Value.of(JsonSchemaGenerator.create());
@@ -4169,7 +4170,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean class that this context is defined against.
 		 * @return A new logger.
 		 */
-		protected Logger createLogger(BasicBeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
+		protected Logger createLogger(BasicBeanStore2 beanStore, Supplier<?> resource, Class<?> resourceClass) {
 
 			// Default value.
 			Value<Logger> v = Value.of(Logger.getLogger(cn(resourceClass)));
@@ -4196,7 +4197,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new messages sub-builder.
 		 */
-		protected Messages.Builder createMessages(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected Messages.Builder createMessages(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<Messages.Builder> v = Value.of(Messages.create(resourceClass));
@@ -4223,7 +4224,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new method execution statistics store sub-builder.
 		 */
-		protected MethodExecStore.Builder createMethodExecStore(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected MethodExecStore.Builder createMethodExecStore(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<MethodExecStore.Builder> v = Value.of(MethodExecStore.create(beanStore));
@@ -4254,7 +4255,7 @@ public class RestContext extends Context {
 		 * 	<br>Created by {@link RestContext.Builder#beanStore()}.
 		 * @return A new parser group sub-builder.
 		 */
-		protected ParserSet.Builder createParsers(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected ParserSet.Builder createParsers(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<ParserSet.Builder> v = Value.of(ParserSet.create(beanStore));
@@ -4284,7 +4285,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new part parser sub-builder.
 		 */
-		protected HttpPartParser.Creator createPartParser(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected HttpPartParser.Creator createPartParser(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<HttpPartParser.Creator> v = Value.of(HttpPartParser.creator().type(OpenApiParser.class));
@@ -4320,7 +4321,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new part serializer sub-builder.
 		 */
-		protected HttpPartSerializer.Creator createPartSerializer(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected HttpPartSerializer.Creator createPartSerializer(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<HttpPartSerializer.Creator> v = Value.of(HttpPartSerializer.creator().type(OpenApiSerializer.class));
@@ -4352,7 +4353,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new post-call method list.
 		 */
-		protected MethodList createPostCallMethods(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected MethodList createPostCallMethods(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<MethodList> v = Value.of(MethodList.of(getAnnotatedMethods(resource, RestPostCall.class).collect(Collectors.toList())));
@@ -4372,7 +4373,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new post-init-child-first method list.
 		 */
-		protected MethodList createPostInitChildFirstMethods(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected MethodList createPostInitChildFirstMethods(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			var ap = AP;
@@ -4400,7 +4401,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new post-init method list.
 		 */
-		protected MethodList createPostInitMethods(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected MethodList createPostInitMethods(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			var ap = AP;
@@ -4428,7 +4429,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new pre-call method list.
 		 */
-		protected MethodList createPreCallMethods(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected MethodList createPreCallMethods(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<MethodList> v = Value.of(MethodList.of(getAnnotatedMethods(resource, RestPreCall.class).collect(Collectors.toList())));
@@ -4452,7 +4453,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new response processor list sub-builder.
 		 */
-		protected ResponseProcessorList.Builder createResponseProcessors(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected ResponseProcessorList.Builder createResponseProcessors(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			// @formatter:off
@@ -4493,7 +4494,7 @@ public class RestContext extends Context {
 		 * @return A new REST children list.
 		 * @throws Exception If a problem occurred instantiating one of the child rest contexts.
 		 */
-		protected RestChildren.Builder createRestChildren(BasicBeanStore beanStore, Supplier<?> resource, RestContext restContext) throws Exception {
+		protected RestChildren.Builder createRestChildren(BasicBeanStore2 beanStore, Supplier<?> resource, RestContext restContext) throws Exception {
 
 			// Default value.
 			Value<RestChildren.Builder> v = Value.of(RestChildren.create(beanStore).type(childrenClass));
@@ -4567,7 +4568,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new REST operation args sub-builder.
 		 */
-		protected RestOpArgList.Builder createRestOpArgs(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected RestOpArgList.Builder createRestOpArgs(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<RestOpArgList.Builder> v = Value.of(RestOpArgList.create(beanStore).add(AttributeArg.class, ContentArg.class, FormDataArg.class, HasFormDataArg.class, HasQueryArg.class,
@@ -4598,7 +4599,7 @@ public class RestContext extends Context {
 		 * @return A new REST operations list.
 		 * @throws ServletException If a problem occurred instantiating one of the child rest contexts.
 		 */
-		protected RestOperations.Builder createRestOperations(BasicBeanStore beanStore, Supplier<?> resource, RestContext restContext) throws ServletException {
+		protected RestOperations.Builder createRestOperations(BasicBeanStore2 beanStore, Supplier<?> resource, RestContext restContext) throws ServletException {
 
 			// Default value.
 			Value<RestOperations.Builder> v = Value.of(RestOperations.create(beanStore));
@@ -4634,7 +4635,7 @@ public class RestContext extends Context {
 
 						RestOpContext.Builder rocb = RestOpContext.create(mi.inner(), restContext).beanStore(beanStore).type(opContextClass);
 
-						beanStore = BasicBeanStore.of(beanStore).addBean(RestOpContext.Builder.class, rocb);
+						beanStore = BasicBeanStore2.of(beanStore).addBean(RestOpContext.Builder.class, rocb);
 						for (var m : initMap.values()) {
 							if (! beanStore.hasAllParams(m, resource.get())) {
 								throw servletException("Could not call @RestInit method {0}.{1}.  Could not find prerequisites: {2}.", cns(m.getDeclaringClass()), m.getSignature(),
@@ -4697,7 +4698,7 @@ public class RestContext extends Context {
 		 * 	<br>Created by {@link RestContext.Builder#beanStore()}.
 		 * @return A new serializer group sub-builder.
 		 */
-		protected SerializerSet.Builder createSerializers(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected SerializerSet.Builder createSerializers(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<SerializerSet.Builder> v = Value.of(SerializerSet.create(beanStore));
@@ -4723,7 +4724,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new start call method list.
 		 */
-		protected MethodList createStartCallMethods(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected MethodList createStartCallMethods(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<MethodList> v = Value.of(MethodList.of(getAnnotatedMethods(resource, RestStartCall.class).collect(Collectors.toList())));
@@ -4747,7 +4748,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new static files sub-builder.
 		 */
-		protected BeanCreator<StaticFiles> createStaticFiles(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected BeanCreator<StaticFiles> createStaticFiles(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			var creator = BeanCreator.of(StaticFiles.class, beanStore).type(BasicStaticFiles.class);
 
@@ -4778,7 +4779,7 @@ public class RestContext extends Context {
 		 * 		resource class with any of the following arguments:
 		 * 		<ul>
 		 * 			<li>{@link RestContext}
-		 * 			<li>{@link BasicBeanStore}
+		 * 			<li>{@link BasicBeanStore2}
 		 * 			<li>Any <a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestServerSpringbootBasics">juneau-rest-server-springboot Basics</a>.
 		 * 		</ul>
 		 * 	<li>Resolves it via the bean store registered in this context.
@@ -4796,7 +4797,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new swagger provider sub-builder.
 		 */
-		protected BeanCreator<SwaggerProvider> createSwaggerProvider(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected BeanCreator<SwaggerProvider> createSwaggerProvider(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			var creator = BeanCreator.of(SwaggerProvider.class, beanStore).type(BasicSwaggerProvider.class);
 
@@ -4828,7 +4829,7 @@ public class RestContext extends Context {
 		 * 	<br>Created by {@link RestContext.Builder#beanStore()}.
 		 * @return A new thrown-store sub-builder.
 		 */
-		protected ThrownStore.Builder createThrownStore(BasicBeanStore beanStore, Supplier<?> resource, RestContext parent) {
+		protected ThrownStore.Builder createThrownStore(BasicBeanStore2 beanStore, Supplier<?> resource, RestContext parent) {
 
 			// Default value.
 			Value<ThrownStore.Builder> v = Value.of(ThrownStore.create(beanStore).impl(parent == null ? null : parent.getThrownStore()));
@@ -4860,7 +4861,7 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean type that this context is defined against.
 		 * @return A new variable resolver sub-builder.
 		 */
-		protected VarResolver.Builder createVarResolver(BasicBeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
+		protected VarResolver.Builder createVarResolver(BasicBeanStore2 beanStore, Supplier<?> resource, Class<?> resourceClass) {
 
 			// Default value.
 			// @formatter:off
@@ -4947,8 +4948,8 @@ public class RestContext extends Context {
 	protected final AtomicBoolean initialized = new AtomicBoolean(false);
 	protected final BasicHttpException initException;
 	protected final BeanContext beanContext;
-	protected final BasicBeanStore beanStore;
-	protected final BasicBeanStore rootBeanStore;
+	protected final BasicBeanStore2 beanStore;
+	protected final BasicBeanStore2 rootBeanStore;
 	protected final Builder builder;
 	protected final CallLogger callLogger;
 	protected final Charset defaultCharset;
@@ -5028,10 +5029,10 @@ public class RestContext extends Context {
 			resourceClass = builder.resourceClass;
 			rootBeanStore = builder.rootBeanStore();
 
-			BasicBeanStore bs = beanStore = builder.beanStore();
+			BasicBeanStore2 bs = beanStore = builder.beanStore();
 			// @formatter:off
 			beanStore
-				.addBean(BasicBeanStore.class, beanStore)
+				.addBean(BasicBeanStore2.class, beanStore)
 				.addBean(RestContext.class, this)
 				.addBean(Object.class, resource.get())
 				.addBean(DefaultSettingsMap.class, defaultSettings)
@@ -5313,7 +5314,7 @@ public class RestContext extends Context {
 	 *
 	 * @return The resource resolver associated with this context.
 	 */
-	public BasicBeanStore getBeanStore() { return beanStore; }
+	public BasicBeanStore2 getBeanStore() { return beanStore; }
 
 	/**
 	 * Returns the builder that created this context.
@@ -5602,7 +5603,7 @@ public class RestContext extends Context {
 	 *
 	 * @return The root bean store for this context.
 	 */
-	public BasicBeanStore getRootBeanStore() { return rootBeanStore; }
+	public BasicBeanStore2 getRootBeanStore() { return rootBeanStore; }
 
 	/**
 	 * Returns the serializers associated with this context.
@@ -5963,13 +5964,13 @@ public class RestContext extends Context {
 	 * 	<br>Created by {@link RestContext.Builder#beanStore()}.
 	 * @return The array of resolvers.
 	 */
-	protected RestOpArg[] findRestOperationArgs(Method m, BasicBeanStore beanStore) {
+	protected RestOpArg[] findRestOperationArgs(Method m, BasicBeanStore2 beanStore) {
 
 		var mi = MethodInfo.of(m);
 		var params = mi.getParameters();
 		var ra = new RestOpArg[params.size()];
 
-		beanStore = BasicBeanStore.of(beanStore);
+		beanStore = BasicBeanStore2.of(beanStore);
 
 		for (var i = 0; i < params.size(); i++) {
 			var pi = params.get(i);
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
index 1a51d77bac..24680d0680 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
@@ -38,6 +38,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.commons.collections.*;
 import org.apache.juneau.commons.collections.FluentMap;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.lang.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.commons.utils.*;
@@ -90,7 +91,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 	public static class Builder extends Context.Builder {
 
 		private BeanContext.Builder beanContext;
-		private BasicBeanStore beanStore;
+		private BasicBeanStore2 beanStore;
 		private boolean dotAll;
 		private Charset defaultCharset;
 		private EncoderSet.Builder encoders;
@@ -126,7 +127,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 			this.parent = context.builder;
 			this.restMethod = method;
 
-			this.beanStore = BasicBeanStore.of(context.getBeanStore()).addBean(java.lang.reflect.Method.class, method);
+			this.beanStore = BasicBeanStore2.of(context.getBeanStore()).addBean(java.lang.reflect.Method.class, method);
 			var ap = context.getBeanContext().getAnnotationProvider();
 
 			var mi = MethodInfo.of(context.getResourceClass(), method);
@@ -202,7 +203,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 *
 		 * @return The bean store being used by this builder.
 		 */
-		public BasicBeanStore beanStore() {
+		public BasicBeanStore2 beanStore() {
 			return beanStore;
 		}
 
@@ -1391,12 +1392,12 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		}
 
 		/**
-		 * Specifies a {@link BasicBeanStore} to use when resolving constructor arguments.
+		 * Specifies a {@link BasicBeanStore2} to use when resolving constructor arguments.
 		 *
 		 * @param beanStore The bean store to use for resolving constructor arguments.
 		 * @return This object.
 		 */
-		protected Builder beanStore(BasicBeanStore beanStore) {
+		protected Builder beanStore(BasicBeanStore2 beanStore) {
 			this.beanStore = beanStore;
 			return this;
 		}
@@ -1412,14 +1413,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new bean context sub-builder.
 		 */
-		protected BeanContext.Builder createBeanContext(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected BeanContext.Builder createBeanContext(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			// Default value.
 			Value<BeanContext.Builder> v = Value.of(parent.beanContext().copy());
 
 			// Replace with bean from:  @RestInject(methodScope="foo") public [static] BeanContext xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(BeanContext.Builder.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(BeanContext.Builder.class, v.get());
 			new BeanCreateMethodFinder<>(BeanContext.class, resource, bs)
 				.find(this::matches)
 				.run(x -> v.get().impl(x));
@@ -1505,7 +1506,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new response converter list sub-builder.
 		 */
-		protected RestConverterList.Builder createConverters(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected RestConverterList.Builder createConverters(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<RestConverterList.Builder> v = Value.of(RestConverterList.create(beanStore));
@@ -1533,13 +1534,13 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new default request attributes sub-builder.
 		 */
-		protected NamedAttributeMap createDefaultRequestAttributes(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected NamedAttributeMap createDefaultRequestAttributes(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			var v = Value.of(parent.defaultRequestAttributes().copy());
 
 			// Replace with bean from:  @RestInject(name="defaultRequestAttributes",methodScope="foo") public [static] NamedAttributeMap xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(NamedAttributeMap.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(NamedAttributeMap.class, v.get());
 			new BeanCreateMethodFinder<>(NamedAttributeMap.class, resource, bs)
 				.find(x -> matches(x, "defaultRequestAttributes"))
 				.run(x -> v.set(x));
@@ -1559,13 +1560,13 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new default request form data sub-builder.
 		 */
-		protected PartList createDefaultRequestFormData(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected PartList createDefaultRequestFormData(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			var v = Value.of(PartList.create());
 
 			// Replace with bean from:  @RestInject(name="defaultRequestFormData",methodScope="foo") public [static] PartList xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(PartList.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(PartList.class, v.get());
 			new BeanCreateMethodFinder<>(PartList.class, resource, bs)
 				.find(x -> matches(x, "defaultRequestFormData"))
 				.run(x -> v.set(x));
@@ -1585,13 +1586,13 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new default request headers sub-builder.
 		 */
-		protected HeaderList createDefaultRequestHeaders(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected HeaderList createDefaultRequestHeaders(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			var v = Value.of(parent.defaultRequestHeaders().copy());
 
 			// Replace with bean from:  @RestInject(name="defaultRequestHeaders",methodScope="foo") public [static] HeaderList xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(HeaderList.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(HeaderList.class, v.get());
 			new BeanCreateMethodFinder<>(HeaderList.class, resource, bs)
 				.find(x -> matches(x, "defaultRequestHeaders"))
 				.run(x -> v.set(x));
@@ -1611,13 +1612,13 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new default request query data sub-builder.
 		 */
-		protected PartList createDefaultRequestQueryData(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected PartList createDefaultRequestQueryData(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			var v = Value.of(PartList.create());
 
 			// Replace with bean from:  @RestInject(name="defaultRequestQueryData",methodScope="foo") public [static] PartList xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(PartList.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(PartList.class, v.get());
 			new BeanCreateMethodFinder<>(PartList.class, resource, bs)
 				.find(x -> matches(x, "defaultRequestQueryData"))
 				.run(x -> v.set(x));
@@ -1637,13 +1638,13 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new default response headers sub-builder.
 		 */
-		protected HeaderList createDefaultResponseHeaders(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected HeaderList createDefaultResponseHeaders(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			var v = Value.of(parent.defaultResponseHeaders().copy());
 
 			// Replace with bean from:  @RestInject(name="defaultResponseHeaders",methodScope="foo") public [static] HeaderList xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(HeaderList.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(HeaderList.class, v.get());
 			new BeanCreateMethodFinder<>(HeaderList.class, resource, bs)
 				.find(x -> matches(x, "defaultResponseHeaders"))
 				.run(x -> v.set(x));
@@ -1663,14 +1664,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new encoder group sub-builder.
 		 */
-		protected EncoderSet.Builder createEncoders(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected EncoderSet.Builder createEncoders(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			// Default value.
 			Value<EncoderSet.Builder> v = Value.of(parent.encoders().copy());
 
 			// Replace with bean from:  @RestInject(methodScope="foo") public [static] EncoderSet xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(EncoderSet.Builder.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(EncoderSet.Builder.class, v.get());
 			new BeanCreateMethodFinder<>(EncoderSet.class, resource, bs)
 				.find(this::matches)
 				.run(x -> v.get().impl(x));
@@ -1696,7 +1697,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 		<ul>
 		 * 			<li>{@link Method} - The Java method this context belongs to.
 		 * 			<li>{@link RestContext}
-		 * 			<li>{@link BasicBeanStore}
+		 * 			<li>{@link BasicBeanStore2}
 		 * 			<li>Any <a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestServerSpringbootBasics">juneau-rest-server-springboot Basics</a>.
 		 * 		</ul>
 		 * 	<li>Resolves it via the bean store registered in this context.
@@ -1709,7 +1710,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new guard list sub-builder.
 		 */
-		protected RestGuardList.Builder createGuards(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected RestGuardList.Builder createGuards(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<RestGuardList.Builder> v = Value.of(RestGuardList.create(beanStore));
@@ -1742,14 +1743,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new JSON schema generator sub-builder.
 		 */
-		protected JsonSchemaGenerator.Builder createJsonSchemaGenerator(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected JsonSchemaGenerator.Builder createJsonSchemaGenerator(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			// Default value.
 			Value<JsonSchemaGenerator.Builder> v = Value.of(parent.jsonSchemaGenerator().copy());
 
 			// Replace with bean from:  @RestInject(methodScope="foo") public [static] JsonSchemaGenerator xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(JsonSchemaGenerator.Builder.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(JsonSchemaGenerator.Builder.class, v.get());
 			new BeanCreateMethodFinder<>(JsonSchemaGenerator.class, resource, bs)
 				.find(this::matches)
 				.run(x -> v.get().impl(x));
@@ -1801,7 +1802,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 		<ul>
 		 * 			<li>{@link java.lang.reflect.Method} - The Java method this context belongs to.
 		 * 			<li>{@link RestContext}
-		 * 			<li>{@link BasicBeanStore}
+		 * 			<li>{@link BasicBeanStore2}
 		 * 			<li>Any <a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestServerSpringbootBasics">juneau-rest-server-springboot Basics</a>.
 		 * 		</ul>
 		 * 	<li>Resolves it via the bean store registered in this context.
@@ -1814,7 +1815,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new matcher list sub-builder.
 		 */
-		protected RestMatcherList.Builder createMatchers(BasicBeanStore beanStore, Supplier<?> resource) {
+		protected RestMatcherList.Builder createMatchers(BasicBeanStore2 beanStore, Supplier<?> resource) {
 
 			// Default value.
 			Value<RestMatcherList.Builder> v = Value.of(RestMatcherList.create(beanStore));
@@ -1847,14 +1848,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new parser group sub-builder.
 		 */
-		protected ParserSet.Builder createParsers(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected ParserSet.Builder createParsers(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			// Default value.
 			Value<ParserSet.Builder> v = Value.of(parent.parsers().copy());
 
 			// Replace with bean from:  @RestInject(methodScope="foo") public [static] ParserSet xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(ParserSet.Builder.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(ParserSet.Builder.class, v.get());
 			new BeanCreateMethodFinder<>(ParserSet.class, resource, bs)
 				.find(this::matches)
 				.run(x -> v.get().impl(x));
@@ -1874,14 +1875,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new part parser sub-builder.
 		 */
-		protected HttpPartParser.Creator createPartParser(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected HttpPartParser.Creator createPartParser(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			// Default value.
 			Value<HttpPartParser.Creator> v = Value.of(parent.partParser().copy());
 
 			// Replace with bean from:  @RestInject(methodScope="foo") public [static] HttpPartParser xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(HttpPartParser.Creator.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(HttpPartParser.Creator.class, v.get());
 			new BeanCreateMethodFinder<>(HttpPartParser.class, resource, bs)
 				.find(this::matches)
 				.run(x -> v.get().impl(x));
@@ -1901,14 +1902,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new part serializer sub-builder.
 		 */
-		protected HttpPartSerializer.Creator createPartSerializer(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected HttpPartSerializer.Creator createPartSerializer(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			// Default value.
 			Value<HttpPartSerializer.Creator> v = Value.of(parent.partSerializer().copy());
 
 			// Replace with bean from:  @RestInject(methodScope="foo") public [static] HttpPartSerializer xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(HttpPartSerializer.Creator.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(HttpPartSerializer.Creator.class, v.get());
 			new BeanCreateMethodFinder<>(HttpPartSerializer.class, resource, bs)
 				.find(this::matches)
 				.run(x -> v.get().impl(x));
@@ -1928,14 +1929,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @return A new serializer group sub-builder.
 		 */
-		protected SerializerSet.Builder createSerializers(BasicBeanStore beanStore, RestContext.Builder parent, Supplier<?> resource) {
+		protected SerializerSet.Builder createSerializers(BasicBeanStore2 beanStore, RestContext.Builder parent, Supplier<?> resource) {
 
 			// Default value.
 			Value<SerializerSet.Builder> v = Value.of(parent.serializers().copy());
 
 			// Replace with bean from:  @RestInject(methodScope="foo") public [static] SerializerSet xxx(<args>)
 			// @formatter:off
-			var bs = BasicBeanStore.of(beanStore).addBean(SerializerSet.Builder.class, v.get());
+			var bs = BasicBeanStore2.of(beanStore).addBean(SerializerSet.Builder.class, v.get());
 			new BeanCreateMethodFinder<>(SerializerSet.class, resource, bs)
 				.find(this::matches)
 				.run(x -> v.get().impl(x));
@@ -2169,12 +2170,12 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 			mi = MethodInfo.of(method).accessible();
 
 			// @formatter:off
-			var bs = BasicBeanStore.of(context.getRootBeanStore())
+			var bs = BasicBeanStore2.of(context.getRootBeanStore())
 				.addBean(RestOpContext.class, this)
 				.addBean(Method.class, method)
 				.addBean(AnnotationWorkList.class, builder.getApplied());
 			// @formatter:on
-			bs.addBean(BasicBeanStore.class, bs);
+			bs.addBean(BasicBeanStore2.class, bs);
 
 			beanContext = bs.add(BeanContext.class, builder.getBeanContext().orElse(context.getBeanContext()));
 			converters = bs.add(RestConverter[].class, builder.converters().build().asArray());
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpSession.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpSession.java
index 969dd1a9a0..693b04f6c5 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpSession.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpSession.java
@@ -23,6 +23,7 @@ import java.io.*;
 import org.apache.http.*;
 import org.apache.juneau.*;
 import org.apache.juneau.commons.collections.FluentMap;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.rest.logger.*;
@@ -148,7 +149,7 @@ public class RestOpSession extends ContextSession {
 	 *
 	 * @return The bean store for this session.
 	 */
-	public BasicBeanStore getBeanStore() { return session.getBeanStore(); }
+	public BasicBeanStore2 getBeanStore() { return session.getBeanStore(); }
 
 	@Override /* Overridden from ContextSession */
 	public RestOpContext getContext() { return ctx; }
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperations.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperations.java
index 170e39e258..4d95309caa 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperations.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOperations.java
@@ -22,6 +22,7 @@ import static org.apache.juneau.commons.utils.Utils.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.rest.annotation.*;
@@ -44,7 +45,7 @@ public class RestOperations {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(RestOperations.class, beanStore);
 			map = new TreeMap<>();
 			set = set();
@@ -115,7 +116,7 @@ public class RestOperations {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
index 77500e6add..65903d0fc8 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestSession.java
@@ -26,6 +26,7 @@ import java.util.*;
 import org.apache.http.*;
 import org.apache.juneau.*;
 import org.apache.juneau.commons.collections.FluentMap;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.lang.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.response.*;
@@ -201,7 +202,7 @@ public class RestSession extends ContextSession {
 	}
 
 	private final long startTime = System.currentTimeMillis();
-	private final BasicBeanStore beanStore;
+	private final BasicBeanStore2 beanStore;
 	private CallLogger logger;
 	private HttpServletRequest req;
 	private HttpServletResponse res;
@@ -223,7 +224,7 @@ public class RestSession extends ContextSession {
 		super(builder);
 		context = builder.ctx;
 		resource = builder.resource;
-		beanStore = BasicBeanStore.of(context.getBeanStore()).addBean(RestContext.class, context);
+		beanStore = BasicBeanStore2.of(context.getBeanStore()).addBean(RestContext.class, context);
 
 		logger = beanStore.add(CallLogger.class, builder.logger);
 		pathInfoUndecoded = builder.pathInfoUndecoded;
@@ -289,7 +290,7 @@ public class RestSession extends ContextSession {
 	 *
 	 * @return The bean store of this call.
 	 */
-	public BasicBeanStore getBeanStore() { return beanStore; }
+	public BasicBeanStore2 getBeanStore() { return beanStore; }
 
 	/**
 	 * Returns the context that created this call.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
index 8b5419ce2a..a8ae9e71dd 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
@@ -26,6 +26,7 @@ import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.commons.annotation.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.config.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.encoders.*;
@@ -167,7 +168,7 @@ public @interface Rest {
 	 *
 	 * @return The annotation value.
 	 */
-	Class<? extends BasicBeanStore> beanStore() default BasicBeanStore.Void.class;
+	Class<? extends BasicBeanStore2> beanStore() default BasicBeanStore2.Void.class;
 
 	/**
 	 * Specifies the logger to use for logging of HTTP requests and responses.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
index ac4eb6eb53..6bd0963a12 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestAnnotation.java
@@ -28,6 +28,7 @@ import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.commons.annotation.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.arg.*;
@@ -71,7 +72,7 @@ public class RestAnnotation {
 		private Class<? extends RestGuard>[] guards = new Class[0];
 		private Class<? extends SwaggerProvider> swaggerProvider = SwaggerProvider.Void.class;
 		private Class<? extends RestOpArg>[] restOpArgs = new Class[0];
-		private Class<? extends BasicBeanStore> beanStore = BasicBeanStore.Void.class;
+		private Class<? extends BasicBeanStore2> beanStore = BasicBeanStore2.Void.class;
 		private Class<? extends RestChildren> restChildrenClass = RestChildren.Void.class;
 		private Class<? extends DebugEnablement> debugEnablement = DebugEnablement.Void.class;
 		private Class<? extends Serializer>[] serializers = new Class[0];
@@ -132,7 +133,7 @@ public class RestAnnotation {
 		 * @param value The new value for this property.
 		 * @return This object.
 		 */
-		public Builder beanStore(Class<? extends BasicBeanStore> value) {
+		public Builder beanStore(Class<? extends BasicBeanStore2> value) {
 			beanStore = value;
 			return this;
 		}
@@ -740,7 +741,7 @@ public class RestAnnotation {
 		private final Class<? extends RestGuard>[] guards;
 		private final Class<? extends SwaggerProvider> swaggerProvider;
 		private final Class<? extends RestOpArg>[] restOpArgs;
-		private final Class<? extends BasicBeanStore> beanStore;
+		private final Class<? extends BasicBeanStore2> beanStore;
 		private final Class<? extends RestChildren> restChildrenClass;
 		private final Class<? extends DebugEnablement> debugEnablement;
 		private final Class<? extends Serializer>[] serializers;
@@ -824,7 +825,7 @@ public class RestAnnotation {
 		}
 
 		@Override /* Overridden from Rest */
-		public Class<? extends BasicBeanStore> beanStore() {
+		public Class<? extends BasicBeanStore2> beanStore() {
 			return beanStore;
 		}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInject.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInject.java
index a9b78a20d8..352ea66501 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInject.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInject.java
@@ -23,6 +23,7 @@ import java.lang.annotation.*;
 import java.util.logging.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.config.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.encoders.*;
@@ -126,7 +127,7 @@ import org.apache.juneau.svl.*;
  * <p class='bcode'>
  * 	<jc>// Fields that get set during initialization based on beans found in the bean store.</jc>
  * 	<ja>@RestInject</ja> CallLogger <jf>callLogger</jf>;
- * 	<ja>@RestInject</ja> BasicBeanStore <jf>beanStore</jf>;  <jc>// Note that BasicBeanStore itself can be accessed this way.</jc>
+ * 	<ja>@RestInject</ja> BasicBeanStore2 <jf>beanStore</jf>;  <jc>// Note that BasicBeanStore2 itself can be accessed this way.</jc>
  * </p>
  *
  * <h5 class='section'>Notes:</h5><ul>
@@ -142,7 +143,7 @@ import org.apache.juneau.svl.*;
  * <table class='w800 styled'>
  * 	<tr><th>Bean class</td><th>Bean qualifying names</th><th>Scope</th></tr>
  * 	<tr><td>{@link BeanContext}<br>{@link org.apache.juneau.BeanContext.Builder}</td><td></td><td>class<br>method</td></tr>
- * 	<tr><td>{@link BasicBeanStore}<br>{@link org.apache.juneau.cp.BasicBeanStore.Builder}</td><td></td><td>class</td></tr>
+ * 	<tr><td>{@link BasicBeanStore2}<br>{@link org.apache.juneau.commons.inject.BasicBeanStore2.Builder}</td><td></td><td>class</td></tr>
  * 	<tr><td>{@link CallLogger}<br>{@link org.apache.juneau.rest.logger.CallLogger.Builder}</td><td></td><td>class</td></tr>
  * 	<tr><td>{@link Config}</td><td></td><td>class</td></tr>
  * 	<tr><td>{@link DebugEnablement}<br>{@link org.apache.juneau.rest.debug.DebugEnablement.Builder}</td><td></td><td>class</td></tr>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/DefaultArg.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/DefaultArg.java
index 3d68910d8d..bb5fb4d45a 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/DefaultArg.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/DefaultArg.java
@@ -18,6 +18,7 @@ package org.apache.juneau.rest.arg;
 
 import static org.apache.juneau.commons.utils.Utils.*;
 
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.*;
@@ -31,7 +32,7 @@ import org.apache.juneau.rest.annotation.*;
  * <p class='bjava'>
  * 	<jv>opSession</jv>
  * 		.{@link RestOpSession#getBeanStore() getBeanStore}()
- * 		.{@link BasicBeanStore#getBean(Class) getBean}(<jv>type</jv>);
+ * 		.{@link BasicBeanStore2#getBean(Class) getBean}(<jv>type</jv>);
  * </p>
  *
  * <p>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathRemainderArg.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathRemainderArg.java
index 0a9c299204..c14d4dacf6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathRemainderArg.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathRemainderArg.java
@@ -67,7 +67,7 @@ public class PathRemainderArg implements RestOpArg {
 	 *
 	 * @param paramInfo The Java method parameter being resolved.
 	 * @param annotations The annotations to apply to any new part parsers.
-	 * @param pathMatcher Path matcher for the specified method (not used, but included for BasicBeanStore compatibility).
+	 * @param pathMatcher Path matcher for the specified method (not used, but included for BasicBeanStore2 compatibility).
 	 * @return A new {@link PathRemainderArg}, or <jk>null</jk> if the parameter is not annotated with {@link PathRemainder}.
 	 */
 	public static PathRemainderArg create(ParameterInfo paramInfo, AnnotationWorkList annotations, UrlPathMatcher pathMatcher) {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RestOpArgList.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RestOpArgList.java
index af19bc4f27..ef3c0bc760 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RestOpArgList.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RestOpArgList.java
@@ -22,6 +22,7 @@ import static org.apache.juneau.commons.utils.CollectionUtils.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -44,7 +45,7 @@ public class RestOpArgList {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(RestOpArgList.class, beanStore);
 			entries = list();
 		}
@@ -85,7 +86,7 @@ public class RestOpArgList {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RestOpSessionArgs.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RestOpSessionArgs.java
index b64b1e7b09..464d13d4c2 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RestOpSessionArgs.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/RestOpSessionArgs.java
@@ -18,6 +18,7 @@ package org.apache.juneau.rest.arg;
 
 import org.apache.juneau.cp.*;
 import org.apache.juneau.commons.function.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
@@ -26,7 +27,7 @@ import org.apache.juneau.rest.annotation.*;
  * Resolves method parameters on {@link RestOp}-annotated Java methods of types found on the {@link RestOpSession} object.
  *
  * <ul class='javatree'>
- * 	<li class='jc'>{@link BasicBeanStore}
+ * 	<li class='jc'>{@link BasicBeanStore2}
  * 	<li class='jc'>{@link RestOpSession}
  * </ul>
  *
@@ -43,7 +44,7 @@ public class RestOpSessionArgs extends SimpleRestOperationArg {
 	 * @return A new arg, or <jk>null</jk> if the parameter type is not one of the supported types.
 	 */
 	public static RestOpSessionArgs create(ParameterInfo paramInfo) {
-		if (paramInfo.isType(BasicBeanStore.class))
+		if (paramInfo.isType(BasicBeanStore2.class))
 			return new RestOpSessionArgs(RestOpSession::getBeanStore);
 		if (paramInfo.isType(RestOpSession.class))
 			return new RestOpSessionArgs(x -> x);
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/DefaultConfig.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/DefaultConfig.java
index d4899c6c53..953f10450c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/DefaultConfig.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/DefaultConfig.java
@@ -17,6 +17,7 @@
 package org.apache.juneau.rest.config;
 
 import org.apache.juneau.annotation.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.encoders.*;
 import org.apache.juneau.oapi.*;
@@ -122,7 +123,7 @@ import org.apache.juneau.serializer.annotation.*;
 	title="$S{j.title,$E{J_TITLE,}}",
 
 	// Injectable/overridable beans.
-	beanStore=BasicBeanStore.Void.class,  // Defaults to BasicBeanStore.
+	beanStore=BasicBeanStore2.Void.class,  // Defaults to BasicBeanStore2.
 	callLogger=CallLogger.Void.class,  // Defaults to BasicCallLogger.
 	debugEnablement=DebugEnablement.Void.class,  // Defaults to BasicDefaultEnablement.
 	staticFiles=StaticFiles.Void.class,  // Defaults to BasicStaticFiles.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converter/RestConverterList.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converter/RestConverterList.java
index f8618f5459..2c887bcf3c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converter/RestConverterList.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/converter/RestConverterList.java
@@ -21,6 +21,7 @@ import static org.apache.juneau.commons.utils.CollectionUtils.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -43,7 +44,7 @@ public class RestConverterList {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(RestConverterList.class, beanStore);
 			this.entries = list();
 		}
@@ -97,7 +98,7 @@ public class RestConverterList {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/BasicDebugEnablement.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/BasicDebugEnablement.java
index cae6a7430f..0b1172510d 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/BasicDebugEnablement.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/BasicDebugEnablement.java
@@ -24,6 +24,7 @@ import static org.apache.juneau.rest.annotation.RestOpAnnotation.*;
 import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.cp.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.commons.utils.*;
 import org.apache.juneau.rest.*;
@@ -55,12 +56,12 @@ public class BasicDebugEnablement extends DebugEnablement {
 	 *
 	 * @param beanStore The bean store containing injectable beans for this enablement.
 	 */
-	public BasicDebugEnablement(BasicBeanStore beanStore) {
+	public BasicDebugEnablement(BasicBeanStore2 beanStore) {
 		super(beanStore);
 	}
 
 	@Override
-	protected Builder init(BasicBeanStore beanStore) {
+	protected Builder init(BasicBeanStore2 beanStore) {
 		var b = super.init(beanStore);
 
 		var defaultSettings = beanStore.getBean(DefaultSettingsMap.class).get();
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
index 8ba1ee81a9..b331373370 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
@@ -24,6 +24,7 @@ import java.util.function.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.commons.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.response.*;
@@ -55,7 +56,7 @@ public abstract class DebugEnablement {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			mapBuilder = ReflectionMap.create(Enablement.class);
 			defaultEnablement = NEVER;
 			conditional = x -> eqic("true", x.getHeader("Debug"));
@@ -195,7 +196,7 @@ public abstract class DebugEnablement {
 	 * Represents no DebugEnablement.
 	 */
 	public abstract class Void extends DebugEnablement {
-		Void(BasicBeanStore beanStore) {
+		Void(BasicBeanStore2 beanStore) {
 			super(beanStore);
 		}
 	}
@@ -206,7 +207,7 @@ public abstract class DebugEnablement {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
@@ -217,11 +218,11 @@ public abstract class DebugEnablement {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Subclasses typically override the {@link #init(BasicBeanStore)} method when using this constructor.
+	 * Subclasses typically override the {@link #init(BasicBeanStore2)} method when using this constructor.
 	 *
 	 * @param beanStore The bean store containing injectable beans for this enablement.
 	 */
-	public DebugEnablement(BasicBeanStore beanStore) {
+	public DebugEnablement(BasicBeanStore2 beanStore) {
 		var builder = init(beanStore);
 		this.defaultEnablement = firstNonNull(builder.defaultEnablement, NEVER);
 		this.enablementMap = builder.mapBuilder.build();
@@ -296,7 +297,7 @@ public abstract class DebugEnablement {
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 * @return A new builder object.
 	 */
-	protected Builder init(BasicBeanStore beanStore) {
+	protected Builder init(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/guard/RestGuardList.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/guard/RestGuardList.java
index 736009a1b2..db59b5b5cc 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/guard/RestGuardList.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/guard/RestGuardList.java
@@ -21,6 +21,7 @@ import static org.apache.juneau.commons.utils.CollectionUtils.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -43,7 +44,7 @@ public class RestGuardList {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(RestGuardList.class, beanStore);
 			entries = list();
 		}
@@ -97,7 +98,7 @@ public class RestGuardList {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicCallLogger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicCallLogger.java
index 085a5395ce..fba72427ff 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicCallLogger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicCallLogger.java
@@ -19,6 +19,7 @@ package org.apache.juneau.rest.logger;
 import static java.util.logging.Level.*;
 import static org.apache.juneau.rest.logger.CallLoggingDetail.*;
 
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.*;
 
@@ -44,7 +45,7 @@ public class BasicCallLogger extends CallLogger {
 	 * Uses the same settings as {@link CallLogger}.
 	 */
 	public BasicCallLogger() {
-		super(BasicBeanStore.INSTANCE);
+		super(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -52,12 +53,12 @@ public class BasicCallLogger extends CallLogger {
 	 *
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 */
-	public BasicCallLogger(BasicBeanStore beanStore) {
+	public BasicCallLogger(BasicBeanStore2 beanStore) {
 		super(beanStore);
 	}
 
 	@Override
-	protected Builder init(BasicBeanStore beanStore) {
+	protected Builder init(BasicBeanStore2 beanStore) {
 		// @formatter:off
 		return super.init(beanStore)
 			.normalRules(  // Rules when debugging is not enabled.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicDisabledCallLogger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicDisabledCallLogger.java
index 7ac563c8d3..3a24d92f5f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicDisabledCallLogger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicDisabledCallLogger.java
@@ -16,6 +16,7 @@
  */
 package org.apache.juneau.rest.logger;
 
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -32,12 +33,12 @@ public class BasicDisabledCallLogger extends CallLogger {
 	 *
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 */
-	public BasicDisabledCallLogger(BasicBeanStore beanStore) {
+	public BasicDisabledCallLogger(BasicBeanStore2 beanStore) {
 		super(beanStore);
 	}
 
 	@Override
-	protected Builder init(BasicBeanStore beanStore) {
+	protected Builder init(BasicBeanStore2 beanStore) {
 		return super.init(beanStore).disabled();
 	}
 }
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCallLogger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCallLogger.java
index 48f12d0755..bbd79096ca 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCallLogger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCallLogger.java
@@ -21,6 +21,7 @@ import static org.apache.juneau.Enablement.*;
 import static org.apache.juneau.commons.utils.Utils.*;
 import static org.apache.juneau.rest.logger.CallLoggingDetail.*;
 
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.*;
 
@@ -69,12 +70,12 @@ public class BasicTestCallLogger extends CallLogger {
 	 *
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 */
-	public BasicTestCallLogger(BasicBeanStore beanStore) {
+	public BasicTestCallLogger(BasicBeanStore2 beanStore) {
 		super(beanStore);
 	}
 
 	@Override
-	protected Builder init(BasicBeanStore beanStore) {
+	protected Builder init(BasicBeanStore2 beanStore) {
 		// @formatter:off
 		return super.init(beanStore)
 			.normalRules(  // Rules when debugging is not enabled.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCaptureCallLogger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCaptureCallLogger.java
index 3820c1007e..9957275a5d 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCaptureCallLogger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/BasicTestCaptureCallLogger.java
@@ -23,6 +23,7 @@ import java.util.concurrent.atomic.*;
 import java.util.logging.*;
 
 import org.apache.juneau.assertions.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -84,7 +85,7 @@ public class BasicTestCaptureCallLogger extends CallLogger {
 	 * Uses the same settings as {@link CallLogger}.
 	 */
 	public BasicTestCaptureCallLogger() {
-		super(BasicBeanStore.INSTANCE);
+		super(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -92,7 +93,7 @@ public class BasicTestCaptureCallLogger extends CallLogger {
 	 *
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 */
-	public BasicTestCaptureCallLogger(BasicBeanStore beanStore) {
+	public BasicTestCaptureCallLogger(BasicBeanStore2 beanStore) {
 		super(beanStore);
 	}
 
@@ -175,7 +176,7 @@ public class BasicTestCaptureCallLogger extends CallLogger {
 	}
 
 	@Override
-	protected Builder init(BasicBeanStore beanStore) {
+	protected Builder init(BasicBeanStore2 beanStore) {
 		// @formatter:off
 		return super.init(beanStore)
 			.normalRules(  // Rules when debugging is not enabled.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
index fedb4503f5..19b00cc84c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLogger.java
@@ -31,6 +31,7 @@ import java.util.logging.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.commons.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.utils.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.annotation.*;
@@ -113,7 +114,7 @@ public class CallLogger {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			logger = Logger.getLogger(env(SP_logger, "global"));
 			enabled = env(SP_enabled, ALWAYS);
 			enabledTest = x -> false;
@@ -406,12 +407,12 @@ public class CallLogger {
 
 	/** Represents no logger */
 	public abstract class Void extends CallLogger {
-		Void(BasicBeanStore beanStore) {
+		Void(BasicBeanStore2 beanStore) {
 			super(beanStore);
 		}
 	}
 
-	private static final CallLoggerRule DEFAULT_RULE = CallLoggerRule.create(BasicBeanStore.INSTANCE).build();
+	private static final CallLoggerRule DEFAULT_RULE = CallLoggerRule.create(BasicBeanStore2.INSTANCE).build();
 
 	/**
 	 * System property name for the default logger name to use for {@link CallLogger} objects.
@@ -486,7 +487,7 @@ public class CallLogger {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
@@ -501,11 +502,11 @@ public class CallLogger {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Subclasses typically override the {@link #init(BasicBeanStore)} method when using this constructor.
+	 * Subclasses typically override the {@link #init(BasicBeanStore2)} method when using this constructor.
 	 *
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 */
-	public CallLogger(BasicBeanStore beanStore) {
+	public CallLogger(BasicBeanStore2 beanStore) {
 		var builder = init(beanStore);
 		this.logger = builder.logger;
 		this.thrownStore = builder.thrownStore;
@@ -729,7 +730,7 @@ public class CallLogger {
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 * @return A new builder object.
 	 */
-	protected Builder init(BasicBeanStore beanStore) {
+	protected Builder init(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore).logger(beanStore.getBean(Logger.class).orElse(null)).thrownStore(beanStore.getBean(ThrownStore.class).orElse(null));
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLoggerRule.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLoggerRule.java
index 3034a2abe3..26c7927d35 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLoggerRule.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/logger/CallLoggerRule.java
@@ -24,6 +24,7 @@ import java.util.logging.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.commons.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 import jakarta.servlet.http.*;
@@ -56,7 +57,7 @@ public class CallLoggerRule {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(CallLoggerRule.class, beanStore);
 		}
 
@@ -303,7 +304,7 @@ public class CallLoggerRule {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/RestMatcherList.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/RestMatcherList.java
index 8f36d6eca5..aee8d8d6f1 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/RestMatcherList.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/RestMatcherList.java
@@ -22,6 +22,7 @@ import static org.apache.juneau.commons.utils.CollectionUtils.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -44,7 +45,7 @@ public class RestMatcherList {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(RestMatcherList.class, beanStore);
 			entries = list();
 		}
@@ -98,7 +99,7 @@ public class RestMatcherList {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processor/ResponseProcessorList.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processor/ResponseProcessorList.java
index 797f649086..17dbec7699 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processor/ResponseProcessorList.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/processor/ResponseProcessorList.java
@@ -22,6 +22,7 @@ import static org.apache.juneau.commons.utils.CollectionUtils.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.cp.*;
 
@@ -45,7 +46,7 @@ public class ResponseProcessorList {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(ResponseProcessorList.class, beanStore);
 			this.entries = list();
 		}
@@ -97,11 +98,11 @@ public class ResponseProcessorList {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
-	private static ResponseProcessor instantiate(Object o, BasicBeanStore bs) {
+	private static ResponseProcessor instantiate(Object o, BasicBeanStore2 bs) {
 		if (o instanceof ResponseProcessor o2)
 			return o2;
 		try {
@@ -119,7 +120,7 @@ public class ResponseProcessorList {
 	 * @param builder The builder containing the contents for this list.
 	 */
 	protected ResponseProcessorList(Builder builder) {
-		BasicBeanStore bs = builder.beanStore();
+		BasicBeanStore2 bs = builder.beanStore();
 		// @formatter:off
 		entries =
 			builder
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFiles.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFiles.java
index e2fea387c2..0dc781aba6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFiles.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFiles.java
@@ -27,6 +27,7 @@ import java.util.*;
 
 import org.apache.http.*;
 import org.apache.juneau.commons.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.io.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.resource.*;
@@ -53,7 +54,7 @@ public class BasicStaticFiles implements StaticFiles {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static StaticFiles.Builder create(BasicBeanStore beanStore) {
+	public static StaticFiles.Builder create(BasicBeanStore2 beanStore) {
 		return new StaticFiles.Builder(beanStore);
 	}
 
@@ -68,7 +69,7 @@ public class BasicStaticFiles implements StaticFiles {
 	 *
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 */
-	public BasicStaticFiles(BasicBeanStore beanStore) {
+	public BasicStaticFiles(BasicBeanStore2 beanStore) {
 		// @formatter:off
 		this(StaticFiles
 			.create(beanStore)
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFiles.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFiles.java
index e7ddba9bc8..19a12fc54b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFiles.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFiles.java
@@ -23,6 +23,7 @@ import java.util.*;
 
 import org.apache.http.*;
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.io.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.resource.*;
@@ -49,7 +50,7 @@ public interface StaticFiles extends FileFinder {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(BasicStaticFiles.class, beanStore);
 			headers = list();
 			fileFinder = FileFinder.create(beanStore);
@@ -191,7 +192,7 @@ public interface StaticFiles extends FileFinder {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	static Builder create(BasicBeanStore beanStore) {
+	static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStats.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStats.java
index 3df5ec39e8..57e4277307 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStats.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStats.java
@@ -25,6 +25,7 @@ import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.commons.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -50,7 +51,7 @@ public class MethodExecStats {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(MethodExecStats.class, beanStore);
 		}
 
@@ -100,7 +101,7 @@ public class MethodExecStats {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStore.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStore.java
index e29c7d0bcf..b1e1282c6d 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStore.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodExecStore.java
@@ -24,6 +24,7 @@ import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -50,7 +51,7 @@ public class MethodExecStore {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(MethodExecStore.class, beanStore);
 		}
 
@@ -118,7 +119,7 @@ public class MethodExecStore {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -127,12 +128,12 @@ public class MethodExecStore {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
 	private final ThrownStore thrownStore;
-	private final BasicBeanStore beanStore;
+	private final BasicBeanStore2 beanStore;
 	private final Class<? extends MethodExecStats> statsImplClass;
 	private final ConcurrentHashMap<Method,MethodExecStats> db = new ConcurrentHashMap<>();
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodInvoker.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodInvoker.java
index 1c4976a15b..dce49d2c8b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodInvoker.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/MethodInvoker.java
@@ -20,6 +20,7 @@ import static org.apache.juneau.commons.utils.ThrowableUtils.*;
 
 import java.lang.reflect.*;
 
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.apache.juneau.cp.*;
 
@@ -81,7 +82,7 @@ public class MethodInvoker {
 	 * @throws IllegalArgumentException If wrong arguments were passed to method.
 	 * @throws InvocationTargetException If method threw an exception.
 	 */
-	public Object invoke(BasicBeanStore beanStore, Object o) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+	public Object invoke(BasicBeanStore2 beanStore, Object o) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 		if (beanStore.hasAllParams(m, o))
 			return invoke(o, beanStore.getParams(m, o));
 		throw illegalArg("Could not find prerequisites to invoke method ''{0}'': {1}", getFullName(), beanStore.getMissingParams(m, o));
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStats.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStats.java
index 87762f696d..04fb902941 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStats.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStats.java
@@ -23,6 +23,7 @@ import java.util.*;
 import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.commons.collections.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -38,7 +39,7 @@ public class ThrownStats implements Cloneable {
 	 */
 	public static class Builder {
 
-		final BasicBeanStore beanStore;
+		final BasicBeanStore2 beanStore;
 		Throwable throwable;
 		long hash;
 		List<String> stackTrace;
@@ -51,7 +52,7 @@ public class ThrownStats implements Cloneable {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			this.beanStore = beanStore;
 			this.creator = BeanCreator.of(ThrownStats.class, beanStore).builder(Builder.class, this);
 		}
@@ -127,7 +128,7 @@ public class ThrownStats implements Cloneable {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStore.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStore.java
index 1e9efbe130..1d336c8813 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStore.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/stats/ThrownStore.java
@@ -26,6 +26,7 @@ import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 
 /**
@@ -53,7 +54,7 @@ public class ThrownStore {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			super(ThrownStore.class, beanStore);
 		}
 
@@ -124,7 +125,7 @@ public class ThrownStore {
 	 * @return A new builder for this object.
 	 */
 	public static Builder create() {
-		return new Builder(BasicBeanStore.INSTANCE);
+		return new Builder(BasicBeanStore2.INSTANCE);
 	}
 
 	/**
@@ -133,13 +134,13 @@ public class ThrownStore {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	public static Builder create(BasicBeanStore beanStore) {
+	public static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
 	private final ConcurrentHashMap<Long,ThrownStats> db = new ConcurrentHashMap<>();
 	private final Optional<ThrownStore> parent;
-	private final BasicBeanStore beanStore;
+	private final BasicBeanStore2 beanStore;
 	private final Class<? extends ThrownStats> statsImplClass;
 	private final Set<String> ignoreClasses;
 
@@ -147,7 +148,7 @@ public class ThrownStore {
 	 * Constructor.
 	 */
 	public ThrownStore() {
-		this(create(BasicBeanStore.INSTANCE));
+		this(create(BasicBeanStore2.INSTANCE));
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProvider.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProvider.java
index 9f0ad10a92..e10dced677 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProvider.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProvider.java
@@ -21,6 +21,7 @@ import static org.apache.juneau.commons.utils.Utils.*;
 import java.util.*;
 
 import org.apache.juneau.bean.swagger.Swagger;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.jsonschema.*;
 import org.apache.juneau.rest.*;
@@ -40,14 +41,14 @@ public class BasicSwaggerProvider implements SwaggerProvider {
 	private final JsonSchemaGenerator js;
 	private final Messages messages;
 	private final FileFinder fileFinder;
-	private final BasicBeanStore beanStore;
+	private final BasicBeanStore2 beanStore;
 
 	/**
 	 * Constructor.
 	 *
 	 * @param beanStore The bean store containing injectable beans for this logger.
 	 */
-	public BasicSwaggerProvider(BasicBeanStore beanStore) {
+	public BasicSwaggerProvider(BasicBeanStore2 beanStore) {
 		// @formatter:off
 		this(
 			SwaggerProvider
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/SwaggerProvider.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/SwaggerProvider.java
index 7809519eba..d6e4a70684 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/SwaggerProvider.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/SwaggerProvider.java
@@ -22,6 +22,7 @@ import java.util.*;
 import java.util.function.*;
 
 import org.apache.juneau.bean.swagger.Swagger;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.jsonschema.*;
@@ -42,7 +43,7 @@ public interface SwaggerProvider {
 	 */
 	public class Builder {
 
-		final BasicBeanStore beanStore;
+		final BasicBeanStore2 beanStore;
 		Class<?> resourceClass;
 		Supplier<VarResolver> varResolver;
 		Supplier<JsonSchemaGenerator> jsonSchemaGenerator;
@@ -55,7 +56,7 @@ public interface SwaggerProvider {
 		 *
 		 * @param beanStore The bean store to use for creating beans.
 		 */
-		protected Builder(BasicBeanStore beanStore) {
+		protected Builder(BasicBeanStore2 beanStore) {
 			this.beanStore = beanStore;
 			this.creator = BeanCreator.of(SwaggerProvider.class, beanStore).type(BasicSwaggerProvider.class).builder(Builder.class, this);
 		}
@@ -202,7 +203,7 @@ public interface SwaggerProvider {
 	 * @param beanStore The bean store to use for creating beans.
 	 * @return A new builder for this object.
 	 */
-	static Builder create(BasicBeanStore beanStore) {
+	static Builder create(BasicBeanStore2 beanStore) {
 		return new Builder(beanStore);
 	}
 
diff --git a/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BasicBeanStore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BasicBeanStore_Test.java
new file mode 100644
index 0000000000..97276695bf
--- /dev/null
+++ b/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BasicBeanStore_Test.java
@@ -0,0 +1,942 @@
+/*
+ * 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.juneau.commons.inject;
+
+import static org.apache.juneau.commons.utils.Utils.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.junit.jupiter.api.*;
+
+class BasicBeanStore_Test extends TestBase {
+
+	// Test bean classes
+	static class TestBean {
+		private final String name;
+		TestBean(String name) { this.name = name; }
+		String getName() { return name; }
+		@Override public String toString() { return "TestBean[" + name + "]"; }
+		@Override public boolean equals(Object o) { return o instanceof TestBean o2 && eq(this, o2, (x,y) -> eq(x.name, y.name)); }
+		@Override public int hashCode() { return h(name); }
+	}
+
+	static class AnotherBean {
+		private final int value;
+		AnotherBean(int value) { this.value = value; }
+		int getValue() { return value; }
+		@Override public boolean equals(Object o) { return o instanceof AnotherBean o2 && eq(this, o2, (x,y) -> eq(x.value, y.value)); }
+		@Override public int hashCode() { return value; }
+	}
+
+	//====================================================================================================
+	// Constructor
+	//====================================================================================================
+
+	@Test
+	void a01_constructor_noParent() {
+		var store = new BasicBeanStore(null);
+		assertNotNull(store);
+		assertTrue(store.getBean(BasicBeanStore.class).isPresent());
+		assertSame(store, store.getBean(BasicBeanStore.class).get());
+	}
+
+	@Test
+	void a02_constructor_withParent() {
+		var parent = new BasicBeanStore(null);
+		var store = new BasicBeanStore(parent);
+		assertNotNull(store);
+		assertTrue(store.getBean(BasicBeanStore.class).isPresent());
+		assertSame(store, store.getBean(BasicBeanStore.class).get());
+	}
+
+	//====================================================================================================
+	// addBean(Class, Object)
+	//====================================================================================================
+
+	@Test
+	void b01_addBean_unnamed() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean);
+
+		var result = store.getBean(TestBean.class);
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void b02_addBean_unnamed_nullValue() {
+		var store = new BasicBeanStore(null);
+		store.addBean(TestBean.class, null);
+
+		var result = store.getBean(TestBean.class);
+		// Java's Optional cannot represent "present but null", so null beans return empty
+		assertFalse(result.isPresent());
+	}
+
+	@Test
+	void b03_addBean_unnamed_returnsThis() {
+		var store = new BasicBeanStore(null);
+		var result = store.addBean(TestBean.class, new TestBean("test1"));
+		assertSame(store, result);
+	}
+
+	@Test
+	void b04_addBean_unnamed_replaceExisting() {
+		var store = new BasicBeanStore(null);
+		var bean1 = new TestBean("test1");
+		var bean2 = new TestBean("test2");
+		store.addBean(TestBean.class, bean1);
+		store.addBean(TestBean.class, bean2);
+
+		var result = store.getBean(TestBean.class);
+		assertTrue(result.isPresent());
+		assertSame(bean2, result.get());
+	}
+
+	//====================================================================================================
+	// addBean(Class, Object, String)
+	//====================================================================================================
+
+	@Test
+	void c01_addBean_named() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean, "named1");
+
+		var result = store.getBean(TestBean.class, "named1");
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void c02_addBean_named_nullName() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean, null);
+
+		var result = store.getBean(TestBean.class);
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void c03_addBean_named_emptyString() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean, "");
+
+		var result = store.getBean(TestBean.class);
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void c04_addBean_named_multipleNames() {
+		var store = new BasicBeanStore(null);
+		var bean1 = new TestBean("test1");
+		var bean2 = new TestBean("test2");
+		var bean3 = new TestBean("test3");
+		store.addBean(TestBean.class, bean1, "name1");
+		store.addBean(TestBean.class, bean2, "name2");
+		store.addBean(TestBean.class, bean3, null);
+
+		assertSame(bean1, store.getBean(TestBean.class, "name1").get());
+		assertSame(bean2, store.getBean(TestBean.class, "name2").get());
+		assertSame(bean3, store.getBean(TestBean.class).get());
+	}
+
+	@Test
+	void c05_addBean_named_replaceExisting() {
+		var store = new BasicBeanStore(null);
+		var bean1 = new TestBean("test1");
+		var bean2 = new TestBean("test2");
+		store.addBean(TestBean.class, bean1, "name1");
+		store.addBean(TestBean.class, bean2, "name1");
+
+		var result = store.getBean(TestBean.class, "name1");
+		assertTrue(result.isPresent());
+		assertSame(bean2, result.get());
+	}
+
+	//====================================================================================================
+	// add(Class, Object) and add(Class, Object, String)
+	//====================================================================================================
+
+	@Test
+	void d01_add_unnamed_returnsBean() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		var result = store.add(TestBean.class, bean);
+
+		assertSame(bean, result);
+		assertSame(bean, store.getBean(TestBean.class).get());
+	}
+
+	@Test
+	void d02_add_named_returnsBean() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		var result = store.add(TestBean.class, bean, "name1");
+
+		assertSame(bean, result);
+		assertSame(bean, store.getBean(TestBean.class, "name1").get());
+	}
+
+	//====================================================================================================
+	// addSupplier(Class, Supplier)
+	//====================================================================================================
+
+	@Test
+	void e01_addSupplier_unnamed() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addSupplier(TestBean.class, () -> bean);
+
+		var result = store.getBean(TestBean.class);
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void e02_addSupplier_unnamed_lazyEvaluation() {
+		var store = new BasicBeanStore(null);
+		var callCount = new int[1];
+		store.addSupplier(TestBean.class, () -> {
+			callCount[0]++;
+			return new TestBean("test" + callCount[0]);
+		});
+
+		assertEquals(0, callCount[0]);
+		var result1 = store.getBean(TestBean.class);
+		assertEquals(1, callCount[0]);
+		var result2 = store.getBean(TestBean.class);
+		assertEquals(2, callCount[0]);
+		assertNotSame(result1.get(), result2.get());
+	}
+
+	@Test
+	void e03_addSupplier_unnamed_nullValue() {
+		var store = new BasicBeanStore(null);
+		store.addSupplier(TestBean.class, () -> null);
+
+		var result = store.getBean(TestBean.class);
+		// Java's Optional cannot represent "present but null", so null beans return empty
+		assertFalse(result.isPresent());
+	}
+
+	//====================================================================================================
+	// addSupplier(Class, Supplier, String)
+	//====================================================================================================
+
+	@Test
+	void f01_addSupplier_named() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addSupplier(TestBean.class, () -> bean, "name1");
+
+		var result = store.getBean(TestBean.class, "name1");
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void f02_addSupplier_named_lazyEvaluation() {
+		var store = new BasicBeanStore(null);
+		var callCount = new int[1];
+		store.addSupplier(TestBean.class, () -> {
+			callCount[0]++;
+			return new TestBean("test" + callCount[0]);
+		}, "name1");
+
+		assertEquals(0, callCount[0]);
+		var result1 = store.getBean(TestBean.class, "name1");
+		assertEquals(1, callCount[0]);
+		var result2 = store.getBean(TestBean.class, "name1");
+		assertEquals(2, callCount[0]);
+		assertNotSame(result1.get(), result2.get());
+	}
+
+	//====================================================================================================
+	// getBean(Class)
+	//====================================================================================================
+
+	@Test
+	void g01_getBean_unnamed_notFound() {
+		var store = new BasicBeanStore(null);
+		var result = store.getBean(TestBean.class);
+		assertFalse(result.isPresent());
+	}
+
+	@Test
+	void g02_getBean_unnamed_found() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean);
+
+		var result = store.getBean(TestBean.class);
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void g03_getBean_unnamed_withParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean);
+
+		var store = new BasicBeanStore(parent);
+		var result = store.getBean(TestBean.class);
+		assertTrue(result.isPresent());
+		assertSame(parentBean, result.get());
+	}
+
+	@Test
+	void g04_getBean_unnamed_childOverridesParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean);
+
+		var store = new BasicBeanStore(parent);
+		var childBean = new TestBean("child");
+		store.addBean(TestBean.class, childBean);
+
+		var result = store.getBean(TestBean.class);
+		assertTrue(result.isPresent());
+		assertSame(childBean, result.get());
+	}
+
+	@Test
+	void g05_getBean_unnamed_typeMapExistsButNoUnnamedBean() {
+		var store = new BasicBeanStore(null);
+		// Add a named bean - this creates the typeMap but no "" key
+		store.addBean(TestBean.class, new TestBean("test1"), "name1");
+
+		// getBean should return empty since no unnamed bean exists
+		var result = store.getBean(TestBean.class);
+		assertFalse(result.isPresent());
+	}
+
+	//====================================================================================================
+	// getBean(Class, String)
+	//====================================================================================================
+
+	@Test
+	void h01_getBean_named_notFound() {
+		var store = new BasicBeanStore(null);
+		var result = store.getBean(TestBean.class, "name1");
+		assertFalse(result.isPresent());
+	}
+
+	@Test
+	void h02_getBean_named_found() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean, "name1");
+
+		var result = store.getBean(TestBean.class, "name1");
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void h03_getBean_named_nullName() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean, null);
+
+		var result = store.getBean(TestBean.class, null);
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void h04_getBean_named_emptyString() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean, "");
+
+		var result = store.getBean(TestBean.class, "");
+		assertTrue(result.isPresent());
+		assertSame(bean, result.get());
+	}
+
+	@Test
+	void h05_getBean_named_withParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean, "name1");
+
+		var store = new BasicBeanStore(parent);
+		var result = store.getBean(TestBean.class, "name1");
+		assertTrue(result.isPresent());
+		assertSame(parentBean, result.get());
+	}
+
+	@Test
+	void h06_getBean_named_childOverridesParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean, "name1");
+
+		var store = new BasicBeanStore(parent);
+		var childBean = new TestBean("child");
+		store.addBean(TestBean.class, childBean, "name1");
+
+		var result = store.getBean(TestBean.class, "name1");
+		assertTrue(result.isPresent());
+		assertSame(childBean, result.get());
+	}
+
+	@Test
+	void h07_getBean_named_typeMapExistsButSupplierNull() {
+		var store = new BasicBeanStore(null);
+		// Add a bean with different name - this creates the typeMap but not the requested key
+		store.addBean(TestBean.class, new TestBean("test1"), "name1");
+
+		// getBean should return empty since "name2" doesn't exist
+		var result = store.getBean(TestBean.class, "name2");
+		assertFalse(result.isPresent());
+	}
+
+	//====================================================================================================
+	// getBeansOfType(Class)
+	//====================================================================================================
+
+	@Test
+	void i01_getBeansOfType_notFound() {
+		var store = new BasicBeanStore(null);
+		var result = store.getBeansOfType(TestBean.class);
+		assertNotNull(result);
+		assertTrue(result.isEmpty());
+	}
+
+	@Test
+	void i02_getBeansOfType_singleUnnamed() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean);
+
+		var result = store.getBeansOfType(TestBean.class);
+		assertEquals(1, result.size());
+		assertSame(bean, result.get(""));
+	}
+
+	@Test
+	void i03_getBeansOfType_singleNamed() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean, "name1");
+
+		var result = store.getBeansOfType(TestBean.class);
+		assertEquals(1, result.size());
+		assertSame(bean, result.get("name1"));
+	}
+
+	@Test
+	void i04_getBeansOfType_multipleNamed() {
+		var store = new BasicBeanStore(null);
+		var bean1 = new TestBean("test1");
+		var bean2 = new TestBean("test2");
+		var bean3 = new TestBean("test3");
+		store.addBean(TestBean.class, bean1, "name1");
+		store.addBean(TestBean.class, bean2, "name2");
+		store.addBean(TestBean.class, bean3, null);
+
+		var result = store.getBeansOfType(TestBean.class);
+		assertEquals(3, result.size());
+		assertSame(bean1, result.get("name1"));
+		assertSame(bean2, result.get("name2"));
+		assertSame(bean3, result.get(""));
+	}
+
+	@Test
+	void i05_getBeansOfType_withParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean1 = new TestBean("parent1");
+		var parentBean2 = new TestBean("parent2");
+		parent.addBean(TestBean.class, parentBean1, "name1");
+		parent.addBean(TestBean.class, parentBean2, "name2");
+
+		var store = new BasicBeanStore(parent);
+		var result = store.getBeansOfType(TestBean.class);
+		assertEquals(2, result.size());
+		assertSame(parentBean1, result.get("name1"));
+		assertSame(parentBean2, result.get("name2"));
+	}
+
+	@Test
+	void i06_getBeansOfType_childOverridesParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean, "name1");
+
+		var store = new BasicBeanStore(parent);
+		var childBean = new TestBean("child");
+		store.addBean(TestBean.class, childBean, "name1");
+
+		var result = store.getBeansOfType(TestBean.class);
+		assertEquals(1, result.size());
+		assertSame(childBean, result.get("name1"));
+	}
+
+	@Test
+	void i07_getBeansOfType_childAndParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean1 = new TestBean("parent1");
+		var parentBean2 = new TestBean("parent2");
+		parent.addBean(TestBean.class, parentBean1, "name1");
+		parent.addBean(TestBean.class, parentBean2, "name2");
+
+		var store = new BasicBeanStore(parent);
+		var childBean = new TestBean("child");
+		store.addBean(TestBean.class, childBean, "name3");
+
+		var result = store.getBeansOfType(TestBean.class);
+		assertEquals(3, result.size());
+		assertSame(parentBean1, result.get("name1"));
+		assertSame(parentBean2, result.get("name2"));
+		assertSame(childBean, result.get("name3"));
+	}
+
+	@Test
+	void i08_getBeansOfType_differentTypes() {
+		var store = new BasicBeanStore(null);
+		var testBean = new TestBean("test1");
+		var anotherBean = new AnotherBean(42);
+		store.addBean(TestBean.class, testBean);
+		store.addBean(AnotherBean.class, anotherBean);
+
+		var testResult = store.getBeansOfType(TestBean.class);
+		assertEquals(1, testResult.size());
+		assertSame(testBean, testResult.get(""));
+
+		var anotherResult = store.getBeansOfType(AnotherBean.class);
+		assertEquals(1, anotherResult.size());
+		assertSame(anotherBean, anotherResult.get(""));
+	}
+
+	//====================================================================================================
+	// hasBean(Class)
+	//====================================================================================================
+
+	@Test
+	void j01_hasBean_unnamed_notFound() {
+		var store = new BasicBeanStore(null);
+		assertFalse(store.hasBean(TestBean.class));
+	}
+
+	@Test
+	void j02_hasBean_unnamed_found() {
+		var store = new BasicBeanStore(null);
+		store.addBean(TestBean.class, new TestBean("test1"));
+		assertTrue(store.hasBean(TestBean.class));
+	}
+
+	@Test
+	void j03_hasBean_unnamed_onlyNamedExists() {
+		var store = new BasicBeanStore(null);
+		store.addBean(TestBean.class, new TestBean("test1"), "name1");
+		assertFalse(store.hasBean(TestBean.class));
+	}
+
+	@Test
+	void j04_hasBean_unnamed_withParent() {
+		var parent = new BasicBeanStore(null);
+		parent.addBean(TestBean.class, new TestBean("parent"));
+
+		var store = new BasicBeanStore(parent);
+		assertTrue(store.hasBean(TestBean.class));
+	}
+
+	@Test
+	void j05_hasBean_unnamed_childOverridesParent() {
+		var parent = new BasicBeanStore(null);
+		parent.addBean(TestBean.class, new TestBean("parent"));
+
+		var store = new BasicBeanStore(parent);
+		store.addBean(TestBean.class, new TestBean("child"));
+		assertTrue(store.hasBean(TestBean.class));
+	}
+
+	@Test
+	void j06_hasBean_unnamed_notInCurrentButInParent() {
+		var parent = new BasicBeanStore(null);
+		parent.addBean(TestBean.class, new TestBean("parent"));
+
+		var store = new BasicBeanStore(parent);
+		// Store has no beans, but parent does
+		// This should hit line 259: return nn(parent) && parent.hasBean(beanType);
+		assertTrue(store.hasBean(TestBean.class));
+	}
+
+	@Test
+	void j07_hasBean_unnamed_noParentAndNotFound() {
+		var store = new BasicBeanStore(null);
+		// No beans, no parent - should hit line 259 with parent=null
+		assertFalse(store.hasBean(TestBean.class));
+	}
+
+	//====================================================================================================
+	// hasBean(Class, String)
+	//====================================================================================================
+
+	@Test
+	void k01_hasBean_named_notFound() {
+		var store = new BasicBeanStore(null);
+		assertFalse(store.hasBean(TestBean.class, "name1"));
+	}
+
+	@Test
+	void k02_hasBean_named_found() {
+		var store = new BasicBeanStore(null);
+		store.addBean(TestBean.class, new TestBean("test1"), "name1");
+		assertTrue(store.hasBean(TestBean.class, "name1"));
+	}
+
+	@Test
+	void k03_hasBean_named_nullName() {
+		var store = new BasicBeanStore(null);
+		store.addBean(TestBean.class, new TestBean("test1"), null);
+		assertTrue(store.hasBean(TestBean.class, null));
+	}
+
+	@Test
+	void k04_hasBean_named_emptyString() {
+		var store = new BasicBeanStore(null);
+		store.addBean(TestBean.class, new TestBean("test1"), "");
+		assertTrue(store.hasBean(TestBean.class, ""));
+	}
+
+	@Test
+	void k05_hasBean_named_withParent() {
+		var parent = new BasicBeanStore(null);
+		parent.addBean(TestBean.class, new TestBean("parent"), "name1");
+
+		var store = new BasicBeanStore(parent);
+		assertTrue(store.hasBean(TestBean.class, "name1"));
+	}
+
+	@Test
+	void k06_hasBean_named_childOverridesParent() {
+		var parent = new BasicBeanStore(null);
+		parent.addBean(TestBean.class, new TestBean("parent"), "name1");
+
+		var store = new BasicBeanStore(parent);
+		store.addBean(TestBean.class, new TestBean("child"), "name1");
+		assertTrue(store.hasBean(TestBean.class, "name1"));
+	}
+
+	@Test
+	void k07_hasBean_named_notInCurrentButInParent() {
+		var parent = new BasicBeanStore(null);
+		parent.addBean(TestBean.class, new TestBean("parent"), "name1");
+
+		var store = new BasicBeanStore(parent);
+		// Store has no beans, but parent does
+		// This should hit line 280: return nn(parent) && parent.hasBean(beanType, name);
+		assertTrue(store.hasBean(TestBean.class, "name1"));
+	}
+
+	@Test
+	void k08_hasBean_named_typeMapExistsButKeyNotFound() {
+		var store = new BasicBeanStore(null);
+		// Add a bean with different name - this creates the typeMap but not the requested key
+		store.addBean(TestBean.class, new TestBean("test1"), "name1");
+
+		// hasBean should return false since "name2" doesn't exist
+		// This should hit line 277: if (typeMap.containsKey(key)) - false branch
+		assertFalse(store.hasBean(TestBean.class, "name2"));
+	}
+
+	@Test
+	void k09_hasBean_named_noParentAndNotFound() {
+		var store = new BasicBeanStore(null);
+		// No beans, no parent - should hit line 280 with parent=null
+		assertFalse(store.hasBean(TestBean.class, "name1"));
+	}
+
+	//====================================================================================================
+	// clear()
+	//====================================================================================================
+
+	@Test
+	void m01_clear() {
+		var store = new BasicBeanStore(null);
+		store.addBean(TestBean.class, new TestBean("test1"));
+		store.addBean(TestBean.class, new TestBean("test2"), "name1");
+		store.addBean(AnotherBean.class, new AnotherBean(42));
+
+		store.clear();
+
+		assertFalse(store.hasBean(TestBean.class));
+		assertFalse(store.hasBean(TestBean.class, "name1"));
+		assertFalse(store.hasBean(AnotherBean.class));
+	}
+
+	@Test
+	void m02_clear_returnsThis() {
+		var store = new BasicBeanStore(null);
+		var result = store.clear();
+		assertSame(store, result);
+	}
+
+	@Test
+	void m03_clear_doesNotAffectParent() {
+		var parent = new BasicBeanStore(null);
+		parent.addBean(TestBean.class, new TestBean("parent"));
+
+		var store = new BasicBeanStore(parent);
+		store.addBean(TestBean.class, new TestBean("child"));
+		store.clear();
+
+		assertTrue(parent.hasBean(TestBean.class));
+		// After clearing, hasBean() checks parent, so it should return true
+		assertTrue(store.hasBean(TestBean.class));
+		// But getBean() should return the parent's bean
+		assertTrue(store.getBean(TestBean.class).isPresent());
+	}
+
+	//====================================================================================================
+	// Thread safety
+	//====================================================================================================
+
+	@Test
+	void n01_concurrentAccess() throws InterruptedException {
+		var store = new BasicBeanStore(null);
+		var threads = new Thread[10];
+		var exceptions = Collections.synchronizedList(new ArrayList<Exception>());
+
+		// Start threads that add beans
+		for (int i = 0; i < 5; i++) {
+			final int index = i;
+			threads[i] = new Thread(() -> {
+				try {
+					for (int j = 0; j < 100; j++) {
+						store.addBean(TestBean.class, new TestBean("test" + index + "-" + j), "name" + index);
+					}
+				} catch (Exception e) {
+					exceptions.add(e);
+				}
+			});
+		}
+
+		// Start threads that read beans
+		for (int i = 5; i < 10; i++) {
+			final int index = i - 5;
+			threads[i] = new Thread(() -> {
+				try {
+					for (int j = 0; j < 100; j++) {
+						store.getBean(TestBean.class, "name" + index);
+						store.hasBean(TestBean.class, "name" + index);
+						store.getBeansOfType(TestBean.class);
+					}
+				} catch (Exception e) {
+					exceptions.add(e);
+				}
+			});
+		}
+
+		// Start all threads
+		for (var thread : threads) {
+			thread.start();
+		}
+
+		// Wait for all threads to complete
+		for (var thread : threads) {
+			thread.join();
+		}
+
+		// Verify no exceptions occurred
+		assertTrue(exceptions.isEmpty(), "Exceptions occurred: " + exceptions);
+	}
+
+	//====================================================================================================
+	// getBeanSupplier(Class)
+	//====================================================================================================
+
+	@Test
+	void o01_getBeanSupplier_unnamed_notFound() {
+		var store = new BasicBeanStore(null);
+		var result = store.getBeanSupplier(TestBean.class);
+		assertFalse(result.isPresent());
+	}
+
+	@Test
+	void o02_getBeanSupplier_unnamed_found() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean);
+
+		var result = store.getBeanSupplier(TestBean.class);
+		assertTrue(result.isPresent());
+		var supplier = result.get();
+		assertNotNull(supplier);
+		assertSame(bean, supplier.get());
+	}
+
+	@Test
+	void o03_getBeanSupplier_unnamed_typeMapExistsButSupplierNull() {
+		var store = new BasicBeanStore(null);
+		// Add a named bean - this creates the typeMap but no "" key
+		store.addBean(TestBean.class, new TestBean("test1"), "name1");
+
+		var result = store.getBeanSupplier(TestBean.class);
+		assertFalse(result.isPresent());
+	}
+
+	@Test
+	void o04_getBeanSupplier_unnamed_withParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean);
+
+		var store = new BasicBeanStore(parent);
+		var result = store.getBeanSupplier(TestBean.class);
+		assertTrue(result.isPresent());
+		var supplier = result.get();
+		assertSame(parentBean, supplier.get());
+	}
+
+	@Test
+	void o05_getBeanSupplier_unnamed_childOverridesParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean);
+
+		var store = new BasicBeanStore(parent);
+		var childBean = new TestBean("child");
+		store.addBean(TestBean.class, childBean);
+
+		var result = store.getBeanSupplier(TestBean.class);
+		assertTrue(result.isPresent());
+		var supplier = result.get();
+		assertSame(childBean, supplier.get());
+	}
+
+	@Test
+	void o06_getBeanSupplier_unnamed_noParentAndNotFound() {
+		var store = new BasicBeanStore(null);
+		// No beans, no parent - should hit line 304
+		var result = store.getBeanSupplier(TestBean.class);
+		assertFalse(result.isPresent());
+	}
+
+	//====================================================================================================
+	// getBeanSupplier(Class, String)
+	//====================================================================================================
+
+	@Test
+	void p01_getBeanSupplier_named_notFound() {
+		var store = new BasicBeanStore(null);
+		var result = store.getBeanSupplier(TestBean.class, "name1");
+		assertFalse(result.isPresent());
+	}
+
+	@Test
+	void p02_getBeanSupplier_named_found() {
+		var store = new BasicBeanStore(null);
+		var bean = new TestBean("test1");
+		store.addBean(TestBean.class, bean, "name1");
+
+		var result = store.getBeanSupplier(TestBean.class, "name1");
+		assertTrue(result.isPresent());
+		var supplier = result.get();
+		assertNotNull(supplier);
+		assertSame(bean, supplier.get());
+	}
+
+	@Test
+	void p03_getBeanSupplier_named_typeMapExistsButSupplierNull() {
+		var store = new BasicBeanStore(null);
+		// Add a bean with different name - this creates the typeMap but not the requested key
+		store.addBean(TestBean.class, new TestBean("test1"), "name1");
+
+		var result = store.getBeanSupplier(TestBean.class, "name2");
+		assertFalse(result.isPresent());
+	}
+
+	@Test
+	void p04_getBeanSupplier_named_withParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean, "name1");
+
+		var store = new BasicBeanStore(parent);
+		var result = store.getBeanSupplier(TestBean.class, "name1");
+		assertTrue(result.isPresent());
+		var supplier = result.get();
+		assertSame(parentBean, supplier.get());
+	}
+
+	@Test
+	void p05_getBeanSupplier_named_childOverridesParent() {
+		var parent = new BasicBeanStore(null);
+		var parentBean = new TestBean("parent");
+		parent.addBean(TestBean.class, parentBean, "name1");
+
+		var store = new BasicBeanStore(parent);
+		var childBean = new TestBean("child");
+		store.addBean(TestBean.class, childBean, "name1");
+
+		var result = store.getBeanSupplier(TestBean.class, "name1");
+		assertTrue(result.isPresent());
+		var supplier = result.get();
+		assertSame(childBean, supplier.get());
+	}
+
+	@Test
+	void p06_getBeanSupplier_named_noParentAndNotFound() {
+		var store = new BasicBeanStore(null);
+		// No beans, no parent - should hit line 330
+		var result = store.getBeanSupplier(TestBean.class, "name1");
+		assertFalse(result.isPresent());
+	}
+
+	//====================================================================================================
+	// toString()
+	//====================================================================================================
+
+	@Test
+	void q01_toString() {
+		var store = new BasicBeanStore(null);
+		store.addBean(TestBean.class, new TestBean("test1"), "name1");
+		store.addBean(AnotherBean.class, new AnotherBean(42));
+
+		var result = store.toString();
+		assertNotNull(result);
+		assertFalse(result.isEmpty());
+		// Should contain some representation of the store
+		assertTrue(result.contains("BasicBeanStore") || result.contains("entries") || result.length() > 0);
+	}
+
+	@Test
+	void q02_toString_withParent() {
+		var parent = new BasicBeanStore(null);
+		parent.addBean(TestBean.class, new TestBean("parent"));
+
+		var store = new BasicBeanStore(parent);
+		store.addBean(AnotherBean.class, new AnotherBean(42));
+
+		var result = store.toString();
+		assertNotNull(result);
+		assertFalse(result.isEmpty());
+	}
+}
+
diff --git a/juneau-utest/src/test/java/org/apache/juneau/cp/BeanStore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/cp/BeanStore_Test.java
index 9cd00271a0..7c55c51415 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/cp/BeanStore_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/cp/BeanStore_Test.java
@@ -29,6 +29,7 @@ import java.util.function.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.annotation.Named;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.reflect.*;
 import org.junit.jupiter.api.*;
 
@@ -51,7 +52,7 @@ class BeanStore_Test extends TestBase {
 
 	public static final String A1n = A1.class.getSimpleName();  // NOSONAR
 
-	public static class A3 extends BasicBeanStore {
+	public static class A3 extends BasicBeanStore2 {
 		protected A3(Builder builder) {
 			super(builder);
 		}
@@ -61,30 +62,30 @@ class BeanStore_Test extends TestBase {
 	private static A2 a2a = new A2();
 
 	@Test void a00_dummy() {
-		assertDoesNotThrow(BasicBeanStore.Void::new);
+		assertDoesNotThrow(BasicBeanStore2.Void::new);
 	}
 
 	@Test void a01_builderCopyConstructor() {
-		var b1p = BasicBeanStore.create().readOnly().threadSafe().build();
-		var b1c = BasicBeanStore.create().parent(b1p).build();
+		var b1p = BasicBeanStore2.create().readOnly().threadSafe().build();
+		var b1c = BasicBeanStore2.create().parent(b1p).build();
 		assertContains("readOnly=true", b1c.toString());
 		assertContains("threadSafe=true", b1c.toString());
 	}
 
 	@Test void a02_readOnly() {
-		var b1p = BasicBeanStore.create().readOnly().build();
-		var b1c = BasicBeanStore.create().parent(b1p).build();
-		var b2p = BasicBeanStore.create().readOnly().threadSafe().build();
-		var b2c = BasicBeanStore.create().parent(b1p).threadSafe().build();
+		var b1p = BasicBeanStore2.create().readOnly().build();
+		var b1c = BasicBeanStore2.create().parent(b1p).build();
+		var b2p = BasicBeanStore2.create().readOnly().threadSafe().build();
+		var b2c = BasicBeanStore2.create().parent(b1p).threadSafe().build();
 
 		for (var b : array(b1p, b2p)) {
-			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore is read-only.", ()->b.add(A1.class, a1a));
-			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore is read-only.", ()->b.add(A1.class, a1a, "foo"));
-			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore is read-only.", ()->b.addBean(A1.class, a1a));
-			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore is read-only.", ()->b.addBean(A1.class, a1a, "foo"));
-			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore is read-only.", ()->b.addSupplier(A1.class, ()->a1a));
-			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore is read-only.", ()->b.addSupplier(A1.class, ()->a1a, "foo"));
-			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore is read-only.", b::clear);
+			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore2 is read-only.", ()->b.add(A1.class, a1a));
+			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore2 is read-only.", ()->b.add(A1.class, a1a, "foo"));
+			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore2 is read-only.", ()->b.addBean(A1.class, a1a));
+			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore2 is read-only.", ()->b.addBean(A1.class, a1a, "foo"));
+			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore2 is read-only.", ()->b.addSupplier(A1.class, ()->a1a));
+			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore2 is read-only.", ()->b.addSupplier(A1.class, ()->a1a, "foo"));
+			assertThrowsWithMessage(IllegalStateException.class, "Method cannot be used because BasicBeanStore2 is read-only.", b::clear);
 		}
 
 		for (var b : array(b1c, b2c)) {
@@ -99,10 +100,10 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void a04_addBean() {
-		var b1p = BasicBeanStore.create().build();
-		var b1c = BasicBeanStore.of(b1p);
-		var b2p = BasicBeanStore.create().threadSafe().build();
-		var b2c = BasicBeanStore.create().threadSafe().parent(b2p).build();
+		var b1p = BasicBeanStore2.create().build();
+		var b1c = BasicBeanStore2.of(b1p);
+		var b2p = BasicBeanStore2.create().threadSafe().build();
+		var b2c = BasicBeanStore2.create().threadSafe().parent(b2p).build();
 
 		for (var b : array(b1p, b1c, b2p, b2c)) {
 			assertFalse(b.hasBean(A1.class));
@@ -142,7 +143,7 @@ class BeanStore_Test extends TestBase {
 //		for (var b : array(b1p, b1c, b2p, b2c)) {
 //			assertTrue(b.hasBean(A1.class));
 //			assertEquals(a1b, b.getBean(A1.class).get());
-//			assertList(b.stream(A1.class).map(BasicBeanStore.Entry::get), a1b, a1a);
+//			assertList(b.stream(A1.class).map(BasicBeanStore2.Entry::get), a1b, a1a);
 //		}
 //
 //		b1c.add(A2.class, a2a);
@@ -155,7 +156,7 @@ class BeanStore_Test extends TestBase {
 //		for (var b : array(b1c, b2c)) {
 //			assertTrue(b.hasBean(A2.class));
 //			assertEquals(a2a, b.getBean(A2.class).get());
-//			assertList(b.stream(A2.class).map(BasicBeanStore.Entry::get), a2a);
+//			assertList(b.stream(A2.class).map(BasicBeanStore2.Entry::get), a2a);
 //		}
 //
 //		assertMatchesGlob("{entries=[{type=A1,bean="+Utils.id(a1b)+"},{type=A1,bean="+Utils.id(a1a)+"}],identity=*}", b1p);
@@ -176,7 +177,7 @@ class BeanStore_Test extends TestBase {
 //		for (var b : array(b1c, b2c)) {
 //			assertTrue(b.hasBean(A1.class));
 //			assertEquals(a1a, b.getBean(A1.class).get());
-//			assertList(b.stream(A1.class).map(BasicBeanStore.Entry::get), a1a);
+//			assertList(b.stream(A1.class).map(BasicBeanStore2.Entry::get), a1a);
 //		}
 //
 //		b1c.removeBean(A1.class);
@@ -189,10 +190,10 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void a05_addNamedBeans() {
-		var b1p = BasicBeanStore.create().build();
-		var b1c = BasicBeanStore.of(b1p);
-		var b2p = BasicBeanStore.create().threadSafe().build();
-		var b2c = BasicBeanStore.create().threadSafe().parent(b2p).build();
+		var b1p = BasicBeanStore2.create().build();
+		var b1c = BasicBeanStore2.of(b1p);
+		var b2p = BasicBeanStore2.create().threadSafe().build();
+		var b2c = BasicBeanStore2.create().threadSafe().parent(b2p).build();
 
 		for (var b : array(b1p, b2p)) {
 			b.addBean(A1.class, a1a).addBean(A1.class, a1b, "foo").addBean(A1.class, a1c, "bar").addBean(A1.class, a1d, "bar").addBean(A2.class, a2a, "foo");
@@ -202,10 +203,10 @@ class BeanStore_Test extends TestBase {
 		}
 
 //		for (var b : array(b1p, b2p)) {
-//			assertList(b.stream(A1.class).map(BasicBeanStore.Entry::get), a1d,a1c,a1b,a1a);
+//			assertList(b.stream(A1.class).map(BasicBeanStore2.Entry::get), a1d,a1c,a1b,a1a);
 //		}
 //		for (var b : array(b1c, b2c)) {
-//			assertList(b.stream(A1.class).map(BasicBeanStore.Entry::get), a1e,a1d,a1c,a1b,a1a);
+//			assertList(b.stream(A1.class).map(BasicBeanStore2.Entry::get), a1e,a1d,a1c,a1b,a1a);
 //		}
 //
 		for (var b : array(b1p, b1c, b2p, b2c)) {
@@ -228,9 +229,9 @@ class BeanStore_Test extends TestBase {
 	public static class B1 {
 		A1 a1;
 		Optional<A2> a2;
-		BasicBeanStore a3;
+		BasicBeanStore2 a3;
 
-		public B1(A1 a1, Optional<A2> a2, BasicBeanStore a3) {
+		public B1(A1 a1, Optional<A2> a2, BasicBeanStore2 a3) {
 			this.a1 = a1;
 			this.a2 = a2;
 			this.a3 = a3;
@@ -241,7 +242,7 @@ class BeanStore_Test extends TestBase {
 			this.a2 = a2;
 		}
 
-		public void m1(A1 a1, Optional<A2> a2, BasicBeanStore a3) {
+		public void m1(A1 a1, Optional<A2> a2, BasicBeanStore2 a3) {
 			this.a1 = a1;
 			this.a2 = a2;
 			this.a3 = a3;
@@ -253,7 +254,7 @@ class BeanStore_Test extends TestBase {
 			this.a3 = null;
 		}
 
-		public static B1 m3(A1 a1, Optional<A2> a2, BasicBeanStore a3) {
+		public static B1 m3(A1 a1, Optional<A2> a2, BasicBeanStore2 a3) {
 			return new B1(a1, a2, a3);
 		}
 	}
@@ -261,20 +262,20 @@ class BeanStore_Test extends TestBase {
 	@Test void b01_getParams() {
 
 		Predicate<Object> pEmptyOptional = x -> !((Optional<?>)x).isPresent();
-		Predicate<Object> pIsBeanStore = BasicBeanStore.class::isInstance;
+		Predicate<Object> pIsBeanStore = BasicBeanStore2.class::isInstance;
 		Predicate<Object> pNull = x -> x == null;
 		Predicate<Object> pA1a = x -> x==a1a;
 		Predicate<Object> pA2a = x -> ((Optional<?>)x).get()==a2a;
 
 		var outer = new B1(null, null, null);
 
-		var b1p = BasicBeanStore.create().build().addBean(B1.class, outer);
-		var b1c = BasicBeanStore.create().parent(b1p).build();
-		var b2p = BasicBeanStore.create().threadSafe().build().addBean(B1.class, outer);
-		var b2c = BasicBeanStore.create().parent(b1p).threadSafe().build();
+		var b1p = BasicBeanStore2.create().build().addBean(B1.class, outer);
+		var b1c = BasicBeanStore2.create().parent(b1p).build();
+		var b2p = BasicBeanStore2.create().threadSafe().build().addBean(B1.class, outer);
+		var b2c = BasicBeanStore2.create().parent(b1p).threadSafe().build();
 
 		var ci = ClassInfo.of(B1.class);
-		var c1 = ci.getPublicConstructor(x -> x.hasParameterTypes(A1.class, Optional.class, BasicBeanStore.class)).get();
+		var c1 = ci.getPublicConstructor(x -> x.hasParameterTypes(A1.class, Optional.class, BasicBeanStore2.class)).get();
 		var c2 = ci.getPublicConstructor(x -> x.hasParameterTypes(A1.class, Optional.class)).get();
 		var m1 = ci.getPublicMethod(x-> x.hasName("m1")).get();
 		var m2 = ci.getPublicMethod(x-> x.hasName("m2")).get();
@@ -379,9 +380,9 @@ class BeanStore_Test extends TestBase {
 	public class B2 {
 		A1 a1;
 		Optional<A2> a2;
-		BasicBeanStore a3;
+		BasicBeanStore2 a3;
 
-		public B2(A1 a1, Optional<A2> a2, BasicBeanStore a3) {
+		public B2(A1 a1, Optional<A2> a2, BasicBeanStore2 a3) {
 			this.a1 = a1;
 			this.a2 = a2;
 			this.a3 = a3;
@@ -396,19 +397,19 @@ class BeanStore_Test extends TestBase {
 	@Test void b02_getParams_innerClass() {
 
 		Predicate<Object> pEmptyOptional = x -> !((Optional<?>)x).isPresent();
-		Predicate<Object> pIsBeanStore = BasicBeanStore.class::isInstance;
+		Predicate<Object> pIsBeanStore = BasicBeanStore2.class::isInstance;
 		Predicate<Object> pNull = x -> x == null;
 		Predicate<Object> pThis = x -> x == this;
 		Predicate<Object> pA1a = x -> x==a1a;
 		Predicate<Object> pA2a = x -> ((Optional<?>)x).get()==a2a;
 
-		var b1p = BasicBeanStore.create().build().addBean(BeanStore_Test.class, this);
-		var b1c = BasicBeanStore.create().parent(b1p).build();
-		var b2p = BasicBeanStore.create().threadSafe().build().addBean(BeanStore_Test.class, this);
-		var b2c = BasicBeanStore.create().parent(b1p).threadSafe().build();
+		var b1p = BasicBeanStore2.create().build().addBean(BeanStore_Test.class, this);
+		var b1c = BasicBeanStore2.create().parent(b1p).build();
+		var b2p = BasicBeanStore2.create().threadSafe().build().addBean(BeanStore_Test.class, this);
+		var b2c = BasicBeanStore2.create().parent(b1p).threadSafe().build();
 
 		var ci = ClassInfo.of(B2.class);
-		var c1 = ci.getPublicConstructor(x -> x.hasParameterTypes(BeanStore_Test.class, A1.class, Optional.class, BasicBeanStore.class)).get();
+		var c1 = ci.getPublicConstructor(x -> x.hasParameterTypes(BeanStore_Test.class, A1.class, Optional.class, BasicBeanStore2.class)).get();
 		var c2 = ci.getPublicConstructor(x -> x.hasParameterTypes(BeanStore_Test.class, A1.class, Optional.class)).get();
 
 		for (var b : array(b1p, b1c, b2p, b2c)) {
@@ -488,7 +489,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void c00_createMethodFinder_invalidArgs() {
-		var b = BasicBeanStore.create().build();
+		var b = BasicBeanStore2.create().build();
 //		assertThrowsWithMessage(IllegalArgumentException.class, "Method cannot be used without outer bean definition.", ()->new BeanCreateMethodFinder<>(null, b));
 		assertThrowsWithMessage(IllegalArgumentException.class, "Argument 'beanType' cannot be null.", ()->new BeanCreateMethodFinder<>((Class<?>)null, "", b));
 		assertThrowsWithMessage(IllegalArgumentException.class, "Argument 'resourceClass' cannot be null.", ()->new BeanCreateMethodFinder<>(String.class, null, b));
@@ -523,7 +524,7 @@ class BeanStore_Test extends TestBase {
 		public static C createC3(Optional<A1> a) { C e = new C(); e.a = a.orElse(null); return e; }
 		public static C createC4(@Named("Foo") A1 a) { return new C(); }
 		public static C createC5(@Named("Foo") Optional<A1> a) { C e = new C(); e.a = a.orElse(null); return e; }
-		public static C createC6(BasicBeanStore bs) { assertNotNull(bs); return new C(); }
+		public static C createC6(BasicBeanStore2 bs) { assertNotNull(bs); return new C(); }
 	}
 
 
@@ -535,7 +536,7 @@ class BeanStore_Test extends TestBase {
 	public class D1b {}
 
 	@Test void d01_createBean_basic() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertNotNull(BeanCreator.of(D1a.class, bs).outer(this).run());
 		assertNotNull(BeanCreator.of(D1b.class, bs).outer(this).run());
 		assertThrows(IllegalArgumentException.class, () -> BeanCreator.of(null, bs).outer(this).run());
@@ -547,7 +548,7 @@ class BeanStore_Test extends TestBase {
 	public static D2 d2 = new D2();
 
 	@Test void d02_createBean_staticCreator_create() {
-		var bs = BasicBeanStore.INSTANCE;
+		var bs = BasicBeanStore2.INSTANCE;
 		assertEquals(d2, BeanCreator.of(D2.class, bs).run());
 	}
 
@@ -557,7 +558,7 @@ class BeanStore_Test extends TestBase {
 	public static D3 d3 = new D3() {};
 
 	@Test void d03_createBean_staticCreator_getInstance() {
-		var bs = BasicBeanStore.INSTANCE;
+		var bs = BasicBeanStore2.INSTANCE;
 		assertEquals(d3, BeanCreator.of(D3.class, bs).run());
 	}
 
@@ -583,7 +584,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d04_createBean_staticCreator_invalidSignatures() {
-		var bs = BasicBeanStore.INSTANCE;
+		var bs = BasicBeanStore2.INSTANCE;
 		assertNotEqualsAny(BeanCreator.of(D4a.class, bs).run(), d4a1, d4a2, d4a3, d4a4);
 		assertNotEqualsAny(BeanCreator.of(D4b.class, bs).run(), d4b1, d4b2);
 		assertNotNull(BeanCreator.of(D4c.class, bs).run());
@@ -598,7 +599,7 @@ class BeanStore_Test extends TestBase {
 	public static D5 d5a = new D5(), d5b = new D5(), d5c = new D5();
 
 	@Test void d05_createBean_staticCreator_withBeans() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertEquals(d5a, BeanCreator.of(D5.class, bs).run());
 		bs.add(Integer.class, 1);
 		assertEquals(d5c, BeanCreator.of(D5.class, bs).run());
@@ -615,7 +616,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d06_createBean_staticCreator_ignoredWithBuilder() {
-		var bs = BasicBeanStore.INSTANCE;
+		var bs = BasicBeanStore2.INSTANCE;
 		assertString("1", BeanCreator.of(D6.class, bs).builder(String.class, "1").run().s);
 	}
 
@@ -626,7 +627,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d07_createBean_staticCreator_withOptional() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertString("X", BeanCreator.of(D7.class, bs).run().a);
 		bs.add(String.class, "bar");
 		assertString("bar", BeanCreator.of(D7.class, bs).run().a);
@@ -639,7 +640,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d08_createBean_staticCreator_missingPrereqs() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class org.apache.juneau.cp.BeanStore_Test$D8: Static creator found but could not find prerequisites: Integer.", ()->BeanCreator.of(D8.class, bs).run());
 		bs.add(Integer.class, 1);
 		assertString("null,1", BeanCreator.of(D8.class, bs).run().a);
@@ -654,7 +655,7 @@ class BeanStore_Test extends TestBase {
 	public interface D9b {}
 
 	@Test void d09_createBean_staticCreator_withBeans() {
-		var bs = BasicBeanStore.INSTANCE;
+		var bs = BasicBeanStore2.INSTANCE;
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D9a.class.getName()+": Class is abstract.", ()->BeanCreator.of(D9a.class, bs).run());
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D9b.class.getName()+": Class is an interface.", ()->BeanCreator.of(D9b.class, bs).run());
 	}
@@ -667,7 +668,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d10_createBean_constructors_public() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D10.class.getName()+": Public constructor found but could not find prerequisites: Integer or Integer,String or String.", ()->BeanCreator.of(D10.class, bs).run());
 		bs.add(String.class, "foo");
 		assertString("s=foo", BeanCreator.of(D10.class, bs).run().a);
@@ -683,7 +684,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d11_createBean_constructors_protected() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D11.class.getName()+": Protected constructor found but could not find prerequisites: Integer or Integer,String or String.", ()->BeanCreator.of(D11.class, bs).run());
 		bs.add(String.class, "foo");
 		assertString("s=foo", BeanCreator.of(D11.class, bs).run().a);
@@ -698,7 +699,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d12_createBean_constructors_publicOverProtected() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D12.class.getName()+": Public constructor found but could not find prerequisites: String.", ()->BeanCreator.of(D12.class, bs).run());
 		bs.add(String.class, "foo");
 		bs.add(Integer.class, 1);
@@ -710,7 +711,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d13_createBean_constructors_private() {
-		var bs = BasicBeanStore.INSTANCE;
+		var bs = BasicBeanStore2.INSTANCE;
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D13.class.getName()+": No public/protected constructors found.", ()->BeanCreator.of(D13.class, bs).run());
 	}
 
@@ -721,7 +722,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d14_createBean_constructors_namedBean() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D14.class.getName()+": Public constructor found but could not find prerequisites: Integer,String@foo or String@foo.", ()->BeanCreator.of(D14.class, bs).run());
 		bs.add(String.class, "bar", "foo");
 		assertString("bar", BeanCreator.of(D14.class, bs).run().a);
@@ -734,7 +735,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d15_createBean_constructors_namedBean_withOuter() {
-		var bs = BasicBeanStore.create().build().addBean(BeanStore_Test.class, new BeanStore_Test());
+		var bs = BasicBeanStore2.create().build().addBean(BeanStore_Test.class, new BeanStore_Test());
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D15.class.getName()+": Public constructor found but could not find prerequisites: Integer,String@foo or String@foo.", ()->BeanCreator.of(D15.class, bs).run());
 		bs.add(String.class, "bar", "foo");
 		assertString("bar", BeanCreator.of(D15.class, bs).run().a);
@@ -750,7 +751,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d16_createBean_builders() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		var b = D16.create();
 		b.b = "foo";
 		assertString("foo", BeanCreator.of(D16.class, bs).builder(D16.Builder.class, b).run().a);
@@ -769,7 +770,7 @@ class BeanStore_Test extends TestBase {
 	}
 
 	@Test void d17_createBean_builders_inherent() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		assertNull(BeanCreator.<D17>of(D17.class, bs).run().a);
 		assertThrowsWithMessage(ExecutableException.class, "Could not instantiate class "+D17.class.getName()+": Protected constructor found but could not find prerequisites: Builder or Builder,Integer or Integer.", ()->BeanCreator.<D17>of(D17.class, bs).builder(Boolean.class, true).run());
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/cp/FileFinder_Test.java b/juneau-utest/src/test/java/org/apache/juneau/cp/FileFinder_Test.java
index 2fe05026c5..429101d184 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/cp/FileFinder_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/cp/FileFinder_Test.java
@@ -26,6 +26,7 @@ import java.nio.file.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.io.*;
 import org.apache.juneau.cp.sub.*;
 import org.junit.jupiter.api.*;
@@ -658,7 +659,7 @@ public class FileFinder_Test extends TestBase {  // NOSONAR - Needs to be public
 
 	public static class E03a extends FileFinder.Builder {
 		protected E03a() {
-			super(BasicBeanStore.INSTANCE);
+			super(BasicBeanStore2.INSTANCE);
 		}
 	}
 	public static class E03b extends BasicFileFinder {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/mstat/MethodExecStore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/mstat/MethodExecStore_Test.java
index 91254b44fe..10f4df219d 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/mstat/MethodExecStore_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/mstat/MethodExecStore_Test.java
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.stats.*;
 import org.junit.jupiter.api.*;
@@ -77,7 +78,7 @@ class MethodExecStore_Test extends TestBase {
 	}
 
 	@Test void a05_builder_beanFactory() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 
 		assertThrowsWithMessage(Exception.class, "Public constructor found but could not find prerequisites: A5a", ()->MethodExecStore.create(bs).type(A5b.class).build());
 		assertInstanceOf(A5c.class, MethodExecStore.create(bs).type(A5c.class).build());
@@ -106,7 +107,7 @@ class MethodExecStore_Test extends TestBase {
 	}
 
 	@Test public void a06_builder_statsImplClass() throws Exception {  // NOSONAR - Must be public.
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 		var m = MethodExecStore_Test.class.getMethod("a06_builder_statsImplClass");
 
 		assertThrowsWithMessage(Exception.class, "Public constructor found but could not find prerequisites: A6a", ()->MethodExecStore.create(bs).statsImplClass(A6b.class).build().getStats(m));
@@ -127,7 +128,7 @@ class MethodExecStore_Test extends TestBase {
 		assertSame(s, store.getThrownStore());
 
 		var s2 = ThrownStore.create().build();
-		var bs = BasicBeanStore.create().build().addBean(ThrownStore.class, s2);
+		var bs = BasicBeanStore2.create().build().addBean(ThrownStore.class, s2);
 		store = MethodExecStore.create(bs).build();
 		assertSame(s2, store.getThrownStore());
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/mstat/ThrownStore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/mstat/ThrownStore_Test.java
index b80c18ff88..9e120d324c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/mstat/ThrownStore_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/mstat/ThrownStore_Test.java
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.stats.*;
 import org.junit.jupiter.api.*;
@@ -223,7 +224,7 @@ class ThrownStore_Test extends TestBase {
 	}
 
 	@Test void b05_builder_beanFactory() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 
 		assertThrowsWithMessage(Exception.class, "Public constructor found but could not find prerequisites: B5a", ()->ThrownStore.create(bs).type(B5b.class).build());
 		assertInstanceOf(B5c.class, ThrownStore.create(bs).type(B5c.class).build());
@@ -252,7 +253,7 @@ class ThrownStore_Test extends TestBase {
 	}
 
 	@Test void b06_statsImplClass() {
-		var bs = BasicBeanStore.create().build();
+		var bs = BasicBeanStore2.create().build();
 
 		var t1 = new Throwable();
 		t1.fillInStackTrace();
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_Builder_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_Builder_Test.java
index 1115169ef4..8f68e29cd7 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_Builder_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_Builder_Test.java
@@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.Named;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.client.*;
@@ -37,23 +38,23 @@ class RestContext_Builder_Test extends TestBase {
 
 	@Rest
 	public static class A1 {
-		@RestInject static BasicBeanStore beanStore;
+		@RestInject static BasicBeanStore2 beanStore;
 	}
 
 	@Test void a01_createBeanStore_default() {
 		MockRestClient.buildLax(A1.class);
-		assertEquals("BasicBeanStore", A1.beanStore.getClass().getSimpleName());
+		assertEquals("BasicBeanStore2", A1.beanStore.getClass().getSimpleName());
 	}
 
-	public static class MyBeanStore extends BasicBeanStore {
+	public static class MyBeanStore extends BasicBeanStore2 {
 		protected MyBeanStore(Builder builder) {
-			super(builder.parent(BasicBeanStore.create().build().addBean(A.class, new A())));
+			super(builder.parent(BasicBeanStore2.create().build().addBean(A.class, new A())));
 		}
 	}
 
 	@Rest(beanStore=MyBeanStore.class)
 	public static class A2 {
-		@RestInject static BasicBeanStore beanStore;
+		@RestInject static BasicBeanStore2 beanStore;
 	}
 
 	@Test void a02_createBeanStore_annotation() {
@@ -63,9 +64,9 @@ class RestContext_Builder_Test extends TestBase {
 
 	@Rest
 	public static class A3 {
-		@RestInject static BasicBeanStore beanStore;
+		@RestInject static BasicBeanStore2 beanStore;
 
-		@RestInject BasicBeanStore.Builder beanStore(BasicBeanStore.Builder b) {
+		@RestInject BasicBeanStore2.Builder beanStore(BasicBeanStore2.Builder b) {
 			return b.type(MyBeanStore.class);
 		}
 	}
@@ -77,10 +78,10 @@ class RestContext_Builder_Test extends TestBase {
 
 	@Rest
 	public static class A4 {
-		@RestInject static BasicBeanStore beanStore;
+		@RestInject static BasicBeanStore2 beanStore;
 
-		@RestInject BasicBeanStore beanStore() {
-			return BasicBeanStore.create().type(MyBeanStore.class).build();
+		@RestInject BasicBeanStore2 beanStore() {
+			return BasicBeanStore2.create().type(MyBeanStore.class).build();
 		}
 	}
 
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
index 1ca23787db..2af79e28f0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/Swagger_Test.java
@@ -25,6 +25,7 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.commons.lang.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.annotation.*;
@@ -67,7 +68,7 @@ class Swagger_Test extends TestBase {
 	public static class TestClasspathFileFinder extends BasicStaticFiles {
 
 		public TestClasspathFileFinder() {
-			super(StaticFiles.create(BasicBeanStore.INSTANCE).cp(Swagger_Test.class, null, false));
+			super(StaticFiles.create(BasicBeanStore2.INSTANCE).cp(Swagger_Test.class, null, false));
 		}
 
 		@Override /* FileFinder */
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestAnnotation_Test.java
index f36c34af26..2121201d4a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestAnnotation_Test.java
@@ -21,6 +21,7 @@ import static org.apache.juneau.junit.bct.BctAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.encoders.*;
 import org.apache.juneau.httppart.*;
@@ -50,7 +51,7 @@ class RestAnnotation_Test extends TestBase {
 		.allowedHeaderParams("b")
 		.allowedMethodHeaders("c")
 		.allowedMethodParams("d")
-		.beanStore(BasicBeanStore.class)
+		.beanStore(BasicBeanStore2.class)
 		.callLogger(CallLogger.class)
 		.children(RestAnnotation_Test.class)
 		.clientVersionHeader("e")
@@ -101,7 +102,7 @@ class RestAnnotation_Test extends TestBase {
 		.allowedHeaderParams("b")
 		.allowedMethodHeaders("c")
 		.allowedMethodParams("d")
-		.beanStore(BasicBeanStore.class)
+		.beanStore(BasicBeanStore2.class)
 		.callLogger(CallLogger.class)
 		.children(RestAnnotation_Test.class)
 		.clientVersionHeader("e")
@@ -150,7 +151,7 @@ class RestAnnotation_Test extends TestBase {
 	@Test void a01_basic() {
 		assertBean(a1,
 			"allowedHeaderParams,allowedMethodHeaders,allowedMethodParams,beanStore,callLogger,children,clientVersionHeader,config,consumes,converters,debug,debugEnablement,debugOn,defaultAccept,defaultCharset,defaultContentType,defaultRequestAttributes,defaultRequestHeaders,defaultResponseHeaders,description,disableContentParam,encoders,guards,maxInput,messages,on,onClass,parsers,partParser,partSerializer,path,produces,renderResponseStackTraces,responseProcessors,restChildrenClass,restOpArgs,rol [...]
-			"b,c,d,BasicBeanStore,CallLogger,[RestAnnotation_Test],e,f,[g],[RestConverter],h,DebugEnablement,i,j,k,l,[m],[n],[o],[p],a,[Encoder],[RestGuard],q,r,[s],[RestAnnotation_Test],[Parser],HttpPartParser,HttpPartSerializer,t,[u],v,[ResponseProcessor],RestChildren,[RestOpArg],w,x,[Serializer],y,StaticFiles,{{[],,,},[],{[],},{[],,},[],[],[],[],},BasicSwaggerProvider,[z],aa,bb,cc,dd");
+			"b,c,d,BasicBeanStore2,CallLogger,[RestAnnotation_Test],e,f,[g],[RestConverter],h,DebugEnablement,i,j,k,l,[m],[n],[o],[p],a,[Encoder],[RestGuard],q,r,[s],[RestAnnotation_Test],[Parser],HttpPartParser,HttpPartSerializer,t,[u],v,[ResponseProcessor],RestChildren,[RestOpArg],w,x,[Serializer],y,StaticFiles,{{[],,,},[],{[],},{[],,},[],[],[],[],},BasicSwaggerProvider,[z],aa,bb,cc,dd");
 	}
 
 	@Test void a02_testEquivalency() {
@@ -199,7 +200,7 @@ class RestAnnotation_Test extends TestBase {
 		allowedHeaderParams="b",
 		allowedMethodHeaders="c",
 		allowedMethodParams="d",
-		beanStore=BasicBeanStore.class,
+		beanStore=BasicBeanStore2.class,
 		callLogger=CallLogger.class,
 		children=RestAnnotation_Test.class,
 		clientVersionHeader="e",
@@ -252,7 +253,7 @@ class RestAnnotation_Test extends TestBase {
 		allowedHeaderParams="b",
 		allowedMethodHeaders="c",
 		allowedMethodParams="d",
-		beanStore=BasicBeanStore.class,
+		beanStore=BasicBeanStore2.class,
 		callLogger=CallLogger.class,
 		children=RestAnnotation_Test.class,
 		clientVersionHeader="e",
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringBeanStore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringBeanStore_Test.java
index 7773d99656..ea9c179fdd 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringBeanStore_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringBeanStore_Test.java
@@ -25,7 +25,7 @@ class SpringBeanStore_Test extends TestBase {
 
 	@Test
 	void a01_fluentChaining_clear() {
-		// Test that clear() returns SpringBeanStore (not BasicBeanStore)
+		// Test that clear() returns SpringBeanStore (not BasicBeanStore2)
 		var store = new SpringBeanStore(opte(), opte(), null);
 
 		SpringBeanStore result = store.clear();