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

incubator-juneau git commit: Eliminate support for toObjectMap() method on classes.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master 88d1d38ca -> 21fcc1197


Eliminate support for toObjectMap() method on classes.

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

Branch: refs/heads/master
Commit: 21fcc1197e3d954ebb0fa60b895f43e347b6b19f
Parents: 88d1d38
Author: JamesBognar <ja...@apache.org>
Authored: Sun Feb 5 12:48:40 2017 -0500
Committer: JamesBognar <ja...@apache.org>
Committed: Sun Feb 5 12:48:40 2017 -0500

----------------------------------------------------------------------
 .../java/org/apache/juneau/jena/RdfParser.java  |   2 +-
 .../org/apache/juneau/jena/RdfSerializer.java   |   5 -
 .../a/rttests/RoundTripToObjectMapsTest.java    |   2 +-
 .../juneau/dto/html5/HtmlTemplatesTest.java     |  19 +--
 .../java/org/apache/juneau/BeanSession.java     |   2 +-
 .../main/java/org/apache/juneau/ClassMeta.java  | 102 ++++++--------
 .../java/org/apache/juneau/html/HtmlParser.java |   2 +-
 .../org/apache/juneau/html/HtmlSerializer.java  |   4 -
 .../java/org/apache/juneau/json/JsonParser.java |   2 +-
 .../org/apache/juneau/json/JsonSerializer.java  |   2 -
 .../apache/juneau/msgpack/MsgPackParser.java    |   2 +-
 .../juneau/msgpack/MsgPackSerializer.java       |   2 -
 .../apache/juneau/urlencoding/UonParser.java    |   2 +-
 .../juneau/urlencoding/UonSerializer.java       |   2 -
 .../juneau/urlencoding/UrlEncodingParser.java   |   2 +-
 .../urlencoding/UrlEncodingSerializer.java      |   2 -
 .../java/org/apache/juneau/xml/XmlParser.java   |   2 +-
 .../apache/juneau/xml/XmlSchemaSerializer.java  |   6 +-
 .../org/apache/juneau/xml/XmlSerializer.java    |  10 +-
 juneau-core/src/main/javadoc/overview.html      | 141 ++++++++++++++++++-
 20 files changed, 206 insertions(+), 107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index 26a9697..b18ab15 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -329,7 +329,7 @@ public class RdfParser extends ReaderParser {
 				return null;
 			Map m = new ObjectMap(session);
 			parseIntoMap(session, r, m, eType.getKeyType(), eType.getValueType());
-			o = sType.newInstanceFromObjectMap(outer, (ObjectMap)m);
+			o = sType.newInstanceFromObjectMap(session, outer, (ObjectMap)m);
 		} else if (sType.canCreateNewBean(outer)) {
 			Resource r = n.asResource();
 			if (session.wasAlreadyProcessed(r))

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index c579001..461decb 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -225,11 +225,6 @@ public class RdfSerializer extends WriterSerializer {
 				serializeMap(session, m2, (Resource)n, sType);
 			}
 
-		} else if (sType.hasToObjectMapMethod()) {
-			Map m2 = sType.toObjectMap(o);
-			n = m.createResource();
-			serializeMap(session, m2, (Resource)n, sType);
-
 		} else if (sType.isBean()) {
 			BeanMap bm = session.toBeanMap(o);
 			Object uri = null;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
index 4a9ada9..3c7b33a 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
@@ -69,7 +69,7 @@ public class RoundTripToObjectMapsTest extends RoundTripTest {
 			this.f1 = m.getString("f1");
 			this.f2 = m.getInt("f2");
 		}
-		public ObjectMap toObjectMap() {
+		public ObjectMap swap(BeanSession session) {
 			return new ObjectMap().append("f1",f1).append("f2",f2);
 		}
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java
index 93073bc..6606228 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java
@@ -48,11 +48,11 @@ public class HtmlTemplatesTest {
 		return Arrays.asList(new Object[][] {
 			{
 				"FormTemplate-1",
-				new FormTemplate("myaction", "foo", "bar"),
-				"<form action='myaction'><input type='text' name='v1' value='foo'/><input type='text' name='v2' value='bar'/></form>",
-				"<form action='myaction'><input type='text' name='v1' value='foo'/><input type='text' name='v2' value='bar'/></form>\n",
-				"<form action='myaction'><input type='text' name='v1' value='foo'/><input type='text' name='v2' value='bar'/></form>",
-				"<form action='myaction'><input type='text' name='v1' value='foo'/><input type='text' name='v2' value='bar'/></form>\n",
+				new FormTemplate("myaction", 123, true),
+				"<form action='myaction'><input type='text' name='v1' value='123'/><input type='text' name='v2' value='true'/></form>",
+				"<form action='myaction'><input type='text' name='v1' value='123'/><input type='text' name='v2' value='true'/></form>\n",
+				"<form action='myaction'><input type='text' name='v1' value='123'/><input type='text' name='v2' value='true'/></form>",
+				"<form action='myaction'><input type='text' name='v1' value='123'/><input type='text' name='v2' value='true'/></form>\n",
 			},
 		});
 	}
@@ -62,15 +62,16 @@ public class HtmlTemplatesTest {
 	public static class FormTemplate {
 		
 		private String action;
-		private String value1, value2;
+		private int value1;
+		private boolean value2;
 		
 		public FormTemplate(Form f) {
 			this.action = f.getAttr("action");
-			this.value1 = ((Input)f.getChildren().get(0)).getAttr("value");
-			this.value2 = ((Input)f.getChildren().get(1)).getAttr("value");
+			this.value1 = f.getChild(Input.class, 0).getAttr(int.class, "value");
+			this.value2 = f.getChild(Input.class, 1).getAttr(boolean.class, "value");
 		}
 		
-		public FormTemplate(String action, String value1, String value2) {
+		public FormTemplate(String action, int value1, boolean value2) {
 			this.action = action;
 			this.value1 = value1;
 			this.value2 = value2;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
index 2f01534..e7a405d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
@@ -555,7 +555,7 @@ public class BeanSession extends Session {
 				return newBeanMap(tc).load((Map<?,?>) value).getBean();
 
 			if (type.canCreateNewInstanceFromObjectMap(outer) && value instanceof ObjectMap)
-				return type.newInstanceFromObjectMap(outer, (ObjectMap)value);
+				return type.newInstanceFromObjectMap(this, outer, (ObjectMap)value);
 
 			if (type.canCreateNewInstanceFromNumber(outer) && value instanceof Number)
 				return type.newInstanceFromNumber(this, outer, (Number)value);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
index fe22629..74027e6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
@@ -67,14 +67,13 @@ public final class ClassMeta<T> implements Type {
 	private final Constructor<T>
 		stringConstructor,                                   // The X(String) constructor (if it has one).
 		numberConstructor,                                   // The X(Number) constructor (if it has one).
-		swapConstructor,                                     // The X(Swappable) constructor (if it has one).
-		objectMapConstructor;                                // The X(ObjectMap) constructor (if it has one).
+		swapConstructor;                                     // The X(Swappable) constructor (if it has one).
 	private final Class<?>
 		swapMethodType,                                      // The class type of the object in the number constructor.
 		numberConstructorType;
 	private final Method
-		toObjectMapMethod,                                   // The toObjectMap() method (if it has one).
 		swapMethod,                                          // The swap() method (if it has one).
+		unswapMethod,                                        // The unswap() method (if it has one).
 		namePropertyMethod,                                  // The method to set the name on an object (if it has one).
 		parentPropertyMethod;                                // The method to set the parent on an object (if it has one).
 	private final boolean
@@ -139,7 +138,7 @@ public final class ClassMeta<T> implements Type {
 
 		// We always immediately add this class meta to the bean context cache so that we can resolve recursive references.
 		if (beanContext != null && beanContext.cmCache != null)
-			beanContext.cmCache.putIfAbsent(innerClass, this);
+			beanContext.cmCache.put(innerClass, this);
 
 		this.implClass = implClass;
 		this.childPojoSwaps = childPojoSwaps;
@@ -151,14 +150,13 @@ public final class ClassMeta<T> implements Type {
 		boolean _isDelegate = false;
 		Method
 			_fromStringMethod = null,
-			_toObjectMapMethod = null,
 			_swapMethod = null,
+			_unswapMethod = null,
 			_parentPropertyMethod = null,
 			_namePropertyMethod = null;
 		Constructor<T>
 			_noArgConstructor = null,
 			_stringConstructor = null,
-			_objectMapConstructor = null,
 			_swapConstructor = null,
 			_numberConstructor = null;
 		Class<?>
@@ -272,17 +270,13 @@ public final class ClassMeta<T> implements Type {
 				_fromStringMethod = LocaleAsString.class.getMethod("fromString", String.class);
 		} catch (NoSuchMethodException e1) {}
 
-		// Find toObjectMap() method if present.
+		// Find swap() method if present.
 		for (Method m : c.getMethods()) {
 			if (isPublic(m) && isNotDeprecated(m) && ! isStatic(m)) {
 				String mName = m.getName();
-				if (mName.equals("toObjectMap")) {
-					if (m.getParameterTypes().length == 0 && m.getReturnType() == ObjectMap.class) {
-						_toObjectMapMethod = m;
-						break;
-					}
-				} else if (mName.equals("swap")) {
-					if (m.getParameterTypes().length == 1 && m.getParameterTypes()[0] == BeanSession.class) {
+				if (mName.equals("swap")) {
+					Class<?>[] pt = m.getParameterTypes();
+					if (pt.length == 1 && pt[0] == BeanSession.class) {
 						_swapMethod = m;
 						_swapMethodType = m.getReturnType();
 						break;
@@ -290,6 +284,21 @@ public final class ClassMeta<T> implements Type {
 				}
 			}
 		}
+		// Find unswap() method if present.
+		if (_swapMethod != null) {
+			for (Method m : c.getMethods()) {
+				if (isPublic(m) && isNotDeprecated(m) && isStatic(m)) {
+					String mName = m.getName();
+					if (mName.equals("unswap")) {
+						Class<?>[] pt = m.getParameterTypes();
+						if (pt.length == 2 && pt[0] == BeanSession.class && pt[1] == _swapMethodType) {
+							_unswapMethod = m;
+							break;
+						}
+					}
+				}
+			}
+		}
 
 		// Find @NameProperty and @ParentProperty methods if present.
 		for (Method m : c.getDeclaredMethods()) {
@@ -316,8 +325,6 @@ public final class ClassMeta<T> implements Type {
 					Class<?> arg = args[(isMemberClass ? 1 : 0)];
 					if (arg == String.class)
 						_stringConstructor = cs;
-					else if (ObjectMap.class.isAssignableFrom(arg))
-						_objectMapConstructor = cs;
 					else if (_swapMethodType != null && _swapMethodType.isAssignableFrom(arg))
 						_swapConstructor = cs;
 					else if (_cc != NUMBER && (Number.class.isAssignableFrom(arg) || (arg.isPrimitive() && (arg == int.class || arg == short.class || arg == long.class || arg == float.class || arg == double.class)))) {
@@ -388,11 +395,14 @@ public final class ClassMeta<T> implements Type {
 			beanFilter = findBeanFilter();
 
 		if (_swapMethod != null) {
+			final Method fSwapMethod = _swapMethod;
+			final Method fUnswapMethod = _unswapMethod;
+			final Constructor<T> fSwapConstructor = _swapConstructor;
 			_pojoSwap = new PojoSwap<T,Object>(c, _swapMethod.getReturnType()) {
 				@Override
 				public Object swap(BeanSession session, Object o) throws SerializeException {
 					try {
-						return swapMethod.invoke(o, session);
+						return fSwapMethod.invoke(o, session);
 					} catch (Exception e) {
 						throw new SerializeException(e);
 					}
@@ -400,8 +410,10 @@ public final class ClassMeta<T> implements Type {
 				@Override
 				public T unswap(BeanSession session, Object f, ClassMeta<?> hint) throws ParseException {
 					try {
-						if (swapConstructor != null)
-							return swapConstructor.newInstance(f);
+						if (fUnswapMethod != null)
+							return (T)fUnswapMethod.invoke(null, session, f);
+						if (fSwapConstructor != null)
+							return fSwapConstructor.newInstance(f);
 						return super.unswap(session, f, hint);
 					} catch (Exception e) {
 						throw new ParseException(e);
@@ -484,14 +496,13 @@ public final class ClassMeta<T> implements Type {
 		this.cc = _cc;
 		this.isDelegate = _isDelegate;
 		this.fromStringMethod = _fromStringMethod;
-		this.toObjectMapMethod = _toObjectMapMethod;
 		this.swapMethod = _swapMethod;
+		this.unswapMethod = _unswapMethod;
 		this.swapMethodType = _swapMethodType;
 		this.parentPropertyMethod = _parentPropertyMethod;
 		this.namePropertyMethod =_namePropertyMethod;
 		this.noArgConstructor = _noArgConstructor;
 		this.stringConstructor = _stringConstructor;
-		this.objectMapConstructor =_objectMapConstructor;
 		this.swapConstructor = _swapConstructor;
 		this.numberConstructor = _numberConstructor;
 		this.numberConstructorType = _numberConstructorType;
@@ -529,11 +540,10 @@ public final class ClassMeta<T> implements Type {
 		this.stringConstructor = mainType.stringConstructor;
 		this.numberConstructor = mainType.numberConstructor;
 		this.swapConstructor = mainType.swapConstructor;
-		this.objectMapConstructor = mainType.objectMapConstructor;
 		this.swapMethodType = mainType.swapMethodType;
 		this.numberConstructorType = mainType.numberConstructorType;
-		this.toObjectMapMethod = mainType.toObjectMapMethod;
 		this.swapMethod = mainType.swapMethod;
+		this.unswapMethod = mainType.unswapMethod;
 		this.namePropertyMethod = mainType.namePropertyMethod;
 		this.parentPropertyMethod = mainType.parentPropertyMethod;
 		this.isDelegate = mainType.isDelegate;
@@ -1204,24 +1214,16 @@ public final class ClassMeta<T> implements Type {
 	 * @return <jk>true</jk> if this class has a no-arg constructor or invocation handler.
 	 */
 	public boolean canCreateNewInstanceFromObjectMap(Object outer) {
-		if (objectMapConstructor != null) {
+		// TODO - Get rid of?
+		if (swapMethodType == ObjectMap.class && (swapConstructor != null || unswapMethod != null)) {
 			if (isMemberClass)
-				return outer != null && objectMapConstructor.getParameterTypes()[0] == outer.getClass();
+				return outer != null && swapConstructor.getParameterTypes()[0] == outer.getClass();
 			return true;
 		}
 		return false;
 	}
 
 	/**
-	 * Returns <jk>true</jk> if this class has an <code>ObjectMap toObjectMap()</code> method.
-	 *
-	 * @return <jk>true</jk> if class has a <code>toObjectMap()</code> method.
-	 */
-	public boolean hasToObjectMapMethod() {
-		return toObjectMapMethod != null;
-	}
-
-	/**
 	 * Returns the method annotated with {@link NameProperty @NameProperty}.
 	 *
 	 * @return The method annotated with {@link NameProperty @NameProperty} or <jk>null</jk> if method does not exist.
@@ -1240,23 +1242,6 @@ public final class ClassMeta<T> implements Type {
  	}
 
 	/**
-	 * Converts an instance of this class to an {@link ObjectMap}.
-	 *
-	 * @param t The object to convert to a map.
-	 * @return The converted object, or <jk>null</jk> if method does not have a <code>toObjectMap()</code> method.
-	 * @throws BeanRuntimeException Thrown by <code>toObjectMap()</code> method invocation.
-	 */
-	public ObjectMap toObjectMap(Object t) throws BeanRuntimeException {
-		try {
-			if (toObjectMapMethod != null)
-				return (ObjectMap)toObjectMapMethod.invoke(t);
-			return null;
-		} catch (Exception e) {
-			throw new BeanRuntimeException(e);
-		}
-	}
-
-	/**
 	 * Returns the reason why this class is not a bean, or <jk>null</jk> if it is a bean.
 	 *
 	 * @return The reason why this class is not a bean, or <jk>null</jk> if it is a bean.
@@ -1363,6 +1348,7 @@ public final class ClassMeta<T> implements Type {
 	 * 	<li><code><jk>public</jk> T(ObjectMap in);</code>
 	 * </ul>
 	 *
+	 * @param session The current bean session.
 	 * @param outer The outer class object for non-static member classes.  Can be <jk>null</jk> for non-member or static classes.
 	 * @param arg The input argument value.
 	 * @return A new instance of the object.
@@ -1372,12 +1358,16 @@ public final class ClassMeta<T> implements Type {
 	 * 	does not have one of the methods described above.
 	 * @throws InvocationTargetException If the underlying constructor throws an exception.
 	 */
-	public T newInstanceFromObjectMap(Object outer, ObjectMap arg) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
-		Constructor<T> c = objectMapConstructor;
-		if (c != null) {
+	@SuppressWarnings("unchecked")
+	public T newInstanceFromObjectMap(BeanSession session, Object outer, ObjectMap arg) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
+		// TODO - Get rid of?
+		if (swapConstructor != null) {
 			if (isMemberClass)
-				return c.newInstance(outer, arg);
-			return c.newInstance(arg);
+				return swapConstructor.newInstance(outer, arg);
+			return swapConstructor.newInstance(arg);
+		}
+		if (unswapMethod != null) {
+			return (T)unswapMethod.invoke(null, session, arg);
 		}
 		throw new InstantiationError("No map constructor method found for class '"+getInnerClass().getName()+"'");
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
index 1a88144..7757386 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
@@ -177,7 +177,7 @@ public final class HtmlParser extends XmlParser {
 				} else if (sType.canCreateNewInstanceFromObjectMap(outer)) {
 					ObjectMap m = new ObjectMap(session);
 					parseIntoMap(session, r, m, string(), object(), pMeta);
-					o = sType.newInstanceFromObjectMap(outer, m);
+					o = sType.newInstanceFromObjectMap(session, outer, m);
 				} else if (sType.canCreateNewBean(outer)) {
 					BeanMap m = session.newBeanMap(outer, sType.getInnerClass());
 					o = parseIntoBean(session, r, m).getBean();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index 995015a..8828409 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -261,10 +261,6 @@ public class HtmlSerializer extends XmlSerializer {
 					out.sTag("boolean").append(o).eTag("boolean");
 				cr = CR_SIMPLE;
 
-			} else if (sType.hasToObjectMapMethod()) {
-				out.nlIf(! isRoot);
-				serializeMap(session, out, sType.toObjectMap(o), sType, null, null, typeName, pMeta);
-
 			} else if (sType.isMap() || (wType != null && wType.isMap())) {
 				out.nlIf(! isRoot);
 				if (o instanceof BeanMap)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
index e141dd0..3289abe 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
@@ -166,7 +166,7 @@ public final class JsonParser extends ReaderParser {
 		} else if (sType.canCreateNewInstanceFromObjectMap(outer)) {
 			ObjectMap m = new ObjectMap(session);
 			parseIntoMap2(session, r, m, string(), object(), pMeta);
-			o = sType.newInstanceFromObjectMap(outer, m);
+			o = sType.newInstanceFromObjectMap(session, outer, m);
 		} else if (sType.canCreateNewBean(outer)) {
 			BeanMap m = session.newBeanMap(outer, sType.getInnerClass());
 			o = parseIntoBeanMap2(session, r, m).getBean();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
index 43ba2b5..3559590 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -200,8 +200,6 @@ public class JsonSerializer extends WriterSerializer {
 			out.append("null");
 		else if (sType.isNumber() || sType.isBoolean())
 			out.append(o);
-		else if (sType.hasToObjectMapMethod())
-			serializeMap(session, out, sType.toObjectMap(o), sType);
 		else if (sType.isBean())
 			serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty);
 		else if (sType.isUri() || (pMeta != null && pMeta.isUri()))

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
index a3f731a..acb5a3c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
@@ -109,7 +109,7 @@ public final class MsgPackParser extends InputStreamParser {
 				ObjectMap m = new ObjectMap(session);
 				for (int i = 0; i < length; i++)
 					m.put(parseAnything(session, string(), is, outer, pMeta), parseAnything(session, object(), is, m, pMeta));
-				o = sType.newInstanceFromObjectMap(outer, m);
+				o = sType.newInstanceFromObjectMap(session, outer, m);
 			} else if (sType.canCreateNewBean(outer)) {
 				if (dt == MAP) {
 					BeanMap m = session.newBeanMap(outer, sType.getInnerClass());

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index 93fa938..4e4ed0d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -91,8 +91,6 @@ public class MsgPackSerializer extends OutputStreamSerializer {
 			out.appendBoolean((Boolean)o);
 		else if (sType.isNumber())
 			out.appendNumber((Number)o);
-		else if (sType.hasToObjectMapMethod())
-			serializeMap(session, out, sType.toObjectMap(o), sType);
 		else if (sType.isBean())
 			serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty);
 		else if (sType.isUri() || (pMeta != null && pMeta.isUri()))

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
index 79feb29..c6a3b97 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
@@ -157,7 +157,7 @@ public class UonParser extends ReaderParser {
 		} else if (sType.canCreateNewInstanceFromObjectMap(outer)) {
 			ObjectMap m = new ObjectMap(session);
 			parseIntoMap(session, r, m, string(), object(), pMeta);
-			o = sType.newInstanceFromObjectMap(outer, m);
+			o = sType.newInstanceFromObjectMap(session, outer, m);
 		} else if (sType.canCreateNewBean(outer)) {
 			BeanMap m = session.newBeanMap(outer, sType.getInnerClass());
 			m = parseIntoBeanMap(session, r, m);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
index c65f674..9c752f2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
@@ -280,8 +280,6 @@ public class UonSerializer extends WriterSerializer {
 		// '\0' characters are considered null.
 		if (o == null || (sType.isChar() && ((Character)o).charValue() == 0))
 			out.appendObject(null, false, false, isTop);
-		else if (sType.hasToObjectMapMethod())
-			serializeMap(session, out, sType.toObjectMap(o), eType);
 		else if (sType.isBean())
 			serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty);
 		else if (sType.isUri() || (pMeta != null && pMeta.isUri()))

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index fac17c9..acb6827 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -91,7 +91,7 @@ public class UrlEncodingParser extends UonParser {
 		} else if (sType.canCreateNewInstanceFromObjectMap(outer)) {
 			ObjectMap m = new ObjectMap(session);
 			parseIntoMap(session, r, m, string(), object());
-			o = sType.newInstanceFromObjectMap(outer, m);
+			o = sType.newInstanceFromObjectMap(session, outer, m);
 		} else if (sType.canCreateNewBean(outer)) {
 			BeanMap m = session.newBeanMap(outer, sType.getInnerClass());
 			m = parseIntoBeanMap(session, r, m);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 99862d0..e96ef9b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -249,8 +249,6 @@ public class UrlEncodingSerializer extends UonSerializer {
 				serializeBeanMap(session, out, (BeanMap)o, addTypeProperty);
 			else
 				serializeMap(session, out, (Map)o, sType);
-		} else if (sType.hasToObjectMapMethod()) {
-			serializeMap(session, out, sType.toObjectMap(o), sType);
 		} else if (sType.isBean()) {
 			serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty);
 		} else if (sType.isCollection()) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
index b5ec875..0e39e89 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -144,7 +144,7 @@ public class XmlParser extends ReaderParser {
 		} else if (sType.canCreateNewInstanceFromObjectMap(outer)) {
 			ObjectMap m = new ObjectMap(session);
 			parseIntoMap(session, r, m, string(), object(), pMeta);
-			o = sType.newInstanceFromObjectMap(outer, m);
+			o = sType.newInstanceFromObjectMap(session, outer, m);
 		} else if (sType.canCreateNewBean(outer)) {
 			if (sType.getExtendedMeta(XmlClassMeta.class).getFormat() == COLLAPSED) {
 				String fieldName = r.getLocalName();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
index 3d9782e..35effd0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
@@ -341,7 +341,7 @@ public class XmlSchemaSerializer extends XmlSerializer {
 
 			w.cTag().nl();
 
-			if (! (cm.isMapOrBean() || cm.hasToObjectMapMethod() || cm.isCollectionOrArray() || (cm.isAbstract() && ! cm.isNumber()) || cm.isObject())) {
+			if (! (cm.isMapOrBean() || cm.isCollectionOrArray() || (cm.isAbstract() && ! cm.isNumber()) || cm.isObject())) {
 				w.oTag(i+1, "attribute").attr("name", session.getBeanTypePropertyName()).attr("type", "string").ceTag().nl();
 
 			} else {
@@ -479,7 +479,7 @@ public class XmlSchemaSerializer extends XmlSerializer {
 					}
 
 				//----- Map -----
-				} else if (cm.isMap() || cm.hasToObjectMapMethod() || cm.isAbstract() || cm.isObject()) {
+				} else if (cm.isMap() || cm.isAbstract() || cm.isObject()) {
 					w.sTag(i+1, "sequence").nl();
 					w.oTag(i+2, "any")
 						.attr("processContents", "skip")
@@ -512,7 +512,7 @@ public class XmlSchemaSerializer extends XmlSerializer {
 					name = "number";
 				else if (cm.isCollectionOrArray())
 					name = "array";
-				else if (! (cm.isMapOrBean() || cm.hasToObjectMapMethod() || cm.isCollectionOrArray() || cm.isObject() || cm.isAbstract()))
+				else if (! (cm.isMapOrBean() || cm.isCollectionOrArray() || cm.isObject() || cm.isAbstract()))
 					name = "string";
 				else
 					name = "object";

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index 006b32d..e8e0bbf 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -373,7 +373,7 @@ public class XmlSerializer extends WriterSerializer {
 			type = NUMBER;
 		} else if (sType.isBoolean()) {
 			type = BOOLEAN;
-		} else if (sType.isMapOrBean() || sType.hasToObjectMapMethod()) {
+		} else if (sType.isMapOrBean()) {
 			isCollapsed = sType.getExtendedMeta(XmlClassMeta.class).getFormat() == COLLAPSED;
 			type = OBJECT;
 		} else if (sType.isCollectionOrArray()) {
@@ -406,7 +406,7 @@ public class XmlSerializer extends WriterSerializer {
 		}
 
 		// Do we need a carriage return after the start tag?
-		boolean cr = o != null && (sType.isMapOrBean() || sType.isCollectionOrArray() || sType.hasToObjectMapMethod()) && ! isMixed;
+		boolean cr = o != null && (sType.isMapOrBean() || sType.isCollectionOrArray()) && ! isMixed;
 
 		String en = elementName;
 		if (en == null) {
@@ -443,10 +443,10 @@ public class XmlSerializer extends WriterSerializer {
 					o = sType.getPrimitiveDefault();
 			}
 
-			if (o != null && ! (sType.isMapOrBean() || sType.hasToObjectMapMethod()))
+			if (o != null && ! (sType.isMapOrBean()))
 				out.append('>');
 
-			if (cr && ! (sType.isMapOrBean() || sType.hasToObjectMapMethod()))
+			if (cr && ! (sType.isMapOrBean()))
 				out.nl();
 		}
 
@@ -468,8 +468,6 @@ public class XmlSerializer extends WriterSerializer {
 					rc = serializeBeanMap(session, out, (BeanMap)o, elementNamespace, isCollapsed, isMixed);
 				else
 					rc = serializeMap(session, out, (Map)o, sType, eType.getKeyType(), eType.getValueType(), isMixed);
-			} else if (sType.hasToObjectMapMethod()) {
-				rc = serializeMap(session, out, sType.toObjectMap(o), sType, null, null, isMixed);
 			} else if (sType.isBean()) {
 				rc = serializeBeanMap(session, out, session.toBeanMap(o), elementNamespace, isCollapsed, isMixed);
 			} else if (sType.isCollection() || (wType != null && wType.isCollection())) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index 10431b6..b91970d 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -77,6 +77,7 @@
 		<li><p><a class='doclink' href='#Core.Transforms'>Transforms</a></p>
 		<ol>
 			<li><p><a class='doclink' href='#Core.PojoSwaps'>PojoSwaps</a></p>
+			<li><p><a class='doclink' href='#Core.SwapMethods'>Swap methods</a></p>
 			<li><p><a class='doclink' href='#Core.BeanFilters'>BeanFilters and @Bean annotations</a></p>
 		</ol>
 		<li><p><a class='doclink' href='#Core.BeanDictionaries'>Bean Name and Dictionaries</a></p>
@@ -742,8 +743,131 @@
 		</div>
 	
 		<!-- ======================================================================================================== -->
+		<a id="Core.SwapMethods"></a>
+		<h4 class='topic' onclick='toggle(this)'>2.6.2 - Swap methods</h4>
+		<div class='topic'>
+			<p>
+				Various methods can be defined on a class directly to affect how it gets serialized.
+			</p>
+			<p>
+				Objects normally serialized to <code>Strings</code> can be parsed back into their original objects by implementing 
+				one of the following methods on the class:
+			</p>		
+			<ul>
+				<li><code><jk>public static</jk> T fromString(String)</code> method.<br>
+					Any of the following method names also work: 
+					<ul>
+						<li><code>valueOf(String)</code>
+						<li><code>parse(String)</code>
+						<li><code>parseString(String)</code>
+						<li><code>forName(String)</code>
+						<li><code>forString(String)</code>
+					</ul>
+				<li><code><jk>public</jk> T(String)</code> constructor.
+			</ul>
+			<p>
+				Note that these methods cover conversion from several built-in Java types, meaning these can be constructed directly by the parser from strings:
+			</p>
+			<ul>
+				<li><code>fromString(String)</code> - {@link java.util.UUID}
+				<li><code>valueOf(String)</code> - {@link java.lang.Boolean}, {@link java.lang.Byte}, {@link java.lang.Double}, {@link java.lang.Float}, 
+					{@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Short}, {@link java.sql.Date}, {@link java.sql.Time}, {@link java.sql.Timestamp}
+				<li><code>parse(String)</code> - {@link java.text.DateFormat}, {@link java.text.MessageFormat}, {@link java.text.NumberFormat}, {@link java.util.Date}, {@link java.util.logging.Level}
+				<li><code>parseString(String)</code> - {@link javax.xml.bind.DatatypeConverter}
+				<li><code>forName(String)</code> - {@link java.lang.Class}
+			</ul>
+			<p>
+				If you want to force a bean-like class to be serialized as a string, you can use the {@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore}
+				annotation on the class to force it to be serialized to a string using the <code>toString()</code> method.
+			</p>
+			<p>
+				Serializing to other intermediate objects can be accomplished by defining a swap method directly on the class:
+			</p>			
+			<ul>
+				<li><code><jk>public</jk> X swap(BeanSession)</code> method, where <code>X</code> is any serializable object.
+			</ul>
+			<p>
+				The <code>BeanSession</code> parameter allows you access to various information about the current serialization session.
+				For example, you could provide customized results based on the media type being produced ({@link org.apache.juneau.BeanSession#getMediaType()}).
+			</p>
+			<p>
+				The following example shows how an HTML5 form template object can be created that gets serialized as a populated HTML5 {@link org.apache.juneau.dto.html5.Form} bean.
+			</p>
+			<p class='bcode'>
+	<jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*;
+	
+	<jd>/**
+	 * A simple HTML form template whose serialized form is an HTML5 Form object.
+	 */</jd>
+	<jk>public class</jk> FormTemplate {
+		
+		<jk>private</jk> String <jf>action</jf>;
+		<jk>private int</jk> <jf>value1</jf>;
+		<jk>private boolean</jk> <jf>value2</jf>;
+		
+		<jk>public</jk> FormTemplate(String action, <jk>int</jk> value1, <jk>boolean</jk> value2) {
+			<jk>this</jk>.<jf>action</jf> = action;
+			<jk>this</jk>.<jf>value1</jf> = value1;
+			<jk>this</jk>.<jf>value2</jf> = value2;
+		}
+		
+		<jk>public</jk> Form swap(BeanSession session) {
+			<jk>return</jk> <jsm>form</jsm>(<jf>action</jf>,
+				<jsm>input</jsm>(<js>"text"</js>).name(<js>"v1"</js>).value(<jf>value1</jf>),
+				<jsm>input</jsm>(<js>"text"</js>).name(<js>"v2"</js>).value(<jf>value2</jf>)
+			);
+		}
+	}
+			</p>
+			<p>
+				Swapped objects can be converted back into their original form by the parsers by specifying one of the following methods:
+			</p>
+			<ul>
+				<li><code><jk>public static</jk> T unswap(BeanSession, X)</code> method where <code>X</code> is the swap class type.
+				<li><code><jk>public</jk> T(X)</code> constructor where <code>X</code> is the swap class type.
+			</ul>
+			<p>
+				The following shows how our form template class can be modified to allow the parsers to reconstruct our original object:
+			</p>
+			<p class='bcode'>
+	<jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*;
+	
+	<jd>/**
+	 * A simple HTML form template whose serialized form is an HTML5 Form object.
+	 * This time with parsing support.
+	 */</jd>
+	<ja>@Bean</ja>(beanDictionary=HtmlBeanDictionary.<jk>class</jk>)
+	<jk>public class</jk> FormTemplate {
+		
+		<jk>private</jk> String <jf>action</jf>;
+		<jk>private int</jk> <jf>value1</jf>;
+		<jk>private boolean</jk> <jf>value2</jf>;
+		
+		<jc>// Our 'unswap' constructor</jc>
+		<jk>public</jk> FormTemplate(Form f) {
+			<jk>this</jk>.<jf>action</jf> = f.getAttr(<js>"action"</js>);
+			<jk>this</jk>.<jf>value1</jf> = f.getChild(Input.<jk>class</jk>, 0).getAttr(<jk>int</jk>.<jk>class</jk>, <js>"value"</js>);
+			<jk>this</jk>.<jf>value2</jf> = f.getChild(Input.<jk>class</jk>, 1).getAttr(<jk>boolean</jk>.<jk>class</jk>, <js>"value"</js>);
+		}
+		
+		<jk>public</jk> FormTemplate(String action, <jk>int</jk> value1, <jk>boolean</jk> value2) {
+			<jk>this</jk>.<jf>action</jf> = action;
+			<jk>this</jk>.<jf>value1</jf> = value1;
+			<jk>this</jk>.<jf>value2</jf> = value2;
+		}
+		
+		<jk>public</jk> Form swap(BeanSession session) {
+			<jk>return</jk> <jsm>form</jsm>(<jf>action</jf>,
+				<jsm>input</jsm>(<js>"text"</js>).name(<js>"v1"</js>).value(<jf>value1</jf>),
+				<jsm>input</jsm>(<js>"text"</js>).name(<js>"v2"</js>).value(<jf>value2</jf>)
+			);
+		}
+	}
+		</div>
+
+		<!-- ======================================================================================================== -->
 		<a id="Core.BeanFilters"></a>
-		<h4 class='topic' onclick='toggle(this)'>2.6.2 - BeanFilters and @Bean annotations</h4>
+		<h4 class='topic' onclick='toggle(this)'>2.6.3 - BeanFilters and @Bean annotations</h4>
 		<div class='topic'>
 			<p>
 				{@link org.apache.juneau.transform.BeanFilter BeanFilters} are used to control aspects of how beans are handled during serialization and parsing.
@@ -1127,10 +1251,10 @@
 			<tr class='light bb' style='background-color:lightyellow'>
 				<td style='text-align:center'>5b</td>
 				<td>
-					<b>Objects with standardized <code>static T valueOf(ObjectMap)</code>/<code>static T fromObjectMap(ObjectMap)</code> methods, or constructors with an <code>ObjectMap</code> argument, 
-					and having a <code>toObjectMap()</code> method.</b><br>
-					During serialization, objects are converted to {@link org.apache.juneau.ObjectMap ObjectMaps} using the <code>toObjectMap()</code> method.
-					During parsing, maps are converted to objects using one of these static methods or constructors.				
+					<b>Objects with standardized <code>Object swap(BeanSession)</code>/<code>static T unswap(BeanSession,Object)</code> methods, or constructors with an <code>Object</code> argument
+					where the objects are any object on this list.</b><br> 
+					During serialization, normal objects are converted to swapped objects using the <code>swap()</code> method.
+					During parsing, swapped objects are converted to normal objects using the static method or constructor.				
 				</td>
 				<td>&nbsp;</td>
 				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
@@ -5344,6 +5468,9 @@
 				<li>{@link org.apache.juneau.transform.PojoSwap#swap(BeanSession,Object)}
 				<li>{@link org.apache.juneau.transform.PojoSwap#unswap(BeanSession,Object,ClassMeta)}
 			</ul>
+			<li>Replaced support for <code>toObjectMap()</code> and <code>fromObjectMap()/T(ObjectMap)</code> methods with
+				generalized <code>swap(BeanSession)</code>/<code>unswap(BeanSession,X)</code>/<code>T(BeanSession,X)</code> methods.<br>
+				See new section <a class='doclink' href='#Core.SwapMethods'>Swap methods</a> for information.
 			<li>Session-level media type now available through {@link org.apache.juneau.BeanSession#getMediaType()} method.
 				Allows for swaps and serializer/parser behavior to be tailored to individual media types.
 			<li>Several new {@link java.util.Calendar} and {@link java.util.Date} swaps:
@@ -6994,7 +7121,7 @@
 		<h6 class='topic'>Other changes</h6>
 		<ul class='spaced-list'>
 			<li>Various new methods added to {@link org.apache.juneau.internal.StringUtils} and {@link org.apache.juneau.internal.ClassUtils}.
-			<li>Improved support on {@link org.apache.juneau.BeanContext#getClassMetaFromString(String)}.<br>
+			<li>Improved support on <code><del>BeanContext.getClassMetaFromString(String)</del></code>.<br>
 				Now supports resolving <code>"long[]"</code>, and so forth.
 			<li>{@link org.apache.juneau.rest.labels.ResourceDescription} name parameter is now automatically URL-encoded in links.
 			<li>{@link org.apache.juneau.rest.RestRequest} now correctly handles cases involving URL-encoded characters in the 
@@ -7028,7 +7155,7 @@
 			<li>Support for URL-matching and path info containing encoded characters (e.g. <js>'/'</js>) now supported.	
 			<li>Removed some lazy-initialization of bean information in {@link org.apache.juneau.ClassMeta} that allowed the removal of
 				some synchronized blocks.
-			<li>Improved support of {@link org.apache.juneau.BeanContext#getClassMetaFromString(String)}.
+			<li>Improved support of <code><del>BeanContext.getClassMetaFromString(String)</del></code>.
 				Now supports primitive arrays such as <js>"long[]"</js> in addition to the previous support for the equivalent <js>"[J"</js>.
 			<li>Various new convenience methods added to {@link org.apache.juneau.internal.StringUtils} and {@link org.apache.juneau.internal.ClassUtils}.
 		</ul>