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 2016/08/01 00:08:12 UTC

[23/51] [partial] incubator-juneau git commit: Initial Juno contents from IBM JazzHub repo

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter.java
new file mode 100755
index 0000000..afddef1
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/PojoFilter.java
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2011, 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.filter;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.parser.*;
+import com.ibm.juno.core.serializer.*;
+import com.ibm.juno.core.utils.*;
+
+/**
+ * Used to convert non-serializable objects to a serializable form.
+ *
+ *
+ * <h6 class='topic'>Description</h6>
+ * <p>
+ * 	<code>PojoFilters</code> are used to extend the functionality of the serializers and parsers to be able to handle POJOs
+ * 	that aren't automatically handled by the serializers or parsers.  For example, JSON does not have a standard
+ * 	representation for rendering dates.  By defining a special {@code Date} filter and associating it with a serializer and
+ * 	parser, you can convert a {@code Date} object to a {@code String} during serialization, and convert that {@code String} object back into
+ * 	a {@code Date} object during parsing.
+ * <p>
+ * 	Object filters MUST declare a public no-arg constructor so that the bean context can instantiate them.
+ * <p>
+ * 	<code>PojoFilters</code> are associated with instances of {@link BeanContext BeanContexts} by passing the filter class to
+ * 	the {@link BeanContextFactory#addFilters(Class...)} method.<br>
+ * 	When associated with a bean context, fields of the specified type will automatically be converted when the
+ * 	{@link BeanMap#get(Object)} or {@link BeanMap#put(String, Object)} methods are called.<br>
+ * <p>
+ * 	<code>PojoFilters</code> have two parameters:
+ * 	<ol>
+ * 		<li>{@code <F>} - The filtered representation of an object.
+ * 		<li>{@code <T>} - The normal representation of an object.
+ * 	</ol>
+ * 	<br>
+ * 	{@link Serializer Serializers} use object filters to convert objects of type T into objects of type F, and on calls to {@link BeanMap#get(Object)}.<br>
+ * 	{@link Parser Parsers} use object filters to convert objects of type F into objects of type T, and on calls to {@link BeanMap#put(String,Object)}.
+ *
+ *
+ * <h6 class='topic'>Filtered Class Type {@code <F>}</h6>
+ * <p>
+ * 	The filtered object representation of an object must be an object type that the serializers can
+ * 	natively convert to JSON (or language-specific equivalent).  The list of valid filtered types are as follows...
+ * 	<ul>
+ * 		<li>{@link String}
+ * 		<li>{@link Number}
+ * 		<li>{@link Boolean}
+ * 		<li>{@link Collection} containing anything on this list.
+ * 		<li>{@link Map} containing anything on this list.
+ * 		<li>A java bean with properties of anything on this list.
+ * 		<li>An array of anything on this list.
+ * 	</ul>
+ *
+ *
+ * <h6 class='topic'>Normal Class Type {@code <T>}</h6>
+ * <p>
+ * 	The normal object representation of an object.<br>
+ *
+ *
+ * <h6 class='topic'>One-way vs. Two-way Serialization</h6>
+ * <p>
+ * 	Note that while there is a unified interface for handling filtering during both serialization and parsing,
+ * 	in many cases only one of the {@link #filter(Object)} or {@link #unfilter(Object, ClassMeta)} methods will be defined
+ * 	because the filter is one-way.  For example, a filter may be defined to convert an {@code Iterator} to a {@code ObjectList}, but
+ * 	it's not possible to unfilter an {@code Iterator}.  In that case, the {@code generalize(Object}} method would
+ * 	be implemented, but the {@code narrow(ObjectMap)} object would not, and the filter would be associated on
+ * 	the serializer, but not the parser.  Also, you may choose to serialize objects like {@code Dates} to readable {@code Strings},
+ * 	in which case it's not possible to reparse it back into a {@code Date}, since there is no way for the {@code Parser} to
+ * 	know it's a {@code Date} from just the JSON or XML text.
+ *
+ *
+ * <h6 class='topic'>Additional information</h6>
+ * 	See {@link com.ibm.juno.core.filter} for more information.
+ *
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ * @param <T> The normal form of the class.
+ * @param <F> The filtered form of the class.
+ */
+public abstract class PojoFilter<T,F> extends Filter {
+
+	/** Represents no filter. */
+	public static class NULL extends PojoFilter<Object,Object> {}
+
+	Class<T> normalClass;
+	Class<F> filteredClass;
+	ClassMeta<F> filteredClassMeta;
+
+	/**
+	 * Constructor.
+	 */
+	@SuppressWarnings("unchecked")
+	protected PojoFilter() {
+		super();
+
+		Class<?> c = this.getClass().getSuperclass();
+		Type t = this.getClass().getGenericSuperclass();
+		while (c != PojoFilter.class) {
+			t = c.getGenericSuperclass();
+			c = c.getSuperclass();
+		}
+
+		// Attempt to determine the T and G classes using reflection.
+		if (t instanceof ParameterizedType) {
+			ParameterizedType pt = (ParameterizedType)t;
+			Type[] pta = pt.getActualTypeArguments();
+			if (pta.length == 2) {
+				Type nType = pta[0];
+				if (nType instanceof Class) {
+					this.normalClass = (Class<T>)nType;
+
+				// <byte[],x> ends up containing a GenericArrayType, so it has to
+				// be handled as a special case.
+				} else if (nType instanceof GenericArrayType) {
+					Class<?> cmpntType = (Class<?>)((GenericArrayType)nType).getGenericComponentType();
+					this.normalClass = (Class<T>)Array.newInstance(cmpntType, 0).getClass();
+
+				// <Class<?>,x> ends up containing a ParameterizedType, so just use the raw type.
+				} else if (nType instanceof ParameterizedType) {
+					this.normalClass = (Class<T>)((ParameterizedType)nType).getRawType();
+
+				} else
+					throw new RuntimeException("Unsupported parameter type: " + nType);
+				if (pta[1] instanceof Class)
+					this.filteredClass = (Class<F>)pta[1];
+				else if (pta[1] instanceof ParameterizedType)
+					this.filteredClass = (Class<F>)((ParameterizedType)pta[1]).getRawType();
+				else
+					throw new RuntimeException("Unexpected filtered class type: " + pta[1].getClass().getName());
+			}
+		}
+	}
+
+	/**
+	 * Constructor for when the normal and filtered classes are already known.
+	 *
+	 * @param normalClass The normal class (cannot be serialized).
+	 * @param filteredClass The filtered class (serializable).
+	 */
+	protected PojoFilter(Class<T> normalClass, Class<F> filteredClass) {
+		this.normalClass = normalClass;
+		this.filteredClass = filteredClass;
+	}
+
+	/**
+	 * If this filter is to be used to serialize non-serializable POJOs, it must implement this method.
+	 * <p>
+	 * 	The object must be converted into one of the following serializable types:
+	 * 	<ul>
+	 * 		<li>{@link String}
+	 * 		<li>{@link Number}
+	 * 		<li>{@link Boolean}
+	 * 		<li>{@link Collection} containing anything on this list.
+	 * 		<li>{@link Map} containing anything on this list.
+	 * 		<li>A java bean with properties of anything on this list.
+	 * 		<li>An array of anything on this list.
+	 * 	</ul>
+	 *
+	 * @param o The object to be filtered.
+	 * @return The filtered object.
+	 * @throws SerializeException If a problem occurred trying to convert the output.
+	 */
+	public F filter(T o) throws SerializeException {
+		throw new SerializeException("Generalize method not implemented on filter ''{0}''", this.getClass().getName());
+	}
+
+	/**
+	 * If this filter is to be used to reconstitute POJOs that aren't true Java beans, it must implement this method.
+	 *
+	 * @param f The filtered object.
+	 * @param hint If possible, the parser will try to tell you the object type being created.  For example,
+	 * 	on a serialized date, this may tell you that the object being created must be of type {@code GregorianCalendar}.<br>
+	 * 	This may be <jk>null</jk> if the parser cannot make this determination.
+	 * @return The narrowed object.
+	 * @throws ParseException If this method is not implemented.
+	 */
+	public T unfilter(F f, ClassMeta<?> hint) throws ParseException {
+		throw new ParseException("Narrow method not implemented on filter ''{0}''", this.getClass().getName());
+	}
+
+	/**
+	 * Returns the T class, the normalized form of the class.
+	 *
+	 * @return The normal form of this class.
+	 */
+	public Class<T> getNormalClass() {
+		return normalClass;
+	}
+
+	/**
+	 * Returns the G class, the generialized form of the class.
+	 * <p>
+	 * 	Subclasses must override this method if the generialized class is {@code Object},
+	 * 	meaning it can produce multiple generialized forms.
+	 *
+	 * @return The filtered form of this class.
+	 */
+	public Class<F> getFilteredClass() {
+		return filteredClass;
+	}
+
+	/**
+	 * Returns the {@link ClassMeta} of the filtered class type.
+	 * This value is cached for quick lookup.
+	 *
+	 * @return The {@link ClassMeta} of the filtered class type.
+	 */
+	public ClassMeta<F> getFilteredClassMeta() {
+		if (filteredClassMeta == null)
+			filteredClassMeta = beanContext.getClassMeta(filteredClass);
+		return filteredClassMeta;
+	}
+
+	/**
+	 * Checks if the specified object is an instance of the normal class defined on this filter.
+	 *
+	 * @param o The object to check.
+	 * @return <jk>true</jk> if the specified object is a subclass of the normal class defined on this filter.
+	 * <jk>null</jk> always return <jk>false</jk>.
+	 */
+	public boolean isNormalObject(Object o) {
+		if (o == null)
+			return false;
+		return ClassUtils.isParentClass(normalClass, o.getClass());
+	}
+
+	/**
+	 * Checks if the specified object is an instance of the filtered class defined on this filter.
+	 *
+	 * @param o The object to check.
+	 * @return <jk>true</jk> if the specified object is a subclass of the filtered class defined on this filter.
+	 * <jk>null</jk> always return <jk>false</jk>.
+	 */
+	public boolean isFilteredObject(Object o) {
+		if (o == null)
+			return false;
+		return ClassUtils.isParentClass(filteredClass, o.getClass());
+	}
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* Filter */
+	public Class<?> forClass() {
+		return normalClass;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return getClass().getSimpleName() + '<' + getNormalClass().getSimpleName() + "," + getFilteredClass().getSimpleName() + '>';
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/SurrogateFilter.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/SurrogateFilter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/SurrogateFilter.class
new file mode 100755
index 0000000..20cf6e9
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/SurrogateFilter.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/SurrogateFilter.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/SurrogateFilter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/SurrogateFilter.java
new file mode 100755
index 0000000..52faf3d
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/SurrogateFilter.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.filter;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.annotation.*;
+import com.ibm.juno.core.parser.*;
+import com.ibm.juno.core.serializer.*;
+
+
+/**
+ * Specialized {@link PojoFilter} for surrogate classes.
+ * <p>
+ * Surrogate classes are used in place of other classes during serialization.
+ * For example, you may want to use a surrogate class to change the names or order of bean
+ * properties on a bean.
+ * <p>
+ * The following is an example of a surrogate class change changes a property name:
+ * <p class='bcode'>
+ * 	<jk>public class</jk> SurrogateClass {
+ * 		<jk>public</jk> String surrogateField;  <jc>// New bean property</jc>
+ *
+ * 		<jk>public</jk> SurrogateClass(NormalClass normalClass) {
+ * 			<jk>this</jk>.surrogateField = normalClass.normalField;
+ * 		}
+ * 	}
+ * </p>
+ * <p>
+ * Optionally, a public static method can be used to unfilter a class during parsing:
+ * <p class='bcode'>
+ * 	<jk>public class</jk> SurrogateClass {
+ * 		...
+ * 		<jk>public static</jk> NormalClass <jsm>toNormalClass</jsm>(SurrogateClass surrogateClass) {
+ * 			<jk>return new</jk> NormalClass(surrogateClass.filteredField);
+ * 		}
+ * 	}
+ * </p>
+ * <p>
+ * Surrogate classes must conform to the following:
+ * <ul>
+ * 	<li>It must have a one or more public constructors that take in a single parameter whose type is the normal types.
+ * 		(It is possible to define a class as a surrogate for multiple class types by using multiple constructors with
+ * 		different parameter types).
+ * 	<li>It optionally can have a public static method that takes in a single parameter whose type is the filtered type
+ * 		and returns an instance of the normal type.  This is called the unfilter method.  The method can be called anything.
+ * 	<li>If an unfilter method is present, the class must also contain a no-arg constructor (so that the filtered class
+ * 		can be instantiated by the parser before being converted into the normal class by the unfilter method).
+ * </ul>
+ * <p>
+ * Surrogate classes are associated with serializers and parsers using the {@link CoreApi#addFilters(Class...)} method.
+ * <p class='bcode'>
+ * 	<ja>@Test</ja>
+ * 	<jk>public void</jk> test() <jk>throws</jk> Exception {
+ * 		JsonSerializer s = <jk>new</jk> JsonSerializer.Simple().addFilters(Surrogate.<jk>class</jk>);
+ * 		JsonParser p = <jk>new</jk> JsonParser().addFilters(Surrogate.<jk>class</jk>);
+ * 		String r;
+ * 		Normal n = Normal.<jsm>create</jsm>();
+ *
+ * 		r = s.serialize(n);
+ * 		assertEquals(<js>"{f2:'f1'}"</js>, r);
+ *
+ * 		n = p.parse(r, Normal.<jk>class</jk>);
+ * 		assertEquals(<js>"f1"</js>, n.f1);
+ * 	}
+ *
+ * 	<jc>// The normal class</jc>
+ * 	<jk>public class</jk> Normal {
+ * 		<jk>public</jk> String f1;
+ *
+ * 		<jk>public static</jk> Normal <jsm>create</jsm>() {
+ * 			Normal n = <jk>new</jk> Normal();
+ * 			n.f1 = <js>"f1"</js>;
+ * 			<jk>return</jk> n;
+ * 		}
+ * 	}
+ *
+ * 	<jc>// The surrogate class</jc>
+ * 	<jk>public static class</jk> Surrogate {
+ * 		<jk>public</jk> String f2;
+ *
+ * 		<jc>// Surrogate constructor</jc>
+ * 		<jk>public</jk> Surrogate(Normal n) {
+ * 			f2 = n.f1;
+ * 		}
+ *
+ * 		<jc>// Constructor used during parsing (only needed if unfilter method specified)</jc>
+ * 		<jk>public</jk> Surrogate() {}
+ *
+ * 		<jc>// Unfilter method (optional)</jc>
+ * 		<jk>public static</jk> Normal <jsm>toNormal</jsm>(Surrogate f) {
+ * 			Normal n = <jk>new</jk> Normal();
+ * 			n.f1 = f.f2;
+ * 			<jk>return</jk> n;
+ * 		}
+ * 	}
+ * </p>
+ * <p>
+ * It should be noted that a surrogate class is functionally equivalent to the following {@link PojoFilter} implementation:
+ * <p class='bcode'>
+ * 	<jk>public static class</jk> SurrogateFilter <jk>extends</jk> PojoFilter&lt;Normal,Surrogate&gt; {
+ * 		<jk>public</jk> Surrogate filter(Normal n) <jk>throws</jk> SerializeException {
+ * 			<jk>return new</jk> Surrogate(n);
+ * 		}
+ * 		<jk>public</jk> Normal unfilter(Surrogate s, ClassMeta<?> hint) <jk>throws</jk> ParseException {
+ * 			<jk>return</jk> Surrogate.<jsm>toNormal</jsm>(s);
+ * 		}
+ * 	}
+ * </p>
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ * @param <T> The class type that this filter applies to.
+ * @param <F> The filtered class type.
+ */
+public class SurrogateFilter<T,F> extends PojoFilter<T,F> {
+
+	private Constructor<F> constructor;   // public F(T t);
+	private Method unfilterMethod;        // public static T valueOf(F f);
+
+	/**
+	 * Constructor.
+	 *
+	 * @param forClass The normal class.
+	 * @param constructor The constructor on the surrogate class that takes the normal class as a parameter.
+	 * @param unfilterMethod The static method that converts surrogate objects into normal objects.
+	 */
+	protected SurrogateFilter(Class<T> forClass, Constructor<F> constructor, Method unfilterMethod) {
+		super(forClass, constructor.getDeclaringClass());
+		this.constructor = constructor;
+		this.unfilterMethod = unfilterMethod;
+	}
+
+	/**
+	 * Given the specified surrogate class, return the list of POJO filters.
+	 * A filter is returned for each public 1-arg constructor found.
+	 * Returns an empty list if no public 1-arg constructors are found.
+	 *
+	 * @param c The surrogate class.
+	 * @return The list of POJO filters that apply to this class.
+	 */
+	@SuppressWarnings({"unchecked", "rawtypes"})
+	public static List<SurrogateFilter<?,?>> findFilters(Class<?> c) {
+		List<SurrogateFilter<?,?>> l = new LinkedList<SurrogateFilter<?,?>>();
+		for (Constructor<?> cc : c.getConstructors()) {
+			if (cc.getAnnotation(BeanIgnore.class) == null) {
+				Class<?>[] pt = cc.getParameterTypes();
+
+				// Only constructors with one parameter.
+				// Ignore instance class constructors.
+				if (pt.length == 1 && pt[0] != c.getDeclaringClass()) {
+					int mod = cc.getModifiers();
+					if (Modifier.isPublic(mod)) {  // Only public constructors.
+
+						// Find the unfilter method if there is one.
+						Method unfilterMethod = null;
+						for (Method m : c.getMethods()) {
+							if (pt[0].equals(m.getReturnType())) {
+								Class<?>[] mpt = m.getParameterTypes();
+								if (mpt.length == 1 && mpt[0].equals(c)) { // Only methods with one parameter and where the return type matches this class.
+									int mod2 = m.getModifiers();
+									if (Modifier.isPublic(mod2) && Modifier.isStatic(mod2))  // Only public static methods.
+										unfilterMethod = m;
+								}
+							}
+						}
+
+						l.add(new SurrogateFilter(pt[0], cc, unfilterMethod));
+					}
+				}
+			}
+		}
+		return l;
+	}
+
+	@Override /* PojoFilter */
+	public F filter(T o) throws SerializeException {
+		try {
+			return constructor.newInstance(o);
+		} catch (Exception e) {
+			throw new SerializeException(e);
+		}
+	}
+
+	@Override /* PojoFilter */
+	@SuppressWarnings("unchecked")
+	public T unfilter(F f, ClassMeta<?> hint) throws ParseException {
+		if (unfilterMethod == null)
+			throw new ParseException("static valueOf({0}) method not implement on surrogate class ''{1}''", f.getClass().getName(), getNormalClass().getName());
+		try {
+			return (T)unfilterMethod.invoke(null, f);
+		} catch (Exception e) {
+			throw new ParseException(e);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/doc-files/classes.dnx
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/doc-files/classes.dnx b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/doc-files/classes.dnx
new file mode 100755
index 0000000..72c091b
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/doc-files/classes.dnx
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--xtools2_universal_type_manager-->
+<?com.ibm.xtools.emf.core.signature <signature id="com.ibm.xtools.mmi.ui.signatures.diagram" version="7.0.0"><feature description="" name="Rational Modeling Platform (com.ibm.xtools.rmp)" url="" version="7.0.0"/></signature>?>
+<umlnotation:UMLDiagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/3.0.0/UML" xmlns:umlnotation="http://www.ibm.com/xtools/1.5.3/Umlnotation" xmi:id="_14FVwJJREeKbSvxwiT0Fog" type="Class" name="classes.dnx">
+  <eAnnotations xmi:id="_14FVwZJREeKbSvxwiT0Fog" source="com.ibm.xtools.common.ui.reduction.editingCapabilities">
+    <details xmi:id="_14FVwpJREeKbSvxwiT0Fog" key="com.ibm.xtools.viz.java.webservice.capability" value="1"/>
+    <details xmi:id="_14FVw5JREeKbSvxwiT0Fog" key="com.ibm.xtools.activities.javaVisualizerActivity" value="1"/>
+  </eAnnotations>
+  <children xmi:type="umlnotation:UMLShape" xmi:id="_3ZQ0oJJREeKbSvxwiT0Fog" fontName="Segoe UI" fontHeight="8" showListSignature="true" fillColor="14286847" transparency="0" lineColor="3394764" lineWidth="1" roundedBendpointsRadius="4">
+    <children xmi:type="notation:DecorationNode" xmi:id="_3ZSCwJJREeKbSvxwiT0Fog" type="ImageCompartment">
+      <layoutConstraint xmi:type="notation:Size" xmi:id="_3ZSCwZJREeKbSvxwiT0Fog" width="1320" height="1320"/>
+    </children>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_3ZSCwpJREeKbSvxwiT0Fog" type="Stereotype"/>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_3ZSp0JJREeKbSvxwiT0Fog" type="Name"/>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_3ZSp0ZJREeKbSvxwiT0Fog" type="Parent"/>
+    <children xmi:type="notation:ListCompartment" xmi:id="_3ZSp0pJREeKbSvxwiT0Fog" visible="false" type="ANNOTATION_COMPARTMENT"/>
+    <children xmi:type="notation:ListCompartment" xmi:id="_3ZSp05JREeKbSvxwiT0Fog" visible="false" type="ANNOTATED_ATTRIBUTE_COMPARTMENT"/>
+    <children xmi:type="notation:ListCompartment" xmi:id="_3ZTQ4JJREeKbSvxwiT0Fog" visible="false" type="ANNOTATED_OPERATION_COMPARTMENT" filtering="Manual">
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=Filter%5Esign=(QClass%3C*%3E;Z)V%5Bjsrctype%5Ename=Filter%5Bjcu%5Ename=Filter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=forClass%5Esign=()QClass%3C*%3E;%5Bjsrctype%5Ename=Filter%5Bjcu%5Ename=Filter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=isBeanFilter%5Esign=()Z%5Bjsrctype%5Ename=Filter%5Bjcu%5Ename=Filter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+    </children>
+    <element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=Filter%5Bjcu%5Ename=Filter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D$uml.Class"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_3ZQ0oZJREeKbSvxwiT0Fog" x="9193" y="3170"/>
+  </children>
+  <children xmi:type="umlnotation:UMLShape" xmi:id="_64c4UJJREeKbSvxwiT0Fog" fontName="Segoe UI" fontHeight="8" showListSignature="true" fillColor="14286847" transparency="0" lineColor="3394764" lineWidth="1" roundedBendpointsRadius="4">
+    <children xmi:type="notation:DecorationNode" xmi:id="_64dfYJJREeKbSvxwiT0Fog" type="ImageCompartment">
+      <layoutConstraint xmi:type="notation:Size" xmi:id="_64dfYZJREeKbSvxwiT0Fog" width="1320" height="1320"/>
+    </children>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_64dfYpJREeKbSvxwiT0Fog" type="Stereotype"/>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_64dfY5JREeKbSvxwiT0Fog" type="Name"/>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_64dfZJJREeKbSvxwiT0Fog" type="Parent"/>
+    <children xmi:type="notation:ListCompartment" xmi:id="_64eGcJJREeKbSvxwiT0Fog" visible="false" type="ANNOTATION_COMPARTMENT"/>
+    <children xmi:type="notation:ListCompartment" xmi:id="_64eGcZJREeKbSvxwiT0Fog" visible="false" type="ANNOTATED_ATTRIBUTE_COMPARTMENT" collapsed="true" filtering="Manual">
+      <filteredObjects xmi:type="uml:Property" href="mmi:///#jfield%5Ename=normalClass%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Property"/>
+      <filteredObjects xmi:type="uml:Property" href="mmi:///#jfield%5Ename=filteredClass%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Property"/>
+    </children>
+    <children xmi:type="notation:ListCompartment" xmi:id="_64eGcpJREeKbSvxwiT0Fog" type="ANNOTATED_OPERATION_COMPARTMENT" filtering="Manual">
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=PojoFilter%5Esign=()V%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=forClass%5Esign=()QClass%3C*%3E;%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=getNormalClass%5Esign=()QClass%3CQT;%3E;%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=getFilteredClass%5Esign=()QClass%3CQF;%3E;%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=toString%5Esign=()QString;%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+    </children>
+    <children xmi:type="notation:SemanticListCompartment" xmi:id="_64hJwJJREeKbSvxwiT0Fog" visible="false" type="TemplateCompartment">
+      <element xmi:type="uml:RedefinableTemplateSignature" href="mmi:///#jtsig%5Ename=PojoFilter%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.RedefinableTemplateSignature"/>
+    </children>
+    <element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D$uml.Class"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_64c4UZJREeKbSvxwiT0Fog" x="11095" y="6974"/>
+  </children>
+  <children xmi:type="umlnotation:UMLShape" xmi:id="_aiL3oJJ9EeKbSvxwiT0Fog" fontName="Segoe UI" fontHeight="8" fillColor="14286847" transparency="0" lineColor="3394764" lineWidth="1" roundedBendpointsRadius="4">
+    <children xmi:type="notation:DecorationNode" xmi:id="_aiMesJJ9EeKbSvxwiT0Fog" type="ImageCompartment">
+      <layoutConstraint xmi:type="notation:Size" xmi:id="_aiMesZJ9EeKbSvxwiT0Fog" width="1320" height="1320"/>
+    </children>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_aiMespJ9EeKbSvxwiT0Fog" type="Stereotype"/>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_aiMes5J9EeKbSvxwiT0Fog" type="Name"/>
+    <children xmi:type="notation:BasicDecorationNode" xmi:id="_aiNFwJJ9EeKbSvxwiT0Fog" type="Parent"/>
+    <children xmi:type="notation:ListCompartment" xmi:id="_aiNFwZJ9EeKbSvxwiT0Fog" visible="false" type="ANNOTATION_COMPARTMENT"/>
+    <children xmi:type="notation:ListCompartment" xmi:id="_aiNFwpJ9EeKbSvxwiT0Fog" visible="false" type="ANNOTATED_ATTRIBUTE_COMPARTMENT" filtering="Manual">
+      <filteredObjects xmi:type="uml:Property" href="mmi:///#jfield%5Ename=properties%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Property"/>
+      <filteredObjects xmi:type="uml:Property" href="mmi:///#jfield%5Ename=excludeProperties%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Property"/>
+    </children>
+    <children xmi:type="notation:ListCompartment" xmi:id="_aiNFw5J9EeKbSvxwiT0Fog" type="ANNOTATED_OPERATION_COMPARTMENT" filtering="Manual">
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=BeanFilter%5Esign=()V%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=BeanFilter%5Esign=(QClass%3CQT;%3E;)V%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=setProperties%5Esign=(%255bQString;)QBeanFilter%3CQT;%3E;%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=setExcludeProperties%5Esign=(%255bQString;)QBeanFilter%3CQT;%3E;%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=setPropertyNamer%5Esign=(QClass%3C+QPropertyNamer;%3E;)QBeanFilter%3CQT;%3E;%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=setSubTypeProperty%5Esign=(QString;)QBeanFilter%3CQT;%3E;%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=setSubTypes%5Esign=(QLinkedHashMap%3CQClass%3C*%3E;QString;%3E;)QBeanFilter%3CQT;%3E;%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=addSubType%5Esign=(QClass%3C*%3E;QString;)QBeanFilter%3CQT;%3E;%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+      <filteredObjects xmi:type="uml:Operation" href="mmi:///#jmethod%5Ename=setInterfaceClass%5Esign=(QClass%3C*%3E;)QBeanFilter%3CQT;%3E;%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Operation"/>
+    </children>
+    <children xmi:type="notation:SemanticListCompartment" xmi:id="_aiRXMJJ9EeKbSvxwiT0Fog" visible="false" type="TemplateCompartment">
+      <element xmi:type="uml:RedefinableTemplateSignature" href="mmi:///#jtsig%5Ename=BeanFilter%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.RedefinableTemplateSignature"/>
+    </children>
+    <element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D$uml.Class"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_aiL3oZJ9EeKbSvxwiT0Fog" x="4755" y="6023"/>
+  </children>
+  <element xsi:nil="true"/>
+  <edges xmi:type="umlnotation:UMLConnector" xmi:id="_681pEJJREeKbSvxwiT0Fog" source="_64c4UJJREeKbSvxwiT0Fog" target="_3ZQ0oJJREeKbSvxwiT0Fog" fontName="Segoe UI" fontHeight="8" roundedBendpointsRadius="4" routing="Rectilinear" lineColor="8421504" lineWidth="1" showStereotype="Text">
+    <children xmi:type="notation:DecorationNode" xmi:id="_682QIJJREeKbSvxwiT0Fog" type="NameLabel">
+      <children xmi:type="notation:BasicDecorationNode" xmi:id="_682QIpJREeKbSvxwiT0Fog" type="Stereotype"/>
+      <children xmi:type="notation:BasicDecorationNode" xmi:id="_682QI5JREeKbSvxwiT0Fog" type="Name"/>
+      <layoutConstraint xmi:type="notation:Bounds" xmi:id="_682QIZJREeKbSvxwiT0Fog" y="-186"/>
+    </children>
+    <element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjsrctype%5Ename=PojoFilter%5Bjcu%5Ename=PojoFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=Filter%5Bjcu%5Ename=Filter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Generalization"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_681pEZJREeKbSvxwiT0Fog" points="[-1858, -950, 1012, 1758]$[-1858, -1283, 1012, 1425]$[-2510, -1283, 360, 1425]$[-2510, -2247, 360, 461]"/>
+  </edges>
+  <edges xmi:type="umlnotation:UMLConnector" xmi:id="_ani4wJJ9EeKbSvxwiT0Fog" source="_aiL3oJJ9EeKbSvxwiT0Fog" target="_3ZQ0oJJREeKbSvxwiT0Fog" fontName="Segoe UI" fontHeight="8" roundedBendpointsRadius="4" routing="Rectilinear" lineColor="8421504" lineWidth="1" showStereotype="Text">
+    <children xmi:type="notation:DecorationNode" xmi:id="_anjf0JJ9EeKbSvxwiT0Fog" type="NameLabel">
+      <children xmi:type="notation:BasicDecorationNode" xmi:id="_anjf0pJ9EeKbSvxwiT0Fog" type="Stereotype"/>
+      <children xmi:type="notation:BasicDecorationNode" xmi:id="_anjf05J9EeKbSvxwiT0Fog" type="Name"/>
+      <layoutConstraint xmi:type="notation:Bounds" xmi:id="_anjf0ZJ9EeKbSvxwiT0Fog" y="-186"/>
+    </children>
+    <element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjsrctype%5Ename=BeanFilter%5Bjcu%5Ename=BeanFilter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=Filter%5Bjcu%5Ename=Filter.java%5Bjpack%5Ename=com.ibm.juno.core.filter%5Bjsrcroot%5Esrcfolder=src%5Bproject%5Eid=com.ibm.juno%5D%5D%5D%5D%5D$uml.Generalization"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ani4wZJ9EeKbSvxwiT0Fog" points="[1044, -950, -2481, 1758]$[1044, -1283, -2481, 1425]$[2925, -1283, -600, 1425]$[2925, -2247, -600, 461]"/>
+  </edges>
+</umlnotation:UMLDiagram>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/doc-files/classes.png
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/doc-files/classes.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/doc-files/classes.png
new file mode 100755
index 0000000..0a2ef0d
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/doc-files/classes.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/package.html
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/package.html b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/package.html
new file mode 100755
index 0000000..60ca7d2
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filter/package.html
@@ -0,0 +1,764 @@
+<!DOCTYPE HTML>
+<!--
+    Licensed Materials - Property of IBM
+    (c) Copyright IBM Corporation 2014. All Rights Reserved.
+   
+    Note to U.S. Government Users Restricted Rights:  
+    Use, duplication or disclosure restricted by GSA ADP Schedule 
+    Contract with IBM Corp. 
+ -->
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<style type="text/css">
+		/* For viewing in Page Designer */
+		@IMPORT url("../../../../../../javadoc.css");
+
+		/* For viewing in REST interface */
+		@IMPORT url("../htdocs/javadoc.css");
+		body { 
+			margin: 20px; 
+		}	
+	</style>
+	<script>
+		/* Replace all @code and @link tags. */	
+		window.onload = function() {
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+		}
+	</script>
+</head>
+<body>
+<p>Filter API</p>
+
+<script>
+	function toggle(x) {
+		var div = x.nextSibling;
+		while (div != null && div.nodeType != 1)
+			div = div.nextSibling;
+		if (div != null) {
+			var d = div.style.display;
+			if (d == 'block' || d == '') {
+				div.style.display = 'none';
+				x.className += " closed";
+			} else {
+				div.style.display = 'block';
+				x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' );
+			}
+		}
+	}
+</script>
+
+<a id='TOC'></a><h5 class='toc'>Table of Contents</h5>
+<ol class='toc'>
+	<li><p><a class='doclink' href='#Filters'>Filters</a></p>
+	<ol>
+		<li><p><a class='doclink' href='#BeanFilters'>BeanFilter Class</a></p>
+		<li><p><a class='doclink' href='#PojoFilters'>PojoFilter Class</a></p>
+		<li><p><a class='doclink' href='#PojoFilters_OneWay'>One-Way PojoFilters</a></p>
+		<li><p><a class='doclink' href='#StopClasses'>Stop Classes</a></p>
+		<li><p><a class='doclink' href='#SurrogateClasses'>Surrogate Classes</a></p>
+		<li><p><a class='doclink' href='#ToObjectMaps'>Serializing to ObjectMaps</a></p>
+	</ol>
+</ol>
+
+<!-- ======================================================================================================== -->
+<a id="Filters"></a>
+<h2 class='topic' onclick='toggle(this)'>1 - Filters</h2>
+<div class='topic'>
+	<p>
+		By default, the Juno framework can serialize and parse a wide variety of POJOs out-of-the-box.  
+		However, a <code>Filter</code> API is provided to tailor how certain Java objects are handled by the framework.
+		The class hierarchy is shown here:
+	</p>
+	<ul class='spaced-list'>
+		<li>{@link com.ibm.juno.core.filter.Filter} - Top-level interface for all filters.
+	<ul>
+		<li>{@link com.ibm.juno.core.filter.BeanFilter} - Filters that alter the way beans are handled.
+		<li>{@link com.ibm.juno.core.filter.PojoFilter} - Filters that transform non-serializable POJOs into serializable POJOs during serialization 
+			(and optionally vis-versa during parsing).
+		</ul>
+	</ul>
+	<p>
+		Filters are added to serializers and parsers in a variety of ways:
+	</p> 
+	<ul>
+		<li>{@link com.ibm.juno.core.serializer.Serializer#addFilters(Class[])} - On serializers.
+		<li>{@link com.ibm.juno.core.serializer.SerializerGroup#addFilters(Class[])} - On groups of serializers.
+		<li>{@link com.ibm.juno.core.parser.Parser#addFilters(Class[])} - On parsers.
+		<li>{@link com.ibm.juno.core.parser.ParserGroup#addFilters(Class[])} - On groups of parsers.
+		<li>{@link com.ibm.juno.client.RestClient#addFilters(Class[])} - On the serializer and parser registered on a REST client.
+		<li>{@link com.ibm.juno.server.annotation.RestResource#filters() @RestResource.filters()} - On all serializers and parsers defined on a REST servlet.
+		<li>{@link com.ibm.juno.server.annotation.RestMethod#filters() @RestMethod.filters()} - On all serializers and parsers defined on a method in a REST servlet.
+		<li>{@link com.ibm.juno.server.jaxrs.JunoProvider#filters()} - On all serializers and parsers defined on a JAX-RS provider.
+	</ul>
+	<p>
+		Filters (typically <code>PojoFilters</code>) can also be associated with classes through the {@link com.ibm.juno.core.annotation.Filter @Filter} annotation. 
+	</p>
+		
+	<!-- ======================================================================================================== -->
+	<a id="BeanFilters"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.1 - BeanFilter Class</h3>
+	<div class='topic'>
+		<p>
+			Bean filters are used to tailor how Juno handles bean classes.
+			They can be used for the following purposes:
+		</p>
+		<ul>
+			<li>Include or exclude which properties are exposed in beans, or the order those properties are serialized.
+			<li>Define property-namers for customizing bean property names.
+			<li>Define bean subtypes.
+			<li>Define bean interface classes.
+		</ul>
+		<p>
+			It should be noted that the {@link com.ibm.juno.core.annotation.Bean @Bean} annotation provides equivalent functionality
+				through annotations.  
+			However, the <code>BeanFilter</code> class allows you to provide the same features when you do
+				not have access to the source code.
+		<p>
+		<h5 class='topic'>Examples</h5>
+
+		<h6 class='topic'>Explicitly specify which properties are visible on a bean class</h6>
+		<p class='bcode'>
+	<jc>// Define filter that orders properties by "age" then "name"</jc>
+	<jk>public class</jk> MyFilter <jk>extends</jk> BeanFilter&ltPerson&gt; {
+		<jk>public</jk> MyFilter() {
+			setProperties(<js>"age"</js>,<js>"name"</js>);
+		}
+	}
+	
+	WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(MyFilter.<jk>class</jk>);
+	Person p = getPerson();
+	String json = s.serialize(p);  <jc>// Prints "{age:45,name:'John Smith'}"</jc>
+		</p>
+		<p>
+			Note that this is equivalent to specifying the following annotation on the bean class:
+		</p>
+		<p class='bcode'>
+	<ja>@Bean</ja>(properties={<js>"age"</js>,<js>"name"</js>})
+	<jk>public class</jk> Person {
+		...
+	}
+		</p>
+
+		<h6 class='topic'>Exclude which properties are visible on a bean class</h6>
+		<p class='bcode'>
+	<jc>// Define filter that excludes "name"</jc>
+	<jk>public class</jk> MyFilter <jk>extends</jk> BeanFilter&ltPerson&gt; {
+		<jk>public</jk> MyFilter() {
+			setExcludeProperties(<js>"name"</js>);
+		}
+	}
+	
+	WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(MyFilter.<jk>class</jk>);
+	Person p = getPerson();
+	String json = s.serialize(p);  <jc>// Prints "{age:45}"</jc>
+		</p>
+		<p>
+			Note that this is equivalent to specifying the following annotation on the bean class:
+		</p>
+		<p class='bcode'>
+	<ja>@Bean</ja>(excludeProperties={<js>"name"</js>})
+	<jk>public class</jk> Person {
+		...
+	}
+		</p>
+
+		<h6 class='topic'>Define specialized property namers</h6>
+		<p class='bcode'>
+	<jc>// Define filter with our own property namer.</jc>
+	<jk>public class</jk> MyFilter <jk>extends</jk> BeanFilter&ltPerson&gt; {
+		<jk>public</jk> MyFilter() {
+			setPropertyNamer(UpperCasePropertyNamer.<jk>class</jk>);
+		}
+	}
+
+	<jc>// Define property namer that upper-cases the property names</jc>	
+	<jk>public class</jk> UpperCasePropertyNamer <jk>implements</jk> PropertyNamer {
+	
+		<ja>@Override</ja>
+		<jk>public</jk> String getPropertyName(String name) {
+			<jk>return</jk> name.toUpperCase();
+		}
+	}
+	
+	<jc>// Serialize to JSON</jc>
+	WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(MyFilter.<jk>class</jk>);
+	Person person = getPerson();
+	String json = s.serialize(p);  <jc>// Prints "{AGE:45,NAME:'John Smith'}"</jc>
+	
+	<jc>// Parse back into bean</jc>
+	ReaderParser p = <jk>new</jk> JsonParser().addFilters(MyFilter.<jk>class</jk>);
+	person = p.parse(json, Person.class); <jc>// Read back into original object</jc>
+		</p>
+		<p>
+			Note that this is equivalent to specifying the following annotation on the bean class:
+		</p>
+		<p class='bcode'>
+	<ja>@Bean</ja>(propertyNamer=UpperCasePropertyNamer.<jk>class</jk>)
+	<jk>public class</jk> Person {
+		...
+	}
+		</p>
+		
+		<h6 class='topic'>Define bean subtypes</h6>
+		<p>
+			Juno allows you to losslessly serialize and parse abstract class fields back into the original 
+				concrete objects by defining a subtype attribute and a list of subtypes/ids.
+		</p>
+		<p>
+			For example, let's define the following parent class with two subclasses:
+		</p>
+		<p class='bcode'>
+	<jc>// Abstract parent class</jc>
+	<jk>public abstract class</jk> MyClass {
+		<jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+	}
+
+	<jc>// Subclass 1</jc>
+	<jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+		<jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+	}
+	
+	<jc>// Subclass 2</jc>
+	<jk>public class</jk> MyClassBaz <jk>extends</jk> MyClass {
+		<jk>public</jk> String <jf>baz</jf>=<js>"baz"</js>;
+	}
+		</p>
+		<p>
+			Normally, when parsing a serialized <code>MyClass</code> object, the parser does not know what subtype to create.
+			This can be fixed by defining the following filter:
+		</p>		
+		<p class='bcode'>
+	<jc>// Define filter with our own property namer.</jc>
+	<jk>public class</jk> MyClassFilter <jk>extends</jk> BeanFilter&ltMyClass&gt; {
+		<jk>public</jk> MyClassFilter() {
+			setSubTypeProperty(<js>"subType"</js>);
+			addSubType(MyClassBar.<jk>class</jk>, <js>"BAR"</js>);
+			addSubType(MyClassBaz.<jk>class</jk>, <js>"BAZ"</js>);
+		}
+	}
+		</p>
+		<p>
+			When serialized, the serialized bean will include a <code>"subType"</code> attribute that identifies the subclass, and
+				allows it to be parsed back into the original subclass.
+		</p>
+		<p class='bcode'>
+	<jc>// Serialize to JSON</jc>
+	WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(MyClassFilter.<jk>class</jk>);
+	MyClass c = <jk>new</jk> MyClassBar();
+	String json = s.serialize(p);  <jc>// Prints "{subType:'BAR',foo:'foo',bar:'bar'}"</jc>
+	
+	<jc>// Parse back into bean</jc>
+	ReaderParser p = <jk>new</jk> JsonParser().addFilters(MyClassFilter.<jk>class</jk>);
+	c = p.parse(json, MyClass.<jk>class</jk>); <jc>// c is an instance of MyClassBar</jc>
+		</p>	
+		<p>
+			It should be noted that the sub type attribute is always rendered first in the JSON object so 
+				that the bean object can be instantiated before the real properties are set on it during parsing.  
+			Beans with subtypes are thus 'lazy-instantiated' when the sub type attribute is set.
+			If the sub type attribute is not listed first, the parser will still be able to parse the input,
+			but with reduced efficiency since it must cache the incoming data until the bean can be instantiated.
+		</p>
+		<p>
+			Note that this filter is equivalent to specifying the following annotation on the bean class:
+		</p>
+		<p class='bcode'>
+	<ja>@Bean</ja>(
+		subTypeProperty=<js>"subType"</js>,
+		subTypes={
+			<ja>@BeanSubType</ja>(type=MyClassBar.<jk>class</jk>, id=<js>"BAR"</js>),
+			<ja>@BeanSubType</ja>(type=MyClassBaz.<jk>class</jk>, id=<js>"BAZ"</js>)
+		}
+	)
+	<jk>public abstract class</jk> MyClass {
+		...
+	}
+		</p>
+			
+		<h6 class='topic'>Limiting bean properties to parent bean classes</h6>
+		<p>
+			Occassionally, you may want to limit bean properties to some parent interface.
+			For example, in the <code>RequestEchoResource</code> class in the sample war file, we serialize instances of
+				<code>HttpServletRequest</code> and <code>HttpServletResponse</code>.
+			However, we really only want to serialize the properties defined on those specific APIs, not 
+				vendor-specific methods on the instances of those classes.
+			This can be done through the <code>interfaceClass</code> property of a bean filter.
+		</p>
+		<p>
+			For example, let's define the following parent class and subclass:
+		</p>
+		<p class='bcode'>
+	<jc>// Abstract parent class</jc>
+	<jk>public abstract class</jk> MyClass {
+		<jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+	}
+
+	<jc>// Subclass 1</jc>
+	<jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+		<jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+	}
+		</p>
+		<p>
+			Suppose we only want to render the properties defined on <code>MyClass</code>, not those defined on child classes.
+			To do so, we can define the following filter:
+		</p>
+		<p class='bcode'>
+	<jc>// Define filter that limits properties to only those defined on MyClass</jc>
+	<jk>public class</jk> MyClassFilter <jk>extends</jk> BeanFilter&ltMyClass&gt; {
+		<jk>public</jk> MyClassFilter() {
+			setInterfaceClass(MyClass.<jk>class</jk>);
+		}
+	}
+		</p>
+		<p>
+			When serialized, the serialized bean will only include properties defined on the parent class.
+		</p>
+		<p class='bcode'>
+	<jc>// Serialize to JSON</jc>
+	WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(MyClassFilter.<jk>class</jk>);
+	MyClass c = <jk>new</jk> MyClassBar();
+	String json = s.serialize(p);  <jc>// Prints "{foo:'foo'}"</jc>
+		</p>	
+		<p>
+			The equivalent can be done through an annotation on the parent class, which applies to all child classes:
+		</p>
+		<p class='bcode'>
+	<ja>@Bean</ja>(interfaceClass=MyClass.<jk>class</jk>)
+	<jk>public abstract class</jk> MyClass {
+		<jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+	}
+		</p>
+		<p>
+			The annotation can also be applied on the individual child classes, like so...
+		</p>
+		<p class='bcode'>
+	<ja>@Bean</ja>(interfaceClass=MyClass.<jk>class</jk>)
+	<jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+		<jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+	}
+		</p>
+		<p>
+			Also, the <code>addFilters(...)</code> methods will automatically interpret any non-<code>Filter</code> classes
+				passed in as meaning interface classes.  
+			So in the previous example, the <code>BeanFilter</code> class could have been avoided altogether by just 
+				passing in <code>MyClass.<jk>class</jk></code> to the serializer, like so:
+		</p>
+		<p class='bcode'>
+	<jc>// Serialize to JSON</jc>
+	WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(MyClass.<jk>class</jk>);
+		</p>
+		<p>
+			In fact, this is the shortcut used in the <code>RequestEchoResource</code> sample class:
+		</p>
+		<p class='bcode'>
+	<ja>@RestResource</ja>(
+		filters={
+			<jc>// Interpret these as their parent classes, not subclasses</jc>
+			HttpServletRequest.<jk>class</jk>, HttpSession.<jk>class</jk>, ServletContext.<jk>class</jk>
+		}
+	)
+	<jk>public class</jk> RequestEchoResource <jk>extends</jk> RestServletDefault {
+		</p>
+		
+		<h6 class='topic'>Allowing non-public bean classes/methods/fields to be used by the framework</h6>
+		<p>
+			By default, only public classes are interpreted as beans.  Non-public classes are treated as 'other' POJOs that
+			are typically just serialized to strings using the <code>toString()</code> method.
+			Likewise, by default, only public fields/methods are interpreted as bean properties.
+		</p>
+		<p>
+			The following bean context properties can be used to allow non-public classes/methods/fields to be
+			used by the framework:
+		</p>
+		<ul>
+			<li>{@link com.ibm.juno.core.BeanContextProperties#BEAN_beanClassVisibility}
+			<li>{@link com.ibm.juno.core.BeanContextProperties#BEAN_beanConstructorVisibility}
+			<li>{@link com.ibm.juno.core.BeanContextProperties#BEAN_methodVisibility}
+			<li>{@link com.ibm.juno.core.BeanContextProperties#BEAN_beanFieldVisibility}
+		</ul>
+		<p>
+			Also, specifying a {@link com.ibm.juno.core.annotation.BeanProperty @BeanProperty} annotation on non-public getters/setters/fields
+				will also allow them to be detected by the framework.
+		</p>
+		<p class='bcode'>
+	<jk>public class</jk> MyBean {
+		<jc>// A bean property</jc>
+		<jk>public int</jk> f1;    
+		
+		<jc>// Not a bean property</jc>
+		<ja>@BeanIgnore</ja>
+		<jk>public int</jk> f2;     
+		
+		<jc>// A bean property</jc>
+		<ja>@BeanProperty</ja>    
+		<jk>protected int</jk> f3;  
+		
+		<jc>// A bean property</jc>
+		<ja>@BeanProperty</ja>    
+		<jk>private int</jk> getF3() {...}
+	}
+		</p>
+	</div>
+
+	<!-- ======================================================================================================== -->
+	<a id="PojoFilters"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.2 - PojoFilter Class</h3>
+	<div class='topic'>
+		<p>
+			{@link com.ibm.juno.core.filter.PojoFilter PojoFilters} are a critical component of the Juno architecture.  
+			They allow the Juno serializers and parsers to be extended to handle virtually any kind of Java object. 
+		</p>
+		<p>
+			As explained in the overview, Juno has built-in support for serializing and parsing specific kinds of objects, like primitive objects, bean, maps, collections, and arrays.  
+			Other kinds of POJOs, such as {@code Date} objects, cannot be serialized properly, since they are not true beans.  
+			This is where <code>PojoFilters</code> come into play.
+		</p>
+		<p>
+			The purpose of an <code>PojoFilter</code> is to convert a non-serializable object to a serializable surrogate form during serialization, and to optionally convert that surrogate form back into the original object during parsing.
+		</p>
+		<p>
+			For example, the following filter can be used to convert {@link java.util.Date} objects to ISO8601 strings during serialization, and {@link java.util.Date} objects from ISO8601 string during parsing:
+		</p>
+		<p class='bcode'>
+	<jc>// Sample filter for converting Dates to ISO8601 strings.</jc>
+	<jk>public class</jk> MyDateFilter <jk>extends</jk> PojoFilter&lt;Date,String&gt; {
+		
+		<jc>// ISO8601 formatter.</jc>
+		<jk>private</jk> DateFormat <jf>format</jf> = <jk>new</jk> SimpleDateFormat(<js>"yyyy-MM-dd'T'HH:mm:ssZ"</js>);
+		
+		<jd>/** Converts a Date object to an ISO8601 string. */</jd>
+		<ja>@Override</ja>
+		<jk>public</jk> String filter(Date o) {
+			<jk>return</jk> <jf>format</jf>.format(o);
+		}
+		
+		<jd>/** Converts an ISO8601 string to a Date object. */</jd>
+		<ja>@Override</ja>
+		<jk>public</jk> Date unfilter(String o, ClassMeta&lt;?&gt; hint) <jk>throws</jk> ParseException {
+			<jk>try</jk> {
+				<jk>return</jk> <jf>format</jf>.parse(o);
+			} <jk>catch</jk> (java.text.ParseException e) {
+				<jk>throw new</jk> ParseException(e);
+			}
+		}
+	}
+		</p>
+		<p>
+			The filter above can then be associated with serializers and parsers as the following example shows:
+		</p>
+		<p class='bcode'>
+	<jc>// Sample bean with a Date field.</jc>
+	<jk>public class</jk> MyBean {
+		<jk>public</jk> Date <jf>date</jf> = <jk>new</jk> Date(112, 2, 3, 4, 5, 6);
+	}
+
+	<jc>// Create a new JSON serializer, associate our date filter with it, and serialize a sample bean.</jc>
+	Serializer serializer = <jk>new</jk> JsonSerializer().addFilters(MyDateFilter.<jk>class</jk>);
+	String json = serializer.serialize(<jk>new</jk> MyBean());	<jc>// == "{date:'2012-03-03T04:05:06-0500'}"</jc>
+	
+	<jc>// Create a JSON parser, associate our date filter with it, and reconstruct our bean (including the date).</jc>
+	ReaderParser parser = <jk>new</jk> JsonParser().addFilters(MyDateFilter.<jk>class</jk>);
+	MyBean bean = parser.parse(json, MyBean.<jk>class</jk>);
+	<jk>int</jk> day = bean.<jf>date</jf>.getDay(); 						<jc>// == 3</jc>
+		</p>
+		<p>
+			In addition, the {@link com.ibm.juno.core.BeanMap#get(Object)} and {@link com.ibm.juno.core.BeanMap#put(String,Object)} methods will automatically convert to filtered values as the following example shows:
+		</p>
+		<p class='bcode'>
+	<jc>// Create a new bean context and add our filter.</jc>
+	BeanContext beanContext = <jk>new</jk> BeanContext().addFilters(MyDateFilter.<jk>class</jk>);
+
+	<jc>// Create a new bean.</jc>
+	MyBean myBean = <jk>new</jk> MyBean();
+
+	<jc>// Wrap it in a bean map.</jc>
+	BeanMap&lt;Bean&gt; beanMap = beanContext.forBean(myBean);
+
+	<jc>// Use the get() method to get the date field as an ISO8601 string.</jc>
+	String date = (String)beanMap.get(<js>"date"</js>);				<jc>// == "2012-03-03T04:05:06-0500"</jc> 
+	
+	<jc>// Use the put() method to set the date field to an ISO8601 string.</jc>
+	beanMap.put(<js>"date"</js>, <js>"2013-01-01T12:30:00-0500"</js>);	<jc>// Set it to a new value.</jc> 
+	
+	<jc>// Verify that the date changed on the original bean.</jc>
+	<jk>int</jk> year = myBean.<jf>date</jf>.getYear(); 								<jc>// == 113</jc>
+		</p>
+		<p>
+			Another example of a <code>PojoFilter</code> is one that converts <code><jk>byte</jk>[]</code> arrays to BASE64-encoded strings:
+		</p>
+		<p class='bcode'>
+	<jk>public class</jk> ByteArrayBase64Filter <jk>extends</jk> PojoFilter&lt;<jk>byte</jk>[],String&gt; {
+	
+		<ja>@Override</ja>
+		<jk>public</jk> String filter(<jk>byte</jk>[] b) <jk>throws</jk> SerializeException {
+			<jk>try</jk> {
+				ByteArrayOutputStream baos = <jk>new</jk> ByteArrayOutputStream();
+				OutputStream b64os = MimeUtility.encode(baos, <js>"base64"</js>);
+				b64os.write(b);
+				b64os.close();
+				<jk>return new</jk> String(baos.toByteArray());
+			} <jk>catch</jk> (Exception e) {
+				<jk>throw new</jk> SerializeException(e);
+			}
+		}
+		
+		<ja>@Override</ja>
+		<jk>public byte</jk>[] unfilter(String s, ClassMeta&lt;?&gt; hint) <jk>throws</jk> ParseException {
+			<jk>try</jk> {
+				<jk>byte</jk>[] b = s.getBytes();
+				ByteArrayInputStream bais = <jk>new</jk> ByteArrayInputStream(b);
+				InputStream b64is = MimeUtility.decode(bais, <js>"base64"</js>);
+				<jk>byte</jk>[] tmp = <jk>new byte</jk>[b.length];
+				<jk>int</jk> n = b64is.read(tmp);
+				<jk>byte</jk>[] res = <jk>new byte</jk>[n];
+				System.<jsm>arraycopy</jsm>(tmp, 0, res, 0, n);
+				<jk>return</jk> res;
+			} <jk>catch</jk> (Exception e) {
+				<jk>throw new</jk> ParseException(e);
+			}
+		}
+	}
+		</p>
+		<p>
+			The following example shows the BASE64 filter in use:
+		</p>
+		<p class='bcode'>
+	<jc>// Create a JSON serializer and register the BASE64 encoding filter with it.</jc>
+	Serializer serializer = <jk>new</jk> JsonSerializer().addFilters(ByteArrayBase64Filter.<jk>class</jk>);
+	ReaderParser parser = <jk>new</jk> JsonParser().addFilters(ByteArrayBase64Filter.<jk>class</jk>);
+	
+	<jk>byte</jk>[] a1 = {1,2,3};
+	String s1 = serializer.serialize(a1);		<jc>// Produces "'AQID'"</jc>
+	a1 = parser.parse(s1, <jk>byte</jk>[].<jk>class</jk>);		<jc>// Reproduces {1,2,3}</jc>
+	
+	<jk>byte</jk>[][] a2 = {{1,2,3},{4,5,6},<jk>null</jk>};
+	String s2 = serializer.serialize(a2);		<jc>// Produces "['AQID','BAUG',null]"</jc>
+	a2 = parser.parse(s2, <jk>byte</jk>[][].<jk>class</jk>);		<jc>// Reproduces {{1,2,3},{4,5,6},null}</jc>
+		</p>
+		<p>
+			It should be noted that the sample filters shown above have already been implemented in the {@link com.ibm.juno.core.filters} package.
+			The following are a list of out-of-the-box filters:
+		</p>
+		<ul>
+			<li>{@link com.ibm.juno.core.filters.ByteArrayBase64Filter} - Converts byte arrays to BASE64 encoded strings.
+			<li>{@link com.ibm.juno.core.filters.CalendarFilter} - Filters for converting <code>Calendar</code> objects to various date format strings.
+			<li>{@link com.ibm.juno.core.filters.DateFilter} - Filters for converting <code>Date</code> objects to various date format strings.
+			<li>{@link com.ibm.juno.core.filters.EnumerationFilter} - Filters for converting <code>Enumeration</code> objects to arrays.
+			<li>{@link com.ibm.juno.core.filters.IteratorFilter} - Filters for converting <code>Iterator</code> objects to arrays.
+			<li>{@link com.ibm.juno.core.filters.ReaderFilter} - Filters for converting <code>Readers</code> to objects before serialization.
+			<li>{@link com.ibm.juno.core.filters.XMLGregorianCalendarFilter} - Filters for converting <code>XMLGregorianCalendar</code> objects to ISO8601 strings.
+		</ul>
+		
+		<h6 class='topic'>Valid filtered class types</h6>
+		<p>
+			The filtered class type can be any serializable class type as defined in the <a href='../package-summary.html#PojoCategories'>POJO categories</a> table.
+		</p>
+	</div>
+	
+
+	<!-- ======================================================================================================== -->
+	<a id="PojoFilters_OneWay"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.3 - One-Way PojoFilters</h3>
+	<div class='topic'>
+		<p>
+			In the previous section, we defined two-way filters, meaning filters where the original objects could be reconstructing during parsing.  However, there are certain kinds of POJOs that we may want to support for serializing, but that are not possible to reconstruct during parsing.  For these, we can use one-way object filters.
+		</p>
+		<p>
+			A one-way object filter is simply an object filter that only implements the {@code filter()} method.  The {@code unfilter()} method is simply left unimplemented.
+		</p>
+		<p>
+			An example of a one-way filter would be one that allows {@code Iterators} to be serialized as JSON arrays.  It can make sense to be able to render {@code Iterators} as arrays, but in general it's not possible to reconstruct an {@code Iterator} during parsing. 
+		</p>
+		<p class='bcode'>
+	<jk>public class</jk> IteratorFilter <jk>extends</jk> PojoFilter&lt;Iterator,List&gt; {
+		
+		<ja>@Override</ja>
+		<jk>public</jk> List filter(Iterator o) {
+			List l = <jk>new</jk> LinkedList();
+			<jk>while</jk> (o.hasNext())
+				l.add(o.next());
+			<jk>return</jk> l;
+		}
+	}
+		</p>
+		<p>
+			Here is an example of our one-way filter being used.  Note that trying to parse the original object will cause a {@link com.ibm.juno.core.parser.ParseException} to be thrown.
+		</p>
+		<p class='bcode'>
+	<jc>// Create a JSON serializer that can serialize Iterators.</jc>
+	Serializer serializer = <jk>new</jk> JsonSerializer().addFilters(IteratorFilter.<jk>class</jk>);
+	
+	<jc>// Construct an iterator we want to serialize.</jc>
+	Iterator iterator = <jk>new</jk> ObjectList(1,2,3).iterator();
+	
+	<jc>// Serialize our Iterator</jc>
+	String s = serializer.serialize(iterator);		<jc>// Produces "[1,2,3]"</jc>
+	
+	<jc>// Try to parse it.</jc>
+	ReaderParser parser = <jk>new</jk> JsonParser().addFilters(IteratorFilter.<jk>class</jk>);
+	iterator = parser.parse(s, Iterator.<jk>class</jk>);		<jc>// Throws ParseException!!!</jc>
+		</p>
+	</div>
+
+	<!-- ======================================================================================================== -->
+	<a id="StopClasses"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.4 - Stop Classes</h3>
+	<div class='topic'>
+		<p>
+			Occassionally, you may want to limit bean properties to only those defined on a parent class or interface.  
+			There are a couple of ways of doing this.
+		</p>
+		<p>
+			For example, let's define the following parent class and subclass:
+		</p>
+		<p class='bcode'>
+	<jc>// Abstract parent class</jc>
+	<jk>public abstract class</jk> MyClass {
+		<jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+	}
+
+	<jc>// Subclass 1</jc>
+	<jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+		<jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+	}
+		</p>
+		<p>
+			Suppose we only want to render the properties defined on <code>MyClass</code>, not those defined on child classes. 
+			To do so, we can define the following filter:
+		</p>
+		<p class='bcode'>
+	<jc>// Define filter that limits properties to only those defined on MyClass</jc>
+	<jk>public class</jk> MyClassFilter <jk>extends</jk> BeanFilter&ltMyClass&gt; {
+		<jk>public</jk> MyClassFilter() {
+			setInterfaceClass(MyClass.<jk>class</jk>);
+		}
+	}
+		</p>
+		<p>
+			When serialized, the serialized bean will only include properties defined on the parent class.
+		</p>
+		<p class='bcode'>
+	<jc>// Serialize to JSON</jc>
+	WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(MyClassFilter.<jk>class</jk>);
+	MyClass c = <jk>new</jk> MyClassBar();
+	String json = s.serialize(p);  <jc>// Prints "{foo:'foo'}"</jc>
+		</p>	
+		<p>
+			The equivalent can be done through an annotation on the parent class, which applies to all child classes:
+		</p>
+		<p class='bcode'>
+	<ja>@Bean</ja>(interfaceClass=MyClass.<jk>class</jk>)
+	<jk>public abstract class</jk> MyClass {
+		<jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+	}
+		</p>
+		<p>
+			The annotation can also be applied on the individual child classes, like so...
+		</p>
+		<p class='bcode'>
+	<ja>@Bean</ja>(interfaceClass=MyClass.<jk>class</jk>)
+	<jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+		<jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+	}
+		</p>
+		<p>
+			Also, the <code>addFilters()</code> methods will automatically interpret any non-Filter classes passed in as meaning interface classes. 
+			So in the previous example, the <code>BeanFilter</code> class could have been avoided altogether by just passing in <code>MyClass.<jk>class</jk></code> to the serializer, like so:
+		</p>
+		<p class='bcode'>
+	<jc>// Serialize to JSON</jc>
+	WriterSerializer s = <jk>new</jk> JsonSerializer().addFilters(MyClass.<jk>class</jk>);
+		</p>
+	</div>
+
+	<!-- ======================================================================================================== -->
+	<a id="SurrogateClasses"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.5 - Surrogate Classes</h3>
+	<div class='topic'>
+		<p>
+			Surrogate classes are very similar in concept to one-way <code>PojoFilters</code> except they represent a simpler syntax.
+		</p>
+		<p>
+			For example, let's say we want to be able to serialize the following class, but it's not serializable for some reason (for example, there are no
+			properties exposed):  
+		<p class='bcode'>
+	<jk>public class</jk> MyNonSerializableClass {
+		<jk>protected</jk> String <jf>foo</jf>;
+	}
+		</p>
+		<p>
+			This could be solved with the following <code>PojoFilter</code>.
+		</p>
+		<p class='bcode'>
+	<jk>public class</jk> MySerializableSurrogate {
+		<jk>public</jk> String <jf>foo</jf>;
+	}
+		
+	<jk>public class</jk> MyFilter <jk>extends</jk> PojoFilter&lt;MyNonSerializableClass,MySerializableSurrogate&gt; {
+		
+		<ja>@Override</ja>
+		<jk>public</jk> MySerializableSurrogate filter(MyNonSerializableClass o) {
+			MySerializableSurrogate s = <jk>new</jk> MySerializableSurrogate();
+			s.<jf>foo</jf> = o.<jf>foo</jf>;
+			<jk>return</jk> s;
+		}
+	}
+		</p>
+		<p>
+			However, the same can be accomplished by using a surrogate class that simply contains a constructor with the non-serializable class as an argument:
+		</p>
+		<p class='bcode'>
+	<jk>public class</jk> MySerializableSurrogate {
+		<jk>public</jk> String <jf>foo</jf>;
+		
+		<jk>public</jk> MySerializableSurrogate(MyNonSerializableClass c) {
+			<jk>this</jk>.<jf>foo</jf> = c.<jf>foo</jf>;
+		}
+	}
+		</p>
+		<p>
+			The surrogate class is registered just like any other filter:
+		</p>
+		<p class='bcode'>
+	<jc>// Create a JSON serializer that can serialize Iterators.</jc>
+	Serializer serializer = <jk>new</jk> JsonSerializer().addFilters(MySerializableSurrogate.<jk>class</jk>);
+		</p>
+		<p>
+			When the serializer encounters the non-serializable class, it will serialize an instance of the surrogate instead.
+		</p>
+	</div>
+	
+	<!-- ======================================================================================================== -->
+	<a id="ToObjectMaps"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.6 - Serializing to ObjectMaps</h3>
+	<div class='topic'>
+	<div class='topic'>
+		<p>
+			A shortcut method for filtering is provided that can often be simpler than defining filters.
+			In this case, we add methods to our class to serialize to {@link com.ibm.juno.core.ObjectMap ObjectMaps}
+		</p>
+		<p>
+		<p class='bcode'>
+	<jk>public class</jk> MyClass {
+		<jk>private</jk> String <jf>f1</jf>;
+		
+		<jc>// Constructor that takes in an ObjectMap</jc>
+		<jk>public</jk> MyClass(ObjectMap m) {
+			<jf>f1</jf> = m.getString(<js>"f1"</js>);
+		}
+		
+		<jc>// Method that converts object to an ObjectMap</jc>
+		<jk>public</jk> ObjectMap toObjectMap() {
+			<jk>return new</jk> ObjectMap().append(<js>"f1"</js>, <jf>f1</jf>);
+		}
+		</p>
+		<p>
+			The <code>toObjectMap()</code> method will automatically be used during serialization, and 
+			the constructor will automatically be used during parsing.
+			This will work for all serializers and parsers.
+		</p>
+	</div>
+</div>
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/BeanStringFilter.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/BeanStringFilter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/BeanStringFilter.class
new file mode 100755
index 0000000..5314954
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/BeanStringFilter.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/BeanStringFilter.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/BeanStringFilter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/BeanStringFilter.java
new file mode 100755
index 0000000..9d26786
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/BeanStringFilter.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2011, 2014. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.filters;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.filter.*;
+
+/**
+ * Transforms beans into {@link String Strings} by simply calling the {@link Object#toString()} method.
+ * <p>
+ * 	Allows you to specify classes that should just be converted to {@code Strings} instead of potentially
+ * 	being turned into Maps by the {@link BeanContext} (or worse, throwing {@link BeanRuntimeException BeanRuntimeExceptions}).
+ * <p>
+ * 	This is usually a one-way filter.
+ * 	Beans serialized as strings cannot be reconstituted using a parser unless it is a <a class='doclink' href='../package-summary.html#PojoCategories'>Type 5 POJO</a>.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ * @param <T> The class type of the bean.
+ */
+public class BeanStringFilter<T> extends PojoFilter<T,String> {
+
+	/**
+	 * Converts the specified bean to a {@link String}.
+	 */
+	@Override /* PojoFilter */
+	public String filter(T o) {
+		return o.toString();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/ByteArrayBase64Filter.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/ByteArrayBase64Filter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/ByteArrayBase64Filter.class
new file mode 100755
index 0000000..86985c7
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/ByteArrayBase64Filter.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/ByteArrayBase64Filter.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/ByteArrayBase64Filter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/ByteArrayBase64Filter.java
new file mode 100755
index 0000000..3382ffb
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/ByteArrayBase64Filter.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2011, 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.filters;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.filter.*;
+import com.ibm.juno.core.parser.*;
+import com.ibm.juno.core.serializer.*;
+import com.ibm.juno.core.utils.*;
+
+/**
+ * Transforms <code><jk>byte</jk>[]</code> arrays to BASE-64 encoded {@link String Strings}.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public class ByteArrayBase64Filter extends PojoFilter<byte[],String> {
+
+	/**
+	 * Converts the specified <code><jk>byte</jk>[]</code> to a {@link String}.
+	 */
+	@Override /* PojoFilter */
+	public String filter(byte[] b) throws SerializeException {
+		try {
+			return StringUtils.base64Encode(b);
+		} catch (Exception e) {
+			throw new SerializeException(e);
+		}
+	}
+
+	/**
+	 * Converts the specified {@link String} to a <code><jk>byte</jk>[]</code>.
+	 */
+	@Override /* PojoFilter */
+	public byte[] unfilter(String s, ClassMeta<?> hint) throws ParseException {
+		try {
+			return StringUtils.base64Decode(s);
+		} catch (Exception e) {
+			throw new ParseException(e);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ISO8601DT.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ISO8601DT.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ISO8601DT.class
new file mode 100755
index 0000000..c723505
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ISO8601DT.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ISO8601DTZ.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ISO8601DTZ.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ISO8601DTZ.class
new file mode 100755
index 0000000..1ac8054
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ISO8601DTZ.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$Medium.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$Medium.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$Medium.class
new file mode 100755
index 0000000..afb00ca
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$Medium.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822D.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822D.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822D.class
new file mode 100755
index 0000000..8c219ac
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822D.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822DT.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822DT.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822DT.class
new file mode 100755
index 0000000..257f747
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822DT.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822DTZ.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822DTZ.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822DTZ.class
new file mode 100755
index 0000000..c3f9e2f
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$RFC2822DTZ.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$Simple.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$Simple.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$Simple.class
new file mode 100755
index 0000000..d3e015f
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$Simple.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ToString.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ToString.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ToString.class
new file mode 100755
index 0000000..151b15e
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter$ToString.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter.class
new file mode 100755
index 0000000..98a12e5
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/filters/CalendarFilter.class differ