From 9d4db8498776d574616c45556d247dc29c2adfc7 Mon Sep 17 00:00:00 2001
From: FURUHASHI Sadayuki <frsyuki@users.sourceforge.jp>
Date: Thu, 7 Apr 2011 22:32:59 +0900
Subject: [PATCH 01/10] MSGPACK-4 BufferedUnpackerImpl.unpackLong:
 more(4)+advance(4) -> more(5)+advance(5)

---
 java/src/main/java/org/msgpack/BufferedUnpackerImpl.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java b/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java
index 406fff73..36b6a59c 100644
--- a/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java
+++ b/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java
@@ -215,10 +215,10 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
 			advance(3);
 			return (long)castBuffer.getShort(0);
 		case 0xd2:  // signed int 32
-			more(4);
+			more(5);
 			castBuffer.rewind();
 			castBuffer.put(buffer, offset+1, 4);
-			advance(4);
+			advance(5);
 			return (long)castBuffer.getInt(0);
 		case 0xd3:  // signed int 64
 			more(9);

From 983ae0c5a2a5c67b5a7e20d9489bad0bc8ab2be0 Mon Sep 17 00:00:00 2001
From: FURUHASHI Sadayuki <frsyuki@users.sourceforge.jp>
Date: Thu, 7 Apr 2011 23:21:30 +0900
Subject: [PATCH 02/10] MSGPACK-4 BufferedUnapckerImpl.unpackInt:
 more(4)+advance(4) -> more(5)+advance(5)

---
 java/src/main/java/org/msgpack/BufferedUnpackerImpl.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java b/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java
index 36b6a59c..30637a1a 100644
--- a/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java
+++ b/java/src/main/java/org/msgpack/BufferedUnpackerImpl.java
@@ -146,10 +146,10 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
 			advance(3);
 			return (int)castBuffer.getShort(0);
 		case 0xd2:  // signed int 32
-			more(4);
+			more(5);
 			castBuffer.rewind();
 			castBuffer.put(buffer, offset+1, 4);
-			advance(4);
+			advance(5);
 			return (int)castBuffer.getInt(0);
 		case 0xd3:  // signed int 64
 			more(9);

From b50ff920f08bc3f21d72994ab55ecac6266bdf5b Mon Sep 17 00:00:00 2001
From: FURUHASHI Sadayuki <frsyuki@users.sourceforge.jp>
Date: Thu, 7 Apr 2011 23:21:56 +0900
Subject: [PATCH 03/10] MSGPACK-5 added test cases for Unpacker.unpackXxx()
 methods

---
 java/src/test/java/org/msgpack/TestCases.java | 174 +++++++++++++++++-
 1 file changed, 172 insertions(+), 2 deletions(-)

diff --git a/java/src/test/java/org/msgpack/TestCases.java b/java/src/test/java/org/msgpack/TestCases.java
index c368972f..38c1d1c2 100644
--- a/java/src/test/java/org/msgpack/TestCases.java
+++ b/java/src/test/java/org/msgpack/TestCases.java
@@ -2,6 +2,7 @@ package org.msgpack;
 
 import java.io.*;
 import java.util.*;
+import java.math.BigInteger;
 
 import org.junit.Test;
 import static org.junit.Assert.*;
@@ -20,7 +21,7 @@ public class TestCases {
 	}
 
 	@Test
-	public void testCases() throws Exception {
+	public void testDynamicType() throws Exception {
 		Unpacker pac = new Unpacker();
 		Unpacker pac_compact = new Unpacker();
 
@@ -28,13 +29,182 @@ public class TestCases {
 		feedFile(pac_compact, "src/test/resources/cases_compact.mpac");
 
 		UnpackResult result = new UnpackResult();
+		UnpackResult result_compact = new UnpackResult();
 		while(pac.next(result)) {
-			UnpackResult result_compact = new UnpackResult();
 			assertTrue( pac_compact.next(result_compact) );
 			assertTrue( result.getData().equals(result_compact.getData()) );
 		}
 
 		assertFalse( pac_compact.next(result) );
 	}
+
+	@Test
+	public void testDirectConversion() throws Exception {
+		Unpacker pac = new Unpacker();
+		Unpacker pac_compact = new Unpacker();
+
+		feedFile(pac, "src/test/resources/cases.mpac");
+		feedFile(pac_compact, "src/test/resources/cases_compact.mpac");
+
+		UnpackResult result_compact = new UnpackResult();
+		while(pac_compact.next(result_compact)) {
+			MessagePackObject obj = result_compact.getData();
+			testDirectConversionRecursive(pac, obj);
+		}
+
+		assertFalse( pac_compact.next(result_compact) );
+	}
+
+	private void testDirectConversionRecursive(Unpacker pac, MessagePackObject obj) throws Exception {
+		if(obj.isBooleanType()) {
+			boolean expect = obj.asBoolean();
+			boolean actual = pac.unpackBoolean();
+			assertEquals(expect, actual);
+
+		} else if(obj.isIntegerType()) {
+			BigInteger expect = obj.asBigInteger();
+			if(BigInteger.valueOf((long)Byte.MIN_VALUE).compareTo(expect) <= 0 &&
+					expect.compareTo(BigInteger.valueOf((long)Byte.MAX_VALUE)) <= 0) {
+				byte actual = pac.unpackByte();
+				assertEquals(expect.byteValue(), actual);
+			} else if(BigInteger.valueOf((long)Short.MIN_VALUE).compareTo(expect) <= 0 &&
+					expect.compareTo(BigInteger.valueOf((long)Short.MAX_VALUE)) <= 0) {
+				short actual = pac.unpackShort();
+				assertEquals(expect.shortValue(), actual);
+			} else if(BigInteger.valueOf((long)Integer.MIN_VALUE).compareTo(expect) <= 0 &&
+					expect.compareTo(BigInteger.valueOf((long)Integer.MAX_VALUE)) <= 0) {
+				int actual = pac.unpackInt();
+				assertEquals(expect.intValue(), actual);
+			} else if(BigInteger.valueOf(Long.MIN_VALUE).compareTo(expect) <= 0 &&
+					expect.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0) {
+				long actual = pac.unpackLong();
+				assertEquals(expect.longValue(), actual);
+			} else {
+				BigInteger actual = pac.unpackBigInteger();
+				assertEquals(expect, actual);
+			}
+
+		} else if(obj.isFloatType()) {
+			double expect = obj.asFloat();
+			double actual = pac.unpackDouble();
+			assertEquals(expect, actual, 0.01);
+
+		} else if(obj.isArrayType()) {
+			MessagePackObject[] expect = obj.asArray();
+			int length = pac.unpackArray();
+			assertEquals(expect.length, length);
+			for(int i=0; i < length; i++) {
+				testDirectConversionRecursive(pac, expect[i]);
+			}
+
+		} else if(obj.isMapType()) {
+			Map<MessagePackObject, MessagePackObject> expect = obj.asMap();
+			int size = pac.unpackMap();
+			assertEquals(expect.size(), size);
+			for(int i=0; i < size; i++) {
+				MessagePackObject key = pac.unpackObject();
+				MessagePackObject value = expect.get(key);
+				assertNotNull(value);
+				testDirectConversionRecursive(pac, value);
+			}
+
+		} else if(obj.isRawType()) {
+			byte[] expect = obj.asByteArray();
+			int length = pac.unpackRaw();
+			assertEquals(expect.length, length);
+			byte[] actual = pac.unpackRawBody(length);
+			assertTrue(Arrays.equals(expect, actual));
+
+		} else if(obj.isNil()) {
+			pac.unpackNull();
+
+		} else {
+			fail("unexpected object: "+obj);
+		}
+	}
+
+	@Test
+	public void testIndirectConversion() throws Exception {
+		Unpacker pac = new Unpacker();
+		Unpacker pac_compact = new Unpacker();
+
+		feedFile(pac, "src/test/resources/cases.mpac");
+		feedFile(pac_compact, "src/test/resources/cases_compact.mpac");
+
+		UnpackResult result = new UnpackResult();
+		UnpackResult result_compact = new UnpackResult();
+		while(pac.next(result)) {
+			assertTrue( pac_compact.next(result_compact) );
+			testIndirectConversionRecursive(result.getData(), result_compact.getData());
+		}
+
+		assertFalse( pac_compact.next(result) );
+	}
+
+	private void testIndirectConversionRecursive(MessagePackObject target, MessagePackObject obj) {
+		if(obj.isBooleanType()) {
+			boolean expect = obj.asBoolean();
+			boolean actual = target.asBoolean();
+			assertEquals(expect, actual);
+
+		} else if(obj.isIntegerType()) {
+			BigInteger expect = obj.asBigInteger();
+			if(BigInteger.valueOf((long)Byte.MIN_VALUE).compareTo(expect) <= 0 &&
+					expect.compareTo(BigInteger.valueOf((long)Byte.MAX_VALUE)) <= 0) {
+				byte actual = target.asByte();
+				assertEquals(expect.byteValue(), actual);
+			} else if(BigInteger.valueOf((long)Short.MIN_VALUE).compareTo(expect) <= 0 &&
+					expect.compareTo(BigInteger.valueOf((long)Short.MAX_VALUE)) <= 0) {
+				short actual = target.asShort();
+				assertEquals(expect.shortValue(), actual);
+			} else if(BigInteger.valueOf((long)Integer.MIN_VALUE).compareTo(expect) <= 0 &&
+					expect.compareTo(BigInteger.valueOf((long)Integer.MAX_VALUE)) <= 0) {
+				int actual = target.asInt();
+				assertEquals(expect.intValue(), actual);
+			} else if(BigInteger.valueOf(Long.MIN_VALUE).compareTo(expect) <= 0 &&
+					expect.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0) {
+				long actual = target.asLong();
+				assertEquals(expect.longValue(), actual);
+			} else {
+				BigInteger actual = target.asBigInteger();
+				assertEquals(expect, actual);
+			}
+
+		} else if(obj.isFloatType()) {
+			double expect = obj.asFloat();
+			double actual = target.asDouble();
+			assertEquals(expect, actual, 0.01);
+
+		} else if(obj.isArrayType()) {
+			MessagePackObject[] expect = obj.asArray();
+			MessagePackObject[] actual = target.asArray();
+			assertEquals(expect.length, actual.length);
+			for(int i=0; i < expect.length; i++) {
+				testIndirectConversionRecursive(actual[i], expect[i]);
+			}
+
+		} else if(obj.isMapType()) {
+			Map<MessagePackObject, MessagePackObject> expect = obj.asMap();
+			Map<MessagePackObject, MessagePackObject> actual = target.asMap();
+			assertEquals(expect.size(), actual.size());
+			for(Map.Entry<MessagePackObject,MessagePackObject> pair : expect.entrySet()) {
+				MessagePackObject value = actual.get(pair.getKey());
+				assertNotNull(value);
+				testIndirectConversionRecursive(value, pair.getValue());
+			}
+
+		} else if(obj.isRawType()) {
+			byte[] expect = obj.asByteArray();
+			byte[] actual = obj.asByteArray();
+			assertEquals(expect.length, actual.length);
+			assertTrue(Arrays.equals(expect, actual));
+
+		} else if(obj.isNil()) {
+			assertTrue(target.isNil());
+
+		} else {
+			fail("unexpected object: "+obj);
+		}
+	}
 };
 

From 4f3d9a1dedf3497133ec5dc7cdc7d2b2eae4bb59 Mon Sep 17 00:00:00 2001
From: Muga Nishizawa <muga.nishizawa@gmail.com>
Date: Fri, 8 Apr 2011 16:13:29 +0900
Subject: [PATCH 04/10] Refactored programs related to TemplateBuilder.java

---
 .../main/java/org/msgpack/MessagePack.java    |   5 -
 .../msgpack/MessagePackTemplateProvider.java  |   3 +-
 .../template/TemplateBuildException.java      |   2 +-
 ...=> AnnotationTemplateBuilderSelector.java} |  29 +-
 .../builder/ArrayTemplateBuilder.java         |  10 +-
 .../builder/ArrayTemplateBuilderSelector.java |   7 +-
 .../BeansBuildContext.java                    |  16 +-
 .../BeansTemplateBuilder.java}                |  22 +-
 ...java => BeansTemplateBuilderSelector.java} |  30 +-
 .../{javassist => builder}/BuildContext.java  |  16 +-
 .../BuildContextBase.java                     |  17 +-
 .../BuildContextFactory.java                  |   3 +-
 .../template/builder/BuilderSelector.java     |  19 +-
 .../builder/BuilderSelectorRegistry.java      |  27 +-
 .../builder/CustomTemplateBuilder.java        |   5 +-
 ....java => EnumTemplateBuilderSelector.java} |  13 +-
 .../JavassistTemplate.java                    |  27 +-
 .../JavassistTemplateBuilder.java             |   8 +-
 .../builder/OrdinalEnumTemplateBuilder.java   |   3 +-
 ...> OrdinalEnumTemplateBuilderSelector.java} |  24 +-
 .../ReflectionTemplateBuilder.java            |   8 +-
 .../template/builder/TemplateBuilder.java     | 389 +-----------------
 .../TemplatePrecompiler.java}                 |  11 +-
 ...ionTemplateBuilderJavaBeansPackUnpack.java |  12 +-
 ...tReflectionTemplateBuilderPackConvert.java |  12 +-
 ...stReflectionTemplateBuilderPackUnpack.java |  12 +-
 .../JavassistTypeScalaTemplateBuilder.scala   |   2 +-
 .../scala/org/msgpack/ScalaMessagePack.scala  |   7 +-
 .../ScalaTemplateBuilderSelector.scala        |   3 +-
 29 files changed, 126 insertions(+), 616 deletions(-)
 rename java/src/main/java/org/msgpack/template/builder/{MessagePackMessageBuilderSelector.java => AnnotationTemplateBuilderSelector.java} (68%)
 rename java/src/main/java/org/msgpack/template/{javassist => builder}/BeansBuildContext.java (95%)
 rename java/src/main/java/org/msgpack/template/{BeansReflectionTemplateBuilder.java => builder/BeansTemplateBuilder.java} (90%)
 rename java/src/main/java/org/msgpack/template/builder/{MessagePackBeansBuilderSelector.java => BeansTemplateBuilderSelector.java} (66%)
 rename java/src/main/java/org/msgpack/template/{javassist => builder}/BuildContext.java (95%)
 rename java/src/main/java/org/msgpack/template/{javassist => builder}/BuildContextBase.java (95%)
 rename java/src/main/java/org/msgpack/template/{javassist => builder}/BuildContextFactory.java (89%)
 rename java/src/main/java/org/msgpack/template/builder/{EnumBuilderSelector.java => EnumTemplateBuilderSelector.java} (93%)
 rename java/src/main/java/org/msgpack/template/{javassist => builder}/JavassistTemplate.java (57%)
 rename java/src/main/java/org/msgpack/template/{ => builder}/JavassistTemplateBuilder.java (96%)
 rename java/src/main/java/org/msgpack/template/builder/{MessagePackOrdinalEnumBuilderSelector.java => OrdinalEnumTemplateBuilderSelector.java} (71%)
 rename java/src/main/java/org/msgpack/template/{ => builder}/ReflectionTemplateBuilder.java (97%)
 rename java/src/main/java/org/msgpack/{template/TemplateClassWriter.java => util/TemplatePrecompiler.java} (89%)

diff --git a/java/src/main/java/org/msgpack/MessagePack.java b/java/src/main/java/org/msgpack/MessagePack.java
index a650b797..27cfc506 100644
--- a/java/src/main/java/org/msgpack/MessagePack.java
+++ b/java/src/main/java/org/msgpack/MessagePack.java
@@ -22,7 +22,6 @@ import java.io.InputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import org.msgpack.template.TemplateRegistry;
-import org.msgpack.template.TemplateClassWriter;
 import org.msgpack.template.FieldList;
 
 public class MessagePack {
@@ -146,10 +145,6 @@ public class MessagePack {
 		}
 	}
 
