New org.apache.juneau.reflection package.
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
index bdf1943..f04fe7a 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/ClassUtilsTest.java
@@ -82,26 +82,26 @@
 	public void testIsParentClass() throws Exception {

 

 		// Strict

-		assertTrue(isParentClass(A.class, A1.class, true));

-		assertTrue(isParentClass(A1.class, A2.class, true));

-		assertTrue(isParentClass(Object.class, A2.class, true));

-		assertFalse(isParentClass(A.class, A.class, true));

-		assertFalse(isParentClass(A1.class, A1.class, true));

-		assertFalse(isParentClass(A2.class, A2.class, true));

-		assertFalse(isParentClass(A2.class, A1.class, true));

-		assertFalse(isParentClass(A1.class, A.class, true));

-		assertFalse(isParentClass(A2.class, Object.class, true));

+		assertTrue(getClassInfo(A.class).isParentOf(A1.class, true));

+		assertTrue(getClassInfo(A1.class).isParentOf(A2.class, true));

+		assertTrue(getClassInfo(Object.class).isParentOf(A2.class, true));

+		assertFalse(getClassInfo(A.class).isParentOf(A.class, true));

+		assertFalse(getClassInfo(A1.class).isParentOf(A1.class, true));

+		assertFalse(getClassInfo(A2.class).isParentOf(A2.class, true));

+		assertFalse(getClassInfo(A2.class).isParentOf(A1.class, true));

+		assertFalse(getClassInfo(A1.class).isParentOf(A.class, true));

+		assertFalse(getClassInfo(A2.class).isParentOf(Object.class, true));

 

 		// Not strict

-		assertTrue(isParentClass(A.class, A1.class, false));

-		assertTrue(isParentClass(A1.class, A2.class, false));

-		assertTrue(isParentClass(Object.class, A2.class, false));

-		assertTrue(isParentClass(A.class, A.class, false));

-		assertTrue(isParentClass(A1.class, A1.class, false));

-		assertTrue(isParentClass(A2.class, A2.class, false));

-		assertFalse(isParentClass(A2.class, A1.class, false));

-		assertFalse(isParentClass(A1.class, A.class, false));

-		assertFalse(isParentClass(A2.class, Object.class, false));

+		assertTrue(getClassInfo(A.class).isParentOf(A1.class, false));

+		assertTrue(getClassInfo(A1.class).isParentOf(A2.class, false));

+		assertTrue(getClassInfo(Object.class).isParentOf(A2.class, false));

+		assertTrue(getClassInfo(A.class).isParentOf(A.class, false));

+		assertTrue(getClassInfo(A1.class).isParentOf(A1.class, false));

+		assertTrue(getClassInfo(A2.class).isParentOf(A2.class, false));

+		assertFalse(getClassInfo(A2.class).isParentOf(A1.class, false));

+		assertFalse(getClassInfo(A1.class).isParentOf(A.class, false));

+		assertFalse(getClassInfo(A2.class).isParentOf(Object.class, false));

 	}

 

 	public interface A {}

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index db46c8a..049d9a2 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -2004,9 +2004,10 @@
 
 		LinkedList<BeanFilter> lbf = new LinkedList<>();
 		for (Class<?> c : getClassListProperty(BEAN_beanFilters)) {
-			if (isParentClass(BeanFilter.class, c))
+			ClassInfo ci = getClassInfo(c);
+			if (ci.isChildOf(BeanFilter.class))
 				lbf.add(newInstance(BeanFilter.class, c));
-			else if (isParentClass(BeanFilterBuilder.class, c))
+			else if (ci.isChildOf(BeanFilterBuilder.class))
 				lbf.add(newInstance(BeanFilterBuilder.class, c).build());
 			else
 				lbf.add(new InterfaceBeanFilterBuilder(c).build());
@@ -2016,13 +2017,13 @@
 		LinkedList<PojoSwap<?,?>> lpf = new LinkedList<>();
 		for (Object o : getListProperty(BEAN_pojoSwaps, Object.class)) {
 			if (o instanceof Class) {
-				Class<?> c = (Class<?>)o;
-				if (isParentClass(PojoSwap.class, c))
-					lpf.add(newInstance(PojoSwap.class, c));
-				else if (isParentClass(Surrogate.class, c))
-					lpf.addAll(SurrogateSwap.findPojoSwaps(c));
+				ClassInfo ci = getClassInfo((Class<?>)o);
+				if (ci.isChildOf(PojoSwap.class))
+					lpf.add(newInstance(PojoSwap.class, ci.getInnerClass()));
+				else if (ci.isChildOf(Surrogate.class))
+					lpf.addAll(SurrogateSwap.findPojoSwaps(ci.getInnerClass()));
 				else
-					throw new FormattedRuntimeException("Invalid class {0} specified in BeanContext.pojoSwaps property.  Must be a subclass of PojoSwap or Surrogate.", c);
+					throw new FormattedRuntimeException("Invalid class {0} specified in BeanContext.pojoSwaps property.  Must be a subclass of PojoSwap or Surrogate.", ci.getInnerClass());
 			} else if (o instanceof PojoSwap) {
 				lpf.add((PojoSwap)o);
 			}
@@ -2185,8 +2186,9 @@
 				if (p.getName().startsWith(p2))
 					return true;
 		}
+		ClassInfo ci = getClassInfo(c);
 		for (Class exclude : notBeanClasses)
-			if (isParentClass(exclude, c))
+			if (ci.isChildOf(exclude))
 				return true;
 		return false;
 	}
