/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * 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 com.alibaba.dubbo.common.serialize.support.dubbo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Matcher;

import com.alibaba.dubbo.common.bytecode.ClassGenerator;
import com.alibaba.dubbo.common.io.ClassDescriptorMapper;
import com.alibaba.dubbo.common.io.UnsafeByteArrayInputStream;
import com.alibaba.dubbo.common.io.UnsafeByteArrayOutputStream;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.serialize.support.java.CompactedObjectInputStream;
import com.alibaba.dubbo.common.serialize.support.java.CompactedObjectOutputStream;
import com.alibaba.dubbo.common.utils.ClassHelper;
import com.alibaba.dubbo.common.utils.IOUtils;
import com.alibaba.dubbo.common.utils.ReflectUtils;
import com.alibaba.dubbo.common.utils.StringUtils;

/**
 * Builder.
 * 
 * @author qian.lei
 *
 * @param <T> type.
 */

@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class Builder<T> implements GenericDataFlags
{
	// Must be protected. by qian.lei
	protected static Logger logger = LoggerFactory.getLogger(Builder.class);

	private static final AtomicLong BUILDER_CLASS_COUNTER = new AtomicLong(0);

	private static final String BUILDER_CLASS_NAME = Builder.class.getName();

	private static final Map<Class<?>, Builder<?>> BuilderMap = new ConcurrentHashMap<Class<?>, Builder<?>>();
	private static final Map<Class<?>, Builder<?>> nonSerializableBuilderMap = new ConcurrentHashMap<Class<?>, Builder<?>>();

	private static final String FIELD_CONFIG_SUFFIX = ".fc";

	private static final int MAX_FIELD_CONFIG_FILE_SIZE = 16 * 1024;

	private static final Comparator<String> FNC = new Comparator<String>(){
		public int compare(String n1, String n2){ return compareFieldName(n1, n2); }
	};

	private static final Comparator<Field> FC = new Comparator<Field>(){
		public int compare(Field f1, Field f2){ return compareFieldName(f1.getName(), f2.getName()); }
	};

	private static final Comparator<Constructor> CC = new Comparator<Constructor>(){
		public int compare(Constructor o1, Constructor o2){ return o1.getParameterTypes().length - o2.getParameterTypes().length; }
	};

	// class-descriptor mapper
	private static final List<String> mDescList = new ArrayList<String>();

	private static final Map<String, Integer> mDescMap = new ConcurrentHashMap<String, Integer>();

	public static ClassDescriptorMapper DEFAULT_CLASS_DESCRIPTOR_MAPPER = new ClassDescriptorMapper(){
		public String getDescriptor(int index)
		{
			if( index < 0 || index >= mDescList.size() )
				return null;
			return mDescList.get(index);
		}

		public int getDescriptorIndex(String desc)
		{
			Integer ret = mDescMap.get(desc);
			return ret == null ? -1 : ret.intValue();
		}
	};

	protected Builder(){}

	abstract public Class<T> getType();

	public void writeTo(T obj, OutputStream os) throws IOException
	{
		GenericObjectOutput out = new GenericObjectOutput(os);
		writeTo(obj, out);
		out.flushBuffer();
	}

	public T parseFrom(byte[] b) throws IOException
	{
		return parseFrom(new UnsafeByteArrayInputStream(b));
	}

	public T parseFrom(InputStream is) throws IOException
	{
		return parseFrom(new GenericObjectInput(is));
	}

	abstract public void writeTo(T obj, GenericObjectOutput out) throws IOException;

	abstract public T parseFrom(GenericObjectInput in) throws IOException;

	public static <T> Builder<T> register(Class<T> c, boolean isAllowNonSerializable)
    {
        if( c == Object.class || c.isInterface() )
            return (Builder<T>)GenericBuilder;
        if( c == Object[].class )
            return (Builder<T>)GenericArrayBuilder;

        Builder<T> b = (Builder<T>)BuilderMap.get(c);
        if(null != b) return b;
        
        boolean isSerializable = Serializable.class.isAssignableFrom(c);
        if(!isAllowNonSerializable && !isSerializable) {
            throw new IllegalStateException("Serialized class " + c.getName() +
            " must implement java.io.Serializable (dubbo codec setting: isAllowNonSerializable = false)");
        }
        
        b = (Builder<T>)nonSerializableBuilderMap.get(c);
        if(null != b) return b;
        
        b = newBuilder(c);
        if(isSerializable)
            BuilderMap.put(c, b);
        else
            nonSerializableBuilderMap.put(c, b);
        
        return b;
    } 
	
	public static <T> Builder<T> register(Class<T> c)
	{
	    return register(c, false);
	}

	public static <T> void register(Class<T> c, Builder<T> b)
	{
	    if(Serializable.class.isAssignableFrom(c))
	        BuilderMap.put(c, b);
	    else
	        nonSerializableBuilderMap.put(c, b);
	}

	private static <T> Builder<T> newBuilder(Class<T> c)
	{
		if( c.isPrimitive() )
			throw new RuntimeException("Can not create builder for primitive type: " + c);

		if( logger.isInfoEnabled() )
			logger.info("create Builder for class: " + c);

		Builder<?> builder;
		if( c.isArray() )
			builder = newArrayBuilder(c);
		else
			builder = newObjectBuilder(c);
		return (Builder<T>)builder;
	}
	
	private static Builder<?> newArrayBuilder(Class<?> c)
	{
		Class<?> cc = c.getComponentType();
		if( cc.isInterface() )
			return GenericArrayBuilder;

		ClassLoader cl = ClassHelper.getClassLoader(c);

		String cn = ReflectUtils.getName(c), ccn = ReflectUtils.getName(cc); // get class name as int[][], double[].
		String bcn = BUILDER_CLASS_NAME + "$bc" + BUILDER_CLASS_COUNTER.getAndIncrement();

		int ix = cn.indexOf(']');
		String s1 = cn.substring(0, ix), s2 = cn.substring(ix); // if name='int[][]' then s1='int[', s2='][]'

		StringBuilder cwt = new StringBuilder("public void writeTo(Object obj, ").append(GenericObjectOutput.class.getName()).append(" out) throws java.io.IOException{"); // writeTo code.
		StringBuilder cpf = new StringBuilder("public Object parseFrom(").append(GenericObjectInput.class.getName()).append(" in) throws java.io.IOException{"); // parseFrom code.

		cwt.append("if( $1 == null ){ $2.write0(OBJECT_NULL); return; }");
		cwt.append(cn).append(" v = (").append(cn).append(")$1; int len = v.length; $2.write0(OBJECT_VALUES); $2.writeUInt(len); for(int i=0;i<len;i++){ ");

		cpf.append("byte b = $1.read0(); if( b == OBJECT_NULL ) return null; if( b != OBJECT_VALUES ) throw new java.io.IOException(\"Input format error, expect OBJECT_NULL|OBJECT_VALUES, get \" + b + \".\");");
		cpf.append("int len = $1.readUInt(); if( len == 0 ) return new ").append(s1).append('0').append(s2).append("; ");
		cpf.append(cn).append(" ret = new ").append(s1).append("len").append(s2).append("; for(int i=0;i<len;i++){ ");

		Builder<?> builder = null;
		if( cc.isPrimitive() )
		{
			if( cc == boolean.class )
			{
				cwt.append("$2.writeBool(v[i]);");
				cpf.append("ret[i] = $1.readBool();");
			}
			else if( cc == byte.class )
			{
				cwt.append("$2.writeByte(v[i]);");
				cpf.append("ret[i] = $1.readByte();");
			}
			else if( cc == char.class )
			{
				cwt.append("$2.writeShort((short)v[i]);");
				cpf.append("ret[i] = (char)$1.readShort();");
			}
			else if( cc == short.class )
			{
				cwt.append("$2.writeShort(v[i]);");
				cpf.append("ret[i] = $1.readShort();");
			}
			else if( cc == int.class )
			{
				cwt.append("$2.writeInt(v[i]);");
				cpf.append("ret[i] = $1.readInt();");
			}
			else if( cc == long.class )
			{
				cwt.append("$2.writeLong(v[i]);");
				cpf.append("ret[i] = $1.readLong();");
			}
			else if( cc == float.class )
			{
				cwt.append("$2.writeFloat(v[i]);");
				cpf.append("ret[i] = $1.readFloat();");
			}
			else if( cc == double.class )
			{
				cwt.append("$2.writeDouble(v[i]);");
				cpf.append("ret[i] = $1.readDouble();");
			}
		}
		else
		{
			builder = register(cc);

			cwt.append("builder.writeTo(v[i], $2);");
			cpf.append("ret[i] = (").append(ccn).append(")builder.parseFrom($1);");
		}
		cwt.append(" } }");
		cpf.append(" } return ret; }");

		ClassGenerator cg = ClassGenerator.newInstance(cl);
		cg.setClassName(bcn);
		cg.setSuperClass(Builder.class);
		cg.addDefaultConstructor();
		if( builder != null )
			cg.addField("public static " + BUILDER_CLASS_NAME + " builder;");
		cg.addMethod("public Class getType(){ return " + cn + ".class; }");
		cg.addMethod(cwt.toString());
		cg.addMethod(cpf.toString());
		try
		{
			Class<?> wc = cg.toClass();
			// set static field.
			if( builder != null )
				wc.getField("builder").set(null, builder);
			return (Builder<?>)wc.newInstance();
		}
		catch(RuntimeException e)
		{
			throw e;
		}
		catch(Throwable e)
		{
			throw new RuntimeException(e.getMessage());
		}
		finally
		{
			cg.release();
		}
	}

	private static Builder<?> newObjectBuilder(final Class<?> c)
	{
		if( c.isEnum() )
			return newEnumBuilder(c);

		if( c.isAnonymousClass() )
			throw new RuntimeException("Can not instantiation anonymous class: " + c);

		if( c.getEnclosingClass() != null && !Modifier.isStatic(c.getModifiers()) )
			throw new RuntimeException("Can not instantiation inner and non-static class: " + c);

		if( Throwable.class.isAssignableFrom(c) )
			return SerializableBuilder;

		ClassLoader cl = ClassHelper.getClassLoader(c);
	
		// is same package.
		boolean isp;
		String cn = c.getName(), bcn;
		if( c.getClassLoader() == null ) // is system class. if( cn.startsWith("java.") || cn.startsWith("javax.") || cn.startsWith("sun.") )
		{
			isp = false;
			bcn = BUILDER_CLASS_NAME + "$bc" + BUILDER_CLASS_COUNTER.getAndIncrement();
		}
		else
		{
			isp = true;
			bcn = cn + "$bc" + BUILDER_CLASS_COUNTER.getAndIncrement();
		}

		// is Collection, is Map, is Serializable.
		boolean isc = Collection.class.isAssignableFrom(c);
		boolean ism = !isc && Map.class.isAssignableFrom(c);
		boolean iss = !( isc || ism ) && Serializable.class.isAssignableFrom(c);

		// deal with fields.
		String[] fns = null; // fix-order fields names
		InputStream is = c.getResourceAsStream(c.getSimpleName() + FIELD_CONFIG_SUFFIX); // load field-config file.
		if( is != null )
		{
			try
			{
				int len = is.available();
				if( len > 0 )
				{
					if( len > MAX_FIELD_CONFIG_FILE_SIZE )
						throw new RuntimeException("Load [" + c.getName() + "] field-config file error: File-size too larger");

					String[] lines = IOUtils.readLines(is);
					if( lines != null && lines.length > 0 )
					{
						List<String> list = new ArrayList<String>();
						for(int i=0;i<lines.length;i++)
						{
							fns = lines[i].split(",");
							Arrays.sort(fns, FNC);
							for(int j=0;j<fns.length;j++)
								list.add(fns[j]);
						}
						fns = list.toArray(new String[0]);
					}
				}
			}
			catch(IOException e)
			{
				throw new RuntimeException("Load [" + c.getName() + "] field-config file error: " + e.getMessage() );
			}
			finally
			{
				try{ is.close(); }
				catch(IOException e){}
			}
		}

		Field f, fs[];
		if( fns != null )
		{
			fs = new Field[fns.length];
			for(int i=0;i<fns.length;i++)
			{
				String fn = fns[i];
				try
				{
					f = c.getDeclaredField(fn);
					int mod = f.getModifiers();
					if( Modifier.isStatic(mod) || (serializeIgnoreFinalModifier(c) && Modifier.isFinal(mod)) )
						throw new RuntimeException("Field [" + c.getName() + "." + fn + "] is static/final field.");
					if( Modifier.isTransient(mod) )
					{
						if( iss )
							return SerializableBuilder;
						throw new RuntimeException("Field [" + c.getName() + "." + fn + "] is transient field.");
					}
					f.setAccessible(true);
					fs[i] = f;
				}
				catch(SecurityException e)
				{
					throw new RuntimeException(e.getMessage());
				}
				catch(NoSuchFieldException e)
				{
					throw new RuntimeException("Field [" + c.getName() + "." + fn + "] not found.");
				}
			}
		}
		else
		{
			Class<?> t = c;
			List<Field> fl = new ArrayList<Field>();
			do
			{
				fs = t.getDeclaredFields();
				for( Field tf : fs )
				{
					int mod = tf.getModifiers();
                    if (Modifier.isStatic(mod)
                            || (serializeIgnoreFinalModifier(c) && Modifier.isFinal(mod))
                            || tf.getName().equals("this$0") // skip static or inner-class's 'this$0' field.
                            || ! Modifier.isPublic(tf.getType().getModifiers()) ) //skip private inner-class field
						continue;
					if( Modifier.isTransient(mod) )
					{
						if( iss )
							return SerializableBuilder;
						continue;
					}
					tf.setAccessible(true);
					fl.add(tf);
				}
				t = t.getSuperclass();
			}
			while( t != Object.class );

			fs = fl.toArray(new Field[0]);
			if( fs.length > 1 )
				Arrays.sort(fs, FC);
		}

		// deal with constructors.
		Constructor<?>[] cs = c.getDeclaredConstructors();
		if( cs.length == 0 )
		{
			Class<?> t = c;
			do
			{
				t = t.getSuperclass();
				if( t == null )
					throw new RuntimeException("Can not found Constructor?");
				cs = c.getDeclaredConstructors();
			}
			while( cs.length == 0 );
		}
		if( cs.length > 1 )
			Arrays.sort(cs, CC);

		// writeObject code.
		StringBuilder cwf = new StringBuilder("protected void writeObject(Object obj, ").append(GenericObjectOutput.class.getName()).append(" out) throws java.io.IOException{");
		cwf.append(cn).append(" v = (").append(cn).append(")$1; ");
		cwf.append("$2.writeInt(fields.length);");

		// readObject code.
		StringBuilder crf = new StringBuilder("protected void readObject(Object ret, ").append(GenericObjectInput.class.getName()).append(" in) throws java.io.IOException{");
		crf.append("int fc = $2.readInt();");
		crf.append("if( fc != ").append(fs.length).append(" ) throw new IllegalStateException(\"Deserialize Class [").append(cn).append("], field count not matched. Expect ").append(fs.length).append(" but get \" + fc +\".\");");
		crf.append(cn).append(" ret = (").append(cn).append(")$1;");

		// newInstance code.
		StringBuilder cni = new StringBuilder("protected Object newInstance(").append(GenericObjectInput.class.getName()).append(" in){ return ");
		Constructor<?> con = cs[0];
		int mod = con.getModifiers();
		boolean dn = Modifier.isPublic(mod) || ( isp && !Modifier.isPrivate(mod) );
		if( dn )
		{
			cni.append("new ").append(cn).append("(");
		}
		else
		{
			con.setAccessible(true);
			cni.append("constructor.newInstance(new Object[]{");
		}
		Class<?>[] pts = con.getParameterTypes();
		for(int i=0;i<pts.length;i++)
		{
			if( i > 0 )
				cni.append(',');
			cni.append(defaultArg(pts[i]));
		}
		if( !dn )
			cni.append("}"); // close object array.
		cni.append("); }");

		// get bean-style property metadata.
		Map<String, PropertyMetadata> pms = propertyMetadatas(c);
		List<Builder<?>> builders = new ArrayList<Builder<?>>(fs.length);
		String fn, ftn; // field name, field type name.
		Class<?> ft; // field type.
		boolean da; // direct access.
		PropertyMetadata pm;
		for(int i=0;i<fs.length;i++)
		{
			f = fs[i];
			fn = f.getName();
			ft = f.getType();
			ftn = ReflectUtils.getName(ft);
			da = isp && ( f.getDeclaringClass() == c ) && ( Modifier.isPrivate(f.getModifiers()) == false );
			if( da )
			{
				pm = null;
			}
			else
			{
				pm = pms.get(fn);
				if( pm != null && ( pm.type != ft || pm.setter == null || pm.getter == null ) )
					pm = null;
			}

			crf.append("if( fc == ").append(i).append(" ) return;");
			if( ft.isPrimitive() )
			{
				if( ft == boolean.class )
				{
					if( da )
					{
						cwf.append("$2.writeBool(v.").append(fn).append(");");
						crf.append("ret.").append(fn).append(" = $2.readBool();");
					}
					else if( pm != null )
					{
						cwf.append("$2.writeBool(v.").append(pm.getter).append("());");
						crf.append("ret.").append(pm.setter).append("($2.readBool());");
					}
					else
					{
						cwf.append("$2.writeBool(((Boolean)fields[").append(i).append("].get($1)).booleanValue());");
						crf.append("fields[").append(i).append("].set(ret, ($w)$2.readBool());");
					}
				}
				else if( ft == byte.class )
				{
					if( da )
					{
						cwf.append("$2.writeByte(v.").append(fn).append(");");
						crf.append("ret.").append(fn).append(" = $2.readByte();");
					}
					else if( pm != null )
					{
						cwf.append("$2.writeByte(v.").append(pm.getter).append("());");
						crf.append("ret.").append(pm.setter).append("($2.readByte());");
					}
					else
					{
						cwf.append("$2.writeByte(((Byte)fields[").append(i).append("].get($1)).byteValue());");
						crf.append("fields[").append(i).append("].set(ret, ($w)$2.readByte());");
					}
				}
				else if( ft == char.class )
				{
					if( da )
					{
						cwf.append("$2.writeShort((short)v.").append(fn).append(");");
						crf.append("ret.").append(fn).append(" = (char)$2.readShort();");
					}
					else if( pm != null )
					{
						cwf.append("$2.writeShort((short)v.").append(pm.getter).append("());");
						crf.append("ret.").append(pm.setter).append("((char)$2.readShort());");
					}
					else
					{
						cwf.append("$2.writeShort((short)((Character)fields[").append(i).append("].get($1)).charValue());");
						crf.append("fields[").append(i).append("].set(ret, ($w)((char)$2.readShort()));");
					}
				}
				else if( ft == short.class )
				{
					if( da )
					{
						cwf.append("$2.writeShort(v.").append(fn).append(");");
						crf.append("ret.").append(fn).append(" = $2.readShort();");
					}
					else if( pm != null )
					{
						cwf.append("$2.writeShort(v.").append(pm.getter).append("());");
						crf.append("ret.").append(pm.setter).append("($2.readShort());");
					}
					else
					{
						cwf.append("$2.writeShort(((Short)fields[").append(i).append("].get($1)).shortValue());");
						crf.append("fields[").append(i).append("].set(ret, ($w)$2.readShort());");
					}
				}
				else if( ft == int.class )
				{
					if( da )
					{
						cwf.append("$2.writeInt(v.").append(fn).append(");");
						crf.append("ret.").append(fn).append(" = $2.readInt();");
					}
					else if( pm != null )
					{
						cwf.append("$2.writeInt(v.").append(pm.getter).append("());");
						crf.append("ret.").append(pm.setter).append("($2.readInt());");
					}
					else
					{
						cwf.append("$2.writeInt(((Integer)fields[").append(i).append("].get($1)).intValue());");
						crf.append("fields[").append(i).append("].set(ret, ($w)$2.readInt());");
					}
				}
				else if( ft == long.class )
				{
					if( da )
					{
						cwf.append("$2.writeLong(v.").append(fn).append(");");
						crf.append("ret.").append(fn).append(" = $2.readLong();");
					}
					else if( pm != null )
					{
						cwf.append("$2.writeLong(v.").append(pm.getter).append("());");
						crf.append("ret.").append(pm.setter).append("($2.readLong());");
					}
					else
					{
						cwf.append("$2.writeLong(((Long)fields[").append(i).append("].get($1)).longValue());");
						crf.append("fields[").append(i).append("].set(ret, ($w)$2.readLong());");
					}
				}
				else if( ft == float.class )
				{
					if( da )
					{
						cwf.append("$2.writeFloat(v.").append(fn).append(");");
						crf.append("ret.").append(fn).append(" = $2.readFloat();");
					}
					else if( pm != null )
					{
						cwf.append("$2.writeFloat(v.").append(pm.getter).append("());");
						crf.append("ret.").append(pm.setter).append("($2.readFloat());");
					}
					else
					{
						cwf.append("$2.writeFloat(((Float)fields[").append(i).append("].get($1)).floatValue());");
						crf.append("fields[").append(i).append("].set(ret, ($w)$2.readFloat());");
					}
				}
				else if( ft == double.class )
				{
					if( da )
					{
						cwf.append("$2.writeDouble(v.").append(fn).append(");");
						crf.append("ret.").append(fn).append(" = $2.readDouble();");
					}
					else if( pm != null )
					{
						cwf.append("$2.writeDouble(v.").append(pm.getter).append("());");
						crf.append("ret.").append(pm.setter).append("($2.readDouble());");
					}
					else
					{
						cwf.append("$2.writeDouble(((Double)fields[").append(i).append("].get($1)).doubleValue());");
						crf.append("fields[").append(i).append("].set(ret, ($w)$2.readDouble());");
					}
				}
			}
			else if( ft == c )
			{
				if( da )
				{
					cwf.append("this.writeTo(v.").append(fn).append(", $2);");
					crf.append("ret.").append(fn).append(" = (").append(ftn).append(")this.parseFrom($2);");
				}
				else if( pm != null )
				{
					cwf.append("this.writeTo(v.").append(pm.getter).append("(), $2);");
					crf.append("ret.").append(pm.setter).append("((").append(ftn).append(")this.parseFrom($2));");
				}
				else
				{
					cwf.append("this.writeTo((").append(ftn).append(")fields[").append(i).append("].get($1), $2);");
					crf.append("fields[").append(i).append("].set(ret, this.parseFrom($2));");
				}
			}
			else
			{
				int bc = builders.size();
				builders.add( register(ft) );

				if( da )
				{
					cwf.append("builders[").append(bc).append("].writeTo(v.").append(fn).append(", $2);");
					crf.append("ret.").append(fn).append(" = (").append(ftn).append(")builders[").append(bc).append("].parseFrom($2);");
				}
				else if( pm != null )
				{
					cwf.append("builders[").append(bc).append("].writeTo(v.").append(pm.getter).append("(), $2);");
					crf.append("ret.").append(pm.setter).append("((").append(ftn).append(")builders[").append(bc).append("].parseFrom($2));");
				}
				else
				{
					cwf.append("builders[").append(bc).append("].writeTo((").append(ftn).append(")fields[").append(i).append("].get($1), $2);");
					crf.append("fields[").append(i).append("].set(ret, builders[").append(bc).append("].parseFrom($2));");
				}
			}
		}

		// skip any fields.
		crf.append("for(int i=").append(fs.length).append(";i<fc;i++) $2.skipAny();");

		// collection or map
		if( isc )
		{
			cwf.append("$2.writeInt(v.size()); for(java.util.Iterator it=v.iterator();it.hasNext();){ $2.writeObject(it.next()); }");
			crf.append("int len = $2.readInt(); for(int i=0;i<len;i++) ret.add($2.readObject());");
		}
		else if( ism )
		{
			cwf.append("$2.writeInt(v.size()); for(java.util.Iterator it=v.entrySet().iterator();it.hasNext();){ java.util.Map.Entry entry = (java.util.Map.Entry)it.next(); $2.writeObject(entry.getKey()); $2.writeObject(entry.getValue()); }");
			crf.append("int len = $2.readInt(); for(int i=0;i<len;i++) ret.put($2.readObject(), $2.readObject());");
		}
		cwf.append(" }");
		crf.append(" }");

		ClassGenerator cg = ClassGenerator.newInstance(cl);
		cg.setClassName(bcn);
		cg.setSuperClass(AbstractObjectBuilder.class);
		cg.addDefaultConstructor();
		cg.addField("public static java.lang.reflect.Field[] fields;");
		cg.addField("public static " + BUILDER_CLASS_NAME + "[] builders;");
		if( !dn )
			cg.addField("public static java.lang.reflect.Constructor constructor;");
		cg.addMethod("public Class getType(){ return " + cn + ".class; }");
		cg.addMethod(cwf.toString());
		cg.addMethod(crf.toString());
		cg.addMethod(cni.toString());
		try
		{
			Class<?> wc = cg.toClass();
			// set static field
			wc.getField("fields").set(null, fs);
			wc.getField("builders").set(null, builders.toArray(new Builder<?>[0]));
			if( !dn )
				wc.getField("constructor").set(null, con);
			return (Builder<?>)wc.newInstance();
		}
		catch(RuntimeException e)
		{
			throw e;
		}
		catch(Throwable e)
		{
			throw new RuntimeException(e.getMessage(), e);
		}
		finally
		{
			cg.release();
		}
	}

	private static Builder<?> newEnumBuilder(Class<?> c)
	{
		ClassLoader cl = ClassHelper.getClassLoader(c);
		
		String cn = c.getName();
		String bcn = BUILDER_CLASS_NAME + "$bc" + BUILDER_CLASS_COUNTER.getAndIncrement();

		StringBuilder cwt = new StringBuilder("public void writeTo(Object obj, ").append(GenericObjectOutput.class.getName()).append(" out) throws java.io.IOException{"); // writeTo code.
		cwt.append(cn).append(" v = (").append(cn).append(")$1;");
		cwt.append("if( $1 == null ){ $2.writeUTF(null); }else{ $2.writeUTF(v.name()); } }");

		StringBuilder cpf = new StringBuilder("public Object parseFrom(").append(GenericObjectInput.class.getName()).append(" in) throws java.io.IOException{"); // parseFrom code.
		cpf.append("String name = $1.readUTF(); if( name == null ) return null; return (").append(cn).append(")Enum.valueOf(").append(cn).append(".class, name); }");

		ClassGenerator cg = ClassGenerator.newInstance(cl);
		cg.setClassName(bcn);
		cg.setSuperClass(Builder.class);
		cg.addDefaultConstructor();
		cg.addMethod("public Class getType(){ return " + cn + ".class; }");
		cg.addMethod(cwt.toString());
		cg.addMethod(cpf.toString());
		try
		{
			Class<?> wc = cg.toClass();
			return (Builder<?>)wc.newInstance();
		}
		catch(RuntimeException e)
		{
			throw e;
		}
		catch(Throwable e)
		{
			throw new RuntimeException(e.getMessage(), e);
		}
		finally
		{
			cg.release();
		}
	}

	private static Map<String, PropertyMetadata> propertyMetadatas(Class<?> c)
	{
		Map<String, Method> mm = new HashMap<String, Method>(); // method map.
		Map<String, PropertyMetadata> ret = new HashMap<String, PropertyMetadata>(); // property metadata map.

		// All public method.
		for( Method m : c.getMethods() )
		{
			if( m.getDeclaringClass() == Object.class ) // Ignore Object's method.
				continue;
			mm.put(ReflectUtils.getDesc(m), m);
		}

		Matcher matcher;
		for( Map.Entry<String,Method> entry : mm.entrySet() )
		{
			String desc = entry.getKey();
			Method method = entry.getValue();
			if( ( matcher = ReflectUtils.GETTER_METHOD_DESC_PATTERN.matcher(desc) ).matches() ||
					( matcher = ReflectUtils.IS_HAS_CAN_METHOD_DESC_PATTERN.matcher(desc) ).matches() )
			{
				String pn = propertyName(matcher.group(1));
				Class<?> pt = method.getReturnType();
				PropertyMetadata pm = ret.get(pn);
				if( pm == null )
				{
					pm = new PropertyMetadata();
					pm.type = pt;
					ret.put(pn, pm);
				}
				else
				{
					if( pm.type != pt )
						continue;
				}
				pm.getter = method.getName();
			}
			else if( ( matcher = ReflectUtils.SETTER_METHOD_DESC_PATTERN.matcher(desc) ).matches() )
			{
				String pn = propertyName(matcher.group(1));
				Class<?> pt = method.getParameterTypes()[0];
				PropertyMetadata pm = ret.get(pn);
				if( pm == null )
				{
					pm = new PropertyMetadata();
					pm.type = pt;
					ret.put(pn, pm);
				}
				else
				{
					if( pm.type != pt )
						continue;
				}
				pm.setter = method.getName();
			}
		}
		return ret;
	}

	private static String propertyName(String s)
	{
		return s.length() == 1 || Character.isLowerCase(s.charAt(1)) ? Character.toLowerCase(s.charAt(0)) + s.substring(1) : s;
	}
	
	private static boolean serializeIgnoreFinalModifier(Class cl)
    {
//	    if (cl.isAssignableFrom(BigInteger.class)) return false;
//	    for performance
//	    if (cl.getName().startsWith("java")) return true;
//	    if (cl.getName().startsWith("javax")) return true;
	    
	    return false;
    }
	
	@SuppressWarnings("unused")
    private static boolean isPrimitiveOrPrimitiveArray1(Class<?> cl)
    {
        if (cl.isPrimitive()){
            return true;
        } else {
            Class clazz = cl.getClass().getComponentType();
            if (clazz!=null && clazz.isPrimitive()){
                return true;
            }
        } 
        return false;
    }

	private static String defaultArg(Class<?> cl)
	{
	    if( boolean.class == cl ) return "false";
	    if( int.class == cl ) return "0";
	    if( long.class == cl ) return "0l";
	    if( double.class == cl ) return "(double)0";
	    if( float.class == cl ) return "(float)0";
	    if( short.class == cl ) return "(short)0";
	    if( char.class == cl ) return "(char)0";
	    if( byte.class == cl ) return "(byte)0";
	    if( byte[].class == cl ) return "new byte[]{0}";
	    if( !cl.isPrimitive() ) return "null";
	    throw new UnsupportedOperationException();
	}

	private static int compareFieldName(String n1, String n2)
	{
		int l = Math.min(n1.length(), n2.length());
		for(int i=0;i<l;i++)
		{
			int t = n1.charAt(i) - n2.charAt(i);
			if( t != 0 )
				return t;
		}
		return n1.length() - n2.length();
	}

	private static void addDesc(Class<?> c)
	{
		String desc = ReflectUtils.getDesc(c);
		int index = mDescList.size();
		mDescList.add(desc);
		mDescMap.put(desc, index);
	}

	static class PropertyMetadata
	{
		Class<?> type;
		String setter, getter;
	}

	public static abstract class AbstractObjectBuilder<T> extends Builder<T>
	{
		abstract public Class<T> getType();

		public void writeTo(T obj, GenericObjectOutput out) throws IOException
		{
			if( obj == null )
			{
				out.write0(OBJECT_NULL);
			}
			else
			{
				int ref = out.getRef(obj);
				if( ref < 0 )
				{
					out.addRef(obj);
					out.write0(OBJECT);
					writeObject(obj, out);
				}
				else
				{
					out.write0(OBJECT_REF);
					out.writeUInt(ref);
				}
			}
		}

		public T parseFrom(GenericObjectInput in) throws IOException
		{
			byte b = in.read0();
			switch( b )
			{
				case OBJECT:
				{
					T ret = newInstance(in);
					in.addRef(ret);
					readObject(ret, in);
					return ret;
				}
				case OBJECT_REF:
					return (T)in.getRef(in.readUInt());
				case OBJECT_NULL:
					return null;
				default:
					throw new IOException("Input format error, expect OBJECT|OBJECT_REF|OBJECT_NULL, get " + b);
			}
		}

		abstract protected void writeObject(T obj, GenericObjectOutput out) throws IOException;

		abstract protected T newInstance(GenericObjectInput in) throws IOException;

		abstract protected void readObject(T ret, GenericObjectInput in) throws IOException;
	}

	static final Builder<Object> GenericBuilder = new Builder<Object>(){
		@Override
		public Class<Object> getType(){ return Object.class; }
		@Override
		public void writeTo(Object obj, GenericObjectOutput out) throws IOException{ out.writeObject(obj); }
		@Override
		public Object parseFrom(GenericObjectInput in) throws IOException{ return in.readObject(); }
	};

	static final Builder<Object[]> GenericArrayBuilder = new AbstractObjectBuilder<Object[]>(){
		@Override
		public Class<Object[]> getType(){ return Object[].class; }
		@Override
		protected Object[] newInstance(GenericObjectInput in) throws IOException
		{
			return new Object[in.readUInt()];
		}
		@Override
		protected void readObject(Object[] ret, GenericObjectInput in) throws IOException
		{
			for(int i=0;i<ret.length;i++)
				ret[i] = in.readObject();
		}
		@Override
		protected void writeObject(Object[] obj, GenericObjectOutput out) throws IOException
		{
			out.writeUInt(obj.length);
			for( Object item : obj )
				out.writeObject(item);
		}
	};

	static final Builder<Serializable> SerializableBuilder = new Builder<Serializable>(){
		@Override
		public Class<Serializable> getType()
		{
			return Serializable.class;
		}
		@Override
		public void writeTo(Serializable obj, GenericObjectOutput out) throws IOException
		{
			if( obj == null )
			{
				out.write0(OBJECT_NULL);
			}
			else
			{
				out.write0(OBJECT_STREAM);
				UnsafeByteArrayOutputStream bos = new UnsafeByteArrayOutputStream();
				CompactedObjectOutputStream oos = new CompactedObjectOutputStream(bos);
				oos.writeObject(obj);
				oos.flush();
				bos.close();
				byte[] b = bos.toByteArray();
				out.writeUInt(b.length);
				out.write0(b, 0, b.length);
			}
		}
		@Override
		public Serializable parseFrom(GenericObjectInput in) throws IOException
		{
			byte b = in.read0();
			if( b == OBJECT_NULL )
				return null;
			if( b != OBJECT_STREAM )
				throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_STREAM, get " + b + ".");

			UnsafeByteArrayInputStream bis = new UnsafeByteArrayInputStream(in.read0(in.readUInt()));
			CompactedObjectInputStream ois = new CompactedObjectInputStream(bis);
			try{ return (Serializable)ois.readObject(); }
			catch(ClassNotFoundException e){ throw new IOException(StringUtils.toString(e)); }
		}
	};

	static
	{
		addDesc(boolean[].class);
		addDesc(byte[].class);
		addDesc(char[].class);
		addDesc(short[].class);
		addDesc(int[].class);
		addDesc(long[].class);
		addDesc(float[].class);
		addDesc(double[].class);

		addDesc(Boolean.class);
		addDesc(Byte.class);
		addDesc(Character.class);
		addDesc(Short.class);
		addDesc(Integer.class);
		addDesc(Long.class);
		addDesc(Float.class);
		addDesc(Double.class);

		addDesc(String.class);
		addDesc(String[].class);

		addDesc(ArrayList.class);
		addDesc(HashMap.class);
		addDesc(HashSet.class);
		addDesc(Date.class);
		addDesc(java.sql.Date.class);
		addDesc(java.sql.Time.class);
		addDesc(java.sql.Timestamp.class);
		addDesc(java.util.LinkedList.class);
		addDesc(java.util.LinkedHashMap.class);
		addDesc(java.util.LinkedHashSet.class);

		register(byte[].class, new Builder<byte[]>(){
			@Override
			public Class<byte[]> getType(){ return byte[].class; }
			@Override
			public void writeTo(byte[] obj, GenericObjectOutput out) throws IOException{ out.writeBytes(obj); }
			@Override
			public byte[] parseFrom(GenericObjectInput in) throws IOException{ return in.readBytes(); }
		});
		register(Boolean.class, new Builder<Boolean>(){
			@Override
			public Class<Boolean> getType(){ return Boolean.class; }
			@Override
			public void writeTo(Boolean obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
					out.write0(VARINT_N1);
				else if( obj.booleanValue() )
					out.write0(VARINT_1);
				else
					out.write0(VARINT_0);
			}
			@Override
			public Boolean parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				switch( b )
				{
					case VARINT_N1: return null;
					case VARINT_0: return Boolean.FALSE;
					case VARINT_1: return Boolean.TRUE;
					default: throw new IOException("Input format error, expect VARINT_N1|VARINT_0|VARINT_1, get " + b + ".");
				}
			}
		});
		register(Byte.class, new Builder<Byte>(){
			@Override
			public Class<Byte> getType(){ return Byte.class; }
			@Override
			public void writeTo(Byte obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeByte(obj.byteValue());
				}
			}
			@Override
			public Byte parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return Byte.valueOf(in.readByte());
			}
		});
		register(Character.class, new Builder<Character>(){
			@Override
			public Class<Character> getType(){ return Character.class; }
			@Override
			public void writeTo(Character obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeShort((short)obj.charValue());
				}
			}
			@Override
			public Character parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return Character.valueOf((char)in.readShort());
			}
		});
		register(Short.class, new Builder<Short>(){
			@Override
			public Class<Short> getType(){ return Short.class; }
			@Override
			public void writeTo(Short obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeShort(obj.shortValue());
				}
			}
			@Override
			public Short parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return Short.valueOf(in.readShort());
			}
		});
		register(Integer.class, new Builder<Integer>(){
			@Override
			public Class<Integer> getType(){ return Integer.class; }
			@Override
			public void writeTo(Integer obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeInt(obj.intValue());
				}
			}
			@Override
			public Integer parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return Integer.valueOf(in.readInt());
			}
		});
		register(Long.class, new Builder<Long>(){
			@Override
			public Class<Long> getType(){ return Long.class; }
			@Override
			public void writeTo(Long obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeLong(obj.longValue());
				}
			}
			@Override
			public Long parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return Long.valueOf(in.readLong());
			}
		});
		register(Float.class, new Builder<Float>(){
			@Override
			public Class<Float> getType(){ return Float.class; }
			@Override
			public void writeTo(Float obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeFloat(obj.floatValue());
				}
			}
			@Override
			public Float parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return new Float(in.readFloat());
			}
		});
		register(Double.class, new Builder<Double>(){
			@Override
			public Class<Double> getType(){ return Double.class; }
			@Override
			public void writeTo(Double obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeDouble(obj.doubleValue());
				}
			}
			@Override
			public Double parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return new Double(in.readDouble());
			}
		});
		register(String.class, new Builder<String>(){
			@Override
			public Class<String> getType(){ return String.class; }
			@Override
			public String parseFrom(GenericObjectInput in) throws IOException{ return in.readUTF(); }
			@Override
			public void writeTo(String obj, GenericObjectOutput out) throws IOException{ out.writeUTF(obj); }
		});
		register(StringBuilder.class, new Builder<StringBuilder>(){
			@Override
			public Class<StringBuilder> getType(){ return StringBuilder.class; }
			@Override
			public StringBuilder parseFrom(GenericObjectInput in) throws IOException{ return new StringBuilder(in.readUTF()); }
			@Override
			public void writeTo(StringBuilder obj, GenericObjectOutput out) throws IOException{ out.writeUTF(obj.toString()); }
		});
		register(StringBuffer.class, new Builder<StringBuffer>(){
			@Override
			public Class<StringBuffer> getType(){ return StringBuffer.class; }
			@Override
			public StringBuffer parseFrom(GenericObjectInput in) throws IOException{ return new StringBuffer(in.readUTF()); }
			@Override
			public void writeTo(StringBuffer obj, GenericObjectOutput out) throws IOException{ out.writeUTF(obj.toString()); }
		});

		// java.util
		register(ArrayList.class, new Builder<ArrayList>(){
			@Override
			public Class<ArrayList> getType(){ return ArrayList.class; }
			@Override
			public void writeTo(ArrayList obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUES);
					out.writeUInt(obj.size());
					for( Object item : obj )
						out.writeObject(item);
				}
			}
			@Override
			public ArrayList parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUES )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUES, get " + b + ".");

				int len = in.readUInt();
				ArrayList ret = new ArrayList(len);
				for(int i=0;i<len;i++)
					ret.add(in.readObject());
				return ret;
			}
		});
		register(HashMap.class, new Builder<HashMap>(){
			@Override
			public Class<HashMap> getType(){ return HashMap.class; }
			@Override
			public void writeTo(HashMap obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_MAP);
					out.writeUInt(obj.size());
					for( Map.Entry entry : (Set<Map.Entry>)obj.entrySet() )
					{
						out.writeObject(entry.getKey());
						out.writeObject(entry.getValue());
					}
				}
			}
			@Override
			public HashMap parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_MAP )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_MAP, get " + b + ".");

				int len = in.readUInt();
				HashMap ret = new HashMap(len);
				for(int i=0;i<len;i++)
					ret.put(in.readObject(), in.readObject());
				return ret;
			}
		});
		register(HashSet.class, new Builder<HashSet>(){
			@Override
			public Class<HashSet> getType(){ return HashSet.class; }
			@Override
			public void writeTo(HashSet obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUES);
					out.writeUInt(obj.size());
					for( Object item : obj )
						out.writeObject(item);
				}
			}
			@Override
			public HashSet parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUES )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUES, get " + b + ".");

				int len = in.readUInt();
				HashSet ret = new HashSet(len);
				for(int i=0;i<len;i++)
					ret.add(in.readObject());
				return ret;
			}
		});

		register(Date.class, new Builder<Date>(){
			@Override
			public Class<Date> getType(){ return Date.class; }
			@Override
			public void writeTo(Date obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeLong(obj.getTime());
				}
			}
			@Override
			public Date parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return new Date(in.readLong());
			}
		});

		// java.sql
		register(java.sql.Date.class, new Builder<java.sql.Date>(){
			@Override
			public Class<java.sql.Date> getType(){ return java.sql.Date.class; }
			@Override
			public void writeTo(java.sql.Date obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeLong(obj.getTime());
				}
			}
			@Override
			public java.sql.Date parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return new java.sql.Date(in.readLong());
			}
		});
		register(java.sql.Timestamp.class, new Builder<java.sql.Timestamp>(){
			@Override
			public Class<java.sql.Timestamp> getType(){ return java.sql.Timestamp.class; }
			@Override
			public void writeTo(java.sql.Timestamp obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeLong(obj.getTime());
				}
			}
			@Override
			public java.sql.Timestamp parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return new java.sql.Timestamp(in.readLong());
			}
		});
		register(java.sql.Time.class, new Builder<java.sql.Time>(){
			@Override
			public Class<java.sql.Time> getType(){ return java.sql.Time.class; }
			@Override
			public void writeTo(java.sql.Time obj, GenericObjectOutput out) throws IOException
			{
				if( obj == null )
				{
					out.write0(OBJECT_NULL);
				}
				else
				{
					out.write0(OBJECT_VALUE);
					out.writeLong(obj.getTime());
				}
			}
			@Override
			public java.sql.Time parseFrom(GenericObjectInput in) throws IOException
			{
				byte b = in.read0();
				if( b == OBJECT_NULL )
					return null;
				if( b != OBJECT_VALUE )
					throw new IOException("Input format error, expect OBJECT_NULL|OBJECT_VALUE, get " + b + ".");

				return new java.sql.Time(in.readLong());
			}
		});
	}
}