JUNEAU-169 Dynamic annotations.
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
index dd90556..7fe6310 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/ExecutableInfoTest.java
@@ -288,10 +288,12 @@
 		public @CA void m(int bar) {}
 	}
 	static ClassInfo c = ClassInfo.of(C.class);
-	static ExecutableInfo
+	static ConstructorInfo
 		c_c1=c.getPublicConstructor(),
 		c_c2=c.getPublicConstructor(String.class),
-		c_c3=c.getPublicConstructor(int.class),
+		c_c3=c.getPublicConstructor(int.class)
+	;
+	static MethodInfo
 		c_m1=c.getPublicMethod("m"),
 		c_m2=c.getPublicMethod("m", String.class),
 		c_m3=c.getPublicMethod("m", int.class)
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/MethodInfoTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/MethodInfoTest.java
index 7341438..2c117ed 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/MethodInfoTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/reflection/MethodInfoTest.java
@@ -259,11 +259,11 @@
 
 	@Test
 	public void getAnnotationAny() {
-		check("@A(a1)", c_a1.getAnnotation(AX.class, A.class));
-		check("@A(a2b)", c_a2.getAnnotation(AX.class, A.class));
-		check("@A(a3)", c_a3.getAnnotation(AX.class, A.class));
-		check("@A(a4)", c_a4.getAnnotation(AX.class, A.class));
-		check(null, c_a5.getAnnotation(AX.class, A.class));
+		check("@A(a1)", c_a1.getAnyAnnotation(AX.class, A.class));
+		check("@A(a2b)", c_a2.getAnyAnnotation(AX.class, A.class));
+		check("@A(a3)", c_a3.getAnyAnnotation(AX.class, A.class));
+		check("@A(a4)", c_a4.getAnyAnnotation(AX.class, A.class));
+		check(null, c_a5.getAnyAnnotation(AX.class, A.class));
 	}
 
 	@Test
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/InvalidAnnotationException.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/InvalidAnnotationException.java
index b067148..f4367ed 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/InvalidAnnotationException.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/InvalidAnnotationException.java
@@ -44,7 +44,7 @@
 	 */
 	@SafeVarargs
 	public static void assertNoInvalidAnnotations(MethodInfo m, Class<? extends Annotation>...a) throws InvalidAnnotationException {
-		Annotation aa = m.getAnnotation(a);
+		Annotation aa = m.getAnyAnnotation(a);
 		if (aa != null)
 			throw new InvalidAnnotationException("@{0} annotation cannot be used in a @{1} bean.  Method=''{2}''", aa.getClass().getSimpleName(), m.getDeclaringClass().getSimpleName(), m);
 	}
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 1c9d706..804df44 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
@@ -947,7 +947,7 @@
 	 *
 	 * @param a
 	 * 	The annotation to search for.
-	 * @param mp The metadata provider for finding annotations on classes and methods.
+	 * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
 	 * @return
 	 * 	The annotation if found, or <jk>null</jk> if not.
 	 */
@@ -991,7 +991,7 @@
 	 *
 	 * @param <T> The annotation class type.
 	 * @param a The annotation class.
