http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/AsciiSet.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/AsciiSet.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/AsciiSet.java
new file mode 100755
index 0000000..0a35276
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/AsciiSet.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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.utils;
+
+/**
+ * Stores a set of ASCII characters for quick lookup.
+ *
+ * @author James Bognar ([email protected])
+ */
+public final class AsciiSet {
+       final boolean[] store = new boolean[128];
+
+       /**
+        * Constructor.
+        *
+        * @param chars The characters to keep in this store.
+        */
+       public AsciiSet(String chars) {
+               for (int i = 0; i < chars.length(); i++) {
+                       char c = chars.charAt(i);
+                       if (c < 128)
+                               store[c] = true;
+               }
+       }
+
+       /**
+        * Returns <jk>true<jk> if the specified character is in this store.
+        *
+        * @param c The character to check.
+        * @return <jk>true<jk> if the specified character is in this store.
+        */
+       public boolean contains(char c) {
+               if (c > 127)
+                       return false;
+               return store[c];
+       }
+
+       /**
+        * Returns <jk>true<jk> if the specified character is in this store.
+        *
+        * @param c The character to check.
+        * @return <jk>true<jk> if the specified character is in this store.
+        */
+       public boolean contains(int c) {
+               if (c < 0 || c > 127)
+                       return false;
+               return store[c];
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache$1.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache$1.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache$1.class
new file mode 100755
index 0000000..898da0a
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache$1.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/utils/ByteArrayCache$ByteArray.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache$ByteArray.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache$ByteArray.class
new file mode 100755
index 0000000..9040d6c
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache$ByteArray.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/utils/ByteArrayCache.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache.class
new file mode 100755
index 0000000..da300c1
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache.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/utils/ByteArrayCache.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache.java
new file mode 100755
index 0000000..1baee13
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayCache.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 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.utils;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+/**
+ * A utility class for caching byte arrays in memory so that duplicate arrays 
can be reused.
+ * <p>
+ *
+ * @author James Bognar ([email protected])
+ */
+public class ByteArrayCache {
+
+       /**
+        * Default global byte array cache.
+        * Note that this can't ever get garbage collected so don't add really 
large arrays!
+        */
+       public static final ByteArrayCache DEFAULT = new ByteArrayCache();
+
+       private final ConcurrentHashMap<ByteArray,byte[]> cache = new 
ConcurrentHashMap<ByteArray,byte[]>();
+
+       /**
+        * Add the specified byte array to this cache.
+        *
+        * @param contents The byte array to add to this cache.
+        * @return Either the same byte array or a previously cached byte array 
depending on whether the byte array
+        *      already exists in the cache.
+        */
+       public byte[] cache(byte[] contents) {
+               if (contents == null)
+                       return null;
+               ByteArray ba = new ByteArray(contents);
+               cache.putIfAbsent(ba, ba.contents);
+               return cache.get(ba);
+       }
+
+       /**
+        * Add the specified input stream to this cache.
+        *
+        * @param contents The input stream whose contents are to be added to 
this cache.
+        * @return Either the same byte array or a previously cached byte array 
depending on whether the byte array
+        *      already exists in the cache.
+        * @throws IOException
+        */
+       public byte[] cache(InputStream contents) throws IOException {
+               if (contents == null)
+                       return null;
+               ByteArray ba = new ByteArray(IOUtils.readBytes(contents, 1024));
+               cache.putIfAbsent(ba, ba.contents);
+               return cache.get(ba);
+       }
+
+       /**
+        * Returns the number of byte arrays in this cache.
+        *
+        * @return The number of byte arrays in this cache.
+        */
+       public int size() {
+               return cache.size();
+       }
+
+       private static class ByteArray {
+               private int hashCode;
+               private byte[] contents;
+
+               private ByteArray(byte[] contents) {
+                       this.contents = contents;
+                       int multiplier = 1;
+                       for (int i = 0; i < contents.length; i++) {
+                               hashCode += contents[i] * multiplier;
+                               int shifted = multiplier << 5;
+                               multiplier = shifted - multiplier;
+                       }
+               }
+
+               @Override /* Object */
+               public int hashCode() {
+                       if (hashCode == 0) {
+                       }
+                       return hashCode;
+               }
+
+               @Override /* Object */
+               public boolean equals(Object o) {
+                       if (o instanceof ByteArray) {
+                               ByteArray ba = (ByteArray)o;
+                               if (ba.hashCode == hashCode)
+                                       return Arrays.equals(ba.contents, 
contents);
+                       }
+                       return false;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayInOutStream.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayInOutStream.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayInOutStream.class
new file mode 100755
index 0000000..588bee0
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayInOutStream.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/utils/ByteArrayInOutStream.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayInOutStream.java
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayInOutStream.java
new file mode 100755
index 0000000..0e94821
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ByteArrayInOutStream.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 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.utils;
+
+import java.io.*;
+
+/**
+ * Subclass of a ByteArrayOutputStream that avoids a byte array copy when 
reading from an input stream.
+ * <p>
+ * @author James Bognar ([email protected])
+ */
+public class ByteArrayInOutStream extends ByteArrayOutputStream {
+
+       /**
+        * Creates a new input stream from this object.
+        *
+        * @return A new input stream from this object.
+        */
+       public ByteArrayInputStream getInputStream() {
+               return new ByteArrayInputStream(this.buf, 0, this.count);
+       }
+}
\ 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/utils/CharSequenceReader.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CharSequenceReader.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CharSequenceReader.class
new file mode 100755
index 0000000..4b56124
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CharSequenceReader.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/utils/CharSequenceReader.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CharSequenceReader.java
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CharSequenceReader.java
new file mode 100755
index 0000000..9cdd838
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CharSequenceReader.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.utils;
+
+import java.io.*;
+
+/**
+ * Similar to {@link StringReader} except reads from a generic {@link 
CharSequenceReader}.
+ *
+ * @author jbognar
+ */
+public final class CharSequenceReader extends BufferedReader {
+
+       private final CharSequence cs;
+       private String s;
+       private StringBuffer sb;
+       private StringBuilder sb2;
+       private int length;
+       private int next = 0;
+
+       /**
+        * Constructor.
+        *
+        * @param cs The char sequence to read from.  Can be <jk>null</jk>.
+        */
+       public CharSequenceReader(CharSequence cs) {
+               super(new StringReader(""), 1);   // Does not actually use a 
reader.
+               if (cs == null)
+                       cs = "";
+               this.cs = cs;
+               if (cs instanceof String)
+                       s = (String)cs;
+               else if (cs instanceof StringBuffer)
+                       sb = (StringBuffer)cs;
+               else if (cs instanceof StringBuilder)
+                       sb2 = (StringBuilder)cs;
+               this.length = cs.length();
+       }
+
+       @Override /* Reader */
+       public int read() {
+               if (next >= length)
+                       return -1;
+               return cs.charAt(next++);
+       }
+
+       @Override /* Reader */
+       public boolean markSupported() {
+               return false;
+       }
+
+       @Override /* Reader */
+       public int read(final char[] cbuf, final int off, final int len) {
+               if (next >= length)
+                       return -1;
+               int n = Math.min(length - next, len);
+               if (s != null)
+                       s.getChars(next, next + n, cbuf, off);
+               else if (sb != null)
+                       sb.getChars(next, next + n, cbuf, off);
+               else if (sb2 != null)
+                       sb2.getChars(next, next + n, cbuf, off);
+               else {
+                       for (int i = 0; i < n; i++)
+                               cbuf[off+i] = cs.charAt(next+i);
+               }
+               next += n;
+               return n;
+       }
+
+       @Override /* Reader */
+       public long skip(long ns) {
+               if (next >= length)
+                       return 0;
+               long n = Math.min(length - next, ns);
+               n = Math.max(-next, n);
+               next += n;
+               return n;
+       }
+
+       @Override /* Reader */
+       public void close() {
+               // no-op
+       }
+
+       @Override /* Object */
+       public String toString() {
+               return cs.toString();
+       }
+}
\ 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/utils/ClassUtils$ClassComparator.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils$ClassComparator.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils$ClassComparator.class
new file mode 100755
index 0000000..f894333
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils$ClassComparator.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/utils/ClassUtils.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils.class
new file mode 100755
index 0000000..95747e7
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils.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/utils/ClassUtils.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils.java
new file mode 100755
index 0000000..cf79b9d
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ClassUtils.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * 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.utils;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.ibm.juno.core.*;
+
+/**
+ * Class-related utility methods.
+ *
+ * @author James Bognar ([email protected])
+ */
+public final class ClassUtils {
+
+       /**
+        * Given the specified list of objects, return readable names for the 
class types of the objects.
+        *
+        * @param o The objects.
+        * @return An array of readable class type strings.
+        */
+       public static ObjectList getReadableClassNames(Object[] o) {
+               ObjectList l = new ObjectList();
+               for (int i = 0; i < o.length; i++)
+                       l.add(o[i] == null ? "null" : 
getReadableClassName(o[i].getClass()));
+               return l;
+       }
+
+       /**
+        * Shortcut for calling 
<code><jsm>getReadableClassName</jsm>(c.getName())</code>
+        *
+        * @param c The class.
+        * @return A readable class type name, or <jk>null</jk> if parameter is 
<jk>null</jk>.
+        */
+       public static String getReadableClassName(Class<?> c) {
+               if (c == null)
+                       return null;
+               return getReadableClassName(c.getName());
+       }
+
+       /**
+        * Converts the specified class name to a readable form when class name 
is a special construct like <js>"[[Z"</js>.
+        * <p>
+        * Examples:
+        * <p class='bcode'>
+        *      <jsm>getReadableClassName</jsm>(<js>"java.lang.Object"</js>);  
<jc>// Returns "java.lang.Object"</jc>
+        *      <jsm>getReadableClassName</jsm>(<js>"boolean"</js>);  <jc>// 
Returns "boolean"</jc>
+        *      <jsm>getReadableClassName</jsm>(<js>"[Z"</js>);  <jc>// Returns 
"boolean[]"</jc>
+        *      <jsm>getReadableClassName</jsm>(<js>"[[Z"</js>);  <jc>// 
Returns "boolean[][]"</jc>
+        *      
<jsm>getReadableClassName</jsm>(<js>"[Ljava.lang.Object;"</js>);  <jc>// 
Returns "java.lang.Object[]"</jc>
+        *      <jsm>getReadableClassName</jsm>(<jk>null</jk>);  <jc>// Returns 
null</jc>
+        * </p>
+        *
+        * @param className The class name.
+        * @return A readable class type name, or <jk>null</jk> if parameter is 
<jk>null</jk>.
+        */
+       public static String getReadableClassName(String className) {
+               if (className == null)
+                       return null;
+               if (! StringUtils.startsWith(className, '['))
+                       return className;
+               int depth = 0;
+               for (int i = 0; i < className.length(); i++) {
+                       if (className.charAt(i) == '[')
+                               depth++;
+                       else
+                               break;
+               }
+               char type = className.charAt(depth);
+               String c;
+               switch (type) {
+                       case 'Z': c = "boolean"; break;
+                       case 'B': c = "byte"; break;
+                       case 'C': c = "char"; break;
+                       case 'D': c = "double"; break;
+                       case 'F': c = "float"; break;
+                       case 'I': c = "int"; break;
+                       case 'J': c = "long"; break;
+                       case 'S': c = "short"; break;
+                       default: c = className.substring(depth+1, 
className.length()-1);
+               }
+               StringBuilder sb = new StringBuilder(c.length() + 
2*depth).append(c);
+               for (int i = 0; i < depth; i++)
+                       sb.append("[]");
+               return sb.toString();
+       }
+
+       /**
+        * Returns <jk>true</jk> if <code>parent</code> is a parent class of 
<code>child</code>.
+        *
+        * @param parent The parent class.
+        * @param child The child class.
+        * @param strict If <jk>true</jk> returns <jk>false</jk> if the classes 
are the same.
+        * @return <jk>true</jk> if <code>parent</code> is a parent class of 
<code>child</code>.
+        */
+       public static boolean isParentClass(Class<?> parent, Class<?> child, 
boolean strict) {
+               return parent.isAssignableFrom(child) && ((!strict) || ! 
parent.equals(child));
+       }
+
+       /**
+        * Returns <jk>true</jk> if <code>parent</code> is a parent class or 
the same as <code>child</code>.
+        *
+        * @param parent The parent class.
+        * @param child The child class.
+        * @return <jk>true</jk> if <code>parent</code> is a parent class or 
the same as <code>child</code>.
+        */
+       public static boolean isParentClass(Class<?> parent, Class<?> child) {
+               return isParentClass(parent, child, false);
+       }
+
+       /**
+        * Comparator for use with {@link TreeMap TreeMaps} with {@link Class} 
keys.
+        *
+        * @author James Bognar ([email protected])
+        */
+       public final static class ClassComparator implements 
Comparator<Class<?>>, Serializable {
+
+               private static final long serialVersionUID = 1L;
+
+               @Override /* Comparator */
+               public int compare(Class<?> object1, Class<?> object2) {
+                       return object1.getName().compareTo(object2.getName());
+               }
+       }
+
+       /**
+        * Returns the signature of the specified method.
+        * For no-arg methods, the signature will be a simple string such as 
<js>"toString"</js>.
+        * For methods with one or more args, the arguments will be 
fully-qualified class names (e.g. 
<js>"append(java.util.StringBuilder,boolean)"</js>)
+        *
+        * @param m The methods to get the signature on.
+        * @return The methods signature.
+        */
+       public static String getMethodSignature(Method m) {
+               StringBuilder sb = new StringBuilder(m.getName());
+               Class<?>[] pt = m.getParameterTypes();
+               if (pt.length > 0) {
+                       sb.append("(");
+                       for (int i = 0; i < pt.length; i++) {
+                               if (i > 0)
+                                       sb.append(",");
+                               sb.append(getReadableClassName(pt[i]));
+                       }
+                       sb.append(")");
+               }
+               return sb.toString();
+       }
+
+       private final static Map<Class<?>, Class<?>> pmap1 = new 
HashMap<Class<?>, Class<?>>(), pmap2 = new HashMap<Class<?>, Class<?>>();
+       static {
+               pmap1.put(boolean.class, Boolean.class);
+               pmap1.put(byte.class, Byte.class);
+               pmap1.put(short.class, Short.class);
+               pmap1.put(char.class, Character.class);
+               pmap1.put(int.class, Integer.class);
+               pmap1.put(long.class, Long.class);
+               pmap1.put(float.class, Float.class);
+               pmap1.put(double.class, Double.class);
+               pmap2.put(Boolean.class, boolean.class);
+               pmap2.put(Byte.class, byte.class);
+               pmap2.put(Short.class, short.class);
+               pmap2.put(Character.class, char.class);
+               pmap2.put(Integer.class, int.class);
+               pmap2.put(Long.class, long.class);
+               pmap2.put(Float.class, float.class);
+               pmap2.put(Double.class, double.class);
+       }
+
+       /**
+        * If the specified class is a primitive (e.g. 
<code><jk>int</jk>.<jk>class</jk></code>)
+        *      returns it's wrapper class (e.g. 
<code>Integer.<jk>class</jk></code>).
+        *
+        * @param c The class.
+        * @return The wrapper class, or <jk>null</jk> if class is not a 
primitive.
+        */
+       public static Class<?> getPrimitiveWrapper(Class<?> c) {
+               return pmap1.get(c);
+       }
+
+       /**
+        * If the specified class is a primitive wrapper (e.g. 
<code><jk>Integer</jk>.<jk>class</jk></code>)
+        *      returns it's primitive class (e.g. 
<code>int.<jk>class</jk></code>).
+        *
+        * @param c The class.
+        * @return The primitive class, or <jk>null</jk> if class is not a 
primitive wrapper.
+        */
+       public static Class<?> getPrimitiveForWrapper(Class<?> c) {
+               return pmap2.get(c);
+       }
+
+       /**
+        * If the specified class is a primitive (e.g. 
<code><jk>int</jk>.<jk>class</jk></code>)
+        *      returns it's wrapper class (e.g. 
<code>Integer.<jk>class</jk></code>).
+        *
+        * @param c The class.
+        * @return The wrapper class if it's primitive, or the same class if 
class is not a primitive.
+        */
+       public static Class<?> getWrapperIfPrimitive(Class<?> c) {
+               if (! c.isPrimitive())
+                       return c;
+               return pmap1.get(c);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CollectionUtils.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CollectionUtils.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CollectionUtils.class
new file mode 100755
index 0000000..25ba941
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CollectionUtils.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/utils/CollectionUtils.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CollectionUtils.java
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CollectionUtils.java
new file mode 100755
index 0000000..bec00b6
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/CollectionUtils.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 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.utils;
+
+import java.util.*;
+
+/**
+ * Utility methods for collections.
+ *
+ * @author James Bognar ([email protected])
+ */
+public class CollectionUtils {
+
+       /**
+        * Reverses the order of a {@link LinkedHashMap}.
+        *
+        * @param in The map to reverse the order on.
+        * @return A new {@link LinkedHashMap} with keys in reverse order.
+        */
+       public static <K,V> LinkedHashMap<K,V> reverse(LinkedHashMap<K,V> in) {
+               if (in == null)
+                       return null;
+               LinkedHashMap<K,V> m = new LinkedHashMap<K,V>();
+
+               // Note:  Entry objects are reusable in an entry set, so we 
simply can't
+               // create a reversed iteration of that set.
+               List<K> keys = new ArrayList<K>(in.keySet());
+               List<V> values = new ArrayList<V>(in.values());
+               for (int i = in.size()-1; i >= 0; i--)
+                       m.put(keys.get(i), values.get(i));
+
+               return m;
+       }
+
+       /**
+        * Add a value to a list if the value is not null.
+        *
+        * @param l The list to add to.
+        * @param o The element to add.
+        * @return The same list.
+        */
+       public static <T> List<T> addIfNotNull(List<T> l, T o) {
+               if (o != null)
+                       l.add(o);
+               return l;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap$1.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap$1.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap$1.class
new file mode 100755
index 0000000..4452c8c
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap$1.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/utils/DelegateBeanMap$BeanMapEntryOverride.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap$BeanMapEntryOverride.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap$BeanMapEntryOverride.class
new file mode 100755
index 0000000..edd7903
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap$BeanMapEntryOverride.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/utils/DelegateBeanMap.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap.class
new file mode 100755
index 0000000..bd90f1f
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap.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/utils/DelegateBeanMap.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap.java
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap.java
new file mode 100755
index 0000000..c8e85d4
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateBeanMap.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * 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.utils;
+
+import java.util.*;
+
+import com.ibm.juno.core.*;
+
+/**
+ * Represents a wrapped {@link BeanMap} where property values can be 
overridden, removed, or reordered
+ *     without affecting the underlying bean.
+ * <p>
+ *     Provides the {@link #filterKeys(List)} method for specifying the keys 
to keep in the bean map
+ *             and in what order they should appear.
+ *
+ * @author James Bognar ([email protected])
+ * @param <T> The class type of the wrapped bean.
+ */
+@SuppressWarnings("hiding")
+public class DelegateBeanMap<T> extends BeanMap<T> {
+
+       private Set<String> keys = Collections.newSetFromMap(new 
LinkedHashMap<String,Boolean>());
+       private ObjectMap overrideValues = new ObjectMap();
+
+       @SuppressWarnings("unchecked")
+       DelegateBeanMap(T bean, BeanContext bc) {
+               super(bean, bc.getBeanMeta((Class<T>)bean.getClass()));
+       }
+
+       void addKey(String key) {
+               this.keys.add(key);
+       }
+
+       @Override /* Map */
+       public Object put(String key, Object val) {
+               this.overrideValues.put(key, val);
+               this.keys.add(key);
+               return null;
+       }
+
+       @Override /* Map */
+       public Object get(Object key) {
+               if (overrideValues.containsKey(key))
+                       return overrideValues.get(key);
+               return super.get(key);
+       }
+
+       @Override /* Map */
+       public Set<String> keySet() {
+               return keys;
+       }
+
+       /**
+        * Remove all but the specified properties from this bean map.
+        * <p>
+        * This does not affect the underlying bean.
+        *
+        * @param keys The remaining keys in the bean map (in the specified 
order).
+        */
+       public void filterKeys(List<String> keys) {
+               this.keys.clear();
+               this.keys.addAll(keys);
+       }
+
+       @Override /* Map */
+       public Object remove(Object key) {
+               keys.remove(key);
+               return null;
+       }
+
+       @Override /* BeanMap */
+       public BeanMeta<T> getMeta() {
+               return new BeanMetaFiltered<T>(super.getMeta(), keys);
+       }
+
+       @Override /* Map */
+       public Set<Entry<String,Object>> entrySet() {
+               Set<Entry<String,Object>> s = Collections.newSetFromMap(new 
LinkedHashMap<Map.Entry<String,Object>,Boolean>());
+               for (final String key : keys) {
+                       BeanMapEntry<T> bme;
+                       if (overrideValues.containsKey(key))
+                               bme = new BeanMapEntryOverride<T>(this, 
this.getPropertyMeta(key), overrideValues.get(key));
+                       else
+                               bme = this.getProperty(key);
+                       if (bme == null)
+                               throw new 
BeanRuntimeException(super.getClassMeta().getInnerClass(), "Property ''{0}'' 
not found on class.", key);
+                       s.add(bme);
+               }
+               return s;
+       }
+
+       private class BeanMapEntryOverride<T2> extends BeanMapEntry<T2> {
+               Object value;
+
+               private BeanMapEntryOverride(BeanMap<T2> bm, 
BeanPropertyMeta<T2> bpm, Object value) {
+                       super(bm, bpm);
+                       this.value = value;
+               }
+
+               @Override /* Map.Entry */
+               public Object getValue() {
+                       return value;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateList.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateList.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateList.class
new file mode 100755
index 0000000..c7ab98a
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateList.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/utils/DelegateList.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateList.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateList.java
new file mode 100755
index 0000000..379bfe2
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateList.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.utils;
+
+import java.util.*;
+
+import com.ibm.juno.core.*;
+
+/**
+ * Represents a wrapped {@link Collection} where entries in the list can be 
removed or reordered without
+ *     affecting the underlying list.
+ *
+ * @author James Bognar ([email protected])
+ * @param <T> The class type of the wrapped bean.
+ */
+public class DelegateList<T extends Collection<?>> extends ObjectList 
implements Delegate<T> {
+       private static final long serialVersionUID = 1L;
+
+       private transient ClassMeta<T> classMeta;
+
+       DelegateList(ClassMeta<T> classMeta) {
+               this.classMeta = classMeta;
+       }
+
+       @Override /* Delegate */
+       public ClassMeta<T> getClassMeta() {
+               return classMeta;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateMap.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateMap.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateMap.class
new file mode 100755
index 0000000..3ed7bb7
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateMap.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/utils/DelegateMap.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateMap.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateMap.java
new file mode 100755
index 0000000..756546e
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/DelegateMap.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.utils;
+
+import java.util.*;
+
+import com.ibm.juno.core.*;
+
+/**
+ * Represents a wrapped {@link Map} where entries in the map can be removed 
without
+ *     affecting the underlying map.
+ *
+ * @author James Bognar ([email protected])
+ * @param <T> The class type of the wrapped bean.
+ */
+public class DelegateMap<T> extends ObjectMap implements Delegate<T> {
+       private static final long serialVersionUID = 1L;
+
+       private transient ClassMeta<T> classMeta;
+
+       DelegateMap(ClassMeta<T> classMeta) {
+               this.classMeta = classMeta;
+       }
+
+       @Override /* Delegate */
+       public ClassMeta<T> getClassMeta() {
+               return classMeta;
+       }
+
+       /**
+        * Remove all but the specified keys from this map.
+        * <p>
+        * This does not affect the underlying map.
+        *
+        * @param keys The remaining keys in the map (in the specified order).
+        */
+       public void filterKeys(List<String> keys) {
+               ObjectMap m2 = new ObjectMap();
+               for (String k : keys)
+                       m2.put(k, get(k));
+               this.clear();
+               this.putAll(m2);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FileUtils.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FileUtils.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FileUtils.class
new file mode 100755
index 0000000..7967b8f
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FileUtils.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/utils/FileUtils.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FileUtils.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FileUtils.java
new file mode 100755
index 0000000..3639cbf
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FileUtils.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 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.utils;
+
+import static com.ibm.juno.core.utils.ThrowableUtils.*;
+
+import java.io.*;
+
+/**
+ * File utilities.
+ */
+public class FileUtils {
+
+       /**
+        * Same as {@link File#mkdirs()} except throws a RuntimeExeption if 
directory could not be created.
+        *
+        * @param f The directory to create.  Must not be <jk>null</jk>.
+        * @param clean If <jk>true</jk>, deletes the contents of the directory 
if it already exists.
+        * @return The same file.
+        * @throws RuntimeException if directory could not be created.
+        */
+       public static File mkdirs(File f, boolean clean) {
+               assertFieldNotNull(f, "f");
+               if (f.exists()) {
+                       if (clean) {
+                               if (! delete(f))
+                                       throw new RuntimeException("Could not 
clean directory '"+f.getAbsolutePath()+"'");
+                       } else {
+                               return f;
+                       }
+               }
+               if (! f.mkdirs())
+                       throw new RuntimeException("Could not create directory 
'" + f.getAbsolutePath() + "'");
+               return f;
+       }
+
+       /**
+        * Same as {@link #mkdirs(String, boolean)} but uses String path.
+        *
+        * @param path The path of the directory to create.  Must not be 
<jk>null</jk>
+        * @param clean If <jk>true</jk>, deletes the contents of the directory 
if it already exists.
+        * @return The directory.
+        */
+       public static File mkdirs(String path, boolean clean) {
+               assertFieldNotNull(path, "path");
+               return mkdirs(new File(path), clean);
+       }
+
+       /**
+        * Recursively deletes a file or directory.
+        *
+        * @param f The file or directory to delete.
+        * @return <jk>true</jk> if file or directory was successfully deleted.
+        */
+       public static boolean delete(File f) {
+               if (f == null)
+                       return true;
+               if (f.isDirectory()) {
+                       File[] cf = f.listFiles();
+                       if (cf != null)
+                               for (File c : cf)
+                                       delete(c);
+               }
+               return f.delete();
+       }
+
+       /**
+        * Creates a file if it doesn't already exist using {@link 
File#createNewFile()}.
+        * Throws a {@link RuntimeException} if the file could not be created.
+        *
+        * @param f The file to create.
+        */
+       public static void create(File f) {
+               if (f.exists())
+                       return;
+               try {
+                       if (! f.createNewFile())
+                               throw new RuntimeException("Could not create 
file '"+f.getAbsolutePath()+"'");
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Updates the modified timestamp on the specified file.
+        * Method ensures that the timestamp changes even if it's been modified 
within the past millisecond.
+        *
+        * @param f The file to modify the modified timestamp on.
+        */
+       public static void modifyTimestamp(File f) {
+               long lm = f.lastModified();
+               long l = System.currentTimeMillis();
+               if (lm == l)
+                       l++;
+               if (! f.setLastModified(l))
+                       throw new RuntimeException("Could not modify timestamp 
on file '"+f.getAbsolutePath()+"'");
+
+               // Linux only gives 1s precision, so set the date 1s into the 
future.
+               if (lm == f.lastModified()) {
+                       l += 1000;
+                       if (! f.setLastModified(l))
+                               throw new RuntimeException("Could not modify 
timestamp on file '"+f.getAbsolutePath()+"'");
+               }
+       }
+
+       /**
+        * Create a temporary file with the specified name.
+        * <p>
+        * The name is broken into file name and suffix, and the parts
+        * are passed to {@link File#createTempFile(String, String)}.
+        * <p>
+        * {@link File#deleteOnExit()} is called on the resulting file before 
being returned by this method.
+        *
+        * @param name The file name
+        * @return A newly-created temporary file.
+        * @throws IOException
+        */
+       public static File createTempFile(String name) throws IOException {
+               String[] parts = name.split("\\.");
+               File f = File.createTempFile(parts[0], "." + parts[1]);
+               f.deleteOnExit();
+               return f;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap$1.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap$1.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap$1.class
new file mode 100755
index 0000000..69fd5cb
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap$1.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/utils/FilteredMap$ListSet.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap$ListSet.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap$ListSet.class
new file mode 100755
index 0000000..cda0c50
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap$ListSet.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/utils/FilteredMap.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap.class
new file mode 100755
index 0000000..8f0774d
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap.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/utils/FilteredMap.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap.java
new file mode 100755
index 0000000..9579fe3
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/FilteredMap.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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.utils;
+
+import static com.ibm.juno.core.utils.ThrowableUtils.*;
+
+import java.util.*;
+
+/**
+ * Wrapper around a map where the key names are overridden.
+ *
+ * @param <K> The key class type.
+ * @param <V> The value class type.
+ * @author James Bognar ([email protected])
+ */
+public final class FilteredMap<K,V> extends AbstractMap<K,V> {
+
+       private Map<K,V> innerMap;
+       private Set<Map.Entry<K,V>> entries;
+
+       /**
+        * Constructor.
+        *
+        * @param innerMap The map being wrapped.  Must not be <jk>null</jk>.
+        * @param keys The keys in the new map.  Must not be <jk>null</jk>.
+        */
+       public FilteredMap(Map<K,V> innerMap, K[] keys) {
+               assertFieldNotNull(innerMap, "innerMap");
+               assertFieldNotNull(keys, "keys");
+
+               this.innerMap = innerMap;
+                       List<Map.Entry<K,V>> l = new 
ArrayList<Map.Entry<K,V>>(keys.length);
+                       for (K k : keys)
+                               if (innerMap.containsKey(k))
+                                       l.add(createEntry(k));
+                       entries = new ListSet<Map.Entry<K,V>>(l);
+               }
+
+       private Map.Entry<K,V> createEntry(final K key) {
+               return new Map.Entry<K,V>() {
+
+                       @Override /* Map.Entry */
+                       public K getKey() {
+                               return key;
+                       }
+
+                       @Override /* Map.Entry */
+                       public V getValue() {
+                               return innerMap.get(key);
+                       }
+
+                       @Override /* Map.Entry */
+                       public V setValue(V v) {
+                               return innerMap.put(key, v);
+                       }
+               };
+       }
+
+
+       @Override /* Map */
+       public Set<Map.Entry<K,V>> entrySet() {
+               return entries;
+       }
+
+       /**
+        * A set with ordered entries (i.e. a List with a Set API).
+        */
+       private static class ListSet<E> extends AbstractSet<E> {
+
+               private List<E> entries;
+
+               public ListSet(List<E> entries) {
+                       this.entries = entries;
+               }
+
+               @Override /* Set */
+               public Iterator<E> iterator() {
+                       return entries.iterator();
+               }
+
+               @Override /* Set */
+               public int size() {
+                       return entries.size();
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe$LineProcessor.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe$LineProcessor.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe$LineProcessor.class
new file mode 100755
index 0000000..5a68a01
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe$LineProcessor.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/utils/IOPipe.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe.class
new file mode 100755
index 0000000..1f79c1c
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe.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/utils/IOPipe.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe.java
new file mode 100755
index 0000000..51d02a8
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOPipe.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 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.utils;
+
+import static com.ibm.juno.core.utils.ThrowableUtils.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * A utility class for piping input streams and readers to output streams and 
writers.
+ * <p>
+ *     A typical usage is as follows...
+ * <p class='bcode'>
+ *     InputStream in = getInputStream();
+ *     Writer out = getWriter();
+ *     IOPipe.create(in, out).closeOut().run();
+ * </p>
+ * <p>
+ *     By default, the input stream is closed and the output stream is not.
+ *     This can be changed by calling {@link #closeOut()} and {@link 
#close(boolean, boolean)}.
+ *
+ * @author James Bognar ([email protected])
+ */
+@SuppressWarnings("hiding")
+public class IOPipe {
+
+       private Object input, output;
+       private boolean byLines;
+       private boolean closeIn = true, closeOut;
+       private int buffSize = 1024;
+       private LineProcessor lineProcessor;
+
+       private IOPipe(Object input, Object output) {
+               assertFieldNotNull(input, "input");
+               assertFieldNotNull(output, "output");
+
+               if (input instanceof CharSequence)
+                       this.input = new StringReader(input.toString());
+               else if (input instanceof InputStream || input instanceof 
Reader)
+                       this.input = input;
+               else
+                       illegalArg("Invalid input class type.  Must be one of 
the following:  InputStream, Reader, CharSequence");
+
+               if (output instanceof OutputStream || output instanceof Writer)
+                       this.output = output;
+               else
+                       illegalArg("Invalid output class type.  Must be one of 
the following:  OutputStream, Writer");
+       }
+
+       /**
+        * Creates a new pipe with the specified input and output.
+        *
+        * @param input The input.  Must be one of the following types:  
Reader, InputStream, CharSequence.
+        * @param output The output.  Must be one of the following types:  
Writer, OutputStream.
+        * @return This object (for method chaining).
+        */
+       public static IOPipe create(Object input, Object output) {
+               return new IOPipe(input, output);
+       }
+
+       /**
+        * Close output after piping.
+        *
+        * @return This object (for method chaining).
+        */
+       public IOPipe closeOut() {
+               this.closeOut = true;
+               return this;
+       }
+
+       /**
+        * Specifies whether to close the input and output after piping.
+        *
+        * @param in Close input stream.  Default is <jk>true</jk>.
+        * @param out Close output stream.  Default is <jk>false</jk>.
+        * @return This object (for method chaining).
+        */
+       public IOPipe close(boolean in, boolean out) {
+               this.closeIn = in;
+               this.closeOut = out;
+               return this;
+       }
+
+       /**
+        * Specifies the temporary buffer size.
+        *
+        * @param buffSize The buffer size.  Default is <code>1024</code>.
+        * @return This object (for method chaining).
+        */
+       public IOPipe buffSize(int buffSize) {
+               assertFieldPositive(buffSize, "buffSize");
+               this.buffSize = buffSize;
+               return this;
+       }
+
+       /**
+        * Specifies whether the content should be piped line-by-line.
+        * This can be useful if you're trying to pipe console-based input.
+        *
+        * @param byLines Pipe content line-by-line.  Default is <jk>false</jk>.
+        * @return This object (for method chaining).
+        */
+       public IOPipe byLines(boolean byLines) {
+               this.byLines = byLines;
+               return this;
+       }
+
+       /**
+        * Sames as calling {@link #byLines()} with <jk>true</jk>.
+        *
+        * @return This object (for method chaining).
+        */
+       public IOPipe byLines() {
+               this.byLines = true;
+               return this;
+       }
+
+       /**
+        * Specifies a line processor that can be used to process lines before 
they're piped to the output.
+        *
+        * @param lineProcessor The line processor.
+        * @return This object (for method chaining).
+        */
+       public IOPipe lineProcessor(LineProcessor lineProcessor) {
+               this.lineProcessor = lineProcessor;
+               return this;
+       }
+
+       /**
+        * Interface to implement for the {@link #lineProcessor(LineProcessor)} 
method.
+        */
+       public interface LineProcessor {
+               /**
+                * Process the specified line.
+                *
+                * @param line The line to process.
+                * @return The processed line.
+                */
+               public String process(String line);
+       }
+
+       /**
+        * Performs the piping of the input to the output.
+        *
+        * @return The number of bytes (if streams) or characters (if 
readers/writers) piped.
+        * @throws IOException
+        */
+       public int run() throws IOException {
+
+               int c = 0;
+
+               try {
+               if (input instanceof InputStream && output instanceof 
OutputStream && lineProcessor == null) {
+                       InputStream in = (InputStream)input;
+                       OutputStream out = (OutputStream)output;
+                       byte[] b = new byte[buffSize];
+                       int i;
+                               while ((i = in.read(b)) > 0) {
+                                       c += i;
+                                       out.write(b, 0, i);
+                               }
+               } else {
+                               Reader in = (input instanceof Reader ? 
(Reader)input : new InputStreamReader((InputStream)input, IOUtils.UTF8));
+                               Writer out = (output instanceof Writer ? 
(Writer)output : new OutputStreamWriter((OutputStream)output, IOUtils.UTF8));
+                               output = out;
+                               input = in;
+                               if (byLines || lineProcessor != null) {
+                                       Scanner s = new Scanner(in);
+                                       while (s.hasNextLine()) {
+                                               String l = s.nextLine();
+                                               if (lineProcessor != null)
+                                                       l = 
lineProcessor.process(l);
+                                                       if (l != null) {
+                                               out.write(l);
+                                               out.write("\n");
+                                               out.flush();
+                                               c += l.length() + 1;
+                                       }
+                                               }
+                               } else {
+                                       int i;
+                                       char[] b = new char[buffSize];
+                                       while ((i = in.read(b)) > 0) {
+                                               c += i;
+                                               out.write(b, 0, i);
+                                       }
+                               }
+                       }
+                       } finally {
+                       closeQuietly(input, output);
+               }
+               return c;
+       }
+
+       private void closeQuietly(Object input, Object output) {
+                                       if (closeIn)
+                       IOUtils.closeQuietly(input);
+                                       if (closeOut)
+                       IOUtils.closeQuietly(output);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOUtils.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOUtils.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOUtils.class
new file mode 100755
index 0000000..af415ce
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOUtils.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/utils/IOUtils.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOUtils.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOUtils.java
new file mode 100755
index 0000000..16065af
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IOUtils.java
@@ -0,0 +1,352 @@
+/*******************************************************************************
+ * 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.utils;
+
+import static com.ibm.juno.core.utils.ThrowableUtils.*;
+
+import java.io.*;
+import java.nio.charset.*;
+
+/**
+ * Various I/O related utility methods.
+ *
+ * @author jbognar
+ */
+public final class IOUtils {
+
+       /** UTF-8 charset */
+       public static final Charset UTF8 = Charset.forName("UTF-8");
+
+       /**
+        * Reads the contents of a file into a string.
+        *
+        * @param path The path of the file to read using default character 
encoding.
+        * @return The contents of the reader as a string, or <jk>null</jk> if 
file does not exist.
+        * @throws IOException If a problem occurred trying to read from the 
reader.
+        */
+       public static String readFile(String path) throws IOException {
+               return read(new File(path));
+       }
+
+       /**
+        * Reads the contents of a file into a string.
+        *
+        * @param in The file to read using default character encoding.
+        * @return The contents of the reader as a string, or <jk>null</jk> if 
file does not exist.
+        * @throws IOException If a problem occurred trying to read from the 
reader.
+        */
+       public static String read(File in) throws IOException {
+               if (in == null || ! in.exists())
+                       return null;
+               Reader r = new InputStreamReader(new FileInputStream(in), 
Charset.defaultCharset());
+               return read(r, 0, 1024);
+       }
+
+       /**
+        * Writes the contents of the specified <code>Reader</code> to the 
specified file.
+        *
+        * @param out The file to write the output to.
+        * @param in The reader to pipe from.
+        * @return The number of characters written to the file.
+        * @throws IOException
+        */
+       public static int write(File out, Reader in) throws IOException {
+               assertFieldNotNull(out, "out");
+               assertFieldNotNull(in, "in");
+               Writer w = new OutputStreamWriter(new FileOutputStream(out), 
Charset.defaultCharset());
+               try {
+                       return IOPipe.create(in, w).closeOut().run();
+               } finally {
+                       w.close();
+               }
+       }
+
+       /**
+        * Reads the contents of a reader into a string.
+        *
+        * @param in The input reader.
+        * @return The contents of the reader as a string.
+        * @throws IOException If a problem occurred trying to read from the 
reader.
+        */
+       public static String read(Reader in) throws IOException {
+               return read(in, 0, 1024);
+       }
+
+       /**
+        * Reads the contents of an input stream into a string using the 
specified charset.
+        *
+        * @param in The input stream.
+        * @param cs The charset of the contents of the input stream.
+        * @return The contents of the reader as a string.  <jk>null</jk> if 
input stream was null.
+        * @throws IOException If a problem occurred trying to read from the 
input stream.
+        */
+       public static String read(InputStream in, Charset cs) throws 
IOException {
+               if (in == null)
+                       return null;
+               return read(new InputStreamReader(in, cs));
+       }
+
+       /**
+        * Reads the contents of an input stream into a string using the system 
default charset.
+        *
+        * @param in The input stream.
+        * @return The contents of the reader as a string, or <jk>null</jk> if 
the input stream is null.
+        * @throws IOException If a problem occurred trying to read from the 
input stream.
+        */
+       public static String read(InputStream in) throws IOException {
+               if (in == null)
+                       return null;
+               return read(new InputStreamReader(in, 
Charset.defaultCharset()));
+       }
+
+       /**
+        * Read the specified input stream into a byte array and closes the 
stream.
+        *
+        * @param in The input stream.
+        * @param bufferSize The expected size of the buffer.
+        * @return The contents of the stream as a byte array.
+        * @throws IOException Thrown by underlying stream.
+        */
+       public static byte[] readBytes(InputStream in, int bufferSize) throws 
IOException {
+               if (in == null)
+                       return null;
+               ByteArrayOutputStream buff = new 
ByteArrayOutputStream(bufferSize);
+               int nRead;
+               byte[] b = new byte[Math.min(bufferSize, 8192)];
+
+               try {
+                       while ((nRead = in.read(b, 0, b.length)) != -1)
+                                 buff.write(b, 0, nRead);
+
+                               buff.flush();
+
+                               return buff.toByteArray();
+               } finally {
+                       in.close();
+               }
+       }
+
+
+       /**
+        * Reads the specified input into a {@link String} until the end of the 
input is reached.
+        * <p>
+        *      The {@code Reader} is automatically closed.
+        * <p>
+        *      If the {@code Reader} is not an instance of a {@code 
BufferedReader}, then it gets wrapped in a {@code BufferedReader}.
+        *
+        * @param in The input reader.
+        * @param length Specify a positive number if the length of the input 
is known.
+        * @param bufferSize Specify the buffer size to use.
+        * @return The contents of the reader as a string.  <jk>null</jk> if 
reader was null.
+        * @throws IOException If a problem occurred trying to read from the 
reader.
+        */
+       public static String read(Reader in, int length, int bufferSize) throws 
IOException {
+               if (in == null)
+                       return null;
+               length = (length <= 0 ? bufferSize : length);
+               StringBuilder sb = new StringBuilder(length); // Assume they're 
ASCII characters.
+               try {
+                       char[] buf = new char[Math.min(bufferSize, length)];
+                       int i = 0;
+                       while ((i = in.read(buf)) != -1)
+                               sb.append(buf, 0, i);
+                       return sb.toString();
+               } finally {
+                       in.close();
+               }
+       }
+
+       /**
+        * Pipes the contents of the specified reader into the writer.
+        * The reader is closed, the writer is not.
+        *
+        * @param in The reader to pipe from.
+        * @param out The writer to pipe to.
+        * @throws IOException
+        */
+   public static void pipe(Reader in, Writer out) throws IOException {
+               assertFieldNotNull(out, "out");
+               assertFieldNotNull(in, "in");
+      IOPipe.create(in, out).run();
+   }
+
+   /**
+        * Wraps the specified reader in a buffered reader.
+        * <p>
+        * Returns the original reader if it's already one of the following:
+        * <ul>
+        *      <li>{@link BufferedReader}
+        *      <li>{@link StringReader}
+        *      <li>{@link CharSequenceReader}
+        * </ul>
+        *
+        * @param r The reader being wrapped.
+        * @param buffSize The expected size of the input.
+        * @param minBuffSize The minimum buffer size to use if buffSize is too 
small.
+        * @param maxBuffSize The maximum buffer size to use if buffSize is too 
large.
+        * @return The wrapped reader.
+        */
+       public static Reader getBufferedReader(Reader r, int buffSize, int 
minBuffSize, int maxBuffSize) {
+               assertFieldNotNull(r, "r");
+               if (r instanceof BufferedReader || r instanceof StringReader)
+                       return r;
+               if (buffSize <= 0)
+                       buffSize = 1024;
+               if (buffSize < minBuffSize)
+                       buffSize = minBuffSize;
+               else if (buffSize > maxBuffSize)
+                       buffSize = maxBuffSize;
+               return new BufferedReader(r, buffSize);
+       }
+
+       /**
+        * Shortcut for {@code getBufferedReader(r, buffSize, 128, 8096)}
+        *
+        * @param r The reader being wrapped.
+        * @param buffSize The expected size of the input.
+        * @return The reader wrapped in a {@link BufferedReader}, or the 
original {@link Reader} if it's already
+        *      a buffered reader.
+        */
+       public static Reader getBufferedReader(Reader r, int buffSize) {
+               return getBufferedReader(r, buffSize, 128, 8096);
+       }
+
+       /**
+        * Counts the number of bytes in the input stream and then closes the 
stream.
+        *
+        * @param is The input stream to read from.
+        * @return The number of bytes read.
+        * @throws IOException
+        */
+       public static long count(InputStream is) throws IOException {
+               assertFieldNotNull(is, "is");
+               long c = 0;
+               long i;
+               try {
+                       while ((i = is.skip(1024)) != 0)
+                               c += i;
+               } finally {
+                       is.close();
+               }
+               return c;
+       }
+
+       /**
+        * Counts the number of characters in the reader and then closes the 
reader.
+        *
+        * @param r The reader to read from.
+        * @return The number of characters read.
+        * @throws IOException
+        */
+       public static long count(Reader r) throws IOException {
+               assertFieldNotNull(r, "r");
+               long c = 0;
+               long i;
+               try {
+                       while ((i = r.skip(1024)) != 0)
+                               c += i;
+               } finally {
+                       r.close();
+               }
+               return c;
+       }
+
+       /**
+        * Given the specified <js>"Content-Length"</js> header value, return 
an appropriate buffer size.
+        * The maximum buffer size is 1MB.
+        *
+        * @param contentLength The value of the <js>"Content-Length"</js> 
header.
+        * @return The appropriate buffer size.
+        */
+       public static int getBufferSize(String contentLength) {
+               try {
+                       if (! StringUtils.isEmpty(contentLength)) {
+                               long l = Long.decode(contentLength);
+                               if (l > 1048576)
+                                       return 1048576;
+                               if (l <= 0)
+                                       return 8192;
+                               return (int)l;
+                       }
+               } catch (Exception e) {
+                       return 8192;
+               }
+               return 8192;
+       }
+
+       /** 
+        * Close input stream and ignore any exceptions.
+        * No-op if input stream is <jk>null</jk>.
+        *
+        * @param is The input stream to close.
+        */
+       public static void closeQuietly(InputStream is) {
+               try {
+                       if (is != null)
+                               is.close();
+               } catch (IOException e) {}
+       }
+
+       /** 
+        * Close output stream and ignore any exceptions.
+        * No-op if output stream is <jk>null</jk>.
+        *
+        * @param os The output stream to close.
+        */
+       public static void closeQuietly(OutputStream os) {
+               try {
+                       if (os != null)
+                               os.close();
+               } catch (IOException e) {}
+       }
+
+       /** 
+        * Close reader and ignore any exceptions.
+        * No-op if reader is <jk>null</jk>.
+        *
+        * @param r The reader to close.
+        */
+       public static void closeQuietly(Reader r) {
+               try {
+                       if (r != null)
+                               r.close();
+               } catch (IOException e) {}
+       }
+
+       /** 
+        * Close writer and ignore any exceptions.
+        * No-op if writer is <jk>null</jk>.
+        *
+        * @param w The writer to close.
+        */
+       public static void closeQuietly(Writer w) {
+               try {
+                       if (w != null)
+                               w.close();
+               } catch (IOException e) {}
+       }
+
+       /**
+        * Quietly close all specified input streams, output streams, readers, 
and writers.
+        *
+        * @param o The list of all objects to quietly close.
+        */
+       public static void closeQuietly(Object...o) {
+               for (Object o2 : o) {
+                       if (o2 instanceof InputStream)
+                               closeQuietly((InputStream)o2);
+                       if (o2 instanceof OutputStream)
+                               closeQuietly((OutputStream)o2);
+                       if (o2 instanceof Reader)
+                               closeQuietly((Reader)o2);
+                       if (o2 instanceof Writer)
+                               closeQuietly((Writer)o2);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IdentityList.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IdentityList.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IdentityList.class
new file mode 100755
index 0000000..9f262fc
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IdentityList.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/utils/IdentityList.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IdentityList.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IdentityList.java
new file mode 100755
index 0000000..ac14dbd
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/IdentityList.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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.utils;
+
+import java.util.*;
+
+/**
+ * Combination of a {@link LinkedList} and <code>IdentitySet</code>.
+ * <ul>
+ *     <li>Duplicate objects (by identity) will be skipped during insertion.
+ *     <li>Order of insertion maintained.
+ * </ul>
+ * <p>
+ *     Note:  This class is NOT thread safe, and is intended for use on small 
lists.
+ *
+ * @author James Bognar ([email protected])
+ * @param <T> Entry type.
+ */
+public class IdentityList<T> extends LinkedList<T> {
+
+       private static final long serialVersionUID = 1L;
+
+       @Override /* List */
+       public boolean add(T t) {
+               for (T t2 : this)
+                       if (t2 == t)
+                               return false;
+               super.add(t);
+               return true;
+       }
+
+       @Override /* List */
+       public boolean contains(Object t) {
+               for (T t2 : this)
+                       if (t2 == t)
+                               return true;
+               return false;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/KeywordSet.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/KeywordSet.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/KeywordSet.class
new file mode 100755
index 0000000..f080e7f
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/KeywordSet.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/utils/KeywordSet.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/KeywordSet.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/KeywordSet.java
new file mode 100755
index 0000000..e3f995b
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/KeywordSet.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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.utils;
+
+import static com.ibm.juno.core.utils.ThrowableUtils.*;
+
+/**
+ * Stores a set of language keywords for quick lookup.
+ * <p>
+ * Keywords must be:
+ * <ul>
+ *     <li>2 or more characters in length.
+ *     <li>Lowercase ASCII.
+ * </ul>
+ *
+ * @author James Bognar ([email protected])
+ */
+public final class KeywordSet {
+       final char[][][][] store;
+
+       /**
+        * Constructor.
+        *
+        * @param keywords The list of keywords.
+        */
+       public KeywordSet(String... keywords) {
+               this.store = new char[26][][][];
+
+               for (String keyword : keywords) {
+                       if (keyword.length() < 2)
+                               illegalArg("Invalid keyword '{0}' passed to 
KeywordStore.", keyword);
+                       int c0 = keyword.charAt(0) - 'a';
+                       int c1 = keyword.charAt(1) - 'a';
+                       if (c0 < 0 || c0 > 25 || c1 < 0 || c1 > 25)
+                               illegalArg("Invalid keyword '{0}' passed to 
KeywordStore.", keyword);
+                       if (this.store[c0] == null)
+                               this.store[c0] = new char[26][][];
+                       char[][][] x1 = this.store[c0];
+                       char[][] x2;
+                       if (x1[c1] == null)
+                               x2 = new char[1][];
+                       else {
+                               x2 = new char[x1[c1].length+1][];
+                               System.arraycopy(x1[c1], 0, x2, 0, 
x1[c1].length);
+                       }
+                       x2[x2.length-1] = keyword.toCharArray();
+                       x1[c1] = x2;
+               }
+       }
+
+       /**
+        * Returns <jk>true<jk> if the specified string exists in this store.
+        *
+        * @param s The string to check.
+        * @return <jk>true<jk> if the specified string exists in this store.
+        */
+       public boolean contains(String s) {
+               if (s == null || s.length() < 2)
+                       return false;
+               int c0 = s.charAt(0) - 'a', c1 = s.charAt(1) - 'a';
+               if (c0 < 0 || c0 > 25 || c1 < 0 || c1 > 25)
+                       return false;
+               char[][][] x1 = store[c0];
+               if (x1 == null)
+                       return false;
+               char[][] x2 = x1[c1];
+               if (x2 == null)
+                       return false;
+               for (int i = 0; i < x2.length; i++) {
+                       char[] keyword = x2[i];
+                       if (keyword.length == s.length()) {
+                               for (int j = 0; j < keyword.length; j++)
+                                       if (keyword[j] != s.charAt(j))
+                                               return false;
+                               return true;
+                       }
+               }
+               return false;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable$1.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable$1.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable$1.class
new file mode 100755
index 0000000..4e47109
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable$1.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/utils/MultiIterable.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable.class
new file mode 100755
index 0000000..aaec7a1
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable.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/utils/MultiIterable.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable.java
new file mode 100755
index 0000000..089a4e8
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiIterable.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 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.utils;
+
+import static com.ibm.juno.core.utils.ThrowableUtils.*;
+
+import java.util.*;
+
+/**
+ * Utility class for defining an iterator over one or more iterables.
+ * @param <E> The element class type.
+ */
+public class MultiIterable<E> implements Iterable<E> {
+
+       final List<Iterator<E>> iterators = new LinkedList<Iterator<E>>();
+
+       /**
+        * Constructor.
+        *
+        * @param iterators The list of iterators to iterate over.
+        */
+       public MultiIterable(Iterator<E>...iterators) {
+               for (Iterator<E> i : iterators)
+                       append(i);
+       }
+
+       /**
+        * Appends the specified iterator to this list of iterators.
+        *
+        * @param iterator The iterator to append.
+        * @return This object (for method chaining).
+        */
+       public MultiIterable<E> append(Iterator<E> iterator) {
+               assertFieldNotNull(iterator, "iterator");
+               this.iterators.add(iterator);
+               return this;
+       }
+
+       @Override /* Iterable */
+       public Iterator<E> iterator() {
+               return new Iterator<E>() {
+                       Iterator<Iterator<E>> i1 = iterators.iterator();
+                       Iterator<E> i2 = i1.hasNext() ? i1.next() : null;
+
+                       @Override /* Iterator */
+                       public boolean hasNext() {
+                               while (i2 != null && ! i2.hasNext())
+                                       i2 = (i1.hasNext() ? i1.next() : null);
+                               return (i2 != null);
+                       }
+
+                       @Override /* Iterator */
+                       public E next() {
+                               hasNext();
+                               if (i2 == null)
+                                       throw new NoSuchElementException();
+                               return i2.next();
+                       }
+
+                       @Override /* Iterator */
+                       public void remove() {
+                               if (i2 == null)
+                                       throw new NoSuchElementException();
+                               i2.remove();
+                       }
+               };
+       }
+}
\ 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/utils/MultiSet$1.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet$1.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet$1.class
new file mode 100755
index 0000000..f8ca93b
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet$1.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/utils/MultiSet.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet.class
new file mode 100755
index 0000000..5bd3b5e
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet.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/utils/MultiSet.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet.java 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet.java
new file mode 100755
index 0000000..44da937
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/MultiSet.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * 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.utils;
+
+import static com.ibm.juno.core.utils.ThrowableUtils.*;
+
+import java.util.*;
+
+/**
+ * Encapsulates multiple collections so they can be iterated over as if they
+ * were all part of the same collection.
+ *
+ * @author James Bognar ([email protected])
+ * @param <E> The object type of this set.
+ */
+public class MultiSet<E> extends AbstractSet<E> {
+
+       /** Inner collections. */
+       private List<Collection<E>> l = new ArrayList<Collection<E>>();
+
+       /**
+        * Create a new Set that consists as a coalesced set of the specified 
collections.
+        *
+        * @param c Zero or more collections to add to this set.
+        */
+       public MultiSet(Collection<E>...c) {
+               for (Collection<E> cc : c)
+                       append(cc);
+       }
+
+       /**
+        * Appends the specified collection to this set of collections.
+        *
+        * @param c The collection to append to this set of collections.
+        * @return This object (for method chaining).
+        */
+       public MultiSet<E> append(Collection<E> c) {
+               assertFieldNotNull(c, "c");
+               l.add(c);
+               return this;
+       }
+
+       /**
+        * Iterates over all entries in all collections.
+        */
+       @Override /* Set */
+       public Iterator<E> iterator() {
+               return new Iterator<E>() {
+                       int i = 0;
+                       Iterator<E> i2 = (l.size() > 0 ? l.get(i++).iterator() 
: null);
+
+                       @Override /* Iterator */
+                       public boolean hasNext() {
+                               if (i2 == null)
+                                       return false;
+                               if (i2.hasNext())
+                                       return true;
+                               for (int j = i; j < l.size(); j++)
+                                       if (l.get(j).size() > 0)
+                                               return true;
+                               return false;
+                       }
+
+                       @Override /* Iterator */
+                       public E next() {
+                               if (i2 == null)
+                                       throw new NoSuchElementException();
+                               while (! i2.hasNext()) {
+                                       if (i >= l.size())
+                                               throw new 
NoSuchElementException();
+                                       i2 = l.get(i++).iterator();
+                               }
+                               return i2.next();
+                       }
+
+                       @Override /* Iterator */
+                       public void remove() {
+                               if (i2 == null)
+                                       throw new NoSuchElementException();
+                               i2.remove();
+                       }
+               };
+       }
+
+       /**
+        * Enumerates over all entries in all collections.
+        *
+        * @return An enumeration wrapper around this set.
+        */
+       public Enumeration<E> enumerator() {
+               return Collections.enumeration(this);
+       }
+
+       @Override /* Set */
+       public int size() {
+               int i = 0;
+               for (Collection<E> c : l)
+                       i += c.size();
+               return i;
+       }
+}
\ 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/utils/PojoIntrospector.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoIntrospector.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoIntrospector.class
new file mode 100755
index 0000000..d21fa8e
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoIntrospector.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/utils/PojoIntrospector.java
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoIntrospector.java
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoIntrospector.java
new file mode 100755
index 0000000..c051b90
--- /dev/null
+++ 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoIntrospector.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * © 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.utils;
+
+import java.io.*;
+import java.lang.reflect.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.json.*;
+import com.ibm.juno.core.parser.*;
+
+/**
+ * Used to invoke methods on {@code Objects} using arguments in serialized 
form.
+ *     <p>
+ *     Example:
+ *     <p class='bcode'>
+ *             String s = <js>"foobar"</js>;
+ *             String s2 = (String)<jk>new</jk> 
PojoIntrospector(s).invoke(<js>"substring(int,int)"</js>, <js>"[3,6]"</js>);  
<jc>// "bar"</jc>
+ *     </p>
+ *
+ * @author James Bognar ([email protected])
+ */
+public final class PojoIntrospector {
+
+       private final Object o;
+       private final ReaderParser p;
+
+       /**
+        * Constructor.
+        *
+        * @param o The object on which Java methods will be invoked.
+        * @param p The parser to use to parse the method arguments.  If 
<jk>null</jk>, {@link JsonParser#DEFAULT} is used.
+        */
+       public PojoIntrospector(Object o, ReaderParser p) {
+               if (p == null)
+                       p = JsonParser.DEFAULT;
+               this.o = o;
+               this.p = p;
+       }
+
+       /**
+        * Shortcut for calling <code><jk>new</jk> PojoIntrospector(o, 
<jk>null</jk>);</code>
+        *
+        * @param o The object on which Java methods will be invoked.
+        */
+       public PojoIntrospector(Object o) {
+               this(o, null);
+       }
+
+       /**
+        * Primary method.  Invokes the specified method on this bean.
+        *
+        * @param method The method being invoked.
+        * @param args The arguments to pass as parameters to the method.<br>
+        *      These will automatically be converted to the appropriate object 
type if possible.<br>
+        *      Can be <jk>null</jk> if method has no arguments.
+        * @return The object returned by the call to the method, or 
<jk>null</jk> if target object is <jk>null</jk>.
+        * @throws IllegalAccessException If the <code>Constructor</code> 
object enforces Java language access control and the underlying constructor is 
inaccessible.
+        * @throws IllegalArgumentException If one of the following occurs:
+        *      <ul>
+        *              <li>The number of actual and formal parameters differ.
+        *              <li>An unwrapping conversion for primitive arguments 
fails.
+        *              <li>A parameter value cannot be converted to the 
corresponding formal parameter type by a method invocation conversion.
+        *              <li>The constructor pertains to an enum type.
+        *      </ul>
+        * @throws InvocationTargetException If the underlying constructor 
throws an exception.
+        * @throws ParseException If the input contains a syntax error or is 
malformed.
+        * @throws IOException
+        */
+       public Object invokeMethod(Method method, Reader args) throws 
InvocationTargetException, IllegalArgumentException, IllegalAccessException, 
ParseException, IOException {
+               if (o == null)
+                       return null;
+               ClassMeta<?>[] argTypes = 
p.getBeanContext().getClassMetas(method.getParameterTypes());
+               Object[] params = args == null ? null : p.parseArgs(args, -1, 
argTypes);
+               return method.invoke(o, params);
+       }
+
+       /**
+        * Convenience method for invoking argument from method signature (@see 
{@link ClassUtils#getMethodSignature(Method)}.
+        *
+        * @param method The method being invoked.
+        * @param args The arguments to pass as parameters to the method.<br>
+        *      These will automatically be converted to the appropriate object 
type if possible.<br>
+        *      Can be <jk>null</jk> if method has no arguments.
+        * @return The object returned by the call to the method, or 
<jk>null</jk> if target object is <jk>null</jk>.
+        * @throws NoSuchMethodException If method does not exist.
+        * @throws IllegalAccessException If the <code>Constructor</code> 
object enforces Java language access control and the underlying constructor is 
inaccessible.
+        * @throws IllegalArgumentException If one of the following occurs:
+        *      <ul>
+        *              <li>The number of actual and formal parameters differ.
+        *              <li>An unwrapping conversion for primitive arguments 
fails.
+        *              <li>A parameter value cannot be converted to the 
corresponding formal parameter type by a method invocation conversion.
+        *              <li>The constructor pertains to an enum type.
+        *      </ul>
+        * @throws InvocationTargetException If the underlying constructor 
throws an exception.
+        * @throws ParseException If the input contains a syntax error or is 
malformed.
+        * @throws IOException
+        */
+       public Object invokeMethod(String method, String args) throws 
NoSuchMethodException, IllegalArgumentException, InvocationTargetException, 
IllegalAccessException, ParseException, IOException {
+               if (o == null)
+                       return null;
+               Method m = 
p.getBeanContext().getClassMeta(o.getClass()).getPublicMethods().get(method);
+               if (m == null)
+                       throw new NoSuchMethodException(method);
+               return invokeMethod(m, args == null ? null : new 
StringReader(args));
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$1.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$1.class 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$1.class
new file mode 100755
index 0000000..fb9bbd1
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$1.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/utils/PojoQuery$CalendarP.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$CalendarP.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$CalendarP.class
new file mode 100755
index 0000000..8bf4fcc
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$CalendarP.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/utils/PojoQuery$CollectionFilter.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$CollectionFilter.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$CollectionFilter.class
new file mode 100755
index 0000000..c263a15
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$CollectionFilter.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/utils/PojoQuery$DateMatcher.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$DateMatcher.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$DateMatcher.class
new file mode 100755
index 0000000..709ef8d
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$DateMatcher.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/utils/PojoQuery$IMatcher.class
----------------------------------------------------------------------
diff --git 
a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$IMatcher.class
 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$IMatcher.class
new file mode 100755
index 0000000..2c8fc09
Binary files /dev/null and 
b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/PojoQuery$IMatcher.class
 differ

Reply via email to