changeset 0:cb825acd883a

first commit
author sugi
date Sat, 18 Oct 2014 15:06:15 +0900
parents
children 769ba8da0840
files .DS_Store .classpath .project .settings/org.eclipse.core.resources.prefs .settings/org.eclipse.jdt.core.prefs .settings/org.eclipse.m2e.core.prefs .travis.yml AUTHORS CHANGES.txt LICENSE.txt Makefile NOTICE README.md build.xml ivy.xml msgpack.org.md pom.xml src/main/java/org/apache/harmony/beans/Argument.java src/main/java/org/apache/harmony/beans/BeansUtils.java src/main/java/org/apache/harmony/beans/internal/nls/Messages.java src/main/java/org/apache/harmony/beans/internal/nls/messages.properties src/main/java/org/msgpack/MessagePack.java src/main/java/org/msgpack/MessagePackable.java src/main/java/org/msgpack/MessageTypeException.java src/main/java/org/msgpack/annotation/Beans.java src/main/java/org/msgpack/annotation/Delegate.java src/main/java/org/msgpack/annotation/Ignore.java src/main/java/org/msgpack/annotation/Index.java src/main/java/org/msgpack/annotation/Message.java src/main/java/org/msgpack/annotation/MessagePackBeans.java src/main/java/org/msgpack/annotation/MessagePackDelegate.java src/main/java/org/msgpack/annotation/MessagePackMessage.java src/main/java/org/msgpack/annotation/MessagePackOrdinalEnum.java src/main/java/org/msgpack/annotation/NotNullable.java src/main/java/org/msgpack/annotation/Optional.java src/main/java/org/msgpack/annotation/OrdinalEnum.java src/main/java/org/msgpack/io/AbstractInput.java src/main/java/org/msgpack/io/BufferReferer.java src/main/java/org/msgpack/io/BufferedOutput.java src/main/java/org/msgpack/io/ByteBufferOutput.java src/main/java/org/msgpack/io/EndOfBufferException.java src/main/java/org/msgpack/io/Input.java src/main/java/org/msgpack/io/LinkedBufferInput.java src/main/java/org/msgpack/io/LinkedBufferOutput.java src/main/java/org/msgpack/io/Output.java src/main/java/org/msgpack/io/StreamInput.java src/main/java/org/msgpack/io/StreamOutput.java src/main/java/org/msgpack/packer/AbstractPacker.java src/main/java/org/msgpack/packer/BufferPacker.java src/main/java/org/msgpack/packer/MessagePackBufferPacker.java src/main/java/org/msgpack/packer/MessagePackPacker.java src/main/java/org/msgpack/packer/Packer.java src/main/java/org/msgpack/packer/PackerStack.java src/main/java/org/msgpack/packer/Unconverter.java src/main/java/org/msgpack/template/AbstractTemplate.java src/main/java/org/msgpack/template/AnyTemplate.java src/main/java/org/msgpack/template/BigDecimalTemplate.java src/main/java/org/msgpack/template/BigIntegerTemplate.java src/main/java/org/msgpack/template/BooleanArrayTemplate.java src/main/java/org/msgpack/template/BooleanTemplate.java src/main/java/org/msgpack/template/ByteArrayTemplate.java src/main/java/org/msgpack/template/ByteBufferTemplate.java src/main/java/org/msgpack/template/ByteTemplate.java src/main/java/org/msgpack/template/CharacterTemplate.java src/main/java/org/msgpack/template/CollectionTemplate.java src/main/java/org/msgpack/template/DateTemplate.java src/main/java/org/msgpack/template/DoubleArrayTemplate.java src/main/java/org/msgpack/template/DoubleTemplate.java src/main/java/org/msgpack/template/FieldList.java src/main/java/org/msgpack/template/FieldOption.java src/main/java/org/msgpack/template/FloatArrayTemplate.java src/main/java/org/msgpack/template/FloatTemplate.java src/main/java/org/msgpack/template/GenericCollectionTemplate.java src/main/java/org/msgpack/template/GenericMapTemplate.java src/main/java/org/msgpack/template/GenericTemplate.java src/main/java/org/msgpack/template/IntegerArrayTemplate.java src/main/java/org/msgpack/template/IntegerTemplate.java src/main/java/org/msgpack/template/ListTemplate.java src/main/java/org/msgpack/template/LongArrayTemplate.java src/main/java/org/msgpack/template/LongTemplate.java src/main/java/org/msgpack/template/MapTemplate.java src/main/java/org/msgpack/template/MessagePackableTemplate.java src/main/java/org/msgpack/template/NotNullableTemplate.java src/main/java/org/msgpack/template/ObjectArrayTemplate.java src/main/java/org/msgpack/template/OrdinalEnumTemplate.java src/main/java/org/msgpack/template/SetTemplate.java src/main/java/org/msgpack/template/ShortArrayTemplate.java src/main/java/org/msgpack/template/ShortTemplate.java src/main/java/org/msgpack/template/StringTemplate.java src/main/java/org/msgpack/template/Template.java src/main/java/org/msgpack/template/TemplateReference.java src/main/java/org/msgpack/template/TemplateRegistry.java src/main/java/org/msgpack/template/Templates.java src/main/java/org/msgpack/template/ValueTemplate.java src/main/java/org/msgpack/template/builder/AbstractTemplateBuilder.java src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java src/main/java/org/msgpack/template/builder/BeansBuildContext.java src/main/java/org/msgpack/template/builder/BeansFieldEntry.java src/main/java/org/msgpack/template/builder/BuildContext.java src/main/java/org/msgpack/template/builder/DefaultBuildContext.java src/main/java/org/msgpack/template/builder/DefaultFieldEntry.java src/main/java/org/msgpack/template/builder/FieldEntry.java src/main/java/org/msgpack/template/builder/JavassistBeansTemplateBuilder.java src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java.orig src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java src/main/java/org/msgpack/template/builder/ReflectionBeansTemplateBuilder.java src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java src/main/java/org/msgpack/template/builder/TemplateBuildException.java src/main/java/org/msgpack/template/builder/TemplateBuilder.java src/main/java/org/msgpack/template/builder/TemplateBuilderChain.java src/main/java/org/msgpack/template/builder/beans/BeanDescriptor.java src/main/java/org/msgpack/template/builder/beans/BeanInfo.java src/main/java/org/msgpack/template/builder/beans/EventSetDescriptor.java src/main/java/org/msgpack/template/builder/beans/ExceptionListener.java src/main/java/org/msgpack/template/builder/beans/Expression.java src/main/java/org/msgpack/template/builder/beans/FeatureDescriptor.java src/main/java/org/msgpack/template/builder/beans/IndexedPropertyDescriptor.java src/main/java/org/msgpack/template/builder/beans/IntrospectionException.java src/main/java/org/msgpack/template/builder/beans/Introspector.java src/main/java/org/msgpack/template/builder/beans/MethodDescriptor.java src/main/java/org/msgpack/template/builder/beans/ParameterDescriptor.java src/main/java/org/msgpack/template/builder/beans/PropertyChangeEvent.java src/main/java/org/msgpack/template/builder/beans/PropertyChangeListener.java src/main/java/org/msgpack/template/builder/beans/PropertyDescriptor.java src/main/java/org/msgpack/template/builder/beans/PropertyEditor.java src/main/java/org/msgpack/template/builder/beans/PropertyVetoException.java src/main/java/org/msgpack/template/builder/beans/SimpleBeanInfo.java src/main/java/org/msgpack/template/builder/beans/StandardBeanInfo.java src/main/java/org/msgpack/template/builder/beans/Statement.java src/main/java/org/msgpack/template/builder/beans/XMLDecoder.java src/main/java/org/msgpack/type/AbstractArrayValue.java src/main/java/org/msgpack/type/AbstractBooleanValue.java src/main/java/org/msgpack/type/AbstractMapValue.java src/main/java/org/msgpack/type/AbstractRawValue.java src/main/java/org/msgpack/type/AbstractValue.java src/main/java/org/msgpack/type/ArrayValue.java src/main/java/org/msgpack/type/ArrayValueImpl.java src/main/java/org/msgpack/type/BigIntegerValueImpl.java src/main/java/org/msgpack/type/BooleanValue.java src/main/java/org/msgpack/type/ByteArrayRawValueImpl.java src/main/java/org/msgpack/type/DoubleValueImpl.java src/main/java/org/msgpack/type/FalseValueImpl.java src/main/java/org/msgpack/type/FloatValue.java src/main/java/org/msgpack/type/FloatValueImpl.java src/main/java/org/msgpack/type/IntValueImpl.java src/main/java/org/msgpack/type/IntegerValue.java src/main/java/org/msgpack/type/LongValueImpl.java src/main/java/org/msgpack/type/MapValue.java src/main/java/org/msgpack/type/NilValue.java src/main/java/org/msgpack/type/NumberValue.java src/main/java/org/msgpack/type/RawValue.java src/main/java/org/msgpack/type/SequentialMapValueImpl.java src/main/java/org/msgpack/type/StringRawValueImpl.java src/main/java/org/msgpack/type/TrueValueImpl.java src/main/java/org/msgpack/type/Value.java src/main/java/org/msgpack/type/ValueFactory.java src/main/java/org/msgpack/type/ValueType.java src/main/java/org/msgpack/unpacker/AbstractUnpacker.java src/main/java/org/msgpack/unpacker/Accept.java src/main/java/org/msgpack/unpacker/ArrayAccept.java src/main/java/org/msgpack/unpacker/BigIntegerAccept.java src/main/java/org/msgpack/unpacker/BufferUnpacker.java src/main/java/org/msgpack/unpacker/ByteArrayAccept.java src/main/java/org/msgpack/unpacker/Converter.java src/main/java/org/msgpack/unpacker/DoubleAccept.java src/main/java/org/msgpack/unpacker/IntAccept.java src/main/java/org/msgpack/unpacker/LongAccept.java src/main/java/org/msgpack/unpacker/MapAccept.java src/main/java/org/msgpack/unpacker/MessagePackBufferUnpacker.java src/main/java/org/msgpack/unpacker/MessagePackUnpacker.java src/main/java/org/msgpack/unpacker/SizeLimitException.java src/main/java/org/msgpack/unpacker/SkipAccept.java src/main/java/org/msgpack/unpacker/StringAccept.java src/main/java/org/msgpack/unpacker/Unpacker.java src/main/java/org/msgpack/unpacker/UnpackerIterator.java src/main/java/org/msgpack/unpacker/UnpackerStack.java src/main/java/org/msgpack/unpacker/ValueAccept.java src/main/java/org/msgpack/util/TemplatePrecompiler.java src/main/java/org/msgpack/util/android/DalvikVmChecker.java src/main/java/org/msgpack/util/android/PortedImmutableEntry.java src/main/java/org/msgpack/util/json/JSON.java src/main/java/org/msgpack/util/json/JSONBufferPacker.java src/main/java/org/msgpack/util/json/JSONBufferUnpacker.java src/main/java/org/msgpack/util/json/JSONPacker.java src/main/java/org/msgpack/util/json/JSONUnpacker.java src/test/java/org/msgpack/TestBufferPackBufferUnpack.java src/test/java/org/msgpack/TestBufferPackConvert.java src/test/java/org/msgpack/TestBufferPackUnpack.java src/test/java/org/msgpack/TestCrossLang.java src/test/java/org/msgpack/TestMessagePack01.java src/test/java/org/msgpack/TestMessagePack02.java src/test/java/org/msgpack/TestNestedList.java src/test/java/org/msgpack/TestPackBufferUnpack.java src/test/java/org/msgpack/TestPackConvert.java src/test/java/org/msgpack/TestPackUnpack.java src/test/java/org/msgpack/TestSet.java src/test/java/org/msgpack/TestSimpleArrays.java src/test/java/org/msgpack/TestSimpleConvertUnconvert.java src/test/java/org/msgpack/TestSimplePackable.java src/test/java/org/msgpack/TestThreadSafety.java src/test/java/org/msgpack/TestUnconvertConvert.java src/test/java/org/msgpack/TestUnconvertReconvert.java src/test/java/org/msgpack/annotation/TestOptionalBufferPackBufferUnpack.java src/test/java/org/msgpack/annotation/TestOptionalBufferPackUnpack.java src/test/java/org/msgpack/annotation/TestOptionalJavassistBufferPackBufferUnpack.java src/test/java/org/msgpack/annotation/TestOptionalJavassistBufferPackUnpack.java src/test/java/org/msgpack/annotation/TestOptionalJavassistPackBufferUnpack.java src/test/java/org/msgpack/annotation/TestOptionalJavassistPackUnpack.java src/test/java/org/msgpack/annotation/TestOptionalPackBufferUnpack.java src/test/java/org/msgpack/annotation/TestOptionalPackUnpack.java src/test/java/org/msgpack/annotation/TestOptionalReflectionBufferPackBufferUnpack.java src/test/java/org/msgpack/annotation/TestOptionalReflectionBufferPackUnpack.java src/test/java/org/msgpack/annotation/TestOptionalReflectionPackBufferUnpack.java src/test/java/org/msgpack/annotation/TestOptionalReflectionPackUnpack.java src/test/java/org/msgpack/annotation/TestSetOptional.java src/test/java/org/msgpack/io/TestLinkedBufferInput.java src/test/java/org/msgpack/io/TestLinkedBufferOutput.java src/test/java/org/msgpack/simple/TestSimpleDynamicTyping.java src/test/java/org/msgpack/simple/TestSimplePackUnpack.java src/test/java/org/msgpack/simple/TestSimpleStreaming.java src/test/java/org/msgpack/template/TestBigDecimalTemplate.java src/test/java/org/msgpack/template/TestBigIntegerTemplate.java src/test/java/org/msgpack/template/TestBooleanArrayTemplate.java src/test/java/org/msgpack/template/TestBooleanTemplate.java src/test/java/org/msgpack/template/TestByteArrayTemplate.java src/test/java/org/msgpack/template/TestByteBufferTemplate.java src/test/java/org/msgpack/template/TestCharacterTemplate.java src/test/java/org/msgpack/template/TestDateTemplate.java src/test/java/org/msgpack/template/TestDoubleArrayTemplate.java src/test/java/org/msgpack/template/TestDoubleTemplate.java src/test/java/org/msgpack/template/TestFloatArrayTemplate.java src/test/java/org/msgpack/template/TestFloatTemplate.java src/test/java/org/msgpack/template/TestIntegerArrayTemplate.java src/test/java/org/msgpack/template/TestIntegerTemplate.java src/test/java/org/msgpack/template/TestListTemplate.java src/test/java/org/msgpack/template/TestLongArrayTemplate.java src/test/java/org/msgpack/template/TestLongTemplate.java src/test/java/org/msgpack/template/TestMapTemplate.java src/test/java/org/msgpack/template/TestShortArrayTemplate.java src/test/java/org/msgpack/template/TestShortTemplate.java src/test/java/org/msgpack/template/TestStringTemplate.java src/test/java/org/msgpack/template/TestTemplateRegistry.java src/test/java/org/msgpack/template/TestTemplates.java src/test/java/org/msgpack/template/builder/TestJavassistBufferPackBufferUnpack.java src/test/java/org/msgpack/template/builder/TestJavassistBufferPackConvert.java src/test/java/org/msgpack/template/builder/TestJavassistBufferPackUnpack.java src/test/java/org/msgpack/template/builder/TestJavassistPackBufferUnpack.java src/test/java/org/msgpack/template/builder/TestJavassistPackConvert.java src/test/java/org/msgpack/template/builder/TestJavassistPackUnpack.java src/test/java/org/msgpack/template/builder/TestOrdinalEnumBufferPackBufferUnpack.java src/test/java/org/msgpack/template/builder/TestOrdinalEnumBufferPackConvert.java src/test/java/org/msgpack/template/builder/TestOrdinalEnumBufferPackUnpack.java src/test/java/org/msgpack/template/builder/TestOrdinalEnumPackBufferUnpack.java src/test/java/org/msgpack/template/builder/TestOrdinalEnumPackConvert.java src/test/java/org/msgpack/template/builder/TestOrdinalEnumPackUnpack.java src/test/java/org/msgpack/template/builder/TestReflectionBeansBufferPackBufferUnpack.java src/test/java/org/msgpack/template/builder/TestReflectionBeansBufferPackConvert.java src/test/java/org/msgpack/template/builder/TestReflectionBeansBufferPackUnpack.java src/test/java/org/msgpack/template/builder/TestReflectionBeansPackBufferUnpack.java src/test/java/org/msgpack/template/builder/TestReflectionBeansPackConvert.java src/test/java/org/msgpack/template/builder/TestReflectionBeansPackUnpack.java src/test/java/org/msgpack/template/builder/TestReflectionBufferPackBufferUnpack.java src/test/java/org/msgpack/template/builder/TestReflectionBufferPackConvert.java src/test/java/org/msgpack/template/builder/TestReflectionBufferPackUnpack.java src/test/java/org/msgpack/template/builder/TestReflectionPackBufferUnpack.java src/test/java/org/msgpack/template/builder/TestReflectionPackConvert.java src/test/java/org/msgpack/template/builder/TestReflectionPackUnpack.java src/test/java/org/msgpack/template/builder/TestSet.java src/test/java/org/msgpack/testclasses/AbstractClass.java src/test/java/org/msgpack/testclasses/EnumTypeFieldsClass.java src/test/java/org/msgpack/testclasses/EnumTypeFieldsClassNotNullable.java src/test/java/org/msgpack/testclasses/FinalClass.java src/test/java/org/msgpack/testclasses/IndexedFieldsBeanClass.java src/test/java/org/msgpack/testclasses/IndexedFieldsBeanClassNotNullable.java src/test/java/org/msgpack/testclasses/InheritanceClass.java src/test/java/org/msgpack/testclasses/InheritanceClassNotNullable.java src/test/java/org/msgpack/testclasses/Interface.java src/test/java/org/msgpack/testclasses/ListTypeFieldsClass.java src/test/java/org/msgpack/testclasses/ListTypeFieldsClassNotNullable.java src/test/java/org/msgpack/testclasses/MapTypeFieldsClass.java src/test/java/org/msgpack/testclasses/MapTypeFieldsClassNotNullable.java src/test/java/org/msgpack/testclasses/MessagePackableTypeFieldsClass.java src/test/java/org/msgpack/testclasses/MessagePackableTypeFieldsClassNotNullable.java src/test/java/org/msgpack/testclasses/ModifiersFieldsClass.java src/test/java/org/msgpack/testclasses/ModifiersFieldsClassNotNullable.java src/test/java/org/msgpack/testclasses/PrimitiveTypeFieldsClass.java src/test/java/org/msgpack/testclasses/PrimitiveTypeFieldsClassNotNullable.java src/test/java/org/msgpack/testclasses/ReferenceCycleTypeFieldsClass.java src/test/java/org/msgpack/testclasses/ReferenceCycleTypeFieldsClassNotNullable.java src/test/java/org/msgpack/testclasses/ReferenceTypeFieldsClass.java src/test/java/org/msgpack/testclasses/ReferenceTypeFieldsClassNotNullable.java src/test/java/org/msgpack/testclasses/SuperClass.java src/test/java/org/msgpack/testclasses/SuperClassNotNullable.java src/test/java/org/msgpack/testclasses/UserDefinedTypeFieldsClass.java src/test/java/org/msgpack/testclasses/UserDefinedTypeFieldsClassNotNullable.java src/test/java/org/msgpack/type/ProxyValue.java src/test/java/org/msgpack/type/TestEquals.java src/test/java/org/msgpack/type/TestHashCode.java src/test/java/org/msgpack/unpacker/TestBufferUnpacker.java src/test/java/org/msgpack/unpacker/TestMalformedEncoding.java src/test/java/org/msgpack/unpacker/TestReadTemplate.java src/test/java/org/msgpack/unpacker/TestSizeLimit.java src/test/java/org/msgpack/unpacker/TestUnpackerIterator.java src/test/java/org/msgpack/unpacker/TestUnpackerSkip.java src/test/java/org/msgpack/util/TestTemplatePreCompilerBufferPackBufferUnpack.java src/test/java/org/msgpack/util/json/TestJSONBufferPackBufferUnpack.java src/test/java/org/msgpack/util/json/TestJSONBufferPackUnpack.java src/test/java/org/msgpack/util/json/TestJSONPackBufferUnpack.java src/test/java/org/msgpack/util/json/TestJSONPackUnpack.java src/test/java/org/msgpack/util/json/TestSimpleJSONPackUnpack.java src/test/java/org/msgpack/util/json/TestValueToStringJSONUnpack.java src/test/resources/cases.json src/test/resources/cases.mpac src/test/resources/cases_compact.mpac
diffstat 315 files changed, 54287 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
Binary file .DS_Store has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.classpath	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**/*.java" including="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.project	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>msgpack</name>
+	<comment>MessagePack for Java is a binary-based efficient object
+      serialization library in Java.</comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.settings/org.eclipse.core.resources.prefs	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
+encoding/<project>=UTF-8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.settings/org.eclipse.jdt.core.prefs	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.settings/org.eclipse.m2e.core.prefs	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.travis.yml	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,15 @@
+language: java
+jdk:
+  - openjdk6
+  - openjdk7
+  - oraclejdk7
+branches:
+  only:
+    - master
+    - develop
+    - v07
+notifications:
+  email:
+    - muga.nishizawa@gmail.com
+    - ozawa.tsuyoshi@gmail.com
+    - leo@xerial.org
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AUTHORS	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,2 @@
+FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>
+Muga Nishizawa <muga.nishizawa _at_ gmail.com>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGES.txt	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,200 @@
+Release 0.6.8 - 2013/08/17
+  BUG FIXES
+    Replaces method calls of LinkedList#peek{First,Last}() into get{First,Last}() within LinkedBufferInput class (pull request #18)
+    Makes encoding byte[][] work correctly (pull request #24)
+    Ports SimpleImmutableEntry for Android2.2 or below (pull request #27)
+    Fixes to check upper bound and lower bound of IntAccept#acceptInteger(long) correctly (pull request #43)
+
+  IMPROVEMENTS
+    MSGPACK-83 Gracefully handling new enum value with OrdinalEnum (pull request #26)
+    Refactors some jar dependencies for Android
+    Adds MessagePack#read(byte[] bytes, int off, int len, Class<T> c)
+    Changes README format to Markdown
+    Supports maven-findbugs-plugin
+
+Release 0.6.7 - 2012/12/09
+  NEW FEATURES
+    Adds MessagePack for Android
+
+  BUG FIXES
+    MSGPACK-78 Generated template causes SecurityException when used from Java web start applications
+    MSGPACK-76 Tries to generate a template of an abstract class
+    MSGPACK-75 ClassCastException occurs during generating a class that has fields of TypeVariable types
+    MSGPACK-74 Writing message with java.util.Set field causes StackOverflowError
+    MSGPACK-74 Reading message with java.util.Set field causes IllegalArgumentException
+
+Release 0.6.6 - 2012/05/09
+  BUG FIXES
+    Fixes bug: cannot generate templates of user-classes that have fields of
+    generic WildcardType types
+
+  IMPROVEMENTS
+    Changes version of dependency json-simple: 1.1 to 1.1.1
+    Changes version of dependency Javassist: 3.15.0-GA to 3.16.1-GA
+    Implements a template generation for GenericArrayType
+    Increases limition of element sizes of unpacked array and map objects
+
+Release 0.6.5 - 2012/01/12
+  IMPROVEMENTS
+    MSGPACK-59: includes OSGi headers in manifest
+
+Release 0.6.4 - 2012/01/05
+  NEW FEATURES
+    Adds getBufferSize in BufferUnpacker interface.
+
+  BUG FIXES
+    Fixes bug:validation error occurs when loading templates of array classes with
+    Javassist-based template builder.
+    MSGPACK-58 Changes logging library from SLF4J to java.util.logging.Logger.
+    PULL REQUEST-10 Fix compilation error caused by package name mistake.
+
+Release 0.6.3 - 2011/11/08
+  NEW FEATURES
+    Adds getReadByteCount and resetReadByteCount methods to Unpacker interface.
+    Adds setRawSizeLimit, setArraySizeLimit and setMapSizeLimit methods to
+    Unpacker interface.
+
+  BUG FIXES
+    Fixes Perf. loss: generated templates reflectively accessed via variables of
+    public fields in the objects.
+
+  IMPROVEMENTS
+    Changes source and target release, which are Javac options, to 1.6.
+    Registers Date and BigDecimal templates as builtin.
+
+Release 0.6.2 - 2011/10/24
+  NEW FEATURES
+    Enables serializing private fields in objects by Javassist generated templates.
+
+  BUG FIXES
+    MSGPACK-42 VerifyError occurs when generating templates for classes that have 
+    @Optional primitive fields
+    MSGPACK-43 Mutually referencing MessagePack objects causes StackOverflowError
+    MSGPACK-49 Fail to serialize org.msgpack.type.Value objects
+    MSGPACK-50 Fail to serialize object representing classes have fields of
+    nested non-generic List, Map and Collection types
+
+  IMPROVEMENTS
+    Modifies TemplateRegistry class for msgpack-scala
+    Adds deleteTemplateClass method to TemplatePrecompiler.
+
+Release 0.6.1 - 2011/10/07
+  IMPROVEMENTS
+    Deleted unused methods in Packer and Unpacker classes.
+
+Release 0.6.0 - 2011/10/03
+  NEW FEATURES
+    Adds some new APIs (Packer, Unpacker, Value, and so on).  See
+    "Quick Start" (http://wiki.msgpack.org/display/MSGPACK/QuickStart+for+Java).
+    Adds JSON data serialization. See org.msgpack.util.json package. It allows
+    serializing JSON data to MessagePack binary.
+    MessagePack jar file was deployed to Maven's central repository.
+    License of Javassist was changed into triple license of the MPL, the LGPL,
+    and the Apache License.  MessagePack uses Javassist under Apache License.
+
+  IMPROVEMENTS
+    Refactors and optimizes core library for serialization/deserialization.
+    Refactors template classes and those builder classes.
+
+Release 0.5.2 - 2011/04/23
+  NEW FEATURES
+    MSGPACK-6 Added TemplatePrecompiler program
+
+    Added built-in templates of BigDecimal and Date classes.
+
+    Added @MessagePackBeans annotation that enables you to serialize/deserialize
+    JavaBeans.
+
+  BUG FIXES
+    MSGPACK-4 Fixes the deserialization routine of Long value
+
+  IMPROVEMENTS
+    #35 Improves handling of ClassLoader on Javassist template builder.
+
+    MSGPACK-7 Improves compatibility with Java 1.5. Now it runs on JRE 5.
+    It is tested on Jenkins CI: http://ci.msgpack.org/job/java-jre5/
+
+
+Release 0.5.1 - 2010/12/14
+  BUG FIXES
+    Fixes cast error on GenericArrayType
+
+    Throws MessagePackException instead of NullPointerException if target is null
+    on pack method.
+
+
+Release 0.5.0 - 2010/12/09
+  NEW FEATURES
+    Dynamic template builder is rewritten. New ReflectionTemplateBuilder
+    supports DalvikVM.
+
+    Some optimization for dynamic code generator.
+
+    @MessagePackMessage accepts default filed option.
+    Added new field annotations: @Ignore, @Requred and @Index.
+
+    Supported pack/unpack/convertion of arrays including multidimensional arrays.
+
+    Added native pack/unpack routine of ByteBuffer. It will be zero-copy optimized
+    under a specific condition.
+
+
+Release 0.4.3 - 2010/11/10
+  NEW FEATURES
+    Added FieldList class and MessagePack.register(Class<T>, FieldList) method
+    to specify optional/nullable options on runtime without annotations.
+
+    Changed annotation name: @MessagePackNullable -> @Nullable
+    Changed annotation name: @MessagePackOptional -> @Optional
+
+    Supported pack/unpack/convertion of enums.
+
+    Added MessagePack.unpack(buffer, T to) and MessagePackObject.convert(T to)
+    methods. They can unpack/convert buffer/object into existing object and
+    eliminate re-allocation overhead.
+
+
+Release 0.4.2 - 2010/11/09
+  NEW FEATURES
+    Added MessagePackNullable annotation and Tempalte.tNullable(Template)
+    method.
+
+    Added <T> T MessagePackObject.unpack(Class<T>) method.
+
+
+Release 0.4.1 - 2010/11/05
+  BUG FIXES
+    Fixed dynamic code generation of unpack methods
+
+
+Release 0.4.0 - 2010/10/25
+  NEW FEATURES
+    Added MessagePackObject class and org.msgpack.object package that
+    represent unpacked (=dynamically typed) objects.
+    Unpacker.unpack method returns MessagePackObject instead of Object.
+
+    Added Templates class and org.msgpack.template package that provide
+    type conversion feature.
+
+    User-defined classes annotated with MessagePackMessage can be
+    pack/unpack/converted.
+
+    User-defined classes registered with MessagePack.register(Class) can be
+    pack/unpack/converted.
+
+    Added dynamic code generation feature for user-defined classes.
+
+    Added MessagePackOptional annotation.
+
+    Added MessagePack class that implements typical useful methods.
+
+
+Release 0.3 - 2010/05/23
+  NEW FEATURES
+    Added Unbuffered API + Direct Conversion API to the Unpacker.
+
+  BUG FIXES
+    Zero-length Array and Map is deserialized as List and Map, instead of the
+    array of the Object.
+
+    fixed the bug around Packer.packByte().
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE.txt	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,24 @@
+
+.PHONY: compile test eclipse clean package
+
+all:
+	compile
+
+package:
+	mvn package
+
+install:
+	mvn install
+
+compile:
+	mvn compile
+
+test:
+	mvn test
+
+# generate .project and .classpath file for Eclipse
+eclipse:
+	mvn eclipse:eclipse
+
+clean:
+	mvn clean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NOTICE	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,52 @@
+This project uses code from the ASF Apache Harmony project. The following are the relevant notices
+from that project, included in order to comply with its license requirements.
+-------------------
+Apache Harmony
+Copyright 2006, 2010 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of Apache Harmony were originally developed by
+Intel Corporation and are licensed to the Apache Software
+Foundation under the "Software Grant and Corporate Contribution
+License Agreement" and for which the following copyright notices
+apply
+         (C) Copyright 2005 Intel Corporation
+         (C) Copyright 2005-2006 Intel Corporation
+         (C) Copyright 2006 Intel Corporation
+
+Portions of Apache Harmony's Class Library TEXT module contain JavaDoc
+derived from the ICU project.
+Copyright (c) 1995-2008 International Business Machines Corporation and others 
+
+
+The Apache Harmony Development Kit (HDK) contains a jar file from the
+Apache Derby Project for which the following notice applies:
+
+Apache Derby
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of Derby were originally developed by
+International Business Machines Corporation and are
+licensed to the Apache Software Foundation under the
+"Software Grant and Corporate Contribution License Agreement",
+informally known as the "Derby CLA".
+The following copyright notice(s) were affixed to portions of the code
+with which this file is now or was at one time distributed
+and are placed here unaltered.
+
+(C) Copyright 1997,2004 International Business Machines Corporation.
+All rights reserved.
+
+(C) Copyright IBM Corp. 2003. 
+
+The portion of the functionTests under 'nist' was originally 
+developed by the National Institute of Standards and Technology (NIST), 
+an agency of the United States Department of Commerce, and adapted by
+International Business Machines Corporation in accordance with the NIST
+Software Acknowledgment and Redistribution document at
+http://www.itl.nist.gov/div897/ctg/sql_form.htm
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,53 @@
+# MessagePack for Java
+
+[MessagePack](http://msgpack.org/) is an efficient binary serialization format.
+It lets you exchange data among multiple languages like JSON but it's faster and smaller.
+For example, small integers (like flags or error code) are encoded into a single byte,
+and typical short strings only require an extra byte in addition to the strings themselves.
+
+You may be interested in how msgpack-java is faster than the other libraries.
+To know this, please see [jvm-serializers](https://github.com/eishay/jvm-serializers/wiki), which is one of well-known benchmarks for comparing Java libraries of data serialization.
+
+[![Build Status](https://travis-ci.org/msgpack/msgpack-java.png?branch=master)](https://travis-ci.org/msgpack/msgpack-java)
+
+## Quick start
+
+Quick start for msgpack-java is available at [Wiki](https://github.com/msgpack/msgpack-java/wiki/QuickStart).
+
+
+## Build
+
+To build the JAR file of MessagePack, you need to install Maven (http://maven.apache.org), then type the following command:
+
+    $ mvn package
+
+To locally install the project, type
+
+    $ mvn install
+
+To generate project files (.project, .classpath) for Eclipse, do
+
+    $ mvn eclipse:eclipse
+
+then import the folder from your Eclipse.
+
+Next, open the preference page in Eclipse and add the CLASSPATH variable:
+
+    M2_REPO = $HOME/.m2/repository
+
+where $HOME is your home directory. In Windows XP, $HOME is:
+
+    C:/Documents and Settings/(user name)/.m2/repository
+
+
+## How to release
+
+To relese the project (compile, test, tagging, deploy), please use the commands as follows:
+
+    $ mvn release:prepare
+    $ mvn release:perform
+
+## License
+
+This software is distributed under [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build.xml	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,303 @@
+<project name="MessagePack for Java" default="jar"
+    xmlns:ivy="antlib:org.apache.ivy.ant"
+    xmlns:mvn="urn:maven-artifact-ant">
+
+  <property name="Name" value="MessagePack"/>
+  <property name="name" value="msgpack"/>
+  <property name="version" value="0.0.1"/>
+  <property name="fullname" value="${name}-${version}"/>
+  <property name="year" value="2011"/>
+
+  <!-- Load user's default properties. -->
+  <property file="${user.home}/build.properties" />
+
+  <property name="src.dir" value="${basedir}/src/main/java"/>  	
+  <property name="java.src.dir" value="${src.dir}/"/>
+  <property name="build.dir" value="${basedir}/build"/>
+  <property name="lib.dir" value="${basedir}/lib"/>
+  <property name="dist.dir" value="${basedir}/dist"/>
+
+  <property name="build.classes" value="${build.dir}/classes"/>
+  <property name="build.doc" value="${build.dir}/doc"/>
+  <property name="build.javadoc" value="${build.doc}/api/"/>
+  <property name="build.javadoc.log" value="${build.dir}/javadoc.log"/>
+
+  <property name="test.count" value="100"/>
+  <property name="test.junit.output.format" value="plain"/>
+  <property name="test.java.src.dir" value="${basedir}/src/test/java"/>
+  <property name="test.java.build.dir" value="${build.dir}/test"/>
+  <property name="test.java.classes" value="${test.java.build.dir}/classes"/>
+  <property name="test.java.include" value="Test*"/>
+ 
+  <property name="javac.encoding" value="ISO-8859-1"/>
+  <property name="javac.debug" value="on"/>
+  <property name="javac.optimize" value="on"/>
+  <property name="javac.deprecation" value="off"/>
+  <property name="javac.version" value="1.6"/>
+  <property name="javac.args" value=""/>
+  <property name="javac.args.warnings" value="-Xlint:unchecked"/>
+
+  <property name="javadoc.link.java"
+	    value="http://java.sun.com/javase/6/docs/api/"/>
+  <property name="javadoc.packages" value="org.${name}.*"/>
+
+  <!-- ivy settings -->
+  <property name="ivy.version" value="2.1.0"/>
+  <property name="ivy.url"
+	    value="http://repo2.maven.org/maven2/org/apache/ivy/ivy" />
+  <property name="ivy.home" value="${user.home}/.ant" />
+  <property name="ivy.lib" value="${build.dir}/lib"/>
+  <property name="ivy.test.lib" value="${build.dir}/test/lib"/>
+  <property name="mvn.repo"
+	    value="https://repository.apache.org/content/repositories/snapshots"/>
+
+  <!-- the normal classpath -->
+  <path id="libs">
+    <fileset dir="${ivy.lib}">
+      <include name="**/*.jar" />
+    </fileset>
+  </path>
+  <path id="java.classpath">
+    <pathelement location="${build.classes}"/>
+    <fileset dir="${lib.dir}">
+      <include name="**/*.jar" />
+      <exclude name="**/excluded/" />
+    </fileset>
+    <fileset dir="${ant.home}/lib">
+      <include name="ant.jar" />
+    </fileset>
+    <path refid="libs" />
+  </path>
+  <path id="test.libs">
+    <fileset dir="${ivy.test.lib}">
+      <include name="**/*.jar" />
+    </fileset>
+  </path>
+  <path id="test.java.classpath">
+    <pathelement location="${test.java.classes}" />
+    <path refid="java.classpath"/>
+    <path refid="test.libs"/>
+  </path>
+
+  <!-- init & clean -->
+  <target name="init">
+    <mkdir dir="${build.dir}" />
+    <mkdir dir="${lib.dir}" />
+    <mkdir dir="${build.classes}" />
+
+    <mkdir dir="${test.java.build.dir}"/>
+    <mkdir dir="${test.java.classes}"/>
+
+    <mkdir dir="${ivy.lib}"/>
+    <mkdir dir="${ivy.test.lib}"/>
+    <condition property="ivy.jar.exists">
+      <available file="${lib.dir}/ivy-${ivy.version}.jar"/>
+    </condition>
+  </target>
+  <target name="clean">
+    <delete dir="${build.dir}" />
+  </target>
+
+  <!-- ivy targets -->
+  <target name="ivy-download" unless="ivy.jar.exists" depends="init">
+    <delete dir="${lib.dir}"
+	    includes="ivy-*.jar" excludes="ivy-${ivy.version}.jar"/>
+    <get src="${ivy.url}/${ivy.version}/ivy-${ivy.version}.jar"
+         dest="${lib.dir}/ivy-${ivy.version}.jar" usetimestamp="true"/>
+  </target>
+  <target name="ivy-init" depends="ivy-download" unless="ivy.initialized">
+    <taskdef resource="org/apache/ivy/ant/antlib.xml"
+             uri="antlib:org.apache.ivy.ant" classpathref="java.classpath"/>
+    <!-- ensure that ivy taskdef is only run once, otw ant will error -->
+    <property name="ivy.initialized" value="true"/>
+  </target>
+   
+ <target name="ivy-retrieve-build" depends="init,ivy-init">
+    <ivy:retrieve type="jar" conf="build"
+		  pattern="${ivy.lib}/[artifact]-[revision].[ext]"/>
+ </target>
+ <target name="ivy-retrieve-test" depends="init,ivy-init">
+    <ivy:retrieve type="jar" conf="test"
+		  pattern="${ivy.test.lib}/[artifact]-[revision].[ext]"/>
+ </target>
+
+  <!-- compiler -->
+  <macrodef name="java-compiler">
+    <attribute name="dest" default="${build.classes}"/>
+    <attribute name="includes" default="**/*.java"/>
+    <attribute name="excludes" default=""/>
+    <attribute name="classpath" default="java.classpath"/>
+    <element name="src" implicit="yes"/>
+    <sequential>
+      <javac 
+	 destdir="@{dest}"
+         includes="@{includes}"
+         excludes="@{excludes}" 
+	 encoding="${javac.encoding}" 
+	 debug="${javac.debug}"
+	 optimize="${javac.optimize}"
+	 target="${javac.version}"
+	 source="${javac.version}"
+	 deprecation="${javac.deprecation}">
+	<compilerarg line="${javac.args} ${javac.args.warnings}" />
+	<classpath refid="@{classpath}"/>
+        <src />
+      </javac>
+    </sequential>
+  </macrodef>
+
+  <!-- compile -->
+  <target name="compile" depends="init,ivy-retrieve-build">
+    <java-compiler>
+      <src path="${java.src.dir}"/>
+    </java-compiler>
+  </target>
+
+  <!-- test -->
+  <macrodef name="test-runner">
+    <attribute name="files.location" />
+    <attribute name="tests.pattern" />
+    <attribute name="test.dir" default="${test.java.build.dir}" />
+    <sequential>
+      <junit showoutput="yes"
+             printsummary="withOutAndErr"
+             haltonfailure="no"
+             fork="yes" forkMode="once"
+             errorProperty="tests.failed" failureProperty="tests.failed">
+        <sysproperty key="test.count" value="${test.count}"/>
+        <sysproperty key="test.dir" value="@{test.dir}"/>
+        <classpath refid="test.java.classpath"/>
+        <formatter type="${test.junit.output.format}"/>
+        <batchtest todir="${test.java.build.dir}" unless="testcase">
+          <fileset dir="@{files.location}"
+		   includes="@{tests.pattern}"
+		   excludes="**/${test.java.exclude}.java" />
+        </batchtest>
+        <batchtest todir="${test.java.build.dir}" if="testcase">
+          <fileset dir="@{files.location}" includes="**/${testcase}.java"/>
+        </batchtest>
+      </junit>
+      <fail if="tests.failed">Tests Failed!</fail>
+    </sequential>
+  </macrodef>
+  <target name="compile-test" depends="ivy-retrieve-test,compile">
+    <java-compiler dest="${test.java.classes}"
+		   classpath="test.java.classpath">
+      <src path="${test.java.src.dir}/org" />
+    </java-compiler>
+  </target>
+  <target name="test" depends="init,compile-test">
+    <test-runner files.location="${test.java.src.dir}"
+                 tests.pattern="**/${test.java.include}.java"/>
+  </target>
+
+  <!-- jar -->
+  <target name="jar" depends="compile">
+    <jar jarfile="${build.dir}/${name}-${version}.jar" basedir="${build.classes}" >
+      <manifest>
+        <section name="org/${name}">
+          <attribute name="Implementation-Title" value="${Name}"/>
+          <attribute name="Implementation-Version" value="${version}"/>
+        </section>
+      </manifest>
+    </jar>
+  </target>
+
+  <!-- javadoc -->
+  <target name="javadoc" depends="compile" description="Generate javadoc">
+    <mkdir dir="${build.javadoc}"/>
+    <record name="${build.javadoc.log}" action="start"/>
+    <javadoc
+      Locale="en_US"
+      packagenames="org.${org}.${name}.*"
+      destdir="${build.javadoc}"
+      encoding="UTF-8"
+      docencoding="UTF-8"
+      author="true"
+      version="true"
+      use="true"
+      windowtitle="${Name} ${version} API"
+      doctitle="${Name} ${version} API"
+      bottom="Copyright &amp;copy; ${year} The ${Name} Project"
+      >
+        <packageset dir="${java.src.dir}"/>
+        <link href="${javadoc.link.java}"/>
+        <classpath >
+          <path refid="java.classpath" />
+        </classpath>
+    </javadoc>
+    <record name="${build.javadoc.log}" action="stop"/>
+    <condition property="javadoc.warnings">
+      <isfileselected file="${build.javadoc.log}">
+	<contains text=": warning - "/>
+      </isfileselected>
+    </condition>
+    <fail if="javadoc.warnings">Javadoc warnings!</fail>
+  </target>
+  <target name="javadoc-jar" depends="javadoc">
+    <jar jarfile="${build.dir}/${fullname}-javadoc.jar">
+      <fileset dir="${build.javadoc}" includes="**/*"/>
+    </jar>
+  </target>
+
+  <!-- sources -->
+  <target name="source">
+    <jar jarfile="${build.dir}/${fullname}-sources.jar">
+      <fileset dir="${java.src.dir}" includes="**/*.java"/>
+    </jar>
+  </target>
+
+  <!-- pom -->
+  <target name="pom" depends="ivy-init">
+    <ivy:makepom ivyfile="${basedir}/ivy.xml"
+		 pomfile="${dist.dir}/${fullname}.pom">
+      <mapping conf="default" scope="compile"/>
+      <mapping conf="test" scope="test"/>
+    </ivy:makepom>
+  </target>
+
+  <!-- dist -->
+  <target name="dist" depends="jar, pom, source, javadoc-jar"
+	  description="Build distribution">
+    <mkdir dir="${dist.dir}"/>
+    <copy todir="${dist.dir}"> 
+      <fileset file="${build.dir}/${fullname}.jar"/>
+      <fileset file="${build.dir}/${fullname}-sources.jar"/>
+      <fileset file="${build.dir}/${fullname}-javadoc.jar"/>
+    </copy>
+  </target>
+
+  <!-- maven: install msgpack into local m2 cache -->
+  <target name="mvn-install" depends="jar, pom, source, javadoc-jar"
+	  description="Installs msgpack to local m2 cache">
+    <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
+	     uri="urn:maven-artifact-ant"
+	     classpathref="java.classpath"/>
+    <mvn:pom file="${dist.dir}/${fullname}.pom" id="msgpack"/>
+    <mvn:install file="${build.dir}/${fullname}.jar">
+      <attach file="${build.dir}/${fullname}-sources.jar"
+           classifier="sources" />
+      <attach file="${build.dir}/${fullname}-javadoc.jar"
+           classifier="javadoc" />
+      <pom refid="msgpack"/>
+    </mvn:install>
+  </target>
+
+  <!-- maven: create local repository into ${basedir}/maven2 -->
+  <target name="mvn-deploy" depends="jar, pom, source, javadoc-jar"
+     description="Deploys MessagePack to Maven repo.">
+    <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
+	     uri="urn:maven-artifact-ant"
+	     classpathref="java.classpath"/>
+    <mvn:pom file="${dist.dir}/${fullname}.pom" id="msgpack"/>
+    <mvn:deploy file="${build.dir}/${fullname}.jar">
+      <remoteRepository url="file://localhost/${basedir}/maven2/"/>
+      <attach file="${build.dir}/${fullname}-sources.jar"
+           classifier="sources" />
+      <attach file="${build.dir}/${fullname}-javadoc.jar"
+           classifier="javadoc" />
+      <pom refid="msgpack"/>
+    </mvn:deploy>
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ivy.xml	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,23 @@
+<ivy-module version="2.0"
+            xmlns:e="http://ant.apache.org/ivy/extra">
+
+  <info organisation="org"
+    module="${name}" revision="${version}">
+    <ivyauthor name="MessagePack Project" url="http://msgpack.org/"/>
+    <description>MessagePack</description>
+  </info>
+
+  <configurations defaultconfmapping="default">
+    <conf name="default"/> <!-- "runtime" configuration -->
+    <conf name="test"/>
+    <conf name="build" extends="default"/>
+  </configurations>
+
+  <dependencies>
+    <dependency org="com.googlecode.json-simple" name="json-simple" rev="1.1"/>
+    <dependency org="org.javassist" name="javassist" rev="3.15.0-GA"/>
+    <dependency org="org.slf4j" name="slf4j-api" rev="1.6.1"/>
+    <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.6.1"/>
+    <dependency org="junit" name="junit" rev="4.8.2" conf="test->default"/>
+  </dependencies>
+</ivy-module>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/msgpack.org.md	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,46 @@
+# MessagePack for Java
+
+QuickStart for msgpack-java is available [here](https://github.com/msgpack/msgpack-java/wiki/QuickStart).
+
+## How to install
+
+You can install msgpack via maven:
+
+    <dependencies>
+      ...
+      <dependency>
+        <groupId>org.msgpack</groupId>
+        <artifactId>msgpack</artifactId>
+        <version>${msgpack.version}</version>
+      </dependency>
+      ...
+    </dependencies>
+
+## Simple Serialization/Deserialization/Duck Typing using Value
+
+    // Create serialize objects.
+    List<String> src = new ArrayList<String>();
+    src.add("msgpack");
+    src.add("kumofs");
+    src.add("viver");
+
+    MessagePack msgpack = new MessagePack();
+    // Serialize
+    byte[] raw = msgpack.write(src);
+
+    // Deserialize directly using a template
+    List<String> dst1 = msgpack.read(raw, Templates.tList(Templates.TString));
+    System.out.println(dst1.get(0));
+    System.out.println(dst1.get(1));
+    System.out.println(dst1.get(2));
+
+    // Or, Deserialze to Value then convert type.
+    Value dynamic = msgpack.read(raw);
+    List<String> dst2 = new Converter(dynamic)
+        .read(Templates.tList(Templates.TString));
+    System.out.println(dst2.get(0));
+    System.out.println(dst2.get(1));
+    System.out.println(dst2.get(2));
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pom.xml	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,193 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.msgpack</groupId>
+  <artifactId>msgpack</artifactId>
+  <name>MessagePack for Java</name>
+  <description>MessagePack for Java is a binary-based efficient object
+      serialization library in Java.</description>
+  <version>0.6.12-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+  <url>http://msgpack.org/</url>
+
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+
+  <scm>
+    <connection>scm:git:git://github.com/msgpack/msgpack-java.git</connection>
+    <developerConnection>scm:git:git@github.com:msgpack/msgpack-java.git</developerConnection>
+    <url>scm:git:git://github.com/msgpack/msgpack-java.git</url>
+  </scm>
+
+  <issueManagement>
+    <system>GitHub</system>
+    <url>https://github.com/msgpack/msgpack-java/issues</url>
+  </issueManagement>
+
+  <developers>
+    <developer>
+      <id>frsyuki</id>
+      <name>Sadayuki Furuhashi</name>
+      <email>frsyuki@users.sourceforge.jp</email>
+    </developer>
+    <developer>
+      <id>muga</id>
+      <name>Muga Nishizawa</name>
+      <email>muga.nishizawa@gmail.com</email>
+    </developer>
+  </developers>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.googlecode.json-simple</groupId>
+      <artifactId>json-simple</artifactId>
+      <version>1.1.1</version>
+	<exclusions>
+		<exclusion>
+			<artifactId>junit</artifactId>
+			<groupId>junit</groupId>
+		</exclusion>
+	</exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.javassist</groupId>
+      <artifactId>javassist</artifactId>
+      <version>3.18.1-GA</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <parent>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>7</version>
+  </parent>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>src/test/resources</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+          <encoding>UTF-8</encoding>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>2.3.6</version>
+        <extensions>true</extensions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-eclipse-plugin</artifactId>
+        <version>2.5.1</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <version>2.1.2</version>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-scm-plugin</artifactId>
+        <version>1.6</version>
+        <configuration>
+          <pushChanges>false</pushChanges>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>2.8.1</version>
+        <configuration>
+          <doctitle>${project.name} ${project.version} API</doctitle>
+          <aggregate>true</aggregate>
+          <locale>en_US</locale>
+          <encoding>UTF-8</encoding>
+        </configuration>
+      </plugin>
+<!--
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.13</version>
+        <configuration>
+          <parallel>methods</parallel>
+          <threadCount>10</threadCount>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.apache.maven.surefire</groupId>
+            <artifactId>surefire-junit47</artifactId>
+            <version>2.13</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+-->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.8.1</version>
+        <configuration>
+          <argLine>-Xmx512M</argLine>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <configuration>
+          <findbugsXmlOutput>true</findbugsXmlOutput>
+          <xmlOutput>true</xmlOutput>
+          <effort>Max</effort>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+        <version>2.2</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+        <version>2.11</version>
+      </plugin>
+    </plugins>
+  </reporting>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/apache/harmony/beans/Argument.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,62 @@
+// MODIFIED FOR THE MSGPACK PROJECT
+// 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.harmony.beans;
+
+public class Argument {
+
+    private Class<?> type;
+
+    private Object value;
+
+    private Class<?>[] interfaces;
+
+    public Argument(Object value) {
+        this.value = value;
+        if (this.value != null) {
+            this.type = value.getClass();
+            this.interfaces = this.type.getInterfaces();
+        }
+    }
+
+    public Argument(Class<?> type, Object value) {
+        this.type = type;
+        this.value = value;
+        this.interfaces = type.getInterfaces();
+    }
+
+    public Class<?> getType() {
+        return type;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public Class<?>[] getInterfaces() {
+        return interfaces;
+    }
+
+    public void setType(Class<?> type) {
+        this.type = type;
+        this.interfaces = type.getInterfaces();
+    }
+
+    public void setInterfaces(Class<?>[] interfaces) {
+        this.interfaces = interfaces;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/apache/harmony/beans/BeansUtils.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,122 @@
+// MODIFIED FOR THE MSGPACK PROJECT
+// 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.harmony.beans;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+public class BeansUtils {
+
+    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+
+    public static final String NEW = "new"; //$NON-NLS-1$
+
+    public static final String NEWINSTANCE = "newInstance"; //$NON-NLS-1$
+
+    public static final String NEWARRAY = "newArray"; //$NON-NLS-1$
+
+    public static final String FORNAME = "forName"; //$NON-NLS-1$
+
+    public static final String GET = "get"; //$NON-NLS-1$
+
+    public static final String IS = "is"; //$NON-NLS-1$
+
+    public static final String SET = "set"; //$NON-NLS-1$
+
+    public static final String ADD = "add"; //$NON-NLS-1$
+
+    public static final String PUT = "put"; //$NON-NLS-1$
+
+    public static final String NULL = "null"; //$NON-NLS-1$
+
+    public static final String QUOTE = "\"\""; //$NON-NLS-1$
+
+    public static final int getHashCode(Object obj) {
+        return obj != null ? obj.hashCode() : 0;
+    }
+
+    public static final int getHashCode(boolean bool) {
+        return bool ? 1 : 0;
+    }
+
+    public static String toASCIILowerCase(String string) {
+        char[] charArray = string.toCharArray();
+        StringBuilder sb = new StringBuilder(charArray.length);
+        for (int index = 0; index < charArray.length; index++) {
+            if ('A' <= charArray[index] && charArray[index] <= 'Z') {
+                sb.append((char) (charArray[index] + ('a' - 'A')));
+            } else {
+                sb.append(charArray[index]);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String toASCIIUpperCase(String string) {
+        char[] charArray = string.toCharArray();
+        StringBuilder sb = new StringBuilder(charArray.length);
+        for (int index = 0; index < charArray.length; index++) {
+            if ('a' <= charArray[index] && charArray[index] <= 'z') {
+                sb.append((char) (charArray[index] - ('a' - 'A')));
+            } else {
+                sb.append(charArray[index]);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static boolean isPrimitiveWrapper(Class<?> wrapper, Class<?> base) {
+        return (base == boolean.class) && (wrapper == Boolean.class)
+                || (base == byte.class) && (wrapper == Byte.class)
+                || (base == char.class) && (wrapper == Character.class)
+                || (base == short.class) && (wrapper == Short.class)
+                || (base == int.class) && (wrapper == Integer.class)
+                || (base == long.class) && (wrapper == Long.class)
+                || (base == float.class) && (wrapper == Float.class)
+                || (base == double.class) && (wrapper == Double.class);
+    }
+
+    private static final String EQUALS_METHOD = "equals";
+
+    private static final Class<?>[] EQUALS_PARAMETERS = new Class<?>[] { Object.class };
+
+    public static boolean declaredEquals(Class<?> clazz) {
+        for (Method declaredMethod : clazz.getDeclaredMethods()) {
+            if (EQUALS_METHOD.equals(declaredMethod.getName())
+                    && Arrays.equals(declaredMethod.getParameterTypes(),
+                            EQUALS_PARAMETERS)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static String idOfClass(Class<?> clazz) {
+        Class<?> theClass = clazz;
+        StringBuilder sb = new StringBuilder();
+        if (theClass.isArray()) {
+            do {
+                sb.append("Array"); //$NON-NLS-1$
+                theClass = theClass.getComponentType();
+            } while (theClass.isArray());
+        }
+        String clazzName = theClass.getName();
+        clazzName = clazzName.substring(clazzName.lastIndexOf('.') + 1);
+        return clazzName + sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/apache/harmony/beans/internal/nls/Messages.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,240 @@
+// MODIFIED FOR THE MSGPACK PROJECT
+// 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.
+//
+
+//
+// THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+// All changes made to this file manually will be overwritten 
+// if this tool runs again. Better make changes in the template file.
+//
+
+package org.apache.harmony.beans.internal.nls;
+
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+//import org.apache.harmony.kernel.vm.VM;
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ *    org.apache.harmony.beans.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ * 
+ */
+public class Messages {
+
+    // ResourceBundle holding the system messages.
+    static private ResourceBundle bundle = null;
+
+    /**
+     * Retrieves a message which has no arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg) {
+        if (bundle == null)
+            return msg;
+        try {
+            return bundle.getString(msg);
+        } catch (MissingResourceException e) {
+            return "Missing message: " + msg; //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Retrieves a message which takes 1 argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            Object the object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg) {
+        return getString(msg, new Object[] { arg });
+    }
+
+    /**
+     * Retrieves a message which takes 1 integer argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            int the integer to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, int arg) {
+        return getString(msg, new Object[] { Integer.toString(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 1 character argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            char the character to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, char arg) {
+        return getString(msg, new Object[] { String.valueOf(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 2 arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg1
+     *            Object an object to insert in the formatted output.
+     * @param arg2
+     *            Object another object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg1, Object arg2) {
+        return getString(msg, new Object[] { arg1, arg2 });
+    }
+
+    /**
+     * Retrieves a message which takes several arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param args
+     *            Object[] the objects to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object[] args) {
+        String format = msg;
+
+        if (bundle != null) {
+            try {
+                format = bundle.getString(msg);
+            } catch (MissingResourceException e) {
+            }
+        }
+
+        return format(format, args);
+    }
+    
+    /**
+     * Generates a formatted text string given a source string containing
+     * "argument markers" of the form "{argNum}" where each argNum must be in
+     * the range 0..9. The result is generated by inserting the toString of each
+     * argument into the position indicated in the string.
+     * <p>
+     * To insert the "{" character into the output, use a single backslash
+     * character to escape it (i.e. "\{"). The "}" character does not need to be
+     * escaped.
+     * 
+     * @param format
+     *            String the format to use when printing.
+     * @param args
+     *            Object[] the arguments to use.
+     * @return String the formatted message.
+     */
+    public static String format(String format, Object[] args) {
+        StringBuilder answer = new StringBuilder(format.length()
+                + (args.length * 20));
+        String[] argStrings = new String[args.length];
+        for (int i = 0; i < args.length; ++i) {
+            if (args[i] == null)
+                argStrings[i] = "<null>";	//$NON-NLS-1$
+            else
+                argStrings[i] = args[i].toString();
+        }
+        int lastI = 0;
+        for (int i = format.indexOf('{', 0); i >= 0; i = format.indexOf('{',
+                lastI)) {
+            if (i != 0 && format.charAt(i - 1) == '\\') {
+                // It's escaped, just print and loop.
+                if (i != 1)
+                    answer.append(format.substring(lastI, i - 1));
+                answer.append('{');
+                lastI = i + 1;
+            } else {
+                // It's a format character.
+                if (i > format.length() - 3) {
+                    // Bad format, just print and loop.
+                    answer.append(format.substring(lastI, format.length()));
+                    lastI = format.length();
+                } else {
+                    int argnum = (byte) Character.digit(format.charAt(i + 1),
+                            10);
+                    if (argnum < 0 || format.charAt(i + 2) != '}') {
+                        // Bad format, just print and loop.
+						answer.append(format.substring(lastI, i + 1));
+						lastI = i + 1;
+                    } else {
+                        // Got a good one!
+                        answer.append(format.substring(lastI, i));
+                        if (argnum >= argStrings.length)
+                            answer.append("<missing argument>");	//$NON-NLS-1$
+                        else
+                            answer.append(argStrings[argnum]);
+						lastI = i + 3;
+                    }
+                }
+            }
+        }
+        if (lastI < format.length())
+            answer.append(format.substring(lastI, format.length()));
+        return answer.toString();
+    }
+//
+//    /**
+//     * Changes the locale of the messages.
+//     * 
+//     * @param locale
+//     *            Locale the locale to change to.
+//     */
+//    static public ResourceBundle setLocale(final Locale locale,
+//            final String resource) {
+//        try {
+//            final ClassLoader loader = VM.bootCallerClassLoader();
+//            return (ResourceBundle) AccessController
+//                    .doPrivileged(new PrivilegedAction<Object>() {
+//                        public Object run() {
+//                            return ResourceBundle.getBundle(resource, locale,
+//                                    loader != null ? loader : ClassLoader.getSystemClassLoader());
+//                        }
+//                    });
+//        } catch (MissingResourceException e) {
+//        }
+//        return null;
+//    }
+//
+//    static {
+//        // Attempt to load the messages.
+//        try {
+//            bundle = setLocale(Locale.getDefault(),
+//                    "org.apache.harmony.beans.internal.nls.messages"); //$NON-NLS-1$
+//        } catch (Throwable e) {
+//            e.printStackTrace();
+//        }
+//    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/apache/harmony/beans/internal/nls/messages.properties	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,134 @@
+# MODIFIED FOR THE MSGPACK PROJECT
+# 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.
+# 
+
+# messages for EN locale
+beans.00=no getter for {0} property
+beans.01=no property for name {0} is found
+beans.02=in DefaultPersistenceDelegate.mutatesTo() {0} : {1}
+beans.03=Target Bean class is null
+beans.04=bad property name
+beans.05=Modifier for setter method should be public.
+beans.06=Number of parameters in setter method is not equal to 1.
+beans.07=Parameter type in setter method does not corresponds to predefined.
+beans.08=Number of parameters in getter method is not equal to 0.
+beans.09=Parameter type in getter method does not corresponds to predefined.
+beans.0A=Modifier for getter method should be public.
+beans.0B=Exception in command execution
+beans.0C=source is null
+beans.0D=Error in expression: {0}
+beans.0E=Changes are null
+beans.0F=The new BeanContext can not be set
+beans.10=no node is found for statement with target = {0}
+beans.11=no getter for property {0} found
+beans.12=cannot access property {0} getter
+beans.13=no setter for property {0} found
+beans.14=Exception while finding property descriptor
+beans.15=The listener is null
+beans.16=The provider is null
+beans.17=The child is null
+beans.18=The requestor is null
+beans.19=The service class is null
+beans.1A=The service selector is null
+beans.1B=The service is null
+beans.1C=The event is null
+beans.1D=bean is null
+beans.1E=Illegal class name: {0}
+beans.1F=Method not found: get{0}
+beans.20=Method not found: set{0}
+beans.21=Modifier for indexed getter method should be public.
+beans.22=Number of parameters in getter method is not equal to 1.
+beans.23=Parameter in indexed getter method is not of integer type.
+beans.24=Parameter type in indexed getter method does not correspond to predefined.
+beans.25=Modifier for indexed setter method should be public.
+beans.26=Number of parameters in indexed setter method is not equal to 2.
+beans.27=First parameter type in indexed setter method should be int.
+beans.28=Second parameter type in indexed setter method does not corresponds to predefined.
+beans.29=Membership listener is null
+beans.2A=Target child can not be null
+beans.2B=Resource name can not be null
+beans.2C=The child can not be null
+beans.2D=Invalid resource
+beans.2E=PropertyVetoException was thrown while removing a child: {0}; Original error message:{1}
+beans.2F=Target child is null
+beans.30=PropertyVetoException was thrown while adding a child: {0}; Original error message:{1}
+beans.31=No valid method {0} for {1} found.
+beans.32=Cannot acquire event type from {0} listener.
+beans.33={0} does not return <void>
+beans.34={0} should have a single input parameter
+beans.35=Single parameter does not match to {0} class
+beans.36=No input params are allowed for getListenerMethod
+beans.37=Return type of getListenerMethod is not an array of listeners
+beans.38=Add and remove methods are not available
+beans.39=Cannot generate event set descriptor for name {0}.
+beans.3A=Event type with name {0} is not found.
+beans.3B=skipping expression {0}...
+beans.3C=Unknown method name for array
+beans.3D=First parameter in array getter(setter) is not of Integer type
+beans.3E=Illegal number of arguments in array getter
+beans.3F=Illegal number of arguments in array setter
+beans.40=No constructor for class {0} found
+beans.41=No method with name {0} is found
+beans.42=target is not generated: classname {0} is not found
+beans.43=Cannot convert {0} to char
+beans.44=for property {0} no getter(setter) is found
+beans.45=method name is not generated: error in getMethodName()
+beans.46=Not a valid child
+beans.47=Unable to instantiate property editor
+beans.48=Property editor is not assignable from the PropertyEditor interface
+beans.49=Child cannot implement both BeanContextChild and BeanContextProxy
+beans.4A=newInstance is null
+beans.4B=type is null
+beans.4C=encoder is null
+beans.4D=Invalid method call
+beans.4E=stopClass is not ancestor of beanClass
+beans.4F=search path is null
+beans.50=not an indexed property
+beans.51=Listener method {0} should have parameter of type {1}
+beans.52=listenerMethodName(s) is null
+beans.53=eventSetName is null
+beans.54=listenerType is null
+beans.55=Method is null
+beans.56=Provider does not match
+beans.57=Property type is incompatible with the indexed property type
+beans.58=No such indexed read method
+beans.59=Security violation accessing indexed read method
+beans.5A=Indexed read method is not compatible with indexed write method
+beans.5B=Indexed read method must take a single int argument
+beans.5C=Security violation accessing indexed write method
+beans.5D=No such indexed write method
+beans.5E=Indexed method is not compatible with non indexed method
+beans.5F=Indexed write method must take a two arguments
+beans.60=Indexed write method must take an int as its first argument
+beans.61=Indexed write method is not compatible with indexed read method
+beans.62=Cannot decide which method to call to match {0}
+beans.63=The type of element is mismatch with the type of array
+beans.64=Method not found: {0}
+beans.65=not a child of this context
+beans.66=not the service provider registered with this context
+beans.67=null child
+beans.68=cannot update children during serialization
+beans.69=Validation failed to add the child
+beans.6A=null BeanContextChild proxy
+beans.6B=failed to update child's beanContext property
+beans.6C=Illegal to impl both BeanContextChild and BeanContextProxy
+beans.6D=Not a child of this context
+beans.6E=Validation failed to remove the child
+beans.6F=children changed during serialization!
+beans.70=no more objects to read
+beans.71=Unknown tag of basic type: {0}
+beans.72=Unknown root element: {0}
+beans.73=Unknown basic object: {0}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/MessagePack.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,837 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.nio.ByteBuffer;
+import org.msgpack.template.Template;
+import org.msgpack.template.TemplateRegistry;
+import org.msgpack.packer.Packer;
+import org.msgpack.packer.BufferPacker;
+import org.msgpack.packer.MessagePackPacker;
+import org.msgpack.packer.MessagePackBufferPacker;
+import org.msgpack.packer.Unconverter;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.unpacker.BufferUnpacker;
+import org.msgpack.unpacker.MessagePackUnpacker;
+import org.msgpack.unpacker.MessagePackBufferUnpacker;
+import org.msgpack.unpacker.Converter;
+import org.msgpack.type.Value;
+
+/**
+ * <p>
+ * This is basic class to use MessagePack for Java. It creates serializers and
+ * deserializers for objects of classes.
+ * </p>
+ * 
+ * <p>
+ * See <a
+ * href="http://wiki.msgpack.org/display/MSGPACK/QuickStart+for+Java">Quick
+ * Start for Java</a> on MessagePack wiki.
+ * </p>
+ * 
+ */
+public class MessagePack {
+    private TemplateRegistry registry;
+
+    /**
+     * 
+     * @since 0.6.0
+     */
+    public MessagePack() {
+        registry = new TemplateRegistry(null);
+    }
+
+    /**
+     * 
+     * @since 0.6.0
+     * @param msgpack
+     */
+    public MessagePack(MessagePack msgpack) {
+        registry = new TemplateRegistry(msgpack.registry);
+    }
+
+    protected MessagePack(TemplateRegistry registry) {
+        this.registry = registry;
+    }
+
+    /**
+     * 
+     * @since 0.6.0
+     * @param cl
+     */
+    public void setClassLoader(final ClassLoader cl) {
+        registry.setClassLoader(cl);
+    }
+
+    /**
+     * Returns serializer that enables serializing objects into
+     * {@link java.io.OutputStream} object.
+     * 
+     * @since 0.6.0
+     * @param out
+     *            output stream
+     * @return stream-based serializer
+     */
+    public Packer createPacker(OutputStream out) {
+        return new MessagePackPacker(this, out);
+    }
+
+    /**
+     * Returns serializer that enables serializing objects into buffer.
+     * 
+     * @since 0.6.0
+     * @return buffer-based serializer
+     */
+    public BufferPacker createBufferPacker() {
+        return new MessagePackBufferPacker(this);
+    }
+
+    /**
+     * Returns serializer that enables serializing objects into buffer.
+     * 
+     * @since 0.6.0
+     * @param bufferSize
+     *            initial size of buffer
+     * @return buffer-based serializer
+     */
+    public BufferPacker createBufferPacker(int bufferSize) {
+        return new MessagePackBufferPacker(this, bufferSize);
+    }
+
+    /**
+     * Returns deserializer that enables deserializing
+     * {@link java.io.InputStream} object.
+     * 
+     * @since 0.6.0
+     * @param in
+     *            input stream
+     * @return stream-based deserializer
+     */
+    public Unpacker createUnpacker(InputStream in) {
+        return new MessagePackUnpacker(this, in);
+    }
+
+    /**
+     * Returns empty deserializer that enables deserializing buffer.
+     * 
+     * @since 0.6.0
+     * @return buffer-based deserializer
+     */
+    public BufferUnpacker createBufferUnpacker() {
+        return new MessagePackBufferUnpacker(this);
+    }
+
+    /**
+     * Returns deserializer that enables deserializing buffer.
+     * 
+     * @since 0.6.0
+     * @param bytes
+     *            input byte array
+     * @return buffer-based deserializer
+     */
+    public BufferUnpacker createBufferUnpacker(byte[] bytes) {
+        return createBufferUnpacker().wrap(bytes);
+    }
+
+    /**
+     * Returns deserializer that enables deserializing buffer.
+     * 
+     * @since 0.6.0
+     * @param bytes
+     * @param off
+     * @param len
+     * @return buffer-based deserializer
+     */
+    public BufferUnpacker createBufferUnpacker(byte[] bytes, int off, int len) {
+        return createBufferUnpacker().wrap(bytes, off, len);
+    }
+
+    /**
+     * Returns deserializer that enables deserializing buffer.
+     * 
+     * @since 0.6.0
+     * @param buffer
+     *            input {@link java.nio.ByteBuffer} object
+     * @return buffer-based deserializer
+     */
+    public BufferUnpacker createBufferUnpacker(ByteBuffer buffer) {
+        return createBufferUnpacker().wrap(buffer);
+    }
+
+    /**
+     * Serializes specified object.
+     * 
+     * @since 0.6.0
+     * @param v
+     *            serialized object
+     * @return output byte array
+     * @throws IOException
+     */
+    public <T> byte[] write(T v) throws IOException {
+        BufferPacker pk = createBufferPacker();
+        if (v == null) {
+            pk.writeNil();
+        } else {
+            @SuppressWarnings("unchecked")
+            Template<T> tmpl = registry.lookup(v.getClass());
+            tmpl.write(pk, v);
+        }
+        return pk.toByteArray();
+    }
+
+    /**
+     * Serializes specified object. It allows serializing object by specified
+     * template.
+     * 
+     * @since 0.6.0
+     * @param v
+     * @param template
+     * @return
+     * @throws IOException
+     */
+    public <T> byte[] write(T v, Template<T> template) throws IOException {
+        BufferPacker pk = createBufferPacker();
+        template.write(pk, v);
+        return pk.toByteArray();
+    }
+
+    /**
+     * Serializes specified object to output stream.
+     * 
+     * @since 0.6.0
+     * @param out
+     *            output stream
+     * @param v
+     *            serialized object
+     * @throws IOException
+     */
+    public <T> void write(OutputStream out, T v) throws IOException {
+        Packer pk = createPacker(out);
+        if (v == null) {
+            pk.writeNil();
+        } else {
+            @SuppressWarnings("unchecked")
+            Template<T> tmpl = registry.lookup(v.getClass());
+            tmpl.write(pk, v);
+        }
+    }
+
+    /**
+     * Serializes object to output stream by specified template.
+     * 
+     * @since 0.6.0
+     * @param out
+     *            output stream
+     * @param v
+     *            serialized object
+     * @param template
+     *            serializer/deserializer for the object
+     * @throws IOException
+     */
+    public <T> void write(OutputStream out, T v, Template<T> template)
+            throws IOException {
+        Packer pk = createPacker(out);
+        template.write(pk, v);
+    }
+
+    /**
+     * Serializes {@link org.msgpack.type.Value} object to byte array.
+     * 
+     * @since 0.6.0
+     * @param v
+     *            serialized {@link org.msgpack.type.Value} object
+     * @return output byte array
+     * @throws IOException
+     */
+    public byte[] write(Value v) throws IOException {
+        // FIXME ValueTemplate should do this
+        BufferPacker pk = createBufferPacker();
+        pk.write(v);
+        return pk.toByteArray();
+    }
+
+    /**
+     * Deserializes specified byte array to {@link org.msgpack.type.Value}
+     * object.
+     * 
+     * @since 0.6.0
+     * @param bytes
+     *            input byte array
+     * @return
+     * @throws IOException
+     */
+    public Value read(byte[] bytes) throws IOException {
+        return read(bytes, 0, bytes.length);
+    }
+
+    /**
+     * Deserializes byte array to {@link org.msgpack.type.Value} object.
+     * 
+     * @since 0.6.0
+     * @param bytes
+     * @param off
+     * @param len
+     * @return
+     * @throws IOException
+     */
+    public Value read(byte[] bytes, int off, int len) throws IOException {
+        return createBufferUnpacker(bytes, off, len).readValue();
+    }
+
+    /**
+     * Deserializes {@link java.nio.ByteBuffer} object to
+     * {@link org.msgpack.type.Value} object.
+     * 
+     * @since 0.6.0
+     * @param buffer
+     *            input buffer
+     * @return
+     * @throws IOException
+     */
+    public Value read(ByteBuffer buffer) throws IOException {
+        return createBufferUnpacker(buffer).readValue();
+    }
+
+    /**
+     * Deserializes input stream to {@link org.msgpack.type.Value} object.
+     * 
+     * @since 0.6.0
+     * @param in
+     *            input stream
+     * @return deserialized {@link org.msgpack.type.Value} object
+     * @throws IOException
+     */
+    public Value read(InputStream in) throws IOException {
+        return createUnpacker(in).readValue();
+    }
+
+    /**
+     * Deserializes byte array to object.
+     * 
+     * @since 0.6.0
+     * @param bytes
+     *            input byte array
+     * @param v
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(byte[] bytes, T v) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(v.getClass());
+        return read(bytes, v, tmpl);
+    }
+
+    /**
+     * Deserializes byte array to object according to template.
+     * 
+     * @since 0.6.0
+     * @param bytes
+     *            input byte array
+     * @param tmpl
+     *            template
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(byte[] bytes, Template<T> tmpl) throws IOException {
+        return read(bytes, null, tmpl);
+    }
+
+    /**
+     * Deserializes byte array to object of specified class.
+     * 
+     * @since 0.6.0
+     * @param bytes
+     *            input byte array
+     * @param c
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(byte[] bytes, Class<T> c) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(c);
+        return read(bytes, null, tmpl);
+    }
+
+    /**
+     * Deserializes byte array to object according to specified template.
+     * 
+     * @since 0.6.0
+     * @param bytes
+     *            input byte array
+     * @param v
+     * @param tmpl
+     *            template
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(byte[] bytes, T v, Template<T> tmpl) throws IOException {
+        BufferUnpacker u = createBufferUnpacker(bytes);
+        return (T) tmpl.read(u, v);
+    }
+
+    /**
+     * Deserializes byte array to object.
+     *
+     * @since 0.6.8
+     * @param bytes
+     *            input byte array
+     * @param v
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(byte[] bytes, int off, int len, Class<T> c) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(c);
+        BufferUnpacker u = createBufferUnpacker(bytes, off, len);
+        return (T) tmpl.read(u, null);
+    }
+
+    /**
+     * Deserializes buffer to object.
+     * 
+     * @since 0.6.0
+     * @param b
+     *            input {@link java.nio.ByteBuffer} object
+     * @param v
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(ByteBuffer b, T v) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(v.getClass());
+        return read(b, v, tmpl);
+    }
+
+    /**
+     * Deserializes buffer to object according to template.
+     * 
+     * @since 0.6.0
+     * @param b
+     *            input buffer object
+     * @param tmpl
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(ByteBuffer b, Template<T> tmpl) throws IOException {
+        return read(b, null, tmpl);
+    }
+
+    /**
+     * Deserializes buffer to object of specified class.
+     * 
+     * @since 0.6.0
+     * @param b
+     * @param c
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(ByteBuffer b, Class<T> c) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(c);
+        return read(b, null, tmpl);
+    }
+
+    /**
+     * Deserializes buffer to object according to template.
+     * 
+     * @since 0.6.0
+     * @param b
+     *            input buffer object
+     * @param v
+     * @param tmpl
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(ByteBuffer b, T v, Template<T> tmpl) throws IOException {
+        BufferUnpacker u = createBufferUnpacker(b);
+        return tmpl.read(u, v);
+    }
+
+    /**
+     * Deserializes input stream to object.
+     * 
+     * @since 0.6.0
+     * @param in
+     *            input stream
+     * @param v
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(InputStream in, T v) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(v.getClass());
+        return read(in, v, tmpl);
+    }
+
+    /**
+     * Deserializes input stream to object according to template.
+     * 
+     * @since 0.6.0
+     * @param in
+     *            input stream
+     * @param tmpl
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(InputStream in, Template<T> tmpl) throws IOException {
+        return read(in, null, tmpl);
+    }
+
+    /**
+     * Deserializes input stream to object of specified class.
+     * 
+     * @since 0.6.0
+     * @param in
+     * @param c
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(InputStream in, Class<T> c) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(c);
+        return read(in, null, tmpl);
+    }
+
+    /**
+     * Deserializes input stream to object according to template
+     * 
+     * @since 0.6.0
+     * @param in
+     *            input stream
+     * @param v
+     * @param tmpl
+     * @return
+     * @throws IOException
+     */
+    public <T> T read(InputStream in, T v, Template<T> tmpl) throws IOException {
+        Unpacker u = createUnpacker(in);
+        return tmpl.read(u, v);
+    }
+
+    /**
+     * Converts specified {@link org.msgpack.type.Value} object to object.
+     * 
+     * @since 0.6.0
+     * @param v
+     * @param to
+     * @return
+     * @throws IOException
+     */
+    public <T> T convert(Value v, T to) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(to.getClass());
+        return tmpl.read(new Converter(this, v), to);
+    }
+
+    /**
+     * Converts {@link org.msgpack.type.Value} object to object specified class.
+     * 
+     * @since 0.6.0
+     * @param v
+     * @param c
+     * @return
+     * @throws IOException
+     */
+    public <T> T convert(Value v, Class<T> c) throws IOException {
+        @SuppressWarnings("unchecked")
+        Template<T> tmpl = registry.lookup(c);
+        return tmpl.read(new Converter(this, v), null);
+    }
+        
+    /**
+     * Converts {@link org.msgpack.type.Value} object to object according to template
+     * 
+     * @since 0.6.8
+     * @param v
+     * @param tmpl
+     * @return
+     * @throws IOException
+     */
+    public <T> T convert(Value v, Template<T> tmpl) throws IOException {
+        return tmpl.read(new Converter(this, v), null);
+    }
+
+    /**
+     * Unconverts specified object to {@link org.msgpack.type.Value} object.
+     * 
+     * @since 0.6.0
+     * @param v
+     * @return
+     * @throws IOException
+     */
+    public <T> Value unconvert(T v) throws IOException {
+        Unconverter pk = new Unconverter(this);
+        if (v == null) {
+            pk.writeNil();
+        } else {
+            @SuppressWarnings("unchecked")
+            Template<T> tmpl = registry.lookup(v.getClass());
+            tmpl.write(pk, v);
+        }
+        return pk.getResult();
+    }
+
+    /**
+     * Registers {@link org.msgpack.template.Template} object for objects of
+     * specified class. <tt>Template</tt> object is a pair of serializer and
+     * deserializer for object serialization. It is generated automatically.
+     * 
+     * @since 0.6.0
+     * @param type
+     */
+    public void register(Class<?> type) {
+        registry.register(type);
+    }
+
+    /**
+     * Registers specified {@link org.msgpack.template.Template} object
+     * associated by class.
+     * 
+     * @see #register(Class)
+     * @since 0.6.0
+     * @param type
+     * @param template
+     */
+    public <T> void register(Class<T> type, Template<T> template) {
+        registry.register(type, template);
+    }
+
+    /**
+     * Unregisters {@link org.msgpack.template.Template} object for objects of
+     * specified class.
+     * 
+     * @since 0.6.0
+     * @param type
+     * @return
+     */
+    public boolean unregister(Class<?> type) {
+        return registry.unregister(type);
+    }
+
+    /**
+     * Unregisters all {@link org.msgpack.template.Template} objects that have
+     * been registered in advance.
+     * 
+     * @since 0.6.0
+     */
+    public void unregister() {
+        registry.unregister();
+    }
+
+    /**
+     * Looks up a {@link org.msgpack.template.Template} object, which is
+     * serializer/deserializer associated by specified class.
+     * 
+     * @since 0.6.0
+     * @param type
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    public <T> Template<T> lookup(Class<T> type) {
+        return registry.lookup(type);
+    }
+
+    public Template<?> lookup(Type type) {
+        return registry.lookup(type);
+    }
+
+    private static final MessagePack globalMessagePack = new MessagePack();
+
+    /**
+     * Serializes specified object and returns the byte array.
+     * 
+     * @deprecated {@link MessagePack#write(Object)}
+     * @param v
+     * @return
+     * @throws IOException
+     */
+    @Deprecated
+    public static byte[] pack(Object v) throws IOException {
+        return globalMessagePack.write(v);
+    }
+
+    /**
+     * Serializes specified object to output stream.
+     * 
+     * @deprecated {@link MessagePack#write(OutputStream, Object)}
+     * @param out
+     * @param v
+     * @throws IOException
+     */
+    @Deprecated
+    public static void pack(OutputStream out, Object v) throws IOException {
+        globalMessagePack.write(out, v);
+    }
+
+    /**
+     * Serializes object by specified template and return the byte array.
+     * 
+     * @deprecated {@link MessagePack#write(Object, Template)}
+     * @param v
+     * @param template
+     * @return
+     * @throws IOException
+     */
+    @Deprecated
+    public static <T> byte[] pack(T v, Template<T> template) throws IOException {
+        return globalMessagePack.write(v, template);
+    }
+
+    /**
+     * Serializes object to output stream. The object is serialized by specified
+     * template.
+     * 
+     * @deprecated {@link MessagePack#write(OutputStream, Object, Template)}
+     * @param out
+     * @param v
+     * @param template
+     * @throws IOException
+     */
+    @Deprecated
+    public static <T> void pack(OutputStream out, T v, Template<T> template)
+            throws IOException {
+        globalMessagePack.write(out, v, template);
+    }
+
+    /**
+     * Converts byte array to {@link org.msgpack.type.Value} object.
+     * 
+     * @deprecated {@link MessagePack#read(byte[])}
+     * @param bytes
+     * @return
+     * @throws IOException
+     */
+    @Deprecated
+    public static Value unpack(byte[] bytes) throws IOException {
+        return globalMessagePack.read(bytes);
+    }
+
+    @Deprecated
+    public static <T> T unpack(byte[] bytes, Template<T> template) throws IOException {
+        BufferUnpacker u = new MessagePackBufferUnpacker(globalMessagePack).wrap(bytes);
+        return template.read(u, null);
+    }
+
+    @Deprecated
+    public static <T> T unpack(byte[] bytes, Template<T> template, T to) throws IOException {
+        BufferUnpacker u = new MessagePackBufferUnpacker(globalMessagePack).wrap(bytes);
+        return template.read(u, to);
+    }
+
+    /**
+     * Deserializes byte array to object of specified class.
+     * 
+     * @deprecated {@link MessagePack#read(byte[], Class)}
+     * @param bytes
+     * @param klass
+     * @return
+     * @throws IOException
+     */
+    @Deprecated
+    public static <T> T unpack(byte[] bytes, Class<T> klass) throws IOException {
+        return globalMessagePack.read(bytes, klass);
+    }
+
+    /**
+     * Deserializes byte array to object.
+     * 
+     * @param bytes
+     * @param to
+     * @return
+     * @throws IOException
+     */
+    @Deprecated
+    public static <T> T unpack(byte[] bytes, T to) throws IOException {
+        return globalMessagePack.read(bytes, to);
+    }
+
+    /**
+     * Converts input stream to {@link org.msgpack.type.Value} object.
+     * 
+     * @deprecated {@link MessagePack#read(InputStream)}
+     * @param in
+     * @return
+     * @throws IOException
+     */
+    @Deprecated
+    public static Value unpack(InputStream in) throws IOException {
+        return globalMessagePack.read(in);
+    }
+
+    /**
+     * @deprecated
+     * @param in
+     * @param tmpl
+     * @return
+     * @throws IOException
+     * @throws MessageTypeException
+     */
+    @Deprecated
+    public static <T> T unpack(InputStream in, Template<T> tmpl)
+            throws IOException, MessageTypeException {
+        return tmpl.read(new MessagePackUnpacker(globalMessagePack, in), null);
+    }
+
+    /**
+     * @deprecated
+     * @param in
+     * @param tmpl
+     * @param to
+     * @return
+     * @throws IOException
+     * @throws MessageTypeException
+     */
+    @Deprecated
+    public static <T> T unpack(InputStream in, Template<T> tmpl, T to)
+            throws IOException, MessageTypeException {
+        return (T) tmpl.read(new MessagePackUnpacker(globalMessagePack, in), to);
+    }
+
+    /**
+     * Deserializes input stream to object of specified class.
+     * 
+     * @deprecated {@link MessagePack#read(InputStream, Class)}
+     * @param in
+     * @param klass
+     * @return
+     * @throws IOException
+     */
+    @Deprecated
+    public static <T> T unpack(InputStream in, Class<T> klass)
+            throws IOException {
+        return globalMessagePack.read(in, klass);
+    }
+
+    /**
+     * Deserializes input stream to object.
+     * 
+     * @deprecated {@link MessagePack#read(InputStream, Object)}
+     * @param in
+     * @param to
+     * @return
+     * @throws IOException
+     */
+    @Deprecated
+    public static <T> T unpack(InputStream in, T to) throws IOException {
+        return globalMessagePack.read(in, to);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/MessagePackable.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,28 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+public interface MessagePackable {
+    public void writeTo(Packer pk) throws IOException;
+
+    public void readFrom(Unpacker u) throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/MessageTypeException.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,37 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack;
+
+@SuppressWarnings("serial")
+public class MessageTypeException extends RuntimeException {
+    public MessageTypeException() {
+        super();
+    }
+
+    public MessageTypeException(String message) {
+        super(message);
+    }
+
+    public MessageTypeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public MessageTypeException(Throwable cause) {
+        super(cause);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/Beans.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,31 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.msgpack.template.FieldOption;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Beans {
+    FieldOption value() default FieldOption.DEFAULT;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/Delegate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,29 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Delegate {
+    String value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/Ignore.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,28 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Ignore {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/Index.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,29 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Index {
+    int value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/Message.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,31 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.msgpack.template.FieldOption;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Message {
+    FieldOption value() default FieldOption.DEFAULT;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/MessagePackBeans.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,37 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.msgpack.template.FieldOption;
+
+/**
+ * Annotation for java beans class
+ * 
+ * @author takeshita
+ * 
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MessagePackBeans {
+    FieldOption value() default FieldOption.DEFAULT;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/MessagePackDelegate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,29 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MessagePackDelegate {
+    String value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/MessagePackMessage.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,31 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.msgpack.template.FieldOption;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MessagePackMessage {
+    FieldOption value() default FieldOption.DEFAULT;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/MessagePackOrdinalEnum.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,28 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MessagePackOrdinalEnum {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/NotNullable.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,29 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER,
+        ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NotNullable {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/Optional.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,28 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Optional {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/annotation/OrdinalEnum.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,45 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.msgpack.MessageTypeException;
+import org.msgpack.template.OrdinalEnumTemplate;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OrdinalEnum {
+
+	/**
+	 * Specify whether the ordinal index lookup should be handled strictly or
+	 * not when mapping ordinal value to an enum value. By specifying true,
+	 * {@link MessageTypeException} will be thrown if the enum specified by the
+	 * ordinal value does not exist in this implementation. If false, then the
+	 * missing ordinal value treated as null, gracefully handling the lookup.
+	 * Default is true.
+	 * 
+	 * @since 0.6.8
+	 * @see OrdinalEnumTemplate
+	 */
+	boolean strict() default true;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/AbstractInput.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,39 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2011 Muga Nishizawa
+//
+//    Licensed 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.msgpack.io;
+
+abstract class AbstractInput implements Input {
+
+    private int readByteCount = 0;
+
+    public int getReadByteCount() {
+        return readByteCount;
+    }
+
+    public void resetReadByteCount() {
+        readByteCount = 0;
+    }
+
+    protected final void incrReadByteCount(int size) {
+        readByteCount += size;
+    }
+
+    protected final void incrReadOneByteCount() {
+        readByteCount += 1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/BufferReferer.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,25 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public interface BufferReferer {
+    public void refer(ByteBuffer bb, boolean gift) throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/BufferedOutput.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,219 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+abstract class BufferedOutput implements Output {
+    protected byte[] buffer;
+    protected int filled;
+    protected final int bufferSize;
+    protected ByteBuffer castByteBuffer;
+
+    public BufferedOutput(int bufferSize) {
+        if (bufferSize < 9) {
+            bufferSize = 9;
+        }
+        this.bufferSize = bufferSize;
+    }
+
+    private void allocateNewBuffer() {
+        buffer = new byte[bufferSize];
+        castByteBuffer = ByteBuffer.wrap(buffer);
+    }
+
+    private void reserve(int len) throws IOException {
+        if (buffer == null) {
+            allocateNewBuffer();
+            return;
+        }
+        if (bufferSize - filled < len) {
+            if (!flushBuffer(buffer, 0, filled)) {
+                buffer = new byte[bufferSize];
+                castByteBuffer = ByteBuffer.wrap(buffer);
+            }
+            filled = 0;
+        }
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        if (buffer == null) {
+            if (bufferSize < len) {
+                flushBuffer(b, off, len);
+                return;
+            }
+            allocateNewBuffer();
+        }
+        if (len <= bufferSize - filled) {
+            System.arraycopy(b, off, buffer, filled, len);
+            filled += len;
+        } else if (len <= bufferSize) {
+            if (!flushBuffer(buffer, 0, filled)) {
+                allocateNewBuffer();
+            }
+            filled = 0;
+            System.arraycopy(b, off, buffer, 0, len);
+            filled = len;
+        } else {
+            flush();
+            flushBuffer(b, off, len);
+        }
+    }
+
+    @Override
+    public void write(ByteBuffer bb) throws IOException {
+        int len = bb.remaining();
+        if (buffer == null) {
+            if (bufferSize < len) {
+                flushByteBuffer(bb);
+                return;
+            }
+            allocateNewBuffer();
+        }
+        if (len <= bufferSize - filled) {
+            bb.get(buffer, filled, len);
+            filled += len;
+        } else if (len <= bufferSize) {
+            if (!flushBuffer(buffer, 0, filled)) {
+                allocateNewBuffer();
+            }
+            filled = 0;
+            bb.get(buffer, 0, len);
+            filled = len;
+        } else {
+            flush();
+            flushByteBuffer(bb);
+        }
+    }
+
+    @Override
+    public void writeByte(byte v) throws IOException {
+        reserve(1);
+        buffer[filled++] = v;
+    }
+
+    @Override
+    public void writeShort(short v) throws IOException {
+        reserve(2);
+        castByteBuffer.putShort(filled, v);
+        filled += 2;
+    }
+
+    @Override
+    public void writeInt(int v) throws IOException {
+        reserve(4);
+        castByteBuffer.putInt(filled, v);
+        filled += 4;
+    }
+
+    @Override
+    public void writeLong(long v) throws IOException {
+        reserve(8);
+        castByteBuffer.putLong(filled, v);
+        filled += 8;
+    }
+
+    @Override
+    public void writeFloat(float v) throws IOException {
+        reserve(4);
+        castByteBuffer.putFloat(filled, v);
+        filled += 4;
+    }
+
+    @Override
+    public void writeDouble(double v) throws IOException {
+        reserve(8);
+        castByteBuffer.putDouble(filled, v);
+        filled += 8;
+    }
+
+    @Override
+    public void writeByteAndByte(byte b, byte v) throws IOException {
+        reserve(2);
+        buffer[filled++] = b;
+        buffer[filled++] = v;
+    }
+
+    @Override
+    public void writeByteAndShort(byte b, short v) throws IOException {
+        reserve(3);
+        buffer[filled++] = b;
+        castByteBuffer.putShort(filled, v);
+        filled += 2;
+    }
+
+    @Override
+    public void writeByteAndInt(byte b, int v) throws IOException {
+        reserve(5);
+        buffer[filled++] = b;
+        castByteBuffer.putInt(filled, v);
+        filled += 4;
+    }
+
+    @Override
+    public void writeByteAndLong(byte b, long v) throws IOException {
+        reserve(9);
+        buffer[filled++] = b;
+        castByteBuffer.putLong(filled, v);
+        filled += 8;
+    }
+
+    @Override
+    public void writeByteAndFloat(byte b, float v) throws IOException {
+        reserve(5);
+        buffer[filled++] = b;
+        castByteBuffer.putFloat(filled, v);
+        filled += 4;
+    }
+
+    @Override
+    public void writeByteAndDouble(byte b, double v) throws IOException {
+        reserve(9);
+        buffer[filled++] = b;
+        castByteBuffer.putDouble(filled, v);
+        filled += 8;
+    }
+
+    @Override
+    public void flush() throws IOException {
+        if (filled > 0) {
+            if (!flushBuffer(buffer, 0, filled)) {
+                buffer = null;
+            }
+            filled = 0;
+        }
+    }
+
+    protected void flushByteBuffer(ByteBuffer bb) throws IOException {
+        if (bb.hasArray()) {
+            byte[] array = bb.array();
+            int offset = bb.arrayOffset();
+            flushBuffer(array, offset + bb.position(), bb.remaining());
+            bb.position(bb.limit());
+        } else {
+            byte[] buf = new byte[bb.remaining()];
+            bb.get(buf);
+            flushBuffer(buf, 0, buf.length);
+        }
+    }
+
+    protected abstract boolean flushBuffer(byte[] buffer, int off, int len)
+            throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/ByteBufferOutput.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,148 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.BufferOverflowException;
+
+public class ByteBufferOutput implements Output {
+    public static interface ExpandBufferCallback {
+        ByteBuffer call(ByteBuffer buffer, int len) throws IOException;
+    }
+
+    private ByteBuffer buffer;
+    private ExpandBufferCallback callback;
+
+    public ByteBufferOutput(ByteBuffer buffer) {
+        this(buffer, null);
+    }
+
+    public ByteBufferOutput(ByteBuffer buffer, ExpandBufferCallback callback) {
+        this.buffer = buffer;
+        this.callback = callback;
+    }
+
+    private void reserve(int len) throws IOException {
+        if (len <= buffer.remaining()) {
+            return;
+        }
+        if (callback == null) {
+            throw new BufferOverflowException();
+        }
+        buffer = callback.call(buffer, len);
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        reserve(len);
+        buffer.put(b, off, len);
+    }
+
+    @Override
+    public void write(ByteBuffer bb) throws IOException {
+        reserve(bb.remaining());
+        buffer.put(bb);
+    }
+
+    @Override
+    public void writeByte(byte v) throws IOException {
+        reserve(1);
+        buffer.put(v);
+    }
+
+    @Override
+    public void writeShort(short v) throws IOException {
+        reserve(2);
+        buffer.putShort(v);
+    }
+
+    @Override
+    public void writeInt(int v) throws IOException {
+        reserve(4);
+        buffer.putInt(v);
+    }
+
+    @Override
+    public void writeLong(long v) throws IOException {
+        reserve(8);
+        buffer.putLong(v);
+    }
+
+    @Override
+    public void writeFloat(float v) throws IOException {
+        reserve(4);
+        buffer.putFloat(v);
+    }
+
+    @Override
+    public void writeDouble(double v) throws IOException {
+        reserve(8);
+        buffer.putDouble(v);
+    }
+
+    @Override
+    public void writeByteAndByte(byte b, byte v) throws IOException {
+        reserve(2);
+        buffer.put(b);
+        buffer.put(v);
+    }
+
+    @Override
+    public void writeByteAndShort(byte b, short v) throws IOException {
+        reserve(3);
+        buffer.put(b);
+        buffer.putShort(v);
+    }
+
+    @Override
+    public void writeByteAndInt(byte b, int v) throws IOException {
+        reserve(5);
+        buffer.put(b);
+        buffer.putInt(v);
+    }
+
+    @Override
+    public void writeByteAndLong(byte b, long v) throws IOException {
+        reserve(9);
+        buffer.put(b);
+        buffer.putLong(v);
+    }
+
+    @Override
+    public void writeByteAndFloat(byte b, float v) throws IOException {
+        reserve(5);
+        buffer.put(b);
+        buffer.putFloat(v);
+    }
+
+    @Override
+    public void writeByteAndDouble(byte b, double v) throws IOException {
+        reserve(9);
+        buffer.put(b);
+        buffer.putDouble(v);
+    }
+
+    @Override
+    public void flush() throws IOException {
+    }
+
+    @Override
+    public void close() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/EndOfBufferException.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,31 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.EOFException;
+
+@SuppressWarnings("serial")
+public class EndOfBufferException extends EOFException {
+    public EndOfBufferException() {
+        super();
+    }
+
+    public EndOfBufferException(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/Input.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,47 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.IOException;
+import java.io.Closeable;
+
+public interface Input extends Closeable {
+    public int read(byte[] b, int off, int len) throws IOException;
+
+    public boolean tryRefer(BufferReferer ref, int len) throws IOException;
+
+    public byte readByte() throws IOException;
+
+    public void advance();
+
+    public byte getByte() throws IOException;
+
+    public short getShort() throws IOException;
+
+    public int getInt() throws IOException;
+
+    public long getLong() throws IOException;
+
+    public float getFloat() throws IOException;
+
+    public double getDouble() throws IOException;
+
+    public int getReadByteCount();
+
+    public void resetReadByteCount();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/LinkedBufferInput.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,399 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.util.LinkedList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.nio.ByteBuffer;
+
+public class LinkedBufferInput extends AbstractInput {
+    LinkedList<ByteBuffer> link;
+
+    int writable;
+
+    private int nextAdvance;
+
+    private byte[] tmpBuffer;
+
+    private ByteBuffer tmpByteBuffer;
+
+    private final int bufferSize;
+
+    public LinkedBufferInput(int bufferSize) {
+        this.link = new LinkedList<ByteBuffer>();
+        this.writable = -1;
+        this.tmpBuffer = new byte[8];
+        this.tmpByteBuffer = ByteBuffer.wrap(tmpBuffer);
+        this.bufferSize = bufferSize;
+    }
+
+    public int read(byte[] b, int off, int len) throws EOFException {
+        if (link.isEmpty()) {
+            return 0;
+        }
+        int olen = len;
+        while (true) {
+            ByteBuffer bb = link.getFirst();
+            if (len < bb.remaining()) {
+                bb.get(b, off, len);
+                incrReadByteCount(len);
+                return olen;
+            }
+            int rem = bb.remaining();
+            bb.get(b, off, rem);
+            incrReadByteCount(rem);
+            len -= rem;
+            off += rem;
+            if (!removeFirstLink(bb)) {
+                break;
+            }
+        }
+        return olen - len;
+    }
+
+    public boolean tryRefer(BufferReferer ref, int len) throws IOException {
+        ByteBuffer bb = null;
+        try {
+            bb = link.getFirst();
+        } catch(NoSuchElementException e) {}
+        if (bb == null) {
+            throw new EndOfBufferException();
+        } else if (bb.remaining() < len) {
+            return false;
+        }
+        boolean success = false;
+        int pos = bb.position();
+        int lim = bb.limit();
+        try {
+            bb.limit(pos + len);
+            ref.refer(bb, true);
+            incrReadByteCount(len);
+            success = true;
+        } finally {
+            bb.limit(lim);
+            if (success) {
+                bb.position(pos + len);
+            } else {
+                bb.position(pos);
+            }
+            if (bb.remaining() == 0) {
+                removeFirstLink(bb);
+            }
+        }
+        return true;
+    }
+
+    public byte readByte() throws EOFException {
+        ByteBuffer bb = null;
+        try {
+            bb = link.getFirst();
+        } catch(NoSuchElementException e) {}
+        if (bb == null || bb.remaining() == 0) {
+            throw new EndOfBufferException();
+        }
+        byte result = bb.get();
+        incrReadOneByteCount();
+        if (bb.remaining() == 0) {
+            removeFirstLink(bb);
+        }
+        return result;
+    }
+
+    public void advance() {
+        if (link.isEmpty()) {
+            return;
+        }
+        int len = nextAdvance;
+        ByteBuffer bb;
+        while (true) {
+            bb = link.getFirst();
+            if (len < bb.remaining()) {
+                bb.position(bb.position() + len);
+                break;
+            }
+            len -= bb.remaining();
+            bb.position(bb.position() + bb.remaining());
+            if (!removeFirstLink(bb)) {
+                break;
+            }
+        }
+        incrReadByteCount(nextAdvance);
+        nextAdvance = 0;
+    }
+
+    private boolean removeFirstLink(ByteBuffer first) {
+        if (link.size() == 1) {
+            if (writable >= 0) {
+                first.position(0);
+                first.limit(0);
+                writable = first.capacity();
+                return false;
+            } else {
+                link.removeFirst();
+                return false;
+            }
+        } else {
+            link.removeFirst();
+            return true;
+        }
+    }
+
+    private void requireMore(int n) throws EOFException {
+        int off = 0;
+        for (ByteBuffer bb : link) {
+            if (n <= bb.remaining()) {
+                int pos = bb.position();
+                bb.get(tmpBuffer, off, n);
+                bb.position(pos);
+                return;
+            }
+            int rem = bb.remaining();
+            int pos = bb.position();
+            bb.get(tmpBuffer, off, rem);
+            bb.position(pos);
+            n -= rem;
+            off += rem;
+        }
+        throw new EndOfBufferException();
+    }
+
+    private ByteBuffer require(int n) throws EOFException {
+        ByteBuffer bb = null;
+        try {
+            bb = link.getFirst();
+        } catch(NoSuchElementException e) {}
+        if (bb == null) {
+            throw new EndOfBufferException();
+        }
+        if (n <= bb.remaining()) {
+            nextAdvance = n;
+            return bb;
+        } else {
+            requireMore(n);
+            nextAdvance = n;
+            return tmpByteBuffer;
+        }
+    }
+
+    public byte getByte() throws EOFException {
+        ByteBuffer bb = require(1);
+        return bb.get(bb.position());
+    }
+
+    public short getShort() throws EOFException {
+        ByteBuffer bb = require(2);
+        return bb.getShort(bb.position());
+    }
+
+    public int getInt() throws EOFException {
+        ByteBuffer bb = require(4);
+        return bb.getInt(bb.position());
+    }
+
+    public long getLong() throws EOFException {
+        ByteBuffer bb = require(8);
+        return bb.getLong(bb.position());
+    }
+
+    public float getFloat() throws EOFException {
+        ByteBuffer bb = require(4);
+        return bb.getFloat(bb.position());
+    }
+
+    public double getDouble() throws EOFException {
+        ByteBuffer bb = require(8);
+        return bb.getDouble(bb.position());
+    }
+
+    public void feed(byte[] b) {
+        feed(b, 0, b.length, false);
+    }
+
+    public void feed(byte[] b, boolean reference) {
+        feed(b, 0, b.length, reference);
+    }
+
+    public void feed(byte[] b, int off, int len) {
+        feed(b, off, len, false);
+    }
+
+    public void feed(byte[] b, int off, int len, boolean reference) {
+        if (reference) {
+            if (writable > 0 && link.getLast().remaining() == 0) {
+                link.add(link.size()-1, ByteBuffer.wrap(b, off, len));
+                return;
+            }
+            link.addLast(ByteBuffer.wrap(b, off, len));
+            writable = -1;
+            return;
+        }
+
+        ByteBuffer bb = null;
+        try {
+            bb = link.getLast();
+        } catch(NoSuchElementException e) {}
+        if (len <= writable) {
+            int pos = bb.position();
+            bb.position(bb.limit());
+            bb.limit(bb.limit() + len);
+            bb.put(b, off, len);
+            bb.position(pos);
+            writable = bb.capacity() - bb.limit();
+            return;
+        }
+
+        if (writable > 0) {
+            int pos = bb.position();
+            bb.position(bb.limit());
+            bb.limit(bb.limit() + writable);
+            bb.put(b, off, writable);
+            bb.position(pos);
+            off += writable;
+            len -= writable;
+            writable = 0;
+        }
+
+        int sz = Math.max(len, bufferSize);
+        ByteBuffer nb = ByteBuffer.allocate(sz);
+        nb.put(b, off, len);
+        nb.limit(len);
+        nb.position(0);
+        link.addLast(nb);
+        writable = sz - len;
+    }
+
+    public void feed(ByteBuffer b) {
+        feed(b, false);
+    }
+
+    public void feed(ByteBuffer buf, boolean reference) {
+        if (reference) {
+            if (writable > 0 && link.getLast().remaining() == 0) {
+                link.add(link.size()-1, buf);
+                return;
+            }
+            link.addLast(buf);
+            writable = -1;
+            return;
+        }
+
+        int rem = buf.remaining();
+
+        ByteBuffer bb = null;
+        try {
+            bb = link.getLast();
+        } catch(NoSuchElementException e) {}
+        if (rem <= writable) {
+            int pos = bb.position();
+            bb.position(bb.limit());
+            bb.limit(bb.limit() + rem);
+            bb.put(buf);
+            bb.position(pos);
+            writable = bb.capacity() - bb.limit();
+            return;
+        }
+
+        if (writable > 0) {
+            int pos = bb.position();
+            bb.position(bb.limit());
+            bb.limit(bb.limit() + writable);
+            buf.limit(writable);
+            bb.put(buf);
+            bb.position(pos);
+            rem -= writable;
+            buf.limit(buf.limit() + rem);
+            writable = 0;
+        }
+
+        int sz = Math.max(rem, bufferSize);
+        ByteBuffer nb = ByteBuffer.allocate(sz);
+        nb.put(buf);
+        nb.limit(rem);
+        nb.position(0);
+        link.addLast(nb);
+        writable = sz - rem;
+    }
+
+    public void clear() {
+        if (writable >= 0) {
+            ByteBuffer bb = link.getLast();
+            link.clear();
+            bb.position(0);
+            bb.limit(0);
+            link.addLast(bb);
+            writable = bb.capacity();
+        } else {
+            link.clear();
+            writable = -1;
+        }
+    }
+
+    public void copyReferencedBuffer() {
+        if (link.isEmpty()) {
+            return;
+        }
+
+        int size = 0;
+        for(ByteBuffer bb : link) {
+            size += bb.remaining();
+        }
+        if (size == 0) {
+            return;
+        }
+
+        if (writable >= 0) {
+            ByteBuffer last = link.removeLast();
+            byte[] copy = new byte[size - last.remaining()];
+            int off = 0;
+            for(ByteBuffer bb : link) {
+                int len = bb.remaining();
+                bb.get(copy, off, len);
+                off += len;
+            }
+            link.clear();
+            link.add(ByteBuffer.wrap(copy));
+            link.add(last);
+
+        } else {
+            byte[] copy = new byte[size];
+            int off = 0;
+            for(ByteBuffer bb : link) {
+                int len = bb.remaining();
+                bb.get(copy, off, len);
+                off += len;
+            }
+            link.clear();
+            link.add(ByteBuffer.wrap(copy));
+            writable = 0;
+        }
+    }
+
+    public int getSize() {
+        int size = 0;
+        for(ByteBuffer bb : link) {
+            size += bb.remaining();
+        }
+        return size;
+    }
+
+    public void close() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/LinkedBufferOutput.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,76 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.util.LinkedList;
+
+public final class LinkedBufferOutput extends BufferedOutput {
+    private static final class Link {
+        final byte[] buffer;
+        final int offset;
+        final int size;
+
+        Link(byte[] buffer, int offset, int size) {
+            this.buffer = buffer;
+            this.offset = offset;
+            this.size = size;
+        }
+    }
+
+    private LinkedList<Link> link;
+    private int size;
+
+    public LinkedBufferOutput(int bufferSize) {
+        super(bufferSize);
+        link = new LinkedList<Link>();
+    }
+
+    public byte[] toByteArray() {
+        byte[] bytes = new byte[size + filled];
+        int off = 0;
+        for (Link l : link) {
+            System.arraycopy(l.buffer, l.offset, bytes, off, l.size);
+            off += l.size;
+        }
+        if (filled > 0) {
+            System.arraycopy(buffer, 0, bytes, off, filled);
+        }
+        return bytes;
+    }
+
+    public int getSize() {
+        return size + filled;
+    }
+
+    @Override
+    protected boolean flushBuffer(byte[] b, int off, int len) {
+        link.add(new Link(b, off, len));
+        size += len;
+        return false;
+    }
+
+    public void clear() {
+        link.clear();
+        size = 0;
+        filled = 0;
+    }
+
+    @Override
+    public void close() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/Output.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,53 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.IOException;
+import java.io.Closeable;
+import java.io.Flushable;
+import java.nio.ByteBuffer;
+
+public interface Output extends Closeable, Flushable {
+    public void write(byte[] b, int off, int len) throws IOException;
+
+    public void write(ByteBuffer bb) throws IOException;
+
+    public void writeByte(byte v) throws IOException;
+
+    public void writeShort(short v) throws IOException;
+
+    public void writeInt(int v) throws IOException;
+
+    public void writeLong(long v) throws IOException;
+
+    public void writeFloat(float v) throws IOException;
+
+    public void writeDouble(double v) throws IOException;
+
+    public void writeByteAndByte(byte b, byte v) throws IOException;
+
+    public void writeByteAndShort(byte b, short v) throws IOException;
+
+    public void writeByteAndInt(byte b, int v) throws IOException;
+
+    public void writeByteAndLong(byte b, long v) throws IOException;
+
+    public void writeByteAndFloat(byte b, float v) throws IOException;
+
+    public void writeByteAndDouble(byte b, double v) throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/StreamInput.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,114 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.io.IOException;
+import java.io.EOFException;
+
+public class StreamInput extends AbstractInput {
+    private final InputStream in;
+
+    private byte[] castBuffer;
+    private ByteBuffer castByteBuffer;
+    private int filled;
+
+    public StreamInput(InputStream in) {
+        this.in = in;
+        this.castBuffer = new byte[8];
+        this.castByteBuffer = ByteBuffer.wrap(castBuffer);
+        this.filled = 0;
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+        int remain = len;
+        while (remain > 0) {
+            int n = in.read(b, off, remain);
+            if (n <= 0) {
+                throw new EOFException();
+            }
+            incrReadByteCount(n);
+            remain -= n;
+            off += n;
+        }
+        return len;
+    }
+
+    public boolean tryRefer(BufferReferer ref, int size) throws IOException {
+        return false;
+    }
+
+    public byte readByte() throws IOException {
+        int n = in.read();
+        if (n < 0) {
+            throw new EOFException();
+        }
+        incrReadOneByteCount();
+        return (byte) n;
+    }
+
+    public void advance() {
+        incrReadByteCount(filled);
+        filled = 0;
+    }
+
+    private void require(int len) throws IOException {
+        while (filled < len) {
+            int n = in.read(castBuffer, filled, len - filled);
+            if (n < 0) {
+                throw new EOFException();
+            }
+            filled += n;
+        }
+    }
+
+    public byte getByte() throws IOException {
+        require(1);
+        return castBuffer[0];
+    }
+
+    public short getShort() throws IOException {
+        require(2);
+        return castByteBuffer.getShort(0);
+    }
+
+    public int getInt() throws IOException {
+        require(4);
+        return castByteBuffer.getInt(0);
+    }
+
+    public long getLong() throws IOException {
+        require(8);
+        return castByteBuffer.getLong(0);
+    }
+
+    public float getFloat() throws IOException {
+        require(4);
+        return castByteBuffer.getFloat(0);
+    }
+
+    public double getDouble() throws IOException {
+        require(8);
+        return castByteBuffer.getDouble(0);
+    }
+
+    public void close() throws IOException {
+        in.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/io/StreamOutput.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,126 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.DataOutputStream;
+import java.nio.ByteBuffer;
+
+public class StreamOutput implements Output {
+    private DataOutputStream out;
+
+    public StreamOutput(OutputStream out) {
+        this.out = new DataOutputStream(out);
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        out.write(b, off, len);
+    }
+
+    @Override
+    public void write(ByteBuffer bb) throws IOException {
+        if (bb.hasArray()) {
+            byte[] array = bb.array();
+            int offset = bb.arrayOffset();
+            out.write(array, offset, bb.remaining());
+            bb.position(bb.limit());
+        } else {
+            // int pos = bb.position();
+            byte[] buf = new byte[bb.remaining()];
+            bb.get(buf);
+            out.write(buf);
+        }
+    }
+
+    @Override
+    public void writeByte(byte v) throws IOException {
+        out.write(v);
+    }
+
+    @Override
+    public void writeShort(short v) throws IOException {
+        out.writeShort(v);
+    }
+
+    @Override
+    public void writeInt(int v) throws IOException {
+        out.writeInt(v);
+    }
+
+    @Override
+    public void writeLong(long v) throws IOException {
+        out.writeLong(v);
+    }
+
+    @Override
+    public void writeFloat(float v) throws IOException {
+        out.writeFloat(v);
+    }
+
+    @Override
+    public void writeDouble(double v) throws IOException {
+        out.writeDouble(v);
+    }
+
+    @Override
+    public void writeByteAndByte(byte b, byte v) throws IOException {
+        out.write(b);
+        out.write(v);
+    }
+
+    @Override
+    public void writeByteAndShort(byte b, short v) throws IOException {
+        out.write(b);
+        out.writeShort(v);
+    }
+
+    @Override
+    public void writeByteAndInt(byte b, int v) throws IOException {
+        out.write(b);
+        out.writeInt(v);
+    }
+
+    @Override
+    public void writeByteAndLong(byte b, long v) throws IOException {
+        out.write(b);
+        out.writeLong(v);
+    }
+
+    @Override
+    public void writeByteAndFloat(byte b, float v) throws IOException {
+        out.write(b);
+        out.writeFloat(v);
+    }
+
+    @Override
+    public void writeByteAndDouble(byte b, double v) throws IOException {
+        out.write(b);
+        out.writeDouble(v);
+    }
+
+    @Override
+    public void flush() throws IOException {
+    }
+
+    @Override
+    public void close() throws IOException {
+        out.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/packer/AbstractPacker.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,259 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.packer;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.io.IOException;
+import org.msgpack.type.Value;
+import org.msgpack.MessagePack;
+import org.msgpack.template.Template;
+
+public abstract class AbstractPacker implements Packer {
+    protected MessagePack msgpack;
+
+    protected AbstractPacker(MessagePack msgpack) {
+        this.msgpack = msgpack;
+    }
+
+    @Override
+    public Packer write(boolean o) throws IOException {
+        writeBoolean(o);
+        return this;
+    }
+
+    @Override
+    public Packer write(byte o) throws IOException {
+        writeByte(o);
+        return this;
+    }
+
+    @Override
+    public Packer write(short o) throws IOException {
+        writeShort(o);
+        return this;
+    }
+
+    @Override
+    public Packer write(int o) throws IOException {
+        writeInt(o);
+        return this;
+    }
+
+    @Override
+    public Packer write(long o) throws IOException {
+        writeLong(o);
+        return this;
+    }
+
+    @Override
+    public Packer write(float o) throws IOException {
+        writeFloat(o);
+        return this;
+    }
+
+    @Override
+    public Packer write(double o) throws IOException {
+        writeDouble(o);
+        return this;
+    }
+
+    @Override
+    public Packer write(Boolean o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeBoolean(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(Byte o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeByte(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(Short o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeShort(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(Integer o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeInt(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(Long o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeLong(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(BigInteger o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeBigInteger(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(Float o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeFloat(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(Double o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeDouble(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(byte[] o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeByteArray(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(byte[] o, int off, int len) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeByteArray(o, off, len);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(ByteBuffer o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeByteBuffer(o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(String o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            writeString(o);
+        }
+        return this;
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Override
+    public Packer write(Object o) throws IOException {
+        if (o == null) {
+            writeNil();
+        } else {
+            Template tmpl = msgpack.lookup(o.getClass());
+            tmpl.write(this, o);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(Value v) throws IOException {
+        if (v == null) {
+            writeNil();
+        } else {
+            v.writeTo(this);
+        }
+        return this;
+    }
+
+    @Override
+    public Packer writeArrayEnd() throws IOException {
+        writeArrayEnd(true);
+        return this;
+    }
+
+    @Override
+    public Packer writeMapEnd() throws IOException {
+        writeMapEnd(true);
+        return this;
+    }
+
+    @Override
+    public void close() throws IOException {
+    }
+
+    abstract protected void writeBoolean(boolean v) throws IOException;
+
+    abstract protected void writeByte(byte v) throws IOException;
+
+    abstract protected void writeShort(short v) throws IOException;
+
+    abstract protected void writeInt(int v) throws IOException;
+
+    abstract protected void writeLong(long v) throws IOException;
+
+    abstract protected void writeBigInteger(BigInteger v) throws IOException;
+
+    abstract protected void writeFloat(float v) throws IOException;
+
+    abstract protected void writeDouble(double v) throws IOException;
+
+    protected void writeByteArray(byte[] b) throws IOException {
+        writeByteArray(b, 0, b.length);
+    }
+
+    abstract protected void writeByteArray(byte[] b, int off, int len) throws IOException;
+
+    abstract protected void writeByteBuffer(ByteBuffer bb) throws IOException;
+
+    abstract protected void writeString(String s) throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/packer/BufferPacker.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,32 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.packer;
+
+/**
+ * This class is buffer-specific serializer.
+ * 
+ * @version 0.6.0
+ * @see {@link org.msgpack.packer.Packer}
+ */
+public interface BufferPacker extends Packer {
+    public int getBufferSize();
+
+    public byte[] toByteArray();
+
+    public void clear();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/packer/MessagePackBufferPacker.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,46 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.packer;
+
+import org.msgpack.MessagePack;
+import org.msgpack.io.LinkedBufferOutput;
+
+public class MessagePackBufferPacker extends MessagePackPacker implements BufferPacker {
+    private static final int DEFAULT_BUFFER_SIZE = 512;
+
+    public MessagePackBufferPacker(MessagePack msgpack) {
+        this(msgpack, DEFAULT_BUFFER_SIZE);
+    }
+
+    public MessagePackBufferPacker(MessagePack msgpack, int bufferSize) {
+        super(msgpack, new LinkedBufferOutput(bufferSize));
+    }
+
+    public int getBufferSize() {
+        return ((LinkedBufferOutput) out).getSize();
+    }
+
+    public byte[] toByteArray() {
+        return ((LinkedBufferOutput) out).toByteArray();
+    }
+
+    public void clear() {
+        reset();
+        ((LinkedBufferOutput) out).clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/packer/MessagePackPacker.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,334 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.packer;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.math.BigInteger;
+import org.msgpack.io.Output;
+import org.msgpack.io.StreamOutput;
+import org.msgpack.MessagePack;
+import org.msgpack.MessageTypeException;
+
+public class MessagePackPacker extends AbstractPacker {
+    protected final Output out;
+
+    private PackerStack stack = new PackerStack();
+
+    public MessagePackPacker(MessagePack msgpack, OutputStream stream) {
+        this(msgpack, new StreamOutput(stream));
+    }
+
+    protected MessagePackPacker(MessagePack msgpack, Output out) {
+        super(msgpack);
+        this.out = out;
+    }
+
+    @Override
+    protected void writeByte(byte d) throws IOException {
+        if (d < -(1 << 5)) {
+            out.writeByteAndByte((byte) 0xd0, d);
+        } else {
+            out.writeByte(d);
+        }
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeShort(short d) throws IOException {
+        if (d < -(1 << 5)) {
+            if (d < -(1 << 7)) {
+                // signed 16
+                out.writeByteAndShort((byte) 0xd1, d);
+            } else {
+                // signed 8
+                out.writeByteAndByte((byte) 0xd0, (byte) d);
+            }
+        } else if (d < (1 << 7)) {
+            // fixnum
+            out.writeByte((byte) d);
+        } else {
+            if (d < (1 << 8)) {
+                // unsigned 8
+                out.writeByteAndByte((byte) 0xcc, (byte) d);
+            } else {
+                // unsigned 16
+                out.writeByteAndShort((byte) 0xcd, d);
+            }
+        }
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeInt(int d) throws IOException {
+        if (d < -(1 << 5)) {
+            if (d < -(1 << 15)) {
+                // signed 32
+                out.writeByteAndInt((byte) 0xd2, d);
+            } else if (d < -(1 << 7)) {
+                // signed 16
+                out.writeByteAndShort((byte) 0xd1, (short) d);
+            } else {
+                // signed 8
+                out.writeByteAndByte((byte) 0xd0, (byte) d);
+            }
+        } else if (d < (1 << 7)) {
+            // fixnum
+            out.writeByte((byte) d);
+        } else {
+            if (d < (1 << 8)) {
+                // unsigned 8
+                out.writeByteAndByte((byte) 0xcc, (byte) d);
+            } else if (d < (1 << 16)) {
+                // unsigned 16
+                out.writeByteAndShort((byte) 0xcd, (short) d);
+            } else {
+                // unsigned 32
+                out.writeByteAndInt((byte) 0xce, d);
+            }
+        }
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeLong(long d) throws IOException {
+        if (d < -(1L << 5)) {
+            if (d < -(1L << 15)) {
+                if (d < -(1L << 31)) {
+                    // signed 64
+                    out.writeByteAndLong((byte) 0xd3, d);
+                } else {
+                    // signed 32
+                    out.writeByteAndInt((byte) 0xd2, (int) d);
+                }
+            } else {
+                if (d < -(1 << 7)) {
+                    // signed 16
+                    out.writeByteAndShort((byte) 0xd1, (short) d);
+                } else {
+                    // signed 8
+                    out.writeByteAndByte((byte) 0xd0, (byte) d);
+                }
+            }
+        } else if (d < (1 << 7)) {
+            // fixnum
+            out.writeByte((byte) d);
+        } else {
+            if (d < (1L << 16)) {
+                if (d < (1 << 8)) {
+                    // unsigned 8
+                    out.writeByteAndByte((byte) 0xcc, (byte) d);
+                } else {
+                    // unsigned 16
+                    out.writeByteAndShort((byte) 0xcd, (short) d);
+                }
+            } else {
+                if (d < (1L << 32)) {
+                    // unsigned 32
+                    out.writeByteAndInt((byte) 0xce, (int) d);
+                } else {
+                    // unsigned 64
+                    out.writeByteAndLong((byte) 0xcf, d);
+                }
+            }
+        }
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeBigInteger(BigInteger d) throws IOException {
+        if (d.bitLength() <= 63) {
+            writeLong(d.longValue());
+            stack.reduceCount();
+        } else if (d.bitLength() == 64 && d.signum() == 1) {
+            // unsigned 64
+            out.writeByteAndLong((byte) 0xcf, d.longValue());
+            stack.reduceCount();
+        } else {
+            throw new MessageTypeException(
+                    "MessagePack can't serialize BigInteger larger than (2^64)-1");
+        }
+    }
+
+    @Override
+    protected void writeFloat(float d) throws IOException {
+        out.writeByteAndFloat((byte) 0xca, d);
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeDouble(double d) throws IOException {
+        out.writeByteAndDouble((byte) 0xcb, d);
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeBoolean(boolean d) throws IOException {
+        if (d) {
+            // true
+            out.writeByte((byte) 0xc3);
+        } else {
+            // false
+            out.writeByte((byte) 0xc2);
+        }
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeByteArray(byte[] b, int off, int len)
+            throws IOException {
+        if (len < 32) {
+            out.writeByte((byte) (0xa0 | len));
+        } else if (len < 65536) {
+            out.writeByteAndShort((byte) 0xda, (short) len);
+        } else {
+            out.writeByteAndInt((byte) 0xdb, len);
+        }
+        out.write(b, off, len);
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeByteBuffer(ByteBuffer bb) throws IOException {
+        int len = bb.remaining();
+        if (len < 32) {
+            out.writeByte((byte) (0xa0 | len));
+        } else if (len < 65536) {
+            out.writeByteAndShort((byte) 0xda, (short) len);
+        } else {
+            out.writeByteAndInt((byte) 0xdb, len);
+        }
+        int pos = bb.position();
+        try {
+            out.write(bb);
+        } finally {
+            bb.position(pos);
+        }
+        stack.reduceCount();
+    }
+
+    @Override
+    protected void writeString(String s) throws IOException {
+        byte[] b;
+        try {
+            // TODO encoding error?
+            b = s.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new MessageTypeException(ex);
+        }
+        writeByteArray(b, 0, b.length);
+        stack.reduceCount();
+    }
+
+    @Override
+    public Packer writeNil() throws IOException {
+        out.writeByte((byte) 0xc0);
+        stack.reduceCount();
+        return this;
+    }
+
+    @Override
+    public Packer writeArrayBegin(int size) throws IOException {
+        // TODO check size < 0?
+        if (size < 16) {
+            // FixArray
+            out.writeByte((byte) (0x90 | size));
+        } else if (size < 65536) {
+            out.writeByteAndShort((byte) 0xdc, (short) size);
+        } else {
+            out.writeByteAndInt((byte) 0xdd, size);
+        }
+        stack.reduceCount();
+        stack.pushArray(size);
+        return this;
+    }
+
+    @Override
+    public Packer writeArrayEnd(boolean check) throws IOException {
+        if (!stack.topIsArray()) {
+            throw new MessageTypeException(
+                    "writeArrayEnd() is called but writeArrayBegin() is not called");
+        }
+
+        int remain = stack.getTopCount();
+        if (remain > 0) {
+            if (check) {
+                throw new MessageTypeException(
+                        "writeArrayEnd(check=true) is called but the array is not end: " + remain);
+            }
+            for (int i = 0; i < remain; i++) {
+                writeNil();
+            }
+        }
+        stack.pop();
+        return this;
+    }
+
+    @Override
+    public Packer writeMapBegin(int size) throws IOException {
+        // TODO check size < 0?
+        if (size < 16) {
+            // FixMap
+            out.writeByte((byte) (0x80 | size));
+        } else if (size < 65536) {
+            out.writeByteAndShort((byte) 0xde, (short) size);
+        } else {
+            out.writeByteAndInt((byte) 0xdf, size);
+        }
+        stack.reduceCount();
+        stack.pushMap(size);
+        return this;
+    }
+
+    @Override
+    public Packer writeMapEnd(boolean check) throws IOException {
+        if (!stack.topIsMap()) {
+            throw new MessageTypeException(
+                    "writeMapEnd() is called but writeMapBegin() is not called");
+        }
+
+        int remain = stack.getTopCount();
+        if (remain > 0) {
+            if (check) {
+                throw new MessageTypeException(
+                        "writeMapEnd(check=true) is called but the map is not end: " + remain);
+            }
+            for (int i = 0; i < remain; i++) {
+                writeNil();
+            }
+        }
+        stack.pop();
+        return this;
+    }
+
+    public void reset() {
+        stack.clear();
+    }
+
+    @Override
+    public void flush() throws IOException {
+        out.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        out.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/packer/Packer.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,90 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.packer;
+
+import java.math.BigInteger;
+import java.io.IOException;
+import java.io.Closeable;
+import java.io.Flushable;
+import java.nio.ByteBuffer;
+import org.msgpack.type.Value;
+
+/**
+ * Standard serializer in MessagePack for Java. It allows users to serialize
+ * objects like <tt>String</tt>, <tt>List</tt>, <tt>Map</tt>, <tt>byte[]</tt>,
+ * primitive types and so on.
+ * 
+ * @version 0.6.0
+ */
+public interface Packer extends Closeable, Flushable {
+    public Packer write(boolean o) throws IOException;
+
+    public Packer write(byte o) throws IOException;
+
+    public Packer write(short o) throws IOException;
+
+    public Packer write(int o) throws IOException;
+
+    public Packer write(long o) throws IOException;
+
+    public Packer write(float o) throws IOException;
+
+    public Packer write(double o) throws IOException;
+
+    public Packer write(Boolean o) throws IOException;
+
+    public Packer write(Byte o) throws IOException;
+
+    public Packer write(Short o) throws IOException;
+
+    public Packer write(Integer o) throws IOException;
+
+    public Packer write(Long o) throws IOException;
+
+    public Packer write(Float o) throws IOException;
+
+    public Packer write(Double o) throws IOException;
+
+    public Packer write(BigInteger o) throws IOException;
+
+    public Packer write(byte[] o) throws IOException;
+
+    public Packer write(byte[] o, int off, int len) throws IOException;
+
+    public Packer write(ByteBuffer o) throws IOException;
+
+    public Packer write(String o) throws IOException;
+
+    public Packer write(Value v) throws IOException;
+
+    public Packer write(Object o) throws IOException;
+
+    public Packer writeNil() throws IOException;
+
+    public Packer writeArrayBegin(int size) throws IOException;
+
+    public Packer writeArrayEnd(boolean check) throws IOException;
+
+    public Packer writeArrayEnd() throws IOException;
+
+    public Packer writeMapBegin(int size) throws IOException;
+
+    public Packer writeMapEnd(boolean check) throws IOException;
+
+    public Packer writeMapEnd() throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/packer/PackerStack.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,98 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.packer;
+
+import org.msgpack.MessageTypeException;
+
+public final class PackerStack {
+    private int top;
+    private byte[] types;
+    private int[] counts;
+
+    public static final int MAX_STACK_SIZE = 128;
+
+    private static final byte TYPE_INVALID = 0;
+    private static final byte TYPE_ARRAY = 1;
+    private static final byte TYPE_MAP = 2;
+
+    public PackerStack() {
+        this.top = 0;
+        this.types = new byte[MAX_STACK_SIZE];
+        this.counts = new int[MAX_STACK_SIZE];
+        this.types[0] = TYPE_INVALID;
+    }
+
+    public void pushArray(int size) {
+        top++;
+        types[top] = TYPE_ARRAY;
+        counts[top] = size;
+    }
+
+    public void pushMap(int size) {
+        top++;
+        types[top] = TYPE_MAP;
+        counts[top] = size * 2;
+    }
+
+    public void checkCount() {
+        if (counts[top] > 0) {
+            return;
+        }
+
+        if (types[top] == TYPE_ARRAY) {
+            throw new MessageTypeException(
+                    "Array is end but writeArrayEnd() is not called");
+
+        } else if (types[top] == TYPE_MAP) {
+            throw new MessageTypeException(
+                    "Map is end but writeMapEnd() is not called");
+
+        } else {
+            // empty
+            return;
+        }
+    }
+
+    public void reduceCount() {
+        counts[top]--;
+    }
+
+    public void pop() {
+        top--;
+    }
+
+    public int getDepth() {
+        return top;
+    }
+
+    public int getTopCount() {
+        return counts[top];
+    }
+
+    public boolean topIsArray() {
+        return types[top] == TYPE_ARRAY;
+    }
+
+    public boolean topIsMap() {
+        return types[top] == TYPE_MAP;
+    }
+
+    public void clear() {
+        top = 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/packer/Unconverter.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,230 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.packer;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
+import org.msgpack.MessagePack;
+import org.msgpack.MessageTypeException;
+import org.msgpack.type.Value;
+import org.msgpack.type.ValueFactory;
+
+public class Unconverter extends AbstractPacker {
+    private PackerStack stack;
+    private Object[] values;
+    private Value result;
+
+    // private Value topContainer;
+
+    public Unconverter() {
+        this(new MessagePack());
+    }
+
+    public Unconverter(MessagePack msgpack) {
+        super(msgpack);
+        this.stack = new PackerStack();
+        this.values = new Object[PackerStack.MAX_STACK_SIZE];
+    }
+
+    public Value getResult() {
+        return result;
+    }
+
+    public void resetResult() {
+        this.result = null;
+    }
+
+    @Override
+    public void writeBoolean(boolean v) throws IOException {
+        put(ValueFactory.createBooleanValue(v));
+    }
+
+    @Override
+    public void writeByte(byte v) throws IOException {
+        put(ValueFactory.createIntegerValue(v));
+    }
+
+    @Override
+    public void writeShort(short v) throws IOException {
+        put(ValueFactory.createIntegerValue(v));
+    }
+
+    @Override
+    public void writeInt(int v) throws IOException {
+        put(ValueFactory.createIntegerValue(v));
+    }
+
+    @Override
+    public void writeBigInteger(BigInteger v) throws IOException {
+        put(ValueFactory.createIntegerValue(v));
+    }
+
+    @Override
+    public void writeLong(long v) throws IOException {
+        put(ValueFactory.createIntegerValue(v));
+    }
+
+    @Override
+    public void writeFloat(float v) throws IOException {
+        put(ValueFactory.createFloatValue(v));
+    }
+
+    @Override
+    public void writeDouble(double v) throws IOException {
+        put(ValueFactory.createFloatValue(v));
+    }
+
+    @Override
+    public void writeByteArray(byte[] b, int off, int len) throws IOException {
+        put(ValueFactory.createRawValue(b, off, len));
+    }
+
+    @Override
+    public void writeByteBuffer(ByteBuffer bb) throws IOException {
+        put(ValueFactory.createRawValue(bb));
+    }
+
+    @Override
+    public void writeString(String s) throws IOException {
+        put(ValueFactory.createRawValue(s));
+    }
+
+    @Override
+    public Packer writeNil() throws IOException {
+        put(ValueFactory.createNilValue());
+        return this;
+    }
+
+    @Override
+    public Packer writeArrayBegin(int size) throws IOException {
+        if (size == 0) {
+            // Value[] array = new Value[size];
+            putContainer(ValueFactory.createArrayValue());
+            stack.pushArray(0);
+            values[stack.getDepth()] = null;
+        } else {
+            Value[] array = new Value[size];
+            putContainer(ValueFactory.createArrayValue(array, true));
+            stack.pushArray(size);
+            values[stack.getDepth()] = array;
+        }
+        return this;
+    }
+
+    @Override
+    public Packer writeArrayEnd(boolean check) throws IOException {
+        if (!stack.topIsArray()) {
+            throw new MessageTypeException(
+                    "writeArrayEnd() is called but writeArrayBegin() is not called");
+        }
+
+        int remain = stack.getTopCount();
+        if (remain > 0) {
+            if (check) {
+                throw new MessageTypeException(
+                        "writeArrayEnd(check=true) is called but the array is not end");
+            }
+            for (int i = 0; i < remain; i++) {
+                writeNil();
+            }
+        }
+        stack.pop();
+        if (stack.getDepth() <= 0) {
+            this.result = (Value) values[0];
+        }
+        return this;
+    }
+
+    @Override
+    public Packer writeMapBegin(int size) throws IOException {
+        stack.checkCount();
+        if (size == 0) {
+            putContainer(ValueFactory.createMapValue());
+            stack.pushMap(0);
+            values[stack.getDepth()] = null;
+        } else {
+            Value[] array = new Value[size * 2];
+            putContainer(ValueFactory.createMapValue(array, true));
+            stack.pushMap(size);
+            values[stack.getDepth()] = array;
+        }
+        return this;
+    }
+
+    @Override
+    public Packer writeMapEnd(boolean check) throws IOException {
+        if (!stack.topIsMap()) {
+            throw new MessageTypeException(
+                    "writeMapEnd() is called but writeMapBegin() is not called");
+        }
+
+        int remain = stack.getTopCount();
+        if (remain > 0) {
+            if (check) {
+                throw new MessageTypeException(
+                        "writeMapEnd(check=true) is called but the map is not end");
+            }
+            for (int i = 0; i < remain; i++) {
+                writeNil();
+            }
+        }
+        stack.pop();
+        if (stack.getDepth() <= 0) {
+            this.result = (Value) values[0];
+        }
+        return this;
+    }
+
+    @Override
+    public Packer write(Value v) throws IOException {
+        put(v);
+        return this;
+    }
+
+    private void put(Value v) {
+        if (stack.getDepth() <= 0) {
+            this.result = v;
+        } else {
+            stack.checkCount();
+            Value[] array = (Value[]) values[stack.getDepth()];
+            array[array.length - stack.getTopCount()] = v;
+            stack.reduceCount();
+        }
+    }
+
+    private void putContainer(Value v) {
+        if (stack.getDepth() <= 0) {
+            values[0] = (Object) v;
+        } else {
+            stack.checkCount();
+            Value[] array = (Value[]) values[stack.getDepth()];
+            array[array.length - stack.getTopCount()] = v;
+            stack.reduceCount();
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+    }
+
+    @Override
+    public void close() throws IOException {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/AbstractTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,33 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+public abstract class AbstractTemplate<T> implements Template<T> {
+
+    public void write(Packer pk, T v) throws IOException {
+        write(pk, v, false);
+    }
+
+    public T read(Unpacker u, T to) throws IOException {
+        return read(u, to, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/AnyTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,60 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+
+import org.msgpack.MessageTypeException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+public class AnyTemplate<T> extends AbstractTemplate<T> {
+
+    private TemplateRegistry registry;
+
+    public AnyTemplate(TemplateRegistry registry) {
+        this.registry = registry;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void write(Packer pk, T target, boolean required) throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+        } else {
+            registry.lookup(target.getClass()).write(pk, target);
+        }
+    }
+
+    public T read(Unpacker u, T to, boolean required) throws IOException,
+            MessageTypeException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        if (to == null) {
+            throw new MessageTypeException("convert into unknown type is invalid");
+        }
+        T o = u.read(to);
+        if (required && o == null) {
+            throw new MessageTypeException("Unexpected nil value");
+        }
+        return o;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/BigDecimalTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,56 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class BigDecimalTemplate extends AbstractTemplate<BigDecimal> {
+    private BigDecimalTemplate() {
+    }
+
+    public void write(Packer pk, BigDecimal target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write(target.toString());
+    }
+
+    public BigDecimal read(Unpacker u, BigDecimal to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        String temp = u.readString();
+        return new BigDecimal(temp);
+    }
+
+    static public BigDecimalTemplate getInstance() {
+        return instance;
+    }
+
+    static final BigDecimalTemplate instance = new BigDecimalTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/BigIntegerTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,55 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class BigIntegerTemplate extends AbstractTemplate<BigInteger> {
+    private BigIntegerTemplate() {
+    }
+
+    public void write(Packer pk, BigInteger target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((BigInteger) target);
+    }
+
+    public BigInteger read(Unpacker u, BigInteger to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readBigInteger();
+    }
+
+    static public BigIntegerTemplate getInstance() {
+        return instance;
+    }
+
+    static final BigIntegerTemplate instance = new BigIntegerTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/BooleanArrayTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,66 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class BooleanArrayTemplate extends AbstractTemplate<boolean[]> {
+    private BooleanArrayTemplate() {
+    }
+
+    public void write(Packer pk, boolean[] target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.writeArrayBegin(target.length);
+        for (boolean a : target) {
+            pk.write(a);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public boolean[] read(Unpacker u, boolean[] to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        if (to == null || to.length != n) {
+            to = new boolean[n];
+        }
+        for (int i = 0; i < n; i++) {
+            to[i] = u.readBoolean();
+        }
+        u.readArrayEnd();
+        return to;
+    }
+
+    static public BooleanArrayTemplate getInstance() {
+        return instance;
+    }
+
+    static final BooleanArrayTemplate instance = new BooleanArrayTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/BooleanTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,54 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class BooleanTemplate extends AbstractTemplate<Boolean> {
+    private BooleanTemplate() {
+    }
+
+    public void write(Packer pk, Boolean target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((boolean) target);
+    }
+
+    public Boolean read(Unpacker u, Boolean to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readBoolean();
+    }
+
+    static public BooleanTemplate getInstance() {
+        return instance;
+    }
+
+    static final BooleanTemplate instance = new BooleanTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/ByteArrayTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,54 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class ByteArrayTemplate extends AbstractTemplate<byte[]> {
+    private ByteArrayTemplate() {
+    }
+
+    public void write(Packer pk, byte[] target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write(target);
+    }
+
+    public byte[] read(Unpacker u, byte[] to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readByteArray(); // TODO read to 'to' obj
+    }
+
+    static public ByteArrayTemplate getInstance() {
+        return instance;
+    }
+
+    static final ByteArrayTemplate instance = new ByteArrayTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/ByteBufferTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,56 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class ByteBufferTemplate extends AbstractTemplate<ByteBuffer> {
+    private ByteBufferTemplate() {
+    }
+
+    public void write(Packer pk, ByteBuffer target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write(target);
+    }
+
+    public ByteBuffer read(Unpacker u, ByteBuffer to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readByteBuffer(); // TODO read to 'to' obj?
+    }
+
+    static public ByteBufferTemplate getInstance() {
+        return instance;
+    }
+
+    static final ByteBufferTemplate instance = new ByteBufferTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/ByteTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,53 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class ByteTemplate extends AbstractTemplate<Byte> {
+    private ByteTemplate() {
+    }
+
+    public void write(Packer pk, Byte target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((byte) target);
+    }
+
+    public Byte read(Unpacker u, Byte to, boolean required) throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readByte();
+    }
+
+    static public ByteTemplate getInstance() {
+        return instance;
+    }
+
+    static final ByteTemplate instance = new ByteTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/CharacterTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,62 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.MessageTypeException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+/**
+ * CharacterTemplate<br/>
+ * 
+ * @author watabiki
+ */
+public class CharacterTemplate extends AbstractTemplate<Character> {
+
+    private CharacterTemplate() {
+    }
+
+    @Override
+    public void write(Packer pk, Character target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((int) (char) target);
+    }
+
+    @Override
+    public Character read(Unpacker u, Character to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return (char) u.readInt();
+    }
+
+    static public CharacterTemplate getInstance() {
+        return instance;
+    }
+
+    static final CharacterTemplate instance = new CharacterTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/CollectionTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,69 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.LinkedList;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class CollectionTemplate<E> extends AbstractTemplate<Collection<E>> {
+    private Template<E> elementTemplate;
+
+    public CollectionTemplate(Template<E> elementTemplate) {
+        this.elementTemplate = elementTemplate;
+    }
+
+    public void write(Packer pk, Collection<E> target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        Collection<E> col = target;
+        pk.writeArrayBegin(col.size());
+        for (E e : col) {
+            elementTemplate.write(pk, e);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public Collection<E> read(Unpacker u, Collection<E> to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        if (to == null) {
+            to = new LinkedList<E>();
+        } else {
+            to.clear();
+        }
+        for (int i = 0; i < n; i++) {
+            E e = elementTemplate.read(u, null);
+            to.add(e);
+        }
+        u.readArrayEnd();
+        return to;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/DateTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,56 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.util.Date;
+
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class DateTemplate extends AbstractTemplate<Date> {
+    private DateTemplate() {
+    }
+
+    public void write(Packer pk, Date target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((long) target.getTime());
+    }
+
+    public Date read(Unpacker u, Date to, boolean required) throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        long temp = u.readLong();
+        return new Date(temp);
+    }
+
+    static public DateTemplate getInstance() {
+        return instance;
+    }
+
+    static final DateTemplate instance = new DateTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/DoubleArrayTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,66 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class DoubleArrayTemplate extends AbstractTemplate<double[]> {
+    private DoubleArrayTemplate() {
+    }
+
+    public void write(Packer pk, double[] target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.writeArrayBegin(target.length);
+        for (double a : target) {
+            pk.write(a);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public double[] read(Unpacker u, double[] to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        if (to == null || to.length != n) {
+            to = new double[n];
+        }
+        for (int i = 0; i < n; i++) {
+            to[i] = u.readDouble();
+        }
+        u.readArrayEnd();
+        return to;
+    }
+
+    static public DoubleArrayTemplate getInstance() {
+        return instance;
+    }
+
+    static final DoubleArrayTemplate instance = new DoubleArrayTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/DoubleTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,54 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class DoubleTemplate extends AbstractTemplate<Double> {
+    private DoubleTemplate() {
+    }
+
+    public void write(Packer pk, Double target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((double) target);
+    }
+
+    public Double read(Unpacker u, Double to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readDouble();
+    }
+
+    static public DoubleTemplate getInstance() {
+        return instance;
+    }
+
+    static final DoubleTemplate instance = new DoubleTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/FieldList.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,83 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class FieldList {
+    public static class Entry {
+        private String name;
+
+        private FieldOption option;
+
+        public Entry() {
+            this(null, FieldOption.IGNORE);
+        }
+
+        public Entry(final String name, final FieldOption option) {
+            this.name = name;
+            this.option = option;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public FieldOption getOption() {
+            return option;
+        }
+
+        public boolean isAvailable() {
+            return option != FieldOption.IGNORE;
+        }
+    }
+
+    private ArrayList<Entry> list;
+
+    public FieldList() {
+        list = new ArrayList<Entry>();
+    }
+
+    public void add(final String name) {
+        add(name, FieldOption.DEFAULT);
+    }
+
+    public void add(final String name, final FieldOption option) {
+        list.add(new Entry(name, option));
+    }
+
+    public void put(final int index, final String name) {
+        put(index, name, FieldOption.DEFAULT);
+    }
+
+    public void put(final int index, final String name, final FieldOption option) {
+        if (list.size() < index) {
+            do {
+                list.add(new Entry());
+            } while (list.size() < index);
+            list.add(new Entry(name, option));
+        } else {
+            list.set(index, new Entry(name, option));
+        }
+    }
+
+    public List<Entry> getList() {
+        return list;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/FieldOption.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,22 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+public enum FieldOption {
+    IGNORE, OPTIONAL, NOTNULLABLE, DEFAULT;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/FloatArrayTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,66 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class FloatArrayTemplate extends AbstractTemplate<float[]> {
+    private FloatArrayTemplate() {
+    }
+
+    public void write(Packer pk, float[] target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.writeArrayBegin(target.length);
+        for (float a : target) {
+            pk.write(a);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public float[] read(Unpacker u, float[] to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        if (to == null || to.length != n) {
+            to = new float[n];
+        }
+        for (int i = 0; i < n; i++) {
+            to[i] = u.readFloat();
+        }
+        u.readArrayEnd();
+        return to;
+    }
+
+    static public FloatArrayTemplate getInstance() {
+        return instance;
+    }
+
+    static final FloatArrayTemplate instance = new FloatArrayTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/FloatTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,54 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class FloatTemplate extends AbstractTemplate<Float> {
+    private FloatTemplate() {
+    }
+
+    public void write(Packer pk, Float target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((float) target);
+    }
+
+    public Float read(Unpacker u, Float to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readFloat();
+    }
+
+    static public FloatTemplate getInstance() {
+        return instance;
+    }
+
+    static final FloatTemplate instance = new FloatTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/GenericCollectionTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,55 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+public class GenericCollectionTemplate implements GenericTemplate {
+    @SuppressWarnings("rawtypes")
+    Constructor<? extends Template> constructor;
+
+    @SuppressWarnings("rawtypes")
+    public GenericCollectionTemplate(TemplateRegistry registry, Class<? extends Template> tmpl) {
+        try {
+            constructor = tmpl.getConstructor(new Class<?>[] { Template.class });
+            constructor.newInstance(new Object[] { new AnyTemplate(registry) });
+        } catch (NoSuchMethodException e) {
+            throw new IllegalArgumentException(e);
+        } catch (InvocationTargetException e) {
+            throw new IllegalArgumentException(e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(e);
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Template build(Template[] params) {
+        try {
+            return constructor.newInstance((Object[]) params);
+        } catch (InvocationTargetException e) {
+            throw new IllegalArgumentException(e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(e);
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/GenericMapTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,57 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+public class GenericMapTemplate implements GenericTemplate {
+    @SuppressWarnings("rawtypes")
+    Constructor<? extends Template> constructor;
+
+    @SuppressWarnings("rawtypes")
+    public GenericMapTemplate(TemplateRegistry registry, Class<? extends Template> tmpl) {
+        try {
+            constructor = tmpl.getConstructor(new Class<?>[] { Template.class, Template.class });
+            constructor.newInstance(new Object[] { new AnyTemplate(registry), new AnyTemplate(registry) });
+            // AnyTemplate.getInstance(registry),
+            // AnyTemplate.getInstance(registry)});
+        } catch (NoSuchMethodException e) {
+            throw new IllegalArgumentException(e);
+        } catch (InvocationTargetException e) {
+            throw new IllegalArgumentException(e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(e);
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Template build(Template[] params) {
+        try {
+            return constructor.newInstance((Object[]) params);
+        } catch (InvocationTargetException e) {
+            throw new IllegalArgumentException(e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(e);
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/GenericTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,23 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+public interface GenericTemplate {
+    @SuppressWarnings("rawtypes")
+    public Template build(Template[] params);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/IntegerArrayTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,69 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class IntegerArrayTemplate extends AbstractTemplate<int[]> {
+    private IntegerArrayTemplate() {
+    }
+
+    public void write(Packer pk, int[] target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.writeArrayBegin(target.length);
+        for (int a : target) {
+            pk.write(a);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public int[] read(Unpacker u, int[] to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        int[] array;
+        if (to != null && to.length == n) {
+            array = to;
+        } else {
+            array = new int[n];
+        }
+        for (int i = 0; i < n; i++) {
+            array[i] = u.readInt();
+        }
+        u.readArrayEnd();
+        return array;
+    }
+
+    static public IntegerArrayTemplate getInstance() {
+        return instance;
+    }
+
+    static final IntegerArrayTemplate instance = new IntegerArrayTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/IntegerTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,54 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class IntegerTemplate extends AbstractTemplate<Integer> {
+    private IntegerTemplate() {
+    }
+
+    public void write(Packer pk, Integer target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((int) target);
+    }
+
+    public Integer read(Unpacker u, Integer to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readInt();
+    }
+
+    static public IntegerTemplate getInstance() {
+        return instance;
+    }
+
+    static final IntegerTemplate instance = new IntegerTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/ListTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,72 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class ListTemplate<E> extends AbstractTemplate<List<E>> {
+    private Template<E> elementTemplate;
+
+    public ListTemplate(Template<E> elementTemplate) {
+        this.elementTemplate = elementTemplate;
+    }
+
+    public void write(Packer pk, List<E> target, boolean required)
+            throws IOException {
+        if (!(target instanceof List)) {
+            if (target == null) {
+                if (required) {
+                    throw new MessageTypeException("Attempted to write null");
+                }
+                pk.writeNil();
+                return;
+            }
+            throw new MessageTypeException("Target is not a List but "
+                    + target.getClass());
+        }
+        pk.writeArrayBegin(target.size());
+        for (E e : target) {
+            elementTemplate.write(pk, e);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public List<E> read(Unpacker u, List<E> to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        if (to == null) {
+            to = new ArrayList<E>(n);
+        } else {
+            to.clear();
+        }
+        for (int i = 0; i < n; i++) {
+            E e = elementTemplate.read(u, null);
+            to.add(e);
+        }
+        u.readArrayEnd();
+        return to;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/LongArrayTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,66 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class LongArrayTemplate extends AbstractTemplate<long[]> {
+    private LongArrayTemplate() {
+    }
+
+    public void write(Packer pk, long[] target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.writeArrayBegin(target.length);
+        for (long a : target) {
+            pk.write(a);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public long[] read(Unpacker u, long[] to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        if (to == null || to.length != n) {
+            to = new long[n];
+        }
+        for (int i = 0; i < n; i++) {
+            to[i] = u.readLong();
+        }
+        u.readArrayEnd();
+        return to;
+    }
+
+    static public LongArrayTemplate getInstance() {
+        return instance;
+    }
+
+    static final LongArrayTemplate instance = new LongArrayTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/LongTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,53 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class LongTemplate extends AbstractTemplate<Long> {
+    private LongTemplate() {
+    }
+
+    public void write(Packer pk, Long target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write((long) target);
+    }
+
+    public Long read(Unpacker u, Long to, boolean required) throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readLong();
+    }
+
+    static public LongTemplate getInstance() {
+        return instance;
+    }
+
+    static final LongTemplate instance = new LongTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/MapTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,78 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.HashMap;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class MapTemplate<K, V> extends AbstractTemplate<Map<K, V>> {
+    private Template<K> keyTemplate;
+    private Template<V> valueTemplate;
+
+    public MapTemplate(Template<K> keyTemplate, Template<V> valueTemplate) {
+        this.keyTemplate = keyTemplate;
+        this.valueTemplate = valueTemplate;
+    }
+
+    public void write(Packer pk, Map<K, V> target, boolean required)
+            throws IOException {
+        if (!(target instanceof Map)) {
+            if (target == null) {
+                if (required) {
+                    throw new MessageTypeException("Attempted to write null");
+                }
+                pk.writeNil();
+                return;
+            }
+            throw new MessageTypeException("Target is not a Map but " + target.getClass());
+        }
+        Map<K, V> map = (Map<K, V>) target;
+        pk.writeMapBegin(map.size());
+        for (Map.Entry<K, V> pair : map.entrySet()) {
+            keyTemplate.write(pk, pair.getKey());
+            valueTemplate.write(pk, pair.getValue());
+        }
+        pk.writeMapEnd();
+    }
+
+    public Map<K, V> read(Unpacker u, Map<K, V> to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readMapBegin();
+        Map<K, V> map;
+        if (to != null) {
+            map = (Map<K, V>) to;
+            map.clear();
+        } else {
+            map = new HashMap<K, V>(n);
+        }
+        for (int i = 0; i < n; i++) {
+            K key = keyTemplate.read(u, null);
+            V value = valueTemplate.read(u, null);
+            map.put(key, value);
+        }
+        u.readMapEnd();
+        return map;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/MessagePackableTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,62 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessagePackable;
+import org.msgpack.MessageTypeException;
+
+public class MessagePackableTemplate extends AbstractTemplate<MessagePackable> {
+    private Class<?> targetClass;
+
+    MessagePackableTemplate(Class<?> targetClass) {
+        this.targetClass = targetClass;
+    }
+
+    public void write(Packer pk, MessagePackable target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        target.writeTo(pk);
+    }
+
+    public MessagePackable read(Unpacker u, MessagePackable to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        if (to == null) {
+            try {
+                to = (MessagePackable) targetClass.newInstance();
+            } catch (InstantiationException e) {
+                throw new MessageTypeException(e);
+            } catch (IllegalAccessException e) {
+                throw new MessageTypeException(e);
+            }
+        }
+        to.readFrom(u);
+        return to;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/NotNullableTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,35 @@
+package org.msgpack.template;
+
+import java.io.IOException;
+
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+public class NotNullableTemplate<T> extends AbstractTemplate<T> {
+
+    private Template<T> tmpl;
+
+    public NotNullableTemplate(Template<T> elementTemplate) {
+        tmpl = elementTemplate;
+    }
+
+    @Override
+    public void write(Packer pk, T v, boolean required) throws IOException {
+        tmpl.write(pk, v, required);
+    }
+
+    @Override
+    public void write(Packer pk, T v) throws IOException {
+        write(pk, v, true);
+    }
+
+    @Override
+    public T read(Unpacker u, T to, boolean required) throws IOException {
+        return tmpl.read(u, to, required);
+    }
+
+    @Override
+    public T read(Unpacker u, T to) throws IOException {
+        return read(u, to, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/ObjectArrayTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,60 @@
+package org.msgpack.template;
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+
+import org.msgpack.MessageTypeException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class ObjectArrayTemplate extends AbstractTemplate {
+    protected Class componentClass;
+
+    protected Template componentTemplate;
+
+    public ObjectArrayTemplate(Class componentClass, Template componentTemplate) {
+        this.componentClass = componentClass;
+        this.componentTemplate = componentTemplate;
+    }
+
+    @Override
+    public void write(Packer packer, Object v, boolean required)
+            throws IOException {
+        if (v == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            packer.writeNil();
+            return;
+        }
+        if (!(v instanceof Object[]) ||
+                !componentClass.isAssignableFrom(v.getClass().getComponentType())) {
+            throw new MessageTypeException();
+        }
+
+        Object[] array = (Object[]) v;
+        int length = array.length;
+        packer.writeArrayBegin(length);
+        for (int i = 0; i < length; i++) {
+            componentTemplate.write(packer, array[i], required);
+        }
+        packer.writeArrayEnd();
+    }
+
+    @Override
+    public Object read(Unpacker unpacker, Object to, boolean required)
+            throws IOException {
+        if (!required && unpacker.trySkipNil()) {
+            return null;
+        }
+
+        int length = unpacker.readArrayBegin();
+        Object[] array = (Object[]) Array.newInstance(componentClass, length);
+        for (int i = 0; i < length; i++) {
+            array[i] = componentTemplate.read(unpacker, null, required);
+        }
+        unpacker.readArrayEnd();
+        return array;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/OrdinalEnumTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,81 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import org.msgpack.MessageTypeException;
+import org.msgpack.annotation.OrdinalEnum;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+public class OrdinalEnumTemplate<T> extends AbstractTemplate<T> {
+    protected T[] entries;
+    protected HashMap<T, Integer> reverse;
+    protected boolean strict;
+
+    public OrdinalEnumTemplate(Class<T> targetClass) {
+        entries = targetClass.getEnumConstants();
+        reverse = new HashMap<T, Integer>();
+        for (int i = 0; i < entries.length; i++) {
+            reverse.put(entries[i], i);
+        }
+		strict = !targetClass.isAnnotationPresent(OrdinalEnum.class)
+				|| targetClass.getAnnotation(OrdinalEnum.class).strict();
+    }
+
+    @Override
+    public void write(Packer pk, T target, boolean required) throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        Integer ordinal = reverse.get(target);
+        if (ordinal == null) {
+            throw new MessageTypeException(
+                    new IllegalArgumentException("ordinal: " + ordinal));
+        }
+        pk.write((int) ordinal);
+    }
+
+    @Override
+    public T read(Unpacker pac, T to, boolean required) throws IOException,
+            MessageTypeException {
+        if (!required && pac.trySkipNil()) {
+            return null;
+        }
+
+        int ordinal = pac.readInt();
+
+		if (ordinal < entries.length) {
+			return entries[ordinal];
+		}
+
+		if (!strict) {
+			return null;
+		}
+
+		throw new MessageTypeException(new IllegalArgumentException("ordinal: "
+				+ ordinal));
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/SetTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,73 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class SetTemplate<E> extends AbstractTemplate<Set<E>> {
+    private Template<E> elementTemplate;
+
+    public SetTemplate(Template<E> elementTemplate) {
+        this.elementTemplate = elementTemplate;
+    }
+
+    public void write(Packer pk, Set<E> target, boolean required)
+            throws IOException {
+        if (!(target instanceof Set)) {
+            if (target == null) {
+                if (required) {
+                    throw new MessageTypeException("Attempted to write null");
+                }
+                pk.writeNil();
+                return;
+            }
+            throw new MessageTypeException("Target is not a List but "
+                    + target.getClass());
+        }
+        pk.writeArrayBegin(target.size());
+        for (E e : target) {
+            elementTemplate.write(pk, e);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public Set<E> read(Unpacker u, Set<E> to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        if (to == null) {
+            to = new HashSet<E>(n);
+        } else {
+            to.clear();
+        }
+        for (int i = 0; i < n; i++) {
+            E e = elementTemplate.read(u, null);
+            to.add(e);
+        }
+        u.readArrayEnd();
+        return to;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/ShortArrayTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,66 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class ShortArrayTemplate extends AbstractTemplate<short[]> {
+    private ShortArrayTemplate() {
+    }
+
+    public void write(Packer pk, short[] target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.writeArrayBegin(target.length);
+        for (short a : target) {
+            pk.write(a);
+        }
+        pk.writeArrayEnd();
+    }
+
+    public short[] read(Unpacker u, short[] to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        int n = u.readArrayBegin();
+        if (to == null || to.length != n) {
+            to = new short[n];
+        }
+        for (int i = 0; i < n; i++) {
+            to[i] = u.readShort();
+        }
+        u.readArrayEnd();
+        return to;
+    }
+
+    static public ShortArrayTemplate getInstance() {
+        return instance;
+    }
+
+    static final ShortArrayTemplate instance = new ShortArrayTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/ShortTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,54 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class ShortTemplate extends AbstractTemplate<Short> {
+    private ShortTemplate() {
+    }
+
+    public void write(Packer pk, Short target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write(target);
+    }
+
+    public Short read(Unpacker u, Short to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readShort();
+    }
+
+    static public ShortTemplate getInstance() {
+        return instance;
+    }
+
+    static final ShortTemplate instance = new ShortTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/StringTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,54 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+
+public class StringTemplate extends AbstractTemplate<String> {
+    private StringTemplate() {
+    }
+
+    public void write(Packer pk, String target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        pk.write(target);
+    }
+
+    public String read(Unpacker u, String to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readString();
+    }
+
+    static public StringTemplate getInstance() {
+        return instance;
+    }
+
+    static final StringTemplate instance = new StringTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/Template.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,32 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+public interface Template<T> {
+    public void write(Packer pk, T v) throws IOException;
+
+    public void write(Packer pk, T v, boolean required) throws IOException;
+
+    public T read(Unpacker u, T to) throws IOException;
+
+    public T read(Unpacker u, T to, boolean required) throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/TemplateReference.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,74 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+import org.msgpack.MessageTypeException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+
+public class TemplateReference<T> extends AbstractTemplate<T> {
+
+    private TemplateRegistry registry;
+
+    private Type targetType;
+
+    private Template<T> actualTemplate;
+
+    public TemplateReference(TemplateRegistry registry, Type targetType) {
+        this.registry = registry;
+        this.targetType = targetType;
+    }
+
+    @SuppressWarnings("unchecked")
+    private void validateActualTemplate() {
+        if (actualTemplate == null) {
+            actualTemplate = (Template<T>) registry.cache.get(targetType);
+            if (actualTemplate == null) {
+                throw new MessageTypeException(
+                        "Actual template have not been created");
+            }
+        }
+    }
+
+    @Override
+    public void write(Packer pk, T v, boolean required) throws IOException {
+        validateActualTemplate();
+        actualTemplate.write(pk, v, required);
+    }
+
+    @Override
+    public void write(Packer pk, T v) throws IOException {
+        validateActualTemplate();
+        actualTemplate.write(pk, v, false);
+    }
+
+    @Override
+    public T read(Unpacker u, T to, boolean required) throws IOException {
+        validateActualTemplate();
+        return actualTemplate.read(u, to, required);
+    }
+
+    @Override
+    public T read(Unpacker u, T to) throws IOException {
+        validateActualTemplate();
+        return actualTemplate.read(u, to, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/TemplateRegistry.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,623 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
+import org.msgpack.MessagePackable;
+import org.msgpack.MessageTypeException;
+import org.msgpack.template.BigIntegerTemplate;
+import org.msgpack.template.BooleanTemplate;
+import org.msgpack.template.ByteArrayTemplate;
+import org.msgpack.template.ByteTemplate;
+import org.msgpack.template.DoubleArrayTemplate;
+import org.msgpack.template.DoubleTemplate;
+import org.msgpack.template.FieldList;
+import org.msgpack.template.FloatArrayTemplate;
+import org.msgpack.template.FloatTemplate;
+import org.msgpack.template.GenericTemplate;
+import org.msgpack.template.IntegerArrayTemplate;
+import org.msgpack.template.IntegerTemplate;
+import org.msgpack.template.LongArrayTemplate;
+import org.msgpack.template.LongTemplate;
+import org.msgpack.template.ShortArrayTemplate;
+import org.msgpack.template.ShortTemplate;
+import org.msgpack.template.StringTemplate;
+import org.msgpack.template.Template;
+import org.msgpack.template.ValueTemplate;
+import org.msgpack.template.builder.ArrayTemplateBuilder;
+import org.msgpack.template.builder.TemplateBuilder;
+import org.msgpack.template.builder.TemplateBuilderChain;
+import org.msgpack.type.Value;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class TemplateRegistry {
+
+    private TemplateRegistry parent = null;
+
+    private TemplateBuilderChain chain;
+
+    Map<Type, Template<Type>> cache;
+
+    private Map<Type, GenericTemplate> genericCache;
+
+    /**
+     * create <code>TemplateRegistry</code> object of root.
+     */
+    private TemplateRegistry() {
+        parent = null;
+        chain = createTemplateBuilderChain();
+        genericCache = new HashMap<Type, GenericTemplate>();
+        cache = new HashMap<Type, Template<Type>>();
+        registerTemplates();
+        cache = Collections.unmodifiableMap(cache);
+    }
+
+    /**
+     *
+     * @param registry
+     */
+    public TemplateRegistry(TemplateRegistry registry) {
+        if (registry != null) {
+            parent = registry;
+        } else {
+            parent = new TemplateRegistry();
+        }
+        chain = createTemplateBuilderChain();
+        cache = new HashMap<Type, Template<Type>>();
+        genericCache = new HashMap<Type, GenericTemplate>();
+        registerTemplatesWhichRefersRegistry();
+    }
+
+    protected TemplateBuilderChain createTemplateBuilderChain() {
+        return new TemplateBuilderChain(this);
+    }
+
+    public void setClassLoader(final ClassLoader cl) {
+        chain = new TemplateBuilderChain(this, cl);
+    }
+
+    private void registerTemplates() {
+        register(boolean.class, BooleanTemplate.getInstance());
+        register(Boolean.class, BooleanTemplate.getInstance());
+        register(byte.class, ByteTemplate.getInstance());
+        register(Byte.class, ByteTemplate.getInstance());
+        register(short.class, ShortTemplate.getInstance());
+        register(Short.class, ShortTemplate.getInstance());
+        register(int.class, IntegerTemplate.getInstance());
+        register(Integer.class, IntegerTemplate.getInstance());
+        register(long.class, LongTemplate.getInstance());
+        register(Long.class, LongTemplate.getInstance());
+        register(float.class, FloatTemplate.getInstance());
+        register(Float.class, FloatTemplate.getInstance());
+        register(double.class, DoubleTemplate.getInstance());
+        register(Double.class, DoubleTemplate.getInstance());
+        register(BigInteger.class, BigIntegerTemplate.getInstance());
+        register(char.class, CharacterTemplate.getInstance());
+        register(Character.class, CharacterTemplate.getInstance());
+        register(boolean[].class, BooleanArrayTemplate.getInstance());
+        register(short[].class, ShortArrayTemplate.getInstance());
+        register(int[].class, IntegerArrayTemplate.getInstance());
+        register(long[].class, LongArrayTemplate.getInstance());
+        register(float[].class, FloatArrayTemplate.getInstance());
+        register(double[].class, DoubleArrayTemplate.getInstance());
+        register(String.class, StringTemplate.getInstance());
+        register(byte[].class, ByteArrayTemplate.getInstance());
+        register(ByteBuffer.class, ByteBufferTemplate.getInstance());
+        register(Value.class, ValueTemplate.getInstance());
+        register(BigDecimal.class, BigDecimalTemplate.getInstance());
+        register(Date.class, DateTemplate.getInstance());
+
+        registerTemplatesWhichRefersRegistry();
+
+    }
+
+    protected void registerTemplatesWhichRefersRegistry() {
+        AnyTemplate anyTemplate = new AnyTemplate(this);
+
+        register(List.class, new ListTemplate(anyTemplate));
+        register(Set.class, new SetTemplate(anyTemplate));
+        register(Collection.class, new CollectionTemplate(anyTemplate));
+        register(Map.class, new MapTemplate(anyTemplate, anyTemplate));
+        registerGeneric(List.class, new GenericCollectionTemplate(this, ListTemplate.class));
+        registerGeneric(Set.class, new GenericCollectionTemplate(this, SetTemplate.class));
+        registerGeneric(Collection.class, new GenericCollectionTemplate(this, CollectionTemplate.class));
+        registerGeneric(Map.class, new GenericMapTemplate(this, MapTemplate.class));
+    }
+
+    public void register(final Class<?> targetClass) {
+        buildAndRegister(null, targetClass, false, null);
+    }
+
+    public void register(final Class<?> targetClass, final FieldList flist) {
+        if (flist == null) {
+            throw new NullPointerException("FieldList object is null");
+        }
+
+        buildAndRegister(null, targetClass, false, flist);
+    }
+
+    public synchronized void register(final Type targetType, final Template tmpl) {
+        if (tmpl == null) {
+            throw new NullPointerException("Template object is null");
+        }
+
+        if (targetType instanceof ParameterizedType) {
+            cache.put(((ParameterizedType) targetType).getRawType(), tmpl);
+        } else {
+            cache.put(targetType, tmpl);
+        }
+    }
+
+    public synchronized void registerGeneric(final Type targetType, final GenericTemplate tmpl) {
+        if (targetType instanceof ParameterizedType) {
+            genericCache.put(((ParameterizedType) targetType).getRawType(),
+                    tmpl);
+        } else {
+            genericCache.put(targetType, tmpl);
+        }
+    }
+
+    public synchronized boolean unregister(final Type targetType) {
+        Template<Type> tmpl = cache.remove(targetType);
+        return tmpl != null;
+    }
+
+    public synchronized void unregister() {
+        cache.clear();
+    }
+
+    public synchronized Template lookup(Type targetType) {
+        Template tmpl;
+
+        if (targetType instanceof ParameterizedType) {
+            // ParameterizedType is not a Class<?>
+            ParameterizedType paramedType = (ParameterizedType) targetType;
+            tmpl = lookupGenericType(paramedType);
+            if (tmpl != null) {
+                return tmpl;
+            }
+            targetType = paramedType.getRawType();
+        }
+
+        tmpl = lookupGenericArrayType(targetType);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        tmpl = lookupCache(targetType);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        if (targetType instanceof WildcardType ||
+                targetType instanceof TypeVariable) {
+            // WildcardType is not a Class<?>
+            tmpl = new AnyTemplate<Object>(this);
+            register(targetType, tmpl);
+            return tmpl;
+        }
+
+        Class<?> targetClass = (Class<?>) targetType;
+
+        // MessagePackable interface is implemented
+        if (MessagePackable.class.isAssignableFrom(targetClass)) {
+            // FIXME #MN
+            // following processing should be merged into lookAfterBuilding
+            // or lookupInterfaceTypes method in next version
+            tmpl = new MessagePackableTemplate(targetClass);
+            register(targetClass, tmpl);
+            return tmpl;
+        }
+
+        if (targetClass.isInterface()) {
+            // writing interfaces will succeed
+            // reading into interfaces will fail
+            tmpl = new AnyTemplate<Object>(this);
+            register(targetType, tmpl);
+            return tmpl;
+        }
+
+        // find matched template builder and build template
+        tmpl = lookupAfterBuilding(targetClass);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        // lookup template of interface type
+        tmpl = lookupInterfaceTypes(targetClass);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        // lookup template of superclass type
+        tmpl = lookupSuperclasses(targetClass);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        // lookup template of interface type of superclasss
+        tmpl = lookupSuperclassInterfaceTypes(targetClass);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        throw new MessageTypeException(
+                "Cannot find template for " + targetClass + " class.  " +
+                "Try to add @Message annotation to the class or call MessagePack.register(Type).");
+    }
+
+    private Template<Type> lookupGenericType(ParameterizedType paramedType) {
+        Template<Type> tmpl = lookupGenericTypeImpl(paramedType);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        try {
+            tmpl = parent.lookupGenericTypeImpl(paramedType);
+            if (tmpl != null) {
+                return tmpl;
+            }
+        } catch (NullPointerException e) { // ignore
+        }
+
+        tmpl = lookupGenericInterfaceTypes(paramedType);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        tmpl = lookupGenericSuperclasses(paramedType);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        return null;
+    }
+
+    private Template lookupGenericTypeImpl(ParameterizedType targetType) {
+        Type rawType = targetType.getRawType();
+        return lookupGenericTypeImpl0(targetType, rawType);
+    }
+
+    private Template lookupGenericTypeImpl0(ParameterizedType targetType, Type rawType) {
+        GenericTemplate gtmpl = genericCache.get(rawType);
+        if (gtmpl == null) {
+            return null;
+        }
+
+        Type[] types = targetType.getActualTypeArguments();
+        Template[] tmpls = new Template[types.length];
+        for (int i = 0; i < types.length; ++i) {
+            tmpls[i] = lookup(types[i]);
+        }
+
+        return gtmpl.build(tmpls);
+    }
+
+    private <T> Template<T> lookupGenericInterfaceTypes(ParameterizedType targetType) {
+        Type rawType = targetType.getRawType();
+        Template<T> tmpl = null;
+
+        try {
+            Class<?>[] infTypes = ((Class) rawType).getInterfaces();
+            for (Class<?> infType : infTypes) {
+                tmpl = lookupGenericTypeImpl0(targetType, infType);
+                if (tmpl != null) {
+                    return tmpl;
+                }
+            }
+        } catch (ClassCastException e) { // ignore
+        }
+
+        return tmpl;
+    }
+
+    private <T> Template<T> lookupGenericSuperclasses(ParameterizedType targetType) {
+        Type rawType = targetType.getRawType();
+        Template<T> tmpl = null;
+
+        try {
+            Class<?> superClass = ((Class) rawType).getSuperclass();
+            if (superClass == null) {
+                return null;
+            }
+
+            for (; superClass != Object.class; superClass = superClass.getSuperclass()) {
+                tmpl = lookupGenericTypeImpl0(targetType, superClass);
+                if (tmpl != null) {
+                    register(targetType, tmpl);
+                    return tmpl;
+                }
+            }
+        } catch (ClassCastException e) { // ignore
+        }
+
+        return tmpl;
+    }
+
+    private Template<Type> lookupGenericArrayType(Type targetType) {
+        // TODO GenericArrayType is not a Class<?> => buildArrayTemplate
+        if (! (targetType instanceof GenericArrayType)) {
+            return null;
+        }
+
+        GenericArrayType genericArrayType = (GenericArrayType) targetType;
+        Template<Type> tmpl = lookupGenericArrayTypeImpl(genericArrayType);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        try {
+            tmpl = parent.lookupGenericArrayTypeImpl(genericArrayType);
+            if (tmpl != null) {
+                return tmpl;
+            }
+        } catch (NullPointerException e) { // ignore
+        }
+
+        return null;
+    }
+
+    private Template lookupGenericArrayTypeImpl(GenericArrayType genericArrayType) {
+        String genericArrayTypeName = "" + genericArrayType;
+        int dim = genericArrayTypeName.split("\\[").length - 1;
+        if (dim <= 0) {
+            throw new MessageTypeException(
+                    String.format("fatal error: type=", genericArrayTypeName));
+        } else if (dim > 1) {
+            throw new UnsupportedOperationException(String.format(
+                    "Not implemented template generation of %s", genericArrayTypeName));
+        }
+
+        String genericCompTypeName = "" + genericArrayType.getGenericComponentType();
+        boolean isPrimitiveType = isPrimitiveType(genericCompTypeName);
+        StringBuffer sbuf = new StringBuffer();
+        for (int i = 0; i < dim; i++) {
+            sbuf.append('[');
+        }
+        if (!isPrimitiveType) {
+            sbuf.append('L');
+            sbuf.append(toJvmReferenceTypeName(genericCompTypeName));
+            sbuf.append(';');
+        } else {
+            sbuf.append(toJvmPrimitiveTypeName(genericCompTypeName));
+        }
+
+        String jvmArrayClassName = sbuf.toString();
+        Class jvmArrayClass = null;
+        ClassLoader cl = null;
+        try {
+            cl = Thread.currentThread().getContextClassLoader();
+            if (cl != null) {
+                jvmArrayClass = cl.loadClass(jvmArrayClassName);
+                if (jvmArrayClass != null) {
+                    return lookupAfterBuilding(jvmArrayClass);
+                }
+            }
+        } catch (ClassNotFoundException e) {} // ignore
+
+        try {
+            cl = getClass().getClassLoader();
+            if (cl != null) {
+                jvmArrayClass = cl.loadClass(jvmArrayClassName);
+                if (jvmArrayClass != null) {
+                    return lookupAfterBuilding(jvmArrayClass);
+                }
+            }
+        } catch (ClassNotFoundException e) {} // ignore
+
+        try {
+            jvmArrayClass = Class.forName(jvmArrayClassName);
+            if (jvmArrayClass != null) {
+                return lookupAfterBuilding(jvmArrayClass);
+            }
+        } catch (ClassNotFoundException e) {} // ignore
+
+        throw new MessageTypeException(String.format(
+                "cannot find template of %s", jvmArrayClassName));
+    }
+
+    private Template<Type> lookupCache(Type targetType) {
+        Template<Type> tmpl = cache.get(targetType);
+        if (tmpl != null) {
+            return tmpl;
+        }
+
+        try {
+            tmpl = parent.lookupCache(targetType);
+        } catch (NullPointerException e) { // ignore
+        }
+        return tmpl;
+    }
+
+    private <T> Template<T> lookupAfterBuilding(Class<T> targetClass) {
+        TemplateBuilder builder = chain.select(targetClass, true);
+        Template<T> tmpl = null;
+        if (builder != null) {
+            // TODO #MN for Android, we should modify here
+            tmpl = chain.getForceBuilder().loadTemplate(targetClass);
+            if (tmpl != null) {
+                register(targetClass, tmpl);
+                return tmpl;
+            }
+            tmpl = buildAndRegister(builder, targetClass, true, null);
+        }
+        return tmpl;
+    }
+
+    private <T> Template<T> lookupInterfaceTypes(Class<T> targetClass) {
+        Class<?>[] infTypes = targetClass.getInterfaces();
+        Template<T> tmpl = null;
+        for (Class<?> infType : infTypes) {
+            tmpl = (Template<T>) cache.get(infType);
+            if (tmpl != null) {
+                register(targetClass, tmpl);
+                return tmpl;
+            } else {
+                try {
+                    tmpl = (Template<T>) parent.lookupCache(infType);
+                    if (tmpl != null) {
+                        register(targetClass, tmpl);
+                        return tmpl;
+                    }
+                } catch (NullPointerException e) { // ignore
+                }
+            }
+        }
+        return tmpl;
+    }
+
+    private <T> Template<T> lookupSuperclasses(Class<T> targetClass) {
+        Class<?> superClass = targetClass.getSuperclass();
+        Template<T> tmpl = null;
+        if (superClass != null) {
+            for (; superClass != Object.class; superClass = superClass
+                    .getSuperclass()) {
+                tmpl = (Template<T>) cache.get(superClass);
+                if (tmpl != null) {
+                    register(targetClass, tmpl);
+                    return tmpl;
+                } else {
+                    try {
+                        tmpl = (Template<T>) parent.lookupCache(superClass);
+                        if (tmpl != null) {
+                            register(targetClass, tmpl);
+                            return tmpl;
+                        }
+                    } catch (NullPointerException e) { // ignore
+                    }
+                }
+            }
+        }
+        return tmpl;
+    }
+
+    private <T> Template<T> lookupSuperclassInterfaceTypes(Class<T> targetClass) {
+        Class<?> superClass = targetClass.getSuperclass();
+        Template<T> tmpl = null;
+        if (superClass != null) {
+            for (; superClass != Object.class; superClass = superClass.getSuperclass()) {
+                tmpl = (Template<T>) lookupInterfaceTypes(superClass);
+                if (tmpl != null) {
+                    register(targetClass, tmpl);
+                    return tmpl;
+                } else {
+                    try {
+                        tmpl = (Template<T>) parent.lookupCache(superClass);
+                        if (tmpl != null) {
+                            register(targetClass, tmpl);
+                            return tmpl;
+                        }
+                    } catch (NullPointerException e) { // ignore
+                    }
+                }
+            }
+        }
+        return tmpl;
+    }
+
+    private synchronized Template buildAndRegister(TemplateBuilder builder,
+            final Class targetClass, final boolean hasAnnotation,
+            final FieldList flist) {
+        Template newTmpl = null;
+        Template oldTmpl = null;
+        try {
+            if (cache.containsKey(targetClass)) {
+                oldTmpl = cache.get(targetClass);
+            }
+            newTmpl = new TemplateReference(this, targetClass);
+            cache.put(targetClass, newTmpl);
+            if (builder == null) {
+                builder = chain.select(targetClass, hasAnnotation);
+            }
+            newTmpl = flist != null ?
+                    builder.buildTemplate(targetClass, flist) : builder.buildTemplate(targetClass);
+            return newTmpl;
+        } catch (Exception e) {
+            if (oldTmpl != null) {
+                cache.put(targetClass, oldTmpl);
+            } else {
+                cache.remove(targetClass);
+            }
+            newTmpl = null;
+            if (e instanceof MessageTypeException) {
+                throw (MessageTypeException) e;
+            } else {
+                throw new MessageTypeException(e);
+            }
+        } finally {
+            if (newTmpl != null) {
+                cache.put(targetClass, newTmpl);
+            }
+        }
+    }
+
+    private static boolean isPrimitiveType(String genericCompTypeName) {
+        return (genericCompTypeName.equals("byte")
+                || genericCompTypeName.equals("short")
+                || genericCompTypeName.equals("int")
+                || genericCompTypeName.equals("long")
+                || genericCompTypeName.equals("float")
+                || genericCompTypeName.equals("double")
+                || genericCompTypeName.equals("boolean")
+                || genericCompTypeName.equals("char"));
+    }
+
+    private static String toJvmReferenceTypeName(String typeName) {
+        // delete "class " from class name
+        // e.g. "class Foo" to "Foo" by this method
+        return typeName.substring(6);
+    }
+
+    private static String toJvmPrimitiveTypeName(String typeName) {
+        if (typeName.equals("byte")) {
+            return "B";
+        } else if (typeName.equals("short")) {
+            return "S";
+        } else if (typeName.equals("int")) {
+            return "I";
+        } else if (typeName.equals("long")) {
+            return "J";
+        } else if (typeName.equals("float")) {
+            return "F";
+        } else if (typeName.equals("double")) {
+            return "D";
+        } else if (typeName.equals("boolean")) {
+            return "Z";
+        } else if (typeName.equals("char")) {
+            return "C";
+        } else {
+            throw new MessageTypeException(String.format(
+                    "fatal error: type=%s", typeName));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/Templates.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,154 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Date;
+import java.math.BigInteger;
+import java.math.BigDecimal;
+import org.msgpack.type.Value;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public final class Templates {
+    public static final Template<Value> TValue = ValueTemplate.getInstance();
+
+    public static final Template<Byte> TByte = ByteTemplate.getInstance();
+
+    public static final Template<Short> TShort = ShortTemplate.getInstance();
+
+    public static final Template<Integer> TInteger = IntegerTemplate.getInstance();
+
+    public static final Template<Long> TLong = LongTemplate.getInstance();
+
+    public static final Template<Character> TCharacter = CharacterTemplate.getInstance();
+
+    public static final Template<BigInteger> TBigInteger = BigIntegerTemplate.getInstance();
+
+    public static final Template<BigDecimal> TBigDecimal = BigDecimalTemplate.getInstance();
+
+    public static final Template<Float> TFloat = FloatTemplate.getInstance();
+
+    public static final Template<Double> TDouble = DoubleTemplate.getInstance();
+
+    public static final Template<Boolean> TBoolean = BooleanTemplate.getInstance();
+
+    public static final Template<String> TString = StringTemplate.getInstance();
+
+    public static final Template<byte[]> TByteArray = ByteArrayTemplate.getInstance();
+
+    public static final Template<ByteBuffer> TByteBuffer = ByteBufferTemplate.getInstance();
+
+    public static final Template<Date> TDate = DateTemplate.getInstance();
+
+    public static <T> Template<T> tNotNullable(Template<T> innerTemplate) {
+        return new NotNullableTemplate(innerTemplate);
+    }
+
+    public static <E> Template<List<E>> tList(Template<E> elementTemplate) {
+        return new ListTemplate(elementTemplate);
+    }
+
+    public static <K, V> Template<Map<K, V>> tMap(Template<K> keyTemplate, Template<V> valueTemplate) {
+        return new MapTemplate(keyTemplate, valueTemplate);
+    }
+
+    public static <E> Template<Collection<E>> tCollection(Template<E> elementTemplate) {
+        return new CollectionTemplate(elementTemplate);
+    }
+
+    public static <E extends Enum> Template<E> tOrdinalEnum(Class<E> enumClass) {
+        return new OrdinalEnumTemplate(enumClass);
+    }
+
+    // public static Template<T> tClass(Class<T> target) {
+    // // TODO
+    // }
+
+    @Deprecated
+    public static Template tByte() {
+        return TByte;
+    }
+
+    @Deprecated
+    public static Template tShort() {
+        return TShort;
+    }
+
+    @Deprecated
+    public static Template tInteger() {
+        return TInteger;
+    }
+
+    @Deprecated
+    public static Template tLong() {
+        return TLong;
+    }
+
+    @Deprecated
+    public static Template tCharacter() {
+        return TCharacter;
+    }
+
+    @Deprecated
+    public static Template tBigInteger() {
+        return TBigInteger;
+    }
+
+    @Deprecated
+    public static Template tBigDecimal() {
+        return TBigDecimal;
+    }
+
+    @Deprecated
+    public static Template tFloat() {
+        return TFloat;
+    }
+
+    @Deprecated
+    public static Template tDouble() {
+        return TDouble;
+    }
+
+    @Deprecated
+    public static Template tBoolean() {
+        return TBoolean;
+    }
+
+    @Deprecated
+    public static Template tString() {
+        return TString;
+    }
+
+    @Deprecated
+    public static Template tByteArray() {
+        return TByteArray;
+    }
+
+    @Deprecated
+    public static Template tByteBuffer() {
+        return TByteBuffer;
+    }
+
+    @Deprecated
+    public static Template tDate() {
+        return TDate;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/ValueTemplate.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,55 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template;
+
+import java.io.IOException;
+import org.msgpack.packer.Packer;
+import org.msgpack.unpacker.Unpacker;
+import org.msgpack.MessageTypeException;
+import org.msgpack.type.Value;
+
+public class ValueTemplate extends AbstractTemplate<Value> {
+    private ValueTemplate() {
+    }
+
+    public void write(Packer pk, Value target, boolean required)
+            throws IOException {
+        if (target == null) {
+            if (required) {
+                throw new MessageTypeException("Attempted to write null");
+            }
+            pk.writeNil();
+            return;
+        }
+        target.writeTo(pk);
+    }
+
+    public Value read(Unpacker u, Value to, boolean required)
+            throws IOException {
+        if (!required && u.trySkipNil()) {
+            return null;
+        }
+        return u.readValue();
+    }
+
+    static public ValueTemplate getInstance() {
+        return instance;
+    }
+
+    static final ValueTemplate instance = new ValueTemplate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/msgpack/template/builder/AbstractTemplateBuilder.java	Sat Oct 18 15:06:15 2014 +0900
@@ -0,0 +1,293 @@
+//
+// MessagePack for Java
+//
+// Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
+//
+//    Licensed 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.msgpack.template.builder;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.msgpack.annotation.Beans;
+import org.msgpack.annotation.Ignore;
+import org.msgpack.annotation.Index;
+import org.msgpack.annotation.Message;
+import org.msgpack.annotation.MessagePackBeans;
+import org.msgpack.annotation.MessagePackMessage;
+import org.msgpack.annotation.MessagePackOrdinalEnum;
+import org.msgpack.annotation.NotNullable;
+import org.msgpack.annotation.Optional;
+import org.msgpack.annotation.OrdinalEnum;
+import org.msgpack.template.FieldList;
+import org.msgpack.template.FieldOption;
+import org.msgpack.template.Template;
+import org.msgpack.template.TemplateRegistry;
+import org.msgpack.template.builder.TemplateBuildException;
+
+public abstract class AbstractTemplateBuilder implements TemplateBuilder {
+
+    protected TemplateRegistry registry;
+
+    protected AbstractTemplateBuilder(TemplateRegistry registry) {
+        this.registry = registry;
+    }
+
+    @Override
+    public <T> Template<T> buildTemplate(final Type targetType)
+            throws TemplateBuildException {
+        @SuppressWarnings("unchecked")
+        Class<T> targetClass = (Class<T>) targetType;
+        checkClassValidation(targetClass);
+        FieldOption fieldOption = getFieldOption(targetClass);
+        FieldEntry[] entries = toFieldEntries(targetClass, fieldOption);
+        return buildTemplate(targetClass, entries);
+    }
+
+    @Override
+    public <T> Template<T> buildTemplate(final Class<T> targetClass, final FieldList fieldList)
+            throws TemplateBuildException {
+        checkClassValidation(targetClass);
+        FieldEntry[] entries = toFieldEntries(targetClass, fieldList);
+        return buildTemplate(targetClass, entries);
+    }
+
+    protected abstract <T> Template<T> buildTemplate(Class<T> targetClass, FieldEntry[] entries);
+
+    protected void checkClassValidation(final Class<?> targetClass) {
+        if (targetClass.isInterface()) {
+            throw new TemplateBuildException(
+                    "Cannot build template for interfa