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 ([email protected])
+ */
+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 ([email protected])
+ */
+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 ([email protected])
+ */
+@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 ([email protected])
+ */
+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 ([email protected])
+ */
+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 ([email protected])
+ */
+@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 ([email protected])
+ */
+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 ([email protected])
+ */
+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 ([email protected])
+ */
+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 ([email protected])
+ */
+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;
+       }
+}

Reply via email to