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 2025/11/07 13:48:42 UTC

(juneau) 01/03: Utility class modernization

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

commit 3ac06387940265bae6eb2747a14ce85100b49f3b
Author: James Bognar <ja...@salesforce.com>
AuthorDate: Fri Nov 7 08:27:15 2025 -0500

    Utility class modernization
---
 .../juneau/common/reflect/AnnotationInfo.java      |  109 +-
 .../juneau/common/reflect/AnnotationList.java      |   92 -
 .../juneau/common/reflect/ClassInfo.java.bak       | 2506 --------------------
 .../java/org/apache/juneau/AnnotationWorkList.java |   11 +-
 .../src/main/java/org/apache/juneau/Context.java   |   10 +-
 .../rest/client/remote/RemoteOperationMeta.java    |   24 +-
 .../rest/client/remote/RemoteOperationReturn.java  |    6 +-
 .../org/apache/juneau/http/remote/RemoteUtils.java |    5 +-
 .../java/org/apache/juneau/rest/RestContext.java   |    4 +-
 .../java/org/apache/juneau/rest/RestOpContext.java |   21 +-
 .../juneau/rest/annotation/RestOpAnnotation.java   |    5 +-
 .../juneau/rest/debug/BasicDebugEnablement.java    |   22 +-
 .../juneau/rest/matcher/ClientVersionMatcher.java  |    2 +-
 .../rest/swagger/BasicSwaggerProviderSession.java  |    8 +-
 .../annotation/BeanConfigAnnotation_Test.java      |    6 +-
 .../org/apache/juneau/annotation/Bean_Test.java    |   12 +-
 .../juneau/common/reflect/AnnotationInfoTest.java  |    2 +-
 .../juneau/common/reflect/ClassInfo_Test.java      |   29 +-
 .../juneau/common/reflect/MethodInfo_Test.java     |   12 +-
 .../juneau/csv/annotation/CsvConfig_Test.java      |    8 +-
 .../juneau/html/HtmlConfigAnnotation_Test.java     |   12 +-
 .../juneau/html/HtmlDocConfigAnnotation_Test.java  |   28 +-
 .../juneau/json/JsonConfigAnnotationTest.java      |   12 +-
 .../jsonschema/JsonSchemaConfigAnnotationTest.java |    6 +-
 .../juneau/jsonschema/JsonSchemaGeneratorTest.java |    2 +-
 .../msgpack/MsgPackConfigAnnotationTest.java       |   12 +-
 .../juneau/oapi/OpenApiConfigAnnotation_Test.java  |    8 +-
 .../juneau/parser/ParserConfigAnnotationTest.java  |   12 +-
 .../plaintext/PlainTextConfigAnnotation_Test.java  |    8 +-
 .../client/RestClient_Config_Context_Test.java     |    2 +-
 .../serializer/SerializerConfigAnnotationTest.java |   12 +-
 .../juneau/soap/SoapXmlConfigAnnotationTest.java   |    6 +-
 .../apache/juneau/uon/UonConfigAnnotationTest.java |   12 +-
 .../UrlEncodingConfigAnnotationTest.java           |   12 +-
 .../apache/juneau/xml/XmlConfigAnnotationTest.java |   12 +-
 35 files changed, 176 insertions(+), 2874 deletions(-)

diff --git a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
index 39f4601155..960b139673 100644
--- a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
+++ b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
@@ -70,6 +70,18 @@ public class AnnotationInfo<T extends Annotation> {
 		this.rank = findRank(a);
 	}
 
+	/**
+	 * Returns the rank of this annotation.
+	 * 
+	 * <p>
+	 * The rank is used for sorting annotations in order of precedence.
+	 * 
+	 * @return The rank of this annotation.
+	 */
+	public int getRank() {
+		return rank;
+	}
+
 	/**
 	 * Performs an action on all matching values on this annotation.
 	 *
@@ -352,47 +364,6 @@ public class AnnotationInfo<T extends Annotation> {
 				}
 	}
 
-	/**
-	 * Constructs an {@link AnnotationList} of all annotations found on the specified class.
-	 *
-	 * <p>
-	 * Annotations are appended in the following orders:
-	 * <ol>
-	 * 	<li>On the package of this class.
-	 * 	<li>On interfaces ordered parent-to-child.
-	 * 	<li>On parent classes ordered parent-to-child.
-	 * 	<li>On this class.
-	 * </ol>
-	 *
-	 * @param classInfo The class to process.
-	 * @return A new {@link AnnotationList} object on every call.
-	 */
-	public static AnnotationList getAnnotationList(ClassInfo classInfo) {
-		return getAnnotationList(classInfo, x -> true);
-	}
-
-	/**
-	 * Constructs an {@link AnnotationList} of all matching annotations on the specified class.
-	 *
-	 * <p>
-	 * Annotations are appended in the following orders:
-	 * <ol>
-	 * 	<li>On the package of this class.
-	 * 	<li>On interfaces ordered parent-to-child.
-	 * 	<li>On parent classes ordered parent-to-child.
-	 * 	<li>On this class.
-	 * </ol>
-	 *
-	 * @param classInfo The class to process.
-	 * @param filter A predicate to apply to the entries to determine if value should be used.  Can be <jk>null</jk>.
-	 * @return A new {@link AnnotationList} object on every call.
-	 */
-	public static AnnotationList getAnnotationList(ClassInfo classInfo, Predicate<AnnotationInfo<?>> filter) {
-		var l = new AnnotationList();
-		forEachAnnotationInfo(classInfo, filter, x -> l.add(x));
-		return l;
-	}
-
 	//-----------------------------------------------------------------------------------------------------------------
 	// Static methods for MethodInfo
 	//-----------------------------------------------------------------------------------------------------------------
@@ -420,62 +391,6 @@ public class AnnotationInfo<T extends Annotation> {
 		}
 	}
 