-	 * @param mp The metadata provider for finding annotations on classes and methods.
+	 * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
 	 * @return The annotation, or <jk>null</jk> if not found.
 	 */
 	public <T extends Annotation> T getDeclaredAnnotation(Class<T> a, MetaProvider mp) {
@@ -1049,7 +1049,7 @@
 	 *
 	 * @param <T> The annotation to search for.
 	 * @param a The annotation to search for.
-	 * @param mp The metadata provider for finding annotations.
+	 * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
 	 * @return
 	 * 	A list of all matching annotations found in child-to-parent order, or an empty list if none found.
 	 */
@@ -1074,7 +1074,7 @@
 	 *
 	 * @param a
 	 * 	The annotation to search for.
-	 * @param mp The metadata provider for finding annotations.
+	 * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
 	 * @return
 	 * 	A list of all matching annotations found or an empty list if none found.
 	 */
@@ -1189,7 +1189,7 @@
 	 * @param <T> The annotation to search for.
 	 * @param l The list of annotations.
 	 * @param a The annotation to search for.
-	 * @param mp The metadata provider for finding annotations on classes and methods.
+	 * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
 	 * @return The same list.
 	 */
 	public <T extends Annotation> List<T> appendAnnotations(List<T> l, Class<T> a, MetaProvider mp) {
@@ -1237,7 +1237,7 @@
 	 *
 	 * @param l The list of annotations.
 	 * @param a The annotation to search for.
-	 * @param mp The metadata provider for finding annotations on classes and methods.
+	 * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
 	 * @return The same list.
 	 */
 	public <T extends Annotation> List<T> appendAnnotationsParentFirst(List<T> l, Class<T> a, MetaProvider mp) {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
index 36c01b9..1a81b60 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ConstructorInfo.java
@@ -12,6 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.reflect;
 
+import java.lang.annotation.*;
 import java.lang.reflect.*;
 
 import org.apache.juneau.*;
@@ -77,6 +78,48 @@
 		return (Constructor<T>)c;
 	}
 
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// Annotations
+	//-----------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Finds the annotation of the specified type defined on this constructor.
+	 *
+	 * @param a
+	 * 	The annotation to search for.
+	 * @return
+	 * 	The annotation if found, or <jk>null</jk> if not.
+	 */
+	public final <T extends Annotation> T getAnnotation(Class<T> a) {
+		return getAnnotation(a, MetaProvider.DEFAULT);
+	}
+
+	/**
+	 * Finds the annotation of the specified type defined on this constructor.
+	 *
+	 * @param a
+	 * 	The annotation to search for.
+	 * @param mp
+	 * 	The meta provider for looking up annotations on classes/methods/fields.
+	 * @return
+	 * 	The first annotation found, or <jk>null</jk> if it doesn't exist.
+	 */
+	public final <T extends Annotation> T getAnnotation(Class<T> a, MetaProvider mp) {
+		return mp.getAnnotation(a, c);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the specified annotation is present on this constructor.
+	 *
+	 * @param a The annotation to check for.
+	 * @return <jk>true</jk> if the specified annotation is present on this constructor.
+	 */
+	public final boolean hasAnnotation(Class<? extends Annotation> a) {
+		return getAnnotation(a) != null;
+	}
+
+
 	//-----------------------------------------------------------------------------------------------------------------
 	// Other methods
 	//-----------------------------------------------------------------------------------------------------------------
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 08313e4..08d84f1 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
@@ -17,7 +17,6 @@
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
-import java.util.concurrent.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
@@ -36,7 +35,6 @@
 	private Class<?>[] rawParamTypes, rawExceptionTypes;
 	private Type[] rawGenericParamTypes;
 	private Parameter[] rawParameters;
-	private Map<Class<?>,Optional<Annotation>> annotationMap;
 
 	/**
 	 * Constructor.
@@ -303,57 +301,6 @@
 		return e.getParameterAnnotations()[index];
 	}
 
-	/**
-	 * Returns <jk>true</jk> if the specified annotation is present on this method.
-	 *
-	 * @param a The annotation to check for.
-	 * @return <jk>true</jk> if the specified annotation is present on this method.
-	 */
-	public final boolean hasAnnotation(Class<? extends Annotation> a) {
-		return getAnnotation(a) != null;
-	}
-
-	/**
-	 * Finds the annotation of the specified type defined on this executable.
-	 *
-	 * <p>
-	 * If this is a method and the annotation cannot be found on the immediate method, 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 to search for.
-	 * @return
-	 * 	The annotation if found, or <jk>null</jk> if not.
-	 */
-	@SuppressWarnings("unchecked")
-	public final <T extends Annotation> T getAnnotation(Class<T> a) {
-		if (a == null)
-			return null;
-		Optional<Annotation> o = annotationMap().get(a);
-		if (o == null) {
-			o = Optional.ofNullable(findAnnotation(a));
-			annotationMap().put(a, o);
-		}
-		return o.isPresent() ? (T)o.get() : null;
-	}
-
-	/**
-	 * Searched for the specified annotation on the method.
-	 *
-	 * @param a The annotation to search for on the method.
-	 * @return The annotation if found.
-	 */
-	protected <T extends Annotation> T findAnnotation(Class<T> a) {
-		return e.getAnnotation(a);
-	}
-
-	private synchronized Map<Class<?>,Optional<Annotation>> annotationMap() {
-		if (annotationMap == null)
-			annotationMap = new ConcurrentHashMap<>();
-		return annotationMap;
-	}
-
 	//-----------------------------------------------------------------------------------------------------------------
 	// Exceptions
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
index 055641a..3a39b0a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/FieldInfo.java
@@ -98,9 +98,18 @@
 	 * @return The annotation, or <jk>null</jk> if not found.
 	 */
 	public <T extends Annotation> T getAnnotation(Class<T> a) {
-		if (a == null)
-			return null;
-		return f.getAnnotation(a);
+		return getAnnotation(a, MetaProvider.DEFAULT);
+	}
+
+	/**
+	 * Returns the specified annotation on this field.
+	 *
+	 * @param a The annotation to look for.
+	 * @param mp The meta provider for looking up annotations on reflection objects (classes, methods, fields, constructors).
+	 * @return The annotation, or <jk>null</jk> if not found.
+	 */
+	public <T extends Annotation> T getAnnotation(Class<T> a, MetaProvider mp) {
+		return mp.getAnnotation(a, f);
 	}
 
 	/**
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 0cac994..3bbbe6e 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
@@ -151,6 +151,58 @@
 	//-----------------------------------------------------------------------------------------------------------------
 
 	/**
+	 * Finds the annotation of the specified type defined on this method.
+	 *
+	 * <p>
+	 * If this is a method and the annotation cannot be found on the immediate method, 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 to search for.
+	 * @return
+	 * 	The annotation if found, or <jk>null</jk> if not.
+	 */
+	public final <T extends Annotation> T getAnnotation(Class<T> a) {
+		return getAnnotation(a, MetaProvider.DEFAULT);
+	}
+
+	/**
+	 * Finds the annotation of the specified type defined on this method.
+	 *
+	 * <p>
+	 * Searches all methods with the same signature on the parent classes or interfaces
+	 * and the return type on the method.
+	 *
+	 * @param a
+	 * 	The annotation to search for.
+	 * @param mp
+	 * 	The meta provider for looking up annotations on classes/methods/fields.
+	 * @return
+	 * 	The first annotation found, or <jk>null</jk> if it doesn't exist.
+	 */
+	public final <T extends Annotation> T getAnnotation(Class<T> a, MetaProvider mp) {
+		if (a == null)
+			return null;
+		for (Method m2 : getMatching()) {
+			T t = mp.getAnnotation(a, m2);
+			if (t != null)
+				return t;
+		}
+		return null;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the specified annotation is present on this method.
+	 *
+	 * @param a The annotation to check for.
+	 * @return <jk>true</jk> if the specified annotation is present on this method.
+	 */
+	public final boolean hasAnnotation(Class<? extends Annotation> a) {
+		return getAnnotation(a) != null;
+	}
+
+	/**
 	 * Returns all annotations of the specified type defined on the specified method.
 	 *
 	 * <p>
@@ -226,7 +278,7 @@
 	 * @return <jk>true</jk> if this method does not have any of the specified annotations.
 	 */
 	@SafeVarargs
-	public final Annotation getAnnotation(Class<? extends Annotation>...c) {
+	public final Annotation getAnyAnnotation(Class<? extends Annotation>...c) {
 		for (Class<? extends Annotation> cc : c) {
 			Annotation a = getAnnotation(cc);
 			if (a != null)
@@ -304,16 +356,6 @@
 		return false;
 	}
 
-	@Override
-	@SuppressWarnings("unchecked")
-	protected <T extends Annotation> T findAnnotation(Class<T> a) {
-		for (Method m2 : getMatching())
-			for (Annotation a2 :  m2.getAnnotations())
-				if (a.isInstance(a2))
-					return (T)a2;
-		return null;
-	}
-
 	AnnotationList appendAnnotationList(AnnotationList al) {
 		ClassInfo c = this.declaringClass;
 		for (ClassInfo ci : c.getParents()) {
@@ -387,7 +429,7 @@
 
 	/**
 	 * Returns the generic return type of this method as a {@link ClassInfo} object.
-	 * 
+	 *
 	 * <p>
 	 * Unwraps the type if it's a {@link Value}.
 	 *