@@ -2583,7 +2585,7 @@
 		if (c != null) {
 			List<PojoSwap> l = new ArrayList<>();
 			for (PojoSwap f : pojoSwaps)
-				if (isParentClass(f.getNormalClass(), c))
+				if (f.getNormalClass().isParentOf(c))
 					l.add(f);
 			return l.size() == 0 ? null : l.toArray(new PojoSwap[l.size()]);
 		}
@@ -2614,7 +2616,7 @@
 			return null;
 		List<PojoSwap> l = null;
 		for (PojoSwap f : pojoSwaps) {
-			if (isParentClass(c, f.getNormalClass())) {
+			if (f.getNormalClass().isChildOf(c)) {
 				if (l == null)
 					l = new ArrayList<>();
 				l.add(f);
@@ -2634,7 +2636,7 @@
 	private final <T> BeanFilter findBeanFilter(Class<T> c) {
 		if (c != null)
 			for (BeanFilter f : beanFilters)
-				if (isParentClass(f.getBeanClass(), c))
+				if (getClassInfo(f.getBeanClass()).isParentOf(c))
 					return f;
 		return null;
 	}
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 939ff05..4c8f0eb 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
@@ -214,7 +214,7 @@
 					return "Class is annotated with @BeanIgnore";

 

 				// Make sure it's serializable.

-				if (beanFilter == null && ctx.isBeansRequireSerializable() && ! isParentClass(Serializable.class, c))

+				if (beanFilter == null && ctx.isBeansRequireSerializable() && ! ci.isChildOf(Serializable.class))

 					return "Class is not serializable";

 

 				// Look for @BeanConstructor constructor.

@@ -536,16 +536,16 @@
 		String propertyName;

 		MethodType methodType;

 		Method method;

-		Class<?> type;

+		ClassInfo type;

 

 		BeanMethod(String propertyName, MethodType type, Method method) {

 			this.propertyName = propertyName;

 			this.methodType = type;

 			this.method = method;

 			if (type == MethodType.SETTER)

-				this.type = method.getParameterTypes()[0];

+				this.type = getClassInfo(method.getParameterTypes()[0]);

 			else

-				this.type = method.getReturnType();

+				this.type = getClassInfo(method.getReturnType());

 		}

 

 		/*

@@ -572,7 +572,7 @@
 				return true;

 

 			// Doesn't match if not same type or super type as getter/field.

-			if (! isParentClass(type, pt))

+			if (! type.isParentOf(pt))

 				return false;

 

 			// If a setter was previously set, only use this setter if it's a closer

@@ -580,8 +580,7 @@
 			if (b.setter == null)

 				return true;

 

-			Class<?> prevType = b.setter.getParameterTypes()[0];

-			return isParentClass(prevType, type, true);

+			return type.isChildOf(b.setter.getParameterTypes()[0], true);

 		}

 

 		@Override /* Object */

@@ -620,7 +619,7 @@
 				String n = m.getName();

 

 				Class<?>[] pt = m.getParameterTypes();

-				Class<?> rt = m.getReturnType().getInnerClass();

+				ClassInfo rt = m.getReturnType();

 				MethodType methodType = UNKNOWN;

 				String bpName = bpName(bp);

 

@@ -629,16 +628,16 @@
 

 				if (pt.length == 0) {

 					if ("*".equals(bpName)) {

-						if (isParentClass(Collection.class, rt)) {

+						if (rt.isChildOf(Collection.class)) {

 							methodType = EXTRAKEYS;

-						} else if (isParentClass(Map.class, rt)) {

+						} else if (rt.isChildOf(Map.class)) {

 							methodType = GETTER;

 						}

 						n = bpName;

-					} else if (n.startsWith("get") && (! rt.equals(Void.TYPE))) {

+					} else if (n.startsWith("get") && (! rt.is(Void.TYPE))) {

 						methodType = GETTER;

 						n = n.substring(3);

-					} else if (n.startsWith("is") && (rt.equals(Boolean.TYPE) || rt.equals(Boolean.class))) {

+					} else if (n.startsWith("is") && (rt.is(Boolean.TYPE) || rt.is(Boolean.class))) {

 						methodType = GETTER;

 						n = n.substring(2);

 					} else if (bpName != null) {

@@ -655,14 +654,14 @@
 					}

 				} else if (pt.length == 1) {

 					if ("*".equals(bpName)) {

-						if (isParentClass(Map.class, pt[0])) {

+						if (getClassInfo(pt[0]).isChildOf(Map.class)) {

 							methodType = SETTER;

 							n = bpName;

 						} else if (pt[0] == String.class) {

 							methodType = GETTER;

 							n = bpName;

 						}

-					} else if (n.startsWith("set") && (isParentClass(rt, c) || rt.equals(Void.TYPE))) {

+					} else if (n.startsWith("set") && (rt.isParentOf(c) || rt.is(Void.TYPE))) {

 						methodType = SETTER;

 						n = n.substring(3);

 					} else if (bpName != null) {

@@ -674,12 +673,12 @@
 						} else {

 							n = bpName;

 						}

-					} else if (fluentSetters && isParentClass(rt, c)) {

+					} else if (fluentSetters && rt.isParentOf(c)) {

 						methodType = SETTER;

 					}

 				} else if (pt.length == 2) {

 					if ("*".equals(bpName) && pt[0] == String.class) {

-						if (n.startsWith("set") && (isParentClass(rt, c) || rt.equals(Void.TYPE))) {

+						if (n.startsWith("set") && (rt.isParentOf(c) || rt.is(Void.TYPE))) {

 							methodType = SETTER;

 						} else {

 							methodType = GETTER;

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index bb08a2f..0a758a4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -237,11 +237,11 @@
 			isDyna = "*".equals(name);

 

 			// Do some annotation validation.

-			Class<?> c = rawTypeMeta.getInnerClass();

+			ClassInfo ci = rawTypeMeta.getInfo();

 			if (getter != null) {

 				Class<?>[] pt = getter.getParameterTypes();

 				if (isDyna) {

-					if (isParentClass(Map.class, c) && pt.length == 0) {

+					if (ci.isChildOf(Map.class) && pt.length == 0) {

 						isDynaGetterMap = true;

 					} else if (pt.length == 1 && pt[0] == String.class) {

 						// OK.

@@ -249,7 +249,7 @@
 						return false;

 					}

 				} else {

-					if (! isParentClass(getter.getReturnType(), c))

+					if (! ci.isChildOf(getter.getReturnType()))

 						return false;

 				}

 			}

@@ -264,16 +264,16 @@
 				} else {

 					if (pt.length != 1)

 						return false;

-					if (! isParentClass(pt[0], c))

+					if (! ci.isChildOf(pt[0]))

 						return false;

 				}

 			}

 			if (field != null) {

 				if (isDyna) {

-					if (! isParentClass(Map.class, field.getType()))

+					if (! getClassInfo(field.getType()).isChildOf(Map.class))

 						return false;

 				} else {

-					if (! isParentClass(field.getType(), c))

+					if (! ci.isChildOf(field.getType()))

 						return false;

 				}

 			}

@@ -287,7 +287,7 @@
 				return false;

 

 			if (typeMeta == null)

-				typeMeta = (swap != null ? beanContext.getClassMeta(swap.getSwapClass()) : rawTypeMeta == null ? beanContext.object() : rawTypeMeta);

+				typeMeta = (swap != null ? beanContext.getClassMeta(swap.getSwapClass().getInner()) : rawTypeMeta == null ? beanContext.object() : rawTypeMeta);

 			if (typeMeta == null)

 				typeMeta = rawTypeMeta;

 

@@ -313,7 +313,8 @@
 				c = s.impl();

 			if (c == Null.class)

 				return null;

-			if (isParentClass(PojoSwap.class, c)) {

+			ClassInfo ci = getClassInfo(c);

+			if (ci.isChildOf(PojoSwap.class)) {

 				PojoSwap ps = beanContext.newInstance(PojoSwap.class, c);

 				if (ps.forMediaTypes() != null)

 					throw new RuntimeException("TODO - Media types on swaps not yet supported on bean properties.");

@@ -321,7 +322,7 @@
 					throw new RuntimeException("TODO - Templates on swaps not yet supported on bean properties.");

 				return ps;

 			}

-			if (isParentClass(Surrogate.class, c))

+			if (ci.isChildOf(Surrogate.class))

 				throw new RuntimeException("TODO - Surrogate swaps not yet supported on bean properties.");

 			throw new FormattedRuntimeException("Invalid class used in @Swap annotation.  Must be a subclass of PojoSwap or Surrogate.", c);

 		}

@@ -777,7 +778,7 @@
 					}

 

 				} else {

-					if (swap != null && value != null && isParentClass(swap.getSwapClass(), value.getClass())) {

+					if (swap != null && value != null && swap.getSwapClass().isParentOf(value.getClass())) {

 						value = swap.unswap(session, value, rawTypeMeta);

 					} else {

 						value = session.convertToType(value, rawTypeMeta);

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanRegistry.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanRegistry.java
index d20a2a3..2001d1d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanRegistry.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanRegistry.java
@@ -20,6 +20,7 @@
 import java.util.concurrent.*;
 
 import org.apache.juneau.annotation.*;
+import org.apache.juneau.reflection.*;
 
 /**
  * A lookup table for resolving bean types by name.
@@ -63,7 +64,8 @@
 	private void addClass(Class<?> c) {
 		try {
 			if (c != null) {
-				if (isParentClass(Collection.class, c)) {
+				ClassInfo ci = getClassInfo(c);
+				if (ci.isChildOf(Collection.class)) {
 					@SuppressWarnings("rawtypes")
 					Collection cc = beanContext.newInstance(Collection.class, c);
 					for (Object o : cc) {
@@ -72,7 +74,7 @@
 						else
 							throw new BeanRuntimeException("Collection class ''{0}'' passed to BeanRegistry does not contain Class objects.", c.getName());
 					}
-				} else if (isParentClass(Map.class, c)) {
+				} else if (ci.isChildOf(Map.class)) {
 					Map<?,?> m = beanContext.newInstance(Map.class, c);
 					for (Map.Entry<?,?> e : m.entrySet()) {
 						String typeName = asString(e.getKey());
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index 116ebc2..5556dd4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************

 package org.apache.juneau;

 

-import static org.apache.juneau.internal.ClassUtils.*;

 import static org.apache.juneau.internal.StringUtils.*;

 import static org.apache.juneau.internal.ThrowableUtils.*;

 

@@ -27,6 +26,7 @@
 import org.apache.juneau.internal.*;

 import org.apache.juneau.json.*;

 import org.apache.juneau.parser.*;

+import org.apache.juneau.reflection.*;

 import org.apache.juneau.serializer.*;

 import org.apache.juneau.transform.*;

 

@@ -307,16 +307,16 @@
 

 			PojoSwap swap = to.getPojoSwap(this);

 			if (swap != null) {

-				Class<?> nc = swap.getNormalClass(), fc = swap.getSwapClass();

-				if (isParentClass(nc, tc) && isParentClass(fc, value.getClass()))

+				ClassInfo nc = swap.getNormalClass(), fc = swap.getSwapClass();

+				if (nc.isParentOf(tc) && fc.isParentOf(value.getClass()))

 					return (T)swap.unswap(this, value, to);

 			}

 

 			ClassMeta<?> from = getClassMetaForObject(value);

 			swap = from.getPojoSwap(this);

 			if (swap != null) {

-				Class<?> nc = swap.getNormalClass(), fc = swap.getSwapClass();

-				if (isParentClass(nc, from.getInnerClass()) && isParentClass(fc, tc))

+				ClassInfo nc = swap.getNormalClass(), fc = swap.getSwapClass();

+				if (nc.isParentOf(from.getInnerClass()) && fc.isParentOf(tc))

 					return (T)swap.swap(this, value);

 			}

 

@@ -622,7 +622,7 @@
 					String typeName = m2.getString(getBeanTypePropertyName(to));

 					if (typeName != null) {

 						ClassMeta cm = to.getBeanRegistry().getClassMeta(typeName);

-						if (cm != null && isParentClass(to.innerClass, cm.innerClass))

+						if (cm != null && to.info.isParentOf(cm.innerClass))

 							return (T)m2.cast(cm);

 					}

 				}

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
index d9822c9..fd14217 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
@@ -417,7 +417,7 @@
 				else if (c == void.class || c == Void.class)

 					cc = VOID;

 			} else {

-				if (isParentClass(Delegate.class, c))

+				if (ci.isChildOf(Delegate.class))

 					isDelegate = true;

 

 				if (c == Object.class)

@@ -426,24 +426,24 @@
 					cc = ENUM;

 				else if (c.equals(Class.class))

 					cc = CLASS;

-				else if (isParentClass(Method.class, c))

+				else if (ci.isChildOf(Method.class))

 					cc = METHOD;

-				else if (isParentClass(CharSequence.class, c)) {

+				else if (ci.isChildOf(CharSequence.class)) {

 					if (c.equals(String.class))

 						cc = STR;

 					else

 						cc = CHARSEQ;

 				}

-				else if (isParentClass(Number.class, c)) {

-					if (isParentClass(Float.class, c) || isParentClass(Double.class, c))

+				else if (ci.isChildOf(Number.class)) {

+					if (ci.isChildOfAny(Float.class, Double.class))

 						cc = DECIMAL;

 					else

 						cc = NUMBER;

 				}

-				else if (isParentClass(Collection.class, c))

+				else if (ci.isChildOf(Collection.class))

 					cc = COLLECTION;

-				else if (isParentClass(Map.class, c)) {

-					if (isParentClass(BeanMap.class, c))

+				else if (ci.isChildOf(Map.class)) {

+					if (ci.isChildOf(BeanMap.class))

 						cc = BEANMAP;

 					else

 						cc = MAP;

@@ -452,15 +452,15 @@
 					cc = CHAR;

 				else if (c == Boolean.class)

 					cc = BOOLEAN;

-				else if (isParentClass(Date.class, c) || isParentClass(Calendar.class, c))

+				else if (ci.isChildOfAny(Date.class, Calendar.class))

 					cc = DATE;

 				else if (c.isArray())

 					cc = ARRAY;

-				else if (isParentClass(URL.class, c) || isParentClass(URI.class, c) || c.isAnnotationPresent(org.apache.juneau.annotation.URI.class))

+				else if (ci.isChildOfAny(URL.class, URI.class) || c.isAnnotationPresent(org.apache.juneau.annotation.URI.class))

 					cc = URI;

-				else if (isParentClass(Reader.class, c))

+				else if (ci.isChildOf(Reader.class))

 					cc = READER;

-				else if (isParentClass(InputStream.class, c))

+				else if (ci.isChildOf(InputStream.class))

 					cc = INPUTSTREAM;

 			}

 

@@ -535,7 +535,7 @@
 

 			for (FieldInfo f : ci.getDeclaredFields()) {

 				if (f.isAnnotationPresent(Example.class)) {

-					if (! (f.isStatic() && isParentClass(innerClass, f.getType().getInner())))

+					if (! (f.isStatic() && ci.isParentOf(f.getType().getInner())))

 						throw new ClassMetaRuntimeException("@Example used on invalid field ''{0}''.  Must be static and an instance of the type.", f);

 					f.setAccessible(false);

 					exampleField = f.getInner();

@@ -560,7 +560,7 @@
 

 			for (MethodInfo m : ci.getDeclaredMethods()) {

 				if (m.isAnnotationPresent(Example.class)) {

-					if (! (m.isStatic() && m.hasFuzzyArgs(BeanSession.class) && isParentClass(innerClass, m.getReturnType().getInner())))

+					if (! (m.isStatic() && m.hasFuzzyArgs(BeanSession.class) && ci.isParentOf(m.getReturnType().getInner())))

 						throw new ClassMetaRuntimeException("@Example used on invalid method ''{0}''.  Must be static and return an instance of the declaring class.", m);

 					m.setAccessible();

 					exampleMethod = m.getInner();

@@ -800,8 +800,9 @@
 			Class<?> c = s.value();

 			if (c == Null.class)

 				c = s.impl();

+			ClassInfo ci = ClassInfo.create(c);

 

-			if (isParentClass(PojoSwap.class, c)) {

+			if (ci.isChildOf(PojoSwap.class)) {

 				PojoSwap ps = beanContext.newInstance(PojoSwap.class, c);

 				if (s.mediaTypes().length > 0)

 					ps.forMediaTypes(MediaType.forStrings(s.mediaTypes()));

@@ -810,7 +811,7 @@
 				return ps;

 			}

 

-			if (isParentClass(Surrogate.class, c)) {

+			if (ci.isChildOf(Surrogate.class)) {

 				List<SurrogateSwap<?,?>> l = SurrogateSwap.findPojoSwaps(c);

 				if (! l.isEmpty())

 					return (PojoSwap<T,?>)l.iterator().next();

@@ -895,7 +896,7 @@
 	 * @return <jk>true</jk> if this class is a superclass of or the same as the specified class.

 	 */

 	public boolean isAssignableFrom(Class<?> c) {

-		return isParentClass(innerClass, c);

+		return info.isChildOf(c);

 	}

 

 	/**

@@ -905,7 +906,7 @@
 	 * @return <jk>true</jk> if this class is a subclass of or the same as the specified class.

 	 */

 	public boolean isInstanceOf(Class<?> c) {

-		return isParentClass(c, innerClass);

+		return info.isParentOf(c);

 	}

 

 	/**

@@ -933,7 +934,7 @@
 			PojoSwap<?,?> s = childSwapMap.get(normalClass);

 			if (s == null) {

 				for (PojoSwap<?,?> f : childPojoSwaps)

-					if (s == null && isParentClass(f.getNormalClass(), normalClass))

+					if (s == null && f.getNormalClass().isParentOf(normalClass))

 						s = f;

 				if (s == null)

 					s = PojoSwap.NULL;

@@ -960,7 +961,7 @@
 			PojoSwap<?,?> s = childUnswapMap.get(swapClass);

 			if (s == null) {

 				for (PojoSwap<?,?> f : childPojoSwaps)

-					if (s == null && isParentClass(f.getSwapClass(), swapClass))

+					if (s == null && f.getSwapClass().isParentOf(swapClass))

 						s = f;

 				if (s == null)

 					s = PojoSwap.NULL;

@@ -1185,7 +1186,7 @@
 	 * @return <jk>true</jk> if this class extends from {@link Set}.

 	 */

 	public boolean isSet() {

-		return cc == COLLECTION && isParentClass(Set.class, innerClass);

+		return cc == COLLECTION && info.isChildOf(Set.class);

 	}

 

 	/**

@@ -1194,7 +1195,7 @@
 	 * @return <jk>true</jk> if this class extends from {@link List}.

 	 */

 	public boolean isList() {

-		return cc == COLLECTION && isParentClass(List.class, innerClass);

+		return cc == COLLECTION && info.isChildOf(List.class);

 	}

 

 	/**

@@ -1339,7 +1340,7 @@
 	 * @return <jk>true</jk> if this metadata represents the specified type.

 	 */

 	public boolean isType(Class<?> c) {

-		return isParentClass(c, innerClass);

+		return info.isChildOf(c);

 	}

 

 	/**

@@ -1402,7 +1403,7 @@
 	 * @return <jk>true</jk> if this class is a {@link Date}.

 	 */

 	public boolean isDate() {

-		return cc == DATE && isParentClass(Date.class, innerClass);

+		return cc == DATE && info.isChildOf(Date.class);

 	}

 

 	/**

@@ -1411,7 +1412,7 @@
 	 * @return <jk>true</jk> if this class is a {@link Calendar}.

 	 */

 	public boolean isCalendar() {

-		return cc == DATE && isParentClass(Calendar.class, innerClass);

+		return cc == DATE && info.isChildOf(Calendar.class);

 	}

 

 	/**

@@ -2002,7 +2003,7 @@
 	 */

 	public boolean isInstance(Object o) {

 		if (o != null)

-			return isParentClass(this.innerClass, o.getClass()) || (isPrimitive() && info.getPrimitiveWrapper() == o.getClass());

+			return info.isParentOf(o.getClass()) || (isPrimitive() && info.getPrimitiveWrapper() == o.getClass());

 		return false;

 	}

 

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
index a9ac595..b7940c8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************

 package org.apache.juneau;

 

-import static org.apache.juneau.internal.ClassUtils.*;

 import static org.apache.juneau.internal.StringUtils.*;

 

 import java.io.*;

@@ -1564,7 +1563,7 @@
 	 * Otherwise, returns c2.

 	 */

 	private static ClassMeta<?> getNarrowedClassMeta(ClassMeta<?> c1, ClassMeta<?> c2) {

-		if (c2 == null || isParentClass(c2.getInnerClass(), c1.getInnerClass()))

+		if (c2 == null || c2.getInfo().isParentOf(c1.getInnerClass()))

 			return c1;

 		return c2;

 	}

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
index 7d831ae..479a5af 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
@@ -909,9 +909,9 @@
 	//-------------------------------------------------------------------------------------------------------------------
 
 	static <T> T instantiate(ResourceResolver resolver, Object outer, Class<T> c, Object value, Object...args) {
-		if (isParentClass(c, value.getClass()))
+		if (getClassInfo(c).isParentOf(value.getClass()))
 			return (T)value;
-		if (isParentClass(Class.class, value.getClass()))
+		if (getClassInfo(value.getClass()).isChildOf(Class.class))
 			return resolver.resolve(outer, (Class<T>)value, args);
 		return null;
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
index ff986dc..027ccb0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
@@ -39,6 +39,16 @@
 	}

 

 	/**

+	 * Shortcut for calling {@link ClassInfo#create(Object)}.

+	 *

+	 * @param o The object whose class being wrapped.

+	 * @return The wrapped class.

+	 */

+	public static ClassInfo getClassInfo(Object o) {

+		return ClassInfo.create(o);

+	}

+

+	/**

 	 * Shortcut for calling {@link MethodInfo#create(Method)}.

 	 *

 	 * @param m The method being wrapped.

@@ -153,42 +163,6 @@
 	}

 

 	/**

-	 * Returns <jk>true</jk> if <code>parent</code> is a parent class of <code>child</code>.

-	 *

-	 * @param parent The parent class.

-	 * @param child The child class.

-	 * @param strict If <jk>true</jk> returns <jk>false</jk> if the classes are the same.

-	 * @return <jk>true</jk> if <code>parent</code> is a parent class of <code>child</code>.

-	 */

-	public static boolean isParentClass(Class<?> parent, Class<?> child, boolean strict) {

-		return parent.isAssignableFrom(child) && ((!strict) || ! parent.equals(child));

-	}

-

-	/**

-	 * Returns <jk>true</jk> if <code>parent</code> is a parent class or the same as <code>child</code>.

-	 *

-	 * @param parent The parent class.

-	 * @param child The child class.

-	 * @return <jk>true</jk> if <code>parent</code> is a parent class or the same as <code>child</code>.

-	 */

-	public static boolean isParentClass(Class<?> parent, Class<?> child) {

-		return isParentClass(parent, child, false);

-	}

-

-	/**

-	 * Returns <jk>true</jk> if <code>parent</code> is a parent class or the same as <code>child</code>.

-	 *

-	 * @param parent The parent class.

-	 * @param child The child class.

-	 * @return <jk>true</jk> if <code>parent</code> is a parent class or the same as <code>child</code>.

-	 */

-	public static boolean isParentClass(Class<?> parent, Type child) {

-		if (child instanceof Class)

-			return isParentClass(parent, (Class<?>)child);

-		return false;

-	}

-

-	/**

 	 * Returns <jk>true</jk> if the specified class is public.

 	 *

 	 * @param c The class.

@@ -309,7 +283,7 @@
 	public static boolean argsMatch(Class<?>[] paramTypes, Class<?>[] argTypes) {

 		if (paramTypes.length == argTypes.length) {

 			for (int i = 0; i < paramTypes.length; i++)

-				if (! isParentClass(paramTypes[i], argTypes[i]))

+				if (! getClassInfo(paramTypes[i]).isParentOf(argTypes[i]))

 					return false;

 			return true;

 		}

@@ -328,7 +302,7 @@
 		outer: for (Class<?> p : paramTypes) {

 			p = getClassInfo(p).getWrapperIfPrimitive();

 			for (Class<?> a : argTypes) {

-				if (isParentClass(p, a)) {

+				if (getClassInfo(p).isParentOf(a)) {

 					matches++;

 					continue outer;

 				}

@@ -448,7 +422,7 @@
 			} catch (Exception e) {

 				throw new FormattedRuntimeException(e, "Could not instantiate class {0}", c.getName());

 			}

-		} else if (isParentClass(c, c2.getClass())) {

+		} else if (getClassInfo(c).isParentOf(c2.getClass())) {

 			return (T)c2;

 		} else {

 			throw new FormattedRuntimeException("Object of type {0} found but was expecting {1}.", c2.getClass(), c.getClass());

@@ -470,9 +444,9 @@
 	public static Object[] getMatchingArgs(Class<?>[] paramTypes, Object... args) {

 		Object[] params = new Object[paramTypes.length];

 		for (int i = 0; i < paramTypes.length; i++) {

-			Class<?> pt = getClassInfo(paramTypes[i]).getWrapperIfPrimitive();

+			ClassInfo pt = getClassInfo(paramTypes[i]).getWrapperInfoIfPrimitive();

 			for (int j = 0; j < args.length; j++) {

-				if (isParentClass(pt, args[j].getClass())) {

+				if (pt.isParentOf(args[j].getClass())) {

 					params[i] = args[j];

 					break;

 				}

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
index f5c802f..d5fab1b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.jsonschema;
 
-import static org.apache.juneau.internal.ClassUtils.*;
 import static org.apache.juneau.internal.ObjectUtils.*;
 import static org.apache.juneau.jsonschema.TypeCategory.*;
 
@@ -222,13 +221,13 @@
 
 			} else if (tc == COLLECTION) {
 				ClassMeta et = sType.getElementType();
-				if (sType.isCollection() && isParentClass(Set.class, sType.getInnerClass()))
+				if (sType.isCollection() && sType.getInfo().isChildOf(Set.class))
 					out.put("uniqueItems", true);
 				out.put("items", getSchema(et, "items", pNames, exampleAdded, descriptionAdded, null));
 
 			} else if (tc == ARRAY) {
 				ClassMeta et = sType.getElementType();
-				if (sType.isCollection() && isParentClass(Set.class, sType.getInnerClass()))
+				if (sType.isCollection() && sType.getInfo().isChildOf(Set.class))
 					out.put("uniqueItems", true);
 				out.put("items", getSchema(et, "items", pNames, exampleAdded, descriptionAdded, null));
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflection/ClassInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflection/ClassInfo.java
index 7af44ae..5ee03fa 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflection/ClassInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflection/ClassInfo.java
@@ -67,6 +67,18 @@
 	}
 
 	/**
+	 * Same as using the constructor, but operates on an object instance.
+	 *
+	 * @param o The class instance.
+	 * @return The constructed class info.
+	 */
+	public static ClassInfo create(Object o) {
+		if (o == null)
+			return null;
+		return new ClassInfo(o.getClass());
+	}
+
+	/**
 	 * Returns the cached instance of the specified type.
 	 *
 	 * @param t The class type.
@@ -1061,6 +1073,17 @@
 	}
 
 	/**
+	 * Same as {@link #getWrapperIfPrimitive()} but wraps it in a {@link ClassInfo}.
+	 *
+	 * @return The wrapper class if it's primitive, or the same class if class is not a primitive.
+	 */
+	public ClassInfo getWrapperInfoIfPrimitive() {
+		if (! c.isPrimitive())
+			return this;
+		return create(pmap1.get(c));
+	}
+
+	/**
 	 * Returns the default value for this primitive class.
 	 *
 	 * @return The default value, or <jk>null</jk> if this is not a primitive class.
@@ -1088,4 +1111,104 @@
 			.append(Double.class, 0d)
 			.append(Byte.class, (byte)0)
 	);
+
+	/**
+	 * Returns <jk>true</jk> if this class is a parent of <code>child</code>.
+	 *
+	 * @param child The child class.
+	 * @param strict If <jk>true</jk> returns <jk>false</jk> if the classes are the same.
+	 * @return <jk>true</jk> if this class is a parent of <code>child</code>.
+	 */
+	public boolean isParentOf(Class<?> child, boolean strict) {
+		return c.isAssignableFrom(child) && ((!strict) || ! c.equals(child));
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this class is a parent or the same as <code>child</code>.
+	 *
+	 * @param child The child class.
+	 * @return <jk>true</jk> if this class is a parent or the same as <code>child</code>.
+	 */
+	public boolean isParentOf(Class<?> child) {
+		return isParentOf(child, false);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this class is a parent or the same as <code>child</code>.
+	 *
+	 * @param child The child class.
+	 * @return <jk>true</jk> if this class is a parent or the same as <code>child</code>.
+	 */
+	public boolean isParentOf(Type child) {
+		if (child instanceof Class)
+			return isParentOf((Class<?>)child);
+		return false;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this class is a child of <code>parent</code>.
+	 *
+	 * @param parent The parent class.
+	 * @param strict If <jk>true</jk> returns <jk>false</jk> if the classes are the same.
+	 * @return <jk>true</jk> if this class is a parent of <code>child</code>.
+	 */
+	public boolean isChildOf(Class<?> parent, boolean strict) {
+		return parent.isAssignableFrom(c) && ((!strict) || ! c.equals(parent));
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this class is a child or the same as <code>parent</code>.
+	 *
+	 * @param parent The parent class.
+	 * @return <jk>true</jk> if this class is a child or the same as <code>parent</code>.
+	 */
+	public boolean isChildOf(Class<?> parent) {
+		return isChildOf(parent, false);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this class is a child or the same as any of the <code>parents</code>.
+	 *
+	 * @param parents The parents class.
+	 * @return <jk>true</jk> if this class is a child or the same as any of the <code>parents</code>.
+	 */
+	public boolean isChildOfAny(Class<?>...parents) {
+		for (Class<?> p : parents)
+			if (isChildOf(p))
+				return true;
+		return false;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this class is a child or the same as <code>parent</code>.
+	 *
+	 * @param parent The parent class.
+	 * @return <jk>true</jk> if this class is a parent or the same as <code>parent</code>.
+	 */
+	public boolean isChildOf(Type parent) {
+		if (parent instanceof Class)
+			return isChildOf((Class<?>)parent);
+		return false;
+	}
+
+	/**
+	 * Checks for equality with the specified class.
+	 *
+	 * @param c The class to check equality with.
+	 * @return <jk>true</jk> if the specified class is the same as this one.
+	 */
+	public boolean is(Class<?> c) {
+		return this.c.equals(c);
+	}
+
+	/**
+	 * Shortcut for calling {@link Class#newInstance()} on the underlying class.
+	 *
+	 * @return A new instance of the underlying class
+	 * @throws IllegalAccessException
+	 * @throws InstantiationException
+	 */
+	public Object newInstance() throws InstantiationException, IllegalAccessException {
+		return c.newInstance();
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflection/MethodInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflection/MethodInfo.java
index 2340105..ef2e34a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflection/MethodInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflection/MethodInfo.java
@@ -606,7 +606,7 @@
 	 * @return <jk>true</jk> if this method has this parent return type.
 	 */
 	public boolean hasReturnTypeParent(Class<?> c) {
-		return ClassUtils.isParentClass(c, m.getReturnType());
+		return ClassInfo.create(c).isParentOf(m.getReturnType());
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index 937becf..806392e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -316,14 +316,14 @@
 				if (((Object[])value).length == 0)

 					return true;

 			}

-			if (cm.isCollection() || (cm.isObject() && isParentClass(Collection.class, value.getClass()))) {

+			if (cm.isCollection() || (cm.isObject() && getClassInfo(value).isChildOf(Collection.class))) {

 				if (((Collection<?>)value).isEmpty())

 					return true;

 			}

 		}

 

 		if (isTrimEmptyMaps()) {

-			if (cm.isMap() || (cm.isObject() && isParentClass(Map.class, value.getClass()))) {

+			if (cm.isMap() || (cm.isObject() && getClassInfo(value).isChildOf(Map.class))) {

 				if (((Map<?,?>)value).isEmpty())

 					return true;

 			}

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BuilderSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BuilderSwap.java
index ea25951..3b73538 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BuilderSwap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/BuilderSwap.java
@@ -198,7 +198,7 @@
 			for (ConstructorInfo cc : pci.getPublicConstructors()) {

 				if (cc.isVisible(cVis) && cc.hasNumArgs(1)) {

 					Class<?>[] pt = cc.getParameterTypes();

-					if (isParentClass(Builder.class, pt[0])) {

+					if (getClassInfo(pt[0]).isChildOf(Builder.class)) {

 						pojoConstructor = cc.getInner();

 						builderClass = pt[0];

 					}

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
index 314e0e0..13d6ce0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwap.java
@@ -20,6 +20,7 @@
 import org.apache.juneau.annotation.*;

 import org.apache.juneau.http.*;

 import org.apache.juneau.parser.*;

+import org.apache.juneau.reflection.*;

 import org.apache.juneau.serializer.*;

 

 /**

@@ -112,6 +113,7 @@
 

 	private final Class<T> normalClass;

 	private final Class<?> swapClass;

+	private final ClassInfo normalClassInfo, swapClassInfo;

 	private ClassMeta<?> swapClassMeta;

 

 	// Unfortunately these cannot be made final because we want to allow for PojoSwaps with no-arg constructors

@@ -125,6 +127,8 @@
 	protected PojoSwap() {

 		normalClass = (Class<T>)resolveParameterType(PojoSwap.class, 0, this.getClass());

 		swapClass = resolveParameterType(PojoSwap.class, 1, this.getClass());

+		normalClassInfo = getClassInfo(normalClass);

+		swapClassInfo = getClassInfo(swapClass);

 		forMediaTypes = forMediaTypes();

 		template = withTemplate();

 	}

@@ -138,6 +142,8 @@
 	protected PojoSwap(Class<T> normalClass, Class<?> swapClass) {

 		this.normalClass = normalClass;

 		this.swapClass = swapClass;

+		normalClassInfo = getClassInfo(normalClass);

+		swapClassInfo = getClassInfo(swapClass);

 		this.forMediaTypes = forMediaTypes();

 		this.template = withTemplate();

 	}

@@ -345,8 +351,8 @@
 	 *

 	 * @return The normal form of this class.

 	 */

-	public Class<T> getNormalClass() {

-		return normalClass;

+	public ClassInfo getNormalClass() {

+		return normalClassInfo;

 	}

 

 	/**

@@ -358,8 +364,8 @@
 	 *

 	 * @return The transformed form of this class.

 	 */

-	public Class<?> getSwapClass() {

-		return swapClass;

+	public ClassInfo getSwapClass() {

+		return swapClassInfo;

 	}

 

 	/**

@@ -390,7 +396,7 @@
 	public boolean isNormalObject(Object o) {

 		if (o == null)

 			return false;

-		return isParentClass(normalClass, o.getClass());

+		return normalClassInfo.isParentOf(o.getClass());

 	}

 

 	/**

@@ -404,7 +410,7 @@
 	public boolean isSwappedObject(Object o) {

 		if (o == null)

 			return false;

-		return isParentClass(swapClass, o.getClass());

+		return swapClassInfo.isParentOf(o.getClass());

 	}

 

 

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MetadataMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MetadataMap.java
index e70a7bc..7cc5543 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MetadataMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MetadataMap.java
@@ -59,7 +59,7 @@
 			try {
 				for (Constructor<?> con : c.getConstructors()) {
 					Class<?>[] pt = con.getParameterTypes();
-					if (pt.length == 1 && isParentClass(pt[0], constructorArg.getClass())) {
+					if (pt.length == 1 && getClassInfo(pt[0]).isParentOf(constructorArg.getClass())) {
 						o = con.newInstance(constructorArg);
 						break;
 					}
diff --git a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverContext.java b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverContext.java
index eef4c6b..aed1428 100644
--- a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverContext.java
+++ b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverContext.java
@@ -18,6 +18,8 @@
 import java.util.*;
 import java.util.concurrent.*;
 
+import org.apache.juneau.reflection.*;
+
 /**
  * Configurable properties on the {@link VarResolver} class.
  *
@@ -47,7 +49,8 @@
 
 		Map<String,Var> m = new ConcurrentSkipListMap<>();
 		for (Class<?> c : vars) {
-			if (! isParentClass(Var.class, c))
+			ClassInfo ci = getClassInfo(c);
+			if (! ci.isChildOf(Var.class))
 				throw new VarResolverException("Invalid variable class.  Must extend from Var");
 			Var v = newInstance(Var.class, c);
 			m.put(v.getName(), v);
diff --git a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
index c6ac6c6..76b3501 100644
--- a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
+++ b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
@@ -14,6 +14,7 @@
 
 import static org.apache.juneau.internal.SystemUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.internal.ClassUtils.*;
 
 import java.io.*;
 import java.net.*;
@@ -26,6 +27,7 @@
 import org.apache.juneau.config.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.microservice.*;
+import org.apache.juneau.reflection.ClassInfo;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.svl.*;
 import org.apache.juneau.utils.*;
@@ -336,8 +338,8 @@
 		server = factory.create(jettyXml);
 
 		for (String s : cf.getStringArray("Jetty/servlets", new String[0])) {
-			Class<?> c = Class.forName(s);
-			if (ClassUtils.isParentClass(RestServlet.class, c)) {
+			ClassInfo c = getClassInfo(Class.forName(s));
+			if (c.isChildOf(RestServlet.class)) {
 				RestServlet rs = (RestServlet)c.newInstance();
 				addServlet(rs, rs.getPath());
 			} else {
@@ -346,8 +348,8 @@
 		}
 
 		for (Map.Entry<String,Object> e : cf.getObjectMap("Jetty/servletMap", ObjectMap.EMPTY_MAP).entrySet()) {
-			Class<?> c = Class.forName(e.getValue().toString());
-			if (ClassUtils.isParentClass(Servlet.class, c)) {
+			ClassInfo c = getClassInfo(Class.forName(e.getValue().toString()));
+			if (c.isChildOf(Servlet.class)) {
 				Servlet rs = (Servlet)c.newInstance();
 				addServlet(rs, e.getKey());
 			} else {
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java
index 340711a..7bec8a4 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java
@@ -160,9 +160,9 @@
 				if (t.getName().endsWith(serverExceptionName))

 					doThrow(t, serverExceptionMessage);

 			try {

-				Class<?> t = cl.loadClass(serverExceptionName);

-				if (isParentClass(RuntimeException.class, t) || isParentClass(Error.class, t))

-					doThrow(t, serverExceptionMessage);

+				ClassInfo t = getClassInfo(cl.loadClass(serverExceptionName));

+				if (t.isChildOf(RuntimeException.class) || t.isChildOf(Error.class))

+					doThrow(t.getInnerClass(), serverExceptionMessage);

 			} catch (ClassNotFoundException e2) { /* Ignore */ }

 		}

 	}