-	public static void write(Class<?> target, String directoryName) {
-		TemplateClassWriter.write(target, directoryName);
-	}
-
 	public static void register(Class<?> target) {
 		TemplateRegistry.register(target);
 	}
diff --git a/java/src/main/java/org/msgpack/MessagePackTemplateProvider.java b/java/src/main/java/org/msgpack/MessagePackTemplateProvider.java
index 511625b7..8f7515b6 100644
--- a/java/src/main/java/org/msgpack/MessagePackTemplateProvider.java
+++ b/java/src/main/java/org/msgpack/MessagePackTemplateProvider.java
@@ -1,7 +1,7 @@
 //
 // MessagePack for Java
 //
-// Copyright (C) 2009-2010 FURUHASHI Sadayuki
+// Copyright (C) 2009-2011 FURUHASHI Sadayuki
 //
 //    Licensed under the Apache License, Version 2.0 (the "License");
 //    you may not use this file except in compliance with the License.
@@ -18,6 +18,5 @@
 package org.msgpack;
 
 public interface MessagePackTemplateProvider {
-
 	Template getTemplate();
 }
diff --git a/java/src/main/java/org/msgpack/template/TemplateBuildException.java b/java/src/main/java/org/msgpack/template/TemplateBuildException.java
index c4c99566..f8560d1f 100644
--- a/java/src/main/java/org/msgpack/template/TemplateBuildException.java
+++ b/java/src/main/java/org/msgpack/template/TemplateBuildException.java
@@ -1,7 +1,7 @@
 //
 // MessagePack for Java
 //
-// Copyright (C) 2009-2010 FURUHASHI Sadayuki
+// Copyright (C) 2009-2011 FURUHASHI Sadayuki
 //
 //    Licensed under the Apache License, Version 2.0 (the "License");
 //    you may not use this file except in compliance with the License.
diff --git a/java/src/main/java/org/msgpack/template/builder/MessagePackMessageBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/AnnotationTemplateBuilderSelector.java
similarity index 68%
rename from java/src/main/java/org/msgpack/template/builder/MessagePackMessageBuilderSelector.java
rename to java/src/main/java/org/msgpack/template/builder/AnnotationTemplateBuilderSelector.java
index a4b3fe0c..10bf5e62 100644
--- a/java/src/main/java/org/msgpack/template/builder/MessagePackMessageBuilderSelector.java
+++ b/java/src/main/java/org/msgpack/template/builder/AnnotationTemplateBuilderSelector.java
@@ -22,34 +22,33 @@ import java.lang.reflect.Type;
 
 import org.msgpack.annotation.MessagePackMessage;
 
