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/08/22 22:17:32 UTC

[2/2] incubator-juneau git commit: Clean up ObjectMap/ObjectList/PojoRest classes.

Clean up ObjectMap/ObjectList/PojoRest classes.

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

Branch: refs/heads/master
Commit: 23fe563ddc0908107ed47e3da139c95298af3bbc
Parents: 70d2345
Author: JamesBognar <ja...@apache.org>
Authored: Tue Aug 22 15:17:26 2017 -0700
Committer: JamesBognar <ja...@apache.org>
Committed: Tue Aug 22 15:17:26 2017 -0700

----------------------------------------------------------------------
 .../juneau/jena/RdfSerializerSession.java       |   2 +-
 .../java/org/apache/juneau/ObjectListTest.java  |  38 ++-
 .../java/org/apache/juneau/ObjectMapTest.java   |  51 ++-
 .../apache/juneau/transforms/DateSwapTest.java  |   2 +-
 .../org/apache/juneau/utils/PojoRestTest.java   |  44 +--
 .../java/org/apache/juneau/BeanSession.java     |  46 ++-
 .../main/java/org/apache/juneau/ObjectList.java | 160 +++++++--
 .../main/java/org/apache/juneau/ObjectMap.java  | 333 ++++++++++++-------
 .../main/java/org/apache/juneau/Session.java    |  26 +-
 .../juneau/html/HtmlDocSerializerSession.java   |   2 +-
 .../org/apache/juneau/internal/ObjectUtils.java |   4 +-
 .../org/apache/juneau/parser/ParserSession.java |   2 +-
 .../juneau/serializer/SerializerSession.java    |   6 +-
 .../juneau/soap/SoapXmlSerializerSession.java   |   4 +-
 .../main/java/org/apache/juneau/utils/Args.java |   2 +-
 .../java/org/apache/juneau/utils/PojoRest.java  | 156 +++++++--
 .../org/apache/juneau/xml/XmlParserSession.java |   6 +-
 juneau-core/src/main/javadoc/overview.html      |  47 ++-
 juneau-examples-rest/.classpath                 |   2 +-
 .../juneau/examples/rest/PhotosResource.java    |   2 +-
 juneau-microservice/.classpath                  |   2 +-
 .../juneau/microservice/RestMicroservice.java   |   4 +-
 .../eclipse-preferences/user-dictionary.txt     |   1 +
 juneau-rest-test/.classpath                     |   2 +-
 .../juneau/rest/test/AcceptCharsetResource.java |   4 +-
 .../juneau/rest/test/NlsPropertyResource.java   |   2 +-
 .../juneau/rest/test/OnPostCallResource.java    |   2 +-
 .../juneau/rest/test/OnPreCallResource.java     |   4 +-
 .../juneau/rest/test/PropertiesResource.java    |   6 +-
 29 files changed, 696 insertions(+), 266 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
index ad2c663..d033c45 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -99,7 +99,7 @@ public final class RdfSerializerSession extends WriterSerializerSession {
 			this.looseCollections = p.getBoolean(RDF_looseCollections, ctx.looseCollections);
 			this.useXmlNamespaces = p.getBoolean(RDF_useXmlNamespaces, ctx.useXmlNamespaces);
 			this.autoDetectNamespaces = p.getBoolean(RDF_autoDetectNamespaces, ctx.autoDetectNamespaces);
-			this.namespaces = p.get(Namespace[].class, RDF_namespaces, ctx.namespaces);
+			this.namespaces = p.getWithDefault(RDF_namespaces, ctx.namespaces, Namespace[].class);
 			addBeanTypeProperties = p.getBoolean(RDF_addBeanTypeProperties, ctx.addBeanTypeProperties);
 		}
 		this.model = ModelFactory.createDefaultModel();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core-test/src/test/java/org/apache/juneau/ObjectListTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/ObjectListTest.java b/juneau-core-test/src/test/java/org/apache/juneau/ObjectListTest.java