-	/**
-	 * Constructs an {@link AnnotationList} of all annotations found on the specified method.
-	 *
-	 * <p>
-	 * Annotations are appended in the following orders:
-	 * <ol>
-	 * 	<li>On the package of this class.
-	 * 	<li>On interfaces ordered parent-to-child.
-	 * 	<li>On parent classes ordered parent-to-child.
-	 * 	<li>On this class.
-	 * 	<li>On this method and matching methods ordered parent-to-child.
-	 * </ol>
-	 *
-	 * @param methodInfo The method to process.
-	 * @return A new {@link AnnotationList} object on every call.
-	 */
-	public static AnnotationList getAnnotationList(MethodInfo methodInfo) {
-		return getAnnotationList(methodInfo, x -> true);
-	}
-
-	/**
-	 * Constructs an {@link AnnotationList} of all matching annotations found on the specified method.
-	 *
-	 * <p>
-	 * Annotations are appended in the following orders:
-	 * <ol>
-	 * 	<li>On the package of this class.
-	 * 	<li>On interfaces ordered parent-to-child.
-	 * 	<li>On parent classes ordered parent-to-child.
-	 * 	<li>On this class.
-	 * 	<li>On this method and matching methods ordered parent-to-child.
-	 * </ol>
-	 *
-	 * @param methodInfo The method to process.
-	 * @param filter A predicate to apply to the entries to determine if value should be added.  Can be <jk>null</jk>.
-	 * @return A new {@link AnnotationList} object on every call.
-	 */
-	public static AnnotationList getAnnotationList(MethodInfo methodInfo, Predicate<AnnotationInfo<?>> filter) {
-		var al = new AnnotationList();
-		forEachAnnotationInfo(methodInfo, filter, x -> al.add(x));
-		return al;
-	}
-
-	/**
-	 * Same as {@link #getAnnotationList(MethodInfo, Predicate)} except only returns annotations defined on methods.
-	 *
-	 * @param methodInfo The method to process.
-	 * @param filter A predicate to apply to the entries to determine if value should be added.  Can be <jk>null</jk>.
-	 * @return A new {@link AnnotationList} object on every call.
-	 */
-	public static AnnotationList getAnnotationListMethodOnly(MethodInfo methodInfo, Predicate<AnnotationInfo<?>> filter) {
-		var al = new AnnotationList();
-		forEachAnnotationInfoMethodOnly(methodInfo, filter, x -> al.add(x));
-		return al;
-	}
-
 	/**
 	 * Performs an action on all matching annotations on methods only.
 	 *
diff --git a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationList.java b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationList.java
deleted file mode 100644
index 9be5e22bdf..0000000000
--- a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationList.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.common.reflect;
-
-import static org.apache.juneau.common.utils.PredicateUtils.*;
-
-import java.lang.annotation.*;
-import java.util.*;
-import java.util.function.*;
-
-/**
- * An ordered list of annotations and the classes/methods/packages they were found on.
- *
- * <h5 class='section'>See Also:</h5><ul>
- * </ul>
- *
- * @serial exclude
- */
-public class AnnotationList extends ArrayList<AnnotationInfo<?>> {
-	private static final long serialVersionUID = 1L;
-
-	private static final Comparator<AnnotationInfo<?>> RANK_COMPARATOR = (o1, o2) -> o1.rank - o2.rank;
-
-	/**
-	 * Performs an action on all matching annotations in this list.
-	 *
-	 * @param <A> The annotation type.
-	 * @param type The annotation type.
-	 * @param filter A predicate to apply to the entries to determine if action should be performed.  Can be <jk>null</jk>.
-	 * @param action An action to perform on the entry.
-	 * @return This object.
-	 */
-	@SuppressWarnings("unchecked")
-	public <A extends Annotation> AnnotationList forEach(Class<A> type, Predicate<AnnotationInfo<A>> filter, Consumer<AnnotationInfo<A>> action) {
-		forEach(x -> {
-			if (x.isType(type))
-				consumeIf(filter, action, (AnnotationInfo<A>)x);
-		});
-		return this;
-	}
-
-	/**
-	 * Performs an action on all matching annotations in this list.
-	 *
-	 * @param filter A predicate to apply to the entries to determine if action should be performed.  Can be <jk>null</jk>.
-	 * @param action An action to perform on the entry.
-	 * @return This object.
-	 */
-	public AnnotationList forEach(Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> action) {
-		forEach(x -> consumeIf(filter, action, x));
-		return this;
-	}
-
-	/**
-	 * Performs an action on the specified matching values from all annotations in this list.
-	 *
-	 * @param <T> The annotation value type.
-	 * @param type The annotation value type.
-	 * @param name The annotation value name.
-	 * @param filter A predicate to apply to the value to determine if action should be performed.  Can be <jk>null</jk>.
-	 * @param action An action to perform on the value.
-	 * @return This object.
-	 */
-	public <T> AnnotationList forEachValue(Class<T> type, String name, Predicate<T> filter, Consumer<T> action) {
-		forEach(x -> x.forEachValue(type, name, filter, action));
-		return this;
-	}
-
-	/**
-	 * Sort the annotations in this list based on rank.
-	 *
-	 * @return This object.
-	 */
-	public AnnotationList sort() {
-		Collections.sort(this, RANK_COMPARATOR);
-		return this;
-	}
-}
\ No newline at end of file
diff --git a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ClassInfo.java.bak b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ClassInfo.java.bak
deleted file mode 100644
index 487f559316..0000000000
--- a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ClassInfo.java.bak
+++ /dev/null
@@ -1,2506 +0,0 @@
-/*
- * 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.common.reflect;
-
-import static org.apache.juneau.common.utils.AssertionUtils.*;
-import static org.apache.juneau.common.utils.ClassUtils.*;
-import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.PredicateUtils.*;
-import static org.apache.juneau.common.utils.ThrowableUtils.*;
-import static org.apache.juneau.common.utils.Utils.*;
-import static org.apache.juneau.common.reflect.ClassNameFormat.*;
-import static org.apache.juneau.common.reflect.ClassArrayFormat.*;
-import static java.util.stream.Collectors.*;
-import static java.util.stream.Stream.*;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.security.*;
-import java.util.*;
-import java.util.function.*;
-import java.util.stream.*;
-
-import org.apache.juneau.common.collections.*;
-
-/**
- * Lightweight utility class for introspecting information about a class.
- *
- * <p>
- * Provides various convenience methods for introspecting fields/methods/annotations
- * that aren't provided by the standard Java reflection APIs.
- *
- * <p>
- * Objects are designed to be lightweight to create and threadsafe.
- *
- * <h5 class='figure'>Example:</h5>
- * <p class='bjava'>
- * 	<jc>// Wrap our class inside a ClassInfo.</jc>
- * 	ClassInfo <jv>classInfo</jv> = ClassInfo.<jsm>of</jsm>(MyClass.<jk>class</jk>);
- *
- * 	<jc>// Get all methods in parent-to-child order, sorted alphabetically per class.</jc>
- * 	<jk>for</jk> (MethodInfo <jv>methodInfo</jv> : <jv>classInfo</jv>.getAllMethods()) {
- * 		<jc>// Do something with it.</jc>
- * 	}
- *
- * 	<jc>// Get all class-level annotations in parent-to-child order.</jc>
- * 	<jk>for</jk> (MyAnnotation <jv>annotation</jv> : <jv>classInfo</jv>.getAnnotations(MyAnnotation.<jk>class</jk>)) {
- * 		<jc>// Do something with it.</jc>
- * 	}
- * </p>
- *
- * <h5 class='section'>See Also:</h5><ul>
- * </ul>
- */
-@SuppressWarnings({"unchecked","rawtypes"})
-public class ClassInfo extends ElementInfo implements Annotatable {
-
-	private static final Cache<Class,ClassInfo> CACHE = Cache.of(Class.class, ClassInfo.class).build();
-
-	/** Reusable ClassInfo for Object class. */
-	public static final ClassInfo OBJECT = ClassInfo.of(Object.class);
-
-	private static final Map<Class<?>,Class<?>> pmap1 = new HashMap<>(), pmap2 = new HashMap<>();
-
-	static {
-		pmap1.put(boolean.class, Boolean.class);
-		pmap1.put(byte.class, Byte.class);
-		pmap1.put(short.class, Short.class);
-		pmap1.put(char.class, Character.class);
-		pmap1.put(int.class, Integer.class);
-		pmap1.put(long.class, Long.class);
-		pmap1.put(float.class, Float.class);
-		pmap1.put(double.class, Double.class);
-		pmap2.put(Boolean.class, boolean.class);
-		pmap2.put(Byte.class, byte.class);
-		pmap2.put(Short.class, short.class);
-		pmap2.put(Character.class, char.class);
-		pmap2.put(Integer.class, int.class);
-		pmap2.put(Long.class, long.class);
-		pmap2.put(Float.class, float.class);
-		pmap2.put(Double.class, double.class);
-	}
-
-	// @formatter:off
-	private static final Map<Class,Object> primitiveDefaultMap =
-		mapb(Class.class,Object.class)
-			.unmodifiable()
-			.add(Boolean.TYPE, false)
-			.add(Character.TYPE, (char)0)
-			.add(Short.TYPE, (short)0)
-			.add(Integer.TYPE, 0)
-			.add(Long.TYPE, 0L)
-			.add(Float.TYPE, 0f)
-			.add(Double.TYPE, 0d)
-			.add(Byte.TYPE, (byte)0)
-			.add(Boolean.class, false)
-			.add(Character.class, (char)0)
-			.add(Short.class, (short)0)
-			.add(Integer.class, 0)
-			.add(Long.class, 0L)
-			.add(Float.class, 0f)
-			.add(Double.class, 0d)
-			.add(Byte.class, (byte)0)
-			.build();
-	// @formatter:on
-
-	/**
-	 * Returns a class info wrapper around the specified class type.
-	 *
-	 * @param c The class type.
-	 * @return The constructed class info, or <jk>null</jk> if the type was <jk>null</jk>.
-	 */
-	public static ClassInfo of(Class<?> c) {
-		if (c == null)
-			return null;
-		return CACHE.get(c, () -> new ClassInfo(c, c));
-	}
-
-	/**
-	 * Returns a class info wrapper around the specified class type.
-	 *
-	 * @param c The class type.
-	 * @param t The generic type (if parameterized type).
-	 * @return The constructed class info, or <jk>null</jk> if the type was <jk>null</jk>.
-	 */
-	public static ClassInfo of(Class<?> c, Type t) {
-		if (c == t)
-			return of(c);
-		return new ClassInfo(c, t);
-	}
-
-	/**
-	 * Same as using the constructor, but operates on an object instance.
-	 *
-	 * @param o The class instance.
-	 * @return The constructed class info, or <jk>null</jk> if the object was <jk>null</jk>.
-	 */
-	public static ClassInfo of(Object o) {
-		return of(o == null ? null : o instanceof Class ? (Class<?>)o : o.getClass());
-	}
-
-	/**
-	 * Returns a class info wrapper around the specified class type.
-	 *
-	 * @param t The class type.
-	 * @return The constructed class info, or <jk>null</jk> if the type was <jk>null</jk>.
-	 */
-	public static ClassInfo of(Type t) {
-		if (t == null)
-			return null;
-		if (t instanceof Class)
-			return of((Class<?>)t);
-		return new ClassInfo(toClass(t), t);
-	}
-
-	/**
-	 * Same as {@link #of(Object)} but attempts to deproxify the object if it's wrapped in a CGLIB proxy.
-	 *
-	 * @param o The class instance.
-	 * @return The constructed class info, or <jk>null</jk> if the object was <jk>null</jk>.
-	 */
-	public static ClassInfo ofProxy(Object o) {
-		if (o == null)
-			return null;
-		Class<?> c = getProxyFor(o);
-		return c == null ? ClassInfo.of(o) : ClassInfo.of(c);
-	}
-
-	// The underlying Type object (may be Class, ParameterizedType, GenericArrayType, etc.).
-	private final Type t;
-
-	// The underlying Class object (null for non-class types like TypeVariable).  Effectively final.
-	private Class<?> c;
-
-	// True if this represents a ParameterizedType (e.g., List<String>).
-	private final boolean isParameterizedType;
-
-	// Number of array dimensions (0 if not an array).
-	private final Supplier<Integer> dimensions = memoize(this::findDimensions);
-
-	// Base component type for arrays (e.g., String for String[][]), also handles GenericArrayType.  Cached and never null.
-	private final Supplier<ClassInfo> componentType = memoize(this::findComponentType);
-
-	// The package this class belongs to (null for primitive types and arrays).
-	private final Supplier<PackageInfo> packageInfo = memoize(() -> opt(c).map(x -> PackageInfo.of(x.getPackage())).orElse(null));
-
-	// All superclasses of this class in child-to-parent order, starting with this class.
-	private final Supplier<List<ClassInfo>> parents = memoize(this::findParents);
-
-	// All annotations declared directly on this class, wrapped in AnnotationInfo.
-	private final Supplier<List<AnnotationInfo>> declaredAnnotations2 = memoize(() -> (List)opt(c).map(x -> u(l(x.getDeclaredAnnotations()))).orElse(liste()).stream().map(a -> AnnotationInfo.of(this, a)).toList());
-
-	// Fully qualified class name with generics (e.g., "java.util.List<java.lang.String>").
-	private final Supplier<String> fullName = memoize(() -> getNameFormatted(FULL, true, '$', BRACKETS));
-
-	// Simple class name with generics (e.g., "List<String>").
-	private final Supplier<String> shortName = memoize(() -> getNameFormatted(SHORT, true, '$', BRACKETS));
-
-	// Human-readable class name without generics (e.g., "List").
-	private final Supplier<String> readableName = memoize(() -> getNameFormatted(SIMPLE, false, '$', WORD));
-
-	// All interfaces declared directly by this class.
-	private final Supplier<List<ClassInfo>> declaredInterfaces = memoize(() -> opt(c).map(x -> stream(x.getInterfaces()).map(ClassInfo::of).toList()).orElse(liste()));
-
-	// All interfaces implemented by this class and its parents, in child-to-parent order.
-	private final Supplier<List<ClassInfo>> interfaces = memoize(() -> getParents().stream().flatMap(x -> x.getDeclaredInterfaces().stream()).flatMap(ci2 -> concat(Stream.of(ci2), ci2.getInterfaces().stream())).distinct().toList());
-
-	// All parent classes and interfaces, classes first, then in child-to-parent order.
-	// TODO - Determine if this field is still needed now that we have parentsAndInterfaces which handles the hierarchy better.
-	private final Supplier<List<ClassInfo>> allParents = memoize(() -> concat(getParents().stream(), getInterfaces().stream()).toList());
-
-	// All parent classes and interfaces with proper traversal of interface hierarchy to avoid duplicates.
-	private final Supplier<List<ClassInfo>> parentsAndInterfaces = memoize(this::findParentsAndInterfaces);
-
-	/**
-	 * Finds all parent classes and interfaces with proper traversal of interface hierarchy.
-	 *
-	 * @return A list of all parent classes and interfaces without duplicates.
-	 */
-	private List<ClassInfo> findParentsAndInterfaces() {
-		var set = new LinkedHashSet<ClassInfo>();
-
-		// Process all parent classes (includes this class)
-		var parents = getParents();
-		for (int i = 0; i < parents.size(); i++) {
-			var parent = parents.get(i);
-			set.add(parent);
-
-			// Process interfaces declared on this parent (and their parent interfaces)
-			var declaredInterfaces = parent.getDeclaredInterfaces();
-			for (int j = 0; j < declaredInterfaces.size(); j++)
-				addInterfaceHierarchy(set, declaredInterfaces.get(j));
-		}
-
-		return u(new ArrayList<>(set));
-	}
-
-	/**
-	 * Helper method to recursively add an interface and its parent interfaces to the set.
-	 *
-	 * @param set The set to add to.
-	 * @param iface The interface to add.
-	 */
-	private void addInterfaceHierarchy(LinkedHashSet<ClassInfo> set, ClassInfo iface) {
-		if (!set.add(iface))
-			return;
-
-		// Process parent interfaces recursively
-		var parentInterfaces = iface.getDeclaredInterfaces();
-		for (int i = 0; i < parentInterfaces.size(); i++)
-			addInterfaceHierarchy(set, parentInterfaces.get(i));
-	}
-
-	/**
-	 * Finds all annotations on this class and parent classes/interfaces in child-to-parent order.
-	 *
-	 * <p>
-	 * This is similar to {@link org.apache.juneau.common.reflect.AnnotationProvider2#find(Class)} but without runtime annotations.
-	 *
-	 * <p>
-	 * Order of traversal:
-	 * <ol>
-	 * 	<li>Annotations declared on this class
-	 * 	<li>Annotations declared on parent classes (child-to-parent order)
-	 * 	<li>For each parent class, annotations on interfaces declared on that class (child-to-parent interface hierarchy)
-	 * 	<li>Annotations on the package of this class
-	 * </ol>
-	 *
-	 * @return A list of all annotation infos in child-to-parent order.
-	 */
-	private List<AnnotationInfo<Annotation>> findAnnotationInfos() {
-		var list = new ArrayList<AnnotationInfo<Annotation>>();
-
-		// On all parent classes and interfaces (properly traversed to avoid duplicates)
-		var parentsAndInterfaces = getParentsAndInterfaces();
-		for (int i = 0; i < parentsAndInterfaces.size(); i++) {
-			var ci = parentsAndInterfaces.get(i);
-			// Add declared annotations from this class/interface
-			for (var a : ci.inner().getDeclaredAnnotations())
-				for (var a2 : splitRepeated(a))
-					list.add(AnnotationInfo.of(ci, a2));
-		}
-
-		// On the package of this class
-		var pkg = getPackage();
-		if (nn(pkg)) {
-			var pi = PackageInfo.of(pkg.inner());
-			for (var a : pkg.inner().getAnnotations())
-				for (var a2 : splitRepeated(a))
-					list.add(AnnotationInfo.of(pi, a2));
-		}
-
-		return u(list);
-	}
-
-	// All annotations on this class and parent classes/interfaces in child-to-parent order.
-	private final Supplier<List<AnnotationInfo<Annotation>>> annotationInfos = memoize(this::findAnnotationInfos);
-
-	// All record components if this is a record class (Java 14+).
-	private final Supplier<List<RecordComponent>> recordComponents = memoize(() -> opt(c).filter(Class::isRecord).map(x -> u(l(x.getRecordComponents()))).orElse(liste()));
-
-	// All generic interface types (e.g., List<String> implements Comparable<List<String>>).
-	private final Supplier<List<Type>> genericInterfaces = memoize(() -> opt(c).map(x -> u(l(x.getGenericInterfaces()))).orElse(liste()));
-
-	// All type parameters declared on this class (e.g., <T, U> in class Foo<T, U>).
-	private final Supplier<List<TypeVariable<?>>> typeParameters = memoize(() -> opt(c).map(x -> u(l((TypeVariable<?>[])x.getTypeParameters()))).orElse(liste()));
-
-	// All annotated interface types with their annotations.
-	private final Supplier<List<AnnotatedType>> annotatedInterfaces = memoize(() -> opt(c).map(x -> u(l(x.getAnnotatedInterfaces()))).orElse(liste()));
-
-	// All signers of this class (for signed JARs).
-	private final Supplier<List<Object>> signers = memoize(() -> opt(c).map(Class::getSigners).map(x -> u(l(x))).orElse(liste()));
-
-	// All public methods on this class and inherited, excluding Object methods.
-	private final Supplier<List<MethodInfo>> publicMethods = memoize(() -> opt(c).map(x -> stream(x.getMethods()).filter(m -> ne(m.getDeclaringClass(), Object.class)).map(this::getMethodInfo).sorted().toList()).orElse(liste()));
-
-	// All methods declared directly on this class (public, protected, package, private).
-	private final Supplier<List<MethodInfo>> declaredMethods = memoize(() -> opt(c).map(x -> stream(x.getDeclaredMethods()).filter(m -> ne("$jacocoInit", m.getName())).map(this::getMethodInfo).sorted().toList()).orElse(liste()));
-
-	// All methods from this class and all parents, in child-to-parent order.
-	private final Supplier<List<MethodInfo>> allMethods = memoize(() -> allParents.get().stream().flatMap(c -> c.getDeclaredMethods().stream()).toList());
-
-	// All methods from this class and all parents, in parent-to-child order.
-	private final Supplier<List<MethodInfo>> allMethodsParentFirst = memoize(() -> rstream(getAllParents()).flatMap(c -> c.getDeclaredMethods().stream()).toList());
-
-	// All public fields from this class and parents, deduplicated by name (child wins).
-	private final Supplier<List<FieldInfo>> publicFields = memoize(() -> parents.get().stream().flatMap(c -> c.getDeclaredFields().stream()).filter(f -> f.isPublic() && ne("$jacocoData", f.getName())).collect(toMap(FieldInfo::getName, x -> x, (a, b) -> a, LinkedHashMap::new)).values().stream().sorted().collect(toList()));
-
-	// All fields declared directly on this class (public, protected, package, private).
-	private final Supplier<List<FieldInfo>> declaredFields = memoize(() -> opt(c).map(x -> stream(x.getDeclaredFields()).filter(f -> ne("$jacocoData", f.getName())).map(this::getFieldInfo).sorted().toList()).orElse(liste()));
-
-	// All fields from this class and all parents, in parent-to-child order.
-	private final Supplier<List<FieldInfo>> allFields = memoize(() -> rstream(allParents.get()).flatMap(c -> c.getDeclaredFields().stream()).toList());
-
-	// All public constructors declared on this class.
-	private final Supplier<List<ConstructorInfo>> publicConstructors = memoize(() -> opt(c).map(x -> stream(x.getConstructors()).map(this::getConstructorInfo).sorted().toList()).orElse(liste()));
-
-	// All constructors declared on this class (public, protected, package, private).
-	private final Supplier<List<ConstructorInfo>> declaredConstructors = memoize(() -> opt(c).map(x -> stream(x.getDeclaredConstructors()).map(this::getConstructorInfo).sorted().toList()).orElse(liste()));
-
-	// The repeated annotation method (value()) if this class is a @Repeatable container.
-	private final Supplier<MethodInfo> repeatedAnnotationMethod = memoize(this::findRepeatedAnnotationMethod);
-
-	// Cache of wrapped Method objects.
-	private final Cache<Method,MethodInfo> methodCache = Cache.of(Method.class, MethodInfo.class).build();
-
-	// Cache of wrapped Field objects.
-	private final Cache<Field,FieldInfo> fieldCache = Cache.of(Field.class, FieldInfo.class).build();
-
-	// Cache of wrapped Constructor objects.
-	private final Cache<Constructor,ConstructorInfo> constructorCache = Cache.of(Constructor.class, ConstructorInfo.class).build();
-
-	/**
-	 * Constructor.
-	 *
-	 * @param c The class type.
-	 * @param t The generic type (if parameterized type).
-	 */
-	protected ClassInfo(Class<?> c, Type t) {
-		super(c == null ? 0 : c.getModifiers());
-		this.t = t;
-		this.c = c;
-		this.isParameterizedType = t == null ? false : (t instanceof ParameterizedType);
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this type can be used as a parameter for the specified object.
-	 *
-	 * @param child The argument to check.
-	 * @return <jk>true</jk> if this type can be used as a parameter for the specified object.
-	 */
-	public boolean canAcceptArg(Object child) {
-		if (c == null || child == null)
-			return false;
-		if (c.isInstance(child))
-			return true;
-		if (this.isPrimitive() || child.getClass().isPrimitive()) {
-			return this.getWrapperIfPrimitive().isAssignableFrom(of(child).getWrapperIfPrimitive());
-		}
-		return false;
-	}
-
-	@Override
-	public boolean equals(Object o) {
-		return (o instanceof ClassInfo o2) && eq(this, o2, (x, y) -> eq(x.t, y.t));
-	}
-
-
-	/**
-	 * Performs an action on all matching annotations on this class and superclasses/interfaces.
-	 *
-	 * <p>
-	 * Annotations are appended in the following orders:
-	 * <ol>
-	 * 	<li>On the package of this class.
-	 * 	<li>On interfaces ordered parent-to-child.
-	 * 	<li>On parent classes ordered parent-to-child.
-	 * 	<li>On this class.
-	 * </ol>
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param annotationProvider The annotation provider.
-	 * @param type The annotation to look for.
-	 * @param filter A predicate to apply to the entries to determine if action should be performed.  Can be <jk>null</jk>.
-	 * @param action An action to perform on the entry.
-	 * @return This object.
-	 */
-	public <A extends Annotation> ClassInfo forEachAnnotation(AnnotationProvider annotationProvider, Class<A> type, Predicate<A> filter, Consumer<A> action) {
-		if (annotationProvider == null)
-			throw unsupportedOp();
-		A t2 = getPackageAnnotation(type);
-		if (nn(t2))
-			consumeIf(filter, action, t2);
-		var interfaces2 = interfaces.get();
-		for (int i = interfaces2.size() - 1; i >= 0; i--)
-			annotationProvider.getAnnotationProvider().findDeclaredParentFirst(type, interfaces2.get(i).inner()).map(x -> x.inner()).filter(x -> filter == null || filter.test(x)).forEach(x -> action.accept(x));
-		var parents2 = parents.get();
-		for (int i = parents2.size() - 1; i >= 0; i--)
-			annotationProvider.getAnnotationProvider().findDeclaredParentFirst(type, parents2.get(i).inner()).map(x -> x.inner()).filter(x -> filter == null || filter.test(x)).forEach(x -> action.accept(x));
-		return this;
-	}
-
-	/**
-	 * Returns all fields on this class and all parent classes.
-	 *
-	 * <p>
-	 * 	Results are ordered parent-to-child, and then alphabetical per class.
-	 *
-	 * @return
-	 * 	All declared fields on this class.
-	 * 	<br>List is unmodifiable.
-	 */
-	public List<FieldInfo> getAllFields() { return allFields.get(); }
-
-	/**
-	 * Returns all declared methods on this class and all parent classes.
-	 *
-	 * @return
-	 * 	All declared methods on this class and all parent classes.
-	 * 	<br>Results are ordered parent-to-child, and then alphabetically per class.
-	 * 	<br>List is unmodifiable.
-	 */
-	public List<MethodInfo> getAllMethodsParentFirst() { return allMethodsParentFirst.get(); }
-
-	/**
-	 * Returns a list including this class and all parent classes and interfaces.
-	 *
-	 * <p>
-	 * Results are classes-before-interfaces, then child-to-parent order.
-	 *
-	 * @return An unmodifiable list including this class and all parent classes.
-	 * 	<br>Results are ordered child-to-parent order with classes listed before interfaces.
-	 */
-	public List<ClassInfo> getAllParents() { return allParents.get(); }
-
-	/**
-	 * Finds the annotation of the specified type defined on this class or parent class/interface.
-	 *
-	 * <p>
-	 * If the annotation cannot be found on the immediate class, searches methods with the same signature on the parent classes or interfaces. <br>
-	 * The search is performed in child-to-parent order.
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param annotationProvider The annotation provider.
-	 * @param type The annotation to look for.
-	 * @return The annotation if found, or <jk>null</jk> if not.
-	 */
-	public <A extends Annotation> A getAnnotation(AnnotationProvider annotationProvider, Class<A> type) {
-		return findAnnotation(annotationProvider, type);
-	}
-
-	/**
-	 * Returns all annotations of the specified type defined on this or parent classes/interfaces.
-	 *
-	 * <p>
-	 * Returns the list in reverse (parent-to-child) order.
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param annotationProvider The annotation provider.
-	 * @param type The annotation type to look for.
-	 * @return The matching annotations.
-	 */
-	public <A extends Annotation> List<A> getAnnotations(AnnotationProvider annotationProvider, Class<A> type) {
-		List<A> l = list();
-		forEachAnnotation(annotationProvider, type, x -> true, x -> l.add(x));
-		return l;
-	}
-
-	/**
-	 * Returns the {@link ClassLoader} for this class.
-	 *
-	 * <p>
-	 * If this class represents a primitive type or void, <jk>null</jk> is returned.
-	 *
-	 * @return The class loader for this class, or <jk>null</jk> if it doesn't have one.
-	 */
-	public ClassLoader getClassLoader() {
-		return c == null ? null : c.getClassLoader();
-	}
-
-	/**
-	 * Returns the base component type of this class.
-	 *
-	 * <p>
-	 * For array types (e.g., <c>String[][]</c>), returns the deepest component type (e.g., <c>String</c>).
-	 * <br>For non-array types, returns this class itself.
-	 *
-	 * <p>
-	 * <b>Note:</b> Unlike {@link Class#getComponentType()}, this method also handles generic array types (e.g., <c>List&lt;String&gt;[]</c>)
-	 * and returns the full parameterized type information (e.g., <c>List&lt;String&gt;</c>).
-	 * Additionally, this method never returns <jk>null</jk> - non-array types return <jk>this</jk> instead.
-	 *
-	 * @return The base component type of an array, or this class if not an array.
-	 */
-	public ClassInfo getComponentType() {
-		return componentType.get();
-	}
-
-	/**
-	 * Returns the {@link Class} object representing the class or interface that declares the member class
-	 * represented by this class.
-	 *
-	 * <p>
-	 * Returns <jk>null</jk> if this class is not a member class.
-	 *
-	 * @return The declaring class, or <jk>null</jk> if this class is not a member of another class.
-	 */
-	public ClassInfo getDeclaringClass() {
-		return c == null ? null : of(c.getDeclaringClass());
-	}
-
-	/**
-	 * Returns the first matching declared constructor on this class.
-	 *
-	 * @param filter A predicate to apply to the entries to determine if value should be used.  Can be <jk>null</jk>.
-	 * @return The declared constructor that matches the specified predicate.
-	 */
-	public ConstructorInfo getDeclaredConstructor(Predicate<ConstructorInfo> filter) {
-		for (var ci : declaredConstructors.get())
-			if (test(filter, ci))
-				return ci;
-		return null;
-	}
-
-	/**
-	 * Returns all the constructors defined on this class.
-	 *
-	 * @return
-	 * 	All constructors defined on this class.
-	 * 	<br>List is unmodifiable.
-	 */
-	public List<ConstructorInfo> getDeclaredConstructors() { return declaredConstructors.get(); }
-
-	/**
-	 * Returns the first matching declared field on this class.
-	 *
-	 * @param filter A predicate to apply to the entries to determine if value should be used.  Can be <jk>null</jk>.
-	 * @return The declared field, or <jk>null</jk> if not found.
-	 */
-	public FieldInfo getDeclaredField(Predicate<FieldInfo> filter) {
-		for (var f : declaredFields.get())
-			if (test(filter, f))
-				return f;
-		return null;
-	}
-
-	/**
-	 * Returns all declared fields on this class.
-	 *
-	 * @return
-	 * 	All declared fields on this class.
-	 * 	<br>Results are in alphabetical order.
-	 * 	<br>List is unmodifiable.
-	 */
-	public List<FieldInfo> getDeclaredFields() { return declaredFields.get(); }
-
-	/**
-	 * Returns all public member classes and interfaces declared by this class and its superclasses.
-	 *
-	 * <p>
-	 * This includes public class and interface members inherited from superclasses and
-	 * public class and interface members declared by the class.
-	 *
-	 * @return
-	 * 	An unmodifiable list of all public member classes and interfaces declared by this class.
-	 * 	<br>Returns an empty list if this class has no public member classes or interfaces.
-	 */
-	public List<ClassInfo> getClasses() {
-		if (c == null)
-			return u(l());
-		Class<?>[] classes = c.getClasses();
-		List<ClassInfo> l = listOfSize(classes.length);
-		for (Class<?> cc : classes)
-			l.add(of(cc));
-		return u(l);
-	}
-
-	/**
-	 * Returns all classes and interfaces declared as members of this class.
-	 *
-	 * <p>
-	 * This includes public, protected, default (package) access, and private classes and interfaces
-	 * declared by the class, but excludes inherited classes and interfaces.
-	 *
-	 * @return
-	 * 	An unmodifiable list of all classes and interfaces declared as members of this class.
-	 * 	<br>Returns an empty list if this class declares no classes or interfaces as members.
-	 */
-	public List<ClassInfo> getDeclaredClasses() {
-		if (c == null)
-			return u(l());
-		Class<?>[] classes = c.getDeclaredClasses();
-		List<ClassInfo> l = listOfSize(classes.length);
-		for (Class<?> cc : classes)
-			l.add(of(cc));
-		return u(l);
-	}
-
-	/**
-	 * Returns a list of interfaces declared on this class.
-	 *
-	 * <p>
-	 * Does not include interfaces declared on parent classes.
-	 *
-	 * <p>
-	 * Results are in the same order as Class.getInterfaces().
-	 *
-	 * @return
-	 * 	An unmodifiable list of interfaces declared on this class.
-	 * 	<br>Results are in the same order as {@link Class#getInterfaces()}.
-	 */
-	public List<ClassInfo> getDeclaredInterfaces() { return declaredInterfaces.get(); }
-
-	/**
-	 * Returns the immediately enclosing class of this class.
-	 *
-	 * <p>
-	 * Returns <jk>null</jk> if this class is a top-level class.
-	 *
-	 * @return The enclosing class, or <jk>null</jk> if this is a top-level class.
-	 */
-	public ClassInfo getEnclosingClass() {
-		return c == null ? null : of(c.getEnclosingClass());
-	}
-
-	/**
-	 * Returns the {@link ConstructorInfo} object representing the constructor that declares this class if this is a
-	 * local or anonymous class declared within a constructor.
-	 *
-	 * <p>
-	 * Returns <jk>null</jk> if this class was not declared within a constructor.
-	 *
-	 * @return The enclosing constructor, or <jk>null</jk> if this class was not declared within a constructor.
-	 */
-	public ConstructorInfo getEnclosingConstructor() {
-		if (c == null)
-			return null;
-		Constructor<?> ec = c.getEnclosingConstructor();
-		return ec == null ? null : getConstructorInfo(ec);
-	}
-
-	/**
-	 * Returns the {@link MethodInfo} object representing the method that declares this class if this is a
-	 * local or anonymous class declared within a method.
-	 *
-	 * <p>
-	 * Returns <jk>null</jk> if this class was not declared within a method.
-	 *
-	 * @return The enclosing method, or <jk>null</jk> if this class was not declared within a method.
-	 */
-	public MethodInfo getEnclosingMethod() {
-		if (c == null)
-			return null;
-		Method em = c.getEnclosingMethod();
-		return em == null ? null : getMethodInfo(em);
-	}
-
-	/**
-	 * Returns the first matching declared method on this class.
-	 *
-	 * @param filter A predicate to apply to the entries to determine if value should be used.  Can be <jk>null</jk>.
-	 * @return The first matching method, or <jk>null</jk> if no methods matched.
-	 */
-	public MethodInfo getDeclaredMethod(Predicate<MethodInfo> filter) {
-		for (var mi : declaredMethods.get())
-			if (test(filter, mi))
-				return mi;
-		return null;
-	}
-
-	/**
-	 * Returns all methods declared on this class.
-	 *
-	 * @return
-	 * 	All methods declared on this class.
-	 * 	<br>Results are ordered alphabetically.
-	 * 	<br>List is unmodifiable.
-	 */
-	public List<MethodInfo> getDeclaredMethods() { return declaredMethods.get(); }
-
-	/**
-	 * Returns the number of dimensions if this is an array type.
-	 *
-	 * @return The number of dimensions if this is an array type, or <c>0</c> if it is not.
-	 */
-	public int getDimensions() {
-		return dimensions.get();
-	}
-
-	/**
-	 * Returns the full name of this class.
-	 *
-	 * <h5 class='section'>Examples:</h5>
-	 * <ul>
-	 * 	<li><js>"com.foo.MyClass"</js> - Normal class
-	 * 	<li><js>"com.foo.MyClass[][]"</js> - Array.
-	 * 	<li><js>"com.foo.MyClass$InnerClass"</js> - Inner class.
-	 * 	<li><js>"com.foo.MyClass$InnerClass[][]"</js> - Inner class array.
-	 * 	<li><js>"int"</js> - Primitive class.
-	 * 	<li><js>"int[][]"</js> - Primitive class class.
-	 * 	<li><js>"java.util.Map&lt;java.lang.String,java.lang.Object&gt;"</js> - Parameterized type.
-	 * 	<li><js>"java.util.AbstractMap&lt;K,V&gt;"</js> - Parameterized generic type.
-	 * 	<li><js>"V"</js> - Parameterized generic type argument.
-	 * </ul>
-	 *
-	 * @return The underlying class name.
-	 */
-	public String getNameFull() {
-		return fullName.get();
-	}
-
-	/**
-	 * Returns a list of interfaces defined on this class and superclasses.
-	 *
-	 * <p>
-	 * Results are in child-to-parent order.
-	 *
-	 * @return
-	 * 	An unmodifiable list of interfaces defined on this class and superclasses.
-	 * 	<br>Results are in child-to-parent order.
-	 */
-	public List<ClassInfo> getInterfaces() { return interfaces.get(); }
-
-	/**
-	 * Returns all parent classes and interfaces in proper traversal order.
-	 *
-	 * <p>
-	 * This method returns a unique list of all parent classes (including this class) and all interfaces
-	 * (including interface hierarchies) with proper handling of duplicates. The order is:
-	 * <ol>
-	 * 	<li>This class
-	 * 	<li>Parent classes in child-to-parent order
-	 * 	<li>For each class, interfaces declared on that class and their parent interfaces
-	 * </ol>
-	 *
-	 * <p>
-	 * This is useful for annotation processing where you need to traverse the complete type hierarchy
-	 * without duplicates.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bjava'>
-	 * 	<jc>// Interface hierarchy:</jc>
-	 * 	<jk>interface</jk> ISuperGrandParent {}
-	 * 	<jk>interface</jk> IGrandParent <jk>extends</jk> ISuperGrandParent {}
-	 * 	<jk>interface</jk> ISuperParent {}
-	 * 	<jk>interface</jk> IParent <jk>extends</jk> ISuperParent {}
-	 * 	<jk>interface</jk> IChild {}
-	 *
-	 * 	<jc>// Class hierarchy:</jc>
-	 * 	<jk>class</jk> GrandParent <jk>implements</jk> IGrandParent {}
-	 * 	<jk>class</jk> Parent <jk>extends</jk> GrandParent <jk>implements</jk> IParent {}
-	 * 	<jk>class</jk> Child <jk>extends</jk> Parent <jk>implements</jk> IChild {}
-	 *
-	 * 	<jc>// For Child, returns (in this order):</jc>
-	 * 	ClassInfo <jv>ci</jv> = ClassInfo.<jsm>of</jsm>(Child.<jk>class</jk>);
-	 * 	List&lt;ClassInfo&gt; <jv>result</jv> = <jv>ci</jv>.getParentsAndInterfaces();
-	 * 	<jc>// Result: [</jc>
-	 * 	<jc>//   Child,                  // 1. This class</jc>
-	 * 	<jc>//   IChild,                 // 2. Interface on Child</jc>
-	 * 	<jc>//   Parent,                 // 3. Parent class</jc>
-	 * 	<jc>//   IParent,                // 4. Interface on Parent</jc>
-	 * 	<jc>//   ISuperParent,           // 5. Parent interface of IParent</jc>
-	 * 	<jc>//   GrandParent,            // 6. Grandparent class</jc>
-	 * 	<jc>//   IGrandParent,           // 7. Interface on GrandParent</jc>
-	 * 	<jc>//   ISuperGrandParent       // 8. Parent interface of IGrandParent</jc>
-	 * 	<jc>// ]</jc>
-	 * </p>
-	 *
-	 * @return An unmodifiable list of all parent classes and interfaces, properly ordered without duplicates.
-	 */
-	public List<ClassInfo> getParentsAndInterfaces() { return parentsAndInterfaces.get(); }
-
-	/**
-	 * Returns all annotations on this class and parent classes/interfaces in child-to-parent order.
-	 *
-	 * <p>
-	 * This returns all declared annotations from:
-	 * <ol>
-	 * 	<li>This class
-	 * 	<li>Parent classes in child-to-parent order
-	 * 	<li>For each class, interfaces declared on that class and their parent interfaces
-	 * 	<li>The package of this class
-	 * </ol>
-	 *
-	 * <p>
-	 * This does NOT include runtime annotations. For runtime annotation support, use
-	 * {@link org.apache.juneau.common.reflect.AnnotationProvider2}.
-	 *
-	 * @return An unmodifiable list of all annotation infos.
-	 */
-	public List<AnnotationInfo<Annotation>> getAnnotationInfos() { return annotationInfos.get(); }
-
-	/**
-	 * Returns all annotations of the specified type on this class and parent classes/interfaces in child-to-parent order.
-	 *
-	 * <p>
-	 * This returns all declared annotations from:
-	 * <ol>
-	 * 	<li>This class
-	 * 	<li>Parent classes in child-to-parent order
-	 * 	<li>For each class, interfaces declared on that class and their parent interfaces
-	 * 	<li>The package of this class
-	 * </ol>
-	 *
-	 * <p>
-	 * This does NOT include runtime annotations. For runtime annotation support, use
-	 * {@link org.apache.juneau.common.reflect.AnnotationProvider2}.
-	 *
-	 * @param <A> The annotation type.
-	 * @param type The annotation type to filter by.
-	 * @return A stream of annotation infos of the specified type.
-	 */
-	public <A extends Annotation> Stream<AnnotationInfo<A>> getAnnotationInfos(Class<A> type) {
-		assertArgNotNull("type", type);
-		return getAnnotationInfos().stream()
-			.filter(a -> a.isType(type))
-			.map(a -> (AnnotationInfo<A>)a);
-	}
-
-	/**
-	 * Returns the first matching method on this class.
-	 *
-	 * @param filter A predicate to apply to the entries to determine if value should be used.  Can be <jk>null</jk>.
-	 * @return The first matching method, or <jk>null</jk> if no methods matched.
-	 */
-	public MethodInfo getMethod(Predicate<MethodInfo> filter) {
-		for (var mi : allMethods.get())
-			if (test(filter, mi))
-				return mi;
-		return null;
-	}
-
-	/**
-	 * Returns all declared methods on this class and all parent classes.
-	 *
-	 * @return
-	 * 	All declared methods on this class and all parent classes.
-	 * 	<br>Results are ordered child-to-parent, and then alphabetically per class.
-	 * 	<br>List is unmodifiable.
-	 */
-	public List<MethodInfo> getMethods() { return allMethods.get(); }
-
-	/**
-	 * Returns the name of the underlying class.
-	 *
-	 * <p>
-	 * Equivalent to calling {@link Class#getName()} or {@link Type#getTypeName()} depending on whether
-	 * this is a class or type.
-	 *
-	 * <p>
-	 * This method returns the JVM internal format for class names:
-	 * <ul>
-	 * 	<li>Uses fully qualified package names
-	 * 	<li>Uses <js>'$'</js> separator for nested classes
-	 * 	<li>Uses JVM notation for arrays (e.g., <js>"[Ljava.lang.String;"</js>)
-	 * 	<li>Uses single letters for primitive arrays (e.g., <js>"[I"</js> for <c>int[]</c>)
-	 * </ul>
-	 *
-	 * <h5 class='section'>Examples:</h5>
-	 * <ul>
-	 * 	<li><js>"java.lang.String"</js> - Normal class
-	 * 	<li><js>"[Ljava.lang.String;"</js> - Array
-	 * 	<li><js>"[[Ljava.lang.String;"</js> - Multi-dimensional array
-	 * 	<li><js>"java.util.Map$Entry"</js> - Nested class
-	 * 	<li><js>"int"</js> - Primitive class
-	 * 	<li><js>"[I"</js> - Primitive array
-	 * 	<li><js>"[[I"</js> - Multi-dimensional primitive array
-	 * </ul>
-	 *
-	 * <h5 class='section'>See Also:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li><c>{@link #getNameCanonical()}</c> - Java source code format (uses <js>'.'</js> and <js>"[]"</js>)
-	 * 	<li><c>{@link #getNameSimple()}</c> - Simple class name without package
-	 * 	<li><c>{@link #getNameFull()}</c> - Full name with type parameters
-	 * 	<li><c>{@link #getNameShort()}</c> - Short name with type parameters
-	 * 	<li><c>{@link #getNameReadable()}</c> - Human-readable name (uses <js>"Array"</js> suffix)
-	 * </ul>
-	 *
-	 * @return The name of the underlying class in JVM format.
-	 */
-	public String getName() { return nn(c) ? c.getName() : t.getTypeName(); }
-
-	/**
-	 * Returns the canonical name of the underlying class.
-	 *
-	 * <p>
-	 * The canonical name is the name that would be used in Java source code to refer to the class.
-	 * For example:
-	 * <ul>
-	 * 	<li><js>"java.lang.String"</js> - Normal class
-	 * 	<li><js>"java.lang.String[]"</js> - Array
-	 * 	<li><js>"java.util.Map.Entry"</js> - Nested class
-	 * 	<li><jk>null</jk> - Local or anonymous class
-	 * </ul>
-	 *
-	 * @return The canonical name of the underlying class, or <jk>null</jk> if this class doesn't have a canonical name.
-	 */
-	public String getNameCanonical() {
-		// For Class objects, delegate to Class.getCanonicalName() which handles local/anonymous classes
-		// For Type objects (ParameterizedType, etc.), compute the canonical name
-		if (c != null && !isParameterizedType) {
-			return c.getCanonicalName();
-		}
-		// For ParameterizedType, we can't have a true canonical name with type parameters
-		// Return null to maintain consistency with Class.getCanonicalName() behavior
-		return null;
-	}
-
-	/**
-	 * Returns all possible names for this class.
-	 *
-	 * @return
-	 * 	An array consisting of:
-	 * 	<ul>
-	 * 		<li>{@link #getNameFull()}
-	 * 		<li>{@link Class#getName()} - Note that this might be a dup.
-	 * 		<li>{@link #getNameShort()}
-	 * 		<li>{@link #getNameSimple()}
-	 * 	</ul>
-	 */
-	public String[] getNames() { return a(getNameFull(), c.getName(), getNameShort(), getNameSimple()); }
-
-	/**
-	 * Returns the module that this class is a member of.
-	 *
-	 * <p>
-	 * If this class is not in a named module, returns the unnamed module of the class loader for this class.
-	 *
-	 * @return The module that this class is a member of.
-	 */
-	public Module getModule() {
-		return c == null ? null : c.getModule();
-	}
-
-	/**
-	 * Locates the no-arg constructor for this class.
-	 *
-	 * <p>
-	 * Constructor must match the visibility requirements specified by parameter 'v'.
-	 * If class is abstract, always returns <jk>null</jk>.
-	 * Note that this also returns the 1-arg constructor for non-static member classes.
-	 *
-	 * @param v The minimum visibility.
-	 * @return The constructor, or <jk>null</jk> if no no-arg constructor exists with the required visibility.
-	 */
-	public ConstructorInfo getNoArgConstructor(Visibility v) {
-		if (isAbstract())
-			return null;
-		int expectedParams = isNonStaticMemberClass() ? 1 : 0;
-		return getDeclaredConstructors().stream()
-			.filter(cc -> cc.hasNumParameters(expectedParams))
-			.filter(cc -> cc.isVisible(v))
-			.map(cc -> cc.accessible(v))
-			.findFirst()
-			.orElse(null);
-	}
-
-	/**
-	 * Returns the package of this class.
-	 *
-	 * @return The package of this class wrapped in a {@link PackageInfo}, or <jk>null</jk> if this class has no package.
-	 */
-	public PackageInfo getPackage() {
-		return packageInfo.get();
-	}
-
-	/**
-	 * Returns the specified annotation only if it's been declared on the package of this class.
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param type The annotation class.
-	 * @return The annotation, or <jk>null</jk> if not found.
-	 */
-	public <A extends Annotation> A getPackageAnnotation(Class<A> type) {
-		PackageInfo pi = getPackage();
-		if (pi == null)
-			return null;
-		var ai = pi.getAnnotation(type);
-		return ai == null ? null : ai.inner();
-	}
-
-	/**
-	 * Finds the real parameter type of this class.
-	 *
-	 * @param index The zero-based index of the parameter to resolve.
-	 * @param pt The parameterized type class containing the parameterized type to resolve (e.g. <c>HashMap</c>).
-	 * @return The resolved real class.
-	 */
-	public Class<?> getParameterType(int index, Class<?> pt) {
-		assertArgNotNull("pt", pt);
-
-		// We need to make up a mapping of type names.
-		var typeMap = new HashMap<Type,Type>();
-		Class<?> cc = c;
-		while (pt != cc.getSuperclass()) {
-			extractTypes(typeMap, cc);
-			cc = cc.getSuperclass();
-			assertArg(nn(cc), "Class ''{0}'' is not a subclass of parameterized type ''{1}''", c.getSimpleName(), pt.getSimpleName());
-		}
-
-		Type gsc = cc.getGenericSuperclass();
-
-		assertArg(gsc instanceof ParameterizedType, "Class ''{0}'' is not a parameterized type", pt.getSimpleName());
-
-		var cpt = (ParameterizedType)gsc;
-		Type[] atArgs = cpt.getActualTypeArguments();
-		assertArg(index < atArgs.length, "Invalid type index. index={0}, argsLength={1}", index, atArgs.length);
-		Type actualType = cpt.getActualTypeArguments()[index];
-
-		if (typeMap.containsKey(actualType))
-			actualType = typeMap.get(actualType);
-
-		if (actualType instanceof Class) {
-			return (Class<?>)actualType;
-
-		} else if (actualType instanceof GenericArrayType) {
-		Type gct = ((GenericArrayType)actualType).getGenericComponentType();
-		if (gct instanceof ParameterizedType pt3)
-			return Array.newInstance((Class<?>)pt3.getRawType(), 0).getClass();
-	} else if (actualType instanceof TypeVariable<?> typeVariable) {
-		List<Class<?>> nestedOuterTypes = new LinkedList<>();
-		for (Class<?> ec = cc.getEnclosingClass(); nn(ec); ec = ec.getEnclosingClass()) {
-			Class<?> outerClass = cc.getClass();
-			nestedOuterTypes.add(outerClass);
-		var outerTypeMap = new HashMap<Type,Type>();
-		extractTypes(outerTypeMap, outerClass);
-		for (var entry : outerTypeMap.entrySet()) {
-			var key = entry.getKey();
-			var value = entry.getValue();
-			if (key instanceof TypeVariable<?> keyType) {
-				if (keyType.getName().equals(typeVariable.getName()) && isInnerClass(keyType.getGenericDeclaration(), typeVariable.getGenericDeclaration())) {
-					if (value instanceof Class<?> c)
-						return c;
-						typeVariable = (TypeVariable<?>)entry.getValue();
-					}
-				}
-			}
-		}
-	} else if (actualType instanceof ParameterizedType) {
-			return (Class<?>)((ParameterizedType)actualType).getRawType();
-		}
-		throw illegalArg("Could not resolve variable ''{0}'' to a type.", actualType.getTypeName());
-	}
-
-	/**
-	 * Returns a list including this class and all parent classes.
-	 *
-	 * <p>
-	 * Does not include interfaces.
-	 *
-	 * <p>
-	 * Results are in child-to-parent order.
-	 *
-	 * @return An unmodifiable list including this class and all parent classes.
-	 * 	<br>Results are in child-to-parent order.
-	 */
-	public List<ClassInfo> getParents() { return parents.get(); }
-
-	/**
-	 * Returns the default value for this primitive class.
-	 *
-	 * @return The default value, or <jk>null</jk> if this is not a primitive class.
-	 */
-	public Object getPrimitiveDefault() { return primitiveDefaultMap.get(c); }
-
-	/**
-	 * If this class is a primitive wrapper (e.g. <code><jk>Integer</jk>.<jk>class</jk></code>) returns it's
-	 * primitive class (e.g. <code>int.<jk>class</jk></code>).
-	 *
-	 * @return The primitive class, or <jk>null</jk> if class is not a primitive wrapper.
-	 */
-	public Class<?> getPrimitiveForWrapper() { return pmap2.get(c); }
-
-	/**
-	 * If this class is a primitive (e.g. <code><jk>int</jk>.<jk>class</jk></code>) returns it's wrapper class
-	 * (e.g. <code>Integer.<jk>class</jk></code>).
-	 *
-	 * @return The wrapper class, or <jk>null</jk> if class is not a primitive.
-	 */
-	public Class<?> getPrimitiveWrapper() { return pmap1.get(c); }
-
-	/**
-	 * Returns the first matching public constructor on this class.
-	 *
-	 * @param filter A predicate to apply to the entries to determine if value should be used.  Can be <jk>null</jk>.
-	 * @return The public constructor that matches the specified predicate.
-	 */
-	public ConstructorInfo getPublicConstructor(Predicate<ConstructorInfo> filter) {
-		for (var ci : publicConstructors.get())
-			if (test(filter, ci))
-				return ci;
-		return null;
-	}
-
-	/**
-	 * Returns all the public constructors defined on this class.
-	 *
-	 * @return All public constructors defined on this class.
-	 */
-	public List<ConstructorInfo> getPublicConstructors() { return publicConstructors.get(); }
-
-	/**
-	 * Returns the first matching public field on this class.
-	 *
-	 * @param filter A predicate to apply to the entries to determine if value should be used.  Can be <jk>null</jk>.
-	 * @return The public field, or <jk>null</jk> if not found.
-	 */
-	public FieldInfo getPublicField(Predicate<FieldInfo> filter) {
-		for (var f : publicFields.get())
-			if (test(filter, f))
-				return f;
-		return null;
-	}
-
-	/**
-	 * Returns all public fields on this class.
-	 *
-	 * <p>
-	 * Hidden fields are excluded from the results.
-	 *
-	 * @return
-	 * 	All public fields on this class.
-	 * 	<br>Results are in alphabetical order.
-	 * 	<br>List is unmodifiable.
-	 */
-	public List<FieldInfo> getPublicFields() { return publicFields.get(); }
-
-	/**
-	 * Returns the first matching public method on this class.
-	 *
-	 * @param filter A predicate to apply to the entries to determine if value should be used.  Can be <jk>null</jk>.
-	 * @return The first matching method, or <jk>null</jk> if no methods matched.
-	 */
-	public MethodInfo getPublicMethod(Predicate<MethodInfo> filter) {
-		for (var mi : publicMethods.get())
-			if (test(filter, mi))
-				return mi;
-		return null;
-	}
-
-	/**
-	 * Returns all public methods on this class.
-	 *
-	 * <p>
-	 * Methods defined on the {@link Object} class are excluded from the results.
-	 *
-	 * @return
-	 * 	All public methods on this class.
-	 * 	<br>Results are ordered alphabetically.
-	 */
-	public List<MethodInfo> getPublicMethods() { return publicMethods.get(); }
-
-	/**
-	 * Same as {@link #getNameSimple()} but uses <js>"Array"</js> instead of <js>"[]"</js>.
-	 *
-	 * @return The readable name for this class.
-	 */
-	public String getNameReadable() {
-		return readableName.get();
-	}
-
-	/**
-	 * Returns the repeated annotation method on this class.
-	 *
-	 * <p>
-	 * The repeated annotation method is the <code>value()</code> method that returns an array
-	 * of annotations who themselves are marked with the {@link Repeatable @Repeatable} annotation
-	 * of this class.
-	 *
-	 * @return The repeated annotation method on this class, or <jk>null</jk> if it doesn't exist.
-	 */
-	public MethodInfo getRepeatedAnnotationMethod() {
-		return repeatedAnnotationMethod.get();
-	}
-
-	/**
-	 * Returns the short name of the underlying class.
-	 *
-	 * <p>
-	 * Similar to {@link #getNameSimple()} but also renders local or member class name prefixes.
-	 *
-	 * @return The short name of the underlying class.
-	 */
-	public String getNameShort() {
-		return shortName.get();
-	}
-
-	/**
-	 * Returns the simple name of the underlying class.
-	 *
-	 * <p>
-	 * Returns either {@link Class#getSimpleName()} or {@link Type#getTypeName()} depending on whether
-	 * this is a class or type.
-	 *
-	 * @return The simple name of the underlying class;
-	 */
-	public String getNameSimple() { return nn(c) ? c.getSimpleName() : t.getTypeName(); }
-
-	/**
-	 * Returns a formatted class name with configurable options.
-	 *
-	 * <p>
-	 * This is a unified method that can produce output equivalent to all other name methods
-	 * by varying the parameters.
-	 *
-	 * <h5 class='section'>Examples:</h5>
-	 * <p class='bjava'>
-	 * 	<jc>// Given: java.util.HashMap&lt;String,Integer&gt;[]</jc>
-	 *
-	 * 	<jc>// Full name with generics</jc>
-	 * 	getFormattedName(ClassNameFormat.<jsf>FULL</jsf>, <jk>true</jk>, '$', ClassArrayFormat.<jsf>BRACKETS</jsf>)
-	 * 	<jc>// → "java.util.HashMap&lt;java.lang.String,java.lang.Integer&gt;[]"</jc>
-	 *
-	 * 	<jc>// Short name with generics</jc>
-	 * 	getFormattedName(ClassNameFormat.<jsf>SHORT</jsf>, <jk>true</jk>, '$', ClassArrayFormat.<jsf>BRACKETS</jsf>)
-	 * 	<jc>// → "HashMap&lt;String,Integer&gt;[]"</jc>
-	 *
-	 * 	<jc>// Simple name</jc>
-	 * 	getFormattedName(ClassNameFormat.<jsf>SIMPLE</jsf>, <jk>false</jk>, '$', ClassArrayFormat.<jsf>BRACKETS</jsf>)
-	 * 	<jc>// → "HashMap[]"</jc>
-	 *
-	 * 	<jc>// With dot separator</jc>
-	 * 	getFormattedName(ClassNameFormat.<jsf>SHORT</jsf>, <jk>false</jk>, '.', ClassArrayFormat.<jsf>BRACKETS</jsf>)
-	 * 	<jc>// → "Map.Entry"</jc>
-	 *
-	 * 	<jc>// Word format for arrays</jc>
-	 * 	getFormattedName(ClassNameFormat.<jsf>SIMPLE</jsf>, <jk>false</jk>, '$', ClassArrayFormat.<jsf>WORD</jsf>)
-	 * 	<jc>// → "HashMapArray"</jc>
-	 * </p>
-	 *
-	 * <h5 class='section'>Equivalent Methods:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li><c>getName()</c> = <c>getFormattedName(FULL, <jk>false</jk>, '$', JVM)</c>
-	 * 	<li><c>getCanonicalName()</c> = <c>getFormattedName(FULL, <jk>false</jk>, '.', BRACKETS)</c>
-	 * 	<li><c>getSimpleName()</c> = <c>getFormattedName(SIMPLE, <jk>false</jk>, '$', BRACKETS)</c>
-	 * 	<li><c>getFullName()</c> = <c>getFormattedName(FULL, <jk>true</jk>, '$', BRACKETS)</c>
-	 * 	<li><c>getShortName()</c> = <c>getFormattedName(SHORT, <jk>true</jk>, '$', BRACKETS)</c>
-	 * 	<li><c>getReadableName()</c> = <c>getFormattedName(SIMPLE, <jk>false</jk>, '$', WORD)</c>
-	 * </ul>
-	 *
-	 * @param nameFormat
-	 * 	Controls which parts of the class name to include (package, outer classes).
-	 * @param includeTypeParams
-	 * 	If <jk>true</jk>, include generic type parameters recursively.
-	 * 	<br>For example: <js>"HashMap&lt;String,Integer&gt;"</js> instead of <js>"HashMap"</js>
-	 * @param separator
-	 * 	Character to use between outer and inner class names.
-	 * 	<br>Typically <js>'$'</js> (JVM format) or <js>'.'</js> (canonical format).
-	 * 	<br>Ignored when <c>nameFormat</c> is {@link ClassNameFormat#SIMPLE}.
-	 * @param arrayFormat
-	 * 	How to format array dimensions.
-	 * @return
-	 * 	The formatted class name.
-	 */
-	public String getNameFormatted(ClassNameFormat nameFormat, boolean includeTypeParams, char separator, ClassArrayFormat arrayFormat) {
-		var sb = new StringBuilder(128);
-		appendNameFormatted(sb, nameFormat, includeTypeParams, separator, arrayFormat);
-		return sb.toString();
-	}
-
-	/**
-	 * Appends a formatted class name to a StringBuilder with configurable options.
-	 *
-	 * <p>
-	 * This is the core implementation method used by all other name formatting methods.
-	 * Using this method directly avoids String allocations when building complex strings.
-	 * The method is recursive to handle nested generic type parameters.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bjava'>
-	 * 	StringBuilder sb = <jk>new</jk> StringBuilder();
-	 * 	sb.append(<js>"Class: "</js>);
-	 * 	ClassInfo.<jsm>of</jsm>(HashMap.<jk>class</jk>).appendFormattedName(sb, ClassNameFormat.<jsf>FULL</jsf>, <jk>true</jk>, '$', ClassArrayFormat.<jsf>BRACKETS</jsf>);
-	 * 	<jc>// sb now contains: "Class: java.util.HashMap"</jc>
-	 * </p>
-	 *
-	 * @param sb
-	 * 	The StringBuilder to append to.
-	 * @param nameFormat
-	 * 	Controls which parts of the class name to include (package, outer classes).
-	 * @param includeTypeParams
-	 * 	If <jk>true</jk>, include generic type parameters recursively.
-	 * @param separator
-	 * 	Character to use between outer and inner class names.
-	 * 	<br>Ignored when <c>nameFormat</c> is {@link ClassNameFormat#SIMPLE}.
-	 * @param arrayFormat
-	 * 	How to format array dimensions.
-	 * @return
-	 * 	The same StringBuilder for method chaining.
-	 */
-	@SuppressWarnings("null")
-	public StringBuilder appendNameFormatted(StringBuilder sb, ClassNameFormat nameFormat, boolean includeTypeParams, char separator, ClassArrayFormat arrayFormat) {
-		var dim = getDimensions();
-
-		// Handle arrays - format component type recursively, then add array notation
-		if (dim > 0) {
-			var componentType = getComponentType();
-			componentType.appendNameFormatted(sb, nameFormat, includeTypeParams, separator, arrayFormat);
-
-			if (arrayFormat == ClassArrayFormat.WORD) {
-				for (int i = 0; i < dim; i++)
-					sb.append("Array");
-			} else if (arrayFormat == ClassArrayFormat.BRACKETS) {
-				for (int i = 0; i < dim; i++)
-					sb.append("[]");
-			}
-			// JVM format is already in getName() - would need special handling
-
-			return sb;
-		}
-
-		// Get the raw class - for ParameterizedType, extract the raw type
-		var ct = c;
-		if (ct == null && isParameterizedType) {
-			var pt = (ParameterizedType)t;
-			ct = (Class<?>)pt.getRawType();
-		}
-
-		// Append base class name based on format
-		switch (nameFormat) {
-			case FULL:
-				// Full package name + outer classes
-				if (nn(ct)) {
-					sb.append(ct.getName());
-					// Apply separator if not '$'
-					if (separator != '$' && sb.indexOf("$") != -1) {
-						for (int i = 0; i < sb.length(); i++) {
-							if (sb.charAt(i) == '$')
-								sb.setCharAt(i, separator);
-						}
-					}
-				} else {
-					sb.append(t.getTypeName());
-				}
-				break;
-
-			case SHORT:
-				// Outer classes but no package
-				if (nn(ct)) {
-					if (ct.isLocalClass()) {
-						// Local class: include enclosing class simple name
-						sb.append(of(ct.getEnclosingClass()).getNameSimple())
-						  .append(separator)
-						  .append(ct.getSimpleName());
-					} else if (ct.isMemberClass()) {
-						// Member class: include declaring class simple name
-						sb.append(of(ct.getDeclaringClass()).getNameSimple())
-						  .append(separator)
-						  .append(ct.getSimpleName());
-					} else {
-						// Regular class: just simple name
-						sb.append(ct.getSimpleName());
-					}
-				} else {
-					sb.append(t.getTypeName());
-				}
-				break;
-
-			default /* SIMPLE */:
-				// Simple name only - no package, no outer classes
-				if (nn(ct)) {
-					sb.append(ct.getSimpleName());
-				} else {
-					sb.append(t.getTypeName());
-				}
-				break;
-		}
-
-		// Append type parameters if requested
-		if (includeTypeParams && isParameterizedType) {
-			var pt = (ParameterizedType)t;
-			sb.append('<');
-			var first = true;
-			for (var t2 : pt.getActualTypeArguments()) {
-				if (!first)
-					sb.append(',');
-				first = false;
-				of(t2).appendNameFormatted(sb, nameFormat, includeTypeParams, separator, arrayFormat);
-			}
-			sb.append('>');
-		}
-
-		return sb;
-	}
-
-	/**
-	 * Returns the parent class.
-	 *
-	 * @return
-	 * 	The parent class, or <jk>null</jk> if the class has no parent.
-	 */
-	public ClassInfo getSuperclass() { return c == null ? null : of(c.getSuperclass()); }
-
-	/**
-	 * Returns the nest host of this class.
-	 *
-	 * <p>
-	 * Every class belongs to exactly one nest. A class that is not a member of a nest
-	 * is its own nest host.
-	 *
-	 * @return The nest host of this class.
-	 */
-	public ClassInfo getNestHost() {
-		return c == null ? null : of(c.getNestHost());
-	}
-
-	/**
-	 * Returns an array containing all the classes and interfaces that are members of the nest
-	 * to which this class belongs.
-	 *
-	 * @return
-	 * 	An unmodifiable list of all classes and interfaces in the same nest as this class.
-	 * 	<br>Returns an empty list if this object does not represent a class.
-	 */
-	public List<ClassInfo> getNestMembers() {
-		if (c == null)
-			return u(l());
-		var members = c.getNestMembers();
-		List<ClassInfo> l = listOfSize(members.length);
-		for (Class<?> cc : members)
-			l.add(of(cc));
-		return u(l);
-	}
-
-	/**
-	 * Returns the permitted subclasses of this sealed class.
-	 *
-	 * <p>
-	 * If this class is not sealed, returns an empty list.
-	 *
-	 * @return
-	 * 	An unmodifiable list of permitted subclasses if this is a sealed class.
-	 * 	<br>Returns an empty list if this class is not sealed.
-	 */
-	public List<ClassInfo> getPermittedSubclasses() {
-		if (c == null || ! c.isSealed())
-			return u(l());
-		Class<?>[] permitted = c.getPermittedSubclasses();
-		List<ClassInfo> l = listOfSize(permitted.length);
-		for (Class<?> cc : permitted)
-			l.add(of(cc));
-		return u(l);
-	}
-
-	/**
-	 * Returns the record components of this record class.
-	 *
-	 * <p>
-	 * Returns a cached, unmodifiable list of record components.
-	 * The components are returned in the same order as they appear in the record declaration.
-	 * If this class is not a record, returns an empty list.
-	 *
-	 * @return An unmodifiable list of record components, or an empty list if this class is not a record.
-	 */
-	public List<RecordComponent> getRecordComponents() {
-		return recordComponents.get();
-	}
-
-	/**
-	 * Returns the {@link Type} representing the direct superclass of this class.
-	 *
-	 * <p>
-	 * If the superclass is a parameterized type, the {@link Type} returned reflects the actual
-	 * type parameters used in the source code.
-	 *
-	 * @return
-	 * 	The superclass of this class as a {@link Type},
-	 * 	or <jk>null</jk> if this class represents {@link Object}, an interface, a primitive type, or void.
-	 */
-	public Type getGenericSuperclass() {
-		return c == null ? null : c.getGenericSuperclass();
-	}
-
-	/**
-	 * Returns the {@link Type}s representing the interfaces directly implemented by this class.
-	 *
-	 * <p>
-	 * Returns a cached, unmodifiable list.
-	 * If a superinterface is a parameterized type, the {@link Type} returned for it reflects the actual
-	 * type parameters used in the source code.
-	 *
-	 * @return
-	 * 	An unmodifiable list of {@link Type}s representing the interfaces directly implemented by this class.
-	 * 	<br>Returns an empty list if this class implements no interfaces.
-	 */
-	public List<Type> getGenericInterfaces() {
-		return genericInterfaces.get();
-	}
-
-	/**
-	 * Returns a list of {@link TypeVariable} objects that represent the type variables declared by this class.
-	 *
-	 * <p>
-	 * Returns a cached, unmodifiable list.
-	 * The type variables are returned in the same order as they appear in the class declaration.
-	 *
-	 * @return
-	 * 	An unmodifiable list of {@link TypeVariable} objects representing the type parameters of this class.
-	 * 	<br>Returns an empty list if this class declares no type parameters.
-	 */
-	public List<TypeVariable<?>> getTypeParameters() {
-		return typeParameters.get();
-	}
-
-	/**
-	 * Returns an {@link AnnotatedType} object that represents the annotated superclass of this class.
-	 *
-	 * <p>
-	 * If this class represents a class type whose superclass is annotated, the returned object reflects
-	 * the annotations used in the source code to declare the superclass.
-	 *
-	 * @return
-	 * 	An {@link AnnotatedType} object representing the annotated superclass,
-	 * 	or <jk>null</jk> if this class represents {@link Object}, an interface, a primitive type, or void.
-	 */
-	public AnnotatedType getAnnotatedSuperclass() {
-		return c == null ? null : c.getAnnotatedSuperclass();
-	}
-
-	/**
-	 * Returns a list of {@link AnnotatedType} objects that represent the annotated interfaces
-	 * implemented by this class.
-	 *
-	 * <p>
-	 * Returns a cached, unmodifiable list.
-	 * If this class represents a class or interface whose superinterfaces are annotated,
-	 * the returned objects reflect the annotations used in the source code to declare the superinterfaces.
-	 *
-	 * @return
-	 * 	An unmodifiable list of {@link AnnotatedType} objects representing the annotated superinterfaces.
-	 * 	<br>Returns an empty list if this class implements no interfaces.
-	 */
-	public List<AnnotatedType> getAnnotatedInterfaces() {
-		return annotatedInterfaces.get();
-	}
-
-	/**
-	 * Returns the {@link ProtectionDomain} of this class.
-	 *
-	 * <p>
-	 * If a security manager is installed, this method requires <c>RuntimePermission("getProtectionDomain")</c>.
-	 *
-	 * @return The {@link ProtectionDomain} of this class, or <jk>null</jk> if the class does not have a protection domain.
-	 */
-	public java.security.ProtectionDomain getProtectionDomain() {
-		return c == null ? null : c.getProtectionDomain();
-	}
-
-	/**
-	 * Returns the signers of this class.
-	 *
-	 * <p>
-	 * Returns a cached, unmodifiable list.
-	 *
-	 * @return An unmodifiable list of signers, or an empty list if there are no signers.
-	 */
-	public List<Object> getSigners() {
-		return signers.get();
-	}
-
-	/**
-	 * Finds a resource with a given name.
-	 *
-	 * <p>
-	 * The rules for searching resources associated with a given class are implemented by the defining class loader.
-	 *
-	 * @param name The resource name.
-	 * @return A URL object for reading the resource, or <jk>null</jk> if the resource could not be found.
-	 */
-	public java.net.URL getResource(String name) {
-		return c == null ? null : c.getResource(name);
-	}
-
-	/**
-	 * Finds a resource with a given name and returns an input stream for reading the resource.
-	 *
-	 * <p>
-	 * The rules for searching resources associated with a given class are implemented by the defining class loader.
-	 *
-	 * @param name The resource name.
-	 * @return An input stream for reading the resource, or <jk>null</jk> if the resource could not be found.
-	 */
-	public java.io.InputStream getResourceAsStream(String name) {
-		return c == null ? null : c.getResourceAsStream(name);
-	}
-
-	/**
-	 * Returns the descriptor string of this class.
-	 *
-	 * <p>
-	 * The descriptor is a string representing the type of the class, as specified in JVMS 4.3.2.
-	 * For example, the descriptor for <c>String</c> is <js>"Ljava/lang/String;"</js>.
-	 *
-	 * @return The descriptor string of this class.
-	 */
-	public String descriptorString() {
-		return c == null ? null : c.descriptorString();
-	}
-
-	/**
-	 * If this class is a primitive (e.g. <code><jk>int</jk>.<jk>class</jk></code>) returns it's wrapper class
-	 * (e.g. <code>Integer.<jk>class</jk></code>).
-	 *
-	 * @return The wrapper class if it's primitive, or the same class if class is not a primitive.
-	 */
-	public Class<?> getWrapperIfPrimitive() {
-		if (nn(c) && ! c.isPrimitive())
-			return c;
-		return pmap1.get(c);
-	}
-
-	/**
-	 * Same as {@link #getWrapperIfPrimitive()} but wraps it in a {@link ClassInfo}.
-	 *
-	 * @return The wrapper class if it's primitive, or the same class if class is not a primitive.
-	 */
-	public ClassInfo getWrapperInfoIfPrimitive() {
-		if (c == null || ! c.isPrimitive())
-			return this;
-		return of(pmap1.get(c));
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class has the specified annotation.
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param annotationProvider The annotation provider.
-	 * @param type The annotation to look for.
-	 * @return The <jk>true</jk> if annotation if found.
-	 */
-	public <A extends Annotation> boolean hasAnnotation(AnnotationProvider annotationProvider, Class<A> type) {
-		if (annotationProvider == null)
-			throw unsupportedOp();
-		// Inline Context.firstAnnotation() call
-		return nn(annotationProvider.getAnnotationProvider().find(type, c).map(x -> x.inner()).filter(x -> true).findFirst().orElse(null));
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class has the specified annotation.
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param type The annotation to look for.
-	 * @return The <jk>true</jk> if annotation if found.
-	 */
-	public <A extends Annotation> boolean hasAnnotation(Class<A> type) {
-		return getAnnotationInfos(type).findFirst().isPresent();
-	}
-
-	@Override
-	public int hashCode() {
-		return t.hashCode();
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class doesn't have the specified annotation.
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param type The annotation to look for.
-	 * @return The <jk>true</jk> if annotation if not found.
-	 */
-	public <A extends Annotation> boolean hasNoAnnotation(Class<A> type) {
-		return ! hasAnnotation(type);
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is not in the root package.
-	 *
-	 * @return <jk>true</jk> if this class is not in the root package.
-	 */
-	public boolean hasPackage() {
-		return nn(getPackage());
-	}
-
-	/**
-	 * Returns <jk>true</jk> if the {@link #getPrimitiveWrapper()} method returns a value.
-	 *
-	 * @return <jk>true</jk> if the {@link #getPrimitiveWrapper()} method returns a value.
-	 */
-	public boolean hasPrimitiveWrapper() {
-		return pmap1.containsKey(c);
-	}
-
-	/**
-	 * Returns the wrapped class as a {@link Class}.
-	 *
-	 * @param <T> The inner class type.
-	 * @return The wrapped class as a {@link Class}, or <jk>null</jk> if it's not a class (e.g. it's a {@link ParameterizedType}).
-	 */
-	public <T> Class<T> inner() {
-		return (Class<T>)c;
-	}
-
-	/**
-	 * Returns the wrapped class as a {@link Type}.
-	 *
-	 * @return The wrapped class as a {@link Type}.
-	 */
-	public Type innerType() {
-		return t;
-	}
-
-	/**
-	 * Checks for equality with the specified class.
-	 *
-	 * @param c The class to check equality with.
-	 * @return <jk>true</jk> if the specified class is the same as this one.
-	 */
-	public boolean is(Class<?> c) {
-		return nn(this.c) && this.c.equals(c);
-	}
-
-	/**
-	 * Checks for equality with the specified class.
-	 *
-	 * @param c The class to check equality with.
-	 * @return <jk>true</jk> if the specified class is the same as this one.
-	 */
-	public boolean is(ClassInfo c) {
-		if (nn(this.c))
-			return this.c.equals(c.inner());
-		return t.equals(c.t);
-	}
-
-	/**
-	 * Returns <jk>true</jk> if all specified flags are applicable to this class.
-	 *
-	 * @param flags The flags to test for.
-	 * @return <jk>true</jk> if all specified flags are applicable to this class.
-	 */
-	@Override
-	public boolean is(ElementFlag flag) {
-		return switch (flag) {
-			case ANNOTATION -> isAnnotation();
-			case NOT_ANNOTATION -> !isAnnotation();
-			case ANONYMOUS -> isAnonymousClass();
-			case NOT_ANONYMOUS -> !isAnonymousClass();
-			case ARRAY -> isArray();
-			case NOT_ARRAY -> !isArray();
-			case CLASS -> !isInterface();
-			case DEPRECATED -> isDeprecated();
-			case NOT_DEPRECATED -> isNotDeprecated();
-			case ENUM -> isEnum();
-			case NOT_ENUM -> !isEnum();
-			case LOCAL -> isLocalClass();
-			case NOT_LOCAL -> !isLocalClass();
-			case MEMBER -> isMemberClass();
-			case NOT_MEMBER -> isNotMemberClass();
-			case NON_STATIC_MEMBER -> isNonStaticMemberClass();
-			case NOT_NON_STATIC_MEMBER -> !isNonStaticMemberClass();
-			case PRIMITIVE -> isPrimitive();
-			case NOT_PRIMITIVE -> !isPrimitive();
-			case RECORD -> isRecord();
-			case NOT_RECORD -> !isRecord();
-			case SEALED -> isSealed();
-			case NOT_SEALED -> !isSealed();
-			case SYNTHETIC -> isSynthetic();
-			case NOT_SYNTHETIC -> !isSynthetic();
-			default -> super.is(flag);
-		};
-	}
-
-	@Override
-	public boolean isAll(ElementFlag...flags) {
-		return stream(flags).allMatch(this::is);
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is an annotation.
-	 *
-	 * @return <jk>true</jk> if this class is an annotation.
-	 */
-	public boolean isAnnotation() { return nn(c) && c.isAnnotation(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is an anonymous class.
-	 *
-	 * <p>
-	 * An anonymous class is a local class declared within a method or constructor that has no name.
-	 *
-	 * @return <jk>true</jk> if this class is an anonymous class.
-	 */
-	public boolean isAnonymousClass() { return nn(c) && c.isAnonymousClass(); }
-
-	@Override
-	public boolean isAny(ElementFlag...flags) {
-		return stream(flags).anyMatch(this::is);
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is any of the specified types.
-	 *
-	 * @param types The types to check against.
-	 * @return <jk>true</jk> if this class is any of the specified types.
-	 */
-	public boolean isAny(Class<?>...types) {
-		for (var cc : types)
-			if (is(cc))
-				return true;
-		return false;
-	}
-
-
-	/**
-	 * Returns <jk>true</jk> if this class is an array.
-	 *
-	 * @return <jk>true</jk> if this class is an array.
-	 */
-	public boolean isArray() { return nn(c) && c.isArray(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a child or the same as <c>parent</c>.
-	 *
-	 * @param parent The parent class.
-	 * @return <jk>true</jk> if this class is a child or the same as <c>parent</c>.
-	 */
-	public boolean isChildOf(Class<?> parent) {
-		return nn(c) && nn(parent) && parent.isAssignableFrom(c);
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a child or the same as <c>parent</c>.
-	 *
-	 * @param parent The parent class.
-	 * @return <jk>true</jk> if this class is a parent or the same as <c>parent</c>.
-	 */
-	public boolean isChildOf(ClassInfo parent) {
-		return isChildOf(parent.inner());
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a child or the same as <c>parent</c>.
-	 *
-	 * @param parent The parent class.
-	 * @return <jk>true</jk> if this class is a parent or the same as <c>parent</c>.
-	 */
-	public boolean isChildOf(Type parent) {
-		if (parent instanceof Class)
-			return isChildOf((Class<?>)parent);
-		return false;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a child or the same as any of the <c>parents</c>.
-	 *
-	 * @param parents The parents class.
-	 * @return <jk>true</jk> if this class is a child or the same as any of the <c>parents</c>.
-	 */
-	public boolean isChildOfAny(Class<?>...parents) {
-		for (var p : parents)
-			if (isChildOf(p))
-				return true;
-		return false;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is not an interface.
-	 *
-	 * @return <jk>true</jk> if this class is not an interface.
-	 */
-	public boolean isClass() { return nn(c) && ! c.isInterface(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a {@link Collection} or an array.
-	 *
-	 * @return <jk>true</jk> if this class is a {@link Collection} or an array.
-	 */
-	public boolean isCollectionOrArray() { return nn(c) && (Collection.class.isAssignableFrom(c) || c.isArray()); }
-
-	/**
-	 * Returns <jk>true</jk> if this class has the {@link Deprecated @Deprecated} annotation on it.
-	 *
-	 * @return <jk>true</jk> if this class has the {@link Deprecated @Deprecated} annotation on it.
-	 */
-	public boolean isDeprecated() { return nn(c) && c.isAnnotationPresent(Deprecated.class); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is an enum.
-	 *
-	 * @return <jk>true</jk> if this class is an enum.
-	 */
-	public boolean isEnum() { return nn(c) && c.isEnum(); }
-
-	/**
-	 * Returns <jk>true</jk> if the specified value is an instance of this class.
-	 *
-	 * @param value The value to check.
-	 * @return <jk>true</jk> if the specified value is an instance of this class.
-	 */
-	public boolean isInstance(Object value) {
-		if (nn(this.c))
-			return c.isInstance(value);
-		return false;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a local class.
-	 *
-	 * @return <jk>true</jk> if this class is a local class.
-	 */
-	public boolean isLocalClass() { return nn(c) && c.isLocalClass(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a member class.
-	 *
-	 * @return <jk>true</jk> if this class is a member class.
-	 */
-	public boolean isMemberClass() { return nn(c) && c.isMemberClass(); }
-
-	/**
-	 * Determines if this class and the specified class are nestmates.
-	 *
-	 * <p>
-	 * Two classes are nestmates if they belong to the same nest.
-	 *
-	 * @param c The class to check.
-	 * @return <jk>true</jk> if this class and the specified class are nestmates.
-	 */
-	public boolean isNestmateOf(Class<?> c) {
-		return nn(this.c) && nn(c) && this.c.isNestmateOf(c);
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a member class and not static.
-	 *
-	 * @return <jk>true</jk> if this class is a member class and not static.
-	 */
-	public boolean isNonStaticMemberClass() { return nn(c) && c.isMemberClass() && ! isStatic(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class doesn't have the {@link Deprecated @Deprecated} annotation on it.
-	 *
-	 * @return <jk>true</jk> if this class doesn't have the {@link Deprecated @Deprecated} annotation on it.
-	 */
-	public boolean isNotDeprecated() { return c == null || ! c.isAnnotationPresent(Deprecated.class); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a local class.
-	 *
-	 * @return <jk>true</jk> if this class is a local class.
-	 */
-	public boolean isNotLocalClass() { return c == null || ! c.isLocalClass(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a member class.
-	 *
-	 * @return <jk>true</jk> if this class is a member class.
-	 */
-	public boolean isNotMemberClass() { return c == null || ! c.isMemberClass(); }
-
-	/**
-	 * Returns <jk>false</jk> if this class is a member class and not static.
-	 *
-	 * @return <jk>false</jk> if this class is a member class and not static.
-	 */
-	public boolean isNotNonStaticMemberClass() { return ! isNonStaticMemberClass(); }
-
-	/**
-	 * Returns <jk>true</jk> if this is not a primitive class.
-	 *
-	 * @return <jk>true</jk> if this is not a primitive class.
-	 */
-	public boolean isNotPrimitive() { return c == null || ! c.isPrimitive(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 *
-	 * @param child The child class.
-	 * @return <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 */
-	public boolean isParentOf(Class<?> child) {
-		return nn(c) && nn(child) && c.isAssignableFrom(child);
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 *
-	 * @param child The child class.
-	 * @return <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 */
-	public boolean isParentOf(Type child) {
-		if (child instanceof Class)
-			return isParentOf((Class<?>)child);
-		return false;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 *
-	 * <p>
-	 * Primitive classes are converted to wrapper classes and compared.
-	 *
-	 * <h5 class='section'>Examples:</h5>
-	 * <p class='bjava'>
-	 * 		ClassInfo.<jsm>of</jsm>(String.<jk>class</jk>).isParentOfLenient(String.<jk>class</jk>);  <jc>// true</jc>
-	 * 		ClassInfo.<jsm>of</jsm>(CharSequence.<jk>class</jk>).isParentOfLenient(String.<jk>class</jk>);  <jc>// true</jc>
-	 * 		ClassInfo.<jsm>of</jsm>(String.<jk>class</jk>).isParentOfLenient(CharSequence.<jk>class</jk>);  <jc>// false</jc>
-	 * 		ClassInfo.<jsm>of</jsm>(<jk>int</jk>.<jk>class</jk>).isParentOfLenient(Integer.<jk>class</jk>);  <jc>// true</jc>
-	 * 		ClassInfo.<jsm>of</jsm>(Integer.<jk>class</jk>).isParentOfLenient(<jk>int</jk>.<jk>class</jk>);  <jc>// true</jc>
-	 * 		ClassInfo.<jsm>of</jsm>(Number.<jk>class</jk>).isParentOfLenient(<jk>int</jk>.<jk>class</jk>);  <jc>// true</jc>
-	 * 		ClassInfo.<jsm>of</jsm>(<jk>int</jk>.<jk>class</jk>).isParentOfLenient(Number.<jk>class</jk>);  <jc>// false</jc>
-	 * 		ClassInfo.<jsm>of</jsm>(<jk>int</jk>.<jk>class</jk>).isParentOfLenient(<jk>long</jk>.<jk>class</jk>);  <jc>// false</jc>
-	 * </p>
-	 *
-	 * @param child The child class.
-	 * @return <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 */
-	public boolean isParentOfLenient(Class<?> child) {
-		if (c == null || child == null)
-			return false;
-		if (c.isAssignableFrom(child))
-			return true;
-		if (this.isPrimitive() || child.isPrimitive()) {
-			return this.getWrapperIfPrimitive().isAssignableFrom(of(child).getWrapperIfPrimitive());
-		}
-		return false;
-	}
-
-	/**
-	 * Same as {@link #isParentOfLenient(Class)} but takes in a {@link ClassInfo}.
-	 *
-	 * @param child The child class.
-	 * @return <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 */
-	public boolean isParentOfLenient(ClassInfo child) {
-		if (c == null || child == null)
-			return false;
-		if (c.isAssignableFrom(child.inner()))
-			return true;
-		if (this.isPrimitive() || child.isPrimitive()) {
-			return this.getWrapperIfPrimitive().isAssignableFrom(child.getWrapperIfPrimitive());
-		}
-		return false;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 *
-	 * @param child The child class.
-	 * @return <jk>true</jk> if this class is a parent or the same as <c>child</c>.
-	 */
-	public boolean isParentOfLenient(Type child) {
-		if (child instanceof Class)
-			return isParentOfLenient((Class<?>)child);
-		return false;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this is a primitive class.
-	 *
-	 * @return <jk>true</jk> if this is a primitive class.
-	 */
-	public boolean isPrimitive() { return nn(c) && c.isPrimitive(); }
-
-	/**
-	 * Returns <jk>true</jk> if this is a repeated annotation class.
-	 *
-	 * <p>
-	 * A repeated annotation has a single <code>value()</code> method that returns an array
-	 * of annotations who themselves are marked with the {@link Repeatable @Repeatable} annotation
-	 * of this class.
-	 *
-	 * @return <jk>true</jk> if this is a repeated annotation class.
-	 */
-	public boolean isRepeatedAnnotation() {
-		return getRepeatedAnnotationMethod() != null;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this class is a {@link RuntimeException}.
-	 *
-	 * @return <jk>true</jk> if this class is a {@link RuntimeException}.
-	 */
-	public boolean isRuntimeException() { return isChildOf(RuntimeException.class); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a record class.
-	 *
-	 * <p>
-	 * A record class is a final class that extends {@link java.lang.Record}.
-	 *
-	 * @return <jk>true</jk> if this class is a record class.
-	 */
-	public boolean isRecord() { return nn(c) && c.isRecord(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a sealed class.
-	 *
-	 * <p>
-	 * A sealed class is a class that can only be extended by a permitted set of subclasses.
-	 *
-	 * @return <jk>true</jk> if this class is a sealed class.
-	 */
-	public boolean isSealed() { return nn(c) && c.isSealed(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a synthetic class.
-	 *
-	 * <p>
-	 * A synthetic class is one that is generated by the compiler and does not appear in source code.
-	 *
-	 * @return <jk>true</jk> if this class is synthetic.
-	 */
-	public boolean isSynthetic() { return nn(c) && c.isSynthetic(); }
-
-	/**
-	 * Returns <jk>true</jk> if this class is a child of <c>parent</c>.
-	 *
-	 * @param parent The parent class.
-	 * @return <jk>true</jk> if this class is a parent of <c>child</c>.
-	 */
-	public boolean isStrictChildOf(Class<?> parent) {
-		return nn(c) && nn(parent) && parent.isAssignableFrom(c) && ! c.equals(parent);
-	}
-
-	/**
-	 * Identifies if the specified visibility matches this constructor.
-	 *
-	 * @param v The visibility to validate against.
-	 * @return <jk>true</jk> if this visibility matches the modifier attribute of this constructor.
-	 */
-	public boolean isVisible(Visibility v) {
-		return nn(c) && v.isVisible(c);
-	}
-
-	/**
-	 * Returns the last matching annotation on this class and superclasses/interfaces.
-	 *
-	 * <p>
-	 * Annotations are searched in the following orders:
-	 * <ol>
-	 * 	<li>On this class.
-	 * 	<li>On parent classes ordered child-to-parent.
-	 * 	<li>On interfaces ordered child-to-parent.
-	 * 	<li>On the package of this class.
-	 * </ol>
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param annotationProvider The annotation provider.
-	 * @param type The annotation to look for.
-	 * @param filter A predicate to apply to the entries to determine if annotation should be returned.  Can be <jk>null</jk>.
-	 * @return This object.
-	 */
-	public <A extends Annotation> A lastAnnotation(AnnotationProvider annotationProvider, Class<A> type, Predicate<A> filter) {
-		if (annotationProvider == null)
-			throw unsupportedOp();
-		A x = null;
-		x = annotationProvider.getAnnotationProvider().find(type, inner()).map(y -> y.inner()).filter(y -> filter.test(y)).findFirst().orElse(null);
-		if (nn(x) && test(filter, x))
-			return x;
-		var parents2 = parents.get();
-		for (var parent : parents2) {
-			x = annotationProvider.getAnnotationProvider().find(type, parent.inner()).map(y -> y.inner()).filter(y -> filter.test(y)).findFirst().orElse(null);
-			if (nn(x))
-				return x;
-		}
-		var interfaces2 = interfaces.get();
-		for (var element : interfaces2) {
-			x = annotationProvider.getAnnotationProvider().find(type, element.inner()).map(y -> y.inner()).filter(y -> filter.test(y)).findFirst().orElse(null);
-			if (nn(x))
-				return x;
-		}
-		x = getPackageAnnotation(type);
-		if (nn(x) && test(filter, x))
-			return x;
-		return null;
-	}
-
-	/**
-	 * Returns the last matching annotation on this class and superclasses/interfaces.
-	 *
-	 * <p>
-	 * Annotations are searched in the following orders:
-	 * <ol>
-	 * 	<li>On this class.
-	 * 	<li>On parent classes ordered child-to-parent.
-	 * 	<li>On interfaces ordered child-to-parent.
-	 * 	<li>On the package of this class.
-	 * </ol>
-	 *
-	 * @param <A> The annotation type to look for.
-	 * @param type The annotation to look for.
-	 * @param filter A predicate to apply to the entries to determine if annotation should be returned.  Can be <jk>null</jk>.
-	 * @return This object.
-	 */
-	public <A extends Annotation> A lastAnnotation(Class<A> type, Predicate<A> filter) {
-		// Inline implementation using reflection directly instead of delegating to AnnotationProvider
-		if (!nn(type))
-			return null;
-		
-		// Search annotations using reflection (reverse order for "last")
-		var annotations = rstream(l(c.getAnnotationsByType(type)));
-		var result = annotations.filter(a -> test(filter, a)).findFirst().orElse(null);
-		if (nn(result))
-			return result;
-		
-		// Search parents
-		var parents2 = parents.get();
-		for (var parent : parents2) {
-			var parentAnnotations = rstream(l(parent.inner().getAnnotationsByType(type)));
-			result = parentAnnotations.filter(a -> test(filter, a)).findFirst().orElse(null);
-			if (nn(result))
-				return result;
-		}
-		
-		// Search interfaces
-		var interfaces2 = interfaces.get();
-		for (var iface : interfaces2) {
-			var ifaceAnnotations = rstream(l(iface.inner().getAnnotationsByType(type)));
-			result = ifaceAnnotations.filter(a -> test(filter, a)).findFirst().orElse(null);
-			if (nn(result))
-				return result;
-		}
-		
-		// Search package
-		return getPackageAnnotation(type);
-	}
-
-	/**
-	 * Shortcut for calling <c>Class.getDeclaredConstructor().newInstance()</c> on the underlying class.
-	 *
-	 * @return A new instance of the underlying class
-	 * @throws ExecutableException Exception occurred on invoked constructor/method/field.
-	 */
-	public Object newInstance() throws ExecutableException {
-		if (c == null)
-			throw new ExecutableException("Type ''{0}'' cannot be instantiated", getNameFull());
-		try {
-			return c.getDeclaredConstructor().newInstance();
-		} catch (InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException e) {
-			throw new ExecutableException(e);
-		}
-	}
-
-	@Override
-	public String toString() {
-		return t.toString();
-	}
-
-	/**
-	 * Unwrap this class if it's a parameterized type of the specified type such as {@link Value} or {@link Optional}.
-	 *
-	 * @param wrapperTypes The parameterized types to unwrap if this class is one of those types.
-	 * @return The class info on the unwrapped type, or just this type if this isn't one of the specified types.
-	 */
-	public ClassInfo unwrap(Class<?>...wrapperTypes) {
-		for (var wt : wrapperTypes) {
-			if (isParameterizedTypeOf(wt)) {
-				Type t = getFirstParameterType(wt);
-				if (nn(t))
-					return of(t).unwrap(wrapperTypes); // Recursively do it again.
-			}
-		}
-		return this;
-	}
-
-	/**
-	 * Casts an object to the class represented by this {@link ClassInfo} object.
-	 *
-	 * @param <T> The type to cast to.
-	 * @param obj The object to be cast.
-	 * @return The object after casting, or <jk>null</jk> if obj is <jk>null</jk>.
-	 * @throws ClassCastException If the object is not <jk>null</jk> and is not assignable to this class.
-	 */
-	public <T> T cast(Object obj) {
-		return c == null ? null : (T)c.cast(obj);
-	}
-
-	/**
-	 * Casts this {@link ClassInfo} object to represent a subclass of the class represented by the specified class object.
-	 *
-	 * @param <U> The type to cast to.
-	 * @param clazz The class of the type to cast to.
-	 * @return This {@link ClassInfo} object, cast to represent a subclass of the specified class object.
-	 * @throws ClassCastException If this class is not assignable to the specified class.
-	 */
-	public <U> ClassInfo asSubclass(Class<U> clazz) {
-		if (c == null)
-			return null;
-		c.asSubclass(clazz);  // Throws ClassCastException if not assignable
-		return this;
-	}
-
-	/**
-	 * Returns a {@link ClassInfo} for an array type whose component type is this class.
-	 *
-	 * @return A {@link ClassInfo} representing an array type whose component type is this class.
-	 */
-	public ClassInfo arrayType() {
-		return c == null ? null : of(c.arrayType());
-	}
-
-	/**
-	 * Returns the component type of this class if it is an array type.
-	 *
-	 * <p>
-	 * This is equivalent to {@link Class#getComponentType()} but returns a {@link ClassInfo} instead.
-	 * Note that {@link #getComponentType()} also exists and returns the base component type for multi-dimensional arrays.
-	 *
-	 * @return The {@link ClassInfo} representing the component type, or <jk>null</jk> if this class does not represent an array type.
-	 */
-	public ClassInfo componentType() {
-		return c == null ? null : of(c.componentType());
-	}
-
-	private <A extends Annotation> A findAnnotation(AnnotationProvider ap, Class<A> a) {
-		if (a == null)
-			return null;
-		if (ap == null)
-			throw unsupportedOp();
-		// Inline Context.firstDeclaredAnnotation() call
-		A t = ap.getAnnotationProvider().findDeclared(a, c).map(x -> x.inner()).filter(x -> true).findFirst().orElse(null);
-		if (nn(t))
-			return t;
-		ClassInfo sci = getSuperclass();
-		if (nn(sci)) {
-			t = sci.getAnnotation(ap, a);
-			if (nn(t))
-				return t;
-		}
-		for (var c2 : interfaces.get()) {
-			t = c2.getAnnotation(ap, a);
-			if (nn(t))
-				return t;
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the first type parameter of this type if it's parameterized (e.g., T in Optional&lt;T&gt;).
-	 *
-	 * @param parameterizedType The expected parameterized class (e.g., Optional.class).
-	 * @return The first type parameter, or <jk>null</jk> if not parameterized or no parameters exist.
-	 */
-	private Type getFirstParameterType(Class<?> parameterizedType) {
-		if (t instanceof ParameterizedType pt) {
-			var ta = pt.getActualTypeArguments();
-			if (ta.length > 0)
-				return ta[0];
-		} else if (t instanceof Class<?> c) /* Class that extends Optional<T> */ {
-			if (c != parameterizedType && parameterizedType.isAssignableFrom(c))
-				return ClassInfo.of(c).getParameterType(0, parameterizedType);
-		}
-		return null;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this type is a parameterized type of the specified class or a subclass of it.
-	 *
-	 * @param c The class to check against (e.g., Optional.class, List.class).
-	 * @return <jk>true</jk> if this is Optional&lt;T&gt; or a subclass like MyOptional extends Optional&lt;String&gt;.
-	 */
-	private boolean isParameterizedTypeOf(Class<?> c) {
-		return (t instanceof ParameterizedType t2 && t2.getRawType() == c) || (t instanceof Class && c.isAssignableFrom((Class<?>)t));
-	}
-
-	/**
-	 * Returns all annotations declared directly on this class, wrapped in {@link AnnotationInfo} objects.
-	 *
-	 * <p>
-	 * This includes annotations explicitly applied to the class declaration, but excludes inherited annotations
-	 * from parent classes. Each annotation is wrapped for additional functionality such as annotation member
-	 * access and metadata inspection.
-	 *
-	 * @return
-	 * 	An unmodifiable list of {@link AnnotationInfo} wrappers for annotations declared directly on this class.
-	 * 	<br>List is empty if no annotations are declared.
-	 * 	<br>Results are in declaration order.
-	 */
-	public List<AnnotationInfo> getDeclaredAnnotationInfos() {
-		return declaredAnnotations2.get();
-	}
-
-	ConstructorInfo getConstructorInfo(Constructor<?> x) {
-		return constructorCache.get(x, () -> new ConstructorInfo(this, x));
-	}
-
-	FieldInfo getFieldInfo(Field x) {
-		return fieldCache.get(x, () -> new FieldInfo(this, x));
-	}
-
-	MethodInfo getMethodInfo(Method x) {
-		return methodCache.get(x, () -> new MethodInfo(this, x));
-	}
-
-	private List<ClassInfo> findParents() {
-		List<ClassInfo> l = list();
-		Class<?> pc = c;
-		while (nn(pc) && pc != Object.class) {
-			l.add(of(pc));
-			pc = pc.getSuperclass();
-		}
-		return u(l);
-	}
-
-	private MethodInfo findRepeatedAnnotationMethod() {
-		return getPublicMethods().stream()
-			.filter(m -> m.hasName("value"))
-			.filter(m -> m.getReturnType().isArray())
-			.filter(m -> {
-				var rct = m.getReturnType().getComponentType();
-				if (rct.hasAnnotation(Repeatable.class)) {
-					var r = rct.getAnnotationInfos(Repeatable.class).findFirst().map(AnnotationInfo::inner).orElse(null);
-					return r != null && r.value().equals(c);
-				}
-				return false;
-			})
-			.findFirst()
-			.orElse(null);
-	}
-
-	private int findDimensions() {
-		int d = 0;
-		Type ct = t;
-
-		// Handle GenericArrayType (e.g., List<String>[])
-		while (ct instanceof GenericArrayType gat) {
-			d++;
-			ct = gat.getGenericComponentType();
-		}
-
-		// Handle regular arrays
-		Class<?> cc = c;
-		while (nn(cc) && cc.isArray()) {
-			d++;
-			cc = cc.getComponentType();
-		}
-
-		return d;
-	}
-
-	private ClassInfo findComponentType() {
-		Type ct = t;
-		Class<?> cc = c;
-
-		// Handle GenericArrayType (e.g., List<String>[])
-		while (ct instanceof GenericArrayType gat) {
-			ct = gat.getGenericComponentType();
-		}
-
-		// Handle regular arrays
-		while (nn(cc) && cc.isArray()) {
-			cc = cc.getComponentType();
-		}
-
-		// Return the deepest component type found
-		if (ct != t) {
-			return of(ct);
-		} else if (cc != c) {
-			return of(cc);
-		} else {
-			return this;
-		}
-	}
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// Annotatable interface methods
-	//-----------------------------------------------------------------------------------------------------------------
-
-	@Override /* Annotatable */
-	public AnnotatableType getAnnotatableType() {
-		return AnnotatableType.CLASS_TYPE;
-	}
-
-	@Override /* Annotatable */
-	public ClassInfo getClassInfo() {
-		return this;
-	}
-
-	@Override /* Annotatable */
-	public String getAnnotatableName() {
-		return getNameSimple();
-	}
-}
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/AnnotationWorkList.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/AnnotationWorkList.java
index 3880389d3e..24e205d6a3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/AnnotationWorkList.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/AnnotationWorkList.java
@@ -21,6 +21,7 @@ import static org.apache.juneau.common.utils.CollectionUtils.*;
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
+import java.util.stream.*;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.common.reflect.*;
@@ -62,18 +63,18 @@ public class AnnotationWorkList extends ArrayList<AnnotationWork> {
 	 * @param annotations The annotations to create work from.
 	 * @return A new list.
 	 */
-	public static AnnotationWorkList of(AnnotationList annotations) {
+	public static AnnotationWorkList of(Stream<AnnotationInfo<?>> annotations) {
 		return create().add(annotations);
 	}
 
 	/**
 	 * Static creator.
 	 *
-	 * @param annotations The annotations to create work from.
 	 * @param vrs The variable resolver.
+	 * @param annotations The annotations to create work from.
 	 * @return A new list.
 	 */
-	public static AnnotationWorkList of(VarResolverSession vrs, AnnotationList annotations) {
+	public static AnnotationWorkList of(VarResolverSession vrs, Stream<AnnotationInfo<?>> annotations) {
 		return create(vrs).add(annotations);
 	}
 
@@ -101,8 +102,8 @@ public class AnnotationWorkList extends ArrayList<AnnotationWork> {
 	 * @param annotations The annotations to create work from.
 	 * @return This object.
 	 */
-	public AnnotationWorkList add(AnnotationList annotations) {
-		annotations.sort().forEach(x -> applyAnnotation(x));
+	public AnnotationWorkList add(Stream<AnnotationInfo<?>> annotations) {
+		annotations.sorted(Comparator.comparingInt(AnnotationInfo::getRank)).forEach(this::applyAnnotation);
 		return this;
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index 416a5bbe85..ccbb91acae 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -335,7 +335,7 @@ public abstract class Context {
 		 * 	<jk>public class</jk> MyClass {...}
 		 *
 		 * 	<jc>// Find all annotations that themselves are annotated with @ContextPropertiesApply.</jc>
-		 * 	AnnotationList <jv>annotations</jv> = ClassInfo.<jsm>of</jsm>(MyClass.<jk>class</jk>).getAnnotationList(<jsf>CONTEXT_APPLY_FILTER</jsf>);
+		 * 	Stream&lt;AnnotationInfo&lt;?&gt;&gt; <jv>annotations</jv> = ClassInfo.<jsm>of</jsm>(MyClass.<jk>class</jk>).getAnnotationInfos().stream().filter(<jsf>CONTEXT_APPLY_FILTER</jsf>);
 		 * 	VarResolverSession <jv>vrs</jv> = VarResolver.<jsf>DEFAULT</jsf>.createSession();
 		 * 	AnnotationWorkList <jv>work</jv> = AnnotationWorkList.of(<jv>vrs</jv>, <jv>annotations</jv>);
 		 *
@@ -674,13 +674,13 @@ public abstract class Context {
 		private static AnnotationWorkList traverse(AnnotationWorkList work, Object x) {
 			CollectionUtils.traverse(x, y -> {
 				if (x instanceof Class<?> x2)
-					work.add(rstream(ClassInfo.of(x2).getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
+					work.add(rstream(ClassInfo.of(x2).getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).map(ai -> (AnnotationInfo<?>)ai));
 				else if (x instanceof ClassInfo x2)
-					work.add(rstream(x2.getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
+					work.add(rstream(x2.getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).map(ai -> (AnnotationInfo<?>)ai));
 				else if (x instanceof Method x2)
-					work.add(rstream(MethodInfo.of(x2).getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
+					work.add(rstream(MethodInfo.of(x2).getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).map(ai -> (AnnotationInfo<?>)ai));
 				else if (x instanceof MethodInfo x2)
-					work.add(rstream(x2.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
+					work.add(rstream(x2.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).map(ai -> (AnnotationInfo<?>)ai));
 				else
 					illegalArg("Invalid type passed to applyAnnotations:  {0}", cn(x));
 			});
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
index 39a34f9685..dd95e37a74 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
@@ -64,20 +64,20 @@ public class RemoteOperationMeta {
 
 			var mi = MethodInfo.of(m);
 
-		AnnotationList al = rstream(mi.getAllAnnotationInfos()).filter(REMOTE_OP_GROUP).collect(Collectors.toCollection(AnnotationList::new));
-		if (al.isEmpty())
-			al = rstream(mi.getReturnType().unwrap(Value.class, Optional.class).getAnnotationInfos()).filter(REMOTE_OP_GROUP).collect(Collectors.toCollection(AnnotationList::new));
-
-		var _httpMethod = Value.<String>empty();
-		var _path = Value.<String>empty();
-		al.stream().map(x -> x.getName().substring(6).toUpperCase()).filter(x -> ! x.equals("OP")).forEach(x -> _httpMethod.set(x));
-		al.forEachValue(String.class, "method", NOT_EMPTY, x -> _httpMethod.set(x.trim().toUpperCase()));
-		al.forEachValue(String.class, "path", NOT_EMPTY, x -> _path.set(x.trim()));
+			List<AnnotationInfo<?>> al = rstream(mi.getAllAnnotationInfos()).filter(REMOTE_OP_GROUP).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList());
+			if (al.isEmpty())
+				al = rstream(mi.getReturnType().unwrap(Value.class, Optional.class).getAnnotationInfos()).filter(REMOTE_OP_GROUP).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList());
+
+			var _httpMethod = Value.<String>empty();
+			var _path = Value.<String>empty();
+			al.stream().map(x -> x.getName().substring(6).toUpperCase()).filter(x -> ! x.equals("OP")).forEach(x -> _httpMethod.set(x));
+			al.forEach(ai -> ai.forEachValue(String.class, "method", NOT_EMPTY, x -> _httpMethod.set(x.trim().toUpperCase())));
+			al.forEach(ai -> ai.forEachValue(String.class, "path", NOT_EMPTY, x -> _path.set(x.trim())));
 			httpMethod = _httpMethod.orElse("").trim();
 			path = _path.orElse("").trim();
 
 			Value<String> value = Value.empty();
-			al.forEach(RemoteOp.class, x -> isNotEmpty(x.inner().value().trim()), x -> value.set(x.inner().value().trim()));
+			al.stream().filter(x -> x.isType(RemoteOp.class) && isNotEmpty(((RemoteOp)x.inner()).value().trim())).forEach(x -> value.set(((RemoteOp)x.inner()).value().trim()));
 
 			if (value.isPresent()) {
 				String v = value.get();
@@ -89,8 +89,8 @@ public class RemoteOperationMeta {
 					path = v.substring(i).trim();
 				}
 			} else {
-				al.forEach(x -> ! x.isType(RemoteOp.class) && isNotEmpty(x.getValue(String.class, "value", NOT_EMPTY).orElse("").trim()),
-					x -> value.set(x.getValue(String.class, "value", NOT_EMPTY).get().trim()));
+				al.stream().filter(x -> ! x.isType(RemoteOp.class) && isNotEmpty(x.getValue(String.class, "value", NOT_EMPTY).orElse("").trim()))
+					.forEach(x -> value.set(x.getValue(String.class, "value", NOT_EMPTY).get().trim()));
 				if (value.isPresent())
 					path = value.get();
 			}
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationReturn.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationReturn.java
index 759dd33442..5ef11c76a7 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationReturn.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationReturn.java
@@ -49,9 +49,9 @@ public class RemoteOperationReturn {
 	RemoteOperationReturn(MethodInfo m) {
 		ClassInfo rt = m.getReturnType();
 
-		AnnotationList al = rstream(m.getAllAnnotationInfos()).filter(REMOTE_OP_GROUP).collect(Collectors.toCollection(AnnotationList::new));
+		List<AnnotationInfo<?>> al = rstream(m.getAllAnnotationInfos()).filter(REMOTE_OP_GROUP).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList());
 		if (al.isEmpty())
-			al = rstream(m.getReturnType().unwrap(Value.class, Optional.class).getAnnotationInfos()).filter(REMOTE_OP_GROUP).collect(Collectors.toCollection(AnnotationList::new));
+			al = rstream(m.getReturnType().unwrap(Value.class, Optional.class).getAnnotationInfos()).filter(REMOTE_OP_GROUP).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList());
 
 		RemoteReturn rv = null;
 
@@ -67,7 +67,7 @@ public class RemoteOperationReturn {
 			rv = RemoteReturn.NONE;
 		} else {
 			Value<RemoteReturn> v = Value.of(RemoteReturn.BODY);
-			al.forEachValue(RemoteReturn.class, "returns", x -> true, x -> v.set(x));
+			al.forEach(ai -> ai.forEachValue(RemoteReturn.class, "returns", x -> true, x -> v.set(x)));
 			rv = v.get();
 		}
 
diff --git a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/remote/RemoteUtils.java b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/remote/RemoteUtils.java
index a7108fbe61..ccf07672b3 100644
--- a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/remote/RemoteUtils.java
+++ b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/remote/RemoteUtils.java
@@ -26,7 +26,10 @@ import org.apache.juneau.common.reflect.*;
 public class RemoteUtils {
 
 	/**
-	 * Predicate that can be used with the {@link ClassInfo#getAnnotationList(Predicate)} and {@link MethodInfo#getAnnotationList(Predicate)}
+	 * Predicate that can be used to filter annotation streams.
+	 * 
+	 * <p>
+	 * Example: <c>methodInfo.getAllAnnotationInfos().stream().filter(REMOTE_OP_GROUP)</c>
 	 */
 	public static final Predicate<AnnotationInfo<?>> REMOTE_OP_GROUP = x -> x.isInGroup(RemoteOp.class);
 }
\ No newline at end of file
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 05578dce4d..9d53837c98 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
@@ -1786,7 +1786,7 @@ public class RestContext extends Context {
 			});
 
 			var vrs = varResolver().build().createSession();
-			var work = AnnotationWorkList.of(vrs, rstream(rci.getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
+			var work = AnnotationWorkList.of(vrs, rstream(rci.getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).map(ai -> (AnnotationInfo<?>)ai));
 
 			apply(work);
 			beanContext().apply(work);
@@ -4581,7 +4581,7 @@ public class RestContext extends Context {
 			// @formatter:on
 
 			for (var mi : rci.getPublicMethods()) {
-				AnnotationList al = rstream(mi.getAllAnnotationInfos()).filter(REST_OP_GROUP).collect(Collectors.toCollection(AnnotationList::new));
+				List<AnnotationInfo<?>> al = rstream(mi.getAllAnnotationInfos()).filter(REST_OP_GROUP).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList());
 
 				// Also include methods on @Rest-annotated interfaces.
 				if (al.isEmpty()) {
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 3007e2eeb7..d55620ae15 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
@@ -135,26 +135,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				var vr = context.getVarResolver();
 				var vrs = vr.createSession();
 
-//				var oldList = mi.getAnnotationList(CONTEXT_APPLY_FILTER);
-				var newList = rstream(mi.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new));
-			
-//			if (!oldList.equals(newList)) {
-//				var sb = new StringBuilder();
-//				sb.append("\n=== ANNOTATION MISMATCH for method: ").append(mi.getFullName()).append(" ===\n");
-//				sb.append("OLD way size: ").append(oldList.size()).append("\n");
-//				sb.append("NEW way size: ").append(newList.size()).append("\n");
-//				sb.append("OLD way:\n");
-//				oldList.forEach(x -> sb.append("  ").append(x.toSimpleString()).append("\n"));
-//				sb.append("NEW way:\n");
-//				newList.forEach(x -> sb.append("  ").append(x.toSimpleString()).append("\n"));
-//				sb.append("In OLD but not NEW:\n");
-//				oldList.stream().filter(x -> !newList.contains(x)).forEach(x -> sb.append("  - ").append(x.toSimpleString()).append("\n"));
-//				sb.append("In NEW but not OLD:\n");
-//				newList.stream().filter(x -> !oldList.contains(x)).forEach(x -> sb.append("  + ").append(x.toSimpleString()).append("\n"));
-//				System.err.println(sb);
-//			}
-
-				var work = AnnotationWorkList.of(vrs, newList);
+				var work = AnnotationWorkList.of(vrs, rstream(mi.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).map(ai -> (AnnotationInfo<?>)ai));
 
 				apply(work);
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOpAnnotation.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOpAnnotation.java
index b0c5dd1c39..bdae10996d 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOpAnnotation.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestOpAnnotation.java
@@ -609,7 +609,10 @@ public class RestOpAnnotation {
 	/** Default value */
 	public static final RestOp DEFAULT = create().build();
 	/**
-	 * Predicate that can be used with the {@link ClassInfo#getAnnotationList(Predicate)} and {@link MethodInfo#getAnnotationList(Predicate)}
+	 * Predicate that can be used to filter annotation streams.
+	 * 
+	 * <p>
+	 * Example: <c>classInfo.getAnnotationInfos().stream().filter(REST_OP_GROUP)</c>
 	 */
 	public static final Predicate<AnnotationInfo<?>> REST_OP_GROUP = x -> x.isInGroup(RestOp.class);
 
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 de1c359533..a17300a2e9 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
@@ -86,16 +86,18 @@ public class BasicDebugEnablement extends DebugEnablement {
 		// @formatter:off
 		ci.getPublicMethods().stream()
 			.forEach(x -> {
-				rstream(x.getAllAnnotationInfos()).filter(REST_OP_GROUP).collect(Collectors.toCollection(AnnotationList::new)).forEachValue(
-					String.class,
-					"debug",
-					y -> true,
-					y -> {
-						String y2 = varResolver.resolve(y);
-						if (! y2.isEmpty())
-							b.enable(Enablement.fromString(y2), x.getFullName());
-					}
-				);
+				rstream(x.getAllAnnotationInfos()).filter(REST_OP_GROUP).forEach(ai -> {
+						ai.forEachValue(
+							String.class,
+							"debug",
+							y -> true,
+							y -> {
+								String y2 = varResolver.resolve(y);
+								if (! y2.isEmpty())
+									b.enable(Enablement.fromString(y2), x.getFullName());
+							}
+						);
+				});
 			}
 		);
 		// @formatter:on
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/ClientVersionMatcher.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/ClientVersionMatcher.java
index 5576e31036..482ebf29f2 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/ClientVersionMatcher.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/matcher/ClientVersionMatcher.java
@@ -51,7 +51,7 @@ public class ClientVersionMatcher extends RestMatcher {
 	public ClientVersionMatcher(String clientVersionHeader, MethodInfo mi) {
 		this.clientVersionHeader = isEmpty(clientVersionHeader) ? "Client-Version" : clientVersionHeader;
 		Value<String> clientVersion = Value.empty();
-		rstream(mi.getAllAnnotationInfos()).filter(REST_OP_GROUP).collect(Collectors.toCollection(AnnotationList::new)).forEachValue(String.class, "clientVersion", NOT_EMPTY, x -> clientVersion.set(x));
+		rstream(mi.getAllAnnotationInfos()).filter(REST_OP_GROUP).forEach(ai -> ai.forEachValue(String.class, "clientVersion", NOT_EMPTY, x -> clientVersion.set(x)));
 		range = new VersionRange(clientVersion.orElse(null));
 	}
 
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
index cbb78aa40d..5c0f2fd34c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/swagger/BasicSwaggerProviderSession.java
@@ -273,7 +273,7 @@ public class BasicSwaggerProviderSession {
 
 			Method m = sm.getJavaMethod();
 			var mi = MethodInfo.of(m);
-			AnnotationList al = rstream(mi.getAllAnnotationInfos()).filter(REST_OP_GROUP).collect(Collectors.toCollection(AnnotationList::new));
+			List<AnnotationInfo<?>> al = rstream(mi.getAllAnnotationInfos()).filter(REST_OP_GROUP).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList());
 			String mn = m.getName();
 
 			// Get the operation from the existing swagger so far.
@@ -281,7 +281,7 @@ public class BasicSwaggerProviderSession {
 
 			// Add @RestOp(swagger)
 			Value<OpSwagger> _ms = Value.empty();
-			al.forEachValue(OpSwagger.class, "swagger", OpSwaggerAnnotation::notEmpty, x -> _ms.set(x));
+			al.forEach(ai -> ai.forEachValue(OpSwagger.class, "swagger", OpSwaggerAnnotation::notEmpty, x -> _ms.set(x)));
 			OpSwagger ms = _ms.orElseGet(() -> OpSwaggerAnnotation.create().build());
 
 			op.append(parseMap(ms.value(), "@OpSwagger(value) on class {0} method {1}", c, m));
@@ -294,7 +294,7 @@ public class BasicSwaggerProviderSession {
 			);
 
 			Value<String> _summary = Value.empty();
-			al.forEachValue(String.class, "summary", NOT_EMPTY, x -> _summary.set(x));
+			al.forEach(ai -> ai.forEachValue(String.class, "summary", NOT_EMPTY, x -> _summary.set(x)));
 			op.appendIf(ne, "summary",
 				firstNonEmpty(
 					resolve(ms.summary()),
@@ -305,7 +305,7 @@ public class BasicSwaggerProviderSession {
 			);
 
 			Value<String[]> _description = Value.empty();
-			al.forEachValue(String[].class, "description", x -> x.length > 0, x -> _description.set(x));
+			al.forEach(ai -> ai.forEachValue(String[].class, "description", x -> x.length > 0, x -> _description.set(x)));
 			op.appendIf(ne, "description",
 				firstNonEmpty(
 					resolve(ms.description()),
diff --git a/juneau-utest/src/test/java/org/apache/juneau/annotation/BeanConfigAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/annotation/BeanConfigAnnotation_Test.java
index 63f5a8c488..57d90439ed 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/annotation/BeanConfigAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/annotation/BeanConfigAnnotation_Test.java
@@ -145,7 +145,7 @@ class BeanConfigAnnotation_Test extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void a01_basic() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var bs = JsonSerializer.create().apply(al).build().getSession();
 
 		check("PRIVATE", bs.getBeanClassVisibility());
@@ -188,7 +188,7 @@ class BeanConfigAnnotation_Test extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void b01_noValues() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var js = JsonSerializer.create().apply(al).build();
 		var bc = js.getBeanContext();
 		check("PUBLIC", bc.getBeanClassVisibility());
@@ -233,7 +233,7 @@ class BeanConfigAnnotation_Test extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void c01_noAnnotation() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var js = JsonSerializer.create().apply(al).build();
 		var bc = js.getBeanContext();
 		check("PUBLIC", bc.getBeanClassVisibility());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/annotation/Bean_Test.java b/juneau-utest/src/test/java/org/apache/juneau/annotation/Bean_Test.java
index f1d1af0a39..e435b03adb 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/annotation/Bean_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/annotation/Bean_Test.java
@@ -73,7 +73,7 @@ class Bean_Test extends TestBase {
 	static ClassInfo a2ci = ClassInfo.of(A2Config.class);
 
 	@Test void a02_beanAnnotationOverridesPrivate_usingConfig() throws Exception {
-		var al = AnnotationWorkList.of(rstream(a2ci.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(rstream(a2ci.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var js = Json5Serializer.create().apply(al).build();
 		var jp = JsonParser.create().apply(al).build();
 
@@ -157,7 +157,7 @@ class Bean_Test extends TestBase {
 	static ClassInfo b2ci = ClassInfo.of(B2Config.class);
 
 	@Test void a04_beanxAnnotationOverridesPrivate_usingConfig() throws Exception {
-		var al = AnnotationWorkList.of(rstream(b2ci.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(rstream(b2ci.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var js = Json5Serializer.create().apply(al).build();
 		var jp = JsonParser.create().apply(al).build();
 
@@ -224,7 +224,7 @@ class Bean_Test extends TestBase {
 	}
 
 	@Test void d03_beanPropertiesExcludePropertiesCombined_beanConfigOverride() throws Exception {
-		var al = AnnotationWorkList.of(vr, rstream(dConfig.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(vr, rstream(dConfig.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var js = Json5Serializer.create().apply(al).build();
 		var jp = JsonParser.create().apply(al).build();
 
@@ -236,7 +236,7 @@ class Bean_Test extends TestBase {
 	}
 
 	@Test void d04_beanPXpCombined_beanConfigOverride() throws Exception {
-		var al = AnnotationWorkList.of(vr, rstream(dConfig.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(vr, rstream(dConfig.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var js = Json5Serializer.create().apply(al).build();
 		var jp = JsonParser.create().apply(al).build();
 
@@ -335,7 +335,7 @@ class Bean_Test extends TestBase {
 	}
 
 	@Test void e03_beanPropertiesExcludePropertiesCombined_multipleBeanAnnotations_beanConfigOverride() throws Exception {
-		var al = AnnotationWorkList.of(vr, rstream(eConfig.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(vr, rstream(eConfig.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var js = Json5Serializer.create().apply(al).build();
 		var jp = JsonParser.create().apply(al).build();
 
@@ -347,7 +347,7 @@ class Bean_Test extends TestBase {
 	}
 
 	@Test void e04_beanPXpCombined_multipleBeanAnnotations_beanConfigOverride() throws Exception {
-		var al = AnnotationWorkList.of(vr, rstream(eConfig.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(vr, rstream(eConfig.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var js = Json5Serializer.create().apply(al).build();
 		var jp = JsonParser.create().apply(al).build();
 
diff --git a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/AnnotationInfoTest.java b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/AnnotationInfoTest.java
index 80ec937347..ceff76957f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/AnnotationInfoTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/AnnotationInfoTest.java
@@ -53,7 +53,7 @@ class AnnotationInfoTest extends TestBase {
 
 	@Test void d01_isInGroup() {
 		var d = ClassInfo.of(D.class);
-		var l = rstream(d.getAnnotationInfos()).filter(x -> x.isInGroup(D1.class)).collect(Collectors.toCollection(AnnotationList::new));
+		var l = rstream(d.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).filter(x -> x.isInGroup(D1.class));
 		assertSize(2, l);
 	}
 }
\ No newline at end of file
diff --git a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ClassInfo_Test.java b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ClassInfo_Test.java
index f96e899552..df9e56c032 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ClassInfo_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ClassInfo_Test.java
@@ -118,9 +118,6 @@ public class ClassInfo_Test extends TestBase {
 			return "@AConfig(" + ((AConfig)t).value() + ")";
 		if (t instanceof AnnotationInfo)
 			return ClassInfo_Test.TO_STRING.apply(((AnnotationInfo<?>)t).inner());
-		if (t instanceof AnnotationList al) {
-			return al.toString();
-		}
 		return t.toString();
 	};
 
@@ -572,26 +569,26 @@ public class ClassInfo_Test extends TestBase {
 	}
 
 	@Test void getAnnotations() {
-		check("@A(2),@A(1),@A(5),@A(3),@A(6),@A(7)", rstream(g3.getAnnotationInfos()).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).toList());
-		check("@A(2),@A(1),@A(5),@A(3),@A(6),@A(7)", rstream(g4.getAnnotationInfos()).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).toList());
-		check("@A(3)", rstream(g5.getAnnotationInfos()).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).toList());
+		check("@A(2),@A(1),@A(5),@A(3),@A(6),@A(7)", rstream(g3.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).toList());
+		check("@A(2),@A(1),@A(5),@A(3),@A(6),@A(7)", rstream(g4.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).toList());
+		check("@A(3)", rstream(g5.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).toList());
 	}
 
 	@Test void forEachAnnotation() {
 		var l1 = list();
-		rstream(g3.getAnnotationInfos()).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x -> l1.add(x.value()));
+		rstream(g3.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x -> l1.add(x.value()));
 		assertList(l1, "2", "1", "5", "3", "6", "7");
 
 		var l2 = list();
-		rstream(g4.getAnnotationInfos()).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x -> l2.add(x.value()));
+		rstream(g4.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x -> l2.add(x.value()));
 		assertList(l2, "2", "1", "5", "3", "6", "7");
 
 		var l3 = list();
-		rstream(g5.getAnnotationInfos()).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x -> l3.add(x.value()));
+		rstream(g5.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).forEach(x -> l3.add(x.value()));
 		assertList(l3, "3");
 
 		var l4 = list();
-		rstream(g3.getAnnotationInfos()).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).filter(x -> x.value() == 5).forEach(x -> l4.add(x.value()));
+		rstream(g3.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).map(x -> x.cast(A.class)).filter(Objects::nonNull).map(AnnotationInfo::inner).filter(x -> x.value() == 5).forEach(x -> l4.add(x.value()));
 		assertList(l4, "5");
 	}
 
@@ -616,9 +613,9 @@ public class ClassInfo_Test extends TestBase {
 
 	@Test void getAnnotationsMapParentFirst() {
 		// Note: Order changed after inlining - interfaces now processed when they appear in hierarchy, not after all classes
-		check("@PA(10),@A(2),@A(1),@A(5),@A(3),@A(6),@A(7)", rstream(g3.getAnnotationInfos()).collect(Collectors.toList()));
-		check("@PA(10),@A(2),@A(1),@A(5),@A(3),@A(6),@A(7)", rstream(g4.getAnnotationInfos()).collect(Collectors.toList()));
-		check("@PA(10),@A(3)", rstream(g5.getAnnotationInfos()).collect(Collectors.toList()));
+		check("@PA(10),@A(2),@A(1),@A(5),@A(3),@A(6),@A(7)", rstream(g3.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList()));
+		check("@PA(10),@A(2),@A(1),@A(5),@A(3),@A(6),@A(7)", rstream(g4.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList()));
+		check("@PA(10),@A(3)", rstream(g5.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).collect(Collectors.toList()));
 	}
 
 	@A(1) @AConfig(1) interface GBI1 {}
@@ -634,9 +631,9 @@ public class ClassInfo_Test extends TestBase {
 	static ClassInfo gb3=of(GB3.class), gb4=of(GB4.class), gb5=of(GB5.class);
 
 	@Test void getConfigAnnotationsMapParentFirst() {
-		check("@AConfig(2),@AConfig(1),@AConfig(5),@AConfig(3),@AConfig(6),@AConfig(7)", rstream(gb3.getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toList()));
-		check("@AConfig(2),@AConfig(1),@AConfig(5),@AConfig(3),@AConfig(6),@AConfig(7)", rstream(gb4.getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toList()));
-		check("@AConfig(3)", rstream(gb5.getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toList()));
+		check("@AConfig(2),@AConfig(1),@AConfig(5),@AConfig(3),@AConfig(6),@AConfig(7)", rstream(gb3.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toList()));
+		check("@AConfig(2),@AConfig(1),@AConfig(5),@AConfig(3),@AConfig(6),@AConfig(7)", rstream(gb4.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toList()));
+		check("@AConfig(3)", rstream(gb5.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toList()));
 	}
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
index 09f3465005..1ba32b22e8 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/MethodInfo_Test.java
@@ -91,8 +91,6 @@ class MethodInfo_Test extends TestBase {
 				return "@PA(" + t2.value() + ")";
 			if (t instanceof AConfig t2)
 				return "@AConfig(" + t2.value() + ")";
-			if (t instanceof AnnotationList t2)
-				return t2.toString();
 			if (t instanceof ClassInfo t2)
 				return t2.getNameSimple();
 			return t.toString();
@@ -412,11 +410,11 @@ class MethodInfo_Test extends TestBase {
 
 	@Test void getConfigAnnotationsMapParentFirst() {
 		// Note: Order changed after inlining - method annotations now come after class annotations
-		check("@AConfig(C1),@AConfig(C2),@AConfig(C3),@AConfig(a1)", rstream(cb_a1.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
-		check("@AConfig(C1),@AConfig(C2),@AConfig(C3),@AConfig(a2a),@AConfig(a2b)", rstream(cb_a2.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
-		check("@AConfig(C1),@AConfig(C2),@AConfig(C3),@AConfig(a3)", rstream(cb_a3.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
-		check("@AConfig(C1),@AConfig(C2),@AConfig(C3),@AConfig(a4)", rstream(cb_a4.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
-		check("@AConfig(C1),@AConfig(C2),@AConfig(C3)", rstream(cb_a5.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
+		check("@AConfig(C1),@AConfig(C2),@AConfig(C3),@AConfig(a1)", rstream(cb_a1.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).toList());
+		check("@AConfig(C1),@AConfig(C2),@AConfig(C3),@AConfig(a2a),@AConfig(a2b)", rstream(cb_a2.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).toList());
+		check("@AConfig(C1),@AConfig(C2),@AConfig(C3),@AConfig(a3)", rstream(cb_a3.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).toList());
+		check("@AConfig(C1),@AConfig(C2),@AConfig(C3),@AConfig(a4)", rstream(cb_a4.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).toList());
+		check("@AConfig(C1),@AConfig(C2),@AConfig(C3)", rstream(cb_a5.getAllAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).toList());
 	}
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-utest/src/test/java/org/apache/juneau/csv/annotation/CsvConfig_Test.java b/juneau-utest/src/test/java/org/apache/juneau/csv/annotation/CsvConfig_Test.java
index 41f77fd5e1..40e47ad7ab 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/csv/annotation/CsvConfig_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/csv/annotation/CsvConfig_Test.java
@@ -39,12 +39,12 @@ class CsvConfig_Test extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void defaultsSerializer() {
-		var al = AnnotationWorkList.of(rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->CsvSerializer.create().apply(al).build());
 	}
 
 	@Test void defaultsParser() {
-		var al = AnnotationWorkList.of(rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->CsvParser.create().apply(al).build());
 	}
 
@@ -56,12 +56,12 @@ class CsvConfig_Test extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->CsvSerializer.create().apply(al).build());
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->CsvParser.create().apply(al).build());
 	}
 }
\ No newline at end of file
diff --git a/juneau-utest/src/test/java/org/apache/juneau/html/HtmlConfigAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/html/HtmlConfigAnnotation_Test.java
index 4c678badb3..9f0311d96b 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/html/HtmlConfigAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/html/HtmlConfigAnnotation_Test.java
@@ -58,7 +58,7 @@ class HtmlConfigAnnotation_Test extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basicSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlSerializer.create().apply(al).build().getSession();
 		check("true", x.isAddBeanTypes());
 		check("true", x.isAddKeyValueTableHeaders());
@@ -69,7 +69,7 @@ class HtmlConfigAnnotation_Test extends TestBase {
 	}
 
 	@Test void basicParser() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->HtmlParser.create().apply(al).build().createSession());
 	}
 
@@ -82,7 +82,7 @@ class HtmlConfigAnnotation_Test extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void defaultsSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 		check("false", x.isAddKeyValueTableHeaders());
@@ -93,7 +93,7 @@ class HtmlConfigAnnotation_Test extends TestBase {
 	}
 
 	@Test void defaultsParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->HtmlParser.create().apply(al).build().createSession());
 	}
 
@@ -105,7 +105,7 @@ class HtmlConfigAnnotation_Test extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 		check("false", x.isAddKeyValueTableHeaders());
@@ -116,7 +116,7 @@ class HtmlConfigAnnotation_Test extends TestBase {
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->HtmlParser.create().apply(al).build().createSession());
 	}
 }
\ No newline at end of file
diff --git a/juneau-utest/src/test/java/org/apache/juneau/html/HtmlDocConfigAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/html/HtmlDocConfigAnnotation_Test.java
index fd1c662399..fb94b0d175 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/html/HtmlDocConfigAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/html/HtmlDocConfigAnnotation_Test.java
@@ -77,7 +77,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basic() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("foo", x.getAside());
 		check("foo", x.getFooter());
@@ -102,7 +102,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void defaults() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("", x.getAside());
 		check("", x.getFooter());
@@ -126,7 +126,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotation() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("", x.getAside());
 		check("", x.getFooter());
@@ -161,7 +161,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	static ClassInfo d1 = ClassInfo.of(D1.class);
 
 	@Test void inheritance1() {
-		var al = AnnotationWorkList.of(sr, rstream(d1.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(d1.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("foo2,foo", x.getAside());
 		check("foo2,foo", x.getFooter());
@@ -189,7 +189,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	static ClassInfo d2 = ClassInfo.of(D2.class);
 
 	@Test void inheritance2() {
-		var al = AnnotationWorkList.of(sr, rstream(d2.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(d2.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("foo,foo2", x.getAside());
 		check("foo,foo2", x.getFooter());
@@ -217,7 +217,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	static ClassInfo d3 = ClassInfo.of(D3.class);
 
 	@Test void inheritance3() {
-		var al = AnnotationWorkList.of(sr, rstream(d3.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(d3.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("foo2", x.getAside());
 		check("foo2", x.getFooter());
@@ -245,7 +245,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	static ClassInfo d4 = ClassInfo.of(D4.class);
 
 	@Test void inheritance4() {
-		var al = AnnotationWorkList.of(sr, rstream(d4.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(d4.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("", x.getAside());
 		check("", x.getFooter());
@@ -299,7 +299,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	}
 
 	@Test void widgets_basic() {
-		var al = AnnotationWorkList.of(sr, rstream(e.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(e.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("$W{E}", x.getAside());
 		check("$W{E}", x.getFooter());
@@ -316,7 +316,7 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	}
 
 	@Test void widgets_resolution() throws Exception {
-		var al = AnnotationWorkList.of(sr, rstream(e.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(e.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		var r = x.serialize(null).replaceAll("[\r\n]+", "|");
 		assertContainsAll(r, "<aside>xxx</aside>","<footer>xxx</footer>","<head>xxx","<style>@import \"xxx\"; xxx zzz</style>","<nav><ol><li>xxx</li></ol>xxx</nav>","<script>xxx| yyy|</script>");
@@ -362,31 +362,31 @@ class HtmlDocConfigAnnotation_Test extends TestBase {
 	static ClassInfo f5 = ClassInfo.of(F5.class);
 
 	@Test void e01_rankedAnnotations_f1() {
-		var al = AnnotationWorkList.of(sr, rstream(f1.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(f1.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("f1", x.getAside());
 	}
 
 	@Test void e02_rankedAnnotations_f2() {
-		var al = AnnotationWorkList.of(sr, rstream(f2.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(f2.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("f1", x.getAside());
 	}
 
 	@Test void e03_rankedAnnotations_f3() {
-		var al = AnnotationWorkList.of(sr, rstream(f3.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(f3.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("f3", x.getAside());
 	}
 
 	@Test void e04_rankedAnnotations_f4() {
-		var al = AnnotationWorkList.of(sr, rstream(f4.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(f4.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("f3", x.getAside());
 	}
 
 	@Test void e05_rankedAnnotations_f5() {
-		var al = AnnotationWorkList.of(sr, rstream(f5.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(f5.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = HtmlDocSerializer.create().apply(al).build().getSession();
 		check("f5", x.getAside());
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/json/JsonConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/json/JsonConfigAnnotationTest.java
index d54774207f..558cd5a297 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/json/JsonConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/json/JsonConfigAnnotationTest.java
@@ -55,7 +55,7 @@ class JsonConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basicSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSerializer.create().apply(al).build().getSession();
 		check("true", x.isAddBeanTypes());
 		check("true", x.isEscapeSolidus());
@@ -63,7 +63,7 @@ class JsonConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void basicParser() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonParser.create().apply(al).build().getSession();
 		check("true", x.isValidateEnd());
 	}
@@ -77,7 +77,7 @@ class JsonConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 		check("false", x.isEscapeSolidus());
@@ -85,7 +85,7 @@ class JsonConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noValuesParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonParser.create().apply(al).build().getSession();
 		check("false", x.isValidateEnd());
 	}
@@ -98,7 +98,7 @@ class JsonConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 		check("false", x.isEscapeSolidus());
@@ -106,7 +106,7 @@ class JsonConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonParser.create().apply(al).build().getSession();
 		check("false", x.isValidateEnd());
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/jsonschema/JsonSchemaConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/jsonschema/JsonSchemaConfigAnnotationTest.java
index 741f34eaad..74ffb9842d 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/jsonschema/JsonSchemaConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/jsonschema/JsonSchemaConfigAnnotationTest.java
@@ -68,7 +68,7 @@ class JsonSchemaConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basic() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSchemaGenerator.create().apply(al).build().getSession();
 		check("BEAN", x.getAddDescriptionsTo());
 		check("BEAN", x.getAddExamplesTo());
@@ -88,7 +88,7 @@ class JsonSchemaConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValues() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSchemaGenerator.create().apply(al).build().getSession();
 		check("", x.getAddDescriptionsTo());
 		check("", x.getAddExamplesTo());
@@ -107,7 +107,7 @@ class JsonSchemaConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotation() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSchemaGenerator.create().apply(al).build().getSession();
 		check("", x.getAddDescriptionsTo());
 		check("", x.getAddExamplesTo());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorTest.java b/juneau-utest/src/test/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorTest.java
index 24feb82548..1f0eec267a 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorTest.java
@@ -1304,7 +1304,7 @@ class JsonSchemaGeneratorTest extends TestBase {
 	static ClassInfo bConfig = ClassInfo.of(BConfig.class);
 
 	@Test void schemaOnClass_onConfig() throws Exception {
-		var al = AnnotationWorkList.of(rstream(bConfig.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(rstream(bConfig.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSchemaGenerator.create().apply(al).build().getSession();
 		assertContains("$ref", r(x.getSchema(new B())));
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/msgpack/MsgPackConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/msgpack/MsgPackConfigAnnotationTest.java
index 55128e9758..0f784643c3 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/msgpack/MsgPackConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/msgpack/MsgPackConfigAnnotationTest.java
@@ -52,13 +52,13 @@ class MsgPackConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basicSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackSerializer.create().apply(al).build().getSession();
 		check("true", x.isAddBeanTypes());
 	}
 
 	@Test void basicParser() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->MsgPackParser.create().apply(al).build().createSession());
 	}
 
@@ -71,13 +71,13 @@ class MsgPackConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 	}
 
 	@Test void noValuesParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->MsgPackParser.create().apply(al).build().createSession());
 	}
 
@@ -89,13 +89,13 @@ class MsgPackConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->MsgPackParser.create().apply(al).build().createSession());
 	}
 }
\ No newline at end of file
diff --git a/juneau-utest/src/test/java/org/apache/juneau/oapi/OpenApiConfigAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/oapi/OpenApiConfigAnnotation_Test.java
index 96a24b5972..c0b70cf288 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/oapi/OpenApiConfigAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/oapi/OpenApiConfigAnnotation_Test.java
@@ -43,12 +43,12 @@ class OpenApiConfigAnnotation_Test extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->OpenApiSerializer.create().apply(al).build().createSession());
 	}
 
 	@Test void noValuesParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->OpenApiParser.create().apply(al).build().createSession());
 	}
 
@@ -60,12 +60,12 @@ class OpenApiConfigAnnotation_Test extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->OpenApiSerializer.create().apply(al).build().createSession());
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->OpenApiParser.create().apply(al).build().createSession());
 	}
 }
\ No newline at end of file
diff --git a/juneau-utest/src/test/java/org/apache/juneau/parser/ParserConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/parser/ParserConfigAnnotationTest.java
index a0bb88bb1e..160e5d3c54 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/parser/ParserConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/parser/ParserConfigAnnotationTest.java
@@ -71,7 +71,7 @@ class ParserConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basicReaderParser() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonParser.create().apply(al).build().getSession();
 		check("true", x.isAutoCloseStreams());
 		check("1", x.getDebugOutputLines());
@@ -84,7 +84,7 @@ class ParserConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void basicInputStreamParser() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackParser.create().apply(al).build().getSession();
 		check("true", x.isAutoCloseStreams());
 		check("HEX", x.getBinaryFormat());
@@ -104,7 +104,7 @@ class ParserConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesReaderParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonParser.create().apply(al).build().getSession();
 		check("false", x.isAutoCloseStreams());
 		check("5", x.getDebugOutputLines());
@@ -117,7 +117,7 @@ class ParserConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noValuesInputStreamParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackParser.create().apply(al).build().getSession();
 		check("false", x.isAutoCloseStreams());
 		check("HEX", x.getBinaryFormat());
@@ -136,7 +136,7 @@ class ParserConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationReaderParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonParser.create().apply(al).build().getSession();
 		check("false", x.isAutoCloseStreams());
 		check("5", x.getDebugOutputLines());
@@ -149,7 +149,7 @@ class ParserConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noAnnotationInputStreamParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackParser.create().apply(al).build().getSession();
 		check("false", x.isAutoCloseStreams());
 		check("HEX", x.getBinaryFormat());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/plaintext/PlainTextConfigAnnotation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/plaintext/PlainTextConfigAnnotation_Test.java
index e3822affd5..7a2c48a818 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/plaintext/PlainTextConfigAnnotation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/plaintext/PlainTextConfigAnnotation_Test.java
@@ -42,12 +42,12 @@ class PlainTextConfigAnnotation_Test extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->PlainTextSerializer.create().apply(al).build().createSession());
 	}
 
 	@Test void noValuesParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->PlainTextParser.create().apply(al).build().createSession());
 	}
 
@@ -59,12 +59,12 @@ class PlainTextConfigAnnotation_Test extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->PlainTextSerializer.create().apply(al).build().createSession());
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		assertDoesNotThrow(()->PlainTextParser.create().apply(al).build().createSession());
 	}
 }
\ No newline at end of file
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
index a22fb17001..06d5673209 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
@@ -114,7 +114,7 @@ class RestClient_Config_Context_Test extends TestBase {
 		client().applyAnnotations(A6b.class).build().post("/echoBody",A6a.get()).run().cacheContent().assertContent("{bar:2,baz:3,foo:1}").getContent().as(A6a.class);
 		client().applyAnnotations(A6c.class).build().post("/echoBody",A6a.get()).run().cacheContent().assertContent("{bar:2,baz:3,foo:1}").getContent().as(A6a.class);
 		client().applyAnnotations(A6d.class.getMethod("foo")).build().post("/echoBody",A6a.get()).run().cacheContent().assertContent("{bar:2,baz:3,foo:1}").getContent().as(A6a.class);
-		var al = AnnotationWorkList.of(rstream(ClassInfo.of(A6c.class).getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(rstream(ClassInfo.of(A6c.class).getAnnotationInfos()).filter(CONTEXT_APPLY_FILTER).map(ai -> (AnnotationInfo<?>)ai));
 		client().apply(al).build().post("/echoBody",A6a.get()).run().cacheContent().assertContent("{bar:2,baz:3,foo:1}").getContent().as(A6a.class);
 	}
 
diff --git a/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerConfigAnnotationTest.java
index a870d8aa80..12b64a2a18 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerConfigAnnotationTest.java
@@ -81,7 +81,7 @@ class SerializerConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basicWriterSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSerializer.create().apply(al).build().getSession();
 		check("true", ((SerializerSession)x).isAddBeanTypes());
 		check("true", x.isAddRootType());
@@ -105,7 +105,7 @@ class SerializerConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void basicOutputStreamSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackSerializer.create().apply(al).build().getSession();
 		check("true", ((SerializerSession)x).isAddBeanTypes());
 		check("true", x.isAddRootType());
@@ -135,7 +135,7 @@ class SerializerConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesWriterSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSerializer.create().apply(al).build().getSession();
 		check("false", ((SerializerSession)x).isAddBeanTypes());
 		check("false", x.isAddRootType());
@@ -155,7 +155,7 @@ class SerializerConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noValuesOutputStreamSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackSerializer.create().apply(al).build().getSession();
 		check("false", ((SerializerSession)x).isAddBeanTypes());
 		check("false", x.isAddRootType());
@@ -180,7 +180,7 @@ class SerializerConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationWriterSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = JsonSerializer.create().apply(al).build().getSession();
 		check("false", ((SerializerSession)x).isAddBeanTypes());
 		check("false", x.isAddRootType());
@@ -200,7 +200,7 @@ class SerializerConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noAnnotationOutputStreamSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = MsgPackSerializer.create().apply(al).build().getSession();
 		check("false", ((SerializerSession)x).isAddBeanTypes());
 		check("false", x.isAddRootType());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/soap/SoapXmlConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/soap/SoapXmlConfigAnnotationTest.java
index 81bfb42160..b9631c04cd 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/soap/SoapXmlConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/soap/SoapXmlConfigAnnotationTest.java
@@ -52,7 +52,7 @@ class SoapXmlConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basic() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = SoapXmlSerializer.create().apply(al).build().getSession();
 		check("foo", x.getSoapAction());
 	}
@@ -66,7 +66,7 @@ class SoapXmlConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValues() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = SoapXmlSerializer.create().apply(al).build().getSession();
 		check("http://www.w3.org/2003/05/soap-envelope", x.getSoapAction());
 	}
@@ -79,7 +79,7 @@ class SoapXmlConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotation() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = SoapXmlSerializer.create().apply(al).build().getSession();
 		check("http://www.w3.org/2003/05/soap-envelope", x.getSoapAction());
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/uon/UonConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/uon/UonConfigAnnotationTest.java
index df337929d4..76cdcb375d 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/uon/UonConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/uon/UonConfigAnnotationTest.java
@@ -56,7 +56,7 @@ class UonConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basicSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UonSerializer.create().apply(al).build().getSession();
 		check("true", x.isAddBeanTypes());
 		check("true", x.isEncoding());
@@ -64,7 +64,7 @@ class UonConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void basicParser() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UonParser.create().apply(al).build().getSession();
 		check("true", x.isDecoding());
 		check("true", x.isValidateEnd());
@@ -79,7 +79,7 @@ class UonConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UonSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 		check("false", x.isEncoding());
@@ -87,7 +87,7 @@ class UonConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noValuesParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UonParser.create().apply(al).build().getSession();
 		check("false", x.isDecoding());
 		check("false", x.isValidateEnd());
@@ -101,7 +101,7 @@ class UonConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UonSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 		check("false", x.isEncoding());
@@ -109,7 +109,7 @@ class UonConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UonParser.create().apply(al).build().getSession();
 		check("false", x.isDecoding());
 		check("false", x.isValidateEnd());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/urlencoding/UrlEncodingConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/urlencoding/UrlEncodingConfigAnnotationTest.java
index 3a8ca2a98e..ae6b1f3c44 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/urlencoding/UrlEncodingConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/urlencoding/UrlEncodingConfigAnnotationTest.java
@@ -52,13 +52,13 @@ class UrlEncodingConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basicSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UrlEncodingSerializer.create().apply(al).build().getSession();
 		check("true", x.isExpandedParams());
 	}
 
 	@Test void basicParser() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UrlEncodingParser.create().apply(al).build().getSession();
 		check("true", x.isExpandedParams());
 	}
@@ -72,13 +72,13 @@ class UrlEncodingConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UrlEncodingSerializer.create().apply(al).build().getSession();
 		check("false", x.isExpandedParams());
 	}
 
 	@Test void noValuesParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UrlEncodingParser.create().apply(al).build().getSession();
 		check("false", x.isExpandedParams());
 	}
@@ -91,13 +91,13 @@ class UrlEncodingConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UrlEncodingSerializer.create().apply(al).build().getSession();
 		check("false", x.isExpandedParams());
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = UrlEncodingParser.create().apply(al).build().getSession();
 		check("false", x.isExpandedParams());
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/xml/XmlConfigAnnotationTest.java b/juneau-utest/src/test/java/org/apache/juneau/xml/XmlConfigAnnotationTest.java
index dd2e8d210d..9206358d37 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/xml/XmlConfigAnnotationTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/xml/XmlConfigAnnotationTest.java
@@ -102,7 +102,7 @@ class XmlConfigAnnotationTest extends TestBase {
 	static ClassInfo a = ClassInfo.of(A.class);
 
 	@Test void basicSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = XmlSerializer.create().apply(al).build().getSession();
 		check("true", x.isAddBeanTypes());
 		check("true", x.isAddNamespaceUrisToRoot());
@@ -113,7 +113,7 @@ class XmlConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void basicParser() {
-		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(a.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = XmlParser.create().apply(al).build().getSession();
 		check("AA", x.getEventAllocator());
 		check("true", x.isPreserveRootElement());
@@ -131,7 +131,7 @@ class XmlConfigAnnotationTest extends TestBase {
 	static ClassInfo b = ClassInfo.of(B.class);
 
 	@Test void noValuesSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = XmlSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 		check("false", x.isAddNamespaceUrisToRoot());
@@ -142,7 +142,7 @@ class XmlConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noValuesParser() {
-		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(b.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = XmlParser.create().apply(al).build().getSession();
 		check(null, x.getEventAllocator());
 		check("false", x.isPreserveRootElement());
@@ -159,7 +159,7 @@ class XmlConfigAnnotationTest extends TestBase {
 	static ClassInfo c = ClassInfo.of(C.class);
 
 	@Test void noAnnotationSerializer() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = XmlSerializer.create().apply(al).build().getSession();
 		check("false", x.isAddBeanTypes());
 		check("false", x.isAddNamespaceUrisToRoot());
@@ -170,7 +170,7 @@ class XmlConfigAnnotationTest extends TestBase {
 	}
 
 	@Test void noAnnotationParser() {
-		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).collect(Collectors.toCollection(AnnotationList::new)));
+		var al = AnnotationWorkList.of(sr, rstream(c.getAnnotationInfos()).map(ai -> (AnnotationInfo<?>)ai));
 		var x = XmlParser.create().apply(al).build().getSession();
 		check(null, x.getEventAllocator());
 		check("false", x.isPreserveRootElement());