You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/02/03 17:42:30 UTC

incubator-juneau git commit: Add BeanDictionaryMap class and clean up the way Map and Collection class metas are constructed.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master 374d592e1 -> ca48a2ffd


Add BeanDictionaryMap class and clean up the way Map and Collection
class metas are constructed. 

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/ca48a2ff
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/ca48a2ff
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/ca48a2ff

Branch: refs/heads/master
Commit: ca48a2ffd22cbc51db31b3a91a27adae132d9560
Parents: 374d592
Author: JamesBognar <ja...@apache.org>
Authored: Fri Feb 3 12:42:25 2017 -0500
Committer: JamesBognar <ja...@apache.org>
Committed: Fri Feb 3 12:42:25 2017 -0500

----------------------------------------------------------------------
 .../java/org/apache/juneau/BeanConfigTest.java  |  13 -
 .../java/org/apache/juneau/BeanMapTest.java     | 123 +++---
 .../a/rttests/RoundTripPrimitivesBeansTest.java |   2 +-
 .../apache/juneau/a/rttests/RoundTripTest.java  |   4 +-
 .../a/rttests/RoundTripToObjectMapsTest.java    |   4 +-
 .../java/org/apache/juneau/jena/CommonTest.java |   4 +-
 .../CommonParser_UrlEncodingTest.java           |   3 +-
 .../urlencoding/UrlEncodingParserTest.java      |   6 +-
 .../apache/juneau/utils/FilteredMapTest.java    |   5 +-
 .../java/org/apache/juneau/BeanContext.java     | 386 +++++++++----------
 .../java/org/apache/juneau/BeanDictionary.java  |  47 ---
 .../org/apache/juneau/BeanDictionaryList.java   |  55 +++
 .../org/apache/juneau/BeanDictionaryMap.java    |  86 +++++
 .../main/java/org/apache/juneau/BeanMap.java    |   3 +
 .../java/org/apache/juneau/BeanRegistry.java    |  31 +-
 .../java/org/apache/juneau/BeanSession.java     | 108 ++----
 .../java/org/apache/juneau/ContextFactory.java  |   2 +-
 .../main/java/org/apache/juneau/ObjectMap.java  |  19 +-
 .../java/org/apache/juneau/annotation/Bean.java |   4 +-
 .../apache/juneau/annotation/BeanProperty.java  |   4 +-
 .../juneau/dto/html5/HtmlBeanDictionary.java    |   2 +-
 .../apache/juneau/internal/DelegateList.java    |   3 +-
 .../java/org/apache/juneau/parser/Parser.java   |   4 +-
 .../juneau/urlencoding/UrlEncodingParser.java   |   2 +-
 .../urlencoding/UrlEncodingSerializer.java      |   2 +-
 .../java/org/apache/juneau/xml/XmlParser.java   |   4 +-
 juneau-core/src/main/javadoc/overview.html      |   8 +-
 .../org/apache/juneau/rest/client/RestCall.java |   4 +-
 28 files changed, 489 insertions(+), 449 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java b/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
index de7fe8b..24fe4a1 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
@@ -538,19 +538,6 @@ public class BeanConfigTest {
 	}
 
 	//====================================================================================================
