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 2019/06/22 19:25:55 UTC

[juneau] branch master updated: JUNEAU-105 UrlPathPattern should use a state machine.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 588f8d8  JUNEAU-105 UrlPathPattern should use a state machine.
588f8d8 is described below

commit 588f8d8ce5919e1a1039db44b3d6710e40975f5b
Author: JamesBognar <ja...@apache.org>
AuthorDate: Sat Jun 22 15:23:59 2019 -0400

    JUNEAU-105 UrlPathPattern should use a state machine.
---
 .../main/java/org/apache/juneau/config/Config.java |   2 +-
 .../juneau/config/store/ConfigClasspathStore.java  |   4 +-
 .../juneau/config/store/ConfigFileStore.java       |   4 +-
 .../juneau/config/store/ConfigMemoryStore.java     |   4 +-
 .../apache/juneau/config/store/ConfigStore.java    |   4 +-
 .../java/org/apache/juneau/ContextCacheTest.java   |  15 +
 .../apache/juneau/config/ConfigBuilderTest.java    |   4 +-
 .../org/apache/juneau/utils/SimpleMapTest.java     |  10 +-
 .../java/org/apache/juneau/dto/ResultSetList.java  |   2 +-
 .../java/org/apache/juneau/jena/RdfParser.java     |   4 +-
 .../org/apache/juneau/jena/RdfParserSession.java   |   4 +-
 .../java/org/apache/juneau/jena/RdfSerializer.java |   4 +-
 .../apache/juneau/jena/RdfSerializerSession.java   |   4 +-
 .../main/java/org/apache/juneau/BeanContext.java   |   4 +-
 .../main/java/org/apache/juneau/BeanSession.java   |   6 +-
 .../java/org/apache/juneau/BeanSessionArgs.java    |   4 +-
 .../org/apache/juneau/BeanTraverseContext.java     |   4 +-
 .../org/apache/juneau/BeanTraverseSession.java     |   4 +-
 .../src/main/java/org/apache/juneau/ClassMeta.java |   4 +-
 .../src/main/java/org/apache/juneau/Context.java   |  16 +-
 .../src/main/java/org/apache/juneau/Session.java   |  11 +-
 .../main/java/org/apache/juneau/SessionArgs.java   |  11 +-
 .../main/java/org/apache/juneau/csv/CsvParser.java |   4 +-
 .../org/apache/juneau/csv/CsvParserSession.java    |   4 +-
 .../java/org/apache/juneau/csv/CsvSerializer.java  |   4 +-
 .../apache/juneau/csv/CsvSerializerSession.java    |   4 +-
 .../org/apache/juneau/html/HtmlDocSerializer.java  |   4 +-
 .../juneau/html/HtmlDocSerializerSession.java      |   4 +-
 .../java/org/apache/juneau/html/HtmlParser.java    |   4 +-
 .../org/apache/juneau/html/HtmlParserSession.java  |   4 +-
 .../juneau/html/HtmlSchemaDocSerializer.java       |   4 +-
 .../apache/juneau/html/HtmlSchemaSerializer.java   |   4 +-
 .../juneau/html/HtmlSchemaSerializerSession.java   |   4 +-
 .../org/apache/juneau/html/HtmlSerializer.java     |   4 +-
 .../apache/juneau/html/HtmlSerializerSession.java  |   4 +-
 .../juneau/html/HtmlStrippedDocSerializer.java     |   4 +-
 .../html/HtmlStrippedDocSerializerSession.java     |   4 +-
 .../java/org/apache/juneau/internal/SimpleMap.java |  40 +--
 .../main/java/org/apache/juneau/jso/JsoParser.java |   4 +-
 .../org/apache/juneau/jso/JsoParserSession.java    |   4 +-
 .../java/org/apache/juneau/jso/JsoSerializer.java  |   4 +-
 .../apache/juneau/jso/JsoSerializerSession.java    |   4 +-
 .../java/org/apache/juneau/json/JsonParser.java    |   4 +-
 .../org/apache/juneau/json/JsonParserSession.java  |   4 +-
 .../apache/juneau/json/JsonSchemaSerializer.java   |   4 +-
 .../juneau/json/JsonSchemaSerializerSession.java   |   4 +-
 .../org/apache/juneau/json/JsonSerializer.java     |   4 +-
 .../apache/juneau/json/JsonSerializerSession.java  |   4 +-
 .../apache/juneau/json/SimpleJsonSerializer.java   |   4 +-
 .../juneau/jsonschema/JsonSchemaGenerator.java     |   4 +-
 .../jsonschema/JsonSchemaGeneratorSession.java     |   4 +-
 .../java/org/apache/juneau/marshall/Marshall.java  |  72 +++++
 .../org/apache/juneau/msgpack/MsgPackParser.java   |   4 +-
 .../juneau/msgpack/MsgPackParserSession.java       |   4 +-
 .../apache/juneau/msgpack/MsgPackSerializer.java   |   4 +-
 .../juneau/msgpack/MsgPackSerializerSession.java   |   4 +-
 .../java/org/apache/juneau/oapi/OpenApiParser.java |   4 +-
 .../apache/juneau/oapi/OpenApiParserSession.java   |   4 +-
 .../org/apache/juneau/oapi/OpenApiSerializer.java  |   4 +-
 .../juneau/oapi/OpenApiSerializerSession.java      |   4 +-
 .../apache/juneau/parser/InputStreamParser.java    |   4 +-
 .../juneau/parser/InputStreamParserSession.java    |   4 +-
 .../main/java/org/apache/juneau/parser/Parser.java |   4 +-
 .../org/apache/juneau/parser/ParserSession.java    |   4 +-
 .../apache/juneau/parser/ParserSessionArgs.java    |   4 +-
 .../org/apache/juneau/parser/ReaderParser.java     |   4 +-
 .../apache/juneau/parser/ReaderParserSession.java  |   4 +-
 .../apache/juneau/plaintext/PlainTextParser.java   |   4 +-
 .../juneau/plaintext/PlainTextParserSession.java   |   4 +-
 .../juneau/plaintext/PlainTextSerializer.java      |   4 +-
 .../plaintext/PlainTextSerializerSession.java      |   4 +-
 .../juneau/serializer/OutputStreamSerializer.java  |   4 +-
 .../serializer/OutputStreamSerializerSession.java  |   4 +-
 .../org/apache/juneau/serializer/Serializer.java   |   4 +-
 .../juneau/serializer/SerializerSession.java       |   4 +-
 .../juneau/serializer/SerializerSessionArgs.java   |   4 +-
 .../apache/juneau/serializer/WriterSerializer.java |   4 +-
 .../juneau/serializer/WriterSerializerSession.java |   4 +-
 .../org/apache/juneau/soap/SoapXmlSerializer.java  |   4 +-
 .../juneau/soap/SoapXmlSerializerSession.java      |   4 +-
 .../main/java/org/apache/juneau/uon/UonParser.java |   4 +-
 .../org/apache/juneau/uon/UonParserSession.java    |   4 +-
 .../java/org/apache/juneau/uon/UonSerializer.java  |   4 +-
 .../apache/juneau/uon/UonSerializerSession.java    |   4 +-
 .../juneau/urlencoding/UrlEncodingParser.java      |   4 +-
 .../urlencoding/UrlEncodingParserSession.java      |   4 +-
 .../juneau/urlencoding/UrlEncodingSerializer.java  |   4 +-
 .../urlencoding/UrlEncodingSerializerSession.java  |   4 +-
 .../org/apache/juneau/xml/XmlDocSerializer.java    |   4 +-
 .../apache/juneau/xml/XmlDocSerializerSession.java |   4 +-
 .../main/java/org/apache/juneau/xml/XmlParser.java |   4 +-
 .../org/apache/juneau/xml/XmlParserSession.java    |   4 +-
 .../java/org/apache/juneau/xml/XmlSerializer.java  |   4 +-
 .../apache/juneau/xml/XmlSerializerSession.java    |   4 +-
 .../juneau/xmlschema/XmlSchemaDocSerializer.java   |   4 +-
 .../juneau/xmlschema/XmlSchemaSerializer.java      |   4 +-
 .../xmlschema/XmlSchemaSerializerSession.java      |   4 +-
 juneau-doc/docs/ReleaseNotes/8.0.1.html            |  23 ++
 .../11.Transforms/06.SwapMethods.html              |  21 +-
 .../microservice/resources/ConfigResource.java     |   4 +-
 .../apache/juneau/rest/test/ConfigResource.java    |   2 +-
 .../org/apache/juneau/rest/client/RestCall.java    |   4 +-
 .../org/apache/juneau/rest/client/RestClient.java  |   4 +-
 .../juneau/rest/util/UrlPathPatternTest.java       | 354 ++++++++++++++++++++-
 .../apache/juneau/rest/BasicRestCallHandler.java   |  22 ++
 .../java/org/apache/juneau/rest/RequestPath.java   |  15 -
 .../java/org/apache/juneau/rest/RestChild.java     |   3 +-
 .../java/org/apache/juneau/rest/RestContext.java   |   4 +-
 .../org/apache/juneau/rest/RestMethodContext.java  |  23 +-
 .../org/apache/juneau/rest/util/UrlPathParts.java  | 136 ++++----
 .../apache/juneau/rest/util/UrlPathPattern.java    | 201 +++++-------
 .../juneau/rest/util/UrlPathPatternMatch.java      |  78 +++--
 112 files changed, 939 insertions(+), 488 deletions(-)

diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
index 8af8f6d..da920ca 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
@@ -1795,7 +1795,7 @@ public final class Config extends Context implements ConfigEventListener, Writab
 	 * @return A copy of this config as a map of maps.
 	 */
 	@Override /* Context */