index 0f136e6..0c60499 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/ObjectListTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/ObjectListTest.java
@@ -84,15 +84,15 @@ public class ObjectListTest {
 		ObjectList l = new ObjectList("[{foo:'bar'},{baz:123}]");
 		String r;
 
-		r = l.getAt(String.class, "0/foo");
+		r = l.getAt("0/foo", String.class);
 		assertEquals("bar", r);
 
 		l.putAt("0/foo", "bing");
-		r = l.getAt(String.class, "0/foo");
+		r = l.getAt("0/foo", String.class);
 		assertEquals("bing", r);
 
 		l.postAt("", new ObjectMap("{a:'b'}"));
-		r = l.getAt(String.class, "2/a");
+		r = l.getAt("2/a", String.class);
 		assertEquals("b", r);
 
 		l.deleteAt("2");
@@ -106,4 +106,36 @@ public class ObjectListTest {
 	public void testFromReader() throws Exception {
 		assertObjectEquals("[1,2,3]", new ObjectList(new StringReader("[1,2,3]")));
 	}
+	
+	//====================================================================================================
+	// testGetMap
+	//====================================================================================================
+	@Test
+	public void testGetMap() throws Exception {
+		ObjectList l = new ObjectList("[{1:'true',2:'false'}]");
+		Map<Integer,Boolean> m2 = l.getMap(0, Integer.class, Boolean.class);
+		assertObjectEquals("{'1':true,'2':false}", m2);
+		assertEquals(Integer.class, m2.keySet().iterator().next().getClass());
+		assertEquals(Boolean.class, m2.values().iterator().next().getClass());
+	
+		m2 = l.get(0, Map.class, Integer.class, Boolean.class);
+		assertObjectEquals("{'1':true,'2':false}", m2);
+		assertEquals(Integer.class, m2.keySet().iterator().next().getClass());
+		assertEquals(Boolean.class, m2.values().iterator().next().getClass());
+	}
+
+	//====================================================================================================
+	// testGetList
+	//====================================================================================================
+	@Test
+	public void testGetList() throws Exception {
+		ObjectList l = new ObjectList("[['123','456']]");
+		List<Integer> l2 = l.getList(0, Integer.class);
+		assertObjectEquals("[123,456]", l2);
+		assertEquals(Integer.class, l2.iterator().next().getClass());
+	
+		l2 = l.get(0, List.class, Integer.class);
+		assertObjectEquals("[123,456]", l2);
+		assertEquals(Integer.class, l2.iterator().next().getClass());
+	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core-test/src/test/java/org/apache/juneau/ObjectMapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/ObjectMapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/ObjectMapTest.java
index 850eef3..efce0a0 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/ObjectMapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/ObjectMapTest.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.TestUtils.*;
 import static org.junit.Assert.*;
 
 import java.io.*;
+import java.util.*;
 
 import org.apache.juneau.utils.*;
 import org.junit.*;
@@ -299,15 +300,15 @@ public class ObjectMapTest {
 		ObjectMap m = new ObjectMap("{a:[{b:'c'}]}");
 		String r;
 
-		r = m.getAt(String.class, "a/0/b");
+		r = m.getAt("a/0/b", String.class);
 		assertEquals("c", r);
 
 		m.putAt("a/0/b", "d");
-		r = m.getAt(String.class, "a/0/b");
+		r = m.getAt("a/0/b", String.class);
 		assertEquals("d", r);
 
 		m.postAt("a", "e");
-		r = m.getAt(String.class, "a/1");
+		r = m.getAt("a/1", String.class);
 		assertEquals("e", r);
 
 		m.deleteAt("a/1");
@@ -321,4 +322,48 @@ public class ObjectMapTest {
 	public void testFromReader() throws Exception {
 		assertObjectEquals("{foo:'bar'}", new ObjectMap(new StringReader("{foo:'bar'}")));
 	}
+	
+	//====================================================================================================
+	// testGetMap
+	//====================================================================================================
+	@Test
+	public void testGetMap() throws Exception {
+		ObjectMap m = new ObjectMap("{a:{1:'true',2:'false'}}");
+		Map<Integer,Boolean> m2 = m.getMap("a", Integer.class, Boolean.class, null);
+		assertObjectEquals("{'1':true,'2':false}", m2);
+		assertEquals(Integer.class, m2.keySet().iterator().next().getClass());
+		assertEquals(Boolean.class, m2.values().iterator().next().getClass());
+	
+		m2 = m.getMap("b", Integer.class, Boolean.class, null);
+		assertNull(m2);
+		
+		m2 = m.get("a", Map.class, Integer.class, Boolean.class);
+		assertObjectEquals("{'1':true,'2':false}", m2);
+		assertEquals(Integer.class, m2.keySet().iterator().next().getClass());
+		assertEquals(Boolean.class, m2.values().iterator().next().getClass());
+		
+		m2 = m.get("b", Map.class, Integer.class, Boolean.class);
+		assertNull(m2);
+	}
+
+	//====================================================================================================
+	// testGetList
+	//====================================================================================================
+	@Test
+	public void testGetList() throws Exception {
+		ObjectMap m = new ObjectMap("{a:['123','456']}");
+		List<Integer> l2 = m.getList("a", Integer.class, null);
+		assertObjectEquals("[123,456]", l2);
+		assertEquals(Integer.class, l2.iterator().next().getClass());
+	
+		l2 = m.getList("b", Integer.class, null);
+		assertNull(l2);
+		
+		l2 = m.get("a", List.class, Integer.class);
+		assertObjectEquals("[123,456]", l2);
+		assertEquals(Integer.class, l2.iterator().next().getClass());
+		
+		l2 = m.get("b", List.class, Integer.class);
+		assertNull(l2);
+	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java
index e77652f..f05c5ae 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java
@@ -51,7 +51,7 @@ public class DateSwapTest {
 		final String sValue = data.getString("birthday");
 		dateSwap.unswap(BeanContext.DEFAULT.createSession(), sValue, data.getBeanSession().getClassMeta(Date.class));
 		// this does not work
-		data.get(dateSwap, "birthday");
+		data.getSwapped("birthday", dateSwap);
 	}
 
 	public static class A {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java b/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java
index f274435..edb6403 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java
@@ -357,17 +357,17 @@ public class PojoRestTest {
 		assertNull(model.get("f7"));
 		assertNull(model.get("f8"));
 
-		assertEquals("foo", model.get("f1", "foo"));
-		assertEquals(0, model.get("f2", "foo"));
-		assertEquals(0l, model.get("f3", "foo"));
-		assertEquals(false, model.get("f4", "foo"));
-		assertEquals("foo", model.get("f2a", "foo"));
-		assertEquals("foo", model.get("f3a", "foo"));
-		assertEquals("foo", model.get("f4a", "foo"));
-		assertEquals("foo", model.get("f5", "foo"));
-		assertEquals("foo", model.get("f6", "foo"));
-		assertEquals("foo", model.get("f7", "foo"));
-		assertEquals("foo", model.get("f8", "foo"));
+		assertEquals("foo", model.getWithDefault("f1", "foo"));
+		assertEquals(0, model.getWithDefault("f2", "foo"));
+		assertEquals(0l, model.getWithDefault("f3", "foo"));
+		assertEquals(false, model.getWithDefault("f4", "foo"));
+		assertEquals("foo", model.getWithDefault("f2a", "foo"));
+		assertEquals("foo", model.getWithDefault("f3a", "foo"));
+		assertEquals("foo", model.getWithDefault("f4a", "foo"));
+		assertEquals("foo", model.getWithDefault("f5", "foo"));
+		assertEquals("foo", model.getWithDefault("f6", "foo"));
+		assertEquals("foo", model.getWithDefault("f7", "foo"));
+		assertEquals("foo", model.getWithDefault("f8", "foo"));
 
 		assertNull(model.getString("f1"));
 		assertEquals("0", model.getString("f2"));
@@ -575,17 +575,17 @@ public class PojoRestTest {
 		assertEquals("{f5a:'a'}", model.get("f7").toString());
 		assertEquals("[{f6a:'a'}]", model.get("f8").toString());
 
-		assertEquals("1", model.get("f1", "foo"));
-		assertEquals("2", model.get("f2", "foo").toString());
-		assertEquals("3", model.get("f3", "foo").toString());
-		assertEquals("true", model.get("f4", "foo").toString());
-		assertEquals("2", model.get("f2a", "foo").toString());
-		assertEquals("3", model.get("f3a", "foo").toString());
-		assertEquals("true", model.get("f4a", "foo").toString());
-		assertEquals("{f5a:'a'}", model.get("f5", "foo").toString());
-		assertEquals("[{f6a:'a'}]", model.get("f6", "foo").toString());
-		assertEquals("{f5a:'a'}", model.get("f7", "foo").toString());
-		assertEquals("[{f6a:'a'}]", model.get("f8", "foo").toString());
+		assertEquals("1", model.getWithDefault("f1", "foo"));
+		assertEquals("2", model.getWithDefault("f2", "foo").toString());
+		assertEquals("3", model.getWithDefault("f3", "foo").toString());
+		assertEquals("true", model.getWithDefault("f4", "foo").toString());
+		assertEquals("2", model.getWithDefault("f2a", "foo").toString());
+		assertEquals("3", model.getWithDefault("f3a", "foo").toString());
+		assertEquals("true", model.getWithDefault("f4a", "foo").toString());
+		assertEquals("{f5a:'a'}", model.getWithDefault("f5", "foo").toString());
+		assertEquals("[{f6a:'a'}]", model.getWithDefault("f6", "foo").toString());
+		assertEquals("{f5a:'a'}", model.getWithDefault("f7", "foo").toString());
+		assertEquals("[{f6a:'a'}]", model.getWithDefault("f8", "foo").toString());
 
 		assertEquals("1", model.getString("f1"));
 		assertEquals("2", model.getString("f2"));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/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 e7c059d..bad3d38 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
@@ -64,10 +64,10 @@ public class BeanSession extends Session {
 			this.debug = ctx.debug;
 			this.mediaType = args.mediaType != null ? args.mediaType : ctx.mediaType;
 		} else {
-			_locale = (args.locale != null ? args.locale : getProperty(Locale.class, BEAN_locale, ctx.locale));
-			this.timeZone = (args.timeZone != null ? args.timeZone : getProperty(TimeZone.class, BEAN_timeZone, ctx.timeZone));
-			this.debug = getProperty(boolean.class, BEAN_debug, false);
-			this.mediaType = (args.mediaType != null ? args.mediaType : getProperty(MediaType.class, BEAN_mediaType, ctx.mediaType));
+			_locale = (args.locale != null ? args.locale : getPropertyWithDefault(BEAN_locale, ctx.locale, Locale.class));
+			this.timeZone = (args.timeZone != null ? args.timeZone : getPropertyWithDefault(BEAN_timeZone, ctx.timeZone, TimeZone.class));
+			this.debug = getPropertyWithDefault(BEAN_debug, false, boolean.class);
+			this.mediaType = (args.mediaType != null ? args.mediaType : getPropertyWithDefault(BEAN_mediaType, ctx.mediaType, MediaType.class));
 		}
 		this.locale = _locale == null ? Locale.getDefault() : _locale;
 	}
@@ -144,7 +144,7 @@ public class BeanSession extends Session {
 		// Shortcut for most common case.
 		if (value != null && value.getClass() == type)
 			return (T)value;
-		return convertToType(null, value, ctx.getClassMeta(type));
+		return convertToMemberType(null, value, ctx.getClassMeta(type));
 	}
 
 	/**
@@ -160,8 +160,8 @@ public class BeanSession extends Session {
 	 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
 	 * @return The converted value.
 	 */
-	public final <T> T convertToType(Object outer, Object value, Class<T> type) throws InvalidDataConversionException {
-		return convertToType(outer, value, ctx.getClassMeta(type));
+	public final <T> T convertToMemberType(Object outer, Object value, Class<T> type) throws InvalidDataConversionException {
+		return convertToMemberType(outer, value, ctx.getClassMeta(type));
 	}
 
 	/**
@@ -300,7 +300,21 @@ public class BeanSession extends Session {
 	 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
 	 */
 	public final <T> T convertToType(Object value, ClassMeta<T> type) throws InvalidDataConversionException {
-		return convertToType(null, value, type);
+		return convertToMemberType(null, value, type);
+	}
+
+	/**
+	 * Same as {@link #convertToType(Object, Class)}, but allows for complex data types consisting of collections or maps.
+	 *
+	 * @param <T> The class type to convert the value to.
+	 * @param value The value to be converted.
+	 * @param type The target object type.
+	 * @param args The target object parameter types.
+	 * @return The converted type.
+	 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
+	 */
+	public final <T> T convertToType(Object value, Type type, Type...args) throws InvalidDataConversionException {
+		return (T)convertToMemberType(null, value, getClassMeta(type, args));
 	}
 
 	/**
@@ -316,7 +330,7 @@ public class BeanSession extends Session {
 	 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
 	 * @return The converted value.
 	 */
-	public final <T> T convertToType(Object outer, Object value, ClassMeta<T> type) throws InvalidDataConversionException {
+	public final <T> T convertToMemberType(Object outer, Object value, ClassMeta<T> type) throws InvalidDataConversionException {
 		if (type == null)
 			type = (ClassMeta<T>)ctx.object();
 
@@ -511,17 +525,17 @@ public class BeanSession extends Session {
 								if (keyType.isString() && k.getClass() != Class.class)
 									k = k.toString();
 								else
-									k = convertToType(m, k, keyType);
+									k = convertToMemberType(m, k, keyType);
 							}
 							Object v = e.getValue();
 							if (valueType.isNotObject())
-								v = convertToType(m, v, valueType);
+								v = convertToMemberType(m, v, valueType);
 							m.put(k, v);
 						}
 						return (T)m;
 					} else if (!type.canCreateNewInstanceFromString(outer)) {
 						ObjectMap m = new ObjectMap(value.toString(), ctx.defaultParser);
-						return convertToType(outer, m, type);
+						return convertToMemberType(outer, m, type);
 					}
 				} catch (Exception e) {
 					throw new InvalidDataConversionException(value.getClass(), type, e);
@@ -536,12 +550,12 @@ public class BeanSession extends Session {
 
 					if (value.getClass().isArray())
 						for (Object o : (Object[])value)
-							l.add(elementType.isObject() ? o : convertToType(l, o, elementType));
+							l.add(elementType.isObject() ? o : convertToMemberType(l, o, elementType));
 					else if (value instanceof Collection)
 						for (Object o : (Collection)value)
-							l.add(elementType.isObject() ? o : convertToType(l, o, elementType));
+							l.add(elementType.isObject() ? o : convertToMemberType(l, o, elementType));
 					else if (value instanceof Map)
-						l.add(elementType.isObject() ? value : convertToType(l, value, elementType));
+						l.add(elementType.isObject() ? value : convertToMemberType(l, value, elementType));
 					else if (! value.toString().isEmpty())
 						throw new InvalidDataConversionException(value.getClass(), type, null);
 					return (T)l;
@@ -658,7 +672,7 @@ public class BeanSession extends Session {
 				else if (o == null && componentType.isPrimitive())
 					o = componentType.getPrimitiveDefault();
 				else
-					o = convertToType(null, o, componentType);
+					o = convertToType(o, componentType);
 			}
 			try {
 				Array.set(array, i++, o);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/ObjectList.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ObjectList.java b/juneau-core/src/main/java/org/apache/juneau/ObjectList.java
index 13d1be4..53586eb 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ObjectList.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ObjectList.java
@@ -13,6 +13,7 @@
 package org.apache.juneau;
 
 import java.io.*;
+import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.json.*;
@@ -261,109 +262,205 @@ public class ObjectList extends LinkedList<Object> {
 	}
 
 	/**
-	 * Get the entry at the specified index, converted to the specified type (if possible).
+	 * Get the entry at the specified index, converted to the specified type.
+	 *
+	 * <p>
+	 * This is the preferred get method for simple types.
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <p class='bcode'>
+	 * 	ObjectList l = <jk>new</jk> ObjectList(<js>"..."</js>);
+	 *
+	 * 	<jc>// Value converted to a string.</jc>
+	 * 	String s = l.get(1, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a bean.</jc>
+	 * 	MyBean b = l.get(2, MyBean.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a bean array.</jc>
+	 * 	MyBean[] ba = l.get(3, MyBean[].<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of objects.</jc>
+	 * 	List l1 = l.get(4, LinkedList.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map of object keys/values.</jc>
+	 * 	Map m1 = l.get(5, TreeMap.<jk>class</jk>);
+	 * </p>
 	 *
 	 * <p>
 	 * See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
 	 *
-	 * @param type The type of object to convert the entry to.
 	 * @param index The index into this list.
+	 * @param type The type of object to convert the entry to.
 	 * @param <T> The type of object to convert the entry to.
 	 * @return The converted entry.
 	 */
-	public <T> T get(Class<T> type, int index) {
+	public <T> T get(int index, Class<T> type) {
 		return session.convertToType(get(index), type);
 	}
 
 	/**
-	 * Shortcut for calling <code>get(String.<jk>class</jk>, index)</code>.
+	 * Get the entry at the specified index, converted to the specified type.
+	 *
+	 * <p>
+	 * The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <p class='bcode'>
+	 * 	ObjectList l = <jk>new</jk> ObjectList(<js>"..."</js>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of strings.</jc>
+	 * 	List&lt;String&gt; l1 = l.get(1, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of beans.</jc>
+	 * 	List&lt;MyBean&gt; l2 = l.get(2, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of linked-lists of strings.</jc>
+	 * 	List&lt;List&lt;String&gt;&gt; l3 = l.get(3, LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map of string keys/values.</jc>
+	 * 	Map&lt;String,String&gt; m1 = l.get(4, TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map containing string keys and values of lists containing beans.</jc>
+	 * 	Map&lt;String,List&lt;MyBean&gt;&gt; m2 = l.get(5, TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
+	 * </p>
+	 *
+	 * <p>
+	 * <code>Collection</code> classes are assumed to be followed by zero or one objects indicating the element type.
+	 *
+	 * <p>
+	 * <code>Map</code> classes are assumed to be followed by zero or two meta objects indicating the key and value types.
+	 *
+	 * <p>
+	 * The array can be arbitrarily long to indicate arbitrarily complex data structures.
+	 *
+	 * <p>
+	 * See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
+	 *
+	 * @param index The index into this list.
+	 * @param type The type of object to convert the entry to.
+	 * @param args The type arguments of the type to convert the entry to.
+	 * @param <T> The type of object to convert the entry to.
+	 * @return The converted entry.
+	 */
+	public <T> T get(int index, Type type, Type...args) {
+		return session.convertToType(get(index), type, args);
+	}
+
+	/**
+	 * Shortcut for calling <code>get(index, String.<jk>class</jk>)</code>.
 	 *
 	 * @param index The index.
 	 * @return The converted value.
 	 */
 	public String getString(int index) {
-		return get(String.class, index);
+		return get(index, String.class);
 	}
 
 	/**
-	 * Shortcut for calling <code>get(Integer.<jk>class</jk>, index)</code>.
+	 * Shortcut for calling <code>get(index, Integer.<jk>class</jk>)</code>.
 	 *
 	 * @param index The index.
 	 * @return The converted value.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Integer getInt(int index) {
-		return get(Integer.class, index);
+		return get(index, Integer.class);
 	}
 
 	/**
-	 * Shortcut for calling <code>get(Boolean.<jk>class</jk>, index)</code>.
+	 * Shortcut for calling <code>get(index, Boolean.<jk>class</jk>)</code>.
 	 *
 	 * @param index The index.
 	 * @return The converted value.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Boolean getBoolean(int index) {
-		return get(Boolean.class, index);
+		return get(index, Boolean.class);
 	}
 
 	/**
-	 * Shortcut for calling <code>get(Long.<jk>class</jk>, index)</code>.
+	 * Shortcut for calling <code>get(index, Long.<jk>class</jk>)</code>.
 	 *
 	 * @param index The index.
 	 * @return The converted value.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Long getLong(int index) {
-		return get(Long.class, index);
+		return get(index, Long.class);
 	}
 
 	/**
-	 * Shortcut for calling <code>get(Map.<jk>class</jk>, index)</code>.
+	 * Shortcut for calling <code>get(index, Map.<jk>class</jk>)</code>.
 	 *
 	 * @param index The index.
 	 * @return The converted value.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Map<?,?> getMap(int index) {
-		return get(Map.class, index);
+		return get(index, Map.class);
 	}
 
 	/**
-	 * Shortcut for calling <code>get(List.<jk>class</jk>, index)</code>.
+	 * Same as {@link #getMap(int)} except converts the keys and values to the specified types.
+	 *
+	 * @param index The index.
+	 * @param keyType The key type class.
+	 * @param valType The value type class.
+	 * @return The converted value.
+	 * @throws InvalidDataConversionException If value cannot be converted.
+	 */
+	public <K,V> Map<K,V> getMap(int index, Class<K> keyType, Class<V> valType) {
+		return session.convertToType(get(index), Map.class, keyType, valType);
+	}
+
+	/**
+	 * Shortcut for calling <code>get(index, List.<jk>class</jk>)</code>.
 	 *
 	 * @param index The index.
 	 * @return The converted value.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public List<?> getList(int index) {
-		return get(List.class, index);
+		return get(index, List.class);
+	}
+
+	/**
+	 * Same as {@link #getList(int)} except converts the elements to the specified types.
+	 *
+	 * @param index The index.
+	 * @param elementType The element type class.
+	 * @return The converted value.
+	 * @throws InvalidDataConversionException If value cannot be converted.
+	 */
+	public <E> List<E> getList(int index, Class<E> elementType) {
+		return session.convertToType(get(index), List.class, elementType);
 	}
 
 	/**
-	 * Shortcut for calling <code>get(ObjectMap.<jk>class</jk>, index)</code>.
+	 * Shortcut for calling <code>get(index, ObjectMap.<jk>class</jk>)</code>.
 	 *
 	 * @param index The index.
 	 * @return The converted value.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectMap getObjectMap(int index) {
-		return get(ObjectMap.class, index);
+		return get(index, ObjectMap.class);
 	}
 
 	/**
-	 * Shortcut for calling <code>get(ObjectList.<jk>class</jk>, index)</code>.
+	 * Shortcut for calling <code>get(index, ObjectList.<jk>class</jk>)</code>.
 	 *
 	 * @param index The index.
 	 * @return The converted value.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectList getObjectList(int index) {
-		return get(ObjectList.class, index);
+		return get(index, ObjectList.class);
 	}
 
 	/**
-	 * Same as {@link #get(Class,int) get(Class,int)}, but the key is a slash-delimited path used to traverse entries in
+	 * Same as {@link #get(int,Class) get(int,Class)}, but the key is a slash-delimited path used to traverse entries in
 	 * this POJO.
 	 *
 	 * <p>
@@ -376,20 +473,35 @@ public class ObjectList extends LinkedList<Object> {
 	 * 	<jk>long</jk> l = m.getObjectMap(<js>"foo"</js>).getObjectList(<js>"bar"</js>).getObjectMap(<js>"0"</js>).getLong(<js>"baz"</js>);
 	 *
 	 * 	<jc>// Using this method</jc>
-	 * 	<jk>long</jk> l = m.getAt(<jk>long</jk>.<jk>class</jk>, <js>"foo/bar/0/baz"</js>);
+	 * 	<jk>long</jk> l = m.getAt(<js>"foo/bar/0/baz"</js>, <jk>long</jk>.<jk>class</jk>);
 	 * </p>
 	 *
 	 * <p>
 	 * This method uses the {@link PojoRest} class to perform the lookup, so the map can contain any of the various
 	 * class types that the {@link PojoRest} class supports (e.g. beans, collections, arrays).
 	 *
-	 * @param <T> The class type.
+	 * @param path The path to the entry.
 	 * @param type The class type.
+	 *
+	 * @param <T> The class type.
+	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
+	 */
+	public <T> T getAt(String path, Class<T> type) {
+		return getPojoRest().get(path, type);
+	}
+
+	/**
+	 * Same as {@link #getAt(String,Class)}, but allows for conversion to complex maps and collections.
+	 *
 	 * @param path The path to the entry.
+	 * @param type The class type.
+	 * @param args The class parameter types.
+	 *
+	 * @param <T> The class type.
 	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
 	 */
-	public <T> T getAt(Class<T> type, String path) {
-		return getPojoRest().get(type, path);
+	public <T> T getAt(String path, Type type, Type...args) {
+		return getPojoRest().get(path, type, args);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/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 194602f..e3ab9bc 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.internal.ClassUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
 
 import java.io.*;
+import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.internal.*;
@@ -337,116 +338,160 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	}
 
 	/**
-	 * Same as {@link Map#get(Object) get()}, but returns the default value if the key could not be found.
-	 *
-	 * @param key The key.
-	 * @param def The default value if the entry doesn't exist.
-	 * @return The value, or the default value if the entry doesn't exist.
-	 */
-	public Object get(String key, Object def) {
-		Object o = get(key);
-		return (o == null ? def : o);
-	}
-
-	/**
 	 * Same as {@link Map#get(Object) get()}, but casts or converts the value to the specified class type.
 	 *
 	 * <p>
+	 * This is the preferred get method for simple types.
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <p class='bcode'>
+	 * 	ObjectMap m = <jk>new</jk> ObjectMap(<js>"..."</js>);
+	 *
+	 * 	<jc>// Value converted to a string.</jc>
+	 * 	String s = m.get(<js>"key1"</js>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a bean.</jc>
+	 * 	MyBean b = m.get(<js>"key2"</js>, MyBean.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a bean array.</jc>
+	 * 	MyBean[] ba = m.get(<js>"key3"</js>, MyBean[].<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of objects.</jc>
+	 * 	List l = m.get(<js>"key4"</js>, LinkedList.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map of object keys/values.</jc>
+	 * 	Map m2 = m.get(<js>"key5"</js>, TreeMap.<jk>class</jk>);
+	 * </p>
+	 *
+	 * <p>
 	 * See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
 	 *
-	 * @param <T> The class type.
-	 * @param type The class type.
 	 * @param key The key.
+	 * @param <T> The class type returned.
+	 * @param type The class type returned.
 	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
 	 */
-	public <T> T get(Class<T> type, String key) {
-		return get(type, key, null);
+	public <T> T get(String key, Class<T> type) {
+		return getWithDefault(key, (T)null, type);
 	}
 
 	/**
-	 * Same as {@link Map#get(Object) get()}, but converts the raw value to the specified class type using the specified
-	 * beanFilter.
+	 * Same as {@link #get(String,Class)}, but allows for complex data types consisting of collections or maps.
+	 *
+	 * <p>
+	 * The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <p class='bcode'>
+	 * 	ObjectMap m = <jk>new</jk> ObjectMap(<js>"..."</js>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of strings.</jc>
+	 * 	List&lt;String&gt; l1 = m.get(<js>"key1"</js>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of beans.</jc>
+	 * 	List&lt;MyBean&gt; l2 = m.get(<js>"key2"</js>, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of linked-lists of strings.</jc>
+	 * 	List&lt;List&lt;String&gt;&gt; l3 = m.get(<js>"key3"</js>, LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map of string keys/values.</jc>
+	 * 	Map&lt;String,String&gt; m1 = m.get(<js>"key4"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map containing string keys and values of lists containing beans.</jc>
+	 * 	Map&lt;String,List&lt;MyBean&gt;&gt; m2 = m.get(<js>"key5"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
+	 * </p>
+	 *
+	 * <p>
+	 * <code>Collection</code> classes are assumed to be followed by zero or one objects indicating the element type.
+	 *
+	 * <p>
+	 * <code>Map</code> classes are assumed to be followed by zero or two meta objects indicating the key and value types.
+	 *
+	 * <p>
+	 * The array can be arbitrarily long to indicate arbitrarily complex data structures.
+	 *
+	 * <p>
+	 * See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
+	 *
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>Use the {@link #get(String, Class)} method instead if you don't need a parameterized map/collection.
+	 * </ul>
 	 *
-	 * @param <T> The transformed class type.
-	 * @param pojoSwap The swap class used to convert the raw type to a transformed type.
 	 * @param key The key.
+	 * @param <T> The class type returned.
+	 * @param type The class type returned.
+	 * @param args The class type parameters.
 	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
-	 * @throws ParseException Thrown by the POJO swap if a problem occurred trying to parse the value.
 	 */
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	public <T> T get(PojoSwap<T,?> pojoSwap, String key) throws ParseException {
-		try {
-			Object o = super.get(key);
-			if (o == null)
-				return null;
-			PojoSwap swap = pojoSwap;
-			return (T)swap.unswap(session, o, null);
-		} catch (ParseException e) {
-			throw e;
-		} catch (Exception e) {
-			throw new ParseException(e);
-		}
+	public <T> T get(String key, Type type, Type...args) {
+		return getWithDefault(key, null, type, args);
 	}
 
 	/**
-	 * Same as {@link Map#get(Object) get()}, but casts or converts the value to the specified class type.
-	 *
-	 * <p>
-	 * See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
+	 * Same as {@link Map#get(Object) get()}, but returns the default value if the key could not be found.
 	 *
-	 * @param <T> The class type.
-	 * @param type The class type.
 	 * @param key The key.
 	 * @param def The default value if the entry doesn't exist.
 	 * @return The value, or the default value if the entry doesn't exist.
 	 */
-	@SuppressWarnings("unchecked")
-	public <T> T get(Class<T> type, String key, T def) {
+	public Object getWithDefault(String key, Object def) {
 		Object o = get(key);
-		if (o == null)
-			return def;
-		T t = null;
-		if (session != null)
-			t = session.convertToType(o, type);
-		else if (ClassUtils.isParentClass(type, o.getClass()))
-			t = (T)o;
-		if (t == null)
-			return def;
-		return t;
+		return (o == null ? def : o);
 	}
 
 	/**
-	 * Same as {@link Map#get(Object) get()}, but casts or converts the value to the specified class type.
-	 *
-	 * <p>
-	 * See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
+	 * Same as {@link #get(String,Class)} but returns a default value if the value does not exist.
 	 *
-	 * @param <T> The class type.
-	 * @param type The class type.
 	 * @param key The key.
-	 * @return The value, or the default value if the entry doesn't exist.
+	 * @param def The default value.  Can be <jk>null</jk>.
+	 * @param <T> The class type returned.
+	 * @param type The class type returned.
+	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
 	 */
-	public <T> T get(ClassMeta<T> type, String key) {
-		return get(type, key, null);
+	public <T> T getWithDefault(String key, T def, Class<T> type) {
+		return getWithDefault(key, def, type, new Type[0]);
 	}
 
 	/**
-	 * Same as {@link Map#get(Object) get()}, but casts or converts the value to the specified class type.
+	 * Same as {@link #get(String,Type,Type...)} but returns a default value if the value does not exist.
 	 *
-	 * <p>
-	 * See {@link BeanSession#convertToType(Object, ClassMeta)} for the list of valid data conversions.
+	 * @param key The key.
+	 * @param def The default value.  Can be <jk>null</jk>.
+	 * @param <T> The class type returned.
+	 * @param type The class type returned.
+	 * @param args The class type parameters.
+	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
+	 */
+	public <T> T getWithDefault(String key, T def, Type type, Type...args) {
+		T t = session.convertToType(get(key), type, args);
+		return t == null ? def : t;
+	}
+
+
+	/**
+	 * Same as {@link Map#get(Object) get()}, but converts the raw value to the specified class type using the specified
+	 * POJO swap.
 	 *
-	 * @param <T> The class type.
-	 * @param type The class type.
 	 * @param key The key.
-	 * @param def The default value if the entry doesn't exist.
-	 * @return The value, or the default value if the entry doesn't exist.
+	 * @param pojoSwap The swap class used to convert the raw type to a transformed type.
+	 * @param <T> The transformed class type.
+	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
+	 * @throws ParseException Thrown by the POJO swap if a problem occurred trying to parse the value.
 	 */
-	public <T> T get(ClassMeta<T> type, String key, T def) {
-		Object o = get(key);
-		if (o == null)
-			return def;
-		return session.convertToType(o, type);
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	public <T> T getSwapped(String key, PojoSwap<T,?> pojoSwap) throws ParseException {
+		try {
+			Object o = super.get(key);
+			if (o == null)
+				return null;
+			PojoSwap swap = pojoSwap;
+			return (T)swap.unswap(session, o, null);
+		} catch (ParseException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new ParseException(e);
+		}
 	}
 
 	/**
@@ -479,12 +524,12 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	public <T> T find(Class<T> type, String...keys) {
 		for (String key : keys)
 			if (containsKey(key))
-				return get(type, key);
+				return get(key, type);
 		return null;
 	}
 
 	/**
-	 * Same as {@link #get(Class,String) get(Class,String)}, but the key is a slash-delimited path used to traverse
+	 * Same as {@link #get(String,Class) get(String,Class)}, but the key is a slash-delimited path used to traverse
 	 * entries in this POJO.
 	 *
 	 * <p>
@@ -498,20 +543,39 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * 		.getLong(<js>"baz"</js>);
 	 *
 	 * 	<jc>// Using this method</jc>
-	 * 	<jk>long</jk> l = m.getAt(<jk>long</jk>.<jk>class</jk>, <js>"foo/bar/0/baz"</js>);
+	 * 	<jk>long</jk> l = m.getAt(<js>"foo/bar/0/baz"</js>, <jk>long</jk>.<jk>class</jk>);
 	 * </p>
 	 *
 	 * <p>
 	 * This method uses the {@link PojoRest} class to perform the lookup, so the map can contain any of the various
 	 * class types that the {@link PojoRest} class supports (e.g. beans, collections, arrays).
 	 *
-	 * @param <T> The class type.
+	 * @param path The path to the entry.
 	 * @param type The class type.
+	 *
+	 * @param <T> The class type.
+	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
+	 */
+	public <T> T getAt(String path, Class<T> type) {
+		return getPojoRest().get(path, type);
+	}
+
+	/**
+	 * Same as {@link #getAt(String,Class)}, but allows for conversion to complex maps and collections.
+	 *
+	 * <p>
+	 * This method uses the {@link PojoRest} class to perform the lookup, so the map can contain any of the various
+	 * class types that the {@link PojoRest} class supports (e.g. beans, collections, arrays).
+	 *
 	 * @param path The path to the entry.
+	 * @param type The class type.
+	 * @param args The class parameter types.
+	 *
+	 * @param <T> The class type.
 	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
 	 */
-	public <T> T getAt(Class<T> type, String path) {
-		return getPojoRest().get(type, path);
+	public <T> T getAt(String path, Type type, Type...args) {
+		return getPojoRest().get(path, type, args);
 	}
 
 	/**
@@ -618,13 +682,13 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * Returns the specified entry value converted to a {@link String}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(String.<jk>class</jk>, key)</code>.
+	 * Shortcut for <code>get(key, String.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 */
 	public String getString(String key) {
-		return get(String.class, key);
+		return get(key, String.class);
 	}
 
 	/**
@@ -640,7 +704,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * 	Never <jk>null</jk>.
 	 */
 	public String[] getStringArray(String key) {
-		Object s = get(Object.class, key);
+		Object s = get(key, Object.class);
 		if (s == null)
 			return new String[0];
 		if (s instanceof Collection)
@@ -657,7 +721,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @return The value converted to a string array.
 	 */
 	public String[] getStringArray(String key, String[] def) {
-		Object s = get(Object.class, key);
+		Object s = get(key, Object.class);
 		if (s == null)
 			return def;
 		String[] r = null;
@@ -676,35 +740,35 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * Returns the specified entry value converted to a {@link String}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(String.<jk>class</jk>, key, defVal)</code>.
+	 * Shortcut for <code>getWithDefault(key, defVal, String.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
 	 * @return The converted value, or the default value if the map contains no mapping for this key.
 	 */
 	public String getString(String key, String defVal) {
-		return get(String.class, key, defVal);
+		return getWithDefault(key, defVal, String.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to an {@link Integer}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(Integer.<jk>class</jk>, key)</code>.
+	 * Shortcut for <code>get(key, Integer.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Integer getInt(String key) {
-		return get(Integer.class, key);
+		return get(key, Integer.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to an {@link Integer}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(Integer.<jk>class</jk>, key, defVal)</code>.
+	 * Shortcut for <code>getWithDefault(key, defVal, Integer.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
@@ -712,28 +776,28 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Integer getInt(String key, Integer defVal) {
-		return get(Integer.class, key, defVal);
+		return getWithDefault(key, defVal, Integer.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link Long}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(Long.<jk>class</jk>, key)</code>.
+	 * Shortcut for <code>get(key, Long.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Long getLong(String key) {
-		return get(Long.class, key);
+		return get(key, Long.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link Long}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(Long.<jk>class</jk>, key, defVal)</code>.
+	 * Shortcut for <code>getWithDefault(key, defVal, Long.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
@@ -741,28 +805,28 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Long getLong(String key, Long defVal) {
-		return get(Long.class, key, defVal);
+		return getWithDefault(key, defVal, Long.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link Boolean}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(Boolean.<jk>class</jk>, key)</code>.
+	 * Shortcut for <code>get(key, Boolean.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Boolean getBoolean(String key) {
-		return get(Boolean.class, key);
+		return get(key, Boolean.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link Boolean}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(Boolean.<jk>class</jk>, key, defVal)</code>.
+	 * Shortcut for <code>getWithDefault(key, defVal, Boolean.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
@@ -770,28 +834,28 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Boolean getBoolean(String key, Boolean defVal) {
-		return get(Boolean.class, key, defVal);
+		return getWithDefault(key, defVal, Boolean.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link Map}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(Map.<jk>class</jk>, key)</code>.
+	 * Shortcut for <code>get(key, Map.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Map<?,?> getMap(String key) {
-		return get(Map.class, key);
+		return get(key, Map.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link Map}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(Map.<jk>class</jk>, key, defVal)</code>.
+	 * Shortcut for <code>getWithDefault(key, defVal, Map.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
@@ -799,28 +863,45 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Map<?,?> getMap(String key, Map<?,?> defVal) {
-		return get(Map.class, key, defVal);
+		return getWithDefault(key, defVal, Map.class);
+	}
+
+	/**
+	 * Same as {@link #getMap(String, Map)} except converts the keys and values to the specified types.
+	 *
+	 * @param key The key.
+	 * @param keyType The key type class.
+	 * @param valType The value type class.
+	 * @param def The default value if the map doesn't contain the specified mapping.
+	 * @return The converted value, or the default value if the map contains no mapping for this key.
+	 * @throws InvalidDataConversionException If value cannot be converted.
+	 */
+	public <K,V> Map<K,V> getMap(String key, Class<K> keyType, Class<V> valType, Map<K,V> def) {
+		Object o = get(key);
+		if (o == null)
+			return def;
+		return session.convertToType(o, Map.class, keyType, valType);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link List}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(List.<jk>class</jk>, key)</code>.
+	 * Shortcut for <code>get(key, List.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public List<?> getList(String key) {
-		return get(List.class, key);
+		return get(key, List.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link List}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(List.<jk>class</jk>, key, defVal)</code>.
+	 * Shortcut for <code>getWithDefault(key, defVal, List.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
@@ -828,28 +909,44 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public List<?> getList(String key, List<?> defVal) {
-		return get(List.class, key, defVal);
+		return getWithDefault(key, defVal, List.class);
+	}
+
+	/**
+	 * Same as {@link #getList(String, List)} except converts the elements to the specified types.
+	 *
+	 * @param key The key.
+	 * @param elementType The element type class.
+	 * @param def The default value if the map doesn't contain the specified mapping.
+	 * @return The converted value, or the default value if the map contains no mapping for this key.
+	 * @throws InvalidDataConversionException If value cannot be converted.
+	 */
+	public <E> List<E> getList(String key, Class<E> elementType, List<E> def) {
+		Object o = get(key);
+		if (o == null)
+			return def;
+		return session.convertToType(o, List.class, elementType);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link Map}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(ObjectMap.<jk>class</jk>, key)</code>.
+	 * Shortcut for <code>get(key, ObjectMap.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectMap getObjectMap(String key) {
-		return get(ObjectMap.class, key);
+		return get(key, ObjectMap.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link ObjectMap}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(ObjectMap.<jk>class</jk>, key, defVal)</code>.
+	 * Shortcut for <code>getWithDefault(key, defVal, ObjectMap.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
@@ -857,28 +954,28 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectMap getObjectMap(String key, ObjectMap defVal) {
-		return get(ObjectMap.class, key, defVal);
+		return getWithDefault(key, defVal, ObjectMap.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link ObjectList}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(ObjectList.<jk>class</jk>, key)</code>.
+	 * Shortcut for <code>get(key, ObjectList.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectList getObjectList(String key) {
-		return get(ObjectList.class, key);
+		return get(key, ObjectList.class);
 	}
 
 	/**
 	 * Returns the specified entry value converted to a {@link ObjectList}.
 	 *
 	 * <p>
-	 * Shortcut for <code>get(ObjectList.<jk>class</jk>, key, defVal)</code>.
+	 * Shortcut for <code>getWithDefault(key, defVal, ObjectList.<jk>class</jk>)</code>.
 	 *
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
@@ -886,7 +983,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectList getObjectList(String key, ObjectList defVal) {
-		return get(ObjectList.class, key, defVal);
+		return getWithDefault(key, defVal, ObjectList.class);
 	}
 
 	/**
@@ -1038,16 +1135,16 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 
 	/**
 	 * Equivalent to calling <code>get(class,key,def)</code> followed by <code>remove(key);</code>
-	 *
-	 * @param <T> The class type.
-	 * @param type The class type.
 	 * @param key The key.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
+	 * @param type The class type.
+	 *
+	 * @param <T> The class type.
 	 * @return The converted value, or the default value if the map contains no mapping for this key.
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
-	public <T> T remove(Class<T> type, String key, T defVal) {
-		T t = get(type, key, defVal);
+	public <T> T removeWithDefault(String key, T defVal, Class<T> type) {
+		T t = getWithDefault(key, defVal, type);
 		remove(key);
 		return t;
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/Session.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/Session.java b/juneau-core/src/main/java/org/apache/juneau/Session.java
index 256ce16..056604c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/Session.java
+++ b/juneau-core/src/main/java/org/apache/juneau/Session.java
@@ -79,18 +79,18 @@ public abstract class Session {
 	 * @param key The property key.
 	 * @return The property value, or <jk>null</jk> if it doesn't exist.
 	 */
-	public final String getProperty(String key) {
-		return getProperty(key, null);
+	public final String getStringProperty(String key) {
+		return getStringProperty(key, null);
 	}
 
 	/**
-	 * Same as {@link #getProperty(String)} but with a default value.
+	 * Same as {@link #getStringProperty(String)} but with a default value.
 	 *
 	 * @param key The property key.
 	 * @param def The default value if the property doesn't exist or is <jk>null</jk>.
 	 * @return The property value.
 	 */
-	public final String getProperty(String key, String def) {
+	public final String getStringProperty(String key, String def) {
 		Object v = properties.get(key);
 		if (v == null)
 			v = ctx.getPropertyStore().getProperty(key, String.class, null);
@@ -100,26 +100,28 @@ public abstract class Session {
 	}
 
 	/**
-	 * Same as {@link #getProperty(String)} but transforms the value to the specified type.
+	 * Same as {@link #getStringProperty(String)} but transforms the value to the specified type.
 	 *
-	 * @param type The class type of the value.
 	 * @param key The property key.
+	 * @param type The class type of the value.
+	 *
 	 * @return The property value.
 	 */
-	public final <T> T getProperty(Class<T> type, String key) {
-		return getProperty(type, key, null);
+	public final <T> T getProperty(String key, Class<T> type) {
+		return getPropertyWithDefault(key, null, type);
 	}
 
 	/**
-	 * Same as {@link #getProperty(Class,String)} but with a default value.
+	 * Same as {@link #getProperty(String,Class)} but with a default value.
 	 *
-	 * @param type The class type of the value.
 	 * @param key The property key.
 	 * @param def The default value if the property doesn't exist or is <jk>null</jk>.
+	 * @param type The class type of the value.
+	 *
 	 * @return The property value.
 	 */
-	public final <T> T getProperty(Class<T> type, String key, T def) {
-		T t = properties.get(type, key);
+	public final <T> T getPropertyWithDefault(String key, T def, Class<T> type) {
+		T t = properties.get(key, type);
 		if (t == null)
 			t = ctx.getPropertyStore().getProperty(key, type, def);
 		return t;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
index c51a3a0..501de02 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
@@ -69,7 +69,7 @@ public class HtmlDocSerializerSession extends HtmlStrippedDocSerializerSession {
 			script = p.getStringArray(HTMLDOC_script, ctx.script);
 			nowrap = p.getBoolean(HTMLDOC_nowrap, ctx.nowrap);
 			noResultsMessage = p.getString(HTMLDOC_noResultsMessage, ctx.noResultsMessage);
-			template = ClassUtils.newInstance(HtmlDocTemplate.class, p.get(HTMLDOC_template, ctx.template));
+			template = ClassUtils.newInstance(HtmlDocTemplate.class, p.getWithDefault(HTMLDOC_template, ctx.template));
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java
index aab0017..57df024 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/ObjectUtils.java
@@ -178,8 +178,8 @@ public class ObjectUtils {
 	 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
 	 * @return The converted value.
 	 */
-	public static <T> T convertToType(Object outer, Object value, Class<T> type) {
-		return session.convertToType(outer, value, type);
+	public static <T> T convertToMemberType(Object outer, Object value, Class<T> type) {
+		return session.convertToMemberType(outer, value, type);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
index 994eec3..938f643 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -72,7 +72,7 @@ public abstract class ParserSession extends BeanSession {
 			strict = p.getBoolean(PARSER_strict, ctx.strict);
 			inputStreamCharset = p.getString(PARSER_inputStreamCharset, ctx.inputStreamCharset);
 			fileCharset = p.getString(PARSER_fileCharset, ctx.fileCharset);
-			listenerClass = p.get(Class.class, PARSER_listener, ctx.listener);
+			listenerClass = p.getWithDefault(PARSER_listener, ctx.listener, Class.class);
 		}
 		this.javaMethod = args.javaMethod;
 		this.outer = args.outer;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index 4654d0f..f2428b6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -138,9 +138,9 @@ public abstract class SerializerSession extends BeanSession {
 			sortCollections = p.getBoolean(SERIALIZER_sortCollections, ctx.sortMaps);
 			sortMaps = p.getBoolean(SERIALIZER_sortMaps, ctx.sortMaps);
 			abridged = p.getBoolean(SERIALIZER_abridged, ctx.abridged);
-			uriResolution = p.get(UriResolution.class, SERIALIZER_uriResolution, UriResolution.ROOT_RELATIVE);
-			uriRelativity = p.get(UriRelativity.class, SERIALIZER_uriRelativity, UriRelativity.RESOURCE);
-			listenerClass = p.get(Class.class, SERIALIZER_listener, ctx.listener);
+			uriResolution = p.getWithDefault(SERIALIZER_uriResolution, UriResolution.ROOT_RELATIVE, UriResolution.class);
+			uriRelativity = p.getWithDefault(SERIALIZER_uriRelativity, UriRelativity.RESOURCE, UriRelativity.class);
+			listenerClass = p.getWithDefault(SERIALIZER_listener, ctx.listener, Class.class);
 		}
 
 		uriResolver = new UriResolver(uriResolution, uriRelativity, args.uriContext == null ? ctx.uriContext : args.uriContext);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java
index 3960607..c899e44 100644
--- a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java
@@ -58,7 +58,7 @@ public class SoapXmlSerializerSession extends XmlSerializerSession {
 			.attr("encoding", "UTF-8")
 			.appendln("?>");
 		w.oTag("soap", "Envelope")
-			.attr("xmlns", "soap", getProperty(SOAPXML_SOAPAction, "http://www.w3.org/2003/05/soap-envelope"))
+			.attr("xmlns", "soap", getStringProperty(SOAPXML_SOAPAction, "http://www.w3.org/2003/05/soap-envelope"))
 			.appendln(">");
 		w.sTag(1, "soap", "Body").nl(1);
 		indent += 2;
@@ -70,6 +70,6 @@ public class SoapXmlSerializerSession extends XmlSerializerSession {
 
 	@Override /* Serializer */
 	public Map<String,String> getResponseHeaders() {
-		return new AMap<String,String>().append("SOAPAction", getProperty(SOAPXML_SOAPAction, "http://www.w3.org/2003/05/soap-envelope"));
+		return new AMap<String,String>().append("SOAPAction", getStringProperty(SOAPXML_SOAPAction, "http://www.w3.org/2003/05/soap-envelope"));
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/utils/Args.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/Args.java b/juneau-core/src/main/java/org/apache/juneau/utils/Args.java
index a8c5e7c..bcff168 100644
--- a/juneau-core/src/main/java/org/apache/juneau/utils/Args.java
+++ b/juneau-core/src/main/java/org/apache/juneau/utils/Args.java
@@ -221,7 +221,7 @@ public final class Args extends ObjectMap {
 		ObjectList l = (ObjectList)get(name);
 		if (l == null || l.size() == 0)
 			return null;
-		return l.get(c, 0);
+		return l.get(0, c);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/utils/PojoRest.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/PojoRest.java b/juneau-core/src/main/java/org/apache/juneau/utils/PojoRest.java
index 8183a52..2ed77ac 100644
--- a/juneau-core/src/main/java/org/apache/juneau/utils/PojoRest.java
+++ b/juneau-core/src/main/java/org/apache/juneau/utils/PojoRest.java
@@ -190,12 +190,13 @@ public final class PojoRest {
 	/**
 	 * Retrieves the element addressed by the URL.
 	 *
-	 * @param url The URL of the element to retrieve.
-	 * If null or blank, returns the root.
-	 * @return The addressed element, or null if that element does not exist in the tree.
+	 * @param url
+	 * 	The URL of the element to retrieve.
+	 * 	<br>If <jk>null</jk> or blank, returns the root.
+	 * @return The addressed element, or <jk>null</jk> if that element does not exist in the tree.
 	 */
 	public Object get(String url) {
-		return get(url, null);
+		return getWithDefault(url, null);
 	}
 
 	/**
@@ -203,11 +204,11 @@ public final class PojoRest {
 	 *
 	 * @param url
 	 * 	The URL of the element to retrieve.
-	 * 	If null or blank, returns the root.
+	 * 	<br>If <jk>null</jk> or blank, returns the root.
 	 * @param defVal The default value if the map doesn't contain the specified mapping.
 	 * @return The addressed element, or null if that element does not exist in the tree.
 	 */
-	public Object get(String url, Object defVal) {
+	public Object getWithDefault(String url, Object defVal) {
 		Object o = service(GET, url, null);
 		return o == null ? defVal : o;
 	}
@@ -216,34 +217,109 @@ public final class PojoRest {
 	 * Retrieves the element addressed by the URL as the specified object type.
 	 *
 	 * <p>
-	 * Will convert object to the specified type per {@link BeanSession#convertToType(Object, ClassMeta)}.
+	 * Will convert object to the specified type per {@link BeanSession#convertToType(Object, Class)}.
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <p class='bcode'>
+	 * 	PojoRest r = <jk>new</jk> PojoRest(object);
+	 *
+	 * 	<jc>// Value converted to a string.</jc>
+	 * 	String s = r.get(<js>"path/to/string"</js>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a bean.</jc>
+	 * 	MyBean b = r.get(<js>"path/to/bean"</js>, MyBean.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a bean array.</jc>
+	 * 	MyBean[] ba = r.get(<js>"path/to/beanarray"</js>, MyBean[].<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of objects.</jc>
+	 * 	List l = r.get(<js>"path/to/list"</js>, LinkedList.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map of object keys/values.</jc>
+	 * 	Map m2 = r.get(<js>"path/to/map"</js>, TreeMap.<jk>class</jk>);
+	 * </p>
 	 *
-	 * @param type The specified object type.
 	 * @param url
 	 * 	The URL of the element to retrieve.
-	 * 	If null or blank, returns the root.
+	 * 	If <jk>null</jk> or blank, returns the root.
+	 * @param type The specified object type.
+	 *
 	 * @param <T> The specified object type.
 	 * @return The addressed element, or null if that element does not exist in the tree.
 	 */
-	public <T> T get(Class<T> type, String url) {
-		return get(type, url, null);
+	public <T> T get(String url, Class<T> type) {
+		return getWithDefault(url, null, type);
 	}
 
 	/**
 	 * Retrieves the element addressed by the URL as the specified object type.
 	 *
 	 * <p>
-	 * Will convert object to the specified type per {@link BeanSession#convertToType(Object, ClassMeta)}.
+	 * Will convert object to the specified type per {@link BeanSession#convertToType(Object, Class)}.
+	 *
+	 * <p>
+	 * The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <p class='bcode'>
+	 * 	PojoMap r = <jk>new</jk> PojoMap(object);
+	 *
+	 * 	<jc>// Value converted to a linked-list of strings.</jc>
+	 * 	List&lt;String&gt; l1 = r.get(<js>"path/to/list1"</js>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of beans.</jc>
+	 * 	List&lt;MyBean&gt; l2 = r.get(<js>"path/to/list2"</js>, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a linked-list of linked-lists of strings.</jc>
+	 * 	List&lt;List&lt;String&gt;&gt; l3 = r.get(<js>"path/to/list3"</js>, LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map of string keys/values.</jc>
+	 * 	Map&lt;String,String&gt; m1 = r.get(<js>"path/to/map1"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
+	 *
+	 * 	<jc>// Value converted to a map containing string keys and values of lists containing beans.</jc>
+	 * 	Map&lt;String,List&lt;MyBean&gt;&gt; m2 = r.get(<js>"path/to/map2"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
+	 * </p>
+	 *
+	 * <p>
+	 * <code>Collection</code> classes are assumed to be followed by zero or one objects indicating the element type.
+	 *
+	 * <p>
+	 * <code>Map</code> classes are assumed to be followed by zero or two meta objects indicating the key and value types.
+	 *
+	 * <p>
+	 * The array can be arbitrarily long to indicate arbitrarily complex data structures.
+	 *
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>Use the {@link #get(String, Class)} method instead if you don't need a parameterized map/collection.
+	 * </ul>
 	 *
+	 * @param url
+	 * 	The URL of the element to retrieve.
+	 * 	If <jk>null</jk> or blank, returns the root.
 	 * @param type The specified object type.
+	 * @param args The specified object parameter types.
+	 *
+	 * @param <T> The specified object type.
+	 * @return The addressed element, or null if that element does not exist in the tree.
+	 */
+	public <T> T get(String url, Type type, Type...args) {
+		return getWithDefault(url, null, type, args);
+	}
+
+	/**
+	 * Same as {@link #get(String, Class)} but returns a default value if the addressed element is null or non-existent.
+	 *
 	 * @param url
 	 * 	The URL of the element to retrieve.
-	 * 	If null or blank, returns the root.
+	 * 	If <jk>null</jk> or blank, returns the root.
 	 * @param def The default value if addressed item does not exist.
+	 * @param type The specified object type.
+	 *
 	 * @param <T> The specified object type.
 	 * @return The addressed element, or null if that element does not exist in the tree.
 	 */
-	public <T> T get(Class<T> type, String url, T def) {
+	public <T> T getWithDefault(String url, T def, Class<T> type) {
 		Object o = service(GET, url, null);
 		if (o == null)
 			return def;
@@ -251,6 +327,26 @@ public final class PojoRest {
 	}
 
 	/**
+	 * Same as {@link #get(String,Type,Type[])} but returns a default value if the addressed element is null or non-existent.
+	 *
+	 * @param url
+	 * 	The URL of the element to retrieve.
+	 * 	If <jk>null</jk? or blank, returns the root.
+	 * @param def The default value if addressed item does not exist.
+	 * @param type The specified object type.
+	 * @param args The specified object parameter types.
+	 *
+	 * @param <T> The specified object type.
+	 * @return The addressed element, or null if that element does not exist in the tree.
+	 */
+	public <T> T getWithDefault(String url, T def, Type type, Type...args) {
+		Object o = service(GET, url, null);
+		if (o == null)
+			return def;
+		return session.convertToType(o, type, args);
+	}
+
+	/**
 	 * Returns the specified entry value converted to a {@link String}.
 	 *
 	 * <p>
@@ -260,7 +356,7 @@ public final class PojoRest {
 	 * @return The converted value, or <jk>null</jk> if the map contains no mapping for this key.
 	 */
 	public String getString(String url) {
-		return get(String.class, url);
+		return get(url, String.class);
 	}
 
 	/**
@@ -274,7 +370,7 @@ public final class PojoRest {
 	 * @return The converted value, or the default value if the map contains no mapping for this key.
 	 */
 	public String getString(String url, String defVal) {
-		return get(String.class, url, defVal);
+		return getWithDefault(url, defVal, String.class);
 	}
 
 	/**
@@ -288,7 +384,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Integer getInt(String url) {
-		return get(Integer.class, url);
+		return get(url, Integer.class);
 	}
 
 	/**
@@ -303,7 +399,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Integer getInt(String url, Integer defVal) {
-		return get(Integer.class, url, defVal);
+		return getWithDefault(url, defVal, Integer.class);
 	}
 
 	/**
@@ -317,7 +413,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Long getLong(String url) {
-		return get(Long.class, url);
+		return get(url, Long.class);
 	}
 
 	/**
@@ -332,7 +428,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Long getLong(String url, Long defVal) {
-		return get(Long.class, url, defVal);
+		return getWithDefault(url, defVal, Long.class);
 	}
 
 	/**
@@ -346,7 +442,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Boolean getBoolean(String url) {
-		return get(Boolean.class, url);
+		return get(url, Boolean.class);
 	}
 
 	/**
@@ -361,7 +457,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Boolean getBoolean(String url, Boolean defVal) {
-		return get(Boolean.class, url, defVal);
+		return getWithDefault(url, defVal, Boolean.class);
 	}
 
 	/**
@@ -375,7 +471,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Map<?,?> getMap(String url) {
-		return get(Map.class, url);
+		return get(url, Map.class);
 	}
 
 	/**
@@ -390,7 +486,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public Map<?,?> getMap(String url, Map<?,?> defVal) {
-		return get(Map.class, url, defVal);
+		return getWithDefault(url, defVal, Map.class);
 	}
 
 	/**
@@ -404,7 +500,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public List<?> getList(String url) {
-		return get(List.class, url);
+		return get(url, List.class);
 	}
 
 	/**
@@ -419,7 +515,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public List<?> getList(String url, List<?> defVal) {
-		return get(List.class, url, defVal);
+		return getWithDefault(url, defVal, List.class);
 	}
 
 	/**
@@ -433,7 +529,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectMap getObjectMap(String url) {
-		return get(ObjectMap.class, url);
+		return get(url, ObjectMap.class);
 	}
 
 	/**
@@ -448,7 +544,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectMap getObjectMap(String url, ObjectMap defVal) {
-		return get(ObjectMap.class, url, defVal);
+		return getWithDefault(url, defVal, ObjectMap.class);
 	}
 
 	/**
@@ -462,7 +558,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectList getObjectList(String url) {
-		return get(ObjectList.class, url);
+		return get(url, ObjectList.class);
 	}
 
 	/**
@@ -477,7 +573,7 @@ public final class PojoRest {
 	 * @throws InvalidDataConversionException If value cannot be converted.
 	 */
 	public ObjectList getObjectList(String url, ObjectList defVal) {
-		return get(ObjectList.class, url, defVal);
+		return getWithDefault(url, defVal, ObjectList.class);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
index 1f41d56..2a70b52 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
@@ -69,9 +69,9 @@ public class XmlParserSession extends ReaderParserSession {
 			preserveRootElement = ctx.preserveRootElement;
 		} else {
 			validating = p.getBoolean(XML_validating, ctx.validating);
-			reporter = (XMLReporter)p.get(XML_reporter, ctx.reporter);
-			resolver = (XMLResolver)p.get(XML_resolver, ctx.resolver);
-			eventAllocator = (XMLEventAllocator)p.get(XML_eventAllocator, ctx.eventAllocator);
+			reporter = (XMLReporter)p.getWithDefault(XML_reporter, ctx.reporter);
+			resolver = (XMLResolver)p.getWithDefault(XML_resolver, ctx.resolver);
+			eventAllocator = (XMLEventAllocator)p.getWithDefault(XML_eventAllocator, ctx.eventAllocator);
 			preserveRootElement = p.getBoolean(XML_preserveRootElement, ctx.preserveRootElement);
 		}
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/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 904bea8..91e552e 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -6919,6 +6919,37 @@
 				{@link org.apache.juneau.transforms.DateSwap}.
 			<li>
 				New annotation {@link org.apache.juneau.html.annotation.Html#anchorText}.
+			<li>
+				New methods on {@link org.apache.juneau.ObjectList}:
+				<ul>
+					<li>{@link org.apache.juneau.ObjectList#get(int,Class) get(int,Class)}
+					<li>{@link org.apache.juneau.ObjectList#get(int,Type,Type...) get(int,Type,Type...)}
+					<li>{@link org.apache.juneau.ObjectList#getMap(int,Class,Class) getMap(int,Class,Class)}
+					<li>{@link org.apache.juneau.ObjectList#getList(int,Class) getList(int,Class)}
+				</ul>
+			<li>
+				New methods on {@link org.apache.juneau.ObjectMap}:
+				<ul>
+					<li>{@link org.apache.juneau.ObjectMap#get(String,Class) get(String,Class)}
+					<li>{@link org.apache.juneau.ObjectMap#get(String,Type,Type...) get(String,Type,Type...)}
+					<li>{@link org.apache.juneau.ObjectMap#getWithDefault(String,Object) getWithDefault(String,Object)}
+					<li>{@link org.apache.juneau.ObjectMap#getWithDefault(String,Object,Class) getWithDefault(String,Object,Class)}
+					<li>{@link org.apache.juneau.ObjectMap#getWithDefault(String,Object,Type,Type...) getWithDefault(String,Object,Type,Type...)}
+					<li>{@link org.apache.juneau.ObjectMap#getSwapped(String,PojoSwap) getSwapped(String,PojoSwap)}
+					<li>{@link org.apache.juneau.ObjectMap#getAt(String,Class) getAt(String,Class)}
+					<li>{@link org.apache.juneau.ObjectMap#getAt(String,Type,Type...) getAt(String,Type,Type...)}
+					<li>{@link org.apache.juneau.ObjectMap#getMap(String,Class,Class,Map) getMap(String,Class,Class,Map)}
+					<li>{@link org.apache.juneau.ObjectMap#getList(String,Class,List) getList(String,Class,List)}
+				</ul>
+			<li>
+				New methods on {@link org.apache.juneau.utils.PojoRest}:
+				<ul>
+					<li>{@link org.apache.juneau.utils.PojoRest#get(String,Class) get(String,Class)}
+					<li>{@link org.apache.juneau.utils.PojoRest#get(String,Type,Type...) get(String,Type,Type...)}
+					<li>{@link org.apache.juneau.utils.PojoRest#getWithDefault(String,Object) getWithDefault(String,Object)}
+					<li>{@link org.apache.juneau.utils.PojoRest#getWithDefault(String,Object,Class) getWithDefault(String,Object,Class)}
+					<li>{@link org.apache.juneau.utils.PojoRest#getWithDefault(String,Object,Type,Type...) getWithDefault(String,Object,Type,Type...)}
+				</ul>
 		</ul>
 		
 		<h6 class='topic'>org.apache.juneau.rest</h6>
@@ -7266,10 +7297,10 @@
 			<li>New methods on {@link org.apache.juneau.serializer.SerializerSession} and {@link org.apache.juneau.parser.ParserSession}
 				for retrieving context and runtime-override properties:
 				<ul>
-					<li>{@link org.apache.juneau.Session#getProperty(String)}
-					<li>{@link org.apache.juneau.Session#getProperty(String,String)}
-					<li>{@link org.apache.juneau.Session#getProperty(Class,String)}
-					<li>{@link org.apache.juneau.Session#getProperty(Class,String,Object)}
+					<li><code><del>Session.getProperty(String)</del></code>
+					<li><code><del>Session.getProperty(String,String)</del></code>
+					<li><code><del>Session.getProperty(Class,String)</del></code>
+					<li><code><del>Session.getProperty(Class,String,Object)</del></code>
 				</ul>	
 			<li>New {@link org.apache.juneau.serializer.PartSerializer} interface particularly tailored to HTTP
 				headers, query parameters, form-data parameters, and path variables.  
@@ -8367,14 +8398,14 @@
 			<li>Fixed issue in {@link org.apache.juneau.xml.XmlSerializer} where <js>'\r'</js> and <js>'\n'</js> characters were not being handled per XML specs.
 			<li>New methods on {@link org.apache.juneau.ObjectList}:  
 				<ul>
-					<li>{@link org.apache.juneau.ObjectList#getAt(Class,String)}
+					<li><code><del>ObjectList.getAt(Class,String)</del></code>
 					<li>{@link org.apache.juneau.ObjectList#putAt(String,Object)}
 					<li>{@link org.apache.juneau.ObjectList#postAt(String,Object)}
 					<li>{@link org.apache.juneau.ObjectList#deleteAt(String)}
 				</ul>
 			<li>New methods on {@link org.apache.juneau.ObjectMap}:  
 				<ul>
-					<li>{@link org.apache.juneau.ObjectMap#getAt(Class,String)}
+					<li><code><del>ObjectMap.getAt(Class,String)</del></code>
 					<li>{@link org.apache.juneau.ObjectMap#putAt(String,Object)}
 					<li>{@link org.apache.juneau.ObjectMap#postAt(String,Object)}
 					<li>{@link org.apache.juneau.ObjectMap#deleteAt(String)}
@@ -8524,7 +8555,7 @@
 				</ul>
 			<li>New methods on {@link org.apache.juneau.utils.PojoRest}:
 				<ul>
-					<li>{@link org.apache.juneau.utils.PojoRest#get(Class,String,Object)}
+					<li><code><del>PojoRest.get(Class,String,Object)</del></code>
 					<li>{@link org.apache.juneau.utils.PojoRest#getString(String)}
 					<li>{@link org.apache.juneau.utils.PojoRest#getString(String,String)}
 					<li>{@link org.apache.juneau.utils.PojoRest#getInt(String)}
@@ -8858,7 +8889,7 @@
 			<li>New {@link org.apache.juneau.html.SimpleHtmlWriter} class.  
 				Can be used for simple HTML DOM construction.
 			<li>New {@link org.apache.juneau.utils.ProcBuilder} class for calling external processes.
-			<li>New {@link org.apache.juneau.ObjectMap#remove(Class,String,Object)} method.
+			<li>New <code><del>ObjectMap.remove(Class,String,Object)</del></code> method.
 			<li><js>"class='link'"</js> added to links generated by {@link org.apache.juneau.html.HtmlDocSerializer}.
 			<li>New <code><del>EncoderGroup#append(EncoderGroup)</del></code> method.
 			<li>New <code>HtmlDocSerializerContext.HTMLDOC_addLinks</code> configuration property.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-examples-rest/.classpath
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/.classpath b/juneau-examples-rest/.classpath
index 230aeac..bfe718b 100644
--- a/juneau-examples-rest/.classpath
+++ b/juneau-examples-rest/.classpath
@@ -22,7 +22,7 @@
 	<classpathentry kind="src" path="/juneau-core"/>
 	<classpathentry kind="src" path="/juneau-core-rdf"/>
 	<classpathentry kind="src" path="/juneau-rest-client"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
 		<attributes>
 			<attribute name="maven.pomderived" value="true"/>
 		</attributes>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
index 79e094a..d622593 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
@@ -149,7 +149,7 @@ public class PhotosResource extends Resource {
 				@Override /* SerializerSession */ 
 				protected void doSerialize(SerializerPipe out, Object o) throws Exception {
 					RenderedImage image = (RenderedImage)o;
-					String mediaType = getProperty("mediaType");
+					String mediaType = getStringProperty("mediaType");
 					ImageIO.write(image, mediaType.substring(mediaType.indexOf('/')+1), out.getOutputStream());
 				}
 			};

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/23fe563d/juneau-microservice/.classpath
----------------------------------------------------------------------
diff --git a/juneau-microservice/.classpath b/juneau-microservice/.classpath
index fb1c858..c0bbbe8 100644
--- a/juneau-microservice/.classpath
+++ b/juneau-microservice/.classpath
@@ -15,7 +15,7 @@
 	<classpathentry kind="src" path="/juneau-rest"/>
 	<classpathentry kind="src" path="/juneau-core"/>
 	<classpathentry kind="src" path="/juneau-rest-client"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
 		<attributes>
 			<attribute name="maven.pomderived" value="true"/>
 		</attributes>