-public class MessagePackMessageBuilderSelector implements BuilderSelector{
-	
-	public static final String NAME = "MessagePackMessageTemplateBuilder";
-	
-	
+public class AnnotationTemplateBuilderSelector implements BuilderSelector{
+
+	public static final String NAME = "AnnotationTemplateBuilder";
+
     TemplateBuilder builder;
-	public MessagePackMessageBuilderSelector(TemplateBuilder builder){
+
+    public AnnotationTemplateBuilderSelector(TemplateBuilder builder){
 		this.builder = builder;
 	}
-	
-	public String getName(){
+
+    @Override
+    public String getName(){
 		return NAME;
 	}
-	
+
 	@Override
 	public boolean matchType(Type targetType) {
-		Class<?> target = (Class<?>)targetType;
-		return isAnnotated(target, MessagePackMessage.class);
+		Class<?> targetClass = (Class<?>)targetType;
+		return isAnnotated(targetClass, MessagePackMessage.class);
 	}
 
 	@Override
 	public TemplateBuilder getTemplateBuilder(Type targetType) {
 		return builder;
 	}
-	
 
-	private boolean isAnnotated(Class<?> ao, Class<? extends Annotation> with) {
-		return ao.getAnnotation(with) != null;
+	public static boolean isAnnotated(Class<?> targetClass, Class<? extends Annotation> with) {
+		return targetClass.getAnnotation(with) != null;
 	}
-
 }
diff --git a/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java
index 07e49dee..819a6e49 100644
--- a/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java
@@ -22,8 +22,6 @@ import java.lang.reflect.Array;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Map;
 
 import org.msgpack.AbstractTemplate;
 import org.msgpack.MessagePackObject;
@@ -34,17 +32,12 @@ import org.msgpack.Unpacker;
 import org.msgpack.template.BooleanArrayTemplate;
 import org.msgpack.template.DoubleArrayTemplate;
 import org.msgpack.template.FloatArrayTemplate;
-import org.msgpack.template.IFieldEntry;
-import org.msgpack.template.IFieldEntryReader;
 import org.msgpack.template.IntArrayTemplate;
 import org.msgpack.template.LongArrayTemplate;
 import org.msgpack.template.ShortArrayTemplate;
 import org.msgpack.template.TemplateRegistry;
 
-public class ArrayTemplateBuilder extends TemplateBuilder {
-
-
-
+public class ArrayTemplateBuilder implements TemplateBuilder {
 
 	static class ReflectionObjectArrayTemplate extends AbstractTemplate {
 		private Class<?> componentClass;
@@ -128,6 +121,7 @@ public class ArrayTemplateBuilder extends TemplateBuilder {
 			return array;
 		}
 	}
+
 	@Override
 	public Template buildTemplate(Type arrayType) {
 		Type baseType;
diff --git a/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilderSelector.java
index 66428bef..eeefd7ec 100644
--- a/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilderSelector.java
+++ b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilderSelector.java
@@ -20,18 +20,17 @@ package org.msgpack.template.builder;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.Type;
 
-import org.msgpack.Template;
-
 public class ArrayTemplateBuilderSelector implements BuilderSelector {
 
 	public static final String NAME = "ArrayTemplateBuilder";
 	
+	ArrayTemplateBuilder templateBuilder = new ArrayTemplateBuilder();
+
 	@Override
 	public String getName(){
 		return NAME;
 	}
 	
-	
 	@Override
 	public boolean matchType(Type targetType) {
 		if(targetType instanceof GenericArrayType){
@@ -41,8 +40,6 @@ public class ArrayTemplateBuilderSelector implements BuilderSelector {
 		return targetClass.isArray();
 	}
 	
-	ArrayTemplateBuilder templateBuilder = new ArrayTemplateBuilder();
-
 	@Override
 	public TemplateBuilder getTemplateBuilder(Type target) {
 		return templateBuilder;
diff --git a/java/src/main/java/org/msgpack/template/javassist/BeansBuildContext.java b/java/src/main/java/org/msgpack/template/builder/BeansBuildContext.java
similarity index 95%
rename from java/src/main/java/org/msgpack/template/javassist/BeansBuildContext.java
rename to java/src/main/java/org/msgpack/template/builder/BeansBuildContext.java
index 6b4fa265..574ce76e 100644
--- a/java/src/main/java/org/msgpack/template/javassist/BeansBuildContext.java
+++ b/java/src/main/java/org/msgpack/template/builder/BeansBuildContext.java
@@ -15,33 +15,19 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template.javassist;
+package org.msgpack.template.builder;
 
-import java.io.IOException;
-import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Type;
-import java.lang.Thread;
 
 import org.msgpack.*;
 import org.msgpack.template.*;
 
 import javassist.CannotCompileException;
-import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.CtConstructor;
-import javassist.CtMethod;
 import javassist.CtNewConstructor;
-import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
 import javassist.NotFoundException;
-import javassist.ClassClassPath;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
 
 public class BeansBuildContext extends BuildContextBase<BeansFieldEntry> {
 	protected BeansFieldEntry[] entries;
diff --git a/java/src/main/java/org/msgpack/template/BeansReflectionTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilder.java
similarity index 90%
rename from java/src/main/java/org/msgpack/template/BeansReflectionTemplateBuilder.java
rename to java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilder.java
index e97531f7..e5946dd7 100644
--- a/java/src/main/java/org/msgpack/template/BeansReflectionTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilder.java
@@ -15,10 +15,9 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template;
+package org.msgpack.template.builder;
 
 import java.io.IOException;
-import java.lang.reflect.Field;
 
 import org.msgpack.AbstractTemplate;
 import org.msgpack.MessagePackObject;
@@ -26,27 +25,22 @@ import org.msgpack.MessageTypeException;
 import org.msgpack.Packer;
 import org.msgpack.Template;
 import org.msgpack.Unpacker;
-import org.msgpack.template.ReflectionTemplateBuilder.BooleanFieldEntry;
-import org.msgpack.template.ReflectionTemplateBuilder.ByteFieldEntry;
-import org.msgpack.template.ReflectionTemplateBuilder.DoubleFieldEntry;
-import org.msgpack.template.ReflectionTemplateBuilder.FloatFieldEntry;
-import org.msgpack.template.ReflectionTemplateBuilder.IntFieldEntry;
-import org.msgpack.template.ReflectionTemplateBuilder.LongFieldEntry;
-import org.msgpack.template.ReflectionTemplateBuilder.NullFieldEntry;
-import org.msgpack.template.ReflectionTemplateBuilder.ObjectFieldEntry;
-import org.msgpack.template.ReflectionTemplateBuilder.ShortFieldEntry;
-import org.msgpack.template.builder.CustomTemplateBuilder;
+import org.msgpack.template.BeansFieldEntry;
+import org.msgpack.template.BeansFieldEntryReader;
+import org.msgpack.template.IFieldEntry;
+import org.msgpack.template.IFieldEntryReader;
+import org.msgpack.template.TemplateRegistry;
 
 /**
  * Class for building java reflection template builder for java beans class.
  * @author takeshita
  *
  */
-public class BeansReflectionTemplateBuilder extends CustomTemplateBuilder{
+public class BeansTemplateBuilder extends CustomTemplateBuilder{
 
 	IFieldEntryReader reader = new BeansFieldEntryReader();
 	
-	public BeansReflectionTemplateBuilder(){}
+	public BeansTemplateBuilder(){}
 
 	@Override
 	public IFieldEntryReader getFieldEntryReader(){
diff --git a/java/src/main/java/org/msgpack/template/builder/MessagePackBeansBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilderSelector.java
similarity index 66%
rename from java/src/main/java/org/msgpack/template/builder/MessagePackBeansBuilderSelector.java
rename to java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilderSelector.java
index bec4a4f5..b875c2f7 100644
--- a/java/src/main/java/org/msgpack/template/builder/MessagePackBeansBuilderSelector.java
+++ b/java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilderSelector.java
@@ -17,41 +17,33 @@
 //
 package org.msgpack.template.builder;
 
-import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
 import org.msgpack.annotation.MessagePackBeans;
-import org.msgpack.annotation.MessagePackMessage;
 
-public class MessagePackBeansBuilderSelector implements BuilderSelector{
-	
-	public static final String NAME = "MessagePackBeansTemplateBuilder";
-	
-	
+public class BeansTemplateBuilderSelector implements BuilderSelector{
+
+	public static final String NAME = "BeansTemplateBuilder";
+
     TemplateBuilder builder;
-	public MessagePackBeansBuilderSelector(TemplateBuilder builder){
+
+    public BeansTemplateBuilderSelector(TemplateBuilder builder){
 		this.builder = builder;
 	}
-	
-	
+
+    @Override
 	public String getName(){
 		return NAME;
 	}
-	
+
 	@Override
 	public boolean matchType(Type targetType) {
-		Class<?> target = (Class<?>)targetType;
-		return isAnnotated(target, MessagePackBeans.class);
+		Class<?> targetClass = (Class<?>)targetType;
+		return AnnotationTemplateBuilderSelector.isAnnotated(targetClass, MessagePackBeans.class);
 	}
 
 	@Override
 	public TemplateBuilder getTemplateBuilder(Type targetType) {
 		return builder;
 	}
-	
-
-	private boolean isAnnotated(Class<?> ao, Class<? extends Annotation> with) {
-		return ao.getAnnotation(with) != null;
-	}
-
 }
diff --git a/java/src/main/java/org/msgpack/template/javassist/BuildContext.java b/java/src/main/java/org/msgpack/template/builder/BuildContext.java
similarity index 95%
rename from java/src/main/java/org/msgpack/template/javassist/BuildContext.java
rename to java/src/main/java/org/msgpack/template/builder/BuildContext.java
index a3ab97d9..ccb05f52 100644
--- a/java/src/main/java/org/msgpack/template/javassist/BuildContext.java
+++ b/java/src/main/java/org/msgpack/template/builder/BuildContext.java
@@ -15,33 +15,19 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template.javassist;
+package org.msgpack.template.builder;
 
-import java.io.IOException;
-import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Type;
-import java.lang.Thread;
 
 import org.msgpack.*;
 import org.msgpack.template.*;
 
 import javassist.CannotCompileException;
-import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.CtConstructor;
-import javassist.CtMethod;
 import javassist.CtNewConstructor;
-import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
 import javassist.NotFoundException;
-import javassist.ClassClassPath;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
 
 public class BuildContext extends BuildContextBase<FieldEntry> {
 	protected IFieldEntry[] entries;
diff --git a/java/src/main/java/org/msgpack/template/javassist/BuildContextBase.java b/java/src/main/java/org/msgpack/template/builder/BuildContextBase.java
similarity index 95%
rename from java/src/main/java/org/msgpack/template/javassist/BuildContextBase.java
rename to java/src/main/java/org/msgpack/template/builder/BuildContextBase.java
index 1b2db02b..7253bfd4 100644
--- a/java/src/main/java/org/msgpack/template/javassist/BuildContextBase.java
+++ b/java/src/main/java/org/msgpack/template/builder/BuildContextBase.java
@@ -15,37 +15,26 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template.javassist;
+package org.msgpack.template.builder;
 
 import java.io.IOException;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Type;
-import java.lang.Thread;
 
 import org.msgpack.*;
 import org.msgpack.template.*;
 
 import javassist.CannotCompileException;
-import javassist.ClassPool;
 import javassist.CtClass;
-import javassist.CtConstructor;
 import javassist.CtMethod;
-import javassist.CtNewConstructor;
 import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
 import javassist.NotFoundException;
-import javassist.ClassClassPath;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 public abstract class BuildContextBase<T extends IFieldEntry> {
 	
 	private static Logger LOG = LoggerFactory.getLogger(JavassistTemplateBuilder.class);
-
 	
 	protected JavassistTemplateBuilder director;
 
@@ -70,10 +59,8 @@ public abstract class BuildContextBase<T extends IFieldEntry> {
 	public BuildContextBase(JavassistTemplateBuilder director) {
 		this.director = director;
 	}
-	
-	
-	public abstract Template buildTemplate(Class<?> targetClass, T[] entries, Template[] templates);
 
+	public abstract Template buildTemplate(Class<?> targetClass, T[] entries, Template[] templates);
 
 	protected Template build(final String className) {
 		try {
diff --git a/java/src/main/java/org/msgpack/template/javassist/BuildContextFactory.java b/java/src/main/java/org/msgpack/template/builder/BuildContextFactory.java
similarity index 89%
rename from java/src/main/java/org/msgpack/template/javassist/BuildContextFactory.java
rename to java/src/main/java/org/msgpack/template/builder/BuildContextFactory.java
index 1099482b..5974ef7f 100644
--- a/java/src/main/java/org/msgpack/template/javassist/BuildContextFactory.java
+++ b/java/src/main/java/org/msgpack/template/builder/BuildContextFactory.java
@@ -15,9 +15,8 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template.javassist;
+package org.msgpack.template.builder;
 
-import org.msgpack.template.JavassistTemplateBuilder;
 
 public interface BuildContextFactory {
 	
diff --git a/java/src/main/java/org/msgpack/template/builder/BuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/BuilderSelector.java
index 0691612e..8ca94b44 100644
--- a/java/src/main/java/org/msgpack/template/builder/BuilderSelector.java
+++ b/java/src/main/java/org/msgpack/template/builder/BuilderSelector.java
@@ -25,20 +25,9 @@ import java.lang.reflect.Type;
  *
  */
 public interface BuilderSelector {
-	
-	
-	/**
-	 * Name of this.
-	 * @return
-	 */
-	public String getName();
-	
-	
-	public abstract boolean matchType(Type targetType);
-	
-	
-	public abstract TemplateBuilder getTemplateBuilder(Type targetType);
-	
-	
+	String getName();
 
+	boolean matchType(Type targetType);
+
+	TemplateBuilder getTemplateBuilder(Type targetType);
 }
diff --git a/java/src/main/java/org/msgpack/template/builder/BuilderSelectorRegistry.java b/java/src/main/java/org/msgpack/template/builder/BuilderSelectorRegistry.java
index 02d365b8..f5d5a5be 100644
--- a/java/src/main/java/org/msgpack/template/builder/BuilderSelectorRegistry.java
+++ b/java/src/main/java/org/msgpack/template/builder/BuilderSelectorRegistry.java
@@ -22,13 +22,6 @@ import java.util.LinkedList;
 import java.util.List;
 
 import org.msgpack.template.BeansFieldEntryReader;
-import org.msgpack.template.BeansReflectionTemplateBuilder;
-import org.msgpack.template.JavassistTemplateBuilder;
-import org.msgpack.template.ReflectionTemplateBuilder;
-import org.msgpack.template.javassist.BeansBuildContext;
-import org.msgpack.template.javassist.BuildContext;
-import org.msgpack.template.javassist.BuildContextBase;
-import org.msgpack.template.javassist.BuildContextFactory;
 
 /**
  * Registry for BuilderSelectors.
@@ -38,8 +31,9 @@ import org.msgpack.template.javassist.BuildContextFactory;
  *
  */
 public class BuilderSelectorRegistry {
-	
+
 	private static BuilderSelectorRegistry instance = new BuilderSelectorRegistry();
+
 	static{
 		initForJava();
 	}
@@ -50,26 +44,25 @@ public class BuilderSelectorRegistry {
 	
 	TemplateBuilder forceBuilder;
 	
-	
     List<BuilderSelector> builderSelectors = new LinkedList<BuilderSelector>();
 
 	private BuilderSelectorRegistry(){
 	}
+
 	/**
 	 * initialize BuilderSelectors for basic java enviroment.
 	 */
 	private static void initForJava(){
-
 		instance.append(new ArrayTemplateBuilderSelector());
 		
 		if(isSupportJavassist()){
 			instance.append(
-					new MessagePackMessageBuilderSelector(
+					new AnnotationTemplateBuilderSelector(
 							new JavassistTemplateBuilder()));
 			instance.forceBuilder = new JavassistTemplateBuilder();
 
 			//Java beans
-			instance.append(new MessagePackBeansBuilderSelector(
+			instance.append(new BeansTemplateBuilderSelector(
 					new JavassistTemplateBuilder(
 							new BeansFieldEntryReader(),
 							new BuildContextFactory() {
@@ -81,17 +74,17 @@ public class BuilderSelectorRegistry {
 					)));
 		}else{
 			instance.append(
-					new MessagePackMessageBuilderSelector(
+					new AnnotationTemplateBuilderSelector(
 							new ReflectionTemplateBuilder()));
 			instance.forceBuilder = new ReflectionTemplateBuilder();
 			
 			//Java beans
-			instance.append(new MessagePackBeansBuilderSelector(
-					new BeansReflectionTemplateBuilder()));
+			instance.append(new BeansTemplateBuilderSelector(
+					new BeansTemplateBuilder()));
 		}
 		
-		instance.append(new MessagePackOrdinalEnumBuilderSelector());
-		instance.append(new EnumBuilderSelector());
+		instance.append(new OrdinalEnumTemplateBuilderSelector());
+		instance.append(new EnumTemplateBuilderSelector());
 	}
 	public static boolean isSupportJavassist(){
 		try {
diff --git a/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java
index a3875388..439371d7 100644
--- a/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java
@@ -25,14 +25,11 @@ import org.msgpack.template.FieldOption;
 import org.msgpack.template.IFieldEntry;
 import org.msgpack.template.IFieldEntryReader;
 import org.msgpack.template.TemplateBuildException;
-import org.msgpack.template.javassist.BuildContextFactory;
-
-public abstract class CustomTemplateBuilder extends TemplateBuilder {
 
+public abstract class CustomTemplateBuilder implements TemplateBuilder {
 
 	public abstract IFieldEntryReader getFieldEntryReader();
 
-	
 	public abstract Template buildTemplate(Class<?> targetClass , IFieldEntry[] entries);
 	
 	public Template buildTemplate(Class<?> targetClass ,FieldOption implicitOption ){
diff --git a/java/src/main/java/org/msgpack/template/builder/EnumBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/EnumTemplateBuilderSelector.java
similarity index 93%
rename from java/src/main/java/org/msgpack/template/builder/EnumBuilderSelector.java
rename to java/src/main/java/org/msgpack/template/builder/EnumTemplateBuilderSelector.java
index 959aa9ec..816a2faf 100644
--- a/java/src/main/java/org/msgpack/template/builder/EnumBuilderSelector.java
+++ b/java/src/main/java/org/msgpack/template/builder/EnumTemplateBuilderSelector.java
@@ -19,25 +19,24 @@ package org.msgpack.template.builder;
 
 import java.lang.reflect.Type;
 
-public class EnumBuilderSelector implements BuilderSelector {
+public class EnumTemplateBuilderSelector implements BuilderSelector {
 
 	public static final String NAME = "EnumTemplateBuilder";
-	
+
+	OrdinalEnumTemplateBuilder builder = new OrdinalEnumTemplateBuilder();
+
+	@Override
 	public String getName(){
 		return NAME;
 	}
-	
+
 	@Override
 	public boolean matchType(Type targetType) {
 		return ((Class<?>)targetType).isEnum();
 	}
 
-
-	OrdinalEnumTemplateBuilder builder = new OrdinalEnumTemplateBuilder();
-
 	@Override
 	public TemplateBuilder getTemplateBuilder(Type targetType) {
 		return builder;
 	}
-
 }
diff --git a/java/src/main/java/org/msgpack/template/javassist/JavassistTemplate.java b/java/src/main/java/org/msgpack/template/builder/JavassistTemplate.java
similarity index 57%
rename from java/src/main/java/org/msgpack/template/javassist/JavassistTemplate.java
rename to java/src/main/java/org/msgpack/template/builder/JavassistTemplate.java
index c3feabe2..84b8cc1b 100644
--- a/java/src/main/java/org/msgpack/template/javassist/JavassistTemplate.java
+++ b/java/src/main/java/org/msgpack/template/builder/JavassistTemplate.java
@@ -15,31 +15,10 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template.javassist;
+package org.msgpack.template.builder;
 
-import java.io.IOException;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Type;
-import java.lang.Thread;
-
-import org.msgpack.*;
-import org.msgpack.template.*;
-
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtConstructor;
-import javassist.CtMethod;
-import javassist.CtNewConstructor;
-import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
-import javassist.NotFoundException;
-import javassist.ClassClassPath;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.msgpack.AbstractTemplate;
+import org.msgpack.Template;
 
 public abstract class JavassistTemplate extends AbstractTemplate {
 	public Class<?> targetClass;
diff --git a/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java
similarity index 96%
rename from java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java
rename to java/src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java
index 7366c653..a001bf45 100644
--- a/java/src/main/java/org/msgpack/template/JavassistTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java
@@ -15,7 +15,7 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template;
+package org.msgpack.template.builder;
 
 import java.lang.Thread;
 
@@ -28,8 +28,10 @@ import javassist.NotFoundException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.msgpack.template.builder.CustomTemplateBuilder;
-import org.msgpack.template.javassist.*;
+import org.msgpack.template.FieldEntryReader;
+import org.msgpack.template.IFieldEntry;
+import org.msgpack.template.IFieldEntryReader;
+import org.msgpack.template.TemplateRegistry;
 
 public class JavassistTemplateBuilder extends CustomTemplateBuilder {
 	private static Logger LOG = LoggerFactory.getLogger(JavassistTemplateBuilder.class);
diff --git a/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java
index d368984e..471defd4 100644
--- a/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java
@@ -30,7 +30,7 @@ import org.msgpack.Template;
 import org.msgpack.Unpacker;
 import org.msgpack.template.TemplateBuildException;
 
-public class OrdinalEnumTemplateBuilder extends TemplateBuilder{
+public class OrdinalEnumTemplateBuilder implements TemplateBuilder{
 
 	static class ReflectionOrdinalEnumTemplate extends AbstractTemplate {
 		protected Enum<?>[] entries;
@@ -68,6 +68,7 @@ public class OrdinalEnumTemplateBuilder extends TemplateBuilder{
 			return entries[ord];
 		}
 	}
+
 	@Override
 	public Template buildTemplate(Type targetType) {
 		Class<?> targetClass = (Class<?>)targetType;
diff --git a/java/src/main/java/org/msgpack/template/builder/MessagePackOrdinalEnumBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilderSelector.java
similarity index 71%
rename from java/src/main/java/org/msgpack/template/builder/MessagePackOrdinalEnumBuilderSelector.java
rename to java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilderSelector.java
index 93f0f71d..6e612097 100644
--- a/java/src/main/java/org/msgpack/template/builder/MessagePackOrdinalEnumBuilderSelector.java
+++ b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilderSelector.java
@@ -17,35 +17,29 @@
 //
 package org.msgpack.template.builder;
 
-import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
 import org.msgpack.annotation.MessagePackOrdinalEnum;
 
-public class MessagePackOrdinalEnumBuilderSelector implements BuilderSelector {
+public class OrdinalEnumTemplateBuilderSelector implements BuilderSelector {
 
-	public static final String NAME = "MessagePackOrdinalEnumBuilderTemplate";
-	
+	public static final String NAME = "OrdinalEnumBuilder";
+
+	OrdinalEnumTemplateBuilder builder = new OrdinalEnumTemplateBuilder();
+
+	@Override
 	public String getName(){
 		return NAME;
 	}
-	
+
 	@Override
 	public boolean matchType(Type targetType) {
-		Class<?> target = (Class<?>)targetType;
-		return isAnnotated(target, MessagePackOrdinalEnum.class);
+		Class<?> targetClass = (Class<?>)targetType;
+		return AnnotationTemplateBuilderSelector.isAnnotated(targetClass, MessagePackOrdinalEnum.class);
 	}
-	
-	OrdinalEnumTemplateBuilder builder = new OrdinalEnumTemplateBuilder();
 
 	@Override
 	public TemplateBuilder getTemplateBuilder(Type targetType) {
 		return builder;
 	}
-	
-
-	private boolean isAnnotated(Class<?> ao, Class<? extends Annotation> with) {
-		return ao.getAnnotation(with) != null;
-	}
-
 }
diff --git a/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java
similarity index 97%
rename from java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java
rename to java/src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java
index 057d500c..30bdda38 100644
--- a/java/src/main/java/org/msgpack/template/ReflectionTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java
@@ -15,14 +15,18 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template;
+package org.msgpack.template.builder;
 
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 
 import org.msgpack.*;
-import org.msgpack.template.builder.CustomTemplateBuilder;
+import org.msgpack.template.FieldEntry;
+import org.msgpack.template.FieldEntryReader;
+import org.msgpack.template.IFieldEntry;
+import org.msgpack.template.IFieldEntryReader;
+import org.msgpack.template.TemplateRegistry;
 
 public class ReflectionTemplateBuilder extends CustomTemplateBuilder {
 	IFieldEntryReader reader = new FieldEntryReader();
diff --git a/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java
index 3e04a1fa..7c2533a1 100644
--- a/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java
@@ -17,392 +17,11 @@
 //
 package org.msgpack.template.builder;
 
-import java.io.IOException;
-import java.lang.reflect.*;
-import java.lang.annotation.*;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.EnumSet;
-import org.msgpack.*;
-import org.msgpack.annotation.*;
-import org.msgpack.template.FieldList;
-import org.msgpack.template.FieldOption;
-import org.msgpack.template.IFieldEntry;
-import org.msgpack.template.IFieldEntryReader;
-import org.msgpack.template.JavassistTemplateBuilder;
-import org.msgpack.template.ReflectionTemplateBuilder;
+import java.lang.reflect.Type;
 
-public abstract class TemplateBuilder {
+import org.msgpack.Template;
 
-	public abstract Template buildTemplate(Type targetType);
-	/*
-	// Override this method
-<<<<<<< HEAD:java/src/main/java/org/msgpack/template/TemplateBuilder.java
-	public abstract Class<?> loadTemplateClass(Class<?> targetClass);
-
-	// Override this method
-	public abstract Template initializeTemplate(Class<?> targetClass, Class<?> tmplClass, FieldEntry[] entries);
-
-	// Override this method
-	public abstract void writeTemplateClass(Class<?> targetClass, FieldEntry[] entries, String directoryName);
-
-	// Override this method
-	public abstract Template buildTemplate(Class<?> targetClass, FieldEntry[] entries);
-=======
-	public abstract Template buildTemplate(Class<?> targetClass, IFieldEntry[] entries);
->>>>>>> 21f0d0bfc47ddc6d9092621705047f3bef385ba5:java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java
-
-	// Override this method
-	public abstract void writeOrdinalEnumTemplateClass(Class<?> targetClass, Enum<?>[] entires, String directoryName);
-
-	// Override this method
-	public abstract Template buildOrdinalEnumTemplate(Class<?> targetClass, Enum<?>[] entries);
-
-	// Override this method
-	public abstract void writeArrayTemplateClass(Type arrayType, Type genericBaseType,
-			Class<?> baseClass, int dim, String directoryName);
-
-	// Override this method
-	public abstract Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class<?> baseClass, int dim);
-<<<<<<< HEAD:java/src/main/java/org/msgpack/template/TemplateBuilder.java
-
-	public Template initializeTemplate(Class<?> targetClass, Class<?> tmplClass) {
-		return initializeTemplate(targetClass, tmplClass, readFieldEntries(targetClass, readImplicitFieldOption(targetClass)));
-	}
-
-	public void writeTemplateClass(Class<?> targetClass, FieldList fList, String directoryName) throws NoSuchFieldException {
-		checkValidation(targetClass);
-		writeTemplateClass(targetClass, convertFieldEntries(targetClass, fList), directoryName);
-	}
-=======
-    
-	public abstract IFieldEntryReader getFieldEntryReader();
->>>>>>> 21f0d0bfc47ddc6d9092621705047f3bef385ba5:java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java
-
-	public Template buildTemplate(Class<?> targetClass, FieldList flist) throws NoSuchFieldException {
-		checkValidation(targetClass);
-		return buildTemplate(targetClass, getFieldEntryReader().convertFieldEntries(targetClass, flist));
-	}
-
-	public void writeTemplateClass(Class<?> targetClass, FieldOption implicitOption, String directoryName) {
-		checkValidation(targetClass);
-		writeTemplateClass(targetClass, readFieldEntries(targetClass, implicitOption), directoryName);
-	}
-
-	public Template buildTemplate(Class<?> targetClass, FieldOption implicitOption) {
-		checkValidation(targetClass);
-		return buildTemplate(targetClass, getFieldEntryReader().readFieldEntries(targetClass, implicitOption));
-	}
-
-	public void writeTemplateClass(Class<?> targetClass, final String directoryName) {
-		FieldOption implicitOption = readImplicitFieldOption(targetClass);
-		writeTemplateClass(targetClass, implicitOption, directoryName);
-	}
-
-	public Template buildTemplate(Class<?> targetClass) {
-		FieldOption implicitOption = getFieldEntryReader().readImplicitFieldOption(targetClass);
-		return buildTemplate(targetClass, implicitOption);
-	}
-
-	public void writeOrdinalEnumTemplateClass(Class<?> targetClass, String directoryName) {
-		checkOrdinalEnumValidation(targetClass);
-		Enum<?>[] entries = (Enum<?>[])targetClass.getEnumConstants();
-		writeOrdinalEnumTemplateClass(targetClass, entries, directoryName);
-	}
-
-	public Template buildOrdinalEnumTemplate(Class<?> targetClass) {
-		checkOrdinalEnumValidation(targetClass);
-		Enum<?>[] entries = (Enum<?>[])targetClass.getEnumConstants();
-		return buildOrdinalEnumTemplate(targetClass, entries);
-	}
-
-	public void writeArrayTemplateClass(Type arrayType, String directoryName) {
-		throw new UnsupportedOperationException("not supported yet.");// TODO
-	}
-
-	public Template buildArrayTemplate(Type arrayType) {
-		Type baseType;
-		Class<?> baseClass;
-		int dim = 1;
-		if(arrayType instanceof GenericArrayType) {
-			GenericArrayType type = (GenericArrayType)arrayType;
-			baseType = type.getGenericComponentType();
-			while(baseType instanceof GenericArrayType) {
-				baseType = ((GenericArrayType)baseType).getGenericComponentType();
-				dim += 1;
-			}
-			if(baseType instanceof ParameterizedType) {
-				baseClass = (Class<?>)((ParameterizedType)baseType).getRawType();
-			} else {
-				baseClass = (Class<?>)baseType;
-			}
-		} else {
-			Class<?> type = (Class<?>)arrayType;
-			baseClass = type.getComponentType();
-			while(baseClass.isArray()) {
-				baseClass = baseClass.getComponentType();
-				dim += 1;
-			}
-			baseType = baseClass;
-		}
-		return buildArrayTemplate(arrayType, baseType, baseClass, dim);
-	}
-
-	private static Type getComponentType(Type arrayType) {
-		if(arrayType instanceof GenericArrayType) {
-			return ((GenericArrayType)arrayType).getGenericComponentType();
-		} else {
-			return ((Class<?>)arrayType).getComponentType();
-		}
-	}
-	private void checkValidation(Class<?> targetClass) {
-		if(targetClass.isInterface()) {
-			throw new TemplateBuildException("cannot build template of interface");
-		}
-		if(targetClass.isArray()) {
-			throw new TemplateBuildException("cannot build template of array class");
-		}
-		if(targetClass.isPrimitive()) {
-			throw new TemplateBuildException("cannot build template of primitive type");
-		}
-	}
-	private void checkOrdinalEnumValidation(Class<?> targetClass) {
-		if(!targetClass.isEnum()) {
-			throw new TemplateBuildException("tried to build ordinal enum template of non-enum class");
-		}
-	}
-
-    
-	private static TemplateBuilder instance;
-	static {
-		instance = selectDefaultTemplateBuilder();
-	}
-
-	private static TemplateBuilder selectDefaultTemplateBuilder() {
-		try {
-			// FIXME JavassistTemplateBuilder doesn't work on DalvikVM
-			if(System.getProperty("java.vm.name").equals("Dalvik")) {
-				return ReflectionTemplateBuilder.getInstance();
-			}
-		} catch (Exception e) {
-		}
-		return JavassistTemplateBuilder.getInstance();
-	}
-
-	public synchronized static void setInstance(TemplateBuilder builder) {
-		instance = builder;
-	}
-
-	public static Class<?> load(Class<?> targetClass) {
-		return instance.loadTemplateClass(targetClass);
-	}
-
-	public static Template initialize(Class<?> targetClass, Class<?> tmplClass) {
-		return instance.initializeTemplate(targetClass, tmplClass);
-	}
-
-	public static void writeClass(Class<?> targetClass, String directoryName) {
-		instance.writeTemplateClass(targetClass, directoryName);
-	}
-
-	public static Template build(Class<?> targetClass) {
-		return instance.buildTemplate(targetClass);
-	}
-
-	public static void writeClass(Class<?> targetClass, FieldOption implicitOption, String directoryName) {
-		instance.writeTemplateClass(targetClass, implicitOption, directoryName);
-	}
-
-	public static Template build(Class<?> targetClass, FieldOption implicitOption) {
-		return instance.buildTemplate(targetClass, implicitOption);
-	}
-
-	public static void writeClass(Class<?> targetClass, FieldList fList, String directoryName)
-			throws NoSuchFieldException {
-		instance.writeTemplateClass(targetClass, fList, directoryName);
-	}
-
-	public static Template build(Class<?> targetClass, FieldList fList) throws NoSuchFieldException {
-		return instance.buildTemplate(targetClass, fList);
-	}
-
-	public static void writeOrdinalEnumClass(Class<?> targetClass, String directoryName) {
-		instance.writeOrdinalEnumTemplateClass(targetClass, directoryName);
-	}
-
-	public static Template buildOrdinalEnum(Class<?> targetClass) {
-		return instance.buildOrdinalEnumTemplate(targetClass);
-	}
-
-	public static void writeArrayClass(Type arrayType, String directoryName) {
-		throw new UnsupportedOperationException("not supported yet.");// TODO
-	}
-
-	public static Template buildArray(Type arrayType) {
-		return instance.buildArrayTemplate(arrayType);
-	}*/
-
-    /*
-	private static void checkValidation(Class<?> targetClass) {
-		if(targetClass.isInterface()) {
-			throw new TemplateBuildException("cannot build template of interface");
-		}
-		if(targetClass.isArray()) {
-			throw new TemplateBuildException("cannot build template of array class");
-		}
-		if(targetClass.isPrimitive()) {
-			throw new TemplateBuildException("cannot build template of primitive type");
-		}
-	}
-
-	private static void checkOrdinalEnumValidation(Class<?> targetClass) {
-		if(!targetClass.isEnum()) {
-			throw new TemplateBuildException("tried to build ordinal enum template of non-enum class");
-		}
-	}*/
-
-    /*
-	static IFieldEntry[] convertFieldEntries(Class<?> targetClass, FieldList flist) throws NoSuchFieldException {
-		List<FieldList.Entry> src = flist.getList();
-		FieldEntry[] result = new FieldEntry[src.size()];
-		for(int i=0; i < src.size(); i++) {
-			FieldList.Entry s = src.get(i);
-			if(s.isAvailable()) {
-				result[i] = new FieldEntry(targetClass.getDeclaredField(s.getName()), s.getOption());
-			} else {
-				result[i] = new FieldEntry();
-			}
-		}
-		return result;
-	}*/
-    
-	/*static IFieldEntry[] readFieldEntries(Class<?> targetClass, FieldOption implicitOption) {
-		Field[] allFields = readAllFields(targetClass);
-
-		/* index:
-		 *   @Index(0) int field_a;   // 0
-		 *             int field_b;   // 1
-		 *   @Index(3) int field_c;   // 3
-		 *             int field_d;   // 4
-		 *   @Index(2) int field_e;   // 2
-		 *             int field_f;   // 5
-		 *//*
-		List<FieldEntry> indexed = new ArrayList<FieldEntry>();
-		int maxIndex = -1;
-		for(Field f : allFields) {
-			FieldOption opt = readFieldOption(f, implicitOption);
-			if(opt == FieldOption.IGNORE) {
-				// skip
-				continue;
-			}
-
-			int index = readFieldIndex(f, maxIndex);
-
-			if(indexed.size() > index && indexed.get(index) != null) {
-				throw new TemplateBuildException("duplicated index: "+index);
-			}
-			if(index < 0) {
-				throw new TemplateBuildException("invalid index: "+index);
-			}
-
-			while(indexed.size() <= index) {
-				indexed.add(null);
-			}
-			indexed.set(index, new FieldEntry(f, opt));
-
-			if(maxIndex < index) {
-				maxIndex = index;
-			}
-		}
-
-		FieldEntry[] result = new FieldEntry[maxIndex+1];
-		for(int i=0; i < indexed.size(); i++) {
-			FieldEntry e = indexed.get(i);
-			if(e == null) {
-				result[i] = new FieldEntry();
-			} else {
-				result[i] = e;
-			}
-		}
-
-		return result;
-	}*/
-    /* 
-	private static Field[] readAllFields(Class<?> targetClass) {
-		// order: [fields of super class, ..., fields of this class]
-		List<Field[]> succ = new ArrayList<Field[]>();
-		int total = 0;
-		for(Class<?> c = targetClass; c != Object.class; c = c.getSuperclass()) {
-			Field[] fields = c.getDeclaredFields();
-			total += fields.length;
-			succ.add(fields);
-		}
-		Field[] result = new Field[total];
-		int off = 0;
-		for(int i=succ.size()-1; i >= 0; i--) {
-			Field[] fields = succ.get(i);
-			System.arraycopy(fields, 0, result, off, fields.length);
-			off += fields.length;
-		}
-		return result;
-	}
-
-	private static FieldOption readImplicitFieldOption(Class<?> targetClass) {
-		MessagePackMessage a = targetClass.getAnnotation(MessagePackMessage.class);
-		if(a == null) {
-			return FieldOption.DEFAULT;
-		}
-		return a.value();
-	}
-
-	private static FieldOption readFieldOption(Field field, FieldOption implicitOption) {
-		int mod = field.getModifiers();
-		if(Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
-			return FieldOption.IGNORE;
-		}
-
-		if(isAnnotated(field, Ignore.class)) {
-			return FieldOption.IGNORE;
-		} else if(isAnnotated(field, Required.class)) {
-			return FieldOption.REQUIRED;
-		} else if(isAnnotated(field, Optional.class)) {
-			return FieldOption.OPTIONAL;
-		} else if(isAnnotated(field, Nullable.class)) {
-			if(field.getDeclaringClass().isPrimitive()) {
-				return FieldOption.REQUIRED;
-			} else {
-				return FieldOption.NULLABLE;
-			}
-		}
-
-		if(implicitOption != FieldOption.DEFAULT) {
-			return implicitOption;
-		}
-
-		// default mode:
-		//   transient : Ignore
-		//   public    : Required
-		//   others    : Ignore
-		if(Modifier.isTransient(mod)) {
-			return FieldOption.IGNORE;
-		} else if(Modifier.isPublic(mod)) {
-			return FieldOption.REQUIRED;
-		} else {
-			return FieldOption.IGNORE;
-		}
-	}
-
-	private static int readFieldIndex(Field field, int maxIndex) {
-		Index a = field.getAnnotation(Index.class);
-		if(a == null) {
-			return maxIndex + 1;
-		} else {
-			return a.value();
-		}
-	}
-
-	private static boolean isAnnotated(AccessibleObject ao, Class<? extends Annotation> with) {
-		return ao.getAnnotation(with) != null;
-	}*/
+public interface TemplateBuilder {
+	Template buildTemplate(Type targetType);
 }
 
diff --git a/java/src/main/java/org/msgpack/template/TemplateClassWriter.java b/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
similarity index 89%
rename from java/src/main/java/org/msgpack/template/TemplateClassWriter.java
rename to java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
index 157c242b..8ca113b4 100644
--- a/java/src/main/java/org/msgpack/template/TemplateClassWriter.java
+++ b/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
@@ -15,13 +15,14 @@
 //    See the License for the specific language governing permissions and
 //    limitations under the License.
 //
-package org.msgpack.template;
+package org.msgpack.util;
 
+import org.msgpack.template.TemplateBuildException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class TemplateClassWriter {
-	private static final Logger LOG = LoggerFactory.getLogger(TemplateClassWriter.class);
+public class TemplatePrecompiler {
+	private static final Logger LOG = LoggerFactory.getLogger(TemplatePrecompiler.class);
 
 	public static void write(Class<?> target, String directoryName) {
 		if (target.isEnum()) {
@@ -36,7 +37,7 @@ public class TemplateClassWriter {
 
 	private String[] classNames;
 
-	private TemplateClassWriter() {
+	private TemplatePrecompiler() {
 	}
 
 	private void parseOpts(final String[] args) {// TODO
@@ -64,7 +65,7 @@ public class TemplateClassWriter {
 	}
 
 	public static void main(final String[] args) throws Exception {
-		TemplateClassWriter writer = new TemplateClassWriter();
+		TemplatePrecompiler writer = new TemplatePrecompiler();
 		writer.parseOpts(args);
 		writer.writeTemplateClasses();
 	}
diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java
index 951b401c..0bd6f71a 100644
--- a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java
+++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java
@@ -30,9 +30,11 @@ import org.msgpack.annotation.MessagePackMessage;
 import org.msgpack.annotation.MessagePackOrdinalEnum;
 import org.msgpack.annotation.Optional;
 import org.msgpack.template.TestTemplateBuilderPackConvert.SampleInterface;
+import org.msgpack.template.builder.BeansTemplateBuilder;
 import org.msgpack.template.builder.BuilderSelectorRegistry;
-import org.msgpack.template.builder.MessagePackBeansBuilderSelector;
-import org.msgpack.template.builder.MessagePackMessageBuilderSelector;
+import org.msgpack.template.builder.BeansTemplateBuilderSelector;
+import org.msgpack.template.builder.AnnotationTemplateBuilderSelector;
+import org.msgpack.template.builder.ReflectionTemplateBuilder;
 import org.msgpack.template.builder.TemplateBuilder;
 
 import org.junit.Assert;
@@ -46,11 +48,11 @@ public class TestReflectionTemplateBuilderJavaBeansPackUnpack extends TestCase {
 		BuilderSelectorRegistry instance = BuilderSelectorRegistry.getInstance();
 
 		instance.replace(
-				new MessagePackMessageBuilderSelector(
+				new AnnotationTemplateBuilderSelector(
 						new ReflectionTemplateBuilder()));
 		instance.setForceBuilder( new ReflectionTemplateBuilder());
-		instance.replace(new MessagePackBeansBuilderSelector(
-				new BeansReflectionTemplateBuilder()));
+		instance.replace(new BeansTemplateBuilderSelector(
+				new BeansTemplateBuilder()));
 		
 		MessagePack.register(PrimitiveTypeFieldsClass.class);
 		MessagePack.register(OptionalPrimitiveTypeFieldsClass.class);
diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java
index dcb039f7..93523228 100644
--- a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java
+++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java
@@ -24,9 +24,11 @@ import org.msgpack.Unpacker;
 import org.msgpack.annotation.MessagePackMessage;
 import org.msgpack.annotation.MessagePackOrdinalEnum;
 import org.msgpack.annotation.Optional;
+import org.msgpack.template.builder.BeansTemplateBuilder;
 import org.msgpack.template.builder.BuilderSelectorRegistry;
-import org.msgpack.template.builder.MessagePackBeansBuilderSelector;
-import org.msgpack.template.builder.MessagePackMessageBuilderSelector;
+import org.msgpack.template.builder.BeansTemplateBuilderSelector;
+import org.msgpack.template.builder.AnnotationTemplateBuilderSelector;
+import org.msgpack.template.builder.ReflectionTemplateBuilder;
 import org.msgpack.template.builder.TemplateBuilder;
 
 import junit.framework.Assert;
@@ -38,11 +40,11 @@ public class TestReflectionTemplateBuilderPackConvert extends TestCase {
 		BuilderSelectorRegistry instance = BuilderSelectorRegistry.getInstance();
 
 		instance.replace(
-				new MessagePackMessageBuilderSelector(
+				new AnnotationTemplateBuilderSelector(
 						new ReflectionTemplateBuilder()));
 		instance.setForceBuilder( new ReflectionTemplateBuilder());
-		instance.replace(new MessagePackBeansBuilderSelector(
-				new BeansReflectionTemplateBuilder()));
+		instance.replace(new BeansTemplateBuilderSelector(
+				new BeansTemplateBuilder()));
 		
 		MessagePack.register(PrimitiveTypeFieldsClass.class);
 		MessagePack.register(OptionalPrimitiveTypeFieldsClass.class);
diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java
index 6080df6e..64fc9785 100644
--- a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java
+++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java
@@ -25,9 +25,11 @@ import org.msgpack.annotation.MessagePackMessage;
 import org.msgpack.annotation.MessagePackOrdinalEnum;
 import org.msgpack.annotation.Optional;
 import org.msgpack.template.TestTemplateBuilderPackConvert.SampleInterface;
+import org.msgpack.template.builder.BeansTemplateBuilder;
 import org.msgpack.template.builder.BuilderSelectorRegistry;
-import org.msgpack.template.builder.MessagePackBeansBuilderSelector;
-import org.msgpack.template.builder.MessagePackMessageBuilderSelector;
+import org.msgpack.template.builder.BeansTemplateBuilderSelector;
+import org.msgpack.template.builder.AnnotationTemplateBuilderSelector;
+import org.msgpack.template.builder.ReflectionTemplateBuilder;
 import org.msgpack.template.builder.TemplateBuilder;
 
 import junit.framework.Assert;
@@ -41,11 +43,11 @@ public class TestReflectionTemplateBuilderPackUnpack extends TestCase {
 		BuilderSelectorRegistry instance = BuilderSelectorRegistry.getInstance();
 
 		instance.replace(
-				new MessagePackMessageBuilderSelector(
+				new AnnotationTemplateBuilderSelector(
 						new ReflectionTemplateBuilder()));
 		instance.setForceBuilder( new ReflectionTemplateBuilder());
-		instance.replace(new MessagePackBeansBuilderSelector(
-				new BeansReflectionTemplateBuilder()));
+		instance.replace(new BeansTemplateBuilderSelector(
+				new BeansTemplateBuilder()));
 		
 		
 		MessagePack.register(PrimitiveTypeFieldsClass.class);
diff --git a/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala b/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala
index 879bddea..784c9e93 100644
--- a/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala
+++ b/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala
@@ -7,7 +7,7 @@ import java.lang.Class
 import collection.immutable.{ListMap, TreeMap}
 import java.lang.reflect.{Type, Modifier, Method, Field}
 import java.lang.annotation.{Annotation => JavaAnnotation}
-import javassist.{JavassistTemplate, BuildContextBase, BuildContext}
+import builder.{JavassistTemplateBuilder, JavassistTemplate, BuildContextBase, BuildContext}
 import scala.collection.JavaConverters._
 ;
 /*
diff --git a/scala/src/main/scala/org/msgpack/ScalaMessagePack.scala b/scala/src/main/scala/org/msgpack/ScalaMessagePack.scala
index 45b6f5fc..89fb43c6 100644
--- a/scala/src/main/scala/org/msgpack/ScalaMessagePack.scala
+++ b/scala/src/main/scala/org/msgpack/ScalaMessagePack.scala
@@ -1,10 +1,9 @@
 package org.msgpack
 
 import template._
-import builder.{MessagePackMessageBuilderSelector, BuilderSelectorRegistry}
-import template.javassist.BuildContextFactory
+import builder.{AnnotationTemplateBuilderSelector, BuilderSelectorRegistry, BuildContextFactory}
 import collection.mutable.{MutableList, LinkedList}
-import collection.mutable.{Map => MMap,HashMap => MHashMap}
+import collection.mutable.{Map => MMap, HashMap => MHashMap}
 ;
 /*
  * Created by IntelliJ IDEA.
@@ -18,7 +17,7 @@ object ScalaMessagePack {
   {
     // for scala object
     BuilderSelectorRegistry.getInstance.insertBefore(
-      MessagePackMessageBuilderSelector.NAME,
+      AnnotationTemplateBuilderSelector.NAME,
       new ScalaTemplateBuilderSelector)
 
     // register scala's list classes
diff --git a/scala/src/main/scala/org/msgpack/ScalaTemplateBuilderSelector.scala b/scala/src/main/scala/org/msgpack/ScalaTemplateBuilderSelector.scala
index b8b7c122..ac236a56 100644
--- a/scala/src/main/scala/org/msgpack/ScalaTemplateBuilderSelector.scala
+++ b/scala/src/main/scala/org/msgpack/ScalaTemplateBuilderSelector.scala
@@ -3,8 +3,7 @@ package org.msgpack
 import annotation.MessagePackMessage
 import template.builder.BuilderSelector
 import java.lang.reflect.Type
-import template.javassist.BuildContextFactory
-import template.JavassistTemplateBuilder
+import template.builder.{JavassistTemplateBuilder, BuildContextFactory}
 import java.lang.annotation.{Annotation => JAnnotation}
 ;
 /*

From 43fc0a52a64c4678a2497c5e90d0872aa8c28782 Mon Sep 17 00:00:00 2001
From: Muga Nishizawa <muga.nishizawa@gmail.com>
Date: Fri, 8 Apr 2011 16:17:25 +0900
Subject: [PATCH 05/10] scala: added a new AUTHORS file and edited pom.xml

---
 scala/AUTHORS | 1 +
 scala/pom.xml | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 scala/AUTHORS

diff --git a/scala/AUTHORS b/scala/AUTHORS
new file mode 100644
index 00000000..ababacb0
--- /dev/null
+++ b/scala/AUTHORS
@@ -0,0 +1 @@
+FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>
diff --git a/scala/pom.xml b/scala/pom.xml
index 7ec8f3e9..c15f9480 100644
--- a/scala/pom.xml
+++ b/scala/pom.xml
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.msgpack</groupId>
   <artifactId>scala-msgpack</artifactId>
-  <version>0.0.1-SNAPSHOT</version>
+  <version>0.0.1-devel</version>
   <name>${project.artifactId}</name>
   <description>My wonderfull scala app</description>
   <inceptionYear>2010</inceptionYear>

From b96b62f2ac7edc98be9ab78085be9ee4ed8536ea Mon Sep 17 00:00:00 2001
From: Muga Nishizawa <muga.nishizawa@gmail.com>
Date: Fri, 8 Apr 2011 16:20:28 +0900
Subject: [PATCH 06/10] scala: deleted the AUTHORS file

---
 scala/AUTHORS | 1 -
 1 file changed, 1 deletion(-)
 delete mode 100644 scala/AUTHORS

diff --git a/scala/AUTHORS b/scala/AUTHORS
deleted file mode 100644
index ababacb0..00000000
--- a/scala/AUTHORS
+++ /dev/null
@@ -1 +0,0 @@
-FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>

From 58c0fe0f91c32db2d6f89b1a40d7d022da5e0b54 Mon Sep 17 00:00:00 2001
From: Muga Nishizawa <muga.nishizawa@gmail.com>
Date: Sat, 9 Apr 2011 21:10:15 +0900
Subject: [PATCH 07/10] java: Refactored template builders again

---
 .../java/org/msgpack/AbstractTemplate.java    |   5 +-
 java/src/main/java/org/msgpack/Template.java  |   5 +-
 .../msgpack/template/TemplateRegistry.java    |  72 +++--------
 .../builder/ArrayTemplateBuilder.java         |  10 ++
 .../template/builder/BeansBuildContext.java   |  12 +-
 .../builder/BeansTemplateBuilder.java         |   6 +-
 .../template/builder/BuildContext.java        |  20 ++-
 .../template/builder/BuildContextBase.java    |  70 +++++++++--
 .../builder/CustomTemplateBuilder.java        |  28 +++--
 .../template/builder/JavassistTemplate.java   |  31 -----
 .../builder/JavassistTemplateBuilder.java     | 115 ++++++++----------
 .../builder/OrdinalEnumTemplateBuilder.java   |  10 ++
 .../OrdinalEnumTemplateBuilderSelector.java   |   2 +-
 .../builder/ReflectionTemplateBuilder.java    |   8 +-
 .../template/builder/TemplateBuilder.java     |   4 +
 .../org/msgpack/util/TemplatePrecompiler.java |  64 +++++-----
 .../JavassistTypeScalaTemplateBuilder.scala   |  20 ++-
 17 files changed, 264 insertions(+), 218 deletions(-)
 delete mode 100644 java/src/main/java/org/msgpack/template/builder/JavassistTemplate.java

diff --git a/java/src/main/java/org/msgpack/AbstractTemplate.java b/java/src/main/java/org/msgpack/AbstractTemplate.java
index 7f8cb49f..429a4705 100644
--- a/java/src/main/java/org/msgpack/AbstractTemplate.java
+++ b/java/src/main/java/org/msgpack/AbstractTemplate.java
@@ -1,7 +1,7 @@
 //
 // MessagePack for Java
 //
-// Copyright (C) 2009-2010 FURUHASHI Sadayuki
+// Copyright (C) 2009-2011 FURUHASHI Sadayuki
 //
 //    Licensed under the Apache License, Version 2.0 (the "License");
 //    you may not use this file except in compliance with the License.
@@ -23,5 +23,4 @@ public abstract class AbstractTemplate implements Template {
 	public Object unpack(Unpacker pac, Object to) throws IOException, MessageTypeException {
 		return convert(pac.unpackObject(), to);
 	}
-}
-
+}
\ No newline at end of file
diff --git a/java/src/main/java/org/msgpack/Template.java b/java/src/main/java/org/msgpack/Template.java
index 19808afb..8cce999f 100644
--- a/java/src/main/java/org/msgpack/Template.java
+++ b/java/src/main/java/org/msgpack/Template.java
@@ -1,7 +1,7 @@
 //
 // MessagePack for Java
 //
-// Copyright (C) 2009-2010 FURUHASHI Sadayuki
+// Copyright (C) 2009-2011 FURUHASHI Sadayuki
 //
 //    Licensed under the Apache License, Version 2.0 (the "License");
 //    you may not use this file except in compliance with the License.
@@ -18,5 +18,4 @@
 package org.msgpack;
 
 public interface Template extends MessagePacker, MessageUnpacker, MessageConverter {
-}
-
+}
\ No newline at end of file
diff --git a/java/src/main/java/org/msgpack/template/TemplateRegistry.java b/java/src/main/java/org/msgpack/template/TemplateRegistry.java
index ef4d51f2..4c4f87b6 100644
--- a/java/src/main/java/org/msgpack/template/TemplateRegistry.java
+++ b/java/src/main/java/org/msgpack/template/TemplateRegistry.java
@@ -20,12 +20,7 @@ package org.msgpack.template;
 import java.util.Map;
 import java.util.HashMap;
 import java.lang.reflect.Type;
-import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.ParameterizedType;
-import java.lang.annotation.Annotation;
-import org.msgpack.annotation.MessagePackMessage;
-import org.msgpack.annotation.MessagePackDelegate;
-import org.msgpack.annotation.MessagePackOrdinalEnum;
 import org.msgpack.template.builder.BuilderSelectorRegistry;
 import org.msgpack.template.builder.CustomTemplateBuilder;
 import org.msgpack.template.builder.TemplateBuilder;
@@ -44,18 +39,13 @@ public class TemplateRegistry {
 		builderSelectorRegistry = BuilderSelectorRegistry.getInstance();
 	}
 
-	public static void register(Class<?> target) { // auto-detect
+	public static void register(Class<?> target) {
 		TemplateBuilder builder = builderSelectorRegistry.select(target);
 		if(builder != null){
 			register(target,builder.buildTemplate(target));
 		}else{
 			register(target,builderSelectorRegistry.getForceBuilder().buildTemplate(target));
 		}
-		/*if(target.isEnum()) {
-			register(target, TemplateBuilder.buildOrdinalEnum(target));
-		} else {
-			register(target, TemplateBuilder.build(target));
-		}*/
 	}
 
 	public static void register(Class<?> target, FieldOption implicitOption) {
@@ -63,7 +53,7 @@ public class TemplateRegistry {
 		if(builder != null && builder instanceof CustomTemplateBuilder){
 			register(target, ((CustomTemplateBuilder)builder).buildTemplate(target, implicitOption));
 		}else{
-			throw new TemplateBuildException("cannot build template with filed option");
+			throw new TemplateBuildException("Cannot build template with filed option");
 		}
 	}
 
@@ -72,7 +62,7 @@ public class TemplateRegistry {
 		if(builder != null && builder instanceof CustomTemplateBuilder){
 			register(target, ((CustomTemplateBuilder)builder).buildTemplate(target, flist));
 		}else{
-			throw new TemplateBuildException("cannot build template with filed list");
+			throw new TemplateBuildException("Cannot build template with filed list");
 		}
 	}
 
@@ -123,50 +113,21 @@ public class TemplateRegistry {
 			return tmpl;
 		}
 
-		/*if(targetType instanceof GenericArrayType) {
-			// GenericArrayType is not a Class<?>
-			tmpl = TemplateBuilder.buildArray(targetType);
-			register(targetType, tmpl);
-			return tmpl;
-		}
-
-		Class<?> target = (Class<?>)targetType;
-
-		Class<?> tmplClass = TemplateBuilder.load(target);
-		if (tmplClass != null) {
-			tmpl = TemplateBuilder.initialize(target, tmplClass);
-			register(target, tmpl);
-			return tmpl;
-		}
-
-		if(target.isArray()) {
-			// FIXME can't distinguish type-erased T<>[]?
-			tmpl = TemplateBuilder.buildArray(target);
-			register(target, tmpl);
-			return tmpl;
-		}
-
-		if(isAnnotated(target, MessagePackMessage.class)) {
-			tmpl = TemplateBuilder.build(target);
-			register(target, tmpl);
-			return tmpl;
-		} else if(isAnnotated(target, MessagePackDelegate.class)) {
-			// TODO DelegateTemplate
-			throw new UnsupportedOperationException("not supported yet. : " + target.getName());
-		} else if(isAnnotated(target, MessagePackOrdinalEnum.class)) {
-			tmpl = TemplateBuilder.buildOrdinalEnum(target);
-			register(target, tmpl);
-			return tmpl;
-		}*/
 		// find match TemplateBuilder
 		TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(targetType);
 		if(builder != null){
+			tmpl = builder.loadTemplate(targetType);
+			if (tmpl != null) {
+				return tmpl;
+			}
+
 			tmpl = builder.buildTemplate(targetType);
-			register(targetType,tmpl);
-			return tmpl;
+			if (tmpl != null) {
+				register(targetType, tmpl);
+				return tmpl;
+			}
 		}
-		
-		
+
 		Class<?> target = (Class<?>)targetType;
 
 		for(Class<?> i : target.getInterfaces()) {
@@ -212,7 +173,7 @@ public class TemplateRegistry {
 			}
 			return new DefaultTemplate((Class<?>)parameterizedType.getRawType(), parameterizedType);
 		} else {
-			throw new IllegalArgumentException("actual types of the generic type are erased: "+targetType);
+			throw new IllegalArgumentException("Actual types of the generic type are erased: "+targetType);
 		}
 	}
 
@@ -231,10 +192,5 @@ public class TemplateRegistry {
 
 		return gtmpl.build(tmpls);
 	}
-
-	private static boolean isAnnotated(Class<?> ao, Class<? extends Annotation> with) {
-		return ao.getAnnotation(with) != null;
-	}
-
 }
 
diff --git a/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java
index 819a6e49..24e277ac 100644
--- a/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/ArrayTemplateBuilder.java
@@ -151,6 +151,7 @@ public class ArrayTemplateBuilder implements TemplateBuilder {
 		return toTemplate(arrayType, baseType, baseClass, dim);
 	
 	}
+
 	private Template toTemplate(Type arrayType, Type genericBaseType, Class<?> baseClass, int dim) {
 		if(dim == 1) {
 			if(baseClass == boolean.class) {
@@ -181,4 +182,13 @@ public class ArrayTemplateBuilder implements TemplateBuilder {
 		}
 	}
 
+	@Override
+	public void writeTemplate(Type targetType, String directoryName) {
+		throw new UnsupportedOperationException(targetType.toString());
+	}
+
+	@Override
+	public Template loadTemplate(Type targetType) {
+		return null;
+	}
 }
diff --git a/java/src/main/java/org/msgpack/template/builder/BeansBuildContext.java b/java/src/main/java/org/msgpack/template/builder/BeansBuildContext.java
index 574ce76e..af88d3ff 100644
--- a/java/src/main/java/org/msgpack/template/builder/BeansBuildContext.java
+++ b/java/src/main/java/org/msgpack/template/builder/BeansBuildContext.java
@@ -50,7 +50,7 @@ public class BeansBuildContext extends BuildContextBase<BeansFieldEntry> {
 
 	protected void setSuperClass() throws CannotCompileException, NotFoundException {
 		this.tmplCtClass.setSuperclass(
-				director.getCtClass(JavassistTemplate.class.getName()));
+				director.getCtClass(JavassistTemplateBuilder.JavassistTemplate.class.getName()));
 	}
 
 	protected void buildConstructor() throws CannotCompileException, NotFoundException {
@@ -272,4 +272,14 @@ public class BeansBuildContext extends BuildContextBase<BeansFieldEntry> {
 		return getBuiltString();
 	}
 
+	@Override
+	public void writeTemplate(Class<?> targetClass, BeansFieldEntry[] entries,
+			Template[] templates, String directoryName) {
+		throw new UnsupportedOperationException(targetClass.getName());
+	}
+
+	@Override
+	public Template loadTemplate(Class<?> targetClass, BeansFieldEntry[] entries, Template[] templates) {
+		throw new UnsupportedOperationException(targetClass.getName());
+	}
 }
\ No newline at end of file
diff --git a/java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilder.java
index e5946dd7..57634660 100644
--- a/java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/BeansTemplateBuilder.java
@@ -18,6 +18,7 @@
 package org.msgpack.template.builder;
 
 import java.io.IOException;
+import java.lang.reflect.Type;
 
 import org.msgpack.AbstractTemplate;
 import org.msgpack.MessagePackObject;
@@ -299,7 +300,6 @@ public class BeansTemplateBuilder extends CustomTemplateBuilder{
 
 	@Override
 	public Template buildTemplate(Class<?> targetClass, IFieldEntry[] entries) {
-		
 		ReflectionEntry[] refEntries = new ReflectionEntry[entries.length];
 		for(int i = 0;i < entries.length;i++){
 			BeansFieldEntry e = (BeansFieldEntry)entries[i];
@@ -323,10 +323,6 @@ public class BeansTemplateBuilder extends CustomTemplateBuilder{
 				refEntries[i] = new ObjectFieldEntry(e, tmpl);
 			}
 		}
-		
-		
 		return new BeansReflectionTemplate(targetClass,refEntries);
 	}
-	
-	
 }
diff --git a/java/src/main/java/org/msgpack/template/builder/BuildContext.java b/java/src/main/java/org/msgpack/template/builder/BuildContext.java
index ccb05f52..ef843a96 100644
--- a/java/src/main/java/org/msgpack/template/builder/BuildContext.java
+++ b/java/src/main/java/org/msgpack/template/builder/BuildContext.java
@@ -50,7 +50,7 @@ public class BuildContext extends BuildContextBase<FieldEntry> {
 
 	protected void setSuperClass() throws CannotCompileException, NotFoundException {
 		this.tmplCtClass.setSuperclass(
-				director.getCtClass(JavassistTemplate.class.getName()));
+				director.getCtClass(JavassistTemplateBuilder.JavassistTemplate.class.getName()));
 	}
 
 	protected void buildConstructor() throws CannotCompileException, NotFoundException {
@@ -272,4 +272,22 @@ public class BuildContext extends BuildContextBase<FieldEntry> {
 		return getBuiltString();
 	}
 
+	@Override
+	public void writeTemplate(Class<?> targetClass, FieldEntry[] entries,
+			Template[] templates, String directoryName) {
+		this.entries = entries;
+		this.templates = templates;
+		this.origClass = targetClass;
+		this.origName = this.origClass.getName();
+		write(this.origName, directoryName);
+	}
+
+	@Override
+	public Template loadTemplate(Class<?> targetClass, FieldEntry[] entries, Template[] templates) {
+		this.entries = entries;
+		this.templates = templates;
+		this.origClass = targetClass;
+		this.origName = this.origClass.getName();
+		return load(this.origName);
+	}
 }
\ No newline at end of file
diff --git a/java/src/main/java/org/msgpack/template/builder/BuildContextBase.java b/java/src/main/java/org/msgpack/template/builder/BuildContextBase.java
index 7253bfd4..229f1c8c 100644
--- a/java/src/main/java/org/msgpack/template/builder/BuildContextBase.java
+++ b/java/src/main/java/org/msgpack/template/builder/BuildContextBase.java
@@ -42,6 +42,8 @@ public abstract class BuildContextBase<T extends IFieldEntry> {
 
 	protected CtClass tmplCtClass;
 
+	protected abstract Template buildTemplate(Class<?> targetClass, T[] entries, Template[] templates);
+
 	protected abstract void setSuperClass() throws CannotCompileException, NotFoundException;
 
 	protected abstract void buildConstructor() throws CannotCompileException, NotFoundException;
@@ -54,17 +56,21 @@ public abstract class BuildContextBase<T extends IFieldEntry> {
 
 	protected abstract String buildConvertMethodBody();
 
-	protected abstract Template buildInstance(Class<?> c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException;
+	protected abstract Template buildInstance(Class<?> c)
+			throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException;
+
+	protected abstract void writeTemplate(Class<?> targetClass, T[] entries,
+			Template[] templates, String directoryName);
+
+	protected abstract Template loadTemplate(Class<?> targetClass, T[] entries, Template[] templates);
 
 	public BuildContextBase(JavassistTemplateBuilder director) {
 		this.director = director;
 	}
 
-	public abstract Template buildTemplate(Class<?> targetClass, T[] entries, Template[] templates);
-
 	protected Template build(final String className) {
 		try {
-			reset(className);
+			reset(className, false);
 			buildClass();
 			buildConstructor();
 			buildMethodInit();
@@ -76,15 +82,20 @@ public abstract class BuildContextBase<T extends IFieldEntry> {
 			String code = getBuiltString();
 			if(code != null) {
 				LOG.error("builder: " + code, e);
-				throw new TemplateBuildException("cannot compile: " + code, e);
+				throw new TemplateBuildException("Cannot compile: " + code, e);
 			} else {
 				throw new TemplateBuildException(e);
 			}
 		}
 	}
 
-	protected void reset(String className) {
-		tmplName = className + "_$$_Template" + director.nextSeqId();
+	protected void reset(String className, boolean isWritten) {
+		String tmplName = null;
+		if (!isWritten) {
+			tmplName = className + "_$$_Template" + director.nextSeqId();
+		} else {
+			tmplName = className + "_$$_Template";
+		}
 		tmplCtClass = director.makeCtClass(tmplName);
 	}
 
@@ -151,6 +162,10 @@ public abstract class BuildContextBase<T extends IFieldEntry> {
 		return (Class<?>) tmplCtClass.toClass(null, null);
 	}
 
+	protected void saveClass(final String directoryName) throws CannotCompileException, IOException {
+		tmplCtClass.writeFile(directoryName);
+	}
+
 	protected StringBuilder stringBuilder = null;
 
 	protected void resetStringBuilder() {
@@ -171,7 +186,7 @@ public abstract class BuildContextBase<T extends IFieldEntry> {
 		}
 		return stringBuilder.toString();
 	}
-	
+
 	protected String primitivePackName(Class<?> type) {
 		if(type == boolean.class) {
 			return "packBoolean";
@@ -228,4 +243,43 @@ public abstract class BuildContextBase<T extends IFieldEntry> {
 		}
 		return null;
 	}
+
+	protected void write(final String className, final String directoryName) {
+		try {
+			reset(className, true);
+			buildClass();
+			buildConstructor();
+			buildMethodInit();
+			buildPackMethod();
+			buildUnpackMethod();
+			buildConvertMethod();
+			saveClass(directoryName);
+		} catch (Exception e) {
+			String code = getBuiltString();
+			if(code != null) {
+				LOG.error("builder: " + code, e);
+				throw new TemplateBuildException("Cannot compile: " + code, e);
+			} else {
+				throw new TemplateBuildException(e);
+			}
+		}
+	}
+
+	protected Template load(final String className) {
+		String tmplName = className + "_$$_Template";
+		try {
+			Class<?> tmplClass = getClass().getClassLoader().loadClass(tmplName);
+			return buildInstance(tmplClass);
+		} catch (ClassNotFoundException e) {
+			return null;
+		} catch (Exception e) {
+			String code = getBuiltString();
+			if(code != null) {
+				LOG.error("builder: " + code, e);
+				throw new TemplateBuildException("Cannot compile: " + code, e);
+			} else {
+				throw new TemplateBuildException(e);
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java
index 439371d7..8d97689f 100644
--- a/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/CustomTemplateBuilder.java
@@ -31,12 +31,13 @@ public abstract class CustomTemplateBuilder implements TemplateBuilder {
 	public abstract IFieldEntryReader getFieldEntryReader();
 
 	public abstract Template buildTemplate(Class<?> targetClass , IFieldEntry[] entries);
-	
-	public Template buildTemplate(Class<?> targetClass ,FieldOption implicitOption ){
+
+	public Template buildTemplate(Class<?> targetClass, FieldOption implicitOption ){
 		checkValidation(targetClass);
 		return buildTemplate(targetClass,
 				getFieldEntryReader().readFieldEntries(targetClass, implicitOption));
 	}
+
 	public Template buildTemplate(Class<?> targetClass, FieldList flist) throws NoSuchFieldException {
 		checkValidation(targetClass);
 		return buildTemplate(targetClass, getFieldEntryReader().convertFieldEntries(targetClass, flist));
@@ -48,20 +49,29 @@ public abstract class CustomTemplateBuilder implements TemplateBuilder {
 		IFieldEntryReader reader = getFieldEntryReader();
 		FieldOption implicitOption = reader.readImplicitFieldOption(targetClass);
 		checkValidation(targetClass);
-		
 		IFieldEntry[] entries = reader.readFieldEntries(targetClass, implicitOption);
-		
-		return buildTemplate(targetClass,entries);
+		return buildTemplate(targetClass, entries);
 	}
-	private void checkValidation(Class<?> targetClass) {
+
+	protected void checkValidation(Class<?> targetClass) {
 		if(targetClass.isInterface()) {
-			throw new TemplateBuildException("cannot build template of interface");
+			throw new TemplateBuildException("Cannot build template of interface");
 		}
 		if(targetClass.isArray()) {
-			throw new TemplateBuildException("cannot build template of array class");
+			throw new TemplateBuildException("Cannot build template of array class");
 		}
 		if(targetClass.isPrimitive()) {
-			throw new TemplateBuildException("cannot build template of primitive type");
+			throw new TemplateBuildException("Cannot build template of primitive type");
 		}
 	}
+
+	@Override
+	public void writeTemplate(Type targetType, String directoryName) {
+		throw new UnsupportedOperationException(targetType.toString());
+	}
+
+	@Override
+	public Template loadTemplate(Type targetType) {
+		return null;
+	}
 }
\ No newline at end of file
diff --git a/java/src/main/java/org/msgpack/template/builder/JavassistTemplate.java b/java/src/main/java/org/msgpack/template/builder/JavassistTemplate.java
deleted file mode 100644
index 84b8cc1b..00000000
--- a/java/src/main/java/org/msgpack/template/builder/JavassistTemplate.java
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// MessagePack for Java
-//
-// Copyright (C) 2009-2011 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 org.msgpack.AbstractTemplate;
-import org.msgpack.Template;
-
-public abstract class JavassistTemplate extends AbstractTemplate {
-	public Class<?> targetClass;
-	public Template[] templates;
-
-	public JavassistTemplate(Class<?> targetClass, Template[] templates) {
-		this.targetClass = targetClass;
-		this.templates = templates;
-	}
-}
\ No newline at end of file
diff --git a/java/src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java
index a001bf45..f174f03d 100644
--- a/java/src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java
@@ -18,6 +18,7 @@
 package org.msgpack.template.builder;
 
 import java.lang.Thread;
+import java.lang.reflect.Type;
 
 import org.msgpack.*;
 
@@ -29,11 +30,22 @@ import javassist.NotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.msgpack.template.FieldEntryReader;
+import org.msgpack.template.FieldOption;
 import org.msgpack.template.IFieldEntry;
 import org.msgpack.template.IFieldEntryReader;
 import org.msgpack.template.TemplateRegistry;
 
 public class JavassistTemplateBuilder extends CustomTemplateBuilder {
+	public static abstract class JavassistTemplate extends AbstractTemplate {
+		public Class<?> targetClass;
+		public Template[] templates;
+
+		public JavassistTemplate(Class<?> targetClass, Template[] templates) {
+			this.targetClass = targetClass;
+			this.templates = templates;
+		}
+	}
+
 	private static Logger LOG = LoggerFactory.getLogger(JavassistTemplateBuilder.class);
 
 	private static JavassistTemplateBuilder instance;
@@ -49,27 +61,24 @@ public class JavassistTemplateBuilder extends CustomTemplateBuilder {
 		getInstance().pool.appendClassPath(new LoaderClassPath(cl));
 	}
 
-	
 	IFieldEntryReader reader = new FieldEntryReader();
-	
+
 	public void setFieldEntryReader(IFieldEntryReader reader){
 		this.reader = reader;
 	}
-	
+
 	BuildContextFactory buildContextFactory = new BuildContextFactory() {
-		
 		@Override
 		public BuildContextBase createBuildContext(JavassistTemplateBuilder builder) {
 			
 			return new BuildContext(builder);
 		}
 	};
+
 	public void setBuildContextFactory(BuildContextFactory factory){
 		this.buildContextFactory = factory;
 	}
-	
-	
-	
+
 	public JavassistTemplateBuilder() {
 		pool = new ClassPool();
 		boolean appended = false;
@@ -96,6 +105,7 @@ public class JavassistTemplateBuilder extends CustomTemplateBuilder {
 			pool.appendSystemPath();
 		}
 	}
+
 	/**
 	 * Replace FieldEntryReader and BuilderContextFactory.
 	 * you can replace field entry rules and generated codes easily.
@@ -108,7 +118,6 @@ public class JavassistTemplateBuilder extends CustomTemplateBuilder {
 		this.buildContextFactory = buildContextFactory;
 	}
 
-
 	protected ClassPool pool;
 
 	private int seqId = 0;
@@ -125,7 +134,6 @@ public class JavassistTemplateBuilder extends CustomTemplateBuilder {
 		return seqId++;
 	}
 
-
 	@Override
 	public Template buildTemplate(Class<?> targetClass, IFieldEntry[] entries) {
 		// FIXME private / packagefields
@@ -136,10 +144,15 @@ public class JavassistTemplateBuilder extends CustomTemplateBuilder {
 		//		f.setAccessible(true);
 		//	}
 		//}
+		Template[] tmpls = toTemplate(entries);
+		BuildContextBase bc = getBuildContextFacotry().createBuildContext(this);
+		return bc.buildTemplate(targetClass, entries, tmpls);
+	}
 
-		Template[] tmpls = new Template[entries.length];
-		for(int i=0; i < entries.length; i++) {
-			IFieldEntry e = entries[i];
+	private static Template[] toTemplate(IFieldEntry[] from) {
+		Template[] tmpls = new Template[from.length];
+		for(int i=0; i < from.length; i++) {
+			IFieldEntry e = from[i];
 			if(!e.isAvailable()) {
 				tmpls[i] = null;
 			} else {
@@ -147,9 +160,7 @@ public class JavassistTemplateBuilder extends CustomTemplateBuilder {
 				tmpls[i] = tmpl;
 			}
 		}
-
-		BuildContextBase bc = getBuildContextFacotry().createBuildContext(this);
-		return bc.buildTemplate(targetClass, entries, tmpls);
+		return tmpls;
 	}
 
 	@Override
@@ -161,60 +172,36 @@ public class JavassistTemplateBuilder extends CustomTemplateBuilder {
 		return buildContextFactory;
 	}
 
-	
-    /*
-	static class JavassistOrdinalEnumTemplate extends ReflectionTemplateBuilder.ReflectionOrdinalEnumTemplate {
-		JavassistOrdinalEnumTemplate(Enum<?>[] entries) {
-			super(entries);
-		}
+	@Override
+	public void writeTemplate(Type targetType, String directoryName) {
+		Class<?> targetClass = (Class<?>)targetType;
+		IFieldEntryReader reader = getFieldEntryReader();
+		FieldOption implicitOption = reader.readImplicitFieldOption(targetClass);
+		checkValidation(targetClass);
+		IFieldEntry[] entries = reader.readFieldEntries(targetClass, implicitOption);
+		writeTemplate(targetClass, entries, directoryName);
+	}
+
+	private void writeTemplate(Class<?> targetClass, IFieldEntry[] entries, String directoryName) {
+		Template[] tmpls = toTemplate(entries);
+		BuildContextBase bc = getBuildContextFacotry().createBuildContext(this);
+		bc.writeTemplate(targetClass, entries, tmpls, directoryName);
 	}
 
 	@Override
-	public void writeOrdinalEnumTemplateClass(Class<?> targetClass, Enum<?>[] entires, String directoryName) {
-		throw new UnsupportedOperationException("not supported yet.");// TODO
+	public Template loadTemplate(Type targetType) {
+		Class<?> targetClass = (Class<?>)targetType;
+		IFieldEntryReader reader = getFieldEntryReader();
+		FieldOption implicitOption = reader.readImplicitFieldOption(targetClass);
+		checkValidation(targetClass);
+		IFieldEntry[] entries = reader.readFieldEntries(targetClass, implicitOption);
+		return loadTemplate(targetClass, entries);
 	}
 
-	public Template buildOrdinalEnumTemplate(Class<?> targetClass, Enum<?>[] entries) {
-		return new JavassistOrdinalEnumTemplate(entries);
+	private Template loadTemplate(Class<?> targetClass, IFieldEntry[] entries) {
+		Template[] tmpls = toTemplate(entries);
+		BuildContextBase bc = getBuildContextFacotry().createBuildContext(this);
+		return bc.loadTemplate(targetClass, entries, tmpls);
 	}
-
-	@Override
-	public void writeArrayTemplateClass(Type arrayType, Type genericBaseType,
-			Class<?> baseClass, int dim, String directoryName) {
-		throw new UnsupportedOperationException("not supported yet.");//TODO
-	}
-
-	public Template buildArrayTemplate(Type arrayType, Type genericBaseType, Class<?> baseClass, int dim) {
-		if(dim == 1) {
-			if(baseClass == boolean.class) {
-				return BooleanArrayTemplate.getInstance();
-			} else if(baseClass == short.class) {
-				return ShortArrayTemplate.getInstance();
-			} else if(baseClass == int.class) {
-				return IntArrayTemplate.getInstance();
-			} else if(baseClass == long.class) {
-				return LongArrayTemplate.getInstance();
-			} else if(baseClass == float.class) {
-				return FloatArrayTemplate.getInstance();
-			} else if(baseClass == double.class) {
-				return DoubleArrayTemplate.getInstance();
-			} else {
-				// FIXME
-				Template baseTemplate = TemplateRegistry.lookup(genericBaseType);
-				return new ReflectionTemplateBuilder.ReflectionObjectArrayTemplate(baseClass, baseTemplate);
-			}
-		} else if(dim == 2) {
-			// FIXME
-			Class<?> componentClass = Array.newInstance(baseClass, 0).getClass();
-			Template componentTemplate = buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1);
-			return new ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate);
-		} else {
-			// FIXME
-			ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate componentTemplate = (ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate)
-				buildArrayTemplate(arrayType, genericBaseType, baseClass, dim-1);
-			Class<?> componentClass = Array.newInstance(componentTemplate.getComponentClass(), 0).getClass();
-			return new ReflectionTemplateBuilder.ReflectionMultidimentionalArrayTemplate(componentClass, componentTemplate);
-		}
-	}*/
 }
 
diff --git a/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java
index 471defd4..61f29838 100644
--- a/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilder.java
@@ -77,10 +77,20 @@ public class OrdinalEnumTemplateBuilder implements TemplateBuilder{
 		
 		return new ReflectionOrdinalEnumTemplate(entries);
 	}
+
 	private void checkOrdinalEnumValidation(Class<?> targetClass) {
 		if(!targetClass.isEnum()) {
 			throw new TemplateBuildException("tried to build ordinal enum template of non-enum class");
 		}
 	}
 
+	@Override
+	public void writeTemplate(Type targetType, String directoryName) {
+		throw new UnsupportedOperationException(targetType.toString());
+	}
+
+	@Override
+	public Template loadTemplate(Type targetType) {
+		return null;
+	}
 }
diff --git a/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilderSelector.java b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilderSelector.java
index 6e612097..38ff7c4f 100644
--- a/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilderSelector.java
+++ b/java/src/main/java/org/msgpack/template/builder/OrdinalEnumTemplateBuilderSelector.java
@@ -23,7 +23,7 @@ import org.msgpack.annotation.MessagePackOrdinalEnum;
 
 public class OrdinalEnumTemplateBuilderSelector implements BuilderSelector {
 
-	public static final String NAME = "OrdinalEnumBuilder";
+	public static final String NAME = "OrdinalEnumTemplateBuilder";
 
 	OrdinalEnumTemplateBuilder builder = new OrdinalEnumTemplateBuilder();
 
diff --git a/java/src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java
index 30bdda38..6d875015 100644
--- a/java/src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/ReflectionTemplateBuilder.java
@@ -21,7 +21,12 @@ import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 
-import org.msgpack.*;
+import org.msgpack.AbstractTemplate;
+import org.msgpack.MessagePackObject;
+import org.msgpack.MessageTypeException;
+import org.msgpack.Packer;
+import org.msgpack.Template;
+import org.msgpack.Unpacker;
 import org.msgpack.template.FieldEntry;
 import org.msgpack.template.FieldEntryReader;
 import org.msgpack.template.IFieldEntry;
@@ -412,7 +417,6 @@ public class ReflectionTemplateBuilder extends CustomTemplateBuilder {
 				res[i] = new ObjectFieldEntry(e, tmpl);
 			}
 		}
-
 		return new ReflectionTemplate(targetClass, res);
 	}
 }
diff --git a/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java b/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java
index 7c2533a1..0846ac41 100644
--- a/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java
+++ b/java/src/main/java/org/msgpack/template/builder/TemplateBuilder.java
@@ -23,5 +23,9 @@ import org.msgpack.Template;
 
 public interface TemplateBuilder {
 	Template buildTemplate(Type targetType);
+
+	void writeTemplate(Type targetType, String directoryName);
+
+	Template loadTemplate(Type targetType);
 }
 
diff --git a/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java b/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
index 8ca113b4..af99e06c 100644
--- a/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
+++ b/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
@@ -17,56 +17,58 @@
 //
 package org.msgpack.util;
 
-import org.msgpack.template.TemplateBuildException;
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.msgpack.template.builder.BuilderSelectorRegistry;
+import org.msgpack.template.builder.TemplateBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class TemplatePrecompiler {
 	private static final Logger LOG = LoggerFactory.getLogger(TemplatePrecompiler.class);
 
-	public static void write(Class<?> target, String directoryName) {
-		if (target.isEnum()) {
-			throw new UnsupportedOperationException("Not supported yet.");
-		} else {
-			//TemplateBuilder.writeClass(target, directoryName);
-		}
-		LOG.info("finished writing .class file of template class for " + target.getName());
-	}
+	//private static final String SRC = "msgpack.template.srcdir";
 
-	private String directoryName;
+	private static final String DIST = "msgpack.template.distdir";
 
-	private String[] classNames;
+	//private static final String DEFAULT_SRC = ".";
+
+	private static final String DEFAULT_DIST = ".";
 
 	private TemplatePrecompiler() {
 	}
 
-	private void parseOpts(final String[] args) {// TODO
-		if (args.length == 0) {
-			usage();
-		}
+	public void saveTemplates(final String[] classFileNames) throws IOException {
+		throw new UnsupportedOperationException("Not supported yet.");// TODO
 	}
 
-	private void usage() {// TODO
-		System.err.println("java org.msgpack.template.TemplateClassWriter ");
-		System.err.println("");
+	public void saveTemplateClass(Class<?> targetClass) throws IOException {
+		LOG.info("Saving template of " + targetClass.getName() + "...");
+		Properties props = System.getProperties();
+		String distDirName = getDirName(props, DIST, DEFAULT_DIST);
+		if (targetClass.isEnum()) {
+			throw new UnsupportedOperationException("Enum not supported yet: " + targetClass.getName());
+		} else {
+			TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(targetClass);
+			builder.writeTemplate(targetClass, distDirName);
+		}
+		LOG.info("Saved .class file of template class of " + targetClass.getName());
 	}
 
-	private void writeTemplateClasses() {
-		ClassLoader cl = this.getClass().getClassLoader();// TODO
-		for (String className : classNames) {
-			Class<?> origClass = null;
-			try {
-				origClass = cl.loadClass(className);
-			} catch (ClassNotFoundException e) {
-				throw new TemplateBuildException(e);
-			}
-			write(origClass, directoryName);
+	private String getDirName(Properties props, String dirName, String defaultDirName)
+			throws IOException {
+		String dName = props.getProperty(dirName, defaultDirName);
+		File d = new File(dName);
+		if (!d.isDirectory() && !d.exists()) {
+			throw new IOException("Directory not exists: " + dName);
 		}
+		return d.getAbsolutePath();
 	}
 
 	public static void main(final String[] args) throws Exception {
-		TemplatePrecompiler writer = new TemplatePrecompiler();
-		writer.parseOpts(args);
-		writer.writeTemplateClasses();
+		TemplatePrecompiler compiler = new TemplatePrecompiler();// TODO
+		compiler.saveTemplates(args);
 	}
 }
diff --git a/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala b/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala
index 784c9e93..7e39baa0 100644
--- a/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala
+++ b/scala/src/main/scala/org/msgpack/JavassistTypeScalaTemplateBuilder.scala
@@ -7,7 +7,8 @@ import java.lang.Class
 import collection.immutable.{ListMap, TreeMap}
 import java.lang.reflect.{Type, Modifier, Method, Field}
 import java.lang.annotation.{Annotation => JavaAnnotation}
-import builder.{JavassistTemplateBuilder, JavassistTemplate, BuildContextBase, BuildContext}
+import builder.{JavassistTemplateBuilder, BuildContextBase, BuildContext}
+import builder.JavassistTemplateBuilder.JavassistTemplate
 import scala.collection.JavaConverters._
 ;
 /*
@@ -26,6 +27,23 @@ import scala.collection.JavaConverters._
     var templates : Array[Template] = null
     var minimumArrayLength : Int = 0
 
+    def writeTemplate(targetClass : Class[_] ,  entries : Array[IFieldEntry],
+      templates : Array[Template], directoryName : String) = {
+      this.entries = entries;
+      this.templates = templates;
+      this.origClass = targetClass;
+      this.origName = this.origClass.getName();
+      write(this.origName, directoryName);
+	}
+
+    def loadTemplate(targetClass : Class[_] ,  entries : Array[IFieldEntry], templates : Array[Template]) = {
+      this.entries = entries;
+      this.templates = templates;
+      this.origClass = targetClass;
+      this.origName = this.origClass.getName();
+	  load(this.origName);
+	}
+
     def buildTemplate(targetClass : Class[_] ,  entries : Array[IFieldEntry],  templates : Array[Template]) = {
       this.entries = entries;
       this.templates = templates;

From 65ddd1a455eb975e6a88f87b4e89759e57289f10 Mon Sep 17 00:00:00 2001
From: Muga Nishizawa <muga.nishizawa@gmail.com>
Date: Sun, 10 Apr 2011 02:33:46 +0900
Subject: [PATCH 08/10] java: add test program for TemplatePrecompiler

---
 .../msgpack/template/TemplateRegistry.java    |  46 +++++---
 .../org/msgpack/util/TemplatePrecompiler.java |  26 +++--
 .../TestTemplateBuilderPackUnpack.java        |   5 -
 .../msgpack/util/TestTemplatePrecompiler.java | 110 ++++++++++++++++++
 4 files changed, 154 insertions(+), 33 deletions(-)
 create mode 100644 java/src/test/java/org/msgpack/util/TestTemplatePrecompiler.java

diff --git a/java/src/main/java/org/msgpack/template/TemplateRegistry.java b/java/src/main/java/org/msgpack/template/TemplateRegistry.java
index 4c4f87b6..5d869a06 100644
--- a/java/src/main/java/org/msgpack/template/TemplateRegistry.java
+++ b/java/src/main/java/org/msgpack/template/TemplateRegistry.java
@@ -29,7 +29,6 @@ import org.msgpack.Template;
 public class TemplateRegistry {
 	private static Map<Type, Template> map;
 	private static Map<Type, GenericTemplate> genericMap;
-	
 	private static BuilderSelectorRegistry builderSelectorRegistry;
 
 	static {
@@ -41,38 +40,43 @@ public class TemplateRegistry {
 
 	public static void register(Class<?> target) {
 		TemplateBuilder builder = builderSelectorRegistry.select(target);
-		if(builder != null){
+		if (builder != null) {
 			register(target,builder.buildTemplate(target));
-		}else{
+		} else {
 			register(target,builderSelectorRegistry.getForceBuilder().buildTemplate(target));
 		}
 	}
 
 	public static void register(Class<?> target, FieldOption implicitOption) {
 		TemplateBuilder builder = builderSelectorRegistry.select(target);
-		if(builder != null && builder instanceof CustomTemplateBuilder){
+		if (builder != null && builder instanceof CustomTemplateBuilder) {
 			register(target, ((CustomTemplateBuilder)builder).buildTemplate(target, implicitOption));
-		}else{
+		} else {
 			throw new TemplateBuildException("Cannot build template with filed option");
 		}
 	}
 
 	public static void register(Class<?> target, FieldList flist) throws NoSuchFieldException {
 		TemplateBuilder builder = builderSelectorRegistry.select(target);
-		if(builder != null && builder instanceof CustomTemplateBuilder){
+		if (builder != null && builder instanceof CustomTemplateBuilder) {
 			register(target, ((CustomTemplateBuilder)builder).buildTemplate(target, flist));
-		}else{
+		} else {
 			throw new TemplateBuildException("Cannot build template with filed list");
 		}
 	}
 
 	public static synchronized void register(Type rawType, Template tmpl) {
-		if(rawType instanceof ParameterizedType) {
+		if (rawType instanceof ParameterizedType) {
 			rawType = ((ParameterizedType)rawType).getRawType();
 		}
 		map.put(rawType, tmpl);
 	}
 
+	public static boolean unregister(Class<?> target) {
+		Template tmpl = map.remove(target);
+		return tmpl != null;
+	}
+
 	public static synchronized void registerGeneric(Type rawType, GenericTemplate gtmpl) {
 		if(rawType instanceof ParameterizedType) {
 			rawType = ((ParameterizedType)rawType).getRawType();
@@ -81,22 +85,27 @@ public class TemplateRegistry {
 	}
 
 	public static synchronized Template lookup(Type targetType) {
-		return lookupImpl(targetType, false, true);
+		return lookupImpl(targetType, true, false, true);
 	}
 
 	public static synchronized Template lookup(Type targetType, boolean forceBuild) {
-		return lookupImpl(targetType, forceBuild, true);
+		return lookupImpl(targetType, true, forceBuild, true);
+	}
+
+	public static synchronized Template lookup(Type targetType, boolean forceLoad, boolean forceBuild) {
+		return lookupImpl(targetType, forceLoad, forceBuild, true);
 	}
 
 	public static synchronized Template tryLookup(Type targetType) {
-		return lookupImpl(targetType, false, false);
+		return lookupImpl(targetType, true, false, false);
 	}
 
 	public static synchronized Template tryLookup(Type targetType, boolean forceBuild) {
-		return lookupImpl(targetType, forceBuild, false);
+		return lookupImpl(targetType, true, forceBuild, false);
 	}
 
-	private static synchronized Template lookupImpl(Type targetType, boolean forceBuild, boolean fallbackDefault) {
+	private static synchronized Template lookupImpl(Type targetType,
+			boolean forceLoad, boolean forceBuild, boolean fallbackDefault) {
 		Template tmpl;
 
 		if(targetType instanceof ParameterizedType) {
@@ -115,10 +124,13 @@ public class TemplateRegistry {
 
 		// find match TemplateBuilder
 		TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(targetType);
-		if(builder != null){
-			tmpl = builder.loadTemplate(targetType);
-			if (tmpl != null) {
-				return tmpl;
+		if (builder != null) {
+			if (forceLoad) {
+				tmpl = builder.loadTemplate(targetType);
+				if (tmpl != null) {
+					register(targetType, tmpl);
+					return tmpl;
+				}
 			}
 
 			tmpl = builder.buildTemplate(targetType);
diff --git a/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java b/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
index af99e06c..d1d23f6c 100644
--- a/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
+++ b/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.util.Properties;
 
 import org.msgpack.template.builder.BuilderSelectorRegistry;
+import org.msgpack.template.builder.JavassistTemplateBuilder;
 import org.msgpack.template.builder.TemplateBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -29,35 +30,39 @@ import org.slf4j.LoggerFactory;
 public class TemplatePrecompiler {
 	private static final Logger LOG = LoggerFactory.getLogger(TemplatePrecompiler.class);
 
-	//private static final String SRC = "msgpack.template.srcdir";
+	//public static final String SRC = "msgpack.template.srcdir";
 
-	private static final String DIST = "msgpack.template.distdir";
+	public static final String DIST = "msgpack.template.distdir";
 
-	//private static final String DEFAULT_SRC = ".";
+	//public static final String DEFAULT_SRC = ".";
 
-	private static final String DEFAULT_DIST = ".";
+	public static final String DEFAULT_DIST = ".";
+
+	private static TemplatePrecompiler INSTANCE = null;
 
 	private TemplatePrecompiler() {
 	}
 
-	public void saveTemplates(final String[] classFileNames) throws IOException {
+	public static void saveTemplates(final String[] classFileNames) throws IOException {
 		throw new UnsupportedOperationException("Not supported yet.");// TODO
 	}
 
-	public void saveTemplateClass(Class<?> targetClass) throws IOException {
+	public static void saveTemplateClass(Class<?> targetClass) throws IOException {
+		if (INSTANCE != null) {
+			INSTANCE = new TemplatePrecompiler();
+		}
 		LOG.info("Saving template of " + targetClass.getName() + "...");
 		Properties props = System.getProperties();
 		String distDirName = getDirName(props, DIST, DEFAULT_DIST);
 		if (targetClass.isEnum()) {
 			throw new UnsupportedOperationException("Enum not supported yet: " + targetClass.getName());
 		} else {
-			TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(targetClass);
-			builder.writeTemplate(targetClass, distDirName);
+			new JavassistTemplateBuilder().writeTemplate(targetClass, distDirName);
 		}
 		LOG.info("Saved .class file of template class of " + targetClass.getName());
 	}
 
-	private String getDirName(Properties props, String dirName, String defaultDirName)
+	private static String getDirName(Properties props, String dirName, String defaultDirName)
 			throws IOException {
 		String dName = props.getProperty(dirName, defaultDirName);
 		File d = new File(dName);
@@ -68,7 +73,6 @@ public class TemplatePrecompiler {
 	}
 
 	public static void main(final String[] args) throws Exception {
-		TemplatePrecompiler compiler = new TemplatePrecompiler();// TODO
-		compiler.saveTemplates(args);
+		TemplatePrecompiler.saveTemplates(args);
 	}
 }
diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java
index 9ac94ef7..b938ab20 100644
--- a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java
+++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java
@@ -1,7 +1,5 @@
 package org.msgpack.template;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
@@ -15,16 +13,13 @@ import org.junit.Test;
 
 import org.msgpack.MessagePack;
 import org.msgpack.MessagePackable;
-import org.msgpack.MessagePacker;
 import org.msgpack.MessageTypeException;
 import org.msgpack.MessageUnpackable;
 import org.msgpack.Packer;
-import org.msgpack.Template;
 import org.msgpack.Unpacker;
 import org.msgpack.annotation.MessagePackMessage;
 import org.msgpack.annotation.MessagePackOrdinalEnum;
 import org.msgpack.annotation.Optional;
-import org.msgpack.template.TestTemplateBuilderPackConvert.SampleInterface;
 import org.msgpack.template.builder.BuilderSelectorRegistry;
 import org.msgpack.template.builder.TemplateBuilder;
 
diff --git a/java/src/test/java/org/msgpack/util/TestTemplatePrecompiler.java b/java/src/test/java/org/msgpack/util/TestTemplatePrecompiler.java
new file mode 100644
index 00000000..e99c5da1
--- /dev/null
+++ b/java/src/test/java/org/msgpack/util/TestTemplatePrecompiler.java
@@ -0,0 +1,110 @@
+package org.msgpack.util;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+import org.msgpack.MessagePack;
+import org.msgpack.MessageTypeException;
+import org.msgpack.template.TemplateRegistry;
+
+public class TestTemplatePrecompiler {
+ 
+	@Test
+	public void testPrimitiveTypeFields00() throws Exception {
+		System.getProperties().setProperty(TemplatePrecompiler.DIST, "./target/test-classes");
+		Class<?> c = PrimitiveTypeFieldsClass.class;
+		TemplatePrecompiler.saveTemplateClass(PrimitiveTypeFieldsClass.class);
+
+		PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass();
+		src.f0 = (byte) 0;
+		src.f1 = 1;
+		src.f2 = 2;
+		src.f3 = 3;
+		src.f4 = 4;
+		src.f5 = 5;
+		src.f6 = false;
+
+		try {
+			MessagePack.pack(src);
+			fail();
+		} catch (Exception e) {
+			assertTrue(e instanceof MessageTypeException);
+			assertTrue(TemplateRegistry.unregister(c));
+		}
+		try {
+			TemplateRegistry.lookup(c, true, true);
+			byte[] raw = MessagePack.pack(src);
+			PrimitiveTypeFieldsClass dst = MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class);
+			assertEquals(src.f0, dst.f0);
+			assertEquals(src.f1, dst.f1);
+			assertEquals(src.f2, dst.f2);
+			assertEquals(src.f3, dst.f3);
+			//assertEquals(src.f4, dst.f4);
+			//assertEquals(src.f5, dst.f5);
+			assertEquals(src.f6, dst.f6);
+		} finally {
+			TemplateRegistry.unregister(c);
+		}
+	}
+
+	@Test
+	public void testPrimitiveTypeFields01() throws Exception {
+		System.getProperties().setProperty(TemplatePrecompiler.DIST, "./target/test-classes");
+		Class<?> c = PrimitiveTypeFieldsClass.class;
+		TemplatePrecompiler.saveTemplateClass(PrimitiveTypeFieldsClass.class);
+
+		PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass();
+
+		try {
+			MessagePack.pack(src);
+			fail();
+		} catch (Exception e) {
+			assertTrue(e instanceof MessageTypeException);
+			assertTrue(TemplateRegistry.unregister(c));
+		}
+		try {
+			TemplateRegistry.lookup(c, true, true);
+			byte[] raw = MessagePack.pack(src);
+			PrimitiveTypeFieldsClass dst = MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class);
+			assertEquals(src.f0, dst.f0);
+			assertEquals(src.f1, dst.f1);
+			assertEquals(src.f2, dst.f2);
+			assertEquals(src.f3, dst.f3);
+			//assertEquals(src.f4, dst.f4);
+			//assertEquals(src.f5, dst.f5);
+			assertEquals(src.f6, dst.f6);
+		} finally {
+			TemplateRegistry.unregister(c);
+		}
+	}
+
+	@Test
+	public void testPrimitiveTypeFields02() throws Exception {
+		System.getProperties().setProperty(TemplatePrecompiler.DIST, "./target/test-classes");
+		Class<?> c = PrimitiveTypeFieldsClass.class;
+		TemplatePrecompiler.saveTemplateClass(PrimitiveTypeFieldsClass.class);
+
+		PrimitiveTypeFieldsClass src = null;
+		MessagePack.pack(src);
+		try {
+			TemplateRegistry.lookup(c, true, true);
+			byte[] raw = MessagePack.pack(src);
+			PrimitiveTypeFieldsClass dst = MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class);
+			assertEquals(src, dst);
+		} finally {
+			TemplateRegistry.unregister(c);
+		}
+	}
+
+	public static class PrimitiveTypeFieldsClass {
+		public byte f0;
+		public short f1;
+		public int f2;
+		public long f3;
+		public float f4;
+		public double f5;
+		public boolean f6;
+
+		public PrimitiveTypeFieldsClass() {
+		}
+	}
+}

From c6d9bbd7b0e206b2cc69417bb3ed2a8cfa5899a5 Mon Sep 17 00:00:00 2001
From: FURUHASHI Sadayuki <frsyuki@users.sourceforge.jp>
Date: Tue, 12 Apr 2011 18:39:54 +0900
Subject: [PATCH 09/10] MSGPACK-7 fixed test cases; iteration order of HashMap
 is not defined by JDK 5/6 specification

---
 ...ionTemplateBuilderJavaBeansPackUnpack.java | 23 ++++++------------
 ...tReflectionTemplateBuilderPackConvert.java | 24 ++++++-------------
 ...stReflectionTemplateBuilderPackUnpack.java | 24 ++++++-------------
 ...estTemplateBuilderJavaBeansPackUnpack.java | 22 ++++++-----------
 .../TestTemplateBuilderPackConvert.java       | 24 ++++++-------------
 .../TestTemplateBuilderPackUnpack.java        | 24 ++++++-------------
 6 files changed, 42 insertions(+), 99 deletions(-)

diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java
index 0bd6f71a..e894ad65 100644
--- a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java
+++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderJavaBeansPackUnpack.java
@@ -826,7 +826,7 @@ public class TestReflectionTemplateBuilderJavaBeansPackUnpack extends TestCase {
 
 		SampleOptionalListTypes dst =
 			MessagePack.unpack(raw, SampleOptionalListTypes.class);
-		assertEquals(src.f0.size(), dst.f0.size());
+		assertEquals(0, dst.f0.size());
 		assertEquals(src.f1.size(), dst.f1.size());
 		for (int i = 0; i < src.f1.size(); ++i) {
 			assertEquals(src.f1.get(i), dst.f1.get(i));
@@ -1013,22 +1013,18 @@ public class TestReflectionTemplateBuilderJavaBeansPackUnpack extends TestCase {
 
 		SampleMapTypes dst =
 			MessagePack.unpack(raw, SampleMapTypes.class);
+		assertEquals(src.f0.size(), dst.f0.size());
+		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
@@ -1097,21 +1093,16 @@ public class TestReflectionTemplateBuilderJavaBeansPackUnpack extends TestCase {
 		assertEquals(src.f0.size(), dst.f0.size());
 		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
 		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java
index 93523228..a514216d 100644
--- a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java
+++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackConvert.java
@@ -612,22 +612,18 @@ public class TestReflectionTemplateBuilderPackConvert extends TestCase {
 
 		SampleMapTypes dst =
 			MessagePack.unpack(raw).convert(SampleMapTypes.class);
+		assertEquals(src.f0.size(), dst.f0.size());
+		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
@@ -668,24 +664,18 @@ public class TestReflectionTemplateBuilderPackConvert extends TestCase {
 
 		SampleOptionalMapTypes dst =
 			MessagePack.unpack(raw).convert(SampleOptionalMapTypes.class);
-		assertEquals(src.f0.size(), dst.f0.size());
+		assertEquals(0, dst.f0.size());
 		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
diff --git a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java
index 64fc9785..53e48913 100644
--- a/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java
+++ b/java/src/test/java/org/msgpack/template/TestReflectionTemplateBuilderPackUnpack.java
@@ -617,22 +617,18 @@ public class TestReflectionTemplateBuilderPackUnpack extends TestCase {
 
 		SampleMapTypes dst =
 			MessagePack.unpack(raw, SampleMapTypes.class);
+		assertEquals(0, dst.f0.size());
+		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
@@ -673,24 +669,18 @@ public class TestReflectionTemplateBuilderPackUnpack extends TestCase {
 
 		SampleOptionalMapTypes dst =
 			MessagePack.unpack(raw, SampleOptionalMapTypes.class);
-		assertEquals(src.f0.size(), dst.f0.size());
+		assertEquals(0, dst.f0.size());
 		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderJavaBeansPackUnpack.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderJavaBeansPackUnpack.java
index 1310cddb..b5262ac3 100644
--- a/java/src/test/java/org/msgpack/template/TestTemplateBuilderJavaBeansPackUnpack.java
+++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderJavaBeansPackUnpack.java
@@ -1038,22 +1038,18 @@ public class TestTemplateBuilderJavaBeansPackUnpack extends TestCase {
 
 		SampleMapTypes dst =
 			MessagePack.unpack(raw, SampleMapTypes.class);
+		assertEquals(0, dst.f0.size());
+		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
@@ -1119,24 +1115,20 @@ public class TestTemplateBuilderJavaBeansPackUnpack extends TestCase {
 
 		SampleOptionalMapTypes dst =
 			MessagePack.unpack(raw, SampleOptionalMapTypes.class);
-		assertEquals(src.f0.size(), dst.f0.size());
+		assertEquals(0, dst.f0.size());
 		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
 		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
 		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java
index f316e64a..d741c9bf 100644
--- a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java
+++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackConvert.java
@@ -598,22 +598,18 @@ public class TestTemplateBuilderPackConvert extends TestCase {
 
 		SampleMapTypes dst =
 			MessagePack.unpack(raw).convert(SampleMapTypes.class);
+		assertEquals(0, dst.f0.size());
+		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
@@ -654,24 +650,18 @@ public class TestTemplateBuilderPackConvert extends TestCase {
 
 		SampleOptionalMapTypes dst =
 			MessagePack.unpack(raw).convert(SampleOptionalMapTypes.class);
-		assertEquals(src.f0.size(), dst.f0.size());
+		assertEquals(0, dst.f0.size());
 		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java
index b938ab20..7fcf0d7c 100644
--- a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java
+++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java
@@ -594,22 +594,18 @@ public class TestTemplateBuilderPackUnpack extends TestCase {
 
 		SampleMapTypes dst =
 			MessagePack.unpack(raw, SampleMapTypes.class);
+		assertEquals(0, dst.f0.size());
+		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 
@@ -650,24 +646,18 @@ public class TestTemplateBuilderPackUnpack extends TestCase {
 
 		SampleOptionalMapTypes dst =
 			MessagePack.unpack(raw, SampleOptionalMapTypes.class);
-		assertEquals(src.f0.size(), dst.f0.size());
+		assertEquals(0, dst.f0.size());
 		assertEquals(src.f1.size(), dst.f1.size());
 		Iterator<Integer> srcf1 = src.f1.keySet().iterator();
-		Iterator<Integer> dstf1 = dst.f1.keySet().iterator();
 		while (srcf1.hasNext()) {
 			Integer s1 = srcf1.next();
-			Integer d1 = dstf1.next();
-			assertEquals(s1, d1);
-			assertEquals(src.f1.get(s1), dst.f1.get(d1));
+			assertEquals(src.f1.get(s1), dst.f1.get(s1));
 		}
 		assertEquals(src.f2.size(), dst.f2.size());
 		Iterator<String> srcf2 = src.f2.keySet().iterator();
-		Iterator<String> dstf2 = dst.f2.keySet().iterator();
 		while (srcf2.hasNext()) {
 			String s2 = srcf2.next();
-			String d2 = dstf2.next();
-			assertEquals(s2, d2);
-			assertEquals(src.f2.get(s2), dst.f2.get(d2));
+			assertEquals(src.f2.get(s2), dst.f2.get(s2));
 		}
 	}
 

From c58ce1a975ffcda089bbc835e035b0f670294a98 Mon Sep 17 00:00:00 2001
From: FURUHASHI Sadayuki <frsyuki@users.sourceforge.jp>
Date: Tue, 12 Apr 2011 18:41:08 +0900
Subject: [PATCH 10/10] MSGPACK-7 added -source 1.5 -target 1.5 options to
 javac

---
 java/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/java/pom.xml b/java/pom.xml
index 39149d20..b9abaa41 100755
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -63,8 +63,8 @@
       <plugin>
         <artifactId>maven-compiler-plugin</artifactId>
         <configuration>
-          <source>1.6</source>
-          <target>1.6</target>
+          <source>1.5</source>
+          <target>1.5</target>
         </configuration>
       </plugin>