-	public ObjectMap asMap() {
+	public ObjectMap toMap() {
 		return configMap.asMap();
 	}
 
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
index 4385596..987b479 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
@@ -139,8 +139,8 @@ public class ConfigClasspathStore extends ConfigStore {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("ConfigClasspathStore", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
index 01c7433..c9240b9 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigFileStore.java
@@ -485,8 +485,8 @@ public class ConfigFileStore extends ConfigStore {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("ConfigFileStore", new DefaultFilteringObjectMap()
 				.append("charset", charset)
 				.append("extensions", extensions)
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
index 963f917..ec6601c 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigMemoryStore.java
@@ -122,8 +122,8 @@ public class ConfigMemoryStore extends ConfigStore {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("ConfigMemoryStore", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
index a40ceea..8ef6ce4 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
@@ -212,8 +212,8 @@ public abstract class ConfigStore extends Context implements Closeable {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("ConfigStore", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ContextCacheTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ContextCacheTest.java
index 1e06c36..9d770a4 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ContextCacheTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/ContextCacheTest.java
@@ -141,6 +141,11 @@ public class ContextCacheTest {
 		public SessionArgs createDefaultSessionArgs() {
 			return null;
 		}
+
+		@Override
+		public ObjectMap toMap() {
+			return new ObjectMap().append("f1", f1);
+		}
 	}
 
 	@ConfigurableContext
@@ -152,6 +157,11 @@ public class ContextCacheTest {
 			f2 = getIntegerProperty("B.f2.i", -1);
 
 		}
+
+		@Override
+		public ObjectMap toMap() {
+			return super.toMap().append("f2", f2);
+		}
 	}
 
 	@ConfigurableContext
@@ -161,6 +171,11 @@ public class ContextCacheTest {
 			super(ps);
 			f3 = getBooleanProperty("C.f3.b", false);
 		}
+
+		@Override
+		public ObjectMap toMap() {
+			return super.toMap().append("f3", f3);
+		}
 	}
 
 	@Test
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
index 14567b9..05dfc2e 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
@@ -51,10 +51,10 @@ public class ConfigBuilderTest {
 		assertFalse(f.exists());
 
 		cf.commit();
-		assertObjectEquals("{'':{},Test:{A:'a'}}", cf.asMap());
+		assertObjectEquals("{'':{},Test:{A:'a'}}", cf.toMap());
 
 		String NL = System.getProperty("line.separator");
 		cf = cf.load("[Test]"+NL+"A = b"+NL, true);
-		assertObjectEquals("{'':{},Test:{A:'b'}}", cf.asMap());
+		assertObjectEquals("{'':{},Test:{A:'b'}}", cf.toMap());
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/SimpleMapTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/SimpleMapTest.java
index 6f14e0e..2c19e58 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/SimpleMapTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/utils/SimpleMapTest.java
@@ -24,7 +24,7 @@ public class SimpleMapTest {
 	public void doTest() throws Exception {
 		String[] keys = {"a","b"};
 		Object[] vals = {"A","B"};
-		SimpleMap m = new SimpleMap(keys, vals);
+		SimpleMap<String,Object> m = new SimpleMap<>(keys, vals);
 		assertEquals(2, m.size());
 		assertEquals("A", m.get("a"));
 		assertEquals("B", m.get("b"));
@@ -38,11 +38,11 @@ public class SimpleMapTest {
 
 		assertNull(m.get("c"));
 
-		try { m = new SimpleMap(null, vals); fail(); } catch (IllegalArgumentException e) {}
-		try { m = new SimpleMap(keys, null); fail(); } catch (IllegalArgumentException e) {}
-		try { m = new SimpleMap(keys, new Object[0]); fail(); } catch (IllegalArgumentException e) {}
+		try { m = new SimpleMap<>(null, vals); fail(); } catch (IllegalArgumentException e) {}
+		try { m = new SimpleMap<>(keys, null); fail(); } catch (IllegalArgumentException e) {}
+		try { m = new SimpleMap<>(keys, new Object[0]); fail(); } catch (IllegalArgumentException e) {}
 
 		keys[0] = null;
-		try { m = new SimpleMap(keys, vals); fail(); } catch (IllegalArgumentException e) {}
+		try { m = new SimpleMap<>(keys, vals); fail(); } catch (IllegalArgumentException e) {}
 	}
 }
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/ResultSetList.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/ResultSetList.java
index 4f4e2c0..2410e7c 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/ResultSetList.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/ResultSetList.java
@@ -66,7 +66,7 @@ public final class ResultSetList extends LinkedList<Map<String,Object>> {
 					Object o = readEntry(rs, i+1, colTypes[i]);
 					row[i+offset] = o;
 				}
-				add(new SimpleMap(columns, row));
+				add(new SimpleMap<>(columns, row));
 			}
 		} finally {
 			rs.close();
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index 45bf004..7dc427c 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -262,8 +262,8 @@ public class RdfParser extends ReaderParser implements RdfCommon {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("RdfParser", new DefaultFilteringObjectMap()
 				.append("trimWhitespace", trimWhitespace)
 				.append("looseCollections", looseCollections)
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
index da2dbd2..4e173f6 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParserSession.java
@@ -516,8 +516,8 @@ public class RdfParserSession extends ReaderParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("RdfParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index 604a09e..c8408a3 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -458,8 +458,8 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("RdfSerializer", new DefaultFilteringObjectMap()
 				.append("addLiteralTypes", addLiteralTypes)
 				.append("addRootProperty", addRootProperty)
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
index e79618e..c501a81 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -547,8 +547,8 @@ public final class RdfSerializerSession extends WriterSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("RdfSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index cef2360..c25d84c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -3212,8 +3212,8 @@ public class BeanContext extends Context {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("BeanContext", new DefaultFilteringObjectMap()
 				.append("id", System.identityHashCode(this))
 				.append("beanClassVisibility", beanClassVisibility)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index 42a7c72..cdb31e9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -1556,9 +1556,9 @@ public class BeanSession extends Session {
 	}
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
-			.append("Context", ctx.asMap())
+	public ObjectMap toMap() {
+		return super.toMap()
+			.append("Context", ctx.toMap())
 			.append("BeanSession", new DefaultFilteringObjectMap()
 				.append("debug", debug)
 				.append("locale", locale)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSessionArgs.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSessionArgs.java
index fedc80c..6be8f5d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSessionArgs.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSessionArgs.java
@@ -148,8 +148,8 @@ public class BeanSessionArgs extends SessionArgs {
 	}
 
 	@Override /* SessionArgs */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("BeanSessionArgs", new DefaultFilteringObjectMap()
 				.append("schema", schema)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
index 8c92919..e05aec6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
@@ -304,8 +304,8 @@ public abstract class BeanTraverseContext extends BeanContext {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("BeanTraverseContext", new DefaultFilteringObjectMap()
 				.append("detectRecursions", detectRecursions)
 				.append("maxDepth", maxDepth)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseSession.java
index 711ea47..40a740a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseSession.java
@@ -293,8 +293,8 @@ public class BeanTraverseSession extends BeanSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("BeanTraverseSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
index 8f7365c..527b514 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
@@ -494,7 +494,7 @@ public final class ClassMeta<T> implements Type {
 
 			// Find swap() method if present.
 			for (MethodInfo m : ci.getPublicMethods()) {
-				if (m.isAll(PUBLIC, NOT_DEPRECATED, NOT_STATIC) && m.hasName("swap") && m.hasFuzzyArgs(BeanSession.class)) {
+				if (m.isAll(PUBLIC, NOT_DEPRECATED, NOT_STATIC) && (m.hasName("swap") || m.hasName("toMap")) && m.hasFuzzyArgs(BeanSession.class)) {
 					swapMethod = m.inner();
 					swapMethodType = m.getReturnType().inner();
 					break;
@@ -503,7 +503,7 @@ public final class ClassMeta<T> implements Type {
 			// Find unswap() method if present.
 			if (swapMethod != null) {
 				for (MethodInfo m : ci.getPublicMethods()) {
-					if (m.isAll(PUBLIC, NOT_DEPRECATED, STATIC) && m.hasName("unswap") && m.hasFuzzyArgs(BeanSession.class, swapMethodType)) {
+					if (m.isAll(PUBLIC, NOT_DEPRECATED, STATIC) && (m.hasName("unswap") || m.hasName("fromMap")) && m.hasFuzzyArgs(BeanSession.class, swapMethodType)) {
 						unswapMethod = m.inner();
 						break;
 					}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index b921e84..7386858 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -17,7 +17,6 @@ import java.util.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
-import org.apache.juneau.serializer.*;
 
 /**
  * A reusable stateless thread-safe read-only configuration, typically used for creating one-time use {@link Session}
@@ -513,29 +512,22 @@ public abstract class Context {
 	//-----------------------------------------------------------------------------------------------------------------
 	// Other methods
 	//-----------------------------------------------------------------------------------------------------------------
-	
+
 	@Override /* Object */
 	public String toString() {
-		try {
-			return asMap().toString(SimpleJsonSerializer.DEFAULT_READABLE);
-		} catch (SerializeException e) {
-			return e.getLocalizedMessage();
-		}
+		return SimpleJsonSerializer.DEFAULT_READABLE.toString(toMap());
 	}
-	
+
 	/**
 	 * Returns the properties defined on this bean context as a simple map for debugging purposes.
 	 *
 	 * @return A new map containing the properties defined on this context.
 	 */
-	@BeanIgnore
-	public ObjectMap asMap() {
+	public ObjectMap toMap() {
 		return new DefaultFilteringObjectMap()
 			.append("Context", new DefaultFilteringObjectMap()
 				.append("identityCode", identityCode)
 				.append("propertyStore", propertyStore)
 			);
 	}
-
-	
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
index 160d87b..a63bb53 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
@@ -21,7 +21,6 @@ import java.util.*;
 
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
-import org.apache.juneau.serializer.*;
 
 /**
  * A one-time-use non-thread-safe object that's meant to be used once and then thrown away.
@@ -307,22 +306,18 @@ public abstract class Session {
 	//-----------------------------------------------------------------------------------------------------------------
 	// Other methods
 	//-----------------------------------------------------------------------------------------------------------------
-	
+
 	/**
 	 * Returns the properties defined on this bean context as a simple map for debugging purposes.
 	 *
 	 * @return A new map containing the properties defined on this context.
 	 */
-	public ObjectMap asMap() {
+	public ObjectMap toMap() {
 		return new DefaultFilteringObjectMap();
 	}
 
 	@Override /* Object */
 	public String toString() {
-		try {
-			return asMap().toString(SimpleJsonSerializer.DEFAULT_READABLE);
-		} catch (SerializeException e) {
-			return e.getLocalizedMessage();
-		}
+		return SimpleJsonSerializer.DEFAULT_READABLE.toString(toMap());
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionArgs.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionArgs.java
index 6e6afd9..bcf1b4c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionArgs.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/SessionArgs.java
@@ -13,7 +13,6 @@
 package org.apache.juneau;
 
 import org.apache.juneau.json.*;
-import org.apache.juneau.serializer.*;
 
 /**
  * Runtime arguments common to all bean, serializer, and parser sessions.
@@ -86,13 +85,13 @@ public class SessionArgs {
 	//-----------------------------------------------------------------------------------------------------------------
 	// Other methods
 	//-----------------------------------------------------------------------------------------------------------------
-	
+
 	/**
 	 * Returns the properties defined on this object as a simple map for debugging purposes.
 	 *
 	 * @return A new map containing the properties defined on this object.
 	 */
-	public ObjectMap asMap() {
+	public ObjectMap toMap() {
 		return new DefaultFilteringObjectMap()
 			.append("SessionArgs", new DefaultFilteringObjectMap()
 				.append("properties", properties)
@@ -101,10 +100,6 @@ public class SessionArgs {
 
 	@Override /* Object */
 	public String toString() {
-		try {
-			return asMap().toString(SimpleJsonSerializer.DEFAULT_READABLE);
-		} catch (SerializeException e) {
-			return e.getLocalizedMessage();
-		}
+		return SimpleJsonSerializer.DEFAULT_READABLE.toString(toMap());
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
index 7e5af15..2c7ac84 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
@@ -82,8 +82,8 @@ public class CsvParser extends ReaderParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("CsvParser", new DefaultFilteringObjectMap());
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParserSession.java
index 3c8d87a..d745375 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParserSession.java
@@ -56,8 +56,8 @@ public final class CsvParserSession extends ReaderParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("CsvParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
index 9b389d9..40811dd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
@@ -85,8 +85,8 @@ public final class CsvSerializer extends WriterSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("CsvSerializer", new DefaultFilteringObjectMap());
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializerSession.java
index 15d9636..fb82eff 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializerSession.java
@@ -107,8 +107,8 @@ public final class CsvSerializerSession extends WriterSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("CsvSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
index 21b2cf2..f9a6066 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
@@ -844,8 +844,8 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlDocSerializer", new DefaultFilteringObjectMap()
 				.append("header", header)
 				.append("nav", nav)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
index b5aec3d..61cd251 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
@@ -258,8 +258,8 @@ public class HtmlDocSerializerSession extends HtmlStrippedDocSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlDocSerializerSession", new DefaultFilteringObjectMap()
 				.append("aside", aside)
 				.append("head", head)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
index d43ccff..c494179 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
@@ -96,8 +96,8 @@ public class HtmlParser extends XmlParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlParser", new DefaultFilteringObjectMap());
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
index 7ea3fbf..b5fe5ed 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
@@ -736,8 +736,8 @@ public final class HtmlParserSession extends XmlParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
index dcacbd4..b698200 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
@@ -109,8 +109,8 @@ public final class HtmlSchemaDocSerializer extends HtmlDocSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlSchemaDocSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
index 12f662d..b7a309b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
@@ -164,8 +164,8 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlSchemaSerializer", new DefaultFilteringObjectMap()
 				.append("generator", generator)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializerSession.java
index a379860..f77fe0a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializerSession.java
@@ -50,8 +50,8 @@ public class HtmlSchemaSerializerSession extends HtmlSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlSchemaSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index fd95024..6dc3015 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -802,8 +802,8 @@ public class HtmlSerializer extends XmlSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlSerializer", new DefaultFilteringObjectMap()
 				.append("uriAnchorText", uriAnchorText)
 				.append("detectLabelParameters", detectLabelParameters)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
index f8c9ad5..d7c96b7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
@@ -890,8 +890,8 @@ public class HtmlSerializerSession extends XmlSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
index 6aa7c71..01cb16b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
@@ -116,8 +116,8 @@ public class HtmlStrippedDocSerializer extends HtmlSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlStrippedDocSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializerSession.java
index 80a566a..b7f37f6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializerSession.java
@@ -56,8 +56,8 @@ public class HtmlStrippedDocSerializerSession extends HtmlSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("HtmlStrippedDocSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/SimpleMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/SimpleMap.java
index 699e0c5..aff114c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/SimpleMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/SimpleMap.java
@@ -15,13 +15,13 @@ package org.apache.juneau.internal;
 import static org.apache.juneau.internal.ArrayUtils.*;
 import static org.apache.juneau.internal.ThrowableUtils.*;
 
+import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
 
 /**
- * An instance of a <code>Map</code> where the keys and values are simple <code>String[]</code> and
- * <code>Object[]</code> arrays.
+ * An instance of a <code>Map</code> where the keys and values are simple arrays.
  *
  * <p>
  * Typically more efficient than <code>HashMaps</code> for small maps (e.g. &lt;10 entries).
@@ -31,12 +31,15 @@ import org.apache.juneau.*;
  *
  * <p>
  * Setting values overwrites the value on the underlying value array.
+ *
+ * @param <K> The key type.
+ * @param <V> The value type.
  */
-public final class SimpleMap extends AbstractMap<String,Object> {
+public final class SimpleMap<K,V> extends AbstractMap<K,V> {
 
-	final String[] keys;
-	final Object[] values;
-	final Map.Entry<String,Object>[] entries;
+	final K[] keys;
+	final V[] values;
+	final SimpleMapEntry[] entries;
 
 	/**
 	 * Constructor.
@@ -44,7 +47,8 @@ public final class SimpleMap extends AbstractMap<String,Object> {
 	 * @param keys The map keys.  Must not be <jk>null</jk>.
 	 * @param values The map values.  Must not be <jk>null</jk>.
 	 */
-	public SimpleMap(String[] keys, Object[] values) {
+	@SuppressWarnings("unchecked")
+	public SimpleMap(K[] keys, V[] values) {
 		assertFieldNotNull(keys, "keys");
 		assertFieldNotNull(values, "values");
 		if (keys.length != values.length)
@@ -52,7 +56,7 @@ public final class SimpleMap extends AbstractMap<String,Object> {
 
 		this.keys = keys;
 		this.values = values;
-		entries = new SimpleMapEntry[keys.length];
+		entries = (SimpleMapEntry[]) Array.newInstance(SimpleMapEntry.class, keys.length);
 		for (int i = 0; i < keys.length; i++) {
 			if (keys[i] == null)
 				illegalArg("Keys array cannot contain a null value.");
@@ -61,12 +65,12 @@ public final class SimpleMap extends AbstractMap<String,Object> {
 	}
 
 	@Override /* Map */
-	public Set<Map.Entry<String,Object>> entrySet() {
+	public Set<Map.Entry<K,V>> entrySet() {
 		return asSet(entries);
 	}
 
 	@Override /* Map */
-	public Object get(Object key) {
+	public V get(Object key) {
 		for (int i = 0; i < keys.length; i++)
 			if (keys[i].equals(key))
 				return values[i];
@@ -74,15 +78,15 @@ public final class SimpleMap extends AbstractMap<String,Object> {
 	}
 
 	@Override /* Map */
-	public Set<String> keySet() {
+	public Set<K> keySet() {
 		return asSet(keys);
 	}
 
 	@Override /* Map */
-	public Object put(String key, Object value) {
+	public V put(K key, V value) {
 		for (int i = 0; i < keys.length; i++) {
 			if (keys[i].equals(key)) {
-				Object v = values[i];
+				V v = values[i];
 				values[i] = value;
 				return v;
 			}
@@ -90,7 +94,7 @@ public final class SimpleMap extends AbstractMap<String,Object> {
 		throw new FormattedIllegalArgumentException("No key ''{0}'' defined in map", key);
 	}
 
-	final class SimpleMapEntry implements Map.Entry<String,Object> {
+	final class SimpleMapEntry implements Map.Entry<K,V> {
 
 		private int index;
 
@@ -99,18 +103,18 @@ public final class SimpleMap extends AbstractMap<String,Object> {
 		}
 
 		@Override /* Map.Entry */
-		public String getKey() {
+		public K getKey() {
 			return keys[index];
 		}
 
 		@Override /* Map.Entry */
-		public Object getValue() {
+		public V getValue() {
 			return values[index];
 		}
 
 		@Override /* Map.Entry */
-		public Object setValue(Object val) {
-			Object v = values[index];
+		public V setValue(V val) {
+			V v = values[index];
 			values[index] = val;
 			return v;
 		}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParser.java
index 9c8bf89..1f122c3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParser.java
@@ -90,8 +90,8 @@ public final class JsoParser extends InputStreamParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsoParser", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParserSession.java
index 245f25d..5a0eca8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoParserSession.java
@@ -48,8 +48,8 @@ public class JsoParserSession extends InputStreamParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsoParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
index 9c3261b..9c9094e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
@@ -92,8 +92,8 @@ public class JsoSerializer extends OutputStreamSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsoSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializerSession.java
index 04d8dd1..68d82f6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializerSession.java
@@ -54,8 +54,8 @@ public class JsoSerializerSession extends OutputStreamSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsoSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
index 0c4a99b..4469279 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
@@ -269,8 +269,8 @@ public class JsonParser extends ReaderParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsonParser", new DefaultFilteringObjectMap());
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
index 26c4bf3..ed24c11 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java
@@ -803,8 +803,8 @@ public final class JsonParserSession extends ReaderParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsonParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
index af72fe0..0b0c68b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
@@ -172,8 +172,8 @@ public class JsonSchemaSerializer extends JsonSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsonSchemaSerializer", new DefaultFilteringObjectMap()
 				.append("generator", generator)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java
index 3fcabd7..4ac53d1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializerSession.java
@@ -54,8 +54,8 @@ public class JsonSchemaSerializerSession extends JsonSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsonSchemaSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
index 4b751aa..004fc6c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -450,8 +450,8 @@ public class JsonSerializer extends WriterSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsonSerializer", new DefaultFilteringObjectMap()
 				.append("simpleMode", simpleMode)
 				.append("escapeSolidus", escapeSolidus)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
index 1923872..4debee8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
@@ -304,8 +304,8 @@ public class JsonSerializerSession extends WriterSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsonSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonSerializer.java
index f2af29a..b72d3d7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonSerializer.java
@@ -91,8 +91,8 @@ public class SimpleJsonSerializer extends JsonSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("SimpleJsonSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
index aadfe22..b780a48 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
@@ -456,8 +456,8 @@ public class JsonSchemaGenerator extends BeanTraverseContext {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsonSchemaGenerator", new DefaultFilteringObjectMap()
 				.append("useBeanDefs", useBeanDefs)
 				.append("allowNestedExamples", allowNestedExamples)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
index b054712..53d10a4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGeneratorSession.java
@@ -454,8 +454,8 @@ public class JsonSchemaGeneratorSession extends BeanTraverseSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("JsonSchemaGeneratorSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/Marshall.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/Marshall.java
index 5a23bc0..3f70a57 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/Marshall.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/Marshall.java
@@ -14,9 +14,11 @@ package org.apache.juneau.marshall;
 
 import java.io.*;
 import java.lang.reflect.*;
+import java.text.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.serializer.*;
 
 /**
@@ -154,6 +156,76 @@ public abstract class Marshall {
 	}
 
 	/**
+	 * Prints a message with arguments to {@link System#out}.
+	 *
+	 * <p>
+	 * Arguments are automatically converted to strings using this marshaller.
+	 *
+	 * <p>
+	 * Useful for debug messages.
+	 *
+	 * <h5 class='figure'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	SimpleJson.<jsf>DEFAULT</jsf>.out(<js>"myPojo={0}"</js>, myPojo);
+	 * </p>
+	 *
+	 * @param msg The {@link MessageFormat}-styled message.
+	 * @param args The arguments sent to the the formatter after running them through this marshaller.
+	 * @return This object (for method chaining).
+	 */
+	public final Marshall out(String msg, Object...args) {
+		System.out.println(format(msg, args));
+		return this;
+	}
+
+	/**
+	 * Prints a message with arguments to {@link System#err}.
+	 *
+	 * <p>
+	 * Arguments are automatically converted to strings using this marshaller.
+	 *
+	 * <p>
+	 * Useful for debug messages.
+	 *
+	 * <h5 class='figure'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	SimpleJson.<jsf>DEFAULT</jsf>.err(<js>"myPojo={0}"</js>, myPojo);
+	 * </p>
+	 *
+	 * @param msg The {@link MessageFormat}-styled message.
+	 * @param args The arguments sent to the the formatter after running them through this marshaller.
+	 * @return This object (for method chaining).
+	 */
+	public final Marshall err(String msg, Object...args) {
+		System.err.println(format(msg, args));
+		return this;
+	}
+
+	/**
+	 * Formats a message with arguments.
+	 *
+	 * <p>
+	 * Arguments are automatically converted to strings using this marshaller.
+	 *
+	 * <p>
+	 * Useful for debug messages.
+	 *
+	 * <h5 class='figure'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	String msg = SimpleJson.<jsf>DEFAULT</jsf>.format(<js>"myPojo={0}"</js>, myPojo);
+	 * </p>
+	 *
+	 * @param msg The {@link MessageFormat}-styled message.
+	 * @param args The arguments sent to the the formatter after running them through this marshaller.
+	 * @return This object (for method chaining).
+	 */
+	public final String format(String msg, Object...args) {
+		for (int i = 0; i < args.length; i++)
+			args[i] = toString(args[i]);
+		return MessageFormat.format(msg, args);
+	}
+
+	/**
 	 * Parses input into the specified object type.
 	 *
 	 * <p>
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
index 51b7704..adc2331 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
@@ -128,8 +128,8 @@ public class MsgPackParser extends InputStreamParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("MsgPackParser", new DefaultFilteringObjectMap());
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
index 226de99..83dca6b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
@@ -207,8 +207,8 @@ public final class MsgPackParserSession extends InputStreamParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("MsgPackParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index 6fc9026..916d673 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -170,8 +170,8 @@ public class MsgPackSerializer extends OutputStreamSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("MsgPackSerializer", new DefaultFilteringObjectMap()
 				.append("addBeanTypes", addBeanTypes)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
index 9bb5217..f347edb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
@@ -228,8 +228,8 @@ public final class MsgPackSerializerSession extends OutputStreamSerializerSessio
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("MsgPackSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
index 28d7423..ad22592 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
@@ -107,8 +107,8 @@ public class OpenApiParser extends UonParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("OpenApiParser", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParserSession.java
index ab3657a..fd9d227 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParserSession.java
@@ -233,8 +233,8 @@ public class OpenApiParserSession extends UonParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("OpenApiParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
index 17e1cee..1ae619a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
@@ -150,8 +150,8 @@ public class OpenApiSerializer extends UonSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("OpenApiSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializerSession.java
index f884eab..1374fe7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializerSession.java
@@ -310,8 +310,8 @@ public class OpenApiSerializerSession extends UonSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("OpenApiSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
index 919a068..39669e7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
@@ -122,8 +122,8 @@ public abstract class InputStreamParser extends Parser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("InputStreamParser", new DefaultFilteringObjectMap()
 				.append("binaryFormat", binaryFormat)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParserSession.java
index 722f458..de8c2d9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParserSession.java
@@ -98,8 +98,8 @@ public abstract class InputStreamParserSession extends ParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("InputStreamParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
index 10d4890..519d945 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
@@ -900,8 +900,8 @@ public abstract class Parser extends BeanContext {
 	//-----------------------------------------------------------------------------------------------------------------
 	
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("Parser", new DefaultFilteringObjectMap()
 				.append("autoCloseStreams", autoCloseStreams)
 				.append("debugOutputLines", debugOutputLines)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
index 572e2ff..5d69064 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -874,8 +874,8 @@ public abstract class ParserSession extends BeanSession {
 	}
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("ParserSession", new DefaultFilteringObjectMap()
 				.append("javaMethod", javaMethod)
 				.append("listener", listener)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSessionArgs.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSessionArgs.java
index 43a4281..7bf8444 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSessionArgs.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSessionArgs.java
@@ -163,8 +163,8 @@ public final class ParserSessionArgs extends BeanSessionArgs {
 	//-----------------------------------------------------------------------------------------------------------------
 	
 	@Override /* SessionArgs */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("ParserSessionArgs", new DefaultFilteringObjectMap()
 				.append("javaMethod", javaMethod)
 				.append("outer", outer)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
index c5f6765..143f7bd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
@@ -187,8 +187,8 @@ public abstract class ReaderParser extends Parser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("ReaderParser", new DefaultFilteringObjectMap()
 				.append("fileCharset", fileCharset)
 				.append("streamCharset", streamCharset)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java
index 84e93bb..e60f160 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java
@@ -117,8 +117,8 @@ public abstract class ReaderParserSession extends ParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("ReaderParserSession", new DefaultFilteringObjectMap()
 				.append("fileCharset", fileCharset)
 				.append("streamCharset", streamCharset)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
index 1ee5739..b28dc71 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
@@ -116,8 +116,8 @@ public class PlainTextParser extends ReaderParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("PlainTextParser", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParserSession.java
index 625693e..5d0dfd6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParserSession.java
@@ -49,8 +49,8 @@ public class PlainTextParserSession extends ReaderParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("PlainTextParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
index 7d4aa89..5da73f0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
@@ -132,8 +132,8 @@ public class PlainTextSerializer extends WriterSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("PlainTextSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerSession.java
index b5ade98..4c8affd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerSession.java
@@ -50,8 +50,8 @@ public class PlainTextSerializerSession extends WriterSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("PlainTextSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
index 9dbc744..45c1625 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
@@ -170,8 +170,8 @@ public abstract class OutputStreamSerializer extends Serializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("OutputStreamSerializer", new DefaultFilteringObjectMap()
 				.append("binaryFormat", binaryFormat)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializerSession.java
index aa481f8..cef7fc9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializerSession.java
@@ -114,8 +114,8 @@ public abstract class OutputStreamSerializerSession extends SerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("OutputStreamSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
index 2065b9e..4300b83 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
@@ -1031,8 +1031,8 @@ public abstract class Serializer extends BeanTraverseContext {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("Serializer", new DefaultFilteringObjectMap()
 				.append("addBeanTypes", addBeanTypes)
 				.append("trimNullProperties", trimNullProperties)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index d7ea61f..bc07143 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -766,8 +766,8 @@ public abstract class SerializerSession extends BeanTraverseSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("SerializerSession", new DefaultFilteringObjectMap()
 				.append("uriResolver", uriResolver)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSessionArgs.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSessionArgs.java
index 9d596b9..e9aa79a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSessionArgs.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSessionArgs.java
@@ -207,8 +207,8 @@ public final class SerializerSessionArgs extends BeanSessionArgs {
 	//-----------------------------------------------------------------------------------------------------------------
 	
 	@Override /* SessionArgs */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("SerializerSessionArgs", new DefaultFilteringObjectMap()
 				.append("javaMethod", javaMethod)
 				.append("resolver", resolver)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
index 054e5d1..35272bb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
@@ -426,8 +426,8 @@ public abstract class WriterSerializer extends Serializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("WriterSerializer", new DefaultFilteringObjectMap()
 				.append("fileCharset", fileCharset)
 				.append("maxIndent", maxIndent)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializerSession.java
index d32f968..7396a52 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializerSession.java
@@ -142,8 +142,8 @@ public abstract class WriterSerializerSession extends SerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("WriterSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
index 9752448..21d688a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
@@ -123,8 +123,8 @@ public final class SoapXmlSerializer extends XmlSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("SoapXmlSerializer", new DefaultFilteringObjectMap()
 				.append("soapAction", soapAction)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java
index 78a8ba6..b5404b0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializerSession.java
@@ -98,8 +98,8 @@ public class SoapXmlSerializerSession extends XmlSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("SoapXmlSerializerSession", new DefaultFilteringObjectMap()
 				.append("soapAction", soapAction)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
index 3585781..a5905b6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
@@ -290,8 +290,8 @@ public class UonParser extends ReaderParser implements HttpPartParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("UonParser", new DefaultFilteringObjectMap()
 				.append("decoding", decoding)
 				.append("validateEnd", validateEnd)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
index ad4df33..1c12bc8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java
@@ -862,8 +862,8 @@ public class UonParserSession extends ReaderParserSession implements HttpPartPar
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("UonParserSession", new DefaultFilteringObjectMap()
 				.append("decoding", decoding)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
index 1714053..7370ceb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
@@ -456,8 +456,8 @@ public class UonSerializer extends WriterSerializer implements HttpPartSerialize
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("UonSerializer", new DefaultFilteringObjectMap()
 				.append("encoding", encoding)
 				.append("addBeanTypes", addBeanTypes)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
index 15f2099..fee378e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
@@ -331,8 +331,8 @@ public class UonSerializerSession extends WriterSerializerSession implements Htt
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("UonSerializerSession", new DefaultFilteringObjectMap()
 		);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index cb6709e..22c6bb6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -184,8 +184,8 @@ public class UrlEncodingParser extends UonParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("UrlEncodingParser", new DefaultFilteringObjectMap()
 				.append("expandedParams", expandedParams)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
index 7d4376c..7bf4663 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
@@ -372,8 +372,8 @@ public class UrlEncodingParserSession extends UonParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("UrlEncodingParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index ec22227..34cacc1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -355,8 +355,8 @@ public class UrlEncodingSerializer extends UonSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("UrlEncodingSerializer", new DefaultFilteringObjectMap()
 				.append("expandedParams", expandedParams)
 			);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
index 7021833..2aea25a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
@@ -279,8 +279,8 @@ public class UrlEncodingSerializerSession extends UonSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("UrlEncodingSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
index 3c27f92..2b0426f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
@@ -77,8 +77,8 @@ public class XmlDocSerializer extends XmlSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlDocSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializerSession.java
index 9bcd12a..aef59cd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializerSession.java
@@ -57,8 +57,8 @@ public class XmlDocSerializerSession extends XmlSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlDocSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
index 63f5d14..52a69ae 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -322,8 +322,8 @@ public class XmlParser extends ReaderParser {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlParser", new DefaultFilteringObjectMap()
 				.append("validating", validating)
 				.append("preserveRootElement", preserveRootElement)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
index 3a9ee7e..9d1a935 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
@@ -740,8 +740,8 @@ public class XmlParserSession extends ReaderParserSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlParserSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index e899939..106b09e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -642,8 +642,8 @@ public class XmlSerializer extends WriterSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlSerializer", new DefaultFilteringObjectMap()
 				.append("autoDetectNamespaces", autoDetectNamespaces)
 				.append("enableNamespaces", enableNamespaces)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
index 36bdfde..1752ce5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
@@ -821,8 +821,8 @@ public class XmlSerializerSession extends WriterSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaDocSerializer.java
index 376b9b6..75037a9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaDocSerializer.java
@@ -67,8 +67,8 @@ public class XmlSchemaDocSerializer extends XmlSchemaSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlSchemaDocSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializer.java
index 7481c14..2866450 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializer.java
@@ -69,8 +69,8 @@ public class XmlSchemaSerializer extends XmlSerializer {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlSchemaSerializer", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializerSession.java
index 9deff0c..ef9439a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializerSession.java
@@ -570,8 +570,8 @@ public class XmlSchemaSerializerSession extends XmlSerializerSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("XmlSchemaSerializerSession", new DefaultFilteringObjectMap()
 			);
 	}
diff --git a/juneau-doc/docs/ReleaseNotes/8.0.1.html b/juneau-doc/docs/ReleaseNotes/8.0.1.html
index a10f756..2c56f7e 100644
--- a/juneau-doc/docs/ReleaseNotes/8.0.1.html
+++ b/juneau-doc/docs/ReleaseNotes/8.0.1.html
@@ -31,6 +31,29 @@
 			<li class='jf'>{@link oaj.serializer.WriterSerializer#WSERIALIZER_fileCharset}
 			<li class='jf'>{@link oaj.serializer.WriterSerializer#WSERIALIZER_streamCharset}
 		</ul>
+	<li>
+		The following POJO methods can be used to convert a POJO to/from a Map before serialization and after parsing.
+		<br>It's a convenient way of defining a POJO transform.
+		<ul class='doctree'>
+			<li class='jm'><code><jk>public</jk> Map toMap()</code> -  Can be any type of map with string keys and object vals. 
+			<li class='jm'><code><jk>public</jk> ObjectMap toMap()</code>
+			<li class='jm'><code><jk>public</jk> Map toMap(BeanSession bs)</code> -  Can be any type of map with string keys and object vals. 
+			<li class='jm'><code><jk>public</jk> ObjectMap toMap(BeanSession bs)</code>
+			<li class='jm'><code><jk>public static</jk> T fromMap(Map m)</code> -  Can be any type of map with string keys and object vals. 
+			<li class='jm'><code><jk>public static</jk> T fromMap(ObjectMap m)</code>
+			<li class='jm'><code><jk>public static</jk> T fromMap(BeanSession bs, Map m)</code> -  Can be any type of map with string keys and object vals. 
+			<li class='jm'><code><jk>public static</jk> T fromMap(BeanSession bs, ObjectMap m)</code>
+		</ul>
+	<li>
+		New convenience debugging methods on Marshall API:
+		<ul class='doctree'>
+			<li class='jc'>{@link oaj.marshall.Marshall}
+			<ul>
+				<li class='jm'>{@link oaj.marshall.Marshall#format(String,Object...)} - <code>MessageFormat</code>-style formatter.
+				<li class='jm'>{@link oaj.marshall.Marshall#out(String,Object...)} - Prints <code>MessageFormat</code>-style messages to STDOUT.
+				<li class='jm'>{@link oaj.marshall.Marshall#err(String,Object...)} - Prints <code>MessageFormat</code>-style messages to STDERR.
+			</ul>
+		</ul>
 </ul>
 
 <h5 class='topic w800'>juneau-config</h5>
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/11.Transforms/06.SwapMethods.html b/juneau-doc/docs/Topics/02.juneau-marshall/11.Transforms/06.SwapMethods.html
index 8e8af01..79d014e 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/11.Transforms/06.SwapMethods.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/11.Transforms/06.SwapMethods.html
@@ -13,7 +13,7 @@
  ***************************************************************************************************************************/
  -->
 
-Swap Methods
+{updated} Swap Methods
 
 <p>
 	Various methods can be defined on a class directly to affect how it gets serialized.
@@ -62,8 +62,23 @@ Swap Methods
 	class:
 </p>			
 <ul>
-	<li><code><jk>public</jk> X swap(BeanSession)</code> method, where <code>X</code> is any serializable 
-	object.
+	<li><code><jk>public</jk> X swap()</code> method, where <code>X</code> is any serializable object.
+	<li><code><jk>public</jk> X swap(BeanSession)</code> method, where <code>X</code> is any serializable object.
+	<li><code><jk>public static</jk> MyPojo unswap(X)</code> method, where <code>X</code> is any serializable object.
+	<li><code><jk>public static</jk> MyPojo swap(X,BeanSession)</code> method, where <code>X</code> is any serializable object.
+</ul>
+<p>
+	Serializing to and from Maps can be accomplished by defining any of the following methods:
+</p>			
+<ul>
+	<li><code><jk>public</jk> Map toMap()</code> method.  Can be any type of map with string keys and object vals. 
+	<li><code><jk>public</jk> ObjectMap toMap()</code> method. 
+	<li><code><jk>public</jk> Map toMap(BeanSession)</code> method.  Can be any type of map with string keys and object vals. 
+	<li><code><jk>public</jk> ObjectMap toMap(BeanSession)</code> method.
+	<li><code><jk>public static</jk> MyPojo fromMap(Map)</code> method.  Can be any type of map with string keys and object vals. 
+	<li><code><jk>public static</jk> MyPojo fromMap(ObjectMap)</code> method.
+	<li><code><jk>public static</jk> MyPojo fromMap(Map,BeanSession)</code> method.  Can be any type of map with string keys and object vals. 
+	<li><code><jk>public static</jk> MyPojo fromMap(ObjectMap,BeanSession)</code> method.
 </ul>
 <p>
 	The <code>BeanSession</code> parameter allows you access to various information about the current 
diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
index 19043a3..afd44d8 100755
--- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
+++ b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
@@ -61,7 +61,7 @@ public class ConfigResource extends BasicRestServlet {
 		)
 	)
 	public ObjectMap getConfig() {
-		return getServletConfig().getConfig().asMap();
+		return getServletConfig().getConfig().toMap();
 	}
 
 	@RestMethod(
@@ -155,7 +155,7 @@ public class ConfigResource extends BasicRestServlet {
 			@Body(description="New contents in INI file format.") Reader contents
 		) throws Exception {
 
-		return getServletConfig().getConfig().load(contents, true).asMap();
+		return getServletConfig().getConfig().load(contents, true).toMap();
 	}
 
 	@RestMethod(
diff --git a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/ConfigResource.java b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/ConfigResource.java
index 3fd2d6d..6b9ee59 100644
--- a/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/ConfigResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/test/java/org/apache/juneau/rest/test/ConfigResource.java
@@ -29,7 +29,7 @@ public class ConfigResource extends BasicRestServlet {
 
 	@RestMethod(name=GET, path="/")
 	public Object test1(RestRequest req) {
-		return req.getConfig().asMap();
+		return req.getConfig().toMap();
 	}
 
 	@RestMethod(name=GET, path="/{key}/{class}")
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
index 04bca4d..6269b72 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
@@ -2501,8 +2501,8 @@ public final class RestCall extends BeanSession implements Closeable {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("RestCall", new DefaultFilteringObjectMap()
 				.append("allowRedirectsOnPosts", allowRedirectsOnPosts)
 				.append("byLines", byLines)
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index cf66147..e324916 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -1417,8 +1417,8 @@ public class RestClient extends BeanContext implements Closeable {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("RestClient", new DefaultFilteringObjectMap()
 				.append("debug", debug)
 				.append("executorService", executorService)
diff --git a/juneau-rest/juneau-rest-server-test/src/test/java/org/apache/juneau/rest/util/UrlPathPatternTest.java b/juneau-rest/juneau-rest-server-test/src/test/java/org/apache/juneau/rest/util/UrlPathPatternTest.java
index 93f240d..014b813 100644
--- a/juneau-rest/juneau-rest-server-test/src/test/java/org/apache/juneau/rest/util/UrlPathPatternTest.java
+++ b/juneau-rest/juneau-rest-server-test/src/test/java/org/apache/juneau/rest/util/UrlPathPatternTest.java
@@ -12,7 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest.util;
 
-import static org.junit.Assert.*;
+import static org.apache.juneau.testutils.TestUtils.*;
+import static org.junit.Assert.assertEquals;
 
 import java.util.*;
 
@@ -26,10 +27,27 @@ import org.junit.runners.*;
 @SuppressWarnings({"javadoc"})
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class UrlPathPatternTest {
+
+	private void shouldMatch(UrlPathPattern p, String path, String expected) {
+		assertObjectEquals(expected, p.match(path));
+	}
+
+	private void shouldNotMatch(UrlPathPattern p, String path) {
+		assertObjectEquals("null", p.match(path));
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Comparison
+	//------------------------------------------------------------------------------------------------------------------
+
 	@Test
-	public void testComparison() throws Exception {
+	public void a01_comparision() throws Exception {
 		List<UrlPathPattern> l = new LinkedList<>();
 
+		l.add(new UrlPathPattern(""));
+		l.add(new UrlPathPattern("*"));
+		l.add(new UrlPathPattern("/"));
+		l.add(new UrlPathPattern("/*"));
 		l.add(new UrlPathPattern("/foo"));
 		l.add(new UrlPathPattern("/foo/*"));
 		l.add(new UrlPathPattern("/foo/bar"));
@@ -40,6 +58,336 @@ public class UrlPathPatternTest {
 		l.add(new UrlPathPattern("/foo/{id}/bar/*"));
 
 		Collections.sort(l);
-		assertEquals("[{patternString:'/foo/bar',vars:[]},{patternString:'/foo/bar/*',vars:[]},{patternString:'/foo/{id}/bar',vars:['id']},{patternString:'/foo/{id}/bar/*',vars:['id']},{patternString:'/foo/{id}',vars:['id']},{patternString:'/foo/{id}/*',vars:['id']},{patternString:'/foo',vars:[]},{patternString:'/foo/*',vars:[]}]", SimpleJsonSerializer.DEFAULT.builder().sortProperties().build().serialize(l));
+		assertEquals("['/foo/bar','/foo/bar/*','/foo/{id}/bar','/foo/{id}/bar/*','/foo/{id}','/foo/{id}/*','/foo','/foo/*','/','/*','','*']", SimpleJsonSerializer.DEFAULT.toString(l));
+	}
+
+	@Test
+	public void a02_comparision() throws Exception {
+		List<UrlPathPattern> l = new LinkedList<>();
+
+		l.add(new UrlPathPattern("/foo/{id}/bar/*"));
+		l.add(new UrlPathPattern("/foo/{id}/bar"));
+		l.add(new UrlPathPattern("/foo/{id}/*"));
+		l.add(new UrlPathPattern("/foo/{id}"));
+		l.add(new UrlPathPattern("/foo/bar/*"));
+		l.add(new UrlPathPattern("/foo/bar"));
+		l.add(new UrlPathPattern("/foo/*"));
+		l.add(new UrlPathPattern("/foo"));
+		l.add(new UrlPathPattern("/*"));
+		l.add(new UrlPathPattern("/"));
+		l.add(new UrlPathPattern("*"));
+		l.add(new UrlPathPattern(""));
+
+		Collections.sort(l);
+		assertEquals("['/foo/bar','/foo/bar/*','/foo/{id}/bar','/foo/{id}/bar/*','/foo/{id}','/foo/{id}/*','/foo','/foo/*','/','/*','','*']", SimpleJsonSerializer.DEFAULT.toString(l));
+	}
+
+	@Test
+	public void a03_comparision() throws Exception {
+		List<UrlPathPattern> l = new LinkedList<>();
+
+		l.add(new UrlPathPattern("/foo"));
+		l.add(new UrlPathPattern("/foo"));
+
+		Collections.sort(l);
+		assertEquals("['/foo','/foo']", SimpleJsonSerializer.DEFAULT.toString(l));
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Simple pattern matching
+	//------------------------------------------------------------------------------------------------------------------
+
+	@Test
+	public void b01_simple_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo");
+		shouldMatch(p, "/foo", "{}");
+		shouldMatch(p, "/foo/", "{r:''}");
+	}
+
+	@Test
+	public void b02_simple_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo");
+		shouldNotMatch(p, "/fooo");
+		shouldNotMatch(p, "/fo");
+		shouldNotMatch(p, "/fooo/");
+		shouldNotMatch(p, "/");
+		shouldNotMatch(p, "/foo/bar");
+	}
+
+	@Test
+	public void b03_simple_match_2parts() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/bar");
+		shouldMatch(p, "/foo/bar", "{}");
+		shouldMatch(p, "foo/bar/", "{r:''}");
+	}
+
+	@Test
+	public void b04_simple_noMatch_2parts() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/bar");
+		shouldNotMatch(p, "/foo");
+		shouldNotMatch(p, "/foo/baz");
+		shouldNotMatch(p, "/foo/barr");
+		shouldNotMatch(p, "/foo/bar/baz");
+	}
+
+	@Test
+	public void b05_simple_match_0parts() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/");
+		shouldMatch(p, "/", "{r:''}");
+		shouldMatch(p, "", "{}");
+	}
+
+	@Test
+	public void b06_simple_noMatch_0parts() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/");
+		shouldNotMatch(p, "/foo");
+		shouldNotMatch(p, "/foo/bar");
+	}
+
+	@Test
+	public void b07_simple_match_blank() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("");
+		shouldMatch(p, "/", "{r:''}");
+		shouldMatch(p, "", "{}");
+	}
+
+	@Test
+	public void b08_simple_noMatch_blank() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("");
+		shouldNotMatch(p, "/foo");
+		shouldNotMatch(p, "/foo/bar");
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Simple pattern matching with remainder
+	//------------------------------------------------------------------------------------------------------------------
+
+	@Test
+	public void c01_simple_withRemainder_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/*");
+		shouldMatch(p, "/foo", "{}");
+		shouldMatch(p, "/foo/", "{r:''}");
+		shouldMatch(p, "/foo/bar", "{r:'bar'}");
+		shouldMatch(p, "/foo/bar/", "{r:'bar/'}");
+		shouldMatch(p, "/foo/bar/baz", "{r:'bar/baz'}");
+	}
+
+	@Test
+	public void c02_simple_withRemainder_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/*");
+		shouldNotMatch(p, "/fooo");
+		shouldNotMatch(p, "/fo");
+		shouldNotMatch(p, "/fooo/");
+		shouldNotMatch(p, "/");
+		shouldNotMatch(p, "/fooo/bar");
+	}
+
+	@Test
+	public void c03_simple_withRemainder_match_2parts() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/bar/*");
+		shouldMatch(p, "/foo/bar", "{}");
+		shouldMatch(p, "foo/bar/", "{r:''}");
+		shouldMatch(p, "/foo/bar/baz", "{r:'baz'}");
+		shouldMatch(p, "/foo/bar/baz/", "{r:'baz/'}");
+	}
+
+	@Test
+	public void c04_simple_withRemainder_noMatch_2parts() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/bar/*");
+		shouldNotMatch(p, "/");
+		shouldNotMatch(p, "/foo");
+		shouldNotMatch(p, "/foo/baz");
+		shouldNotMatch(p, "/foo/barr");
+		shouldNotMatch(p, "/foo/barr/");
+	}
+
+	@Test
+	public void c05_simple_withRemainder_match_0parts() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/*");
+		shouldMatch(p, "/", "{r:''}");
+		shouldMatch(p, "/foo", "{r:'foo'}");
+		shouldMatch(p, "/foo/bar", "{r:'foo/bar'}");
+	}
+
+	@Test
+	public void c06_simple_withRemainder_match_blank() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("*");
+		shouldMatch(p, "/", "{r:''}");
+		shouldMatch(p, "/foo", "{r:'foo'}");
+		shouldMatch(p, "/foo/bar", "{r:'foo/bar'}");
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Pattern with variables
+	//------------------------------------------------------------------------------------------------------------------
+
+	@Test
+	public void d01_1part1vars_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/{foo}");
+		shouldMatch(p, "/bar", "{v:{foo:'bar'}}");
+		shouldMatch(p, "/bar/", "{v:{foo:'bar'},r:''}");
+	}
+
+	@Test
+	public void d02_1part1var_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/{foo}");
+		shouldNotMatch(p, "/foo/bar");
+		shouldNotMatch(p, "/");
+	}
+
+	@Test
+	public void d03_2parts1var_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/{bar}");
+		shouldMatch(p, "/foo/baz", "{v:{bar:'baz'}}");
+		shouldMatch(p, "/foo/baz/", "{v:{bar:'baz'},r:''}");
+	}
+
+	@Test
+	public void d04_2parts1var_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/{bar}");
+		shouldNotMatch(p, "/fooo/baz");
+		shouldNotMatch(p, "/fo/baz");
+		shouldNotMatch(p, "/foo");
+		shouldNotMatch(p, "/");
+	}
+
+	@Test
+	public void d05_3vars_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/{a}/{b}/{c}");
+		shouldMatch(p, "/A/B/C", "{v:{a:'A',b:'B',c:'C'}}");
+		shouldMatch(p, "/A/B/C/", "{v:{a:'A',b:'B',c:'C'},r:''}");
+	}
+
+	@Test
+	public void d06_3vars_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/{a}/{b}/{c}");
+		shouldNotMatch(p, "/A/B");
+		shouldNotMatch(p, "/A/B/C/D");
+		shouldNotMatch(p, "/");
+	}
+
+	@Test
+	public void d07_7parts3vars_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/a/{a}/b/{b}/c/{c}/d");
+		shouldMatch(p, "/a/A/b/B/c/C/d", "{v:{a:'A',b:'B',c:'C'}}");
+		shouldMatch(p, "/a/A/b/B/c/C/d/", "{v:{a:'A',b:'B',c:'C'},r:''}");
+	}
+
+	@Test
+	public void d08_6parts3vars_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/a/{a}/b/{b}/c/{c}/d");
+		shouldNotMatch(p, "/a/A/a/B/c/C/d");
+		shouldNotMatch(p, "/a/A/b/B/c/C/dd");
+		shouldNotMatch(p, "/a/b/c/d");
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Pattern with variables and remainder
+	//------------------------------------------------------------------------------------------------------------------
+
+	@Test
+	public void e01_1part1vars_withRemainder_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/{foo}/*");
+		shouldMatch(p, "/bar", "{v:{foo:'bar'}}");
+		shouldMatch(p, "/bar/", "{v:{foo:'bar'},r:''}");
+		shouldMatch(p, "/bar/baz", "{v:{foo:'bar'},r:'baz'}");
+		shouldMatch(p, "/bar/baz/qux", "{v:{foo:'bar'},r:'baz/qux'}");
+	}
+
+	@Test
+	public void e02_1part1var_withRemainder_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/{foo}/*");
+		shouldNotMatch(p, "/");
+	}
+
+	@Test
+	public void e03_2parts1var_withRemainder_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/{bar}/*");
+		shouldMatch(p, "/foo/baz", "{v:{bar:'baz'}}");
+		shouldMatch(p, "/foo/baz/", "{v:{bar:'baz'},r:''}");
+		shouldMatch(p, "/foo/baz/qux/", "{v:{bar:'baz'},r:'qux/'}");
+	}
+
+	@Test
+	public void e04_2parts1var_withRemainder_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/{bar}/*");
+		shouldNotMatch(p, "/fooo/baz");
+		shouldNotMatch(p, "/fo/baz");
+		shouldNotMatch(p, "/foo");
+		shouldNotMatch(p, "/");
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Pattern with inner meta
+	//------------------------------------------------------------------------------------------------------------------
+
+	@Test
+	public void f01_innerMeta_withRemainder_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/*/*");
+		shouldMatch(p, "/bar", "{}");
+		shouldMatch(p, "/bar/", "{r:''}");
+		shouldMatch(p, "/bar/baz", "{r:'baz'}");
+		shouldMatch(p, "/bar/baz/qux", "{r:'baz/qux'}");
+	}
+
+	@Test
+	public void f02_innerMeta_withRemainder_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/*/*");
+		shouldNotMatch(p, "/");
+	}
+
+	@Test
+	public void f03_innerMeta_withRemainder_match() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/*/bar/*");
+		shouldMatch(p, "/foo/baz/bar", "{}");
+		shouldMatch(p, "/foo/baz/bar/", "{r:''}");
+		shouldMatch(p, "/foo/baz/bar/qux/", "{r:'qux/'}");
+	}
+
+	@Test
+	public void f04_innerMeta_withRemainder_noMatch() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/*/bar/*");
+		shouldNotMatch(p, "/fooo/baz/bar");
+		shouldNotMatch(p, "/fo/baz/bar");
+		shouldNotMatch(p, "/foo/bar");
+		shouldNotMatch(p, "/");
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Paths with encoded vars
+	//------------------------------------------------------------------------------------------------------------------
+
+	@Test
+	public void g01_encodedVars() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/{bar}/*");
+		shouldMatch(p, "/foo/baz%2Fqux", "{v:{bar:'baz/qux'}}");
+		shouldMatch(p, "/foo/baz+qux", "{v:{bar:'baz qux'}}");
+		shouldMatch(p, "/foo/baz%2Fqux/quux%2Fquuux", "{v:{bar:'baz/qux'},r:'quux%2Fquuux'}");
+		shouldMatch(p, "/foo/baz+qux/quux+quuux", "{v:{bar:'baz qux'},r:'quux+quuux'}");
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Paths with not vars
+	//------------------------------------------------------------------------------------------------------------------
+
+	@Test
+	public void h01_notVars() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/{bar/*");
+		shouldMatch(p, "/foo/{bar", "{}");
+		shouldMatch(p, "/foo/{bar/{baz", "{r:'{baz'}");
+	}
+
+	@Test
+	public void h02_notVars() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/bar}/*");
+		shouldMatch(p, "/foo/bar}", "{}");
+		shouldMatch(p, "/foo/bar}/baz}", "{r:'baz}'}");
+	}
+
+	@Test
+	public void h03_notVars() throws Exception {
+		UrlPathPattern p = new UrlPathPattern("/foo/x{bar}x/*");
+		shouldMatch(p, "/foo/x{bar}x", "{}");
+		shouldMatch(p, "/foo/x{bar}x/x{baz}x", "{r:'x{baz}x'}");
 	}
 }
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
index 51d720b..1a591d1 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
@@ -115,6 +115,28 @@ public class BasicRestCallHandler implements RestCallHandler {
 
 			// If this resource has child resources, try to recursively call them.
 			if (pathInfo != null && context.hasChildResources() && (! pathInfo.equals("/"))) {
+//				for (Map.Entry<UrlPathPattern,RestContext> e : context.getChildResources().entrySet()) {
+//					UrlPathPattern upp = e.getKey();
+//					String[] vars = upp.match(pathInfo);
+//					if (vars != null) {
+//						for (int i = 0; i < vars.length; i++)
+//							r1.setAttribute(upp.getVars()[i], vars[i]);
+//						final String pathInfoRemainder = upp.(i == -1 ? null : pathInfo.substring(i));
+//						final String servletPath = r1.getServletPath() + "/" + pathInfoPart;
+//						final HttpServletRequest childRequest = new HttpServletRequestWrapper(r1) {
+//							@Override /* ServletRequest */
+//							public String getPathInfo() {
+//								return urlDecode(pathInfoRemainder);
+//							}
+//							@Override /* ServletRequest */
+//							public String getServletPath() {
+//								return servletPath;
+//							}
+//						};
+//						childResource.getCallHandler().service(childRequest, r2);
+//						return;
+//					}
+//				}
 				int i = pathInfo.indexOf('/', 1);
 				String pathInfoPart = i == -1 ? pathInfo.substring(1) : pathInfo.substring(1, i);
 				RestContext childResource = context.getChildResource(pathInfoPart);
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestPath.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestPath.java
index c3ff2e3..44e5d7c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestPath.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestPath.java
@@ -39,7 +39,6 @@ public class RequestPath extends TreeMap<String,String> {
 
 	private final RestRequest req;
 	private HttpPartParser parser;
-	private String pattern;
 
 	RequestPath(RestRequest req) {
 		super(String.CASE_INSENSITIVE_ORDER);
@@ -57,11 +56,6 @@ public class RequestPath extends TreeMap<String,String> {
 		return this;
 	}
 
-	RequestPath pattern(String pattern) {
-		this.pattern = pattern;
-		return this;
-	}
-
 	/**
 	 * Sets a request query parameter value.
 	 *
@@ -350,15 +344,6 @@ public class RequestPath extends TreeMap<String,String> {
 		return get("/**");
 	}
 
-	/**
-	 * Returns the path pattern that matched this request.
-	 *
-	 * @return The path pattern that matched this request.
-	 */
-	public String getPattern() {
-		return pattern;
-	}
-
 	//-----------------------------------------------------------------------------------------------------------------
 	// Helper methods
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
index 7d7d201..586bf4b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestChild.java
@@ -37,6 +37,7 @@ package org.apache.juneau.rest;
  */
 public class RestChild {
 
+	// final UrlPathPattern path;
 	final String path;
 	final Object resource;
 
@@ -49,7 +50,7 @@ public class RestChild {
 	 * 	<br>Can either be a Class (which will be instantiated using the registered {@link RestResourceResolver})
 	 * 	or an already-instantiated object.
 	 */
-	public RestChild(String path, Object resource) {
+	public RestChild(/*UrlPathPattern path, */ String path, Object resource) {
 		this.path = path;
 		this.resource = resource;
 	}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 6d7dac4..03b805c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -4969,8 +4969,8 @@ public final class RestContext extends BeanContext {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("RestContext", new DefaultFilteringObjectMap()
 				.append("allowBodyParam", allowBodyParam)
 				.append("allowedMethodParams", allowedMethodParams)
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
index 75a2b8d..e0a1425 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodContext.java
@@ -740,16 +740,14 @@ public class RestMethodContext extends BeanContext implements Comparable<RestMet
 	 */
 	int invoke(String pathInfo, RestRequest req, RestResponse res) throws Throwable {
 
-		String[] patternVals = pathPattern.match(pathInfo);
-		if (patternVals == null)
+		UrlPathPatternMatch pm = pathPattern.match(pathInfo);
+		if (pm == null)
 			return SC_NOT_FOUND;
 
-		String remainder = null;
-		if (patternVals.length > pathPattern.getVars().length)
-			remainder = patternVals[pathPattern.getVars().length];
-		for (int i = 0; i < pathPattern.getVars().length; i++)
-			req.getPathMatch().put(pathPattern.getVars()[i], patternVals[i]);
-		req.getPathMatch().pattern(pathPattern.getPatternString()).remainder(remainder);
+		RequestPath rp = req.getPathMatch();
+		for (Map.Entry<String,String> e : pm.getVars().entrySet())
+			rp.put(e.getKey(), e.getValue());
+		rp.remainder(pm.getRemainder());
 
 		@SuppressWarnings("deprecation")
 		RequestProperties requestProperties = new RequestProperties(req.getVarResolverSession(), properties);
@@ -834,11 +832,6 @@ public class RestMethodContext extends BeanContext implements Comparable<RestMet
 		return SC_OK;
 	}
 
-	@Override /* Object */
-	public String toString() {
-		return "SimpleMethod: name=" + httpMethod + ", path=" + pathPattern.getPatternString();
-	}
-
 	/*
 	 * compareTo() method is used to keep SimpleMethods ordered in the RestCallRouter list.
 	 * It maintains the order in which matches are made during requests.
@@ -948,8 +941,8 @@ public class RestMethodContext extends BeanContext implements Comparable<RestMet
 	//-----------------------------------------------------------------------------------------------------------------
 
 	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
+	public ObjectMap toMap() {
+		return super.toMap()
 			.append("RestMethodContext", new DefaultFilteringObjectMap()
 				.append("defaultFormData", defaultFormData)
 				.append("defaultQuery", defaultQuery)
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathParts.java
similarity index 55%
copy from juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathParts.java
index 14567b9..4ca7a15 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/config/ConfigBuilderTest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathParts.java
@@ -1,60 +1,76 @@
-// ***************************************************************************************************************************
-// * 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.config;
-
-import static org.apache.juneau.internal.FileUtils.*;
-import static org.apache.juneau.internal.StringUtils.*;
-import static org.apache.juneau.testutils.TestUtils.*;
-import static org.junit.Assert.*;
-
-import java.io.*;
-
-import org.apache.juneau.config.store.*;
-import org.junit.*;
-
-public class ConfigBuilderTest {
-
-	private static File tempDir;
-	private static String TEMP_DIR;
-
-	@BeforeClass
-	public static void setup() {
-		tempDir = new File(System.getProperty("java.io.tmpdir"), generateUUID(12));
-		TEMP_DIR = tempDir.getAbsolutePath();
-	}
-
-	@AfterClass
-	public static void teardown() {
-		delete(tempDir);
-	}
-
-	@Test
-	public void testGet_LONGRUNNING() throws Exception {
-		File f;
-		ConfigFileStore cfs = ConfigFileStore.create().directory(TEMP_DIR).useWatcher().watcherSensitivity(WatcherSensitivity.HIGH).build();
-		ConfigBuilder cb = Config.create().store(cfs).name("TestGet.cfg");
-
-		Config cf = cb.build();
-		cf.set("Test/A", "a");
-
-		f = new File(tempDir, "TestGet.cfg");
-		assertFalse(f.exists());
-
-		cf.commit();
-		assertObjectEquals("{'':{},Test:{A:'a'}}", cf.asMap());
-
-		String NL = System.getProperty("line.separator");
-		cf = cf.load("[Test]"+NL+"A = b"+NL, true);
-		assertObjectEquals("{'':{},Test:{A:'b'}}", cf.asMap());
-	}
-}
\ No newline at end of file
+// ***************************************************************************************************************************
+// * 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.rest.util;
+
+import static org.apache.juneau.internal.StringUtils.*;
+
+/**
+ * Represents a parsed URL path.
+ */
+public class UrlPathParts {
+
+	final String[] parts;
+	final String raw;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param path The path.
+	 */
+	public UrlPathParts(String path) {
+		path = emptyIfNull(path);
+		raw = path;
+		if (path.length() > 0 && path.charAt(0) == '/')
+			path = path.substring(1);
+		parts = split(path, '/');
+		for (int i = 0; i < parts.length; i++)
+			parts[i] = urlDecode(parts[i]);
+	}
+
+	/**
+	 * Returns the path parts.
+	 *
+	 * @return The path parts.
+	 */
+	public String[] getParts() {
+		return parts;
+	}
+
+	/**
+	 * Returns a path remainder given the specified number of prefix parts.
+	 *
+	 * @param i The number of prefix parts to discard.
+	 * @return The remainder.
+	 */
+	public String getRemainder(int i) {
+		String s = raw;
+		if (s.length() > 0 && s.charAt(0) == '/')
+			s = s.substring(1);
+		for (int j = 0; j < s.length(); j++) {
+			if (i == 0)
+				return s.substring(j);
+			if (i > 0 && s.charAt(j) == '/')
+				i--;
+		}
+		return isTrailingSlash() ? "" : null;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this path ends with a slash.
+	 *
+	 * @return <jk>true</jk> if this path ends with a slash.
+	 */
+	public boolean isTrailingSlash() {
+		return raw.endsWith("/");
+	}
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathPattern.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathPattern.java
index 073bef7..3507136 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathPattern.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathPattern.java
@@ -12,11 +12,10 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest.util;
 
-import static org.apache.juneau.internal.StringUtils.*;
-
 import java.util.*;
 import java.util.regex.*;
 
+import org.apache.juneau.annotation.*;
 import org.apache.juneau.rest.annotation.*;
 
 /**
@@ -25,12 +24,14 @@ import org.apache.juneau.rest.annotation.*;
  * <p>
  * Handles aspects of matching and precedence ordering.
  */
+@BeanIgnore
 public final class UrlPathPattern implements Comparable<UrlPathPattern> {
 
-	private final Pattern pattern;
-	private final String patternString;
-	private final boolean isOnlyDotAll, isDotAll;
-	private final String[] vars;
+	private static final Pattern VAR_PATTERN = Pattern.compile("\\{([^\\}]+)\\}");
+
+	private final String pattern, comparator;
+	private final String[] parts, vars, varKeys;
+	private final boolean hasRemainder;
 
 	/**
 	 * Constructor.
@@ -38,39 +39,34 @@ public final class UrlPathPattern implements Comparable<UrlPathPattern> {
 	 * @param patternString The raw pattern string from the {@link RestMethod#path() @RestMethod(path)} annotation.
 	 */
 	public UrlPathPattern(String patternString) {
-		this.patternString = patternString;
-		Builder b = new Builder(patternString);
-		pattern = b.pattern;
-		isDotAll = b.isDotAll;
-		isOnlyDotAll = b.isOnlyDotAll;
-		vars = b.vars.toArray(new String[b.vars.size()]);
-	}
+		this.pattern = patternString;
+
+		String c = patternString.replaceAll("\\{[^\\}]+\\}", ".").replaceAll("\\w+", "X").replaceAll("\\.", "W");
+		if (c.isEmpty())
+			c = "+";
+		if (! c.endsWith("/*"))
+			c = c + "/W";
+		this.comparator = c;
+
+		String[] parts = new UrlPathParts(patternString).getParts();
+
+		this.hasRemainder = parts.length > 0 && "*".equals(parts[parts.length-1]);
 
-	private final class Builder {
-		boolean isDotAll, isOnlyDotAll;
-		Pattern pattern;
-		List<String> vars = new LinkedList<>();
-
-		Builder(String patternString) {
-			if (! startsWith(patternString, '/'))
-				patternString = '/' + patternString;
-			if (patternString.equals("/*")) {
-				isOnlyDotAll = true;
-				return;
+		parts = hasRemainder ? Arrays.copyOf(parts, parts.length-1) : parts;
+
+		this.parts = parts;
+		this.vars = new String[parts.length];
+		List<String> vars = new ArrayList<>();
+
+		for (int i = 0; i < parts.length; i++) {
+			Matcher m = VAR_PATTERN.matcher(parts[i]);
+			if (m.matches()) {
+				this.vars[i] = m.group(1);
+				vars.add(this.vars[i]);
 			}
-			if (patternString.endsWith("/*"))
-				isDotAll = true;
-
-			// Find all {xxx} variables.
-			Pattern p = Pattern.compile("\\{([^\\}]+)\\}");
-			Matcher m = p.matcher(patternString);
-			while (m.find())
-				vars.add(m.group(1));
-
-			patternString = patternString.replaceAll("\\{[^\\}]+\\}", "([^\\/]+)");
-			patternString = patternString.replaceAll("\\/\\*$", "((?:)|(?:\\/.*))");
-			pattern = Pattern.compile(patternString);
 		}
+
+		this.varKeys = vars.isEmpty() ? null : vars.toArray(new String[vars.size()]);
 	}
 
 	/**
@@ -78,41 +74,63 @@ public final class UrlPathPattern implements Comparable<UrlPathPattern> {
 	 *
 	 * @param path The path to match against.
 	 * @return
-	 * 	An array of values matched against <js>"{var}"</js> variable in the pattern, or an empty array if the
-	 * 	pattern matched but no vars were present, or <jk>null</jk> if the specified path didn't match the pattern.
+	 * 	A pattern match object, or <jk>null</jk> if the path didn't match this pattern.
 	 */
-	public String[] match(String path) {
+	public UrlPathPatternMatch match(String path) {
+		return match(new UrlPathParts(path));
+	}
 
-		if (isOnlyDotAll) {
-			// Remainder always gets leading slash trimmed.
-			if (path != null)
-				path = path.substring(1);
-			return new String[]{path};
+	/**
+	 * Returns a non-<jk>null</jk> value if the specified path matches this pattern.
+	 *
+	 * @param path The path to match against.
+	 * @return
+	 * 	A pattern match object, or <jk>null</jk> if the path didn't match this pattern.
+	 */
+	public UrlPathPatternMatch match(UrlPathParts path) {
+
+		String[] pp = path.getParts();
+
+		if (parts.length != pp.length) {
+			if (hasRemainder) {
+				if (pp.length == parts.length - 1 && ! path.isTrailingSlash())
+					return null;
+				else if (pp.length < parts.length)
+					return null;
+			} else {
+				if (pp.length != parts.length + 1)
+					return null;
+				if (! path.isTrailingSlash())
+					return null;
+			}
 		}
 
-		if (path == null)
-			return (patternString.equals("/") ? new String[]{} : null);
+		for (int i = 0; i < parts.length; i++)
+			if (vars[i] == null && (pp.length <= i || ! ("*".equals(parts[i]) || pp[i].equals(parts[i]))))
+				return null;
 
-		// If we're not doing a /* match, ignore all trailing slashes.
-		if (! isDotAll)
-			while (path.length() > 1 && path.charAt(path.length()-1) == '/')
-				path = path.substring(0, path.length()-1);
+		String[] vals = varKeys == null ? null : new String[varKeys.length];
 
-		Matcher m = pattern.matcher(path);
-		if (! m.matches())
-			return null;
+		int j = 0;
+		if (vals != null)
+			for (int i = 0; i < parts.length; i++)
+				if (vars[i] != null)
+					vals[j++] = pp[i];
 
-		int len = m.groupCount();
-		String[] v = new String[len];
+		String remainder = path.getRemainder(parts.length);
 
-		for (int i = 0; i < len; i++) {
-			if (isDotAll && i == len-1)
-				v[i] = m.group(i+1).isEmpty() ? null : m.group(i+1).substring(1);
-			else
-			v[i] = urlDecode(m.group(i+1));
-		}
+		return new UrlPathPatternMatch(varKeys, vals, remainder);
+	}
 
-		return v;
+	/**
+	 * Returns the variable names found in the pattern.
+	 *
+	 * @return
+	 * 	The variable names or an empty array if no variables found.
+	 *	<br>Modifying the returned array does not modify this object.
+	 */
+	public String[] getVars() {
+		return varKeys == null ? new String[0] : Arrays.copyOf(varKeys, varKeys.length);
 	}
 
 	/**
@@ -134,66 +152,11 @@ public final class UrlPathPattern implements Comparable<UrlPathPattern> {
 	 */
 	@Override /* Comparable */
 	public int compareTo(UrlPathPattern o) {
-		String s1 = patternString.replaceAll("\\{[^\\}]+\\}", ".").replaceAll("\\w+", "X").replaceAll("\\.", "W");
-		String s2 = o.patternString.replaceAll("\\{[^\\}]+\\}", ".").replaceAll("\\w+", "X").replaceAll("\\.", "W");
-		if (s1.isEmpty())
-			s1 = "+";
-		if (s2.isEmpty())
-			s2 = "+";
-		if (! s1.endsWith("/*"))
-			s1 = s1 + "/W";
-		if (! s2.endsWith("/*"))
-			s2 = s2 + "/W";
-		int c = s2.compareTo(s1);
-		if (c == 0)
-			return o.toRegEx().compareTo(toRegEx());
-		return c;
-	}
-
-	@Override /* Object */
-	public boolean equals(Object o) {
-		if (! (o instanceof UrlPathPattern))
-			return false;
-		return (compareTo((UrlPathPattern)o) == 0);
-	}
-
-	@Override /* Object */
-	public int hashCode() {
-		return super.hashCode();
+		return o.comparator.compareTo(comparator);
 	}
 
 	@Override /* Object */
 	public String toString() {
-		return patternString;
-	}
-
-	/**
-	 * Returns this path pattern as the compiled regular expression.
-	 *
-	 * <p>
-	 * Useful for debugging.
-	 *
-	 * @return The path pattern.
-	 */
-	public String toRegEx() {
-		return isOnlyDotAll ? "*" : pattern.pattern();
-	}
-
-	/**
-	 * Bean property getter:  <property>vars</property>.
-	 *
-	 * @return The value of the <property>vars</property> property on this bean, or <jk>null</jk> if it is not set.
-	 */
-	public String[] getVars() {
-		return vars;
-	}
-
-	/**
-	 * Bean property getter:  <property>patternString</property>.
-	 *
-	 * @return The value of the <property>patternString</property> property on this bean, or <jk>null</jk> if it is not set.
-	 */
-	public String getPatternString() {
-		return patternString;
+		return pattern.toString();
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializerSession.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathPatternMatch.java
similarity index 51%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializerSession.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathPatternMatch.java
index 80a566a..fa39d42 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializerSession.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/UrlPathPatternMatch.java
@@ -10,55 +10,67 @@
 // * "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.html;
+package org.apache.juneau.rest.util;
 
-import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.serializer.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.marshall.*;
 
 /**
- * Session object that lives for the duration of a single use of {@link HtmlStrippedDocSerializer}.
+ * Represents a URL path pattern match.
  *
- * <p>
- * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ * For example, given the pattern <js>"/foo/{bar}/*"</js> and the path <js>"/foo/123/baz/qux"</js>, this match gives
+ * you a map containing <js>"{bar:123}"</js> and a remainder string containing <js>"baz/qux"</js>.
  */
-public class HtmlStrippedDocSerializerSession extends HtmlSerializerSession {
+public class UrlPathPatternMatch {
+
+	private final String remainder;
+	private final Map<String,String> vars;
 
 	/**
-	 * Create a new session using properties specified in the context.
+	 * Constructor.
 	 *
-	 * @param ctx
-	 * 	The context creating this session object.
-	 * 	The context contains all the configuration settings for this object.
-	 * @param args
-	 * 	Runtime arguments.
+	 * @param keys The variable keys.  Can be <jk>null</jk>.
+	 * @param values The variable values.  Can be <jk>null</jk>.
+	 * @param remainder
 	 */
-	protected HtmlStrippedDocSerializerSession(HtmlStrippedDocSerializer ctx, SerializerSessionArgs args) {
-		super(ctx, args);
+	protected UrlPathPatternMatch(String[] keys, String[] values, String remainder) {
+		this.remainder = remainder;
+		this.vars = keys == null ? Collections.emptyMap() : new SimpleMap<>(keys, values);
 	}
 
-	@Override /* SerializerSession */
-	protected void doSerialize(SerializerPipe out, Object o) throws Exception {
-		try (HtmlWriter w = getHtmlWriter(out)) {
-			if (o == null
-				|| (o instanceof Collection && ((Collection<?>)o).size() == 0)
-				|| (o.getClass().isArray() && Array.getLength(o) == 0))
-				w.sTag(1, "p").append("No Results").eTag("p").nl(1);
-			else
-				super.doSerialize(out, o);
-		}
+	/**
+	 * Returns a map of the path variables and values.
+	 *
+	 * @return An unmodifiable map of variable keys/values.
+	 */
+	public Map<String,String> getVars() {
+		return vars;
+	}
+
+	/**
+	 * Returns the remainder of the path after the pattern match has been made.
+	 *
+	 * @return The remainder of the path after the pattern match has been made.
+	 */
+	public String getRemainder() {
+		return remainder;
 	}
 
-	//-----------------------------------------------------------------------------------------------------------------
-	// Other methods
-	//-----------------------------------------------------------------------------------------------------------------
+	/**
+	 * Converts this object to a map.
+	 *
+	 * @return This object converted to a map.
+	 */
+	public ObjectMap toMap() {
+		return new DefaultFilteringObjectMap().append("v", getVars()).append("r", getRemainder());
+	}
 
-	@Override /* Session */
-	public ObjectMap asMap() {
-		return super.asMap()
-			.append("HtmlStrippedDocSerializerSession", new DefaultFilteringObjectMap()
-		);
+	@Override /* Object */
+	public String toString() {
+		return SimpleJson.DEFAULT.toString(toMap());
 	}
 }
+