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

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


The following commit(s) were added to refs/heads/master by this push:
     new ca2cc51  ClassInfo refactoring.
ca2cc51 is described below

commit ca2cc518b11a6747f0fd69b8f495eb5a6af2ed66
Author: JamesBognar <[email protected]>
AuthorDate: Sun Jan 23 14:25:54 2022 -0500

    ClassInfo refactoring.
---
 .../src/main/java/org/apache/juneau/BeanMeta.java  |   4 +-
 .../src/main/java/org/apache/juneau/Context.java   |  39 +++++---
 .../main/java/org/apache/juneau/MetaProvider.java  |  34 +++++--
 .../src/main/java/org/apache/juneau/Value.java     |  47 +++++++++
 .../java/org/apache/juneau/cp/BeanCreator.java     |   6 +-
 .../main/java/org/apache/juneau/cp/BeanStore.java  |  24 +++--
 .../juneau/http/annotation/FormDataAnnotation.java |  22 ++---
 .../juneau/http/annotation/HeaderAnnotation.java   |  22 ++---
 .../juneau/http/annotation/PathAnnotation.java     |  22 ++---
 .../juneau/http/annotation/QueryAnnotation.java    |  22 ++---
 .../juneau/http/remote/RrpcInterfaceMeta.java      |  11 +--
 .../org/apache/juneau/httppart/HttpPartSchema.java |   4 +-
 .../juneau/httppart/bean/ResponseBeanMeta.java     |   6 +-
 .../org/apache/juneau/httppart/bean/Utils.java     |   2 +-
 .../org/apache/juneau/internal/StringUtils.java    |   2 +
 .../java/org/apache/juneau/reflect/ClassInfo.java  |  81 ++++++++++++---
 .../org/apache/juneau/reflect/ExecutableInfo.java  |  19 +---
 .../java/org/apache/juneau/reflect/MethodInfo.java |  29 ++++--
 .../java/org/apache/juneau/reflect/ParamInfo.java  | 110 ++++++++++++++++++---
 .../juneau/rest/client/remote/RemoteMeta.java      |   7 +-
 .../java/org/apache/juneau/rest/RestContext.java   |  30 ++----
 .../org/apache/juneau/rest/arg/AttributeArg.java   |  18 ++--
 .../org/apache/juneau/rest/arg/FormDataArg.java    |   4 +-
 .../java/org/apache/juneau/rest/arg/HeaderArg.java |   4 +-
 .../java/org/apache/juneau/rest/arg/PathArg.java   |   3 +-
 .../java/org/apache/juneau/rest/arg/QueryArg.java  |   4 +-
 .../apache/juneau/rest/arg/ResponseHeaderArg.java  |   4 +-
 .../apache/juneau/rest/servlet/RestServlet.java    |  11 +--
 .../rest/swagger/BasicSwaggerProviderSession.java  |  72 +++++++-------
 .../juneau/reflection/ExecutableInfoTest.java      |   6 --
 30 files changed, 426 insertions(+), 243 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index 48e6af3..3fa26b7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -234,7 +234,7 @@ public class BeanMeta<T> {
                                                for (Beanc bc : 
ctx.getAnnotations(Beanc.class, x))
                                                        if (! 
bc.properties().isEmpty())
                                                                constructorArgs 
= split(bc.properties());
-                                               if (constructorArgs.length != 
x.getParamCount()) {
+                                               if (! 
x.hasNumParams(constructorArgs.length)) {
                                                        if 
(constructorArgs.length != 0)
                                                                throw new 
BeanRuntimeException(c, "Number of properties defined in '@Beanc' annotation 
does not match number of parameters in constructor.");
                                                        constructorArgs = new 
String[x.getParamCount()];
@@ -261,7 +261,7 @@ public class BeanMeta<T> {
                                                        for (Beanc bc : 
ctx.getAnnotations(Beanc.class, x))
                                                                if (! 
bc.properties().isEmpty())
                                                                        
constructorArgs = split(bc.properties());
-                                                       if 
(constructorArgs.length != x.getParamCount()) {
+                                                       if (! 
x.hasNumParams(constructorArgs.length)) {
                                                                if 
(constructorArgs.length != 0)
                                                                        throw 
new BeanRuntimeException(c, "Number of properties defined in '@Beanc' 
annotation does not match number of parameters in constructor.");
                                                                constructorArgs 
= new String[x.getParamCount()];
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 1f9108a..82e563c 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
@@ -929,7 +929,7 @@ public abstract class Context implements MetaProvider {
        private static final boolean DISABLE_ANNOTATION_CACHING = ! 
Boolean.getBoolean("juneau.disableAnnotationCaching");
 
        private TwoKeyConcurrentCache<Class<?>,Class<? extends 
Annotation>,List<Annotation>> classAnnotationCache = new 
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
-       private TwoKeyConcurrentCache<Class<?>,Class<? extends 
Annotation>,List<Annotation>> declaredClassAnnotationCache = new 
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
+       private TwoKeyConcurrentCache<Class<?>,Class<? extends 
Annotation>,Annotation[]> declaredClassAnnotationCache = new 
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
        private TwoKeyConcurrentCache<Method,Class<? extends 
Annotation>,List<Annotation>> methodAnnotationCache = new 
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
        private TwoKeyConcurrentCache<Field,Class<? extends 
Annotation>,List<Annotation>> fieldAnnotationCache = new 
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
        private TwoKeyConcurrentCache<Constructor<?>,Class<? extends 
Annotation>,List<Annotation>> constructorAnnotationCache = new 
TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
@@ -958,28 +958,35 @@ public abstract class Context implements MetaProvider {
                return (List<A>)aa;
        }
 
-       /**
-        * Finds the specified declared annotations on the specified class.
-        *
-        * @param <A> The annotation type to find.
-        * @param a The annotation type to find.
-        * @param c The class to search on.
-        * @return The annotations in an unmodifiable list, or an empty list if 
not found.
-        */
-       @SuppressWarnings("unchecked")
        @Override /* MetaProvider */
-       public <A extends Annotation> List<A> getDeclaredAnnotations(Class<A> 
a, Class<?> c) {
-               if (a == null || c == null)
-                       return emptyList();
-               List<Annotation> aa = declaredClassAnnotationCache.get(c, a);
+       public <A extends Annotation> void getDeclaredAnnotations(Class<A> a, 
Class<?> c, Consumer<A> consumer) {
+               if (a != null && c != null)
+                       for (A aa : declaredAnnotations(a, c))
+                               consumer.accept(aa);
+       }
+
+       @Override /* MetaProvider */
+       public <A extends Annotation> A getDeclaredAnnotation(Class<A> a, 
Class<?> c, Predicate<A> predicate) {
+               if (a != null && c != null)
+                       for (A aa : declaredAnnotations(a, c))
+                               if (predicate.test(aa))
+                                       return aa;
+               return null;
+       }
+
+       @SuppressWarnings("unchecked")
+       private <A extends Annotation> A[] declaredAnnotations(Class<A> a, 
Class<?> c) {
+               A[] aa = (A[])declaredClassAnnotationCache.get(c, a);
                if (aa == null) {
                        A[] x = c.getDeclaredAnnotationsByType(a);
                        AList<Annotation> l = new AList<>(Arrays.asList(x));
                        annotationMap.appendAll(c, a, l);
-                       aa = l.unmodifiable();
+                       aa = (A[]) Array.newInstance(a, l.size());
+                       for (int i = 0; i < l.size(); i++)
+                               Array.set(aa, i, l.get(i));
                        declaredClassAnnotationCache.put(c, a, aa);
                }
-               return (List<A>)aa;
+               return aa;
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MetaProvider.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MetaProvider.java
index eefa75a..dedfdb4 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MetaProvider.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MetaProvider.java
@@ -15,6 +15,7 @@ package org.apache.juneau;
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
+import java.util.function.*;
 
 import static java.util.Collections.*;
 
@@ -41,11 +42,19 @@ public interface MetaProvider {
                }
 
                @Override /* MetaProvider */
-               public <A extends Annotation> List<A> 
getDeclaredAnnotations(Class<A> a, Class<?> c) {
-                       if (a == null || c == null)
-                               return emptyList();
-                       A[] aa = c.getDeclaredAnnotationsByType(a);
-                       return Arrays.asList(aa);
+               public <A extends Annotation> void 
getDeclaredAnnotations(Class<A> a, Class<?> c, Consumer<A> consumer) {
+                       if (a != null && c != null)
+                               for (A aa : c.getDeclaredAnnotationsByType(a))
+                                       consumer.accept(aa);
+               }
+
+               @Override /* MetaProvider */
+               public <A extends Annotation> A getDeclaredAnnotation(Class<A> 
a, Class<?> c, Predicate<A> predicate) {
+                       if (a != null && c != null)
+                               for (A aa : c.getDeclaredAnnotationsByType(a))
+                                       if (predicate.test(aa))
+                                               return aa;
+                       return null;
                }
 
                @Override /* MetaProvider */
@@ -86,12 +95,21 @@ public interface MetaProvider {
        /**
         * Finds the specified declared annotations on the specified class.
         *
-        * @param <A> The annotation type to find.
         * @param a The annotation type to find.
         * @param c The class to search on.
-        * @return The annotations in an unmodifiable list, or an empty list if 
not found.
+        * @param consumer The consumer of the annotations.
+        */
+       <A extends Annotation> void getDeclaredAnnotations(Class<A> a, Class<?> 
c, Consumer<A> consumer);
+
+       /**
+        * Finds the specified declared annotations on the specified class that 
match the specified predicate.
+        *
+        * @param a The annotation type to find.
+        * @param c The class to search on.
+        * @param predicate The predicate to match the annotation against.
+        * @return The matched annotation, or <jk>null</jk> if no annotations 
matched.
         */
-       <A extends Annotation> List<A> getDeclaredAnnotations(Class<A> a, 
Class<?> c);
+       <A extends Annotation> A getDeclaredAnnotation(Class<A> a, Class<?> c, 
Predicate<A> predicate);
 
        /**
         * Finds the specified annotations on the specified method.
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Value.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Value.java
index ae387e1..e5f9d0c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Value.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Value.java
@@ -152,6 +152,22 @@ public class Value<T> {
        }
 
        /**
+        * Sets the value if the specified predicate test passes.
+        *
+        * @param t The new value.
+        * @param p The predicate to test the value against.
+        * @return This object.
+        */
+       public Value<T> setIf(T t, Predicate<T> p) {
+               if (p.test(t)) {
+                       this.t = t;
+                       if (listener != null)
+                               listener.onSet(t);
+               }
+               return this;
+       }
+
+       /**
         * Returns the value.
         *
         * @return The value, or <jk>null</jk> if it is not set.
@@ -208,4 +224,35 @@ public class Value<T> {
        public boolean isEmpty() {
                return t == null;
        }
+
+       /**
+        * Return the value if present, otherwise invoke {@code other} and 
return
+        * the result of that invocation.
+        *
+        * @param other a {@code Supplier} whose result is returned if no value
+        * is present
+        * @return the value if present otherwise the result of {@code 
other.get()}
+        * @throws NullPointerException if value is not present and {@code 
other} is
+        * null
+        */
+       public T orElseGet(Supplier<? extends T> other) {
+               return t != null ? t : other.get();
+       }
+
+       /**
+        * Return the contained value, if present, otherwise throw an exception
+        * to be created by the provided supplier.
+        *
+        * @param exceptionSupplier The supplier which will return the 
exception to
+        * be thrown
+        * @return the present value
+        * @throws X if there is no value present
+        * @throws NullPointerException if no value is present and
+        * {@code exceptionSupplier} is null
+        */
+       public <X extends Throwable> T orElseThrow(Supplier<? extends X> 
exceptionSupplier) throws X {
+               if (t != null)
+                       return t;
+               throw exceptionSupplier.get();
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
index 4e69cbb..f4a7292 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java
@@ -195,7 +195,7 @@ public class BeanCreator<T> {
                        MethodInfo m = type.getPublicMethod(
                                x -> x.isStatic()
                                && x.isNotDeprecated()
-                               && x.getParamCount() == 1
+                               && x.hasNumParams(1)
                                && x.getParam(0).canAccept(builder)
                                && x.hasReturnType(type)
                                && x.hasNoAnnotation(BeanIgnore.class)
@@ -210,7 +210,7 @@ public class BeanCreator<T> {
                        MethodInfo m = type.getPublicMethod(
                                x -> x.isStatic()
                                && x.isNotDeprecated()
-                               && x.getParamCount() == 0
+                               && x.hasNoParams()
                                && x.hasReturnType(type)
                                && x.hasNoAnnotation(BeanIgnore.class)
                                && x.hasName("getInstance")
@@ -286,7 +286,7 @@ public class BeanCreator<T> {
                if (builder == null) {
                        // Look for static-builder/protected-constructor pair.
                        for (ConstructorInfo cc2 : 
type.getDeclaredConstructors()) {
-                               if (cc2.getParamCount() == 1 && 
cc2.isVisible(Visibility.PROTECTED)) {
+                               if (cc2.hasNumParams(1) && 
cc2.isVisible(Visibility.PROTECTED)) {
                                        Class<?> pt = 
cc2.getParam(0).getParameterType().inner();
                                        MethodInfo m = type.getPublicMethod(x 
-> isStaticCreateMethod(x, pt));
                                        if (m != null) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanStore.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanStore.java
index 547fcab..f2dd201 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanStore.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanStore.java
@@ -267,6 +267,19 @@ public class BeanStore {
                        this.type = value;
                        return this;
                }
+
+               /**
+                * Overrides the bean store type if the predicate test passes.
+                *
+                * @param value The bean store type.
+                * @param predicate The predicate to test against.
+                * @return This object.
+                */
+               public Builder typeIf(Class<? extends BeanStore> value, 
Predicate<Class<? extends BeanStore>> predicate) {
+                       if (predicate.test(value))
+                               this.type = value;
+                       return this;
+               }
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -674,17 +687,12 @@ public class BeanStore {
        // Helper methods
        
//-----------------------------------------------------------------------------------------------------------------
        private String findBeanName(ParamInfo pi) {
-               Optional<Annotation> namedAnnotation = 
pi.getAnnotations(Annotation.class).stream().filter(x->isNamedAnnotation(x.annotationType())).findFirst();
-               if (namedAnnotation.isPresent())
-                       return AnnotationInfo.of((ClassInfo)null, 
namedAnnotation.get()).getValue(String.class, "value").orElse(null);
+               Annotation n = pi.getAnnotation(Annotation.class, x -> 
x.annotationType().getSimpleName().equals("Named"));
+               if (n != null)
+                       return AnnotationInfo.of((ClassInfo)null, 
n).getValue(String.class, "value").orElse(null);
                return null;
        }
 
-       private boolean isNamedAnnotation(Class<?> c) {
-               String s = c.getSimpleName();
-               return s.equals("Named");
-       }
-
        private void assertCanWrite() {
                if (readOnly)
                        throw runtimeException("Method cannot be used because 
BeanStore is read-only.");
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
index 5a069ac..898b944 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormDataAnnotation.java
@@ -14,15 +14,14 @@ package org.apache.juneau.http.annotation;
 
 import static java.lang.annotation.ElementType.*;
 import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
 import java.lang.annotation.*;
 import java.lang.reflect.*;
-import java.util.*;
+import java.util.function.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.svl.*;
 
@@ -87,16 +86,15 @@ public class FormDataAnnotation {
         * <p>
         * The last matching name found is returned.
         *
-        * @param lists The lists to search.
-        * @return The last matching name, or {@link Optional#empty()} if not 
found.
+        * @param pi The parameter.
+        * @return The last matching name, or {@link Value#empty()} if not 
found.
         */
-       @SafeVarargs
-       public static Optional<String> findName(List<FormData>...lists) {
-               String n = null;
-               for (List<FormData> l : lists)
-                       for (FormData h : l)
-                               n = firstNonEmpty(h.name(), h.value(), n);
-               return Optional.ofNullable(n);
+       public static Value<String> findName(ParamInfo pi) {
+               Value<String> n = Value.empty();
+               Predicate<String> t = StringUtils::isNotEmpty;
+               pi.getAnnotations(FormData.class, x -> n.setIf(x.value(), 
t).setIf(x.name(), t));
+               pi.getParameterType().getAnnotations(FormData.class, x -> 
n.setIf(x.value(), t).setIf(x.name(), t));
+               return n;
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
index cd7f740..b7413e7 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/HeaderAnnotation.java
@@ -14,15 +14,14 @@ package org.apache.juneau.http.annotation;
 
 import static java.lang.annotation.ElementType.*;
 import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
 import java.lang.annotation.*;
 import java.lang.reflect.*;
-import java.util.*;
+import java.util.function.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.svl.*;
 
@@ -87,16 +86,15 @@ public class HeaderAnnotation {
         * <p>
         * The last matching name found is returned.
         *
-        * @param lists The lists to search.
-        * @return The last matching name, or {@link Optional#empty()} if not 
found.
+        * @param pi The parameter.
+        * @return The last matching name, or {@link Value#empty()} if not 
found.
         */
-       @SafeVarargs
-       public static Optional<String> findName(List<Header>...lists) {
-               String n = null;
-               for (List<Header> l : lists)
-                       for (Header h : l)
-                               n = firstNonEmpty(h.name(), h.value(), n);
-               return Optional.ofNullable(n);
+       public static Value<String> findName(ParamInfo pi) {
+               Value<String> n = Value.empty();
+               Predicate<String> t = StringUtils::isNotEmpty;
+               pi.getAnnotations(Header.class, x -> n.setIf(x.value(), 
t).setIf(x.name(), t));
+               pi.getParameterType().getAnnotations(Header.class, x -> 
n.setIf(x.value(), t).setIf(x.name(), t));
+               return n;
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
index 3803028..5f22375 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/PathAnnotation.java
@@ -14,15 +14,14 @@ package org.apache.juneau.http.annotation;
 
 import static java.lang.annotation.ElementType.*;
 import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
 import java.lang.annotation.*;
 import java.lang.reflect.*;
-import java.util.*;
+import java.util.function.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.svl.*;
 
@@ -87,16 +86,15 @@ public class PathAnnotation {
         * <p>
         * The last matching name found is returned.
         *
-        * @param lists The lists to search.
-        * @return The last matching name, or {@link Optional#empty()} if not 
found.
+        * @param pi The parameter.
+        * @return The last matching name, or {@link Value#empty()} if not 
found.
         */
-       @SafeVarargs
-       public static Optional<String> findName(List<Path>...lists) {
-               String n = null;
-               for (List<Path> l : lists)
-                       for (Path h : l)
-                               n = firstNonEmpty(h.name(), h.value(), n);
-               return Optional.ofNullable(n);
+       public static Value<String> findName(ParamInfo pi) {
+               Value<String> n = Value.empty();
+               Predicate<String> t = StringUtils::isNotEmpty;
+               pi.getAnnotations(Path.class, x -> n.setIf(x.value(), 
t).setIf(x.name(), t));
+               pi.getParameterType().getAnnotations(Path.class, x -> 
n.setIf(x.value(), t).setIf(x.name(), t));
+               return n;
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
index c73a751..603f804 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/QueryAnnotation.java
@@ -14,15 +14,14 @@ package org.apache.juneau.http.annotation;
 
 import static java.lang.annotation.ElementType.*;
 import static java.lang.annotation.RetentionPolicy.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
 import java.lang.annotation.*;
 import java.lang.reflect.*;
-import java.util.*;
+import java.util.function.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.svl.*;
 
@@ -87,16 +86,15 @@ public class QueryAnnotation {
         * <p>
         * The last matching name found is returned.
         *
-        * @param lists The lists to search.
-        * @return The last matching name, or {@link Optional#empty()} if not 
found.
+        * @param pi The parameter.
+        * @return The last matching name, or {@link Value#empty()} if not 
found.
         */
-       @SafeVarargs
-       public static Optional<String> findName(List<Query>...lists) {
-               String n = null;
-               for (List<Query> l : lists)
-                       for (Query h : l)
-                               n = firstNonEmpty(h.name(), h.value(), n);
-               return Optional.ofNullable(n);
+       public static Value<String> findName(ParamInfo pi) {
+               Value<String> n = Value.empty();
+               Predicate<String> t = StringUtils::isNotEmpty;
+               pi.getAnnotations(Query.class, x -> n.setIf(x.value(), 
t).setIf(x.name(), t));
+               pi.getParameterType().getAnnotations(Query.class, x -> 
n.setIf(x.value(), t).setIf(x.name(), t));
+               return n;
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RrpcInterfaceMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RrpcInterfaceMeta.java
index e13e861..38b9781 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RrpcInterfaceMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/remote/RrpcInterfaceMeta.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.internal.StringUtils.*;
 import java.lang.reflect.*;
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.reflect.*;
 
@@ -49,16 +50,14 @@ public class RrpcInterfaceMeta {
         */
        public RrpcInterfaceMeta(Class<?> c, String uri) {
                this.c = c;
-               String path = "";
+               Value<String> path = Value.of("");
                ClassInfo ci = ClassInfo.of(c);
 
-               for (Remote r : ci.getAnnotations(Remote.class))
-                       if (! r.path().isEmpty())
-                               path = trimSlashes(r.path());
+               ci.getAnnotations(Remote.class, x -> { if (! 
x.path().isEmpty()) path.set(trimSlashes(x.path()));});
 
                AMap<Method,RrpcInterfaceMethodMeta> methods = AMap.create();
                ci.getPublicMethods(
-                       x -> true, 
+                       x -> true,
                        x -> methods.put(x.inner(), new 
RrpcInterfaceMethodMeta(uri, x.inner()))
                );
 
@@ -68,7 +67,7 @@ public class RrpcInterfaceMeta {
 
                this.methods = methods.unmodifiable();
                this.methodsByPath = methodsByPath.unmodifiable();
-               this.path = path;
+               this.path = path.get();
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
index 4b7c486..c9860db 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
@@ -686,9 +686,7 @@ public class HttpPartSchema {
 
                Builder apply(Class<? extends Annotation> c, 
java.lang.reflect.Type t) {
                        if (t instanceof Class<?>) {
-                               ClassInfo ci = ClassInfo.of((Class<?>)t);
-                               for (Annotation a : ci.getAnnotations(c))
-                                       apply(a);
+                               ClassInfo.of((Class<?>)t).getAnnotations(c, x 
-> apply(x));
                        } else if (Value.isType(t)) {
                                apply(c, Value.getParameterType(t));
                        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
index f96b7a0..2859c21 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
@@ -55,8 +55,8 @@ public class ResponseBeanMeta {
                        return null;
                Builder b = new Builder(annotations);
                b.apply(ci.innerType());
-               ci.getAnnotations(Response.class).forEach(x -> b.apply(x));
-               ci.getAnnotations(StatusCode.class).forEach(x -> b.apply(x));
+               ci.getAnnotations(Response.class, x -> b.apply(x));
+               ci.getAnnotations(StatusCode.class, x -> b.apply(x));
                return b.build();
        }
 
@@ -167,7 +167,7 @@ public class ResponseBeanMeta {
                                        assertReturnType(m, Header.class, 
int.class, Integer.class);
                                        statusMethod = 
ResponseBeanPropertyMeta.create(RESPONSE_STATUS, m);
                                } else if (m.hasAnnotation(Body.class)) {
-                                       if (m.getParamCount() == 0)
+                                       if (m.hasNoParams())
                                                assertReturnNotVoid(m, 
Header.class);
                                        else
                                                assertArgType(m, Header.class, 
OutputStream.class, Writer.class);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/Utils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/Utils.java
index fb4f03d..ddd9331 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/Utils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/Utils.java
@@ -28,7 +28,7 @@ import org.apache.juneau.reflect.*;
 class Utils {
 
        static void assertNoArgs(MethodInfo m, Class<?> a) throws 
InvalidAnnotationException {
-               if (m.getParamCount() != 0)
+               if (m.hasParams())
                        throw new InvalidAnnotationException("Method with @{0} 
annotation cannot have arguments.  Method=''{1}''", a.getSimpleName(), m);
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
index 30183d9..00818b2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -1785,6 +1785,8 @@ public final class StringUtils {
        public static String trimSlashes(String s) {
                if (s == null)
                        return null;
+               if (s.length() == 0)
+                       return s;
                while (endsWith(s, '/'))
                        s = s.substring(0, s.length()-1);
                while (s.length() > 0 && s.charAt(0) == '/')
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
index cc52b7a..884ed00 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
@@ -950,7 +950,20 @@ public final class ClassInfo {
         *      A list of all matching annotations found or an empty list if 
none found.
         */
        public <T extends Annotation> List<T> getAnnotations(Class<T> a) {
-               return appendAnnotations(new ArrayList<>(), a);
+               List<T> l = new ArrayList<>();
+               getAnnotations(a, x -> l.add(x));
+               return l;
+       }
+
+       /**
+        * Returns the first matching annotation of the specified type defined 
on the specified class or parent classes/interfaces in parent-to-child order.
+        *
+        * @param a The annotation to search for.
+        * @param predicate The predicate to test against.
+        * @return This object.
+        */
+       public <T extends Annotation> T getAnnotation(Class<T> a, Predicate<T> 
predicate) {
+               return getAnnotation(predicate, a, MetaProvider.DEFAULT);
        }
 
        /**
@@ -1035,7 +1048,7 @@ public final class ClassInfo {
 
        /**
         * Finds and appends the specified annotation on the specified class 
and superclasses/interfaces to the specified
-        * list.
+        * consumer.
         *
         * <p>
         * Annotations are appended in the following orders:
@@ -1046,12 +1059,12 @@ public final class ClassInfo {
         *      <li>On this class.
         * </ol>
         *
-        * @param l The list of annotations.
+        * @param consumer The consumer of the annotations.
         * @param a The annotation to search for.
         * @return The same list.
         */
-       public <T extends Annotation> List<T> appendAnnotations(List<T> l, 
Class<T> a) {
-               return appendAnnotations(l, a, MetaProvider.DEFAULT);
+       public <T extends Annotation> ClassInfo getAnnotations(Class<T> a, 
Consumer<T> consumer) {
+               return getAnnotations(a, MetaProvider.DEFAULT, consumer);
        }
 
        /**
@@ -1073,16 +1086,58 @@ public final class ClassInfo {
         * @return The same list.
         */
        public <T extends Annotation> List<T> appendAnnotations(List<T> l, 
Class<T> a, MetaProvider mp) {
-               addIfNotNull(l, getPackageAnnotation(a));
+               getAnnotations(a, mp, x -> l.add(x));
+               return l;
+       }
+
+       /**
+        * Finds and consumes the specified annotation on the specified class 
and superclasses/interfaces to the specified
+        * consumer.
+        *
+        * <p>
+        * Annotations are appended in the following orders:
+        * <ol>
+        *      <li>On the package of this class.
+        *      <li>On interfaces ordered child-to-parent.
+        *      <li>On parent classes ordered child-to-parent.
+        *      <li>On this class.
+        * </ol>
+        *
+        * @param consumer The consumer of the annotations.
+        * @param a The annotation to search for.
+        * @param mp The meta provider for looking up annotations on reflection 
objects (classes, methods, fields, constructors).
+        * @return This object.
+        */
+       public <T extends Annotation> ClassInfo getAnnotations(Class<T> a, 
MetaProvider mp, Consumer<T> consumer) {
+               T t2 = getPackageAnnotation(a);
+               if (t2 != null)
+                       consumer.accept(t2);
                ClassInfo[] interfaces = _getInterfaces();
                for (int i = interfaces.length-1; i >= 0; i--)
-                       for (T t : mp.getDeclaredAnnotations(a, 
interfaces[i].inner()))
-                               l.add(t);
+                       mp.getDeclaredAnnotations(a, interfaces[i].inner(), 
consumer);
                ClassInfo[] parents = _getParents();
                for (int i = parents.length-1; i >= 0; i--)
-                       for (T t : mp.getDeclaredAnnotations(a, 
parents[i].inner()))
-                               l.add(t);
-               return l;
+                       mp.getDeclaredAnnotations(a, parents[i].inner(), 
consumer);
+               return this;
+       }
+
+       private <T extends Annotation> T getAnnotation(Predicate<T> p, Class<T> 
a, MetaProvider mp) {
+               T t2 = getPackageAnnotation(a);
+               if (t2 != null && p.test(t2))
+                       return t2;
+               ClassInfo[] interfaces = _getInterfaces();
+               for (int i = interfaces.length-1; i >= 0; i--) {
+                       T o = mp.getDeclaredAnnotation(a, 
interfaces[i].inner(), p);
+                       if (o != null)
+                               return o;
+               }
+               ClassInfo[] parents = _getParents();
+               for (int i = parents.length-1; i >= 0; i--) {
+                       T o = mp.getDeclaredAnnotation(a, parents[i].inner(), 
p);
+                       if (o != null)
+                               return o;
+               }
+               return null;
        }
 
        /**
@@ -1180,10 +1235,10 @@ public final class ClassInfo {
                if (a == null)
                        return null;
 
-               for (T t : mp.getDeclaredAnnotations(a, c))
+               T t = mp.getDeclaredAnnotation(a, c, x -> true);
+               if (t != null)
                        return t;
 
-               T t;
                ClassInfo sci = getParent();
                if (sci != null) {
                        t = sci.getLastAnnotation(a, mp);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ExecutableInfo.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ExecutableInfo.java
index 857c5d5..0843196 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ExecutableInfo.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ExecutableInfo.java
@@ -38,7 +38,7 @@ public abstract class ExecutableInfo {
 
        private ParamInfo[] params;
        private ClassInfo[] paramTypes, exceptionInfos;
-       private Class<?>[] rawParamTypes, rawExceptionTypes;
+       private Class<?>[] rawParamTypes;
        private Type[] rawGenericParamTypes;
        private Parameter[] rawParameters;
 
@@ -345,18 +345,9 @@ public abstract class ExecutableInfo {
                return new UnmodifiableArray<>(_getExceptionTypes());
        }
 
-       /**
-        * Returns the raw exception types on this executable.
-        *
-        * @return The raw exception types on this executable.
-        */
-       public final Class<?>[] getRawExceptionTypes() {
-               return _getRawExceptionTypes().clone();
-       }
-
        private ClassInfo[] _getExceptionTypes() {
                if (exceptionInfos == null) {
-                       Class<?>[] exceptionTypes = _getRawExceptionTypes();
+                       Class<?>[] exceptionTypes = e.getExceptionTypes();
                        ClassInfo[] l = new ClassInfo[exceptionTypes.length];
                        for (int i = 0; i < exceptionTypes.length; i++)
                                l[i] = ClassInfo.of(exceptionTypes[i]);
@@ -365,12 +356,6 @@ public abstract class ExecutableInfo {
                return exceptionInfos;
        }
 
-       private Class<?>[] _getRawExceptionTypes() {
-               if (rawExceptionTypes == null)
-                       rawExceptionTypes = e.getExceptionTypes();
-               return rawExceptionTypes;
-       }
-
        
//-----------------------------------------------------------------------------------------------------------------
        // Characteristics
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/MethodInfo.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/MethodInfo.java
index dc65932..83123b4 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/MethodInfo.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/MethodInfo.java
@@ -304,15 +304,32 @@ public final class MethodInfo extends ExecutableInfo 
implements Comparable<Metho
         * @param a The annotation.
         * @return The same list.
         */
-       @SuppressWarnings("unchecked")
        public <T extends Annotation> List<T> appendAnnotations(List<T> l, 
Class<T> a) {
-               declaringClass.appendAnnotations(l, a);
+               getAnnotations(a, x -> l.add(x));
+               return l;
+       }
+
+       /**
+        * Consumes all annotations of the specified type defined on the 
specified method.
+        *
+        * <p>
+        * Searches all methods with the same signature on the parent classes 
or interfaces
+        * and the return type on the method.
+        * <br>Results are parent-to-child ordered.
+        *
+        * @param a The annotation to search for.
+        * @param consumer The consumer of the annotation.
+        * @return This object.
+        */
+       @SuppressWarnings("unchecked")
+       public <T extends Annotation> MethodInfo getAnnotations(Class<T> a, 
Consumer<T> consumer) {
+               declaringClass.getAnnotations(a, consumer);
                for (Method m2 : getMatchingParentFirst())
-                       for (Annotation a2 :  m2.getDeclaredAnnotations())
+                       for (Annotation a2 : m2.getDeclaredAnnotations())
                                if (a.isInstance(a2))
-                                       l.add((T)a2);
-               
getReturnType().unwrap(Value.class,Optional.class).appendAnnotations(l, a);
-               return l;
+                                       consumer.accept((T)a2);
+               
getReturnType().unwrap(Value.class,Optional.class).getAnnotations(a, consumer);
+               return this;
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ParamInfo.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ParamInfo.java
index 4e21d03..add7ed2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ParamInfo.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ParamInfo.java
@@ -16,6 +16,7 @@ import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.*;
+import java.util.function.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
@@ -181,49 +182,130 @@ public final class ParamInfo {
         * <p>
         * Results are in parent-to-child order.
         *
-        * @param a
-        *      The annotation to search for.
-        * @return
-        *      A list of all matching annotations found or an empty list if 
none found.
+        * @param a The annotation to search for.
+        * @return A list of all matching annotations found or an empty list if 
none found.
         */
        public <T extends Annotation> List<T> getAnnotations(Class<T> a) {
                return appendAnnotations(new ArrayList<>(), a, true);
        }
 
-       @SuppressWarnings("unchecked")
+       /**
+        * Consumes all annotations of the specified type defined on this 
method parameter.
+        *
+        * <p>
+        * Searches all methods with the same signature on the parent classes 
or interfaces
+        * and the return type on the method.
+        * <p>
+        * Results are in parent-to-child order.
+        *
+        * @param a The annotation to search for.
+        * @param consumer The consumer for the annotations.
+        * @return This object.
+        */
+       public <T extends Annotation> ParamInfo getAnnotations(Class<T> a, 
Consumer<T> consumer) {
+               return getAnnotations(a, true, consumer);
+       }
+
+       /**
+        * Returns the first annotation of the specified type defined on this 
method parameter that matches the specified predicate.
+        *
+        * <p>
+        * Searches all methods with the same signature on the parent classes 
or interfaces
+        * and the return type on the method.
+        * <p>
+        * Results are in parent-to-child order.
+        *
+        * @param a The annotation to search for.
+        * @param predicate The consumer for the annotations.
+        * @return A list of all matching annotations found or an empty list if 
none found.
+        */
+       public <T extends Annotation> T getAnnotation(Class<T> a, Predicate<T> 
predicate) {
+               return getAnnotation(a, true, predicate);
+       }
+
        private <T extends Annotation> List<T> appendAnnotations(List<T> l, 
Class<T> a, boolean parentFirst) {
+               getAnnotations(a, parentFirst, x -> l.add(x));
+               return l;
+       }
+
+       @SuppressWarnings("unchecked")
+       private <T extends Annotation> ParamInfo getAnnotations(Class<T> a, 
boolean parentFirst, Consumer<T> consumer) {
                if (eInfo.isConstructor) {
                        ClassInfo ci = 
eInfo.getParamType(index).unwrap(Value.class,Optional.class);
                        Annotation[] annotations = 
eInfo.getParameterAnnotations(index);
                        if (parentFirst) {
-                               ci.appendAnnotations(l, a);
+                               ci.getAnnotations(a, consumer);
                                for (Annotation a2 : annotations)
                                        if (a.isInstance(a2))
-                                               l.add((T)a2);
+                                               consumer.accept((T)a2);
                        } else {
                                for (Annotation a2 : annotations)
                                        if (a.isInstance(a2))
-                                               l.add((T)a2);
-                               ci.appendAnnotations(l, a);
+                                               consumer.accept((T)a2);
+                               ci.getAnnotations(a, consumer);
                        }
                } else {
                        MethodInfo mi = (MethodInfo)eInfo;
                        ClassInfo ci = 
eInfo.getParamType(index).unwrap(Value.class,Optional.class);
                        if (parentFirst) {
-                               ci.appendAnnotations(l, a);
+                               ci.getAnnotations(a, consumer);
                                for (Method m2 : mi.getMatchingParentFirst())
                                        for (Annotation a2 :  
m2.getParameterAnnotations()[index])
                                                if (a.isInstance(a2))
-                                                       l.add((T)a2);
+                                                       consumer.accept((T)a2);
                        } else {
                                for (Method m2 : mi.getMatching())
                                        for (Annotation a2 :  
m2.getParameterAnnotations()[index])
                                                if (a.isInstance(a2))
-                                                       l.add((T)a2);
-                               ci.appendAnnotations(l, a);
+                                                       consumer.accept((T)a2);
+                               ci.getAnnotations(a, consumer);
                        }
                }
-               return l;
+               return this;
+       }
+
+       @SuppressWarnings("unchecked")
+       private <T extends Annotation> T getAnnotation(Class<T> a, boolean 
parentFirst, Predicate<T> predicate) {
+               if (eInfo.isConstructor) {
+                       ClassInfo ci = 
eInfo.getParamType(index).unwrap(Value.class,Optional.class);
+                       Annotation[] annotations = 
eInfo.getParameterAnnotations(index);
+                       if (parentFirst) {
+                               T o = ci.getAnnotation(a, predicate);
+                               if (o != null)
+                                       return o;
+                               for (Annotation a2 : annotations)
+                                       if (a.isInstance(a2) && 
predicate.test((T)a2))
+                                               return (T)a2;
+                       } else {
+                               for (Annotation a2 : annotations)
+                                       if (a.isInstance(a2) && 
predicate.test((T)a2))
+                                               return (T)a2;
+                               T o = ci.getAnnotation(a, predicate);
+                               if (o != null)
+                                       return o;
+                       }
+               } else {
+                       MethodInfo mi = (MethodInfo)eInfo;
+                       ClassInfo ci = 
eInfo.getParamType(index).unwrap(Value.class,Optional.class);
+                       if (parentFirst) {
+                               T o = ci.getAnnotation(a, predicate);
+                               if (o != null)
+                                       return o;
+                               for (Method m2 : mi.getMatchingParentFirst())
+                                       for (Annotation a2 :  
m2.getParameterAnnotations()[index])
+                                               if (a.isInstance(a2) && 
predicate.test((T)a2))
+                                                       return (T)a2;
+                       } else {
+                               for (Method m2 : mi.getMatching())
+                                       for (Annotation a2 :  
m2.getParameterAnnotations()[index])
+                                               if (a.isInstance(a2) && 
predicate.test((T)a2))
+                                                       return (T)a2;
+                               T o = ci.getAnnotation(a, predicate);
+                               if (o != null)
+                                       return o;
+                       }
+               }
+               return null;
        }
 
        private synchronized Map<Class<?>,Optional<Annotation>> annotationMap() 
{
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
index bd2bb1a..e213f78 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteMeta.java
@@ -51,14 +51,15 @@ public class RemoteMeta {
                String path = "";
 
                ClassInfo ci = ClassInfo.of(c);
-               for (Remote r : ci.getAnnotations(Remote.class))
+               List<Remote> remotes = ci.getAnnotations(Remote.class);
+               for (Remote r : remotes)
                        if (! r.path().isEmpty())
                                path = trimSlashes(r.path());
 
                String versionHeader = "Client-Version", clientVersion = null;
                HeaderList.Builder headersBuilder = 
HeaderList.create().resolving();
 
-               for (Remote r : ci.getAnnotations(Remote.class)) {
+               for (Remote r : remotes) {
                        if (! r.path().isEmpty())
                                path = trimSlashes(resolve(r.path()));
                        for (String h : r.headers())
@@ -82,7 +83,7 @@ public class RemoteMeta {
                AMap<Method,RemoteOperationMeta> operations = AMap.create();
                String path2 = path;
                ci.getPublicMethods(
-                       x -> true, 
+                       x -> true,
                        x -> operations.put(x.inner(), new 
RemoteOperationMeta(path2, x.inner(), "GET"))
                );
 
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 d23492f..faa8320 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
@@ -172,11 +172,7 @@ public class RestContext extends Context {
        public static Builder create(Class<?> resourceClass, RestContext 
parentContext, ServletConfig servletConfig) throws ServletException {
 
                Value<Class<? extends Builder>> v = Value.of(Builder.class);
-               ClassInfo.of(resourceClass)
-                       .getAnnotations(Rest.class)
-                       .stream()
-                       .filter(x -> x.builder() != Builder.Null.class)
-                       .forEach(x -> v.set(x.builder()));
+               ClassInfo.ofc(resourceClass).getAnnotations(Rest.class, x -> 
v.setIf(x.builder(), x2 -> x2 != Builder.Null.class));
 
                if (v.get() == Builder.class)
                        return new Builder(resourceClass, parentContext, 
servletConfig);
@@ -588,13 +584,7 @@ public class RestContext extends Context {
                        );
 
                        // Apply @Rest(beanStore).
-                       ClassInfo.of(resourceClass)
-                               .getAnnotations(Rest.class)
-                               .stream()
-                               .map(x -> x.beanStore())
-                               .filter(x -> x != BeanStore.Null.class)
-                               .reduce((x1,x2)->x2)
-                               .ifPresent(x -> v.get().type(x));
+                       ClassInfo.of(resourceClass).getAnnotations(Rest.class, 
x -> v.get().typeIf(x.beanStore(), y -> y != BeanStore.Null.class));
 
                        // Replace with builder from:  public [static] 
BeanStore.Builder createBeanStore(<args>)
                        v.get().build()
@@ -874,15 +864,13 @@ public class RestContext extends Context {
 
                        // Find our config file.  It's the last non-empty 
@RestResource(config).
                        VarResolver vr = 
beanStore.getBean(VarResolver.class).orElseThrow(()->runtimeException("VarResolver
 not found."));
-                       String cf = ClassInfo
-                               .of(resourceClass)
-                               .getAnnotations(Rest.class)
-                               .stream()
-                               .map(x -> x.config())
-                               .filter(x -> ! x.isEmpty())
-                               .reduce((x1,x2)->x2)
-                               .map(x -> vr.resolve(x))
-                               .orElse("");
+                       Value<String> cfv = Value.empty();
+                       Consumer<Rest> consumer = x -> {
+                               if (! x.config().isEmpty())
+                                       cfv.set(vr.resolve(x.config()));
+                       };
+                       ClassInfo.of(resourceClass).getAnnotations(Rest.class, 
consumer);
+                       String cf = cfv.orElse("");
 
                        // If not specified or value is set to SYSTEM_DEFAULT, 
use system default config.
                        if (v.isEmpty() && "SYSTEM_DEFAULT".equals(cf))
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/AttributeArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/AttributeArg.java
index ec0d87f..927f4d7 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/AttributeArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/AttributeArg.java
@@ -12,8 +12,8 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.arg;
 
-import static org.apache.juneau.internal.StringUtils.*;
-
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
@@ -65,14 +65,16 @@ public class AttributeArg implements RestOpArg {
        }
 
        private String getName(ParamInfo paramInfo) {
-               String n = null;
+               Value<String> n = Value.empty();
                for (Attr h : paramInfo.getAnnotations(Attr.class))
-                       n = firstNonEmpty(h.name(), h.value(), n);
-               for (Attr h : 
paramInfo.getParameterType().getAnnotations(Attr.class))
-                       n = firstNonEmpty(h.name(), h.value(), n);
-               if (n == null)
+                       n.setIf(h.name(), 
StringUtils::isNotEmpty).setIf(h.value(), StringUtils::isNotEmpty);
+               paramInfo.getParameterType().getAnnotations(Attr.class, x -> {
+                       n.setIf(x.name(), StringUtils::isNotEmpty);
+                       n.setIf(x.value(), StringUtils::isNotEmpty);
+               });
+               if (n.isEmpty())
                        throw new ArgException(paramInfo, "@Attr used without 
name or value");
-               return n;
+               return n.get();
        }
 
        @Override /* RestOpArg */
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
index 5088ea9..da68e3b 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/FormDataArg.java
@@ -79,9 +79,7 @@ public class FormDataArg implements RestOpArg {
         * @param annotations The annotations to apply to any new part parsers.
         */
        protected FormDataArg(ParamInfo pi, AnnotationWorkList annotations) {
-               ClassInfo pt = pi.getParameterType();
-
-               this.name = findName(pi.getAnnotations(FormData.class), 
pt.getAnnotations(FormData.class)).orElseThrow(()->new ArgException(pi, 
"@FormData used without name or value"));
+               this.name = findName(pi).orElseThrow(()->new ArgException(pi, 
"@FormData used without name or value"));
                this.type = pi.getParameterType();
                this.schema = HttpPartSchema.create(FormData.class, pi);
                this.partParser = ofNullable(schema.getParser()).map(x -> 
HttpPartParser.creator().type(x).apply(annotations).create()).orElse(null);
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
index 79c7741..83c6e59 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/HeaderArg.java
@@ -120,9 +120,7 @@ public class HeaderArg implements RestOpArg {
         * @param annotations The annotations to apply to any new part parsers.
         */
        protected HeaderArg(ParamInfo pi, AnnotationWorkList annotations) {
-               ClassInfo pt = pi.getParameterType();
-
-               this.name = findName(pi.getAnnotations(Header.class), 
pt.getAnnotations(Header.class)).orElseThrow(() -> new ArgException(pi, 
"@Header used without name or value"));
+               this.name = findName(pi).orElseThrow(() -> new ArgException(pi, 
"@Header used without name or value"));
                this.type = pi.getParameterType();
                this.schema = HttpPartSchema.create(Header.class, pi);
                this.partParser = ofNullable(schema.getParser()).map(x -> 
HttpPartParser.creator().type(x).apply(annotations).create()).orElse(null);
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
index 87210e8..042b186 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/PathArg.java
@@ -84,8 +84,7 @@ public class PathArg implements RestOpArg {
        }
 
        private String getName(ParamInfo pi, UrlPathMatcher pathMatcher) {
-               ClassInfo pt = pi.getParameterType();
-               String p = findName(pi.getAnnotations(Path.class), 
pt.getAnnotations(Path.class)).orElse(null);
+               String p = findName(pi).orElse(null);
                if (p != null)
                        return p;
                if (pathMatcher != null) {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
index acf6eb8..742745c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/QueryArg.java
@@ -78,9 +78,7 @@ public class QueryArg implements RestOpArg {
         * @param annotations The annotations to apply to any new part parsers.
         */
        protected QueryArg(ParamInfo pi, AnnotationWorkList annotations) {
-               ClassInfo pt = pi.getParameterType();
-
-               this.name = 
QueryAnnotation.findName(pi.getAnnotations(Query.class), 
pt.getAnnotations(Query.class)).orElseThrow(() -> new ArgException(pi, "@Query 
used without name or value"));
+               this.name = QueryAnnotation.findName(pi).orElseThrow(() -> new 
ArgException(pi, "@Query used without name or value"));
                this.type = pi.getParameterType();
                this.schema = HttpPartSchema.create(Query.class, pi);
                this.partParser = ofNullable(schema.getParser()).map(x -> 
HttpPartParser.creator().type(x).apply(annotations).create()).orElse(null);
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseHeaderArg.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseHeaderArg.java
index 64734a2..082ac0d 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseHeaderArg.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/arg/ResponseHeaderArg.java
@@ -68,9 +68,7 @@ public class ResponseHeaderArg implements RestOpArg {
         * @param annotations The annotations to apply to any new part parsers.
         */
        protected ResponseHeaderArg(ParamInfo pi, AnnotationWorkList 
annotations) {
-               ClassInfo pt = pi.getParameterType();
-
-               this.name = findName(pi.getAnnotations(Header.class), 
pt.getAnnotations(Header.class)).orElseThrow(() -> new ArgException(pi, 
"@Header used without name or value"));
+               this.name = findName(pi).orElseThrow(() -> new ArgException(pi, 
"@Header used without name or value"));
                this.type = pi.getParameterType().innerType();
                HttpPartSchema schema = HttpPartSchema.create(Header.class, pi);
                this.meta = new ResponsePartMeta(HttpPartType.HEADER, schema, 
ofNullable(schema.getSerializer()).map(x -> 
HttpPartSerializer.creator().type(x).apply(annotations).create()).orElse(null));
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
index 20cdddd..62e7137 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestServlet.java
@@ -36,6 +36,7 @@ import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.converter.*;
 import org.apache.juneau.rest.guard.*;
 import org.apache.juneau.rest.matcher.*;
+import org.apache.juneau.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.response.*;
 
@@ -128,13 +129,9 @@ public abstract class RestServlet extends HttpServlet {
                if (context != null)
                        return context.getFullPath();
                ClassInfo ci = ClassInfo.of(getClass());
-               String path = "";
-               for (Rest rr : ci.getAnnotations(Rest.class))
-                       if (! rr.path().isEmpty())
-                               path = trimSlashes(rr.path());
-               if (! path.isEmpty())
-                       return path;
-               return "";
+               Value<String> path = Value.empty();
+               ci.getAnnotations(Rest.class, x -> 
path.setIf(trimSlashes(x.path()), StringUtils::isNotEmpty));
+               return path.orElse("");
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
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 cbd83bf..a0018b9 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
@@ -320,52 +320,52 @@ public class BasicSwaggerProviderSession {
                                if (mpi.hasAnnotation(Body.class) || 
pt.hasAnnotation(Body.class)) {
                                        OMap param = paramMap.getMap(BODY + 
".body", true).a("in", BODY);
                                        OMap schema = 
getSchema(param.getMap("schema"), type, bs);
-                                       
pt.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
-                                       
mpi.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
-                                       pt.getAnnotations(Body.class).forEach(x 
-> merge(schema, x.schema()));
-                                       
mpi.getAnnotations(Body.class).forEach(x -> merge(schema, x.schema()));
+                                       pt.getAnnotations(Schema.class, x -> 
merge(schema, x));
+                                       mpi.getAnnotations(Schema.class, x -> 
merge(schema, x));
+                                       pt.getAnnotations(Body.class, x -> 
merge(schema, x.schema()));
+                                       mpi.getAnnotations(Body.class, x -> 
merge(schema, x.schema()));
                                        pushupSchemaFields(BODY, param, schema);
                                        param.appendIf(true, true, true, 
"schema", schema);
                                        param.putIfAbsent("required", true);
                                        addBodyExamples(sm, param, false, type, 
locale);
 
                                } else if (mpi.hasAnnotation(Query.class) || 
pt.hasAnnotation(Query.class)) {
-                                       String name = 
QueryAnnotation.findName(mpi.getAnnotations(Query.class), 
pt.getAnnotations(Query.class)).orElse(null);
+                                       String name = 
QueryAnnotation.findName(mpi).orElse(null);
                                        OMap param = paramMap.getMap(QUERY + 
"." + name, true).a("name", name).a("in", QUERY);
-                                       
pt.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-                                       
pt.getAnnotations(Query.class).forEach(x -> merge(param, x.schema()));
-                                       
mpi.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-                                       
mpi.getAnnotations(Query.class).forEach(x -> merge(param, x.schema()));
+                                       pt.getAnnotations(Schema.class, x -> 
merge(param, x));
+                                       pt.getAnnotations(Query.class, x -> 
merge(param, x.schema()));
+                                       mpi.getAnnotations(Schema.class, x -> 
merge(param, x));
+                                       mpi.getAnnotations(Query.class, x -> 
merge(param, x.schema()));
                                        pushupSchemaFields(QUERY, param, 
getSchema(param.getMap("schema"), type, bs));
                                        addParamExample(sm, param, QUERY, type);
 
                                } else if (mpi.hasAnnotation(FormData.class) || 
pt.hasAnnotation(FormData.class)) {
-                                       String name = 
FormDataAnnotation.findName(mpi.getAnnotations(FormData.class), 
pt.getAnnotations(FormData.class)).orElse(null);
+                                       String name = 
FormDataAnnotation.findName(mpi).orElse(null);
                                        OMap param = paramMap.getMap(FORM_DATA 
+ "." + name, true).a("name", name).a("in", FORM_DATA);
-                                       
pt.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-                                       
pt.getAnnotations(FormData.class).forEach(x -> merge(param, x.schema()));
-                                       
mpi.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-                                       
mpi.getAnnotations(FormData.class).forEach(x -> merge(param, x.schema()));
+                                       pt.getAnnotations(Schema.class, x -> 
merge(param, x));
+                                       pt.getAnnotations(FormData.class, x -> 
merge(param, x.schema()));
+                                       mpi.getAnnotations(Schema.class, x -> 
merge(param, x));
+                                       mpi.getAnnotations(FormData.class, x -> 
merge(param, x.schema()));
                                        pushupSchemaFields(FORM_DATA, param, 
getSchema(param.getMap("schema"), type, bs));
                                        addParamExample(sm, param, FORM_DATA, 
type);
 
                                } else if (mpi.hasAnnotation(Header.class) || 
pt.hasAnnotation(Header.class)) {
-                                       String name = 
HeaderAnnotation.findName(mpi.getAnnotations(Header.class), 
pt.getAnnotations(Header.class)).orElse(null);
+                                       String name = 
HeaderAnnotation.findName(mpi).orElse(null);
                                        OMap param = paramMap.getMap(HEADER + 
"." + name, true).a("name", name).a("in", HEADER);
-                                       
pt.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-                                       
pt.getAnnotations(Header.class).forEach(x -> merge(param, x.schema()));
-                                       
mpi.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-                                       
mpi.getAnnotations(Header.class).forEach(x -> merge(param, x.schema()));
+                                       pt.getAnnotations(Schema.class, x -> 
merge(param, x));
+                                       pt.getAnnotations(Header.class, x -> 
merge(param, x.schema()));
+                                       mpi.getAnnotations(Schema.class, x -> 
merge(param, x));
+                                       mpi.getAnnotations(Header.class, x -> 
merge(param, x.schema()));
                                        pushupSchemaFields(HEADER, param, 
getSchema(param.getMap("schema"), type, bs));
                                        addParamExample(sm, param, HEADER, 
type);
 
                                } else if (mpi.hasAnnotation(Path.class) || 
pt.hasAnnotation(Path.class)) {
-                                       String name = 
PathAnnotation.findName(mpi.getAnnotations(Path.class), 
pt.getAnnotations(Path.class)).orElse(null);
+                                       String name = 
PathAnnotation.findName(mpi).orElse(null);
                                        OMap param = paramMap.getMap(PATH + "." 
+ name, true).a("name", name).a("in", PATH);
-                                       
pt.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-                                       pt.getAnnotations(Path.class).forEach(x 
-> merge(param, x.schema()));
-                                       
mpi.getAnnotations(Schema.class).forEach(x -> merge(param, x));
-                                       
mpi.getAnnotations(Path.class).forEach(x -> merge(param, x.schema()));
+                                       pt.getAnnotations(Schema.class, x -> 
merge(param, x));
+                                       pt.getAnnotations(Path.class, x -> 
merge(param, x.schema()));
+                                       mpi.getAnnotations(Schema.class, x -> 
merge(param, x));
+                                       mpi.getAnnotations(Path.class, x -> 
merge(param, x.schema()));
                                        pushupSchemaFields(PATH, param, 
getSchema(param.getMap("schema"), type, bs));
                                        addParamExample(sm, param, PATH, type);
                                        param.putIfAbsent("required", true);
@@ -387,7 +387,7 @@ public class BasicSwaggerProviderSession {
                                                        OMap om = 
responses.getMap(String.valueOf(code), true);
                                                        merge(om, a);
                                                        OMap schema = 
getSchema(om.getMap("schema"), m.getGenericReturnType(), bs);
-                                                       
eci.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
+                                                       
eci.getAnnotations(Schema.class, x -> merge(schema, x));
                                                        
pushupSchemaFields(RESPONSE, om, schema);
                                                        om.appendIf(true, true, 
true, "schema", schema);
                                                }
@@ -402,8 +402,8 @@ public class BasicSwaggerProviderSession {
                                                        String ha = a.name();
                                                        for (Integer code : 
codes) {
                                                                OMap header = 
responses.getMap(String.valueOf(code), true).getMap("headers", true).getMap(ha, 
true);
-                                                               
ecmi.getAnnotations(Schema.class).forEach(x -> merge(header, x));
-                                                               
ecmi.getReturnType().unwrap(Value.class,Optional.class).getAnnotations(Schema.class).forEach(x
 -> merge(header, x));
+                                                               
ecmi.getAnnotations(Schema.class, x -> merge(header, x));
+                                                               
ecmi.getReturnType().unwrap(Value.class,Optional.class).getAnnotations(Schema.class,
 x -> merge(header, x));
                                                                
pushupSchemaFields(RESPONSE_HEADER, header, getSchema(header.getMap("schema"), 
ecmi.getReturnType().unwrap(Value.class,Optional.class).innerType(), bs));
                                                        }
                                                }
@@ -420,7 +420,7 @@ public class BasicSwaggerProviderSession {
                                                OMap om = 
responses.getMap(String.valueOf(code), true);
                                                merge(om, a);
                                                OMap schema = 
getSchema(om.getMap("schema"), m.getGenericReturnType(), bs);
-                                               
mi.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
+                                               mi.getAnnotations(Schema.class, 
x -> merge(schema, x));
                                                pushupSchemaFields(RESPONSE, 
om, schema);
                                                om.appendIf(true, true, true, 
"schema", schema);
                                                addBodyExamples(sm, om, true, 
m.getGenericReturnType(), locale);
@@ -436,8 +436,8 @@ public class BasicSwaggerProviderSession {
                                                        if (! isMulti(a)) {
                                                                for (Integer 
code : codes) {
                                                                        OMap 
header = responses.getMap(String.valueOf(code), true).getMap("headers", 
true).getMap(ha, true);
-                                                                       
ecmi.getAnnotations(Schema.class).forEach(x -> merge(header, x));
-                                                                       
ecmi.getReturnType().unwrap(Value.class,Optional.class).getAnnotations(Schema.class).forEach(x
 -> merge(header, x));
+                                                                       
ecmi.getAnnotations(Schema.class, x -> merge(header, x));
+                                                                       
ecmi.getReturnType().unwrap(Value.class,Optional.class).getAnnotations(Schema.class,
 x -> merge(header, x));
                                                                        
merge(header, a.schema());
                                                                        
pushupSchemaFields(RESPONSE_HEADER, header, getSchema(header, 
ecmi.getReturnType().innerType(), bs));
                                                                }
@@ -449,7 +449,7 @@ public class BasicSwaggerProviderSession {
                                OMap om = responses.getMap("200", true);
                                ClassInfo pt2 = 
ClassInfo.of(m.getGenericReturnType());
                                OMap schema = getSchema(om.getMap("schema"), 
m.getGenericReturnType(), bs);
-                               pt2.getAnnotations(Schema.class).forEach(x -> 
merge(schema, x));
+                               pt2.getAnnotations(Schema.class, x -> 
merge(schema, x));
                                pushupSchemaFields(RESPONSE, om, schema);
                                om.appendIf(true, true, true, "schema", schema);
                                addBodyExamples(sm, om, true, 
m.getGenericReturnType(), locale);
@@ -464,14 +464,14 @@ public class BasicSwaggerProviderSession {
                                        List<Header> la = 
AList.of(mpi.getAnnotations(Header.class)).a(pt.getAnnotations(Header.class));
                                        List<StatusCode> la2 = 
AList.of(mpi.getAnnotations(StatusCode.class)).a(pt.getAnnotations(StatusCode.class));
                                        Set<Integer> codes = getCodes(la2, 200);
-                                       String name = 
HeaderAnnotation.findName(la).orElse(null);
+                                       String name = 
HeaderAnnotation.findName(mpi).orElse(null);
                                        Type type = 
Value.unwrap(mpi.getParameterType().innerType());
                                        for (Header a : la) {
                                                if (! isMulti(a)) {
                                                        for (Integer code : 
codes) {
                                                                OMap header = 
responses.getMap(String.valueOf(code), true).getMap("headers", 
true).getMap(name, true);
-                                                               
mpi.getAnnotations(Schema.class).forEach(x -> merge(header, x));
-                                                               
mpi.getParameterType().getAnnotations(Schema.class).forEach(x -> merge(header, 
x));
+                                                               
mpi.getAnnotations(Schema.class, x -> merge(header, x));
+                                                               
mpi.getParameterType().getAnnotations(Schema.class, x -> merge(header, x));
                                                                merge(header, 
a.schema());
                                                                
pushupSchemaFields(RESPONSE_HEADER, header, getSchema(header, type, bs));
                                                        }
@@ -488,8 +488,8 @@ public class BasicSwaggerProviderSession {
                                                        OMap om = 
responses.getMap(String.valueOf(code), true);
                                                        merge(om, a);
                                                        OMap schema = 
getSchema(om.getMap("schema"), type, bs);
-                                                       
pt.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
-                                                       
mpi.getAnnotations(Schema.class).forEach(x -> merge(schema, x));
+                                                       
pt.getAnnotations(Schema.class, x -> merge(schema, x));
+                                                       
mpi.getAnnotations(Schema.class, x -> merge(schema, x));
                                                        la.forEach(x -> 
merge(schema, x.schema()));
                                                        
pushupSchemaFields(RESPONSE, om, schema);
                                                        om.appendIf(true, true, 
true, "schema", schema);
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
 
b/juneau-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
index 29ce29b..eb9defe 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
@@ -345,12 +345,6 @@ public class ExecutableInfoTest {
                check("IOException", d_c.getExceptionTypes());
        }
 
-       @Test
-       public void getRawExceptionTypes() {
-               check("IOException", d_c.getRawExceptionTypes());
-               check("IOException", d_m.getRawExceptionTypes());
-       }
-
        
//-----------------------------------------------------------------------------------------------------------------
        // Characteristics
        
//-----------------------------------------------------------------------------------------------------------------

Reply via email to