You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2016/08/09 19:53:56 UTC

[23/51] [partial] incubator-juneau git commit: Rename project directories.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackInputStream.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackInputStream.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackInputStream.java
new file mode 100644
index 0000000..918af13
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackInputStream.java
@@ -0,0 +1,482 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+import static org.apache.juneau.msgpack.DataType.*;
+
+import java.io.*;
+import org.apache.juneau.internal.*;
+
+/**
+ * Specialized input stream for parsing MessagePack streams.
+ * <p>
+ * 	<b>Note:  This class is not intended for external use.</b>
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public final class MsgPackInputStream extends InputStream {
+
+	private final InputStream is;
+	private DataType currentDataType;
+	private long length;
+	private int lastByte;
+	private int extType;
+	int pos = 0;
+
+	// Data type quick-lookup table.
+	private static final DataType[] TYPES = new DataType[] {
+		/*0x0?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0x1?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0x2?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0x3?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0x4?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0x5?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0x6?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0x7?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0x8?*/ MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,
+		/*0x9?*/ ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,
+		/*0xA?*/ STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,
+		/*0xB?*/ STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,
+		/*0xC?*/ NULL, INVALID, BOOLEAN, BOOLEAN, BIN, BIN, BIN, EXT, EXT, EXT, FLOAT, DOUBLE, INT, INT, LONG, LONG,
+		/*0xD?*/ INT, INT, INT, LONG, EXT, EXT, EXT, EXT, EXT, STRING, STRING, STRING, ARRAY, ARRAY, MAP, MAP,
+		/*0xE?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
+		/*0xF?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT
+	};
+
+	/**
+	 * Constructor.
+	 * @param is The input stream being wrapped.
+	 */
+	protected MsgPackInputStream(InputStream is) {
+		this.is = is;
+	}
+
+	@Override /* InputStream */
+	public int read() throws IOException {
+		int i = is.read();
+		if (i > 0)
+			pos++;
+		return i;
+	}
+
+	/**
+	 * Reads the data type flag from the stream.
+	 * This is the byte that indicates what kind of data follows.
+	 */
+	DataType readDataType() throws IOException {
+		int i = read();
+		if (i == -1)
+			throw new IOException("Unexpected end of file found at position " + pos);
+		currentDataType = TYPES[i];
+		switch (currentDataType) {
+			case NULL:
+			case FLOAT: {
+				length = 4;
+				break;
+			}
+			case DOUBLE: {
+				length = 8;
+				break;
+			}
+			case BOOLEAN: {
+				lastByte = i;
+				break;
+			}
+			case INT: {
+				//	positive fixnum stores 7-bit positive integer
+				//	+--------+
+				//	|0XXXXXXX|
+				//	+--------+
+				//
+				//	negative fixnum stores 5-bit negative integer
+				//	+--------+
+				//	|111YYYYY|
+				//	+--------+
+				//
+				//	* 0XXXXXXX is 8-bit unsigned integer
+				//	* 111YYYYY is 8-bit signed integer
+				//
+				//	uint 8 stores a 8-bit unsigned integer
+				//	+--------+--------+
+				//	|  0xcc  |ZZZZZZZZ|
+				//	+--------+--------+
+				//
+				//	uint 16 stores a 16-bit big-endian unsigned integer
+				//	+--------+--------+--------+
+				//	|  0xcd  |ZZZZZZZZ|ZZZZZZZZ|
+				//	+--------+--------+--------+
+				//
+				//	uint 32 stores a 32-bit big-endian unsigned integer
+				//	+--------+--------+--------+--------+--------+
+				//	|  0xce  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
+				//	+--------+--------+--------+--------+--------+
+				//
+				//	uint 64 stores a 64-bit big-endian unsigned integer
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+--------+
+				//	|  0xcf  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+--------+
+				//
+				//	int 8 stores a 8-bit signed integer
+				//	+--------+--------+
+				//	|  0xd0  |ZZZZZZZZ|
+				//	+--------+--------+
+				//
+				//	int 16 stores a 16-bit big-endian signed integer
+				//	+--------+--------+--------+
+				//	|  0xd1  |ZZZZZZZZ|ZZZZZZZZ|
+				//	+--------+--------+--------+
+				//
+				//	int 32 stores a 32-bit big-endian signed integer
+				//	+--------+--------+--------+--------+--------+
+				//	|  0xd2  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
+				//	+--------+--------+--------+--------+--------+
+				//
+				//	int 64 stores a 64-bit big-endian signed integer
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+--------+
+				//	|  0xd3  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+--------+
+				lastByte = i;
+				if (i <= POSFIXINT_U)
+					length = 0;
+				else if (i >= NEGFIXINT_L)
+					length = -1;
+				else if (i == INT8 || i == UINT8)
+					length = 1;
+				else if (i == INT16 || i == UINT16)
+					length = 2;
+				else if (i == INT32)
+					length = 4;
+				else
+					length = 0;
+				break;
+			}
+			case LONG: {
+				if (i == UINT32)
+					length = 4;
+				else if (i == INT64 || i == UINT64)
+					length = 8;
+				else
+					length = 0;
+				break;
+			}
+			case STRING:{
+				// fixstr stores a byte array whose length is upto 31 bytes:
+				// +--------+========+
+				// |101XXXXX|  data  |
+				// +--------+========+
+				//
+				// str 8 stores a byte array whose length is upto (2^8)-1 bytes:
+				// +--------+--------+========+
+				// |  0xd9  |YYYYYYYY|  data  |
+				// +--------+--------+========+
+				//
+				// str 16 stores a byte array whose length is upto (2^16)-1 bytes:
+				// +--------+--------+--------+========+
+				// |  0xda  |ZZZZZZZZ|ZZZZZZZZ|  data  |
+				// +--------+--------+--------+========+
+				//
+				// str 32 stores a byte array whose length is upto (2^32)-1 bytes:
+				// +--------+--------+--------+--------+--------+========+
+				// |  0xdb  |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|  data  |
+				// +--------+--------+--------+--------+--------+========+
+				//
+				// where
+				// * XXXXX is a 5-bit unsigned integer which represents N
+				// * YYYYYYYY is a 8-bit unsigned integer which represents N
+				// * ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
+				// * AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
+				// * N is the length of data
+				if (i <= FIXSTR_U)
+					length = i & 0x1F;
+				else if (i == STR8)
+					length = readUInt1();
+				else if (i == STR16)
+					length = readUInt2();
+				else
+					length = readUInt4();
+				break;
+			}
+			case ARRAY: {
+				// fixarray stores an array whose length is upto 15 elements:
+				// +--------+~~~~~~~~~~~~~~~~~+
+				// |1001XXXX|    N objects    |
+				// +--------+~~~~~~~~~~~~~~~~~+
+				//
+				// array 16 stores an array whose length is upto (2^16)-1 elements:
+				// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
+				// |  0xdc  |YYYYYYYY|YYYYYYYY|    N objects    |
+				// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
+				//
+				// array 32 stores an array whose length is upto (2^32)-1 elements:
+				// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+				// |  0xdd  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|    N objects    |
+				// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+				//
+				// where
+				// * XXXX is a 4-bit unsigned integer which represents N
+				// * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
+				// * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
+				//     N is the size of a array
+				if (i <= FIXARRAY_U)
+					length = i & 0x0F;
+				else if (i == ARRAY16)
+					length = readUInt2();
+				else
+					length = readUInt4();
+				break;
+			}
+			case BIN:{
+				//	bin 8 stores a byte array whose length is upto (2^8)-1 bytes:
+				//	+--------+--------+========+
+				//	|  0xc4  |XXXXXXXX|  data  |
+				//	+--------+--------+========+
+				//
+				//	bin 16 stores a byte array whose length is upto (2^16)-1 bytes:
+				//	+--------+--------+--------+========+
+				//	|  0xc5  |YYYYYYYY|YYYYYYYY|  data  |
+				//	+--------+--------+--------+========+
+				//
+				//	bin 32 stores a byte array whose length is upto (2^32)-1 bytes:
+				//	+--------+--------+--------+--------+--------+========+
+				//	|  0xc6  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|  data  |
+				//	+--------+--------+--------+--------+--------+========+
+				//
+				//	where
+				//	* XXXXXXXX is a 8-bit unsigned integer which represents N
+				//	* YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
+				//	* ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
+				//	* N is the length of data
+				if (i == BIN8)
+					length = readUInt1();
+				else if (i == BIN16)
+					length = readUInt2();
+				else
+					length = readUInt4();
+				break;
+			}
+			case EXT:{
+				//	fixext 1 stores an integer and a byte array whose length is 1 byte
+				//	+--------+--------+--------+
+				//	|  0xd4  |  type  |  data  |
+				//	+--------+--------+--------+
+				//
+				//	fixext 2 stores an integer and a byte array whose length is 2 bytes
+				//	+--------+--------+--------+--------+
+				//	|  0xd5  |  type  |       data      |
+				//	+--------+--------+--------+--------+
+				//
+				//	fixext 4 stores an integer and a byte array whose length is 4 bytes
+				//	+--------+--------+--------+--------+--------+--------+
+				//	|  0xd6  |  type  |                data               |
+				//	+--------+--------+--------+--------+--------+--------+
+				//
+				//	fixext 8 stores an integer and a byte array whose length is 8 bytes
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
+				//	|  0xd7  |  type  |                                  data                                 |
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
+				//
+				//	fixext 16 stores an integer and a byte array whose length is 16 bytes
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
+				//	|  0xd8  |  type  |                                  data
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+
+				//	                              data (cont.)                              |
+				//	+--------+--------+--------+--------+--------+--------+--------+--------+
+				//
+				//	ext 8 stores an integer and a byte array whose length is upto (2^8)-1 bytes:
+				//	+--------+--------+--------+========+
+				//	|  0xc7  |XXXXXXXX|  type  |  data  |
+				//	+--------+--------+--------+========+
+				//
+				//	ext 16 stores an integer and a byte array whose length is upto (2^16)-1 bytes:
+				//	+--------+--------+--------+--------+========+
+				//	|  0xc8  |YYYYYYYY|YYYYYYYY|  type  |  data  |
+				//	+--------+--------+--------+--------+========+
+				//
+				//	ext 32 stores an integer and a byte array whose length is upto (2^32)-1 bytes:
+				//	+--------+--------+--------+--------+--------+--------+========+
+				//	|  0xc9  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|  type  |  data  |
+				//	+--------+--------+--------+--------+--------+--------+========+
+				//
+				//	where
+				//	* XXXXXXXX is a 8-bit unsigned integer which represents N
+				//	* YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
+				//	* ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a big-endian 32-bit unsigned integer which represents N
+				//	* N is a length of data
+				//	* type is a signed 8-bit signed integer
+				//	* type < 0 is reserved for future extension including 2-byte type information
+				if (i == FIXEXT1)
+					length = 1;
+				else if (i == FIXEXT2)
+					length = 2;
+				else if (i == FIXEXT4)
+					length = 4;
+				else if (i == FIXEXT8)
+					length = 8;
+				else if (i == FIXEXT16)
+					length = 16;
+				else if (i == EXT8)
+					length = readUInt1();
+				else if (i == EXT16)
+						length = readUInt2();
+				else if (i == EXT32)
+					length = readUInt4();
+				extType = is.read();
+
+				break;
+			}
+			case MAP:{
+				//	fixmap stores a map whose length is upto 15 elements
+				//	+--------+~~~~~~~~~~~~~~~~~+
+				//	|1000XXXX|   N*2 objects   |
+				//	+--------+~~~~~~~~~~~~~~~~~+
+				//
+				//	map 16 stores a map whose length is upto (2^16)-1 elements
+				//	+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+				//	|  0xde  |YYYYYYYY|YYYYYYYY|   N*2 objects   |
+				//	+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+				//
+				//	map 32 stores a map whose length is upto (2^32)-1 elements
+				//	+--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+				//	|  0xdf  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|   N*2 objects   |
+				//	+--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+				//
+				//	where
+				//	* XXXX is a 4-bit unsigned integer which represents N
+				//	* YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
+				//	* ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
+				//	* N is the size of a map
+				//	* odd elements in objects are keys of a map
+				//	* the next element of a key is its associated value
+				if (i <= FIXMAP_U)
+					length = i & 0x0F;
+				else if (i == MAP16)
+					length = readUInt2();
+				else
+					length = readUInt4();
+				break;
+			}
+			default:
+				throw new IOException("Invalid flag 0xC1 detected in stream.");
+		}
+		return currentDataType;
+	}
+
+	/**
+	 * Returns the length value for the field.
+	 * For ints/floats/bins/strings, this is the number of bytes that the field takes up (minus the data-type flag).
+	 * For arrays, it's the number of array entries.
+	 * For maps, it's the number of map entries.
+	 */
+	long readLength() {
+		return length;
+	}
+
+	/**
+	 * Read a boolean from the stream.
+	 */
+	boolean readBoolean() {
+		return lastByte == TRUE;
+	}
+
+	/**
+	 * Read a string from the stream.
+	 */
+	String readString() throws IOException {
+		return new String(readBinary(), IOUtils.UTF8);
+	}
+	
+	/**
+	 * Read a binary field from the stream.
+	 */
+	byte[] readBinary() throws IOException {
+		byte[] b = new byte[(int)length];
+		is.read(b);
+		return b;
+	}
+
+	/**
+	 * Read an integer from the stream.
+	 */
+	int readInt() throws IOException {
+		if (length == 0)
+			return lastByte;
+		if (length == 1)
+			return is.read();
+		if (length == 2)
+			return (is.read() << 8) | is.read();
+		int i = is.read(); i <<= 8; i |= is.read(); i <<= 8; i |= is.read(); i <<= 8; i |= is.read();
+		return i;
+	}
+
+	/**
+	 * Read a float from the stream.
+	 */
+	float readFloat() throws IOException {
+		return Float.intBitsToFloat(readInt());
+	}
+
+	/**
+	 * Read a double from the stream.
+	 */
+	double readDouble() throws IOException {
+		return Double.longBitsToDouble(readLong());
+	}
+
+	/**
+	 * Read 64-bit long from the stream.
+	 */
+	long readLong() throws IOException {
+		if (length == 4)
+			return readUInt4();
+		long l = is.read(); l <<= 8; l |= is.read(); l <<= 8; l |= is.read(); l <<= 8; l |= is.read(); l <<= 8; l |= is.read(); l <<= 8; l |= is.read(); l <<= 8; l |= is.read(); l <<= 8; l |= is.read();
+		return l;
+	}
+
+	/**
+	 * Return the extended-format type.
+	 * Currently not used.
+	 */
+	int getExtType() {
+		return extType;
+	}
+
+	/**
+	 * Read one byte from the stream.
+	 */
+	private int readUInt1() throws IOException {
+		return is.read();
+	}
+
+	/**
+	 * Read two bytes from the stream.
+	 */
+	private int readUInt2() throws IOException {
+		return (is.read() << 8) | is.read();
+	}
+
+	/**
+	 * Read four bytes from the stream.
+	 */
+	private long readUInt4() throws IOException {
+		long l = is.read(); l <<= 8; l |= is.read(); l <<= 8; l |= is.read(); l <<= 8; l |= is.read();
+		return l;
+	}
+
+	/**
+	 * Return the current read position in the stream (i.e. number of bytes we've read so far).
+	 */
+	int getPosition() {
+		return pos;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackOutputStream.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackOutputStream.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackOutputStream.java
new file mode 100644
index 0000000..3ffed66
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackOutputStream.java
@@ -0,0 +1,322 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+import static org.apache.juneau.msgpack.DataType.*;
+
+import java.io.*;
+import java.math.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * Specialized output stream for serializing MessagePack streams.
+ * <p>
+ * 	<b>Note:  This class is not intended for external use.</b>
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public final class MsgPackOutputStream extends OutputStream {
+
+	private final OutputStream os;
+
+	/**
+	 * Constructor.
+	 * @param os The output stream being wrapped.
+	 */
+	protected MsgPackOutputStream(OutputStream os) {
+		this.os = os;
+	}
+
+	@Override /* OutputStream */
+	public void write(int b) throws IOException {
+		os.write(b);
+	}
+
+	/**
+	 * Same as {@link #write(int)}.
+	 */
+	final MsgPackOutputStream append(byte b) throws IOException {
+		os.write(b);
+		return this;
+	}
+
+	/**
+	 * Same as {@link #write(byte[])}.
+	 */
+	final MsgPackOutputStream append(byte[] b) throws IOException {
+		os.write(b);
+		return this;
+	}
+
+	/**
+	 * Appends one byte to the stream.
+	 */
+	final MsgPackOutputStream append1(int i) throws IOException {
+		os.write(i);
+		return this;
+	}
+
+	/**
+	 * Appends two bytes to the stream.
+	 */
+	final MsgPackOutputStream append2(int i) throws IOException {
+		return append1(i>>8).append1(i);
+	}
+
+	/**
+	 * Appends four bytes to the stream.
+	 */
+	final MsgPackOutputStream append4(int i) throws IOException {
+		return append1(i>>24).append1(i>>16).append1(i>>8).append1(i);
+	}
+
+	/**
+	 * Appends eight bytes to the stream.
+	 */
+	final MsgPackOutputStream append8(long l) throws IOException {
+		return append1((int)(l>>56)).append1((int)(l>>48)).append1((int)(l>>40)).append1((int)(l>>32)).append1((int)(l>>24)).append1((int)(l>>16)).append1((int)(l>>8)).append1((int)(l));
+	}
+
+	/**
+	 * Appends a NULL flag to the stream.
+	 */
+	final MsgPackOutputStream appendNull() throws IOException {
+		return append1(NIL);
+	}
+
+	/**
+	 * Appends a boolean to the stream.
+	 */
+	final MsgPackOutputStream appendBoolean(boolean b) throws IOException {
+		return append1(b ? TRUE : FALSE);
+	}
+
+	/**
+	 * Appends an integer to the stream.
+	 */
+	final MsgPackOutputStream appendInt(int i) throws IOException {
+		// POSFIXINT_L  = 0x00,  //   pos fixint     0xxxxxxx     0x00 - 0x7f
+		// POSFIXINT_U  = 0x7F,
+		// UINT8        = 0xCC,  //   uint 8         11001100     0xcc
+		// UINT16       = 0xCD,  //   uint 16        11001101     0xcd
+		// UINT32       = 0xCE,  //   uint 32        11001110     0xce
+		// UINT64       = 0xCF,  //   uint 64        11001111     0xcf
+		// INT8         = 0xD0,  //   int 8          11010000     0xd0
+		// INT16        = 0xD1,  //   int 16         11010001     0xd1
+		// INT32        = 0xD2,  //   int 32         11010010     0xd2
+		// INT64        = 0xD3,  //   int 64         11010011     0xd3
+		// NEGFIXINT_L  = 0xE0,  //   neg fixint     111xxxxx     0xe0 - 0xff
+		// NEGFIXINT_U  = 0xFF;
+		if (i >= 0) {
+			if (i < (1<<7))
+				return append1(i);
+			if (i < (1<<15))
+				return append1(INT16).append2(i);
+			return append1(INT32).append4(i);
+		}
+		if (i > -(1<<6))
+			return append((byte)(0xE0 | -i));
+		if (i > -(1<<7))
+			return append1(INT8).append1(i);
+		if (i > -(1<<15))
+			return append1(INT16).append2(i);
+		return append1(INT32).append4(i);
+	}
+
+	final long L2X31 = ((long)(1<<30))*2;
+
+	/**
+	 * Appends a long to the stream.
+	 */
+	final MsgPackOutputStream appendLong(long l) throws IOException {
+		if (l < L2X31 && l > -(L2X31))
+			return appendInt((int)l);
+		return append1(INT64).append8(l);
+	}
+
+	/**
+	 * Appends a generic Number to the stream.
+	 */
+	final MsgPackOutputStream appendNumber(Number n) throws IOException {
+		Class<?> c = n.getClass();
+		if (c == Integer.class || c == Short.class || c == Byte.class || c == AtomicInteger.class)
+			return appendInt(n.intValue());
+		if (c == Long.class || c == AtomicLong.class)
+			return appendLong(n.longValue());
+		if (c == Float.class)
+			return appendFloat(n.floatValue());
+		if (c == Double.class)
+			return appendDouble(n.doubleValue());
+		if (c == BigInteger.class)
+			return appendLong(n.longValue());
+		if (c == BigDecimal.class)
+			return appendDouble(n.doubleValue());
+		return appendInt(0);
+	}
+
+	/**
+	 * Appends a float to the stream.
+	 */
+	final MsgPackOutputStream appendFloat(float f) throws IOException {
+		// FLOAT32      = 0xCA,  //   float 32       11001010     0xca
+		return append1(FLOAT32).append4(Float.floatToIntBits(f));
+
+	}
+
+	/**
+	 * Appends a double to the stream.
+	 */
+	final MsgPackOutputStream appendDouble(double d) throws IOException {
+		// FLOAT64      = 0xCB,  //   float 64       11001011     0xcb
+		return append1(FLOAT64).append8(Double.doubleToLongBits(d));
+	}
+
+	/**
+	 * Appends a string to the stream.
+	 */
+	final MsgPackOutputStream appendString(CharSequence cs) throws IOException {
+
+		// fixstr stores a byte array whose length is upto 31 bytes:
+		// +--------+========+
+		// |101XXXXX|  data  |
+		// +--------+========+
+		//
+		// str 8 stores a byte array whose length is upto (2^8)-1 bytes:
+		// +--------+--------+========+
+		// |  0xd9  |YYYYYYYY|  data  |
+		// +--------+--------+========+
+		//
+		// str 16 stores a byte array whose length is upto (2^16)-1 bytes:
+		// +--------+--------+--------+========+
+		// |  0xda  |ZZZZZZZZ|ZZZZZZZZ|  data  |
+		// +--------+--------+--------+========+
+		//
+		// str 32 stores a byte array whose length is upto (2^32)-1 bytes:
+		// +--------+--------+--------+--------+--------+========+
+		// |  0xdb  |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|  data  |
+		// +--------+--------+--------+--------+--------+========+
+		// where
+		// * XXXXX is a 5-bit unsigned integer which represents N
+		// * YYYYYYYY is a 8-bit unsigned integer which represents N
+		// * ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
+		// * AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
+		// * N is the length of data
+
+		byte[] b = cs.toString().getBytes("UTF-8");
+		if (b.length < 32)
+			return append1(0xA0 + b.length).append(b);
+		if (b.length < (1<<8))
+			return append1(STR8).append1(b.length).append(b);
+		if (b.length < (1<<16))
+			return append1(STR16).append2(b.length).append(b);
+		return append1(STR32).append4(b.length).append(b);
+	}
+
+	/**
+	 * Appends a binary field to the stream.
+	 */
+	final MsgPackOutputStream appendBinary(byte[] b) throws IOException {
+		// bin 8 stores a byte array whose length is upto (2^8)-1 bytes:
+		// +--------+--------+========+
+		// |  0xc4  |XXXXXXXX|  data  |
+		// +--------+--------+========+
+		//
+		// bin 16 stores a byte array whose length is upto (2^16)-1 bytes:
+		// +--------+--------+--------+========+
+		// |  0xc5  |YYYYYYYY|YYYYYYYY|  data  |
+		// +--------+--------+--------+========+
+		//
+		// bin 32 stores a byte array whose length is upto (2^32)-1 bytes:
+		// +--------+--------+--------+--------+--------+========+
+		// |  0xc6  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|  data  |
+		// +--------+--------+--------+--------+--------+========+
+		//
+		// where
+		// * XXXXXXXX is a 8-bit unsigned integer which represents N
+		// * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
+		// * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
+		// * N is the length of data
+
+		if (b.length < (1<<8))
+			return append1(BIN8).append1(b.length).append(b);
+		if (b.length < (1<<16))
+			return append1(BIN16).append2(b.length).append(b);
+		return append1(BIN32).append4(b.length).append(b);
+	}
+
+	/**
+	 * Appends an array data type flag to the stream.
+	 */
+	final MsgPackOutputStream startArray(int size) throws IOException {
+		// fixarray stores an array whose length is upto 15 elements:
+		// +--------+~~~~~~~~~~~~~~~~~+
+		// |1001XXXX|    N objects    |
+		// +--------+~~~~~~~~~~~~~~~~~+
+		//
+		// array 16 stores an array whose length is upto (2^16)-1 elements:
+		// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
+		// |  0xdc  |YYYYYYYY|YYYYYYYY|    N objects    |
+		// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
+		//
+		// array 32 stores an array whose length is upto (2^32)-1 elements:
+		// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+		// |  0xdd  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|    N objects    |
+		// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+		//
+		// where
+		// * XXXX is a 4-bit unsigned integer which represents N
+		// * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
+		// * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
+		//     N is the size of a array
+
+		if (size < 16)
+			return append1(0x90 + size);
+		if (size < (1<<16))
+			return append1(ARRAY16).append2(size);
+		return append1(ARRAY32).append4(size);
+	}
+
+	/**
+	 * Appends a map data type flag to the stream.
+	 */
+	final MsgPackOutputStream startMap(int size) throws IOException {
+		// fixmap stores a map whose length is upto 15 elements
+		// +--------+~~~~~~~~~~~~~~~~~+
+		// |1000XXXX|   N*2 objects   |
+		// +--------+~~~~~~~~~~~~~~~~~+
+		//
+		// map 16 stores a map whose length is upto (2^16)-1 elements
+		// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
+		// |  0xde  |YYYYYYYY|YYYYYYYY|   N*2 objects   |
+		// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
+		//
+		// map 32 stores a map whose length is upto (2^32)-1 elements
+		// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+		// |  0xdf  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|   N*2 objects   |
+		// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
+		//
+		// where
+		// * XXXX is a 4-bit unsigned integer which represents N
+		// * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
+		// * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
+		// * N is the size of a map
+		// * odd elements in objects are keys of a map
+		// * the next element of a key is its associated value
+
+		if (size < 16)
+			return append1(0x80 + size);
+		if (size < (1<<16))
+			return append1(MAP16).append2(size);
+		return append1(MAP32).append4(size);
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
new file mode 100644
index 0000000..ec62363
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
@@ -0,0 +1,261 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+import static org.apache.juneau.msgpack.DataType.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Parses a MessagePack stream into a POJO model.
+ *
+ *
+ * <h6 class='topic'>Media types</h6>
+ * <p>
+ * 	Handles <code>Content-Type</code> types: <code>octal/msgpack</code>
+ *
+ *
+ * <h6 class='topic'>Configurable properties</h6>
+ * <p>
+ * 	This class has the following properties associated with it:
+ * <ul>
+ * 	<li>{@link MsgPackParserContext}
+ * </ul>
+ *
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+@Consumes({"octal/msgpack"})
+public final class MsgPackParser extends InputStreamParser {
+
+	/** Default parser, all default settings.*/
+	public static final MsgPackParser DEFAULT = new MsgPackParser().lock();
+
+	/**
+	 * Workhorse method.
+	 */
+	private <T> T parseAnything(MsgPackParserSession session, ClassMeta<T> nt, MsgPackInputStream is, Object outer) throws Exception {
+
+		BeanContext bc = session.getBeanContext();
+		if (nt == null)
+			nt = (ClassMeta<T>)object();
+		PojoTransform<T,Object> transform = (PojoTransform<T,Object>)nt.getPojoTransform();
+		ClassMeta<?> ft = nt.getTransformedClassMeta();
+		session.setCurrentClass(ft);
+
+		Object o = null;
+		DataType dt = is.readDataType();
+		int length = (int)is.readLength();
+
+		if (dt != DataType.NULL) {
+			if (dt == BOOLEAN)
+				o = is.readBoolean();
+			else if (dt == INT)
+				o = is.readInt();
+			else if (dt == LONG)
+				o = is.readLong();
+			else if (dt == FLOAT)
+				o = is.readFloat();
+			else if (dt == DOUBLE)
+				o = is.readDouble();
+			else if (dt == STRING)
+				o = session.trim(is.readString());
+			else if (dt == BIN)
+				o = is.readBinary();
+			else if (dt == ARRAY && ft.isObject()) {
+				ObjectList ol = new ObjectList(bc);
+				for (int i = 0; i < length; i++)
+					ol.add(parseAnything(session, object(), is, outer));
+				o = ol;
+			} else if (dt == MAP && ft.isObject()) {
+				ObjectMap om = new ObjectMap(bc);
+				for (int i = 0; i < length; i++)
+					om.put(parseAnything(session, string(), is, outer), parseAnything(session, object(), is, om));
+				o = om.cast();
+			}
+
+			if (ft.isObject()) {
+				// Do nothing.
+			} else if (ft.isBoolean() || ft.isCharSequence() || ft.isChar() || ft.isNumber()) {
+				o = bc.convertToType(o, ft);
+			} else if (ft.isMap()) {
+				if (dt == MAP) {
+					Map m = (ft.canCreateNewInstance(outer) ? (Map)ft.newInstance(outer) : new ObjectMap(bc));
+					for (int i = 0; i < length; i++) {
+						Object key = parseAnything(session, ft.getKeyType(), is, outer);
+						ClassMeta<?> vt = ft.getValueType();
+						Object value = parseAnything(session, vt, is, m);
+						setName(vt, value, key);
+						m.put(key, value);
+					}
+					o = m;
+				} else {
+					throw new ParseException(session, "Invalid data type {0} encountered for parse type {1}", dt, ft);
+				}
+			} else if (ft.canCreateNewInstanceFromObjectMap(outer)) {
+				ObjectMap m = new ObjectMap(bc);
+				for (int i = 0; i < length; i++)
+					m.put(parseAnything(session, string(), is, outer), parseAnything(session, object(), is, m));
+				o = ft.newInstanceFromObjectMap(outer, m);
+			} else if (ft.canCreateNewBean(outer)) {
+				if (dt == MAP) {
+					BeanMap m = bc.newBeanMap(outer, ft.getInnerClass());
+					for (int i = 0; i < length; i++) {
+						String pName = parseAnything(session, string(), is, m.getBean(false));
+						BeanPropertyMeta<?> bpm = m.getPropertyMeta(pName);
+						if (bpm == null) {
+							if (pName.equals("_class"))
+								parseAnything(session, bc.string(), is, null);
+							else
+								onUnknownProperty(session, pName, m, 0, is.getPosition());
+						} else {
+							ClassMeta<?> cm = bpm.getClassMeta();
+							Object value = parseAnything(session, cm, is, m.getBean(false));
+							setName(cm, value, pName);
+							bpm.set(m, value);
+						}
+					}
+					o = m.getBean();
+				} else {
+					throw new ParseException(session, "Invalid data type {0} encountered for parse type {1}", dt, ft);
+				}
+			} else if (ft.canCreateNewInstanceFromString(outer) && dt == STRING) {
+				o = ft.newInstanceFromString(outer, o == null ? "" : o.toString());
+			} else if (ft.canCreateNewInstanceFromNumber(outer) && dt.isOneOf(INT, LONG, FLOAT, DOUBLE)) {
+				o = ft.newInstanceFromNumber(outer, (Number)o);
+			} else if (ft.isCollection()) {
+				if (dt == MAP) {
+					ObjectMap m = new ObjectMap(bc);
+					for (int i = 0; i < length; i++)
+						m.put(parseAnything(session, string(), is, outer), parseAnything(session, object(), is, m));
+					o = m.cast();
+				} else if (dt == ARRAY) {
+					Collection l = (ft.canCreateNewInstance(outer) ? (Collection)ft.newInstance() : new ObjectList(bc));
+					for (int i = 0; i < length; i++)
+						l.add(parseAnything(session, ft.getElementType(), is, l));
+					o = l;
+				} else {
+					throw new ParseException(session, "Invalid data type {0} encountered for parse type {1}", dt, ft);
+				}
+			} else if (ft.isArray()) {
+				if (dt == MAP) {
+					ObjectMap m = new ObjectMap(bc);
+					for (int i = 0; i < length; i++)
+						m.put(parseAnything(session, string(), is, outer), parseAnything(session, object(), is, m));
+					o = m.cast();
+				} else if (dt == ARRAY) {
+					Collection l = (ft.isCollection() && ft.canCreateNewInstance(outer) ? (Collection)ft.newInstance() : new ObjectList(bc));
+					for (int i = 0; i < length; i++)
+						l.add(parseAnything(session, ft.getElementType(), is, l));
+					o = bc.toArray(ft, l);
+				} else {
+					throw new ParseException(session, "Invalid data type {0} encountered for parse type {1}", dt, ft);
+				}
+			} else if (dt == MAP) {
+				ObjectMap m = new ObjectMap(bc);
+				for (int i = 0; i < length; i++)
+					m.put(parseAnything(session, string(), is, outer), parseAnything(session, object(), is, m));
+				if (m.containsKey("_class"))
+					o = m.cast();
+				else
+					throw new ParseException(session, "Class ''{0}'' could not be instantiated.  Reason: ''{1}''", ft.getInnerClass().getName(), ft.getNotABeanReason());
+			} else {
+				throw new ParseException(session, "Invalid data type {0} encountered for parse type {1}", dt, ft);
+			}
+		}
+
+		if (transform != null && o != null)
+			o = transform.normalize(o, nt);
+
+		if (outer != null)
+			setParent(nt, o, outer);
+
+		return (T)o;
+	}
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* Parser */
+	public MsgPackParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer) {
+		return new MsgPackParserSession(getContext(MsgPackParserContext.class), getBeanContext(), input, op, javaMethod, outer);
+	}
+
+	@Override /* Parser */
+	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
+		MsgPackParserSession s = (MsgPackParserSession)session;
+		type = s.getBeanContext().normalizeClassMeta(type);
+		MsgPackInputStream is = s.getInputStream();
+		T o = parseAnything(s, type, is, s.getOuter());
+		return o;
+	}
+
+	@Override /* Parser */
+	public MsgPackParser setProperty(String property, Object value) throws LockedException {
+		super.setProperty(property, value);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public MsgPackParser setProperties(ObjectMap properties) throws LockedException {
+		super.setProperties(properties);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public MsgPackParser addNotBeanClasses(Class<?>...classes) throws LockedException {
+		super.addNotBeanClasses(classes);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public MsgPackParser addTransforms(Class<?>...classes) throws LockedException {
+		super.addTransforms(classes);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public <T> MsgPackParser addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
+		super.addImplClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public MsgPackParser setClassLoader(ClassLoader classLoader) throws LockedException {
+		super.setClassLoader(classLoader);
+		return this;
+	}
+
+	@Override /* Lockable */
+	public MsgPackParser lock() {
+		super.lock();
+		return this;
+	}
+
+	@Override /* Lockable */
+	public MsgPackParser clone() {
+		try {
+			return (MsgPackParser)super.clone();
+		} catch (CloneNotSupportedException e) {
+			throw new RuntimeException(e); // Shouldn't happen
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java
new file mode 100644
index 0000000..2ed5522
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java
@@ -0,0 +1,49 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Configurable properties on the {@link MsgPackParser} class.
+ * <p>
+ * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
+ * returned {@link CoreApi#getContextFactory()}.
+ * <p>
+ * The following convenience methods are also provided for setting context properties:
+ * <ul>
+ * 	<li>{@link MsgPackParser#setProperty(String,Object)}
+ * 	<li>{@link MsgPackParser#setProperties(ObjectMap)}
+ * 	<li>{@link MsgPackParser#addNotBeanClasses(Class[])}
+ * 	<li>{@link MsgPackParser#addTransforms(Class[])}
+ * 	<li>{@link MsgPackParser#addImplClass(Class,Class)}
+ * </ul>
+ * <p>
+ * See {@link ContextFactory} for more information about context properties.
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public final class MsgPackParserContext extends ParserContext {
+
+	/**
+	 * Constructor.
+	 * <p>
+	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 *
+	 * @param cf The factory that created this context.
+	 */
+	public MsgPackParserContext(ContextFactory cf) {
+		super(cf);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
new file mode 100644
index 0000000..4f5057c
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
@@ -0,0 +1,70 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Session object that lives for the duration of a single use of {@link MsgPackParser}.
+ * <p>
+ * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public final class MsgPackParserSession extends ParserSession {
+
+	private MsgPackInputStream inputStream;
+
+	/**
+	 * Create a new session using properties specified in the context.
+	 *
+	 * @param ctx The context creating this session object.
+	 * 	The context contains all the configuration settings for this object.
+	 * @param beanContext The bean context being used.
+	 * @param input The input.  Can be any of the following types:
+	 * 	<ul>
+	 * 		<li><jk>null</jk>
+	 * 		<li>{@link Reader}
+	 * 		<li>{@link CharSequence}
+	 * 		<li>{@link InputStream} containing UTF-8 encoded text.
+	 * 		<li>{@link File} containing system encoded text.
+	 * 	</ul>
+	 * @param op The override properties.
+	 * 	These override any context properties defined in the context.
+	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param outer The outer object for instantiating top-level non-static inner classes.
+	 */
+	public MsgPackParserSession(MsgPackParserContext ctx, BeanContext beanContext, Object input, ObjectMap op, Method javaMethod, Object outer) {
+		super(ctx, beanContext, input, op, javaMethod, outer);
+	}
+
+	@Override /* ParserSession */
+	public MsgPackInputStream getInputStream() throws ParseException {
+		if (inputStream == null)
+			inputStream = new MsgPackInputStream(super.getInputStream());
+		return inputStream;
+	}
+
+	@Override /* ParserSession */
+	public Map<String,Object> getLastLocation() {
+		Map<String,Object> m = super.getLastLocation();
+		if (inputStream != null)
+			m.put("position", inputStream.getPosition());
+		return m;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
new file mode 100644
index 0000000..76aa138
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -0,0 +1,280 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Serializes POJO models to MessagePack.
+ *
+ *
+ * <h6 class='topic'>Media types</h6>
+ * <p>
+ * 	Handles <code>Accept</code> types: <code>octal/msgpack</code>
+ * <p>
+ * 	Produces <code>Content-Type</code> types: <code>octal/msgpack</code>
+ *
+ * <h6 class='topic'>Configurable properties</h6>
+ * <p>
+ * 	This class has the following properties associated with it:
+ * <ul>
+ * 	<li>{@link MsgPackSerializerContext}
+ * 	<li>{@link SerializerContext}
+ * 	<li>{@link BeanContext}
+ * </ul>
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+@Produces({"octal/msgpack"})
+public class MsgPackSerializer extends OutputStreamSerializer {
+
+	/** Default serializer, all default settings.*/
+	public static final MsgPackSerializer DEFAULT = new MsgPackSerializer().lock();
+
+	/**
+	 * Workhorse method. Determines the type of object, and then calls the
+	 * appropriate type-specific serialization method.
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	MsgPackOutputStream serializeAnything(MsgPackSerializerSession session, MsgPackOutputStream out, Object o, ClassMeta<?> eType, String attrName, BeanPropertyMeta pMeta) throws Exception {
+		BeanContext bc = session.getBeanContext();
+
+		if (o == null)
+			return out.appendNull();
+
+		if (eType == null)
+			eType = object();
+
+		boolean addClassAttr;		// Add "_class" attribute to element?
+		ClassMeta<?> aType;			// The actual type
+		ClassMeta<?> gType;			// The generic type
+
+		aType = session.push(attrName, o, eType);
+		boolean isRecursion = aType == null;
+
+		// Handle recursion
+		if (aType == null) {
+			o = null;
+			aType = object();
+		}
+
+		gType = aType.getTransformedClassMeta();
+		addClassAttr = (session.isAddClassAttrs() && ! eType.equals(aType));
+
+		// Transform if necessary
+		PojoTransform transform = aType.getPojoTransform();				// The transform
+		if (transform != null) {
+			o = transform.transform(o);
+
+			// If the transform's getTransformedClass() method returns Object, we need to figure out
+			// the actual type now.
+			if (gType.isObject())
+				gType = bc.getClassMetaForObject(o);
+		}
+
+		// '\0' characters are considered null.
+		if (o == null || (gType.isChar() && ((Character)o).charValue() == 0))
+			out.appendNull();
+		else if (gType.isBoolean())
+			out.appendBoolean((Boolean)o);
+		else if (gType.isNumber())
+			out.appendNumber((Number)o);
+		else if (gType.hasToObjectMapMethod())
+			serializeMap(session, out, gType.toObjectMap(o), gType);
+		else if (gType.isBean())
+			serializeBeanMap(session, out, bc.forBean(o), addClassAttr);
+		else if (gType.isUri() || (pMeta != null && (pMeta.isUri() || pMeta.isBeanUri())))
+			out.appendString(session.resolveUri(o.toString()));
+		else if (gType.isMap()) {
+			if (o instanceof BeanMap)
+				serializeBeanMap(session, out, (BeanMap)o, addClassAttr);
+			else
+				serializeMap(session, out, (Map)o, eType);
+		}
+		else if (gType.isCollection()) {
+			if (addClassAttr)
+				serializeCollectionMap(session, out, (Collection)o, gType);
+			else
+				serializeCollection(session, out, (Collection) o, eType);
+		}
+		else if (gType.isArray()) {
+			if (addClassAttr)
+				serializeCollectionMap(session, out, toList(gType.getInnerClass(), o), gType);
+			else
+				serializeCollection(session, out, toList(gType.getInnerClass(), o), eType);
+		} else
+			out.appendString(session.toString(o));
+
+		if (! isRecursion)
+			session.pop();
+		return out;
+	}
+
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private void serializeMap(MsgPackSerializerSession session, MsgPackOutputStream out, Map m, ClassMeta<?> type) throws Exception {
+
+		ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
+
+		m = session.sort(m);
+		
+		// The map size may change as we're iterating over it, so
+		// grab a snapshot of the entries in a separate list.
+		List<SimpleMapEntry> entries = new ArrayList<SimpleMapEntry>(m.size());
+		for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
+			entries.add(new SimpleMapEntry(e.getKey(), e.getValue()));
+
+		out.startMap(entries.size());
+
+		for (SimpleMapEntry e : entries) {
+			Object value = e.value;
+			Object key = session.generalize(e.key, keyType);
+
+			serializeAnything(session, out, key, keyType, null, null);
+			serializeAnything(session, out, value, valueType, null, null);
+		}
+	}
+
+	@SuppressWarnings({ "rawtypes" })
+	private void serializeCollectionMap(MsgPackSerializerSession session, MsgPackOutputStream out, Collection o, ClassMeta<?> type) throws Exception {
+
+		out.startMap(2);
+		serializeAnything(session, out, "_class", null, null, null);
+		serializeAnything(session, out, type.getInnerClass().getName(), null, null, null);
+		serializeAnything(session, out, "items", null, null, null);
+		serializeCollection(session, out, o, type);
+	}
+
+	@SuppressWarnings({ "rawtypes" })
+	private void serializeBeanMap(MsgPackSerializerSession session, MsgPackOutputStream out, final BeanMap<?> m, boolean addClassAttr) throws Exception {
+
+		List<BeanPropertyValue> values = m.getValues(addClassAttr, session.isTrimNulls());
+
+		int size = values.size();
+		for (BeanPropertyValue p : values)
+			if (p.getThrown() != null)
+				size--;
+		out.startMap(size);
+
+		for (BeanPropertyValue p : values) {
+			BeanPropertyMeta pMeta = p.getMeta();
+			String key = p.getName();
+			Object value = p.getValue();
+			Throwable t = p.getThrown();
+			if (t != null)
+				session.addBeanGetterWarning(pMeta, t);
+			else {
+				serializeAnything(session, out, key, null, null, null);
+				serializeAnything(session, out, value, pMeta == null ? session.getBeanContext().string() : pMeta.getClassMeta(), key, pMeta);
+			}
+		}
+	}
+
+	private static class SimpleMapEntry {
+		final Object key;
+		final Object value;
+
+		private SimpleMapEntry(Object key, Object value) {
+			this.key = key;
+			this.value = value;
+		}
+	}
+
+	@SuppressWarnings({"rawtypes", "unchecked"})
+	private void serializeCollection(MsgPackSerializerSession session, MsgPackOutputStream out, Collection c, ClassMeta<?> type) throws Exception {
+
+		ClassMeta<?> elementType = type.getElementType();
+		List<Object> l = new ArrayList<Object>(c.size());
+
+		c = session.sort(c);
+		l.addAll(c);
+
+		out.startArray(l.size());
+
+		for (Object o : l)
+			serializeAnything(session, out, o, elementType, "<iterator>", null);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* Serializer */
+	public MsgPackSerializerSession createSession(Object output, ObjectMap properties, Method javaMethod) {
+		return new MsgPackSerializerSession(getContext(MsgPackSerializerContext.class), getBeanContext(), output, properties, javaMethod);
+	}
+
+	@Override /* Serializer */
+	protected void doSerialize(SerializerSession session, Object o) throws Exception {
+		MsgPackSerializerSession s = (MsgPackSerializerSession)session;
+		serializeAnything(s, s.getOutputStream(), o, null, "root", null);
+	}
+
+	@Override /* CoreApi */
+	public MsgPackSerializer setProperty(String property, Object value) throws LockedException {
+		super.setProperty(property, value);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public MsgPackSerializer setProperties(ObjectMap properties) throws LockedException {
+		super.setProperties(properties);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public MsgPackSerializer addNotBeanClasses(Class<?>...classes) throws LockedException {
+		super.addNotBeanClasses(classes);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public MsgPackSerializer addTransforms(Class<?>...classes) throws LockedException {
+		super.addTransforms(classes);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public <T> MsgPackSerializer addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
+		super.addImplClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public MsgPackSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
+		super.setClassLoader(classLoader);
+		return this;
+	}
+
+	@Override /* Lockable */
+	public MsgPackSerializer lock() {
+		super.lock();
+		return this;
+	}
+
+	@Override /* Lockable */
+	public MsgPackSerializer clone() {
+		try {
+			MsgPackSerializer c = (MsgPackSerializer)super.clone();
+			return c;
+		} catch (CloneNotSupportedException e) {
+			throw new RuntimeException(e); // Shouldn't happen
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java
new file mode 100644
index 0000000..49638b2
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java
@@ -0,0 +1,49 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Configurable properties on the {@link MsgPackSerializer} class.
+ * <p>
+ * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
+ * returned {@link CoreApi#getContextFactory()}.
+ * <p>
+ * The following convenience methods are also provided for setting context properties:
+ * <ul>
+ * 	<li>{@link MsgPackSerializer#setProperty(String,Object)}
+ * 	<li>{@link MsgPackSerializer#setProperties(ObjectMap)}
+ * 	<li>{@link MsgPackSerializer#addNotBeanClasses(Class[])}
+ * 	<li>{@link MsgPackSerializer#addTransforms(Class[])}
+ * 	<li>{@link MsgPackSerializer#addImplClass(Class,Class)}
+ * </ul>
+ * <p>
+ * See {@link ContextFactory} for more information about context properties.
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public final class MsgPackSerializerContext extends SerializerContext {
+
+	/**
+	 * Constructor.
+	 * <p>
+	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 *
+	 * @param cf The factory that created this context.
+	 */
+	public MsgPackSerializerContext(ContextFactory cf) {
+		super(cf);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
new file mode 100644
index 0000000..a1709d9
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
@@ -0,0 +1,52 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+import java.lang.reflect.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Session object that lives for the duration of a single use of {@link MsgPackSerializer}.
+ * <p>
+ * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public final class MsgPackSerializerSession extends SerializerSession {
+
+	/**
+	 * Create a new session using properties specified in the context.
+	 *
+	 * @param ctx The context creating this session object.
+	 * 	The context contains all the configuration settings for this object.
+	 * @param beanContext The bean context being used.
+	 * @param output The output object.  See {@link JsonSerializerSession#getOutputStream()} for valid class types.
+	 * @param op The override properties.
+	 * 	These override any context properties defined in the context.
+	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 */
+	protected MsgPackSerializerSession(MsgPackSerializerContext ctx, BeanContext beanContext, Object output, ObjectMap op, Method javaMethod) {
+		super(ctx, beanContext, output, op, javaMethod);
+	}
+
+	@Override
+	public MsgPackOutputStream getOutputStream() throws Exception {
+		Object output = getOutput();
+		if (output instanceof MsgPackOutputStream)
+			return (MsgPackOutputStream)output;
+		return new MsgPackOutputStream(super.getOutputStream());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/package.html b/juneau-core/src/main/java/org/apache/juneau/msgpack/package.html
new file mode 100644
index 0000000..d37c0ac
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/package.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML>
+<!--
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ ***************************************************************************************************************************/
+ -->
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<style type="text/css">
+		/* For viewing in Page Designer */
+		@IMPORT url("../../../../../../javadoc.css");
+
+		/* For viewing in REST interface */
+		@IMPORT url("../htdocs/javadoc.css");
+		body { 
+			margin: 20px; 
+		}	
+	</style>
+	<script>
+		/* Replace all @code and @link tags. */	
+		window.onload = function() {
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+		}
+	</script>
+</head>
+<body>
+<p>JSON serialization and parsing support</p>
+<script>
+	function toggle(x) {
+		var div = x.nextSibling;
+		while (div != null && div.nodeType != 1)
+			div = div.nextSibling;
+		if (div != null) {
+			var d = div.style.display;
+			if (d == 'block' || d == '') {
+				div.style.display = 'none';
+				x.className += " closed";
+			} else {
+				div.style.display = 'block';
+				x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' );
+			}
+		}
+	}
+</script>
+
+<a id='TOC'></a><h5 class='toc'>Table of Contents</h5>
+<ol class='toc'>
+</ol>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/package.html b/juneau-core/src/main/java/org/apache/juneau/package.html
new file mode 100644
index 0000000..8b3d585
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/package.html
@@ -0,0 +1,217 @@
+<!DOCTYPE HTML>
+<!--
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ ***************************************************************************************************************************/
+ -->
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<style type="text/css">
+		/* For viewing in Page Designer */
+		@IMPORT url("../../../../../javadoc.css");
+
+		/* For viewing in REST interface */
+		@IMPORT url("../htdocs/javadoc.css");
+		body { 
+			margin: 20px; 
+		}	
+	</style>
+	<script>
+		/* Replace all @code and @link tags. */	
+		window.onload = function() {
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+		}
+	</script>
+</head>
+<body>
+<p>Base toolkit for serializers, parsers, and bean contexts</p>
+
+<script>
+	function toggle(x) {
+		var div = x.nextSibling;
+		while (div != null && div.nodeType != 1)
+			div = div.nextSibling;
+		if (div != null) {
+			var d = div.style.display;
+			if (d == 'block' || d == '') {
+				div.style.display = 'none';
+				x.className += " closed";
+			} else {
+				div.style.display = 'block';
+				x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' );
+			}
+		}
+	}
+</script>
+
+<a id='TOC'></a><h5 class='toc'>Table of Contents</h5>
+<ol class='toc'>
+	<li><p><a class='doclink' href='#BeanContext_Api'>Bean Context API</a></p> 
+	<ol>
+		<li><p><a class='doclink' href='#BeanMap'>The BeanMap class</a></p> 
+		<li><p><a class='doclink' href='#BeanContext'>The BeanContext class</a></p>
+		<li><p><a class='doclink' href='#Bean'>Bean annotations</a></p>
+	</ol>
+	<li><p><a class='doclink' href='#ObjectMap_ObjectList'>ObjectMap and ObjectList APIs</a></p>
+	<li><p><a class='doclink' href='#PojoCategories'>POJO Categories</a></p>
+</ol>
+
+<!-- ======================================================================================================== -->
+<a id="BeanContext_Api"></a>
+<h2 class='topic' onclick='toggle(this)'>1 - Bean Context API</h2>
+<div class='topic'>
+	<p>
+		The {@link org.apache.juneau.BeanContext} class is the core class in the Juneau architecture.  It serves multiple functions...
+	</p>
+	<ul class='normal'>
+		<li>It provides the ability to create instances of {@link org.apache.juneau.BeanMap BeanMaps}.
+		<li>It serves as a repository for {@link org.apache.juneau.transform.Transform Transforms}, which are used to tailor how beans and non-beans are handled. 
+		<li>It's used by all built-in {@link org.apache.juneau.serializer.Serializer Serializers} and {@link org.apache.juneau.parser.Parser Parsers} for working with POJOs in a consistent way.
+	</ul>
+	
+	<!-- ======================================================================================================== -->
+	<a id="BeanMap"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.1 - The BeanMap class</h3>
+	<div class='topic'>
+		<p>
+			The {@link org.apache.juneau.BeanMap} class allows you to access the properties of a bean through the familiar {@code Map} interface. 
+			So, for example, you can use the {@code Map.get(key)} method to retrieve a property value in leu of it's getter method, and the {@code Map.put(key, value)} method to set a property value in leu of it's setter method.
+		</p>
+		<p>
+			The serialization and parsing of beans in Juneau is accomplished by wrapping Java beans inside instances of the class {@code BeanMap}. 
+		</p>
+		<p>
+			<b>Note:</b> Instances of {@link org.apache.juneau.BeanMap} objects are always retrieved through the {@link org.apache.juneau.BeanContext} class. You cannot instantiate {@code BeanMaps} directly since the rules for defining what constitutes a bean depend on various settings in the bean context.
+		</p>
+		<p>
+			In general, the performance on using the {@link org.apache.juneau.BeanMap} class to access properties is equivalent to using reflection directly.
+		</p>
+		<p>
+			See the {@link org.apache.juneau.BeanMap} javadoc for more information.
+		</p>
+	</div>
+	
+	<!-- ======================================================================================================== -->
+	<a id="BeanContext"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.2 - The BeanContext class</h3>
+	<div class='topic'>
+		<p>
+			The {@link org.apache.juneau.BeanContext} class is the workhorse class used to wrap Java beans inside {@link org.apache.juneau.BeanMap BeanMaps}. 
+			There are several options provided on the {@link org.apache.juneau.BeanContext} class to tailor the definition of a bean.
+		</p>
+		<p>
+			The following is a very simple example of how to wrap a bean inside a {@link org.apache.juneau.BeanMap} wrapper and use the wrapper interface to get and set property values on the bean. 
+			In this case, we're using the DEFAULT bean context.
+		</p>
+		<p class='bcode'>
+	<jc>// A sample pseudo bean class.</jc>
+	<jk>public class</jk> Person {
+		<jk>public</jk> String getName();
+		<jk>public void</jk> setName(String name);
+		<jk>public int</jk> getAge();
+		<jk>public void</jk> setAge(<jk>int</jk> age);
+	}
+	
+	<jc>// Get an instance of a bean context.
+	// In this case, just use the default bean context.</jc>
+	BeanContext beanContext = BeanContext.<jsf>DEFAULT</jsf>;
+	
+	<jc>// Create an instance of our bean and wrap it in a bean map.</jc>
+	Person p = <jk>new</jk> Person();
+	BeanMap&lt;Person&gt; m = beanContext.forBean(p);
+	
+	<jc>// Set some properties on the bean.</jc>
+	m.put(<js>"name"</js>, <js>"John Smith"</js>);
+	m.put(<js>"age"</js>, 21);
+	
+	<jc>// Print out bean properties.</jc>
+	System.out.println(m.get(<js>"name"</js>));	<jc>// Prints "John Smith"</jc>
+	System.out.println(p.getName());	  <jc>// Prints "John Smith"</jc>
+	System.out.println(m.get(<js>"age"</js>));	 <jc>// Prints 21</jc>
+	System.out.println(p.getAge());		<jc>// Prints 21</jc>
+	
+	<jc>// The bean context class can also create instances of bean maps.</jc>
+	m = beanContext.newBeanMap(Person.<jk>class</jk>);
+	p = m.getBean();	<jc>// Get the new wrapped bean.</jc>
+	
+	<jc>// The bean context class can also create instances of beans.</jc>
+	p = beanContext.newBean(Person.<jk>class</jk>);
+		</p>
+		<p>
+			There are 3 ways to get an instance of a {@link org.apache.juneau.BeanContext}:
+		</p>
+		<p class='bcode'>
+	<jc>// Use one of the default bean contexts.</jc>
+	BeanContext beanContext = BeanContext.<jsf>DEFAULT</jsf>;
+	
+	<jc>// Create a context from scratch with your own settings.</jc>
+	beanContext = <jk>new</jk> BeanContext().addTransforms(DateTransform.ISO8601DT.<jk>class</jk>);
+	
+	<jc>// Clone and modify an existing context.</jc>
+	beanContext = BeanContext.<jsf>DEFAULT</jsf>.clone().addTransforms(DateTransform.ISO8601DT.<jk>class</jk>);
+		</p>
+		<p>
+			The {@link org.apache.juneau.BeanContext} class is a highly-customizable class.  
+			See the {@link org.apache.juneau.BeanContext} javadoc for more information.
+		</p>
+	</div>
+	
+	<!-- ======================================================================================================== -->
+	<a id="Bean"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.3 - Bean annotations</h3>
+	<div class='topic'>
+		<p>
+			Juneau provides the following annotations that can be used to fine-tune what properties are associated with beans:
+		</p>
+		<ul class='normal'>
+			<li>{@link org.apache.juneau.annotation.Bean} - Fine-tune properties associated with beans.
+			<li>{@link org.apache.juneau.annotation.BeanProperty} - Fine-tune bean properties (fields / getters / setters).
+			<li>{@link org.apache.juneau.annotation.BeanConstructor} - Define read-only bean properties that can only be set through constructor arguments.
+			<li>{@link org.apache.juneau.annotation.BeanIgnore} - Prevent bean classes/methods/fields from being interpreted as bean constructs.
+		</ul>
+		<p>
+			These annotations always override the settings defined in the {@link org.apache.juneau.BeanContext} class.
+		</p>
+		<p>
+			For example, the following bean class will only have one property associated with it, <js>"name"</js>, since it's the only one listed in the list of properties.
+		</p>
+		<p class='bcode'>
+	<jc>// Bean with only one 'name' property</jc>
+	<ja>@Bean</ja>(properties={<js>"name"</js>})
+	<jk>public class</jk> Person {
+		<jk>public</jk> String getName();
+		<jk>public void</jk> setName(String name);
+		<jk>public int</jk> getAge();
+		<jk>public void</jk> setAge(<jk>int</jk> age);
+	}
+		</p>
+		<p>
+			When this bean is serialized using one of the {@link org.apache.juneau.serializer.Serializer Serializers}, the age property will be ignored.
+		</p>
+		<p>
+			Using the <ja>@Bean</ja> and <ja>@BeanProperty</ja> annotations, it's also possible to include non-standard properties (for example, getters or setters with non-standard names), or override the names of properties (for example, {@code "Name"} or {@code "fullName"} instead of {@code "name"}).
+		</p>
+		<p>
+			It should be noted that the {@link org.apache.juneau.transform.BeanTransform} class can also be used to exclude properties from beans.  
+			However, only the annotations can be used to include non-standard properties or override property names.
+		</p>
+		<p>
+			See the {@link org.apache.juneau.annotation.Bean}, {@link org.apache.juneau.annotation.BeanProperty}, {@link org.apache.juneau.annotation.BeanConstructor}, and {@link org.apache.juneau.annotation.BeanIgnore} javadocs for more information.
+		</p>
+	</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java b/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java
new file mode 100644
index 0000000..ac8237c
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java
@@ -0,0 +1,45 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.parser;
+
+import org.apache.juneau.annotation.*;
+
+/**
+ * Subclass of {@link Parser} for byte-based parsers.
+ *
+ *
+ * <h6 class='topic'>Description</h6>
+ * <p>
+ * 	This class is typically the parent class of all byte-based parsers.
+ * 	It has 1 abstract method to implement...
+ * <ul>
+ * 	<li><code>parse(InputStream, ClassMeta, ParserContext)</code>
+ * </ul>
+ *
+ *
+ * <h6 class='topic'>@Consumes annotation</h6>
+ * <p>
+ * 	The media types that this parser can handle is specified through the {@link Consumes @Consumes} annotation.
+ * <p>
+ * 	However, the media types can also be specified programmatically by overriding the {@link #getMediaTypes()} method.
+ *
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public abstract class InputStreamParser extends Parser {
+
+	@Override /* Parser */
+	public boolean isReaderParser() {
+		return false;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/parser/ParseException.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParseException.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParseException.java
new file mode 100644
index 0000000..08e2508
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParseException.java
@@ -0,0 +1,105 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+package org.apache.juneau.parser;
+
+import java.text.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.json.*;
+
+/**
+ * Exception that indicates invalid syntax encountered during parsing.
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public final class ParseException extends FormattedException {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param session The parser session to extract information from.
+	 * @param message The exception message containing {@link MessageFormat}-style arguments.
+	 * @param args Message arguments.
+	 */
+	public ParseException(ParserSession session, String message, Object...args) {
+		super(getMessage(session, message, args));
+	}
+
+	/**
+	 * Constructor.
+	 *
+	 * @param message The exception message containing {@link MessageFormat}-style arguments.
+	 * @param args Message arguments.
+	 */
+	public ParseException(String message, Object...args) {
+		super(getMessage(null, message, args));
+	}
+
+	/**
+	 * Constructor.
+	 *
+	 * @param session The parser session to extract information from.
+	 * @param causedBy The inner exception.
+	 */
+	public ParseException(ParserSession session, Exception causedBy) {
+		super(causedBy, getMessage(session, causedBy.getMessage()));
+	}
+
+	/**
+	 * Constructor.
+	 *
+	 * @param causedBy The inner exception.
+	 */
+	public ParseException(Exception causedBy) {
+		super(causedBy, getMessage(null, causedBy.getMessage()));
+	}
+
+	private static String getMessage(ParserSession session, String msg, Object... args) {
+		if (args.length != 0)
+			msg = MessageFormat.format(msg, args);
+		if (session != null) {
+			Map<String,Object> m = session.getLastLocation();
+			if (m != null && ! m.isEmpty())
+				msg = "Parse exception occurred at " + JsonSerializer.DEFAULT_LAX.toString(m) + ".  " + msg;
+		}
+		return msg;
+	}
+
+	/**
+	 * Returns the highest-level <code>ParseException</code> in the stack trace.
+	 * Useful for JUnit testing of error conditions.
+	 *
+	 * @return The root parse exception, or this exception if there isn't one.
+	 */
+	public ParseException getRootCause() {
+		ParseException t = this;
+		while (! (t.getCause() == null || ! (t.getCause() instanceof ParseException)))
+			t = (ParseException)t.getCause();
+		return t;
+	}
+
+	/**
+	 * Sets the inner cause for this exception.
+	 *
+	 * @param cause The inner cause.
+	 * @return This object (for method chaining).
+	 */
+	@Override /* Throwable */
+	public synchronized ParseException initCause(Throwable cause) {
+		super.initCause(cause);
+		return this;
+	}
+}