-	// testGetClassMetaFromString
-	//====================================================================================================
-	@Test
-	public void testGetClassMetaFromString() throws Exception {
-		BeanContext bc = BeanContext.DEFAULT;
-		assertEquals("java.lang.String[]", bc.getClassMetaFromString("java.lang.String[]").toString());
-		assertEquals("java.lang.String[]", bc.getClassMetaFromString("[Ljava.lang.String;").toString());
-		assertEquals("java.lang.String[][]", bc.getClassMetaFromString("java.lang.String[][]").toString());
-		assertEquals("java.lang.String[][]", bc.getClassMetaFromString("[[Ljava.lang.String;").toString());
-		assertEquals("boolean", bc.getClassMetaFromString("boolean").toString());
-	}
-
-	//====================================================================================================
 	// testFluentStyleSetters
 	//====================================================================================================
 	@Test

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
index 0b43eb7..17dfc5e 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
@@ -33,13 +33,36 @@ public class BeanMapTest {
 
 	JsonSerializer serializer = JsonSerializer.DEFAULT_LAX.clone().setClassLoader(BeanMapTest.class.getClassLoader());
 
+	BeanContext bc = ContextFactory.create()
+			.setClassLoader(this.getClass().getClassLoader())
+			.addToDictionary(MyBeanDictionaryMap.class)
+			.addPojoSwaps(CalendarSwap.ISO8601DTZ.class)
+			.getBeanContext();
+	BeanSession session = bc.createSession();
+
+	public static class MyBeanDictionaryMap extends BeanDictionaryMap {
+		public MyBeanDictionaryMap() {
+			addClass("StringArray", String[].class);
+			addClass("String2dArray", String[][].class);
+			addClass("IntArray", int[].class);
+			addClass("Int2dArray", int[][].class);
+			addClass("S", S.class);
+			addClass("R1", R1.class);
+			addClass("R2", R2.class);
+			addClass("LinkedList", LinkedList.class);
+			addClass("TreeMap", TreeMap.class);
+			addCollectionClass("LinkedListOfInts", LinkedList.class, Integer.class);
+			addCollectionClass("LinkedListOfR1", LinkedList.class, R1.class);
+			addCollectionClass("LinkedListOfCalendar", LinkedList.class, Calendar.class);
+		}
+	}
+	
 	//====================================================================================================
 	// Primitive field properties
 	//====================================================================================================
 	@Test
 	public void testPrimitiveFieldProperties() {
 		A t = new A();
-		BeanSession session = BeanContext.DEFAULT.createSession();
 		Map m = session.toBeanMap(t);
 
 		// Make sure setting primitive values to null causes them to get default values.
@@ -119,7 +142,6 @@ public class BeanMapTest {
 	@Test
 	public void testPrimitiveMethodProperties() {
 		B t = new B();
-		BeanSession session = BeanContext.DEFAULT.createSession();
 		Map m = session.toBeanMap(t);
 
 		// Make sure setting primitive values to null causes them to get default values.
@@ -229,7 +251,6 @@ public class BeanMapTest {
 	@Test
 	public void testCollectionFieldProperties() throws Exception {
 		C t = new C();
-		BeanSession session = BeanContext.DEFAULT.createSession();
 		Map m = session.toBeanMap(t);
 
 		// Non-initialized list fields.
@@ -311,7 +332,6 @@ public class BeanMapTest {
 	@Test
 	public void testCollectionMethodProperties() throws Exception {
 		D t = new D();
-		BeanSession session = BeanContext.DEFAULT.createSession();
 		Map m = session.toBeanMap(t);
 
 		// Non-initialized list fields.
@@ -446,7 +466,6 @@ public class BeanMapTest {
 	@Test
 	public void testArrayProperties() throws Exception {
 		D1 t = new D1();
-		BeanSession session = getBeanContext().createSession();
 		Map m = session.toBeanMap(t);
 		m.put("b", new ObjectMap("{s:'foo'}"));
 		assertNotNull(t.b);
@@ -502,7 +521,6 @@ public class BeanMapTest {
 	@Test
 	public void testArrayPropertiesInObjectList() throws Exception {
 		E t = new E();
-		BeanSession session = BeanContext.DEFAULT.createSession();
 		Map m = session.toBeanMap(t);
 		m.put("s", new ObjectList("['foo']"));
 		m.put("s2", new ObjectList("[['foo']]"));
@@ -528,7 +546,6 @@ public class BeanMapTest {
 	public void testInvokeMethod() throws Exception {
 		F t5 = new F();
 		ReaderParser p = JsonParser.DEFAULT;
-		BeanSession session = BeanContext.DEFAULT.createSession();
 		BeanMap m = session.toBeanMap(t5);
 		new PojoIntrospector(t5, p).invokeMethod("doSetAProperty(java.lang.String)", "['baz']");
 		assertEquals("baz", m.get("prop"));
@@ -549,7 +566,6 @@ public class BeanMapTest {
 	@Test
 	public void testBeanPropertyAnnotation() throws Exception {
 		G1 t6 = new G1();
-		BeanSession session = BeanContext.DEFAULT.createSession();
 		BeanMap m = session.toBeanMap(t6);
 
 		try {
@@ -632,7 +648,6 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testEnum() throws Exception {
-		BeanSession session = getBeanContext().createSession();
 
 		// Initialize existing bean.
 		H t7 = new H();
@@ -761,7 +776,7 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testOverridingDetectionOfGenericTypes2() throws Exception {
-		BeanMap bm = BeanContext.DEFAULT.createSession().newBeanMap(K.class);
+		BeanMap bm = session.newBeanMap(K.class);
 		assertEquals(Float.class, bm.getProperty("p1").getMeta().getClassMeta().getElementType().getInnerClass());
 		assertEquals(Float.class, bm.getProperty("p2").getMeta().getClassMeta().getElementType().getInnerClass());
 		assertEquals(Float.class, bm.getProperty("p3").getMeta().getClassMeta().getElementType().getInnerClass());
@@ -803,7 +818,7 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testGenericListSubclass() throws Exception {
-		BeanMap<L> bm = BeanContext.DEFAULT.createSession().newBeanMap(L.class);
+		BeanMap<L> bm = session.newBeanMap(L.class);
 		bm.put("list", "[{name:'1',value:'1'},{name:'2',value:'2'}]");
 		L b = bm.getBean();
 		assertEquals("1", b.list.get(0).name);
@@ -830,7 +845,6 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testGenericFields() throws Exception {
-		BeanSession session = BeanContext.DEFAULT.createSession();
 
 		M2 t1 = new M2();
 		BeanMap<M2> bm = session.toBeanMap(t1);
@@ -882,7 +896,6 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testGenericMethods() throws Exception {
-		BeanSession session = BeanContext.DEFAULT.createSession();
 
 		N2 t1 = new N2();
 		BeanMap<N2> bm = session.toBeanMap(t1);
@@ -1024,7 +1037,6 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testPropertyNameFactoryDashedLC1() throws Exception {
-		BeanSession session = BeanContext.DEFAULT.createSession();
 		BeanMap<P1> m = session.newBeanMap(P1.class).load("{'foo':1,'bar-baz':2,'bing-boo-url':3}");
 		assertEquals(1, m.get("foo"));
 		assertEquals(2, m.get("bar-baz"));
@@ -1126,11 +1138,10 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastWithNormalBean() throws Exception {
-		BeanSession session = getBeanContext().createSession();
 
 		// With _type
 		ObjectMap m = new ObjectMap(session);
-		m.put("_type", R2.class.getName());
+		m.put("_type", "R2");
 		m.put("f1", 1);
 		m.put("f2", "2");
 
@@ -1177,12 +1188,11 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastWithNestedBean() throws Exception {
-		BeanSession session = getBeanContext().createSession();
 
 		// With _type
 		ObjectMap m = new ObjectMap(session);
-		m.put("_type", S.class.getName());
-		m.put("f1", new ObjectMap(session).append("_type", R1.class.getName()).append("f1", 1));
+		m.put("_type", "S");
+		m.put("f1", new ObjectMap(session).append("_type", "R1").append("f1", 1));
 
 		S t = (S)m.cast();
 		assertEquals(1, t.f1.f1);
@@ -1216,12 +1226,11 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastToAnotherMapType() throws Exception {
-		BeanContext bc = BeanContext.DEFAULT;
 		Map m2;
 
 		// With _type
-		ObjectMap m = new ObjectMap();
-		m.put("_type", TreeMap.class.getName());
+		ObjectMap m = new ObjectMap(session);
+		m.put("_type", "TreeMap");
 		m.put("1", "ONE");
 
 		m2 = (Map)m.cast();
@@ -1236,7 +1245,7 @@ public class BeanMapTest {
 		assertTrue(m2 instanceof TreeMap);
 		assertEquals("ONE", m2.get("1"));
 
-		m2 = (Map)m.cast(bc.getMapClassMeta(TreeMap.class, Integer.class, TEnum.class));
+		m2 = (Map)m.cast(bc.getClassMeta(TreeMap.class, Integer.class, TEnum.class));
 		assertTrue(m2 instanceof TreeMap);
 		Map.Entry e = (Map.Entry)m2.entrySet().iterator().next();
 		assertTrue(e.getKey() instanceof Integer);
@@ -1250,7 +1259,7 @@ public class BeanMapTest {
 		assertTrue(e.getValue() instanceof String);
 		assertEquals("ONE", m2.get("1"));
 
-		m2 = (Map)m.cast(bc.getMapClassMeta(HashMap.class, Integer.class, TEnum.class));
+		m2 = (Map)m.cast(bc.getClassMeta(HashMap.class, Integer.class, TEnum.class));
 		assertTrue(m2 instanceof HashMap);
 		e = (Map.Entry)m2.entrySet().iterator().next();
 		assertTrue(e.getKey() instanceof Integer);
@@ -1273,7 +1282,7 @@ public class BeanMapTest {
 		assertTrue(m2 instanceof TreeMap);
 		assertEquals("ONE", m2.get("1"));
 
-		m2 = (Map)m.cast(bc.getMapClassMeta(TreeMap.class, Integer.class, TEnum.class));
+		m2 = (Map)m.cast(bc.getClassMeta(TreeMap.class, Integer.class, TEnum.class));
 		assertTrue(m2 instanceof TreeMap);
 		e = (Map.Entry)m2.entrySet().iterator().next();
 		assertTrue(e.getKey() instanceof Integer);
@@ -1297,11 +1306,10 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastToLinkedList() throws Exception {
-		BeanContext bc = BeanContext.DEFAULT;
 
 		// With _type
-		ObjectMap m = new ObjectMap();
-		m.put("_type", LinkedList.class.getName());
+		ObjectMap m = new ObjectMap(session);
+		m.put("_type", "LinkedList");
 		m.put("items", new ObjectList().append("1").append("2"));
 
 		List l = (List)m.cast();
@@ -1340,7 +1348,7 @@ public class BeanMapTest {
 		assertTrue(l instanceof ArrayList);
 		assertEquals("1", l.get(0));
 
-		l = (List)m.cast(bc.getCollectionClassMeta(List.class, Integer.class));
+		l = (List)m.cast(bc.getClassMeta(List.class, Integer.class));
 		assertTrue(l instanceof LinkedList);
 		assertTrue(l.get(0) instanceof Integer);
 		assertEquals(1, l.get(0));
@@ -1351,11 +1359,10 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testToLinkedListInteger() throws Exception {
-		BeanContext bc = BeanContext.DEFAULT;
-
+		
 		// With _type
-		ObjectMap m = new ObjectMap();
-		m.put("_type", LinkedList.class.getName() + "<java.lang.Integer>");
+		ObjectMap m = new ObjectMap(session);
+		m.put("_type", "LinkedListOfInts");
 		m.put("items", new ObjectList().append("1").append("2"));
 
 		List l = (List)m.cast();
@@ -1378,7 +1385,7 @@ public class BeanMapTest {
 		assertTrue(l instanceof ArrayList);
 		assertEquals(1, l.get(0));
 
-		l = (List)m.cast(bc.getCollectionClassMeta(List.class, String.class));
+		l = (List)m.cast(bc.getClassMeta(List.class, String.class));
 		assertTrue(l instanceof LinkedList);
 		assertTrue(l.get(0) instanceof String);
 		assertEquals("1", l.get(0));
@@ -1403,7 +1410,7 @@ public class BeanMapTest {
 		assertTrue(l instanceof ArrayList);
 		assertEquals("1", l.get(0));
 
-		l = (List)m.cast(bc.getCollectionClassMeta(List.class, Integer.class));
+		l = (List)m.cast(bc.getClassMeta(List.class, Integer.class));
 		assertTrue(l instanceof ObjectList);
 		assertTrue(l.get(0) instanceof Integer);
 		assertEquals(1, l.get(0));
@@ -1414,11 +1421,10 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastToLinkedListBean() throws Exception {
-		BeanSession session = getBeanContext().createSession();
 
 		// With _type
 		ObjectMap m = new ObjectMap(session);
-		m.put("_type", LinkedList.class.getName() + "<"+R1.class.getName()+">");
+		m.put("_type", "LinkedListOfR1");
 		m.put("items", new ObjectList(session).append("{f1:1}"));
 
 		List l = (List)m.cast();
@@ -1446,7 +1452,7 @@ public class BeanMapTest {
 		assertTrue(l.get(0) instanceof R1);
 		assertEquals(1, ((R1)l.get(0)).f1);
 
-		l = (List)m.cast(session.getCollectionClassMeta(List.class, HashMap.class));
+		l = (List)m.cast(session.getClassMeta(List.class, HashMap.class));
 		assertTrue(l instanceof LinkedList);
 		assertTrue(l.get(0) instanceof HashMap);
 		assertEquals(1, ((Map)l.get(0)).get("f1"));
@@ -1475,17 +1481,17 @@ public class BeanMapTest {
 		assertTrue(l.get(0) instanceof String);
 		assertEquals("{f1:1}", l.get(0));
 
-		l = (List)m.cast(session.getCollectionClassMeta(List.class, R1.class));
+		l = (List)m.cast(session.getClassMeta(List.class, R1.class));
 		assertTrue(l instanceof LinkedList);
 		assertTrue(l.get(0) instanceof R1);
 		assertEquals(1, ((R1)l.get(0)).f1);
 
-		l = (List)m.cast(session.getCollectionClassMeta(List.class, HashMap.class));
+		l = (List)m.cast(session.getClassMeta(List.class, HashMap.class));
 		assertTrue(l instanceof LinkedList);
 		assertTrue(l.get(0) instanceof HashMap);
 		assertEquals(1, ((Map)l.get(0)).get("f1"));
 
-		l = (List)m.cast(session.getCollectionClassMeta(List.class, Map.class));
+		l = (List)m.cast(session.getClassMeta(List.class, Map.class));
 		assertTrue(l instanceof LinkedList);
 		assertTrue(l.get(0) instanceof ObjectMap);
 		assertEquals(1, ((Map)l.get(0)).get("f1"));
@@ -1496,11 +1502,10 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastToLinkedListUsingSwap() throws Exception {
-		BeanSession session = ContextFactory.create().addPojoSwaps(CalendarSwap.ISO8601DTZ.class).getBeanContext().createSession();
 
 		// With _type
 		ObjectMap m = new ObjectMap(session);
-		m.put("_type", LinkedList.class.getName() + "<"+Calendar.class.getName()+">");
+		m.put("_type", "LinkedListOfCalendar");
 		m.put("items", new ObjectList().append("2001-07-04T15:30:45Z"));
 
 		List l = (List)m.cast();
@@ -1525,7 +1530,7 @@ public class BeanMapTest {
 		assertTrue(l instanceof ArrayList);
 		assertEquals(2001, ((Calendar)l.get(0)).get(Calendar.YEAR));
 
-		l = (List)m.cast(session.getCollectionClassMeta(List.class, String.class));
+		l = (List)m.cast(session.getClassMeta(List.class, String.class));
 		assertTrue(l instanceof LinkedList);
 		assertTrue(l.get(0) instanceof String);
 		assertEquals("2001-07-04T15:30:45Z", l.get(0));
@@ -1548,7 +1553,7 @@ public class BeanMapTest {
 		l = m.cast(session.getClassMeta(ArrayList.class));
 		assertTrue(l instanceof ArrayList);
 
-		l = (List)m.cast(session.getCollectionClassMeta(List.class, Calendar.class));
+		l = (List)m.cast(session.getClassMeta(List.class, Calendar.class));
 		assertTrue(l instanceof LinkedList);
 		assertTrue(l.get(0) instanceof Calendar);
 		assertEquals(2001, ((Calendar)l.get(0)).get(Calendar.YEAR));
@@ -1559,11 +1564,10 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastToStringArray() throws Exception {
-		BeanContext bc = BeanContext.DEFAULT;
-
+		
 		// With _type
-		ObjectMap m = new ObjectMap();
-		m.put("_type", String[].class.getName());
+		ObjectMap m = new ObjectMap(session);
+		m.put("_type", "StringArray");
 		m.put("items", new ObjectList().append("1").append("2"));
 
 		String[] l = (String[])m.cast();
@@ -1600,17 +1604,16 @@ public class BeanMapTest {
 		l2 = m.cast(bc.getClassMeta(StringBuffer[].class));
 		assertEquals("1", l[0].toString());
 	}
-
+	
 	//====================================================================================================
 	// testCastToIntArray - cast() to int[]
 	//====================================================================================================
 	@Test
 	public void testCastToIntArray() throws Exception {
-		BeanContext bc = BeanContext.DEFAULT;
 
 		// With _type
-		ObjectMap m = new ObjectMap();
-		m.put("_type", int[].class.getName());
+		ObjectMap m = new ObjectMap(session);
+		m.put("_type", "IntArray");
 		m.put("items", new ObjectList().append("1").append("2"));
 
 		int[] l = (int[])m.cast();
@@ -1652,11 +1655,10 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastToString2dArray() throws Exception {
-		BeanContext bc = BeanContext.DEFAULT;
 
 		// With _type
-		ObjectMap m = new ObjectMap();
-		m.put("_type", String[][].class.getName());
+		ObjectMap m = new ObjectMap(session);
+		m.put("_type", "String2dArray");
 		m.put("items", new ObjectList().append(new ObjectList().append("1")).append(new ObjectList().append("2")));
 
 		String[][] l = (String[][])m.cast();
@@ -1685,11 +1687,10 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testCastToInt2dArray() throws Exception {
-		BeanContext bc = BeanContext.DEFAULT;
 
 		// With _type
-		ObjectMap m = new ObjectMap();
-		m.put("_type", int[][].class.getName());
+		ObjectMap m = new ObjectMap(session);
+		m.put("_type", "Int2dArray");
 		m.put("items", new ObjectList().append(new ObjectList().append("1")).append(new ObjectList().append("2")));
 
 		int[][] l = (int[][])m.cast();
@@ -1881,10 +1882,6 @@ public class BeanMapTest {
 		}
 	}
 
-	private BeanContext getBeanContext() {
-		return ContextFactory.create().setClassLoader(this.getClass().getClassLoader()).getBeanContext();
-	}
-
 	@Test
 	public void testSettingCollectionPropertyMultipleTimes() throws Exception {
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java
index cd83e0f..8dd1407 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java
@@ -274,7 +274,7 @@ public class RoundTripPrimitivesBeansTest extends RoundTripTest {
 		}};
 		if (p == null)
 			return;
-		t = roundTrip(t, p.getBeanContext().getCollectionClassMeta(List.class, PrimitivesBean.class));
+		t = roundTrip(t, p.getBeanContext().createSession().getCollectionClassMeta(List.class, PrimitivesBean.class));
 
 		PrimitivesBean t2 = t.get(2);
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java
index 3c9b63a..675084a 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java
@@ -248,7 +248,7 @@ public abstract class RoundTripTest {
 		Object out = serialize(object, this.s);
 		if (p == null)
 			return object;
-		ClassMeta<? extends T> cm = p.getBeanContext().getMapClassMeta(c, k, v);
+		ClassMeta<? extends T> cm = p.getBeanContext().getClassMeta(c, k, v);
 		T o = this.p.parse(out, cm);
 		return (returnOriginalObject ? object : o);
 	}
@@ -256,7 +256,7 @@ public abstract class RoundTripTest {
 		Object out = serialize(object, this.s);
 		if (p == null)
 			return object;
-		ClassMeta<? extends T> cm = p.getBeanContext().getCollectionClassMeta(c, e);
+		ClassMeta<? extends T> cm = p.getBeanContext().getClassMeta(c, e);
 		T o = this.p.parse(out, cm);
 		return (returnOriginalObject ? object : o);
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
index 9e48e24..4a9ada9 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
@@ -50,13 +50,13 @@ public class RoundTripToObjectMapsTest extends RoundTripTest {
 		assertEquals(2, aa[0].f2);
 
 		List<A> a2 = new ArrayList<A>(){{add(new A(new ObjectMap("{f1:'a',f2:2}")));}};
-		a2 = roundTrip(a2, BeanContext.DEFAULT.getCollectionClassMeta(List.class, A.class));
+		a2 = roundTrip(a2, BeanContext.DEFAULT.createSession().getCollectionClassMeta(List.class, A.class));
 		assertEquals(1, a2.size());
 		assertEquals("a", a2.get(0).f1);
 		assertEquals(2, a2.get(0).f2);
 
 		Map<String,A> a3 = new LinkedHashMap<String,A>(){{put("a", new A(new ObjectMap("{f1:'a',f2:2}")));}};
-		a3 = roundTrip(a3, BeanContext.DEFAULT.getMapClassMeta(Map.class, String.class, A.class));
+		a3 = roundTrip(a3, BeanContext.DEFAULT.createSession().getMapClassMeta(Map.class, String.class, A.class));
 		assertEquals(1, a3.size());
 		assertEquals("a", a3.get("a").f1);
 		assertEquals(2, a3.get("a").f2);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
index c2085a2..45994ec 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
@@ -30,7 +30,7 @@ import org.apache.juneau.testbeans.*;
 import org.apache.juneau.xml.*;
 import org.junit.*;
 
-@SuppressWarnings({"unchecked","serial","javadoc"})
+@SuppressWarnings({"serial","javadoc"})
 public class CommonTest {
 
 	private RdfSerializer getBasicSerializer() {
@@ -236,7 +236,7 @@ public class CommonTest {
 
 		String r = s.serialize(l1);
 		assertEquals("<rdf:Seq><rdf:li rdf:parseType='Resource'><jp:x1><rdf:Seq><rdf:li rdf:parseType='Resource'><jp:x2>2</jp:x2></rdf:li></rdf:Seq></jp:x1><jp:x2>2</jp:x2></rdf:li></rdf:Seq>", strip(r));
-		ClassMeta<LinkedList<F>> cm = p.getBeanContext().getCollectionClassMeta(LinkedList.class, F.class);
+		ClassMeta<LinkedList<F>> cm = p.getBeanContext().getClassMeta(LinkedList.class, F.class);
 		l2 = p.parse(r, cm);
 		assertEqualObjects(l1, l2);
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
index b75834d..6e3823a 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
@@ -170,7 +170,6 @@ public class CommonParser_UrlEncodingTest {
 		assertEquals("unknownProperty,1,4", events.get(0));
 	}
 
-	@SuppressWarnings("unchecked")
 	@Test
 	public void testCollections() throws Exception {
 		WriterSerializer s = new UrlEncodingSerializer().setProperty(UonSerializerContext.UON_simpleMode, true);
@@ -180,7 +179,7 @@ public class CommonParser_UrlEncodingTest {
 		assertEquals("0=foo&1=bar", s.serialize(l));
 
 		String in =  "0=foo&1=bar";
-		ClassMeta<LinkedList<String>> cm = p.getBeanContext().createSession().getCollectionClassMeta(LinkedList.class, String.class);
+		ClassMeta<LinkedList<String>> cm = p.getBeanContext().createSession().getClassMeta(LinkedList.class, String.class);
 		l = p.parse(in, cm);
 		assertObjectEquals("['foo','bar']",l);
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
index 03198f8..18f12c9 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
@@ -165,7 +165,7 @@ public class UrlEncodingParserTest {
 		l = (List)l.get(0);
 		assertTrue(l.isEmpty());
 		t = "(())";
-		l = (List)p.parseParameter(t, p.getBeanContext().getCollectionClassMeta(LinkedList.class, List.class));
+		l = (List)p.parseParameter(t, p.getBeanContext().getClassMeta(LinkedList.class, List.class));
 		assertTrue(l.size() == 1);
 		l = (List)l.get(0);
 		assertTrue(l.isEmpty());
@@ -185,7 +185,7 @@ public class UrlEncodingParserTest {
 		assertTrue(l.size() == 1);
 		assertEquals("", l.get(0));
 		t = "(())";
-		l = (List)p.parseParameter(t, p.getBeanContext().getCollectionClassMeta(List.class, String.class));
+		l = (List)p.parseParameter(t, p.getBeanContext().getClassMeta(List.class, String.class));
 		assertTrue(l.size() == 1);
 		assertEquals("", l.get(0));
 
@@ -217,7 +217,7 @@ public class UrlEncodingParserTest {
 		assertEquals("", l.get(1));
 		assertEquals("", l.get(2));
 		t = "(,,)";
-		l = (List)p.parseParameter(t, p.getBeanContext().getCollectionClassMeta(List.class, Object.class));
+		l = (List)p.parseParameter(t, p.getBeanContext().getClassMeta(List.class, Object.class));
 		assertTrue(l.size() == 3);
 		assertEquals("", l.get(0));
 		assertEquals("", l.get(1));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core-test/src/test/java/org/apache/juneau/utils/FilteredMapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/utils/FilteredMapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/utils/FilteredMapTest.java
index ec75da3..db00d39 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/utils/FilteredMapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/FilteredMapTest.java
@@ -30,12 +30,11 @@ public class FilteredMapTest {
 	// testBasic
 	//====================================================================================================
 	@Test
-	@SuppressWarnings("unchecked")
 	public void testBasic() throws Exception {
 		ObjectMap m = new ObjectMap("{a:'1',b:'2'}");
 
-		ClassMeta<Map<String,Object>> cm = BeanContext.DEFAULT.getMapClassMeta(Map.class, String.class, Object.class);
-		ClassMeta<Map<String,String>> cm2 = BeanContext.DEFAULT.getMapClassMeta(Map.class, String.class, String.class);
+		ClassMeta<Map<String,Object>> cm = BeanContext.DEFAULT.getClassMeta(Map.class, String.class, Object.class);
+		ClassMeta<Map<String,String>> cm2 = BeanContext.DEFAULT.getClassMeta(Map.class, String.class, String.class);
 
 		FilteredMap<String,Object> m2 = new FilteredMap<String,Object>(cm, m, new String[]{"a"});
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
index 06e1f8f..1a06ea4 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
@@ -856,7 +856,8 @@ public class BeanContext extends Context {
 	 * This list can consist of the following class types:
 	 * <ul>
 	 * 	<li>Any bean class that specifies a value for {@link Bean#typeName() @Bean.typeName()}.
-	 * 	<li>Any collection of bean classes above.
+	 * 	<li>Any subclass of {@link BeanDictionaryList} containing a collection of bean classes with type name annotations.
+	 * 	<li>Any subclass of {@link BeanDictionaryMap} containing a mapping of type names to classes without type name annotations.
 	 * </ul>
 	 */
 	public static final String BEAN_beanDictionary = "BeanContext.beanDictionary.list";
@@ -1283,18 +1284,91 @@ public class BeanContext extends Context {
 			return cm;
 		if (cm.isMap()) {
 			ClassMeta<Map> cm2 = (ClassMeta<Map>)cm;
-			cm2 = getMapClassMeta(cm2.getInnerClass(), cm2.getKeyType().getInnerClass(), cm2.getValueType().getInnerClass());
+			cm2 = getClassMeta(cm2.getInnerClass(), cm2.getKeyType().getInnerClass(), cm2.getValueType().getInnerClass());
 			return (ClassMeta<T>)cm2;
 		}
 		if (cm.isCollection()) {
 			ClassMeta<Collection> cm2 = (ClassMeta<Collection>)cm;
-			cm2 = getCollectionClassMeta(cm2.getInnerClass(), cm2.getElementType().getInnerClass());
+			cm2 = getClassMeta(cm2.getInnerClass(), cm2.getElementType().getInnerClass());
 			return (ClassMeta<T>)cm2;
 		}
 		return getClassMeta(cm.getInnerClass());
 	}
 
 	/**
+	 * Resolves the following types of objects:
+	 * <ul>
+	 * 	<li>{@link Class}
+	 * 	<li><code>Object[2]</code> containing <code>{Class&lt;? extends Collection&gt;, Object}</code>
+	 * 		where the 2nd entry is the entry type which can be anything on this list.
+	 * 	<li><code>Object[3]</code> containing <code>{Class&lt;? extends Map&gt;, Object, Object}</code>
+	 * 		where the 2nd entry is the key type and 3rd entry is the value type which can be anything on this list.
+	 * </ul>
+	 *
+	 * @param o
+	 * @return The resolved class meta.
+	 */
+	public final <T> ClassMeta<T> getClassMeta(Object o) {
+		if (o == null)
+			return null;
+		if (o instanceof Class)
+			return getClassMeta((Class)o);
+		if (o instanceof Type)
+			return getClassMeta((Type)o);
+		if (List.class.isAssignableFrom(o.getClass())) {
+			List l = (List)o;
+			o = l.toArray(new Object[l.size()]);
+			return getClassMeta((Object[])o);
+		}
+		if (o.getClass().isArray())
+			return getClassMeta((Object[])o);
+		throw new BeanRuntimeException("Invalid object type passed to getClassMeta(): ''{0}''.  Only Class or arrays containing Class is supported.", o.getClass().getName());
+	}
+
+	/**
+	 * Resolves the following types of objects:
+	 * <ul>
+	 * 	<li><code>Object[2]</code> containing <code>{Class&lt;? extends Collection&gt;, Object}</code>
+	 * 		where the 2nd entry is the entry type which can be anything on this list.
+	 * 	<li><code>Object[3]</code> containing <code>{Class&lt;? extends Map&gt;, Object, Object}</code>
+	 * 		where the 2nd entry is the key type and 3rd entry is the value type which can be anything on this list.
+	 * </ul>
+	 *
+	 * @param o
+	 * @return The resolved class meta.
+	 */
+	public final <T> ClassMeta<T> getClassMeta(Object...o) {
+		if (o == null)
+			return null;
+		int len = o.length;
+		if (len == 2) {
+			Object oc = Array.get(o, 0);
+			if (oc instanceof Class) {
+				Class c = (Class)oc;
+				if (Collection.class.isAssignableFrom(c)) {
+					ClassMeta<?> ce = getClassMeta(Array.get(o, 1));
+					if (ce.isObject())
+						return getClassMeta(c);
+					return new ClassMeta(c, this).setElementType(ce);
+				}
+			}
+		} else if (len == 3) {
+			Object oc = Array.get(o, 0);
+			if (oc instanceof Class) {
+				Class c = (Class)oc;
+				if (Map.class.isAssignableFrom(c)) {
+					ClassMeta<?> ck = getClassMeta(Array.get(o, 1));
+					ClassMeta<?> cv = getClassMeta(Array.get(o, 2));
+					if (ck.isObject() && cv.isObject())
+						return getClassMeta(c);
+					return new ClassMeta(c, this).setKeyType(ck).setValueType(cv);
+				}
+			}
+		}
+		throw new BeanRuntimeException("Invalid object type passed to getClassMeta(): ''{0}''.  Only Class or arrays containing Class is supported.", o.getClass().getName());
+	}
+
+	/**
 	 * Construct a {@code ClassMeta} wrapper around a {@link Class} object.
 	 *
 	 * @param <T> The class type being wrapped.
@@ -1346,97 +1420,6 @@ public class BeanContext extends Context {
 	}
 
 	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Map} object.
-	 *
-	 * @param <K> The map key class type.
-	 * @param <V> The map value class type.
-	 * @param <T> The map class type.
-	 * @param c The map class type.
-	 * @param keyType The map key class type.
-	 * @param valueType The map value class type.
-	 * @return If the key and value types are OBJECT, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
-	 */
-	public final <K,V,T extends Map<K,V>> ClassMeta<T> getMapClassMeta(Class<T> c, ClassMeta<K> keyType, ClassMeta<V> valueType) {
-		if (keyType.isObject() && valueType.isObject())
-			return getClassMeta(c);
-		return new ClassMeta(c, this).setKeyType(keyType).setValueType(valueType);
-	}
-
-	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Map} object.
-	 *
-	 * @param <K> The map key class type.
-	 * @param <V> The map value class type.
-	 * @param <T> The map class type.
-	 * @param c The map class type.
-	 * @param keyType The map key class type.
-	 * @param valueType The map value class type.
-	 * @return If the key and value types are Object, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
-	 */
-	public final <K,V,T extends Map<K,V>> ClassMeta<T> getMapClassMeta(Class<T> c, Class<K> keyType, Class<V> valueType) {
-		return getMapClassMeta(c, getClassMeta(keyType), getClassMeta(valueType));
-	}
-
-	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Map} object.
-	 *
-	 * @param <T> The map class type.
-	 * @param c The map class type.
-	 * @param keyType The map key class type.
-	 * @param valueType The map value class type.
-	 * @return If the key and value types are Object, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
-	 */
-	public final <T extends Map> ClassMeta<T> getMapClassMeta(Class<T> c, Type keyType, Type valueType) {
-		return getMapClassMeta(c, getClassMeta(keyType), getClassMeta(valueType));
-	}
-
-	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Collection} object.
-	 *
-	 * @param <E> The collection element class type.
-	 * @param <T> The collection class type.
-	 * @param c The collection class type.
-	 * @param elementType The collection element class type.
-	 * @return If the element type is <code>OBJECT</code>, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
-	 */
-	public final <E,T extends Collection<E>> ClassMeta<T> getCollectionClassMeta(Class<T> c, ClassMeta<E> elementType) {
-		if (elementType.isObject())
-			return getClassMeta(c);
-		return new ClassMeta(c, this).setElementType(elementType);
-	}
-
-	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Collection} object.
-	 *
-	 * @param <E> The collection element class type.
-	 * @param <T> The collection class type.
-	 * @param c The collection class type.
-	 * @param elementType The collection element class type.
-	 * @return If the element type is <code>OBJECT</code>, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
-	 */
-	public final <E,T extends Collection<E>> ClassMeta<T> getCollectionClassMeta(Class<T> c, Class<E> elementType) {
-		return getCollectionClassMeta(c, getClassMeta(elementType));
-	}
-
-	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Collection} object.
-	 *
-	 * @param <T> The collection class type.
-	 * @param c The collection class type.
-	 * @param elementType The collection element class type.
-	 * @return If the element type is <code>OBJECT</code>, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
-	 */
-	public final <T extends Collection> ClassMeta<T> getCollectionClassMeta(Class<T> c, Type elementType) {
-		return getCollectionClassMeta(c, getClassMeta(elementType));
-	}
-
-	/**
 	 * Constructs a ClassMeta object given the specified object and parameters.
 	 *
 	 * @param o The parent class type.
@@ -1648,112 +1631,115 @@ public class BeanContext extends Context {
 		return cmObject;
 	}
 
-	/**
-	 * Converts class name strings to ClassMeta objects.
-	 *
-	 * <h6 class='topic'>Example:</h6>
-	 * <ul>
-	 * 	<li><js>"java.lang.String"</js>
-	 * 	<li><js>"com.foo.sample.MyBean[]"</js>
-	 * 	<li><js>"java.util.HashMap<java.lang.String,java.lang.Integer>"</js>
-	 * 	<li><js>"[Ljava.lang.String;"</js> (i.e. the value of <code>String[].<jk>class</jk>.getName()</code>)
-	 * </ul>
-	 *
-	 * @param s The class name.
-	 * @return The ClassMeta corresponding to the class name string.
-	 */
-	protected final ClassMeta<?> getClassMetaFromString(String s) {
-		int d = 0;
-		if (s == null || s.isEmpty())
-			return null;
-
-		// Check for Class.getName() on array class types.
-		if (s.charAt(0) == '[') {
-			try {
-				return getClassMeta(findClass(s));
-			} catch (ClassNotFoundException e) {
-				throw new RuntimeException(e);
-			}
-		}
-
-		int i1 = 0;
-		int i2 = 0;
-		int dim = 0;
-		List<ClassMeta<?>> p = null;
-		for (int i = 0; i < s.length(); i++) {
-			char c = s.charAt(i);
-			if (c == '<') {
-				if (d == 0) {
-					i1 = i;
-					i2 = i+1;
-					p = new LinkedList<ClassMeta<?>>();
-				}
-				d++;
-			} else if (c == '>') {
-				d--;
-				if (d == 0 && p != null)
-					p.add(getClassMetaFromString(s.substring(i2, i)));
-			} else if (c == ',' && d == 1) {
-				if (p != null)
-					p.add(getClassMetaFromString(s.substring(i2, i)));
-				i2 = i+1;
-			}
-			if (c == '[') {
-				if (i1 == 0)
-					i1 = i;
-				dim++;
-			}
-		}
-		if (i1 == 0)
-			i1 = s.length();
-		try {
-			String name = s.substring(0, i1).trim();
-			char x = name.charAt(0);
-			Class<?> c = null;
-			if (x >= 'b' && x <= 's') {
-				if (x == 'b' && name.equals("boolean"))
-					c = boolean.class;
-				else if (x == 'b' && name.equals("byte"))
-					c = byte.class;
-				else if (x == 'c' && name.equals("char"))
-					c = char.class;
-				else if (x == 'd' && name.equals("double"))
-					c = double.class;
-				else if (x == 'i' && name.equals("int"))
-					c = int.class;
-				else if (x == 'l' && name.equals("long"))
-					c = long.class;
-				else if (x == 's' && name.equals("short"))
-					c = short.class;
-				else
-					c = findClass(name);
-			} else {
-				c = findClass(name);
-			}
-
-			ClassMeta<?> cm = getClassMeta(c);
-
-			if (p != null) {
-				if (cm.isMap())
-					cm = new ClassMeta(c, this).setKeyType(p.get(0)).setValueType(p.get(1));
-				if (cm.isCollection())
-					cm = new ClassMeta(c, this).setElementType(p.get(0));
-			}
-
-			while (dim > 0) {
-				cm = new ClassMeta(Array.newInstance(cm.getInnerClass(), 0).getClass(), this);
-				dim--;
-			}
-
-			return cm;
-		} catch (ClassNotFoundException e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	private Class<?> findClass(String name) throws ClassNotFoundException {
-		return classLoader == null ? Class.forName(name) : Class.forName(name, true, classLoader);
-	}
+//
+//  This code is inherently unsafe (but still potentially useful?)
+// 
+//	/**
+//	 * Converts class name strings to ClassMeta objects.
+//	 *
+//	 * <h6 class='topic'>Example:</h6>
+//	 * <ul>
+//	 * 	<li><js>"java.lang.String"</js>
+//	 * 	<li><js>"com.foo.sample.MyBean[]"</js>
+//	 * 	<li><js>"java.util.HashMap<java.lang.String,java.lang.Integer>"</js>
+//	 * 	<li><js>"[Ljava.lang.String;"</js> (i.e. the value of <code>String[].<jk>class</jk>.getName()</code>)
+//	 * </ul>
+//	 *
+//	 * @param s The class name.
+//	 * @return The ClassMeta corresponding to the class name string.
+//	 */
+//	protected final ClassMeta<?> getClassMetaFromString(String s) {
+//		int d = 0;
+//		if (s == null || s.isEmpty())
+//			return null;
+//
+//		// Check for Class.getName() on array class types.
+//		if (s.charAt(0) == '[') {
+//			try {
+//				return getClassMeta(findClass(s));
+//			} catch (ClassNotFoundException e) {
+//				throw new RuntimeException(e);
+//			}
+//		}
+//
+//		int i1 = 0;
+//		int i2 = 0;
+//		int dim = 0;
+//		List<ClassMeta<?>> p = null;
+//		for (int i = 0; i < s.length(); i++) {
+//			char c = s.charAt(i);
+//			if (c == '<') {
+//				if (d == 0) {
+//					i1 = i;
+//					i2 = i+1;
+//					p = new LinkedList<ClassMeta<?>>();
+//				}
+//				d++;
+//			} else if (c == '>') {
+//				d--;
+//				if (d == 0 && p != null)
+//					p.add(getClassMetaFromString(s.substring(i2, i)));
+//			} else if (c == ',' && d == 1) {
+//				if (p != null)
+//					p.add(getClassMetaFromString(s.substring(i2, i)));
+//				i2 = i+1;
+//			}
+//			if (c == '[') {
+//				if (i1 == 0)
+//					i1 = i;
+//				dim++;
+//			}
+//		}
+//		if (i1 == 0)
+//			i1 = s.length();
+//		try {
+//			String name = s.substring(0, i1).trim();
+//			char x = name.charAt(0);
+//			Class<?> c = null;
+//			if (x >= 'b' && x <= 's') {
+//				if (x == 'b' && name.equals("boolean"))
+//					c = boolean.class;
+//				else if (x == 'b' && name.equals("byte"))
+//					c = byte.class;
+//				else if (x == 'c' && name.equals("char"))
+//					c = char.class;
+//				else if (x == 'd' && name.equals("double"))
+//					c = double.class;
+//				else if (x == 'i' && name.equals("int"))
+//					c = int.class;
+//				else if (x == 'l' && name.equals("long"))
+//					c = long.class;
+//				else if (x == 's' && name.equals("short"))
+//					c = short.class;
+//				else
+//					c = findClass(name);
+//			} else {
+//				c = findClass(name);
+//			}
+//
+//			ClassMeta<?> cm = getClassMeta(c);
+//
+//			if (p != null) {
+//				if (cm.isMap())
+//					cm = new ClassMeta(c, this).setKeyType(p.get(0)).setValueType(p.get(1));
+//				if (cm.isCollection())
+//					cm = new ClassMeta(c, this).setElementType(p.get(0));
+//			}
+//
+//			while (dim > 0) {
+//				cm = new ClassMeta(Array.newInstance(cm.getInnerClass(), 0).getClass(), this);
+//				dim--;
+//			}
+//
+//			return cm;
+//		} catch (ClassNotFoundException e) {
+//			throw new RuntimeException(e);
+//		}
+//	}
+//
+//	private Class<?> findClass(String name) throws ClassNotFoundException {
+//		return classLoader == null ? Class.forName(name) : Class.forName(name, true, classLoader);
+//	}
 
 	/**
 	 * Returns the {@link PojoSwap} associated with the specified class, or <jk>null</jk> if there is no

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java b/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java
deleted file mode 100644
index 333ef6d..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// ***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
-// * with the License.  You may obtain a copy of the License at                                                              *
-// *                                                                                                                         *
-// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
-// *                                                                                                                         *
-// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
-// * specific language governing permissions and limitations under the License.                                              *
-// ***************************************************************************************************************************
-package org.apache.juneau;
-
-import java.util.*;
-
-import org.apache.juneau.annotation.*;
-
-/**
- * Represents a collection of bean classes that make up a bean dictionary.
- */
-public class BeanDictionary extends ArrayList<Class<?>> {
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Constructor.
-	 *
-	 * @param c The list of bean classes to add to this dictionary.
-	 * 	Classes must either specify a {@link Bean#typeName()} value or be another subclass of <code>BeanDictionary</code>.
-	 */
-	public BeanDictionary(Class<?>...c) {
-		append(c);
-	}
-
-	/**
-	 * Append one or more bean classes to this bean dictionary.
-	 *
-	 * @param c The list of bean classes to add to this dictionary.
-	 * 	Classes must either specify a {@link Bean#typeName()} value or be another subclass of <code>BeanDictionary</code>.
-	 * @return This object (for method chaining).
-	 */
-	public BeanDictionary append(Class<?>...c) {
-		for (Class<?> cc : c)
-			add(cc);
-		return this;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryList.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryList.java b/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryList.java
new file mode 100644
index 0000000..3ce75d0
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryList.java
@@ -0,0 +1,55 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau;
+
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+
+/**
+ * Represents a collection of bean classes that make up a bean dictionary.
+ * <p>
+ * The classes in the list must be one of the following:
+ * <ul>
+ * 	<li>Beans that provide a dictionary name using the {@link Bean#typeName()} annotation.
+ * 	<li>Other subclasses of {@link BeanDictionaryList}.
+ * 	<li>Other subclasses of {@link BeanDictionaryMap}.
+ * <p>
+ * Subclasses must implement a public no-arg constructor so that it can be instantiated by the bean context code.
+ */
+public class BeanDictionaryList extends ArrayList<Class<?>> {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param c The list of bean classes to add to this dictionary.
+	 * 	Classes must either specify a {@link Bean#typeName()} value or be another subclass of <code>BeanDictionaryList</code>.
+	 */
+	public BeanDictionaryList(Class<?>...c) {
+		append(c);
+	}
+
+	/**
+	 * Append one or more bean classes to this bean dictionary.
+	 *
+	 * @param c The list of bean classes to add to this dictionary.
+	 * 	Classes must either specify a {@link Bean#typeName()} value or be another subclass of <code>BeanDictionaryList</code>.
+	 * @return This object (for method chaining).
+	 */
+	protected BeanDictionaryList append(Class<?>...c) {
+		for (Class<?> cc : c)
+			add(cc);
+		return this;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryMap.java b/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryMap.java
new file mode 100644
index 0000000..b6bd314
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryMap.java
@@ -0,0 +1,86 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+
+/**
+ * Represents a map of dictionary type names to bean classes that make up a bean dictionary.
+ * <p>
+ * In general, this approach for defining dictionary names for classes is used when it's not possible
+ * to use the {@link Bean#typeName()} annotation.
+ * <p>
+ * Subclasses must implement a public no-arg constructor so that it can be instantiated by the bean context code.
+ */
+@SuppressWarnings("rawtypes")
+public class BeanDictionaryMap extends LinkedHashMap<String,Object> {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Add a dictionary name mapping for the specified class.
+	 *
+	 * @param typeName The dictionary name of the class.
+	 * @param c The class represented by the dictionary name.
+	 * @return This object (for method chaining).
+	 */
+	protected BeanDictionaryMap addClass(String typeName, Class<?> c) {
+		put(typeName, c);
+		return this;
+	}
+
+	/**
+	 * Add a dictionary name mapping for the specified map class with the specified key and value classes.
+	 *
+	 * @param typeName The dictionary name of the class.
+	 * @param mapClass The map implementation class.
+	 * @param keyClass The key class.
+	 * @param valueClass The value class.
+	 * @return This object (for method chaining).
+	 */
+	protected BeanDictionaryMap addMapClass(String typeName, Class<? extends Map> mapClass, Object keyClass, Object valueClass) {
+		assertValidParameter(keyClass);
+		assertValidParameter(valueClass);
+		put(typeName, new Object[]{mapClass, keyClass, valueClass});
+		return this;
+	}
+
+	/**
+	 * Add a dictionary name mapping for the specified collection class with the specified entry class.
+	 *
+	 * @param typeName The dictionary name of the class.
+	 * @param collectionClass The collection implementation class.
+	 * @param entryClass The entry class.
+	 * @return This object (for method chaining).
+	 */
+	protected BeanDictionaryMap addCollectionClass(String typeName, Class<? extends Collection> collectionClass, Object entryClass) {
+		assertValidParameter(entryClass);
+		put(typeName, new Object[]{collectionClass, entryClass});
+		return this;
+	}
+
+	private void assertValidParameter(Object o) {
+		if (o != null) {
+			if (o instanceof Class)
+				return;
+			if (o.getClass().isArray()) {
+				for (int i = 0; i < Array.getLength(o); i++)
+					assertValidParameter(Array.get(o, i));
+				return;
+			}
+		}
+		throw new BeanRuntimeException("Invalid object type passed to BeanDictionaryMap: ''{0}''.  Only objects of type Class or Object[] containing Class or Object[] objects can be used.");
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
index 7ea88f0..8b7d563 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
@@ -212,6 +212,9 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 				return propertyCache.put(property, value);
 			}
 
+			if (property.equals(session.getBeanTypePropertyName()))
+				return null;
+
 			throw new BeanRuntimeException(meta.c, "Bean property ''{0}'' not found.", property);
 		}
 		if (meta.beanFilter != null)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java b/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java
index 679a3e5..0bc404c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanRegistry.java
@@ -54,26 +54,35 @@ public class BeanRegistry {
 	}
 
 	private void addClass(Class<?> c) {
-		if (c != null) {
-			if (ClassUtils.isParentClass(Collection.class, c)) {
-				try {
+		try {
+			if (c != null) {
+				if (ClassUtils.isParentClass(Collection.class, c)) {
 					@SuppressWarnings("rawtypes")
 					Collection cc = (Collection)c.newInstance();
 					for (Object o : cc) {
 						if (o instanceof Class)
 							addClass((Class<?>)o);
 						else
-							throw new BeanRuntimeException("Collection class passed to BeanRegistry does not contain Class objects.", c.getName());
+							throw new BeanRuntimeException("Collection class ''{0}'' passed to BeanRegistry does not contain Class objects.", c.getName());
 					}
-				} catch (Exception e) {
-					throw new BeanRuntimeException(e);
+				} else if (ClassUtils.isParentClass(Map.class, c)) {
+					Map<?,?> m = (Map<?,?>)c.newInstance();
+					for (Map.Entry<?,?> e : m.entrySet()) {
+						String typeName = StringUtils.toString(e.getKey());
+						ClassMeta<?> val = beanContext.getClassMeta(e.getValue());
+						map.put(typeName, val);
+					}
+				} else {
+					Bean b = c.getAnnotation(Bean.class);
+					if (b == null || b.typeName().isEmpty())
+						throw new BeanRuntimeException("Class ''{0}'' was passed to BeanRegistry but it doesn't have a @Bean.typeName() annotation defined.", c.getName());
+					map.put(b.typeName(), beanContext.getClassMeta(c));
 				}
-			} else {
-				Bean b = c.getAnnotation(Bean.class);
-				if (b == null || b.typeName().isEmpty())
-					throw new BeanRuntimeException("Class ''{0}'' was passed to BeanRegistry but it doesn't have a @Bean.typeName() annotation defined.", c.getName());
-				map.put(b.typeName(), beanContext.getClassMeta(c));
 			}
+		} catch (BeanRuntimeException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new BeanRuntimeException(e);
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
index dd1ccdf..90b794f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
@@ -817,53 +817,52 @@ public class BeanSession extends Session {
 	}
 
 	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Class} object.
+	 * Returns a {@code ClassMeta} wrapper around a {@link Class} object.
 	 *
 	 * @param <T> The class type being wrapped.
 	 * @param c The class being wrapped.
-	 * 	of type {@link Class} or {@link ClassMeta}.
-	 * @return If the class is not an array, returns a cached {@link ClassMeta} object.
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.<br>
+	 * @return The class meta object containing information about the class.
 	 */
 	public final <T> ClassMeta<T> getClassMeta(Class<T> c) {
 		return ctx.getClassMeta(c);
 	}
 
 	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Map} object.
+	 * Returns a {@code ClassMeta} wrapper around a {@link Class} or {@link Type} object.
 	 *
-	 * @param <K> The map key class type.
-	 * @param <V> The map value class type.
-	 * @param <T> The map class type.
-	 * @param c The map class type.
-	 * @param keyType The map key class type.
-	 * @param valueType The map value class type.
-	 * @return If the key and value types are OBJECT, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
+	 * @param <T> The class type being wrapped.
+	 * @param c The class being wrapped.
+	 * @return The class meta object containing information about the class.
 	 */
-	public final <K,V,T extends Map<K,V>> ClassMeta<T> getMapClassMeta(Class<T> c, ClassMeta<K> keyType, ClassMeta<V> valueType) {
-		return ctx.getMapClassMeta(c, keyType, valueType);
+	public final <T> ClassMeta<T> getClassMeta(Object c) {
+		return ctx.getClassMeta(c);
 	}
 
 	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Map} object.
+	 * Returns a {@link ClassMeta} wrapper around a {@link Map} or {@link Collection} class.
+	 * <p>
+	 * Handles the following object arrays:
+	 * <ul>
+	 * 	<li><code>Object[2]</code> containing <code>{Class&lt;? extends Collection&gt;, Object}</code>
+	 * 		where the 2nd entry is the entry type which can be a Class/Type or another array.
+	 * 	<li><code>Object[3]</code> containing <code>{Class&lt;? extends Map&gt;, Object, Object}</code>
+	 * 		where the 2nd entry is the key type which can be a Class/Type and 3rd entry is the value type which can be a Class/Type or another array.
+	 * </ul>
 	 *
-	 * @param <K> The map key class type.
-	 * @param <V> The map value class type.
-	 * @param <T> The map class type.
-	 * @param c The map class type.
-	 * @param keyType The map key class type.
-	 * @param valueType The map value class type.
-	 * @return If the key and value types are Object, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
+	 * @param c The object array being resolved.
+	 * @return The class meta object containing information about the class.
 	 */
-	public final <K,V,T extends Map<K,V>> ClassMeta<T> getMapClassMeta(Class<T> c, Class<K> keyType, Class<V> valueType) {
-		return getMapClassMeta(c, getClassMeta(keyType), getClassMeta(valueType));
+	public final <T> ClassMeta<T> getClassMeta(Object...c) {
+		return ctx.getClassMeta(c);
 	}
 
 	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Map} object.
+	 * Convenience method for creating a {@link Map} class meta.
+	 * <p>
+	 * Equivalent to calling <code>getClassMeta(c, keyType, valueType)</code>.
 	 *
+	 * @param <K> The map key class type.
+	 * @param <V> The map value class type.
 	 * @param <T> The map class type.
 	 * @param c The map class type.
 	 * @param keyType The map key class type.
@@ -871,26 +870,14 @@ public class BeanSession extends Session {
 	 * @return If the key and value types are Object, returns a cached {@link ClassMeta} object.<br>
 	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
 	 */
-	public final <T extends Map> ClassMeta<T> getMapClassMeta(Class<T> c, Type keyType, Type valueType) {
-		return getMapClassMeta(c, getClassMeta(keyType), getClassMeta(valueType));
-	}
-
-	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Collection} object.
-	 *
-	 * @param <E> The collection element class type.
-	 * @param <T> The collection class type.
-	 * @param c The collection class type.
-	 * @param elementType The collection element class type.
-	 * @return If the element type is <code>OBJECT</code>, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
-	 */
-	public final <E,T extends Collection<E>> ClassMeta<T> getCollectionClassMeta(Class<T> c, ClassMeta<E> elementType) {
-		return ctx.getCollectionClassMeta(c, elementType);
+	public final <K,V,T extends Map<K,V>> ClassMeta<T> getMapClassMeta(Class<T> c, Class<K> keyType, Class<V> valueType) {
+		return getClassMeta(c, keyType, valueType);
 	}
 
 	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Collection} object.
+	 * Convenience method for creating a {@link Collection} class meta.
+	 * <p>
+	 * Equivalent to calling <code>getClassMeta(c, keyType, valueType)</code>.
 	 *
 	 * @param <E> The collection element class type.
 	 * @param <T> The collection class type.
@@ -900,20 +887,7 @@ public class BeanSession extends Session {
 	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
 	 */
 	public final <E,T extends Collection<E>> ClassMeta<T> getCollectionClassMeta(Class<T> c, Class<E> elementType) {
-		return getCollectionClassMeta(c, getClassMeta(elementType));
-	}
-
-	/**
-	 * Construct a {@code ClassMeta} wrapper around a {@link Collection} object.
-	 *
-	 * @param <T> The collection class type.
-	 * @param c The collection class type.
-	 * @param elementType The collection element class type.
-	 * @return If the element type is <code>OBJECT</code>, returns a cached {@link ClassMeta} object.<br>
-	 * 	Otherwise, returns a new {@link ClassMeta} object every time.
-	 */
-	public final <T extends Collection> ClassMeta<T> getCollectionClassMeta(Class<T> c, Type elementType) {
-		return getCollectionClassMeta(c, getClassMeta(elementType));
+		return getClassMeta(c, getClassMeta(elementType));
 	}
 
 	/**
@@ -962,24 +936,6 @@ public class BeanSession extends Session {
 	}
 
 	/**
-	 * Converts class name strings to ClassMeta objects.
-	 *
-	 * <h6 class='topic'>Example:</h6>
-	 * <ul>
-	 * 	<li><js>"java.lang.String"</js>
-	 * 	<li><js>"com.foo.sample.MyBean[]"</js>
-	 * 	<li><js>"java.util.HashMap<java.lang.String,java.lang.Integer>"</js>
-	 * 	<li><js>"[Ljava.lang.String;"</js> (i.e. the value of <code>String[].<jk>class</jk>.getName()</code>)
-	 * </ul>
-	 *
-	 * @param s The class name.
-	 * @return The ClassMeta corresponding to the class name string.
-	 */
-	public final ClassMeta<?> getClassMetaFromString(String s) {
-		return ctx.getClassMetaFromString(s);
-	}
-
-	/**
 	 * Returns the type property name as defined by {@link BeanContext#BEAN_beanTypePropertyName}.
 	 *
 	 * @return The type property name.  Never <jk>null</jk>.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java b/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java
index 0057dff..efa69b3 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java
@@ -866,7 +866,7 @@ public final class ContextFactory extends Lockable {
 				try {
 					if (isBeanSessionAvailable()) {
 						BeanSession session = getBeanSession();
-						return (Map<K,V>)session.convertToType(p.value, session.getMapClassMeta(LinkedHashMap.class, keyType, valueType));
+						return (Map<K,V>)session.convertToType(p.value, session.getClassMeta(LinkedHashMap.class, keyType, valueType));
 					}
 					return def;
 				} catch (InvalidDataConversionException e) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
index 48aceeb..5f54e5a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
@@ -1081,7 +1081,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @return This object map cast as another object.
 	 */
 	public Object cast() {
-		return cast((BeanRegistry)null);
+		return cast(session.getBeanRegistry());
 	}
 
 	/**
@@ -1094,10 +1094,12 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 */
 	public Object cast(BeanRegistry beanRegistry) {
 		String c = (String)get(session.getBeanTypePropertyName());
-		if (c == null) {
+		if (c == null || beanRegistry == null)
 			return this;
-		}
-		return cast2(session.getClassMetaFromString(c));
+		ClassMeta<?> cm = beanRegistry.getClassMeta(c);
+		if (cm == null)
+			return this;
+		return cast2(cm);
 	}
 
 	/**
@@ -1116,7 +1118,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 */
 	@SuppressWarnings("unchecked")
 	public <T> T cast(Class<T> type) {
-		ClassMeta<?> c1 = session.getClassMetaFromString((String)get(session.getBeanTypePropertyName()));
+		ClassMeta<?> c1 = session.getBeanRegistry().getClassMeta((String)get(session.getBeanTypePropertyName()));
 		ClassMeta<?> c2 = session.getClassMeta(type);
 		ClassMeta<?> c = narrowClassMeta(c1, c2);
 		return (T)cast2(c);
@@ -1133,7 +1135,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 */
 	@SuppressWarnings({"unchecked"})
 	public <T> T cast(ClassMeta<T> cm) {
-		ClassMeta<?> c1 = session.getClassMetaFromString((String)get(session.getBeanTypePropertyName()));
+		ClassMeta<?> c1 = session.getBeanRegistry().getClassMeta((String)get(session.getBeanTypePropertyName()));
 		ClassMeta<?> c = narrowClassMeta(c1, cm);
 		return (T)cast2(c);
 	}
@@ -1144,7 +1146,6 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * The rule is that child classes superceed parent classes, and c2 superceeds c1
 	 * if one isn't the parent of another.
 	 */
-	@SuppressWarnings("unchecked")
 	private ClassMeta<?> narrowClassMeta(ClassMeta<?> c1, ClassMeta<?> c2) {
 		if (c1 == null)
 			return c2;
@@ -1152,11 +1153,11 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 		if (c1.isMap()) {
 			ClassMeta<?> k = getNarrowedClassMeta(c1.getKeyType(), c2.getKeyType());
 			ClassMeta<?> v = getNarrowedClassMeta(c1.getValueType(), c2.getValueType());
-			return session.getMapClassMeta((Class<? extends Map<?,?>>)c.getInnerClass(), k, v);
+			return session.getClassMeta(c.getInnerClass(), k, v);
 		}
 		if (c1.isCollection()) {
 			ClassMeta<?> e = getNarrowedClassMeta(c1.getElementType(), c2.getElementType());
-			return session.getCollectionClassMeta((Class<? extends Collection<?>>)c.getInnerClass(), e);
+			return session.getClassMeta(c.getInnerClass(), e);
 		}
 		return c;
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java b/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java
index b6c6d8f..f694e0e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java
+++ b/juneau-core/src/main/java/org/apache/juneau/annotation/Bean.java
@@ -280,7 +280,9 @@ public @interface Bean {
 	 * This list can consist of the following class types:
 	 * <ul>
 	 * 	<li>Any bean class that specifies a value for {@link Bean#typeName() @Bean.name()};
-	 * 	<li>Any subclass of {@link BeanDictionary} that defines an entire set of mappings.
+	 * 	<li>Any subclass of {@link BeanDictionaryList} that defines an entire set of mappings.
+	 * 		Note that the subclass MUST implement a no-arg constructor so that it can be instantiated.
+	 * 	<li>Any subclass of {@link BeanDictionaryMap} that defines an entire set of mappings.
 	 * 		Note that the subclass MUST implement a no-arg constructor so that it can be instantiated.
 	 * </ul>
 	 */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java b/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
index bd68408..3e4cc76 100644
--- a/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
+++ b/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
@@ -158,7 +158,9 @@ public @interface BeanProperty {
 	 * This list can consist of the following class types:
 	 * <ul>
 	 * 	<li>Any bean class that specifies a value for {@link Bean#typeName() @Bean.name()};
-	 * 	<li>Any subclass of {@link BeanDictionary} that defines an entire set of mappings.
+	 * 	<li>Any subclass of {@link BeanDictionaryList} that defines an entire set of mappings.
+	 * 		Note that the subclass MUST implement a no-arg constructor so that it can be instantiated.
+	 * 	<li>Any subclass of {@link BeanDictionaryMap} that defines an entire set of mappings.
 	 * 		Note that the subclass MUST implement a no-arg constructor so that it can be instantiated.
 	 * </ul>
 	 */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlBeanDictionary.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlBeanDictionary.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlBeanDictionary.java
index af301bc..46d5c2b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlBeanDictionary.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlBeanDictionary.java
@@ -18,7 +18,7 @@ import org.apache.juneau.*;
  * Defines the Java classes that make up the HTML DTO type dictionary.
  * <p>
  */
-public class HtmlBeanDictionary extends BeanDictionary {
+public class HtmlBeanDictionary extends BeanDictionaryList {
 	private static final long serialVersionUID = 1L;
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/internal/DelegateList.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/DelegateList.java b/juneau-core/src/main/java/org/apache/juneau/internal/DelegateList.java
index 35e6b11..596ec85 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/DelegateList.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/DelegateList.java
@@ -32,10 +32,9 @@ public class DelegateList<T extends Collection<?>> extends ObjectList implements
 	 *
 	 * @param classMeta The data type represented by this delegate.
 	 */
-	@SuppressWarnings("unchecked")
 	public DelegateList(ClassMeta<T> classMeta) {
 		if (classMeta.isArray())
-			classMeta = classMeta.getBeanContext().getCollectionClassMeta(List.class, classMeta.getElementType());
+			classMeta = classMeta.getBeanContext().getClassMeta(List.class, classMeta.getElementType());
 		this.classMeta = classMeta;
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
index 0084be8..d546b18 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
@@ -303,7 +303,7 @@ public abstract class Parser extends CoreApi {
 	 */
 	public final <K,V,T extends Map<K,V>> T parseMap(Object input, Class<T> mapClass, Class<K> keyClass, Class<V> valueClass) throws ParseException {
 		ParserSession session = createSession(input);
-		ClassMeta<T> cm = session.getMapClassMeta(mapClass, keyClass, valueClass);
+		ClassMeta<T> cm = session.getClassMeta(mapClass, keyClass, valueClass);
 		return parse(session, cm);
 	}
 
@@ -343,7 +343,7 @@ public abstract class Parser extends CoreApi {
 	 */
 	public final <E,T extends Collection<E>> T parseCollection(Object input, Class<T> collectionClass, Class<E> entryClass) throws ParseException, IOException {
 		ParserSession session = createSession(input);
-		ClassMeta<T> cm = session.getCollectionClassMeta(collectionClass, entryClass);
+		ClassMeta<T> cm = session.getClassMeta(collectionClass, entryClass);
 		return parse(session, cm);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index 32a68f2..fac17c9 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -416,7 +416,7 @@ public class UrlEncodingParser extends UonParser {
 
 	private Object[] parseArgs(UrlEncodingParserSession session, ParserReader r, ClassMeta<?>[] argTypes) throws Exception {
 		// TODO - This can be made more efficient.
-		ClassMeta<TreeMap<Integer,String>> cm = session.getMapClassMeta(TreeMap.class, Integer.class, String.class);
+		ClassMeta<TreeMap<Integer,String>> cm = session.getClassMeta(TreeMap.class, Integer.class, String.class);
 		TreeMap<Integer,String> m = parseAnything(session, cm, r, session.getOuter());
 		Object[] vals = m.values().toArray(new Object[m.size()]);
 		if (vals.length != argTypes.length)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 64c420f..99862d0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -254,7 +254,7 @@ public class UrlEncodingSerializer extends UonSerializer {
 		} else if (sType.isBean()) {
 			serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty);
 		} else if (sType.isCollection()) {
-			serializeMap(session, out, getCollectionMap((Collection)o), session.getMapClassMeta(Map.class, Integer.class, sType.getElementType()));
+			serializeMap(session, out, getCollectionMap((Collection)o), session.getClassMeta(Map.class, Integer.class, sType.getElementType()));
 		} else {
 			// All other types can't be serialized as key/value pairs, so we create a
 			// mock key/value pair with a "_value" key.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
index 8d0932a..b5ec875 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -521,14 +521,14 @@ public class XmlParser extends ReaderParser {
 	@Override /* ReaderParser */
 	protected <K,V> Map<K,V> doParseIntoMap(ParserSession session, Map<K,V> m, Type keyType, Type valueType) throws Exception {
 		XmlParserSession s = (XmlParserSession)session;
-		ClassMeta cm = session.getMapClassMeta(m.getClass(), keyType, valueType);
+		ClassMeta cm = session.getClassMeta(m.getClass(), keyType, valueType);
 		return parseIntoMap(s, m, cm.getKeyType(), cm.getValueType());
 	}
 
 	@Override /* ReaderParser */
 	protected <E> Collection<E> doParseIntoCollection(ParserSession session, Collection<E> c, Type elementType) throws Exception {
 		XmlParserSession s = (XmlParserSession)session;
-		ClassMeta cm = session.getCollectionClassMeta(c.getClass(), elementType);
+		ClassMeta cm = session.getClassMeta(c.getClass(), elementType);
 		return parseIntoCollection(s,c, cm.getElementType());
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index 620e8b5..10431b6 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -5377,7 +5377,10 @@
 			<li>New method {@link org.apache.juneau.encoders.EncoderGroup#getEncoderMatch(String)} that returns the matched encoder and encoding.
 			<li>General improvements to Bean Dictionary support.
 				<ul>
-					<li>New {@link org.apache.juneau.BeanDictionary} class can be used for defining reusable sets of bean dictionaries.
+					<li>New {@link org.apache.juneau.BeanDictionaryList} class can be used for defining reusable sets of bean dictionaries consisting
+						of classes annotated with {@link org.apache.juneau.annotation.Bean#typeName()}.
+					<li>New {@link org.apache.juneau.BeanDictionaryMap} class can be used for defining reusable sets of bean dictionaries consisting
+						of classes not annotated with {@link org.apache.juneau.annotation.Bean#typeName()}.
 					<li>New {@link org.apache.juneau.annotation.Bean#beanDictionary()} annotation.
 				</ul>
 			<li>Removed restriction on getters and setters to be prefixed with "getX/setX/isX" if a {@link org.apache.juneau.annotation.BeanProperty#name()} annotation is used.
@@ -5389,6 +5392,9 @@
 				</ul>
 			<li>New {@link org.apache.juneau.transform.MapSwap} and {@link org.apache.juneau.transform.StringSwap} classes.
 			<li>New {@link org.apache.juneau.serializer.WriterSerializer#println(Object)} method.  Useful for debugging purposes.
+			<li>New {@link org.apache.juneau.BeanContext#getClassMeta(Object[])} and {@link org.apache.juneau.BeanSession#getClassMeta(Object[])}
+				methods for retrieving Map and Collection class metas.  
+				Replaces the various <code>getMapClassMeta()</code>/<code>getCollectionClassMeta()</code> methods.  
 			<li>New section added to this document:	<a class='doclink' href='#DTOs'>Juneau Data Transfer Objects (org.apache.juneau.dto)</a>
 		</ul>
 		

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ca48a2ff/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
index 916fa6b..b49c59a 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
@@ -795,7 +795,7 @@ public final class RestCall {
 	 * @throws IOException
 	 */
 	public final <K,V,T extends Map<K,V>> T getResponseMap(Class<T> mapClass, Class<K> keyClass, Class<V> valueClass) throws ParseException, IOException {
-		ClassMeta<T> cm = getBeanContext().getMapClassMeta(mapClass, keyClass, valueClass);
+		ClassMeta<T> cm = getBeanContext().getClassMeta(mapClass, keyClass, valueClass);
 		return getResponse(cm);
 	}
 
@@ -822,7 +822,7 @@ public final class RestCall {
 	 * @throws IOException
 	 */
 	public final <E,T extends Collection<E>> T getResponseCollection(Class<T> collectionClass, Class<E> entryClass) throws ParseException, IOException {
-		ClassMeta<T> cm = getBeanContext().getCollectionClassMeta(collectionClass, entryClass);
+		ClassMeta<T> cm = getBeanContext().getClassMeta(collectionClass, entryClass);
 		return getResponse(cm);
 	}