optimize: hessian lisence
diff --git a/src/cotton_hessian.erl b/src/cotton_hessian.erl
new file mode 100644
index 0000000..0c8d763
--- /dev/null
+++ b/src/cotton_hessian.erl
@@ -0,0 +1,844 @@
+% ---------------------------------------------------------------------------
+%   Copyright (C) 2008 0x6e6562
+%
+%   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.
+% ---------------------------------------------------------------------------
+
+-module(cotton_hessian).
+
+-include("hessian.hrl").
+
+-export([encode/2, encode/3, encode/4, encode/5]).
+
+-export([decode/2]).
+-export([init/0]).
+-export([get_deftype/2]).
+-record(decoding_state,{type_pool = dict:new(), reference_pool = dict:new(),hash_pool = dict:new()}).
+
+%---------------------------------------------------------------------------
+% encode/2	<--	** Entry **
+%---------------------------------------------------------------------------
+
+encode(undefined, _State) -> <<$N>>;
+encode(null, _State) -> <<$N>>;
+encode(true, _State) -> <<$T>>;
+encode(false, _State) -> <<$F>>;
+encode(Value, State) when is_integer(Value) -> encode(int, Value, State);
+encode(Value, State) when is_atom(Value) -> encode(string, erlang:atom_to_binary(Value,utf8), State);
+encode(Value, State) when is_float(Value) -> encode(double, Value, State);
+encode(Value, State) when is_list(Value) -> encode(string, Value, State);
+encode(Value, State) when is_binary(Value) -> encode(string, Value, State);
+encode(Value, State) when is_tuple(Value) -> encode(struct, Value, State).
+%---------------------------------------------------------------------------
+% encode/3
+%---------------------------------------------------------------------------
+encode(struct, Input, State) ->
+  case Input of
+    #list{} -> encode(list, Input, State);
+    #map{} -> encode(map, Input, State);
+    #object{} -> encode(object, Input, State);
+    #class{} -> encode(class_store, Input, State);
+    {binary, Bin} -> encode(binary, Bin, State);
+    {date, Timestamp} -> encode(date, Timestamp, State);
+    {ref, Index} ->
+      IndexBin = encode(int, Index, State),
+      <<$Q, IndexBin/binary>>;
+    _Object ->
+      logger:debug("[encode] object ~p",[Input]),
+      encode(class_object, Input, State);
+%%			{<<>>,State};
+    {K, V} ->
+      {BK,SK} = encode(K, State),
+      {BV,SV} = encode(V, SK),
+      {<<BK/binary, BV/binary>>, SV}
+  end;
+encode(int, Int, _State) when Int >= -16, Int =< 47 ->
+  _Int = Int + 16#90,
+  <<_Int:8>>;
+encode(int, Int, _State) when Int >= -2048, Int =< 2047 ->
+  <<B1:8,B0:8>> = <<Int:16>>,
+  _B1 = B1 + 16#c8,
+  <<_B1,B0>>;
+encode(int, Int, _State) when Int >= -262144, Int =< 262143 ->
+  <<B2:8,B1:8,B0:8>> = <<Int:24>>,
+  _B2 = B2 + 16#d4,
+  <<_B2,B1,B0>>;
+encode(int, Int, _State) when Int > -16#80000001, Int < 16#80000000 ->
+  <<$I,Int:32/signed>>;
+encode(int, Int, State) ->
+  encode(long, Int, State);
+encode(long, Long, _State) when Long >= -8, Long =< 15 ->
+  _Long = Long + 16#e0,
+  <<_Long:8>>;
+encode(long, Long, _State) when Long >= -2048, Long =< 2047 ->
+  <<B1:8,B0:8>> = <<Long:16>>,
+  _B1 = B1 + 16#f8,
+  <<_B1,B0>>;
+encode(long, Long, _State) when Long >= -262144, Long =< 262143 ->
+  <<B2:8,B1:8,B0:8>> = <<Long:24>>,
+  _B2 = B2 + 16#3c,
+  <<_B2,B1,B0>>;
+encode(long, Long, _State) when Long > -16#80000001, Long < 16#80000000 ->
+  <<16#59,Long:32/signed>>;
+encode(long, Long, _State) ->
+  <<$L,Long:64/signed>>;
+encode(double, 0.0, _State) ->
+  <<16#5b>>;
+encode(double, 1.0, _State) ->
+  <<16#5c>>;
+encode(double, Double, _State) when Double >= -128.0, Double =< 127.0, Double == round(Double) ->
+  Byte = round(Double),
+  <<16#5d, Byte/signed>>;
+encode(double, Double, _State) when Double >= -32768.0, Double =< 32767.0, Double == round(Double) ->
+  Byte = round(Double),
+  <<16#5e, Byte:16/signed>>;
+encode(double, Double, _State) ->
+  case <<Double/float>> of
+    <<B24,B16,B8,B0,0,0,0,0>> -> <<16#5f,B24,B16,B8,B0>>;
+    Other -> <<$D,Other/binary>>
+  end;
+encode(string, <<>>, _State) ->
+  <<0>>;
+encode(string, [], _State) ->
+  <<0>>;
+encode(string, String, State) when is_list(String)->
+  UTF8 = xmerl_ucs:from_utf8(String),
+  Length = length(UTF8),
+  encode(sub, Length, String, [UTF8|State]);
+encode(string, String, State) when is_binary(String)->
+  encode(string, binary_to_list(String), State);
+encode(binary, <<>>, _State) ->
+  <<16#20>>;
+encode(binary, Value, _State) when size(Value) < 15 ->
+  Size = 16#20 + size(Value),
+  <<Size:8/unsigned,Value/binary>>;
+encode(binary, Value, State) ->
+  encode(binary, Value, <<>>, State);
+encode(date, {MegaSeconds,Seconds,MicroSeconds}, State) ->
+  MilliSeconds = MegaSeconds * ?MegaSeconds + Seconds * ?Seconds + MicroSeconds div ?MicroSeconds,
+  encode(date, MilliSeconds, State);
+encode(date, MilliSeconds, _State) ->
+  MinuteRemain = MilliSeconds rem (?Seconds * 60),
+  case MinuteRemain of
+    0 ->
+      Minutes = MilliSeconds div (?Seconds * 60),
+      <<16#4b,Minutes:32/unsigned>>;
+    _ -> <<16#4a,MilliSeconds:64/unsigned>>
+  end;
+encode(list, Input, [{set,SetInfo},_T]=State) when is_record(Input, list) ->
+  case find_set_info(Input#list.refNo, SetInfo) of
+    not_found -> encode(list, Input#list.len, Input#list.type, Input#list.values, State);
+    List -> encode(list, List#list.len, List#list.type, List#list.values, State)
+  end;
+encode(list, Input, State) when is_record(Input, list) ->
+  encode(list, Input#list.len, Input#list.type, Input#list.values, State);
+encode(list, List, State) ->
+  ListLength = length(List),
+  encode(fixedlist, ListLength, List, State);
+encode(vlist, List, State) ->
+  case List of
+    [] -> <<$W,$Z>>;
+    _ -> encode(vlist, List, <<$W>>, State)
+  end;
+encode(map, Input, [{set,SetInfo},_T]=State) when is_record(Input, map) ->
+  case find_set_info(Input#map.refNo, Input#map.type, SetInfo) of
+    not_found -> encode(map, Input#map.dict, State);
+    Map -> encode(map, Map#map.dict, State)
+  end;
+encode(map, Input, State) when is_record(Input, map) ->
+  encode(map, Input#map.dict, State);
+encode(map, Dict, State) ->
+  List = dict:to_list(Dict),
+  Encoder = fun({Key, Value}, {AccIn, StateIn}) ->
+    % Key
+    RK = encode(Key, StateIn),
+    {KeyBin, NewStateKey} = case RK of
+                              {_, _} -> RK;
+                              KeyB -> {KeyB, StateIn}
+                            end,
+    % Value
+    RV = encode(Value, NewStateKey),
+    {ValueBin, NewStateValue} = case RV of
+                                  {_, _} -> RV;
+                                  ValueB -> {ValueB, NewStateKey}
+                                end,
+    % Acc Out
+    {<<AccIn/binary,KeyBin/binary,ValueBin/binary>>, NewStateValue}
+            end,
+  {AccOut, NewState} = lists:foldl(Encoder, {<<$H>>, State}, List),
+  {<<AccOut/binary,$Z>>, NewState};
+encode(class, #class{name=Name, fields=Fields}, State) ->
+  % type
+  NameBin = encode(Name, State),
+  % fields length
+  FieldsLen = length(Fields),
+  FieldsLenBin = encode(int, FieldsLen, State),
+  % fields
+  encode(list, Fields, <<$C,NameBin/binary,FieldsLenBin/binary>>, State);
+encode(class_store, Input, [{set,SetInfo},ClassList]=State) ->
+  {Bin, _} = encode(class, Input, State),
+  {Bin, [{set,SetInfo},[Input#class{encoded=true}|ClassList]]};
+encode(class_store, Input, State) ->
+  {Bin, _} = encode(class, Input, State),
+%%	{Bin, [Input#class{encoded=true}|State]};
+  {Bin, State};
+encode(object, Input, [{set,SetInfo},T]=State) when is_record(Input, object) ->
+  ClassRes = class(Input#object.typeRef, Input#object.class, [], T),
+  {BaseBin, TypeNum, C, NewState} = case ClassRes of
+                                      {encoded, Class, TypeNo} -> {<<>>, TypeNo, Class, State};
+                                      {Class, TypeNo, NewST} ->
+                                        {Bin, NewClassST} = encode(class, Class, NewST),
+                                        {Bin, TypeNo, Class, [{set,SetInfo},NewClassST]}
+                                    end,
+  case find_set_info(Input#object.refNo, C#class.name, SetInfo) of
+    not_found -> encode(object, BaseBin, TypeNum, Input#object.values, NewState);
+    Obj -> encode(object, BaseBin, TypeNum, Obj#object.values, NewState)
+  end;
+encode(object, Input, State) when is_record(Input, object) ->
+  ClassRes = class(Input#object.typeRef, Input#object.class, [], State),
+
+  {BaseBin, TypeNum, NewState} = case ClassRes of
+                                   {encoded, _Class, TypeNo} -> {<<>>, TypeNo, State};
+                                   {Class, TypeNo, NewST} ->
+                                     {Bin, NewClassST} = encode(class, Class, NewST),
+                                     {Bin, TypeNo, NewClassST}
+                                 end,
+  encode(object, BaseBin, TypeNum, Input#object.values, NewState);
+encode(class_object,Input,State)->
+  [NativeType|Values] = tuple_to_list(Input),
+  {ClassEncodingBin, EncodedRef, NewState} =
+    case type_encoding:visit(NativeType,State) of
+      {ref, Ref} ->
+%%				encode_object(type_information, {ref, Ref}, State);
+        %% todo need check
+        {<<>>,Ref,State};
+      {hash, Ref, Typedef , State0} ->
+        Class = typedef_to_class(Typedef,Ref),
+        {Bin,NewStateClass} = encode(class_store,Class,State0),
+        {Bin,Ref,NewStateClass}
+%%				encode(type_information, {hash, Ref,Typedef }, State0)
+    end,
+  encode(object, ClassEncodingBin, EncodedRef, Values, NewState);
+%%	{AccOut, _NewState} = lists:foldl(fun encode/2,{<<>>, NewState},Values),
+%%	{<<ClassEncodingBin/binary,$o,EncodedRef/binary,AccOut/binary>>, _NewState};
+
+encode(method, Method, State) when is_atom(Method) ->
+  String = atom_to_list(Method),
+  encode(method, String, State);
+encode(method, Method, _State) when is_binary(Method) ->
+  CamMethod = erlang_to_camel_case(Method),
+  Size = size(CamMethod),
+  <<$m,Size:16/unsigned,CamMethod/binary>>;
+encode(method, String, _State) when is_list(String) ->
+  CamString = erlang_to_camel_case(String),
+  Length = string:len(CamString),
+  Bin = list_to_binary(CamString),
+  <<$m,Length:16/unsigned,Bin/binary>>;
+encode(reply, ok, _State) ->
+  <<$H,16#02,16#00,$R,16#01,$N>>;
+encode(reply, {ok, Object}, State) ->
+  encode(reply, Object, State);
+encode(reply, {error, {Error, Reason} }, State) ->
+  encode(fault, Error, Reason, State);
+encode(reply, Object, State) ->
+  case encode(Object, State) of
+    {Bin, _NewState} -> Bin;
+    Bin -> Bin
+  end,
+  <<$H,16#02,16#00,$R,Bin/binary>>.
+%---------------------------------------------------------------------------
+% encode/4
+%---------------------------------------------------------------------------
+encode(sub, Length, String, _State) when Length < 32 ->
+  Bin = list_to_binary(String),
+  <<Length:8,Bin/binary>>;
+encode(sub, Length, String, _State) when Length < 256 ->
+  Bin = list_to_binary(String),
+  <<16#30,Length:8,Bin/binary>>;
+encode(sub, Length, String, _State) when Length < 512 ->
+  Bin = list_to_binary(String),
+  <<16#31,(Length-256):8,Bin/binary>>;
+encode(sub, Length, String, _State) when Length < 768 ->
+  Bin = list_to_binary(String),
+  <<16#32,(Length-512):8,Bin/binary>>;
+encode(sub, Length, String, _State) when Length < ?CHUNK_SIZE ->
+  Bin = list_to_binary(String),
+  <<16#33,(Length-768):8,Bin/binary>>;
+encode(sub, Length, String, _State) when Length =:= ?CHUNK_SIZE ->
+  Bin = list_to_binary(String),
+  <<$S,Length:16,Bin/binary>>;
+encode(sub, Length, _String, [UTF8|State]) ->
+  encode(string, Length, UTF8, <<>>, State);
+encode(binary, Value, <<>>, _State) when size(Value) =< ?CHUNK_SIZE ->
+  Size = size(Value),
+  <<$B,Size:16,Value/binary>>;
+encode(binary, Value, Acc, _State) when size(Value) =< ?CHUNK_SIZE ->
+  Size = size(Value),
+  <<Acc/binary,$B,Size:16,Value/binary>>;
+encode(binary, Value, <<>>, State) ->
+  <<Chunk:?CHUNK_SIZE/binary,Rest/binary>> = Value,
+  encode(binary, Rest, <<$b,?CHUNK_SIZE:16,Chunk/binary>>, State);
+encode(binary, Value, Acc, State) ->
+  <<Chunk:?CHUNK_SIZE/binary,Rest/binary>> = Value,
+  encode(binary, Rest, <<Acc/binary,$b,?CHUNK_SIZE:16,Chunk/binary>>, State);
+encode(list, List, Acc0, State) when is_binary(Acc0) ->
+  lists:foldl(fun encode_accumulate/2, {Acc0,State}, List);
+encode(list, Type, List, State) ->
+  ListLength = length(List),
+  encode(list, ListLength, Type, List, State);
+encode(vlist, List, Acc0, State) when is_binary(Acc0) ->
+  {AccOut, NewState} = lists:foldl(fun encode_accumulate/2, {Acc0,State}, List),
+  {<<AccOut/binary,$Z>>, NewState};
+encode(vlist, Type, List, State) ->
+  TypeBin = encode(Type, State),
+  case List of
+    [] -> <<$U,TypeBin/binary,$Z>>;
+    _ -> encode(vlist, List, <<$U,TypeBin/binary>>, State)
+  end;
+encode(fixedlist, ListLength, List, State) ->
+  case ListLength < 8 of
+    true ->
+      ListLengthFlag = 16#78 + ListLength,
+      case List of
+        [] -> <<ListLengthFlag:8>>;
+        _ -> encode(list, List, <<ListLengthFlag:8>>, State)
+      end;
+    false ->
+      ListLengthBin = encode(int, ListLength, State),
+      encode(list, List, <<$X,ListLengthBin/binary>>, State)
+  end;
+encode(fault, _Error, _Reason, State) ->
+  encode(fault, <<"ServiceException">>, _Error, _Reason, State);
+encode(call, Method, Args, State) ->
+  encode(call, Method, Args, fun encode_accumulate/2, State).
+%---------------------------------------------------------------------------
+% encode/5
+%---------------------------------------------------------------------------
+encode(string, Length, UTF8, Acc, _State) when Length =< ?CHUNK_SIZE ->
+  Bin = list_to_binary(xmerl_ucs:to_utf8(UTF8)),
+  <<Acc/binary,$S,Length:16,Bin/binary>>;
+encode(string, Length, UTF8, Acc, State) ->
+  {Chunk, Rest} = lists:split(?CHUNK_SIZE, UTF8),
+  ChunkBin = list_to_binary(xmerl_ucs:to_utf8(Chunk)),
+  encode(string, (Length-?CHUNK_SIZE), Rest, <<Acc/binary,$R,?CHUNK_SIZE:16,ChunkBin/binary>>, State);
+encode(list, -1, untyped, List, State) ->
+  encode(vlist, List, State);
+encode(list, -1, Type, List, State) ->
+  encode(vlist, Type, List, State);
+encode(list, Len, untyped, List, State) ->
+  encode(fixedlist, Len, List, State);
+encode(list, Len, Type, List, State) ->
+  TypeBin = encode(Type, State),
+  if
+    Len < 8 ->
+      ListLengthFlag = 16#70 + Len,
+      case List of
+        [] -> <<ListLengthFlag:8,TypeBin/binary>>;
+        _ -> encode(list, List, <<ListLengthFlag:8,TypeBin/binary>>, State)
+      end;
+    true ->
+      ListLengthBin = encode(int, Len, State),
+      encode(list, List, <<$V,TypeBin/binary,ListLengthBin/binary>>, State)
+  end;
+encode(object, BaseBin, TypeNo, Values, State) ->
+  IndexBin = if
+               TypeNo < 16 ->
+                 logger:debug("[encode] encode object TypeNo ~p",[TypeNo]),
+                 IndexWrap = TypeNo + 16#60,
+                 <<IndexWrap:8>>;
+               true ->
+                 IndexWrap = encode(int, TypeNo, State),
+                 <<$O, IndexWrap/binary>>
+             end,
+  {Bin, NewState} = encode(list, Values, IndexBin, State),
+  {<<BaseBin/binary,Bin/binary>>, NewState};
+encode(call, Method, Args, Fun, State) when is_function(Fun) ->
+  MethodBin = encode(string, Method, State),
+  ArgsCount = encode(int, erlang:length(Args), State),
+  {Bin, _NewState} = lists:foldl(Fun, {<<>>, State}, Args),
+  <<$H,2,0,$C,MethodBin/binary,ArgsCount/binary,Bin/binary>>;
+encode(fault, Code, _Error, _Reason, State) ->
+  EncodedCode = encode(string,Code, State),
+  <<131,100,_L2:16/unsigned,Error/binary>> = term_to_binary(_Error),
+  EncodedError = encode(string,Error, State),
+  <<$H,16#02,16#00,$F,$H,4,"code",EncodedCode/binary,7,"message",EncodedError/binary,6,"detail",31,"Stack trace not yet implemented",$Z>>.
+
+%---------------------------------------------------------------------------
+% Utility methods
+%---------------------------------------------------------------------------
+erlang_to_camel_case(String) when is_binary(String) ->
+  AsList = binary_to_list(String),
+  AsCamel = lists:foldl(fun camelize/2,[],AsList),
+  list_to_binary(AsCamel);
+erlang_to_camel_case(String) when is_atom(String) ->
+  AsList = atom_to_list(String),
+  AsCamel = lists:foldl(fun camelize/2,[],AsList),
+  list_to_binary(AsCamel).
+
+camelize(Element,Acc) when Element == $_ -> [$_|Acc];
+camelize(Element,[$_|Acc]) -> lists:append(Acc,[Element - 16#20]);
+camelize(Element,Acc) -> lists:append(Acc,[Element]).
+
+encode_accumulate(Value, {Acc, State}) ->
+  logger:debug("[encode] encode_accumulate value ~p",[Value]),
+  case encode(Value, State) of
+    {Encoded,NewState} -> {<<Acc/binary,Encoded/binary>>,NewState};
+    Encoded -> {<<Acc/binary,Encoded/binary>>,State}
+  end.
+
+find_set_info(RefNo, SetInfo) ->
+  find_set_info(RefNo, untyped, SetInfo).
+find_set_info(_RefNo, _Type, []) ->
+  not_found;
+find_set_info(RefNo, Type, [Set|SetInfo]) ->
+  if
+    RefNo =:= Set#set.ref -> Set#set.value;
+    true ->
+      case equal(Type, Set#set.ref) of
+        true -> Set#set.value;
+        false -> find_set_info(RefNo, Type, SetInfo)
+      end
+  end.
+
+type_index(Type, [CurrentType|RestTypes]) when is_record(Type, class) ->
+  case equal(Type#class.name, CurrentType#class.name) of
+    true -> length(RestTypes);
+    false -> type_index(Type, RestTypes)
+  end;
+type_index(Type, [CurrentType|RestTypes]) ->
+  case equal(Type, CurrentType#class.name) of
+    true -> length(RestTypes);
+    false -> type_index(Type, RestTypes)
+  end.
+
+get_type_no(C, RestClasses) when is_record(C, class) ->
+  case C#class.typeNo of
+    -1 -> length(RestClasses);
+    _ -> C#class.typeNo
+  end.
+
+get_type(CListH, C, CListE) when is_record(C, class) ->
+  TypeNo = get_type_no(C, CListE),
+  case C#class.encoded of
+    true -> {encoded, C, TypeNo};
+    false -> {C, TypeNo, CListH++[C#class{encoded=true}|CListE]}
+  end.
+
+class(-1, auto, [], [C|CListE]) ->
+  get_type([], C, CListE);
+class(-1, Class, CListH, [C|CListE]) when is_record(Class, class) ->
+  case Class#class.name of
+    auto ->
+      case CListH of
+        [] -> get_type([], C, CListE);
+        [H|T] ->get_type([], H, T++[C|CListE])
+      end;
+    _ ->
+      case equal(Class#class.name, C#class.name) of
+        true -> get_type(CListH, C, CListE);
+        false -> class(-1, Class, CListH++[C], CListE)
+      end
+  end;
+class(-1, Class, CListH, [C|CListE]) ->
+  case equal(Class, C#class.name) of
+    true -> get_type(CListH, C, CListE);
+    false -> class(-1, Class, CListH++[C], CListE)
+  end;
+class(RefNo, _Class, CListH, [C|CListE]) ->
+  if
+    RefNo =:= length(CListE) -> get_type(CListH, C, CListE);
+    true -> class(RefNo, _Class, CListH++[C], CListE)
+  end.
+
+equal(S1, S2) when is_binary(S1) ->
+  if
+    S1 =:= S2 -> true;
+    true ->
+      S1List = binary_to_list(S1),
+      if
+        S1List =:= S2 -> true;
+        true -> false
+      end
+  end;
+equal(S1, S2) when is_list(S1) ->
+  if
+    S1 =:= S2 -> true;
+    true ->
+      S1Binary = list_to_binary(S1),
+      if
+        S1Binary =:= S2 -> true;
+        true -> false
+      end
+  end;
+equal(_S1, _S2) ->
+  false.
+
+
+typedef_to_class(Typedef,DefineNo)->
+  #class{typeNo=DefineNo, name=Typedef#type_def.foreign_type, fields=Typedef#type_def.fieldnames}.
+
+
+
+
+%---------------------------------------------------------------------------
+% Decoding
+%---------------------------------------------------------------------------
+decode_str(Rest, 0, R) ->
+  {list_to_binary(xmerl_ucs:to_utf8(lists:reverse(R))), Rest};
+decode_str(<<C/utf8, Rest/binary>>, N, R) ->
+  decode_str(Rest, N-1, [C|R]).
+
+% Call
+decode(<<$H,?M,?m,$C,Bin/binary>>, State) ->
+  {Rest, Function, _State} = decode(Bin,State),
+  {Rest2, Count, __State} = decode(Rest,_State),
+  case decode(list, Rest2,Count,[], __State) of
+    {error, Encoded} ->
+      {error, Encoded};
+    {not_found, Hash} ->
+      {not_found, Hash};
+    {_Rest, Arguments, _NewState} ->
+      [Function, Arguments]
+  end;
+% Fault
+decode(<<$H,?M,?m,$F,
+  Rest/binary>>, State) ->
+  {_Rest,#map{dict=Dict},_State} = decode(Rest, State),
+  {ok, Message} = dict:find(<<"message">>, Dict),
+  {error, Message};
+% Reply
+decode(<<$H,?M,?m,$R,Args/binary>>, State) ->
+  case decode(Args,[], State) of
+    {<<>>, Decoded,_State} ->
+      TypeSet = get_type_set(_State),
+      case Decoded of
+        [Value] ->
+          {Value,TypeSet};
+        [H|T] ->
+          {[H|T],TypeSet}
+      end;
+    {error, Encoded} ->
+      {error, Encoded}
+  end;
+% Binaries
+decode(<<16#20,Rest/binary>>, State) -> {Rest, <<>>, State};
+decode(<<Len:8/unsigned,Rest/binary>>, State) when Len =< 16#2f, 16#20 < Len ->
+  _Len = Len - 16#20,
+  <<Bin:_Len/binary,_Rest/binary>> = Rest,
+  {_Rest, Bin, State};
+decode(<<$B,Len:16/unsigned,Bin:Len/binary,Rest/binary>>, State) -> {Rest, Bin, State};
+decode(<<$b,Rest/binary>>,State) -> decode(<<$b,Rest/binary>>, [], State);
+%% Booleans
+decode(<<$T,Rest/binary>>, State) -> {Rest, true, State};
+decode(<<$F,Rest/binary>>, State) -> {Rest, false, State};
+%% Dates
+decode(<<16#4a,Date:64/unsigned,Rest/binary>>, State) ->
+  MegaSecs = Date div ?MegaSeconds,
+  Secs = (Date - MegaSecs * ?MegaSeconds) div ?Seconds,
+  MicroSecs = (Date - MegaSecs * ?MegaSeconds - Secs * ?Seconds) * ?MicroSeconds,
+  {Rest, {MegaSecs, Secs, MicroSecs}, State};
+decode(<<16#4b,Date:32/unsigned,Rest/binary>>, State) ->
+  MegaSecs = (Date * 60000) div ?MegaSeconds,
+  Secs = (Date * 60000 - MegaSecs * ?MegaSeconds) div ?Seconds,
+  {Rest, {MegaSecs, Secs, 0}, State};
+%% Doubles
+decode(<<16#5b,Rest/binary>>, State)-> {Rest, 0.0, State};
+decode(<<16#5c,Rest/binary>>, State)-> {Rest, 1.0, State};
+decode(<<16#5d,Int:8/signed,Rest/binary>>, State)-> {Rest, float(Int), State};
+decode(<<16#5e,Int:16/signed,Rest/binary>>, State)-> {Rest, float(Int), State};
+decode(<<16#5f,Int:32/signed,Rest/binary>>, State)->
+  <<Double:64/float>> = <<Int:32,0,0,0,0>>,
+  {Rest, Double, State};
+decode(<<$D,Double:64/float,Rest/binary>>, State)-> {Rest, Double, State};
+%% Ints
+decode(<<$I,Int:32/signed,Rest/binary>>, State)-> {Rest, Int, State};
+decode(<<Int:8,Rest/binary>>, State) when Int >= 16#80, Int =< 16#bf -> {Rest, Int - 16#90, State};
+decode(<<B2:8,B1:8,B0:8,Rest/binary>>, State) when B2 >= 16#d0, B2 =< 16#d7 -> {Rest, ((B2 - 16#d4) bsl 16) + (B1 bsl 8) + B0, State};
+decode(<<B1:8,B0:8,Rest/binary>>, State) when B1 >= 16#c0, B1 =< 16#cf -> {Rest, ((B1 - 16#c8) bsl 8) + B0, State};
+%% Longs
+decode(<<$L,Long:64/signed,Rest/binary>>, State)-> {Rest, Long, State};
+decode(<<16#59,Long:32/signed,Rest/binary>>, State) -> {Rest, Long, State};
+decode(<<Long:8,Rest/binary>>, State) when Long >= 16#d8, Long =< 16#ef -> {Rest, Long - 16#e0, State};
+decode(<<B2:8,B1:8,B0:8,Rest/binary>>, State) when B2 >= 16#38, B2 =< 16#3f -> {Rest, ((B2 - 16#3c) bsl 16) + (B1 bsl 8) + B0, State};
+decode(<<B1:8,B0:8,Rest/binary>>, State) when B1 >= 16#f0, B1 =< 16#ff -> {Rest, ((B1 - 16#f8) bsl 8) + B0, State};
+%% Strings
+decode(<<0,Rest/binary>>, State) -> {Rest, <<>>, State};
+decode(<<Len:8,Rest/binary>>, State) when Len < 32 ->
+  {String, NewRest} = decode_str(Rest, Len, []),
+  {NewRest, String, State};
+decode(<<B1:8,B0:8,Rest/binary>>, State) when B1 =< 16#33,B1 >= 16#30 ->
+  Len = ((B1 - 16#30) bsl 8) + B0,
+  {String, NewRest} = decode_str(Rest, Len, []),
+  {NewRest, String, State};
+decode(<<$S,Len:16/unsigned,Rest/binary>>, State) ->
+  {String, NewRest} = decode_str(Rest, Len, []),
+  {NewRest, String, State};
+decode(<<$R,Rest/binary>>, State) -> decode(<<$R,Rest/binary>>,[], State);
+%% Nulls
+decode(<<$N,Rest/binary>>, State) -> {Rest, undefined, State};
+%% References
+decode(<<$Q,Bin/binary>>, State)->
+  {Rest, IntRef, _State} = decode(Bin,State),
+  {Rest, {ref, IntRef}, _State};
+%% Maps
+decode(<<$M,Map/binary>>, State) ->
+  {Rest,Type,_State} = decode(Map, State),
+  {_Refnum,__State} = visit(#type_def{foreign_type = map},_State),
+  {_Rest,Dict, NewState} = decode(map, Rest, dict:new(), __State),
+  {_Rest,#map{refNo=_Refnum,type=Type,dict=Dict},NewState};
+decode(<<$H,Map/binary>>, State) ->
+  {_Refnum,_State} = visit(#type_def{foreign_type = map},State),
+  {_Rest,Dict, NewState} = decode(map, Map, dict:new(), _State),
+  {_Rest,#map{refNo=_Refnum,dict=Dict},NewState};
+%% Lists
+% 'V' type int value*   # fixed-length list
+decode(<<$V,Bin/binary>>, State) ->
+  {Rest1,_Type,_State1} = decode(Bin,State),
+  {_Refnum,__State} = visit(#type_def{foreign_type = list},_State1),
+  {Rest2,Len,_State2} = decode(Rest1,__State),
+  {NewRest,List,NewState} = decode(list, Rest2, Len, [], _State2),
+  {NewRest,#list{refNo=_Refnum,len=Len,type=_Type,values=List},NewState};
+% 'X' int value*        # fixed-length untyped list
+decode(<<$X,Bin/binary>>, State) ->
+  {Rest1,Len,_State} = decode(Bin,State),
+  {_Refnum,__State} = visit(#type_def{foreign_type = list},_State),
+  {NewRest,List,NewState} = decode(list, Rest1, Len, [], __State),
+  {NewRest,#list{refNo=_Refnum,len=Len,values=List},NewState};
+% [x70-77] type value*  # fixed-length typed list
+decode(<<H:5,Len:3,Bin/binary>>, State) when H == 14 ->
+  {Rest1,_Type,_State} = decode(Bin,State),
+  {_Refnum,__State} = visit(#type_def{foreign_type = list},_State),
+  {NewRest,List,NewState} = decode(list, Rest1, Len, [], __State),
+  {NewRest,#list{refNo=_Refnum,len=Len,type=_Type,values=List},NewState};
+% [x78-7f] value*       # fixed-length untyped list
+decode(<<H:5,Len:3,Bin/binary>>, State) when H == 15 ->
+  {_Refnum,_State} = visit(#type_def{foreign_type = list},State),
+  {NewRest,List,NewState} = decode(list, Bin, Len, [], _State),
+  {NewRest,#list{refNo=_Refnum,len=Len,values=List},NewState};
+% 'U' type value* 'Z'   # variable-length list
+decode(<<$U,Bin/binary>>, State) ->
+  {Rest1,_Type,_State} = decode(Bin,State),
+  {_Refnum,__State} = visit(#type_def{foreign_type = list},_State),
+  {NewRest,List,NewState} = decode(list, Rest1, [], __State),
+  {NewRest,#list{refNo=_Refnum,type=_Type,values=List},NewState};
+% 'W' value* 'Z'        # variable-length untyped list
+decode(<<$W,Bin/binary>>, State) ->
+  {_Refnum,_State} = visit(#type_def{foreign_type = list},State),
+  {NewRest,List,NewState} = decode(list, Bin, [], _State),
+  {NewRest,#list{refNo=_Refnum,values=List},NewState};
+decode(<<$C,Bin/binary>>, State0) ->
+  {Rest1,Type,State1} = decode(Bin,State0),
+  {Rest, TypeDef, State} = decode(type_definition,Type,Rest1,State1),
+  NewState = hash_store(TypeDef,State),
+  decode(Rest,NewState);
+decode(<<$O,Bin/binary>>, State) ->
+  {Rest,Ref,_State} = decode(Bin, State),
+  case hash_lookup(Ref, _State) of
+    {not_found, Ref} ->
+      {Rest, {not_found, Ref}, _State};
+    ForeignView ->
+      #type_def{fieldnames = ForeignFieldNames} = ForeignView,
+      {_Refnum,__State} = visit(ForeignView,_State),
+      Count = count_fields(ForeignView),
+      case decode(field, Rest, Count,[], __State) of
+        {not_found,Hash} ->
+          {not_found,Hash};
+        {_Rest,FieldValues, NewState} ->
+          Object = project_native_view(ForeignFieldNames,FieldValues,ForeignView),
+          {_Rest, #object{refNo=_Refnum, typeRef=Ref,values=Object}, NewState}
+      end
+  end;
+decode(<<H:4,Ref:4,Rest/binary>>, _State) when H == 6 ->
+  logger:debug("decode data find ref ~p",[Ref]),
+  case hash_lookup(Ref, _State) of
+    {not_found, Ref} ->
+      {Rest, {not_found, Ref}, _State};
+    ForeignView ->
+      #type_def{fieldnames = ForeignFieldNames} = ForeignView,
+      {_Refnum,__State} = visit(ForeignView,_State),
+      Count = count_fields(ForeignView),
+      case decode(field, Rest, Count,[], __State) of
+        {not_found,Hash} ->
+          {not_found,Hash};
+        {_Rest,FieldValues, NewState} ->
+          Object = project_native_view(ForeignFieldNames,FieldValues,ForeignView),
+          {_Rest, #object{refNo=_Refnum, typeRef=Ref,values=Object}, NewState}
+      end
+  end;
+%% Anything else
+decode(<<Unexpected/binary>>, State) ->
+  {error, cotton_hessian:encode(fault, <<"ProtocolException">>, unexpected_byte_sequence, Unexpected, State) }.
+decode(<<$b,Len:16/unsigned,Bin:Len/binary,$b,Rest/binary>>, Acc, State) ->
+  decode(<<$b,Rest/binary>>,Acc ++ [Bin], State);
+decode(<<$b,Len:16/unsigned,Bin:Len/binary,$B,Rest/binary>>, Acc, State) ->
+  _Acc = Acc ++ [Bin],
+  {_Rest,_Bin, State} = decode(<<$B,Rest/binary>>, State),
+  {_Rest, list_to_binary(_Acc ++ [_Bin]), State};
+decode(<<$R,Len:16/unsigned,Rest/binary>>,Acc, State) ->
+  {_String, NewRest} = decode_str(Rest, Len, []),
+  <<H:8,_/binary>> = NewRest,
+  case H of
+    $R -> decode(NewRest,list_to_binary([Acc|[_String]]), State);
+    $S -> {_Rest,_Bin, _State} = decode(NewRest, State),
+      _Acc2 =[Acc |[_String]],
+      {_Rest, list_to_binary(_Acc2 ++ [_Bin]), _State}
+  end;
+decode(<<>>, List, State) -> {<<>>, List, State};
+decode(<<$Z>>, List, State) -> {<<>>, List, State};
+decode(Args, List, State) ->
+  case decode(Args,State) of
+    {Rest,{ref, Ref}, _State} ->
+      decode(Rest, List ++ [{ref, Ref}] , _State);
+    {Rest, [H|T], _State} ->
+      decode(Rest, List ++ [H|T], _State);
+    {Rest, Result, _State} ->
+      decode(Rest, List ++ [Result], _State);
+    {error, Encoded} ->
+      {error, Encoded}
+  end.
+decode(map, <<$Z>>, Dict, State) -> {<<>>,Dict, State};
+decode(map, <<$Z,Rest/binary>>, Dict, State) -> {Rest,Dict, State};
+decode(map, Bin, Dict, State) ->
+  {_Rest, Key, _State} = decode(Bin, State),
+  case decode(_Rest, _State) of
+    {Rest, {ref, Ref}, __State} ->
+      %Value = lists:nth(Ref + 1, List),
+      Value = Ref,
+      decode(map, Rest, dict:store(Key, {ref, Value}, Dict), __State);
+    {Rest, Value, __State} ->
+      decode(map, Rest, dict:store(Key, Value, Dict), __State)
+  end;
+decode(list, <<>>, List, State) -> {<<>>,lists:reverse(List), State};
+decode(list, <<$Z>>, List, State) -> {<<>>,lists:reverse(List), State};
+decode(list, <<$Z,Rest/binary>>, List, State) -> {Rest, lists:reverse(List), State};
+decode(list, Bin, List, State) ->
+  case decode(Bin, State) of
+    {error, Encoded} ->
+      {error, Encoded};
+    {not_found,Hash} ->
+      {not_found, Hash};
+    {_Rest, {not_found, Hash}, _State} ->
+      {not_found, Hash};
+    {Rest, Value, _State} ->
+      decode(list, Rest, [Value|List], _State)
+  end;
+decode(type_definition, ForeignType, Bin, State) ->
+  {Rest,Count, _State} = decode(Bin, State),
+  {NewRest,FieldNames, NewState} = decode(field, Rest, Count, [], _State),
+  {TypeDef,NewState2} = build_foreign_view(ForeignType,FieldNames,NewState),
+  {NewRest, TypeDef, NewState2}.
+decode(list, Bin, 0, List, State) -> {Bin, lists:reverse(List), State};
+decode(list, Bin, Len, List, State) ->
+  case decode(Bin, State) of
+    {error, Encoded} ->
+      {error, Encoded};
+    {not_found,Hash} ->
+      {not_found, Hash};
+    {_Rest, {not_found, Hash}, _State} ->
+      {not_found, Hash};
+    {Rest, Value, _State} ->
+      decode(list, Rest, Len - 1, [Value|List], _State)
+  end;
+decode(field, Rest, 0, Acc, State) -> {Rest, Acc, State};
+decode(field, <<$Z,Rest/binary>>, _Count, Acc, State) -> {Rest, Acc, State};
+decode(field, Bin, Count, Acc, State) ->
+  {Rest,Field, _State} = decode(Bin, State),
+  case Field of
+    {not_found,Hash} ->
+      {not_found,Hash};
+    _ ->
+      decode(field, Rest, Count - 1, Acc ++ [Field], _State)
+  end.
+
+get_type_set(#decoding_state{type_pool = Pool}) ->
+  case dict:to_list(Pool) of
+    [] -> [];
+    Data -> [Value || {_Key,Value} <- Data]
+  end.
+
+build_foreign_view(ForeignType,FieldNames,State) ->
+  logger:debug("[DECODE] build_foreign_view ForeignType ~p FieldNames ~p",[ForeignType,FieldNames]),
+  ForeignView = FieldNames,
+  #decoding_state{type_pool = OldPool} = State,
+  Native = dict:size(OldPool),
+  NewPool = dict:store(Native,
+    #type_def{
+      defineNo = Native,
+%%            native_type = Native,
+      foreign_type = ForeignType,
+      fieldnames = ForeignView},
+    OldPool),
+  {
+    #type_def{defineNo = Native,
+%%            native_type = Native,
+      foreign_type = ForeignType,
+      fieldnames = ForeignView},
+    State#decoding_state{type_pool = NewPool}
+  }.
+
+project_native_view(ForeignView,ForeignData,
+    #type_def{native_type = _NativeType, foreign_type = _ForeignType, fieldnames = NativeView}) ->
+  AsDict = dict:from_list(lists:zip(ForeignView,ForeignData)),
+  NativeData = [dict:fetch(Key,AsDict) || Key <- NativeView],
+  NativeData.
+
+visit(TypeDef, State = #decoding_state{reference_pool = OldPool}) ->
+  logger:debug("[DECODE] visit typedef ~p",[TypeDef]),
+  Size = dict:size(OldPool),
+  NewPool = dict:store(Size, TypeDef, OldPool),
+  {Size,State#decoding_state{reference_pool = NewPool}}.
+
+hash_lookup(Hash,#decoding_state{hash_pool = HashPool} = State) ->
+  case dict:find(Hash,HashPool) of
+    error->
+      {not_found, Hash};
+    {ok,TypeDef}->
+      TypeDef
+  end.
+%%    init(false),
+%%    case ets:lookup(hashes, Hash) of
+%%        [] ->
+%%            {not_found, Hash};
+%%        [{Hash,TypeDef}] ->
+%%            TypeDef
+%%    end.
+
+hash_store(TypeDef = #type_def{defineNo = Hash}, #decoding_state{hash_pool = HashPool} = State) ->
+%%    init(false),
+%%    ets:insert(hashes,{Hash,TypeDef}),
+  logger:debug("[DECODE] hash store typedef ~p",[TypeDef]),
+  NewPool = dict:store(Hash,TypeDef,HashPool),
+  State#decoding_state{hash_pool = NewPool}.
+
+init() -> init(true).
+
+init(Delete) when is_boolean(Delete) ->
+%%    case ets:info(hashes) of
+%%        undefined ->
+%%            ets:new(hashes,[private,named_table]);
+%%        _ ->
+%%            if
+%%                Delete ->
+%%                    ets:delete(hashes),
+%%                    ets:new(hashes,[private,named_table]);
+%%                true ->
+%%                    ok
+%%            end
+%%    end,
+  #decoding_state{}.
+
+count_fields(#type_def{fieldnames = FieldNames}) -> length(FieldNames).
+
+%% extend func
+get_deftype(Ref,#decoding_state{type_pool = Pool})->
+  dict:fetch(Ref,Pool).
\ No newline at end of file
diff --git a/src/dubbo_codec.erl b/src/dubbo_codec.erl
index 2574b29..f2a9301 100644
--- a/src/dubbo_codec.erl
+++ b/src/dubbo_codec.erl
@@ -66,22 +66,22 @@
     {ok,Bin}.
 
 encode_request_data(dubbo_event,Request,Data,State) ->
-    Bin = hessianEncode:encode(Data,State),
+    Bin = cotton_hessian:encode(Data,State),
     {ok,Bin};
 encode_request_data(dubbo_rpc_invocation,Request,Data,State) ->
     METHOD_NAME = Data#dubbo_rpc_invocation.methodName,
     METHOD_ARGS_TYPES = Data#dubbo_rpc_invocation.parameterDesc,
     RequestList = [
-        hessianEncode:encode(?DUBBO_VERSION, State), %% dubbo version
-        hessianEncode:encode(Data#dubbo_rpc_invocation.className, State),
-        hessianEncode:encode(Data#dubbo_rpc_invocation.classVersion, State),
-        hessianEncode:encode(METHOD_NAME, State),
-        hessianEncode:encode(METHOD_ARGS_TYPES, State)
+        cotton_hessian:encode(?DUBBO_VERSION, State), %% dubbo version
+        cotton_hessian:encode(Data#dubbo_rpc_invocation.className, State),
+        cotton_hessian:encode(Data#dubbo_rpc_invocation.classVersion, State),
+        cotton_hessian:encode(METHOD_NAME, State),
+        cotton_hessian:encode(METHOD_ARGS_TYPES, State)
     ],
     {ArgsBin,State2} = encode_arguments(Data,State),
     AttachDict = dict:from_list(Data#dubbo_rpc_invocation.attachments),
     AttachMaps = #map{dict = AttachDict },
-    {AttachBinay,_} = hessianEncode:encode(AttachMaps, State2),
+    {AttachBinay,_} = cotton_hessian:encode(AttachMaps, State2),
     RequestData = erlang:iolist_to_binary(RequestList ++ [ArgsBin,AttachBinay]),
     {ok,RequestData}.
 
@@ -109,18 +109,18 @@
     {ok,Bin} = encode_response_data(DataType,Response,Response#dubbo_response.data,State),
     {ok,Bin}.
 encode_response_data(dubbo_event,Response,Data,State) ->
-    Bin = hessianEncode:encode(Data,State),
+    Bin = cotton_hessian:encode(Data,State),
     {ok,Bin};
 encode_response_data(dubbo_rpc_invocation,Response,Data,State) ->
     Result = case Data of
         null ->
             [
-                hessianEncode:encode(?RESPONSE_NULL_VALUE, State)
+                cotton_hessian:encode(?RESPONSE_NULL_VALUE, State)
             ];
         _ ->
             {ArgsBin,_State2} = encode_arguments(Data,State),
             [
-                hessianEncode:encode(?RESPONSE_VALUE, State),
+                cotton_hessian:encode(?RESPONSE_VALUE, State),
                 ArgsBin
             ]
     end,
@@ -146,7 +146,7 @@
         {StateTmpNew} end,
         {State},Data#dubbo_rpc_invocation.parameterTypes),
     {Bin,State2} = lists:foldl(fun(X,{BinTmp,StateTmp2})->
-        case hessianEncode:encode(X, StateTmp2) of
+        case cotton_hessian:encode(X, StateTmp2) of
             {ArgsBin,StateTmpNew} ->
                 {<<BinTmp/binary,ArgsBin/binary>>, StateTmpNew};
             ArgsBin2 ->
@@ -210,21 +210,21 @@
 %%    dubbo_serializa_fastjson:decode_response(dubbo_rpc_invocation,Res,Data);
 %%
 %%decode_response(?SERIALIZATION_HESSIAN,dubbo_rpc_invocation,Res,Data)->
-%%    {Rest,Type,State} = hessianDecode2:decode(Data,hessianDecode2:init()),
+%%    {Rest,Type,State} = cotton_hessian:decode(Data,cotton_hessian:init()),
 %%    case Type of
 %%        1 ->
-%%            {_,Object,DecodeState} = hessianDecode2:decode(Rest,State),
+%%            {_,Object,DecodeState} = cotton_hessian:decode(Rest,State),
 %%            {ok,Res#dubbo_response{data = Object,decode_state = DecodeState}};
 %%        2 ->
 %%            {ok,Res#dubbo_response{data = null,decode_state = State}};
 %%        _->
 %%            logger:warning("decode unkonw type ~p ~p",[Type,Rest]),
-%%            {Rest2,Object2,DecodeState2} = hessianDecode2:decode(Rest,State),
+%%            {Rest2,Object2,DecodeState2} = cotton_hessian:decode(Rest,State),
 %%            logger:warning("decode unkonw type2 ~p ~p",[Object2,Rest2]),
 %%            {ok,Res#dubbo_response{data = Object2,decode_state = DecodeState2}}
 %%    end;
 %%decode_response(?SERIALIZATION_HESSIAN,dubbo_event,Res,Data)->
-%%    {_Rest,undefined,_NewState} = hessianDecode2:decode(Data,hessianDecode2:init()),
+%%    {_Rest,undefined,_NewState} = cotton_hessian:decode(Data,cotton_hessian:init()),
 %%    {ok,Res#dubbo_response{data = undefined}}.
 
 -spec decode_request(#dubbo_request{},binary())-> {ok,#dubbo_request{}}.
@@ -237,14 +237,14 @@
     end.
 
 %%decode_request(dubbo_rpc_invocation,Req,Data)->
-%%    {ResultList,NewState,RestData} = decode_request_body(Data,hessianDecode2:init(),[dubbo,path,version,method_name,desc_and_args,attachments]),
+%%    {ResultList,NewState,RestData} = decode_request_body(Data,cotton_hessian:init(),[dubbo,path,version,method_name,desc_and_args,attachments]),
 %%    [DubboVersion,Path,Version,MethodName,Desc,ArgsObj,Attachments]=ResultList,
 %%    RpcData = #dubbo_rpc_invocation{className = Path,classVersion = Version,methodName = MethodName,parameterDesc = Data,parameters = ArgsObj,attachments = Attachments},
 %%    Req2 = Req#dubbo_request{data = RpcData},
 %%    {ok,Req2};
 %%
 %%decode_request(dubbo_event,Req,Data)->
-%%    {_Rest,undefined,_NewState} = hessianDecode2:decode(Data,hessianDecode2:init()),
+%%    {_Rest,undefined,_NewState} = cotton_hessian:decode(Data,cotton_hessian:init()),
 %%    {ok,Req#dubbo_request{data = undefined}}.
 %%
 %%decode_request_body(Data,State,List)->
@@ -252,10 +252,10 @@
 %%    {lists:reverse(ResultList),NewState,RestData}.
 %%decode_request_body([ParseType|List],Data,State,ResultList)
 %%    when ParseType==dubbo;ParseType==path;ParseType==version;ParseType==method_name ->
-%%    {Rest,Result,NewState } = hessianDecode2:decode(Data,State),
+%%    {Rest,Result,NewState } = cotton_hessian:decode(Data,State),
 %%    decode_request_body(List,Rest,NewState, [Result] ++ ResultList);
 %%decode_request_body([desc_and_args| List],Data,State,ResultList)->
-%%    {Rest,ParameterDesc,State1 } = hessianDecode2:decode(Data,State),
+%%    {Rest,ParameterDesc,State1 } = cotton_hessian:decode(Data,State),
 %%    if
 %%        size(ParameterDesc) == 0 ->
 %%            decode_request_body(List,Rest,State1, [ [],[] ]++ ResultList);
@@ -265,7 +265,7 @@
 %%            decode_request_body(List,RestData,NewState, [ArgsObjList,ParameterDesc]++ ResultList)
 %%    end;
 %%decode_request_body([attachments|List],Data,State,ResultList)->
-%%    {Rest,Attachments,State1 } = hessianDecode2:decode(Data,State),
+%%    {Rest,Attachments,State1 } = cotton_hessian:decode(Data,State),
 %%    AttachmentsList = dict:to_list(Attachments#map.dict),
 %%    decode_request_body(List,Rest,State1,[AttachmentsList] ++ ResultList);
 %%decode_request_body([_Type1|List],Data,State,ResultList)->
@@ -279,6 +279,6 @@
 %%decode_request_body_args([ArgsType|RestList],Data,State,ArgsObjList) when ArgsType== <<>> ->
 %%    decode_request_body_args(RestList,Data,State,ArgsObjList);
 %%decode_request_body_args([_ArgsType|RestList],Data,State,ArgsObjList) ->
-%%    {Rest,ArgObj,NewState } = hessianDecode2:decode(Data,State),
+%%    {Rest,ArgObj,NewState } = cotton_hessian:decode(Data,State),
 %%    ArgObj2 = de_type_transfer:classobj_to_native(ArgObj,NewState),
 %%    decode_request_body_args(RestList,Rest,NewState,ArgsObjList++[ArgObj2]).
\ No newline at end of file
diff --git a/src/dubbo_serializa_fastjson.erl b/src/dubbo_serializa_fastjson.erl
index ca8ed41..e65b509 100644
--- a/src/dubbo_serializa_fastjson.erl
+++ b/src/dubbo_serializa_fastjson.erl
@@ -51,24 +51,15 @@
 %%        jiffy:encode(Data#dubbo_rpc_invocation.parameterDesc,[]),
         string_encode(Data#dubbo_rpc_invocation.parameterDesc),
         ?LINE_SEPERATOR
-%%
-%%        hessianEncode:encode(?DUBBO_VERSION, State), %% dubbo version
-%%        hessianEncode:encode(Data#dubbo_rpc_invocation.className, State),
-%%        hessianEncode:encode(Data#dubbo_rpc_invocation.classVersion, State),
-%%        hessianEncode:encode(METHOD_NAME, State),
-%%        hessianEncode:encode(METHOD_ARGS_TYPES, State)
     ],
     {ArgsBin,_} = encode_arguments(Data,State),
-%%    AttachDict = dict:from_list(Data#dubbo_rpc_invocation.attachments),
-%%    AttachMaps = #map{dict = AttachDict },
-%%    AttachBinay = hessianEncode:encode(AttachMaps, State2),
     AttachBinay = jiffy:encode({Data#dubbo_rpc_invocation.attachments},[]),
     RequestData = erlang:iolist_to_binary(RequestList ++ [ArgsBin,AttachBinay,?LINE_SEPERATOR]),
     {ok,RequestData};
 encode_request_data(dubbo_event,Request,Data,State) ->
     %% @todo 确认该数据类型
     Bin =  jiffy:encode(Data),
-%%    Bin = hessianEncode:encode(Data,State),
+%%    Bin = cotton_hessian:encode(Data,State),
     {ok,Bin}.
 
 
@@ -96,18 +87,18 @@
     {ok,Bin} = encode_response_data(DataType,Response,Response#dubbo_response.data,State),
     {ok,Bin}.
 encode_response_data(dubbo_event,Response,Data,State) ->
-    Bin = hessianEncode:encode(Data,State),
+    Bin = cotton_hessian:encode(Data,State),
     {ok,Bin};
 encode_response_data(dubbo_rpc_invocation,Response,Data,State) ->
     Result = case Data of
                  null ->
                      [
-                         hessianEncode:encode(?RESPONSE_NULL_VALUE, State)
+                         cotton_hessian:encode(?RESPONSE_NULL_VALUE, State)
                      ];
                  _ ->
                      {ArgsBin,_State2} = encode_arguments(Data,State),
                      [
-                         hessianEncode:encode(?RESPONSE_VALUE, State),
+                         cotton_hessian:encode(?RESPONSE_VALUE, State),
                          ArgsBin
                      ]
              end,
@@ -189,12 +180,12 @@
 decode_response(dubbo_rpc_invocation,Res,Data)->
     DataList = binary:split(Data,<<"\n">>),
     [TypeBin | DataList1] = DataList,
-%%    {Rest,Type,State} = hessianDecode2:decode(Data,hessianDecode2:init()),
+%%    {Rest,Type,State} = cotton_hessian:decode(Data,cotton_hessian:init()),
     Type = jiffy:decode(TypeBin),
 
     case Type of
         ?RESPONSE_VALUE ->
-%%            {_,Object,DecodeState} = hessianDecode2:decode(Rest,State),
+%%            {_,Object,DecodeState} = cotton_hessian:decode(Rest,State),
             [Value | _] = DataList1,
             Object = jiffy:decode(Value),
             {ok,Res#dubbo_response{data = Object}};
@@ -203,9 +194,6 @@
         ?RESPONSE_WITH_EXCEPTION ->
             [ExceptionValue | _] = DataList1,
             ExceptionObject = jiffy:decode(ExceptionValue),
-%%            logger:warning("decode unkonw type ~p ~p",[Type,Rest]),
-%%            {Rest2,Object2,DecodeState2} = hessianDecode2:decode(Rest,State),
-%%            logger:warning("decode unkonw type2 ~p ~p",[Object2,Rest2]),
             {ok,Res#dubbo_response{data = ExceptionObject}};
         Other ->
             logger:error("server response unkonw info ~p",[Other]),
@@ -213,7 +201,7 @@
 
     end;
 decode_response(dubbo_event,Res,Data)->
-%%    {_Rest,undefined,_NewState} = hessianDecode2:decode(Data,hessianDecode2:init()),
+%%    {_Rest,undefined,_NewState} = cotton_hessian:decode(Data,cotton_hessian:init()),
     {ok,Res#dubbo_response{data = null}}.
 
 -spec decode_request(#dubbo_request{},binary())-> {ok,#dubbo_request{}}.
@@ -226,31 +214,17 @@
     end.
 
 decode_request(dubbo_rpc_invocation,Req,Data)->
-    {ResultList,NewState,RestData} = decode_request_body(Data,hessianDecode2:init(),[dubbo,path,version,method_name,desc_and_args,attachments]),
+    {ResultList,NewState,RestData} = decode_request_body(Data,cotton_hessian:init(),[dubbo,path,version,method_name,desc_and_args,attachments]),
     [DubboVersion,Path,Version,MethodName,Desc,ArgsObj,Attachments]=ResultList,
     RpcData = #dubbo_rpc_invocation{className = Path,classVersion = Version,methodName = MethodName,parameterDesc = Data,parameters = ArgsObj,attachments = Attachments},
     Req2 = Req#dubbo_request{data = RpcData},
     {ok,Req2};
-%%    {Rest,Dubbo,State} = hessianDecode2:decode(Data,hessianDecode2:init()),
-%%    {Rest1,ClassName,State1} = hessianDecode2:decode(Data,State),
-%%    {Rest2,ClassName,State2} = hessianDecode2:decode(Rest1,State1),
-%%    case Type of
-%%        1 ->
-%%            {_,Object,DecodeState} = hessianDecode2:decode(Rest,State),
-%%            {ok,Req#dubbo_request{data = Object,decode_state = DecodeState}};
-%%        2 ->
-%%            {ok,Req#dubbo_request{data = null,decode_state = State}};
-%%        _->
-%%            logger:warning("decode unkonw type ~p ~p",[Type,Rest]),
-%%            {Rest2,Object2,DecodeState2} = hessianDecode2:decode(Rest,State),
-%%            logger:warning("decode unkonw type2 ~p ~p",[Object2,Rest2]),
-%%            {ok,Req#dubbo_request{data = Object2,decode_state = DecodeState2}}
-%%    end;
+
 decode_request(dubbo_event,Req,Data)->
 %%    DataList = binary:split(Data,<<"\n">>),
     logger:debug("dubbo_event datalist ~w",[Data]),
     Result = jiffy:decode(Data,[]),
-%%    {_Rest,undefined,_NewState} = hessianDecode2:decode(Data,hessianDecode2:init()),
+%%    {_Rest,undefined,_NewState} = cotton_hessian:decode(Data,cotton_hessian:init()),
     {ok,Req#dubbo_request{data = Result}}.
 
 decode_request_body(Data,State,List)->
@@ -258,10 +232,10 @@
     {lists:reverse(ResultList),NewState,RestData}.
 decode_request_body([ParseType|List],Data,State,ResultList)
     when ParseType==dubbo;ParseType==path;ParseType==version;ParseType==method_name ->
-    {Rest,Result,NewState } = hessianDecode2:decode(Data,State),
+    {Rest,Result,NewState } = cotton_hessian:decode(Data,State),
     decode_request_body(List,Rest,NewState, [Result] ++ ResultList);
 decode_request_body([desc_and_args| List],Data,State,ResultList)->
-    {Rest,ParameterDesc,State1 } = hessianDecode2:decode(Data,State),
+    {Rest,ParameterDesc,State1 } = cotton_hessian:decode(Data,State),
     if
         size(ParameterDesc) == 0 ->
             decode_request_body(List,Rest,State1, [ [],[] ]++ ResultList);
@@ -271,7 +245,7 @@
             decode_request_body(List,RestData,NewState, [ArgsObjList,ParameterDesc]++ ResultList)
     end;
 decode_request_body([attachments|List],Data,State,ResultList)->
-    {Rest,Attachments,State1 } = hessianDecode2:decode(Data,State),
+    {Rest,Attachments,State1 } = cotton_hessian:decode(Data,State),
     AttachmentsList = dict:to_list(Attachments#map.dict),
     decode_request_body(List,Rest,State1,[AttachmentsList] ++ ResultList);
 decode_request_body([_Type1|List],Data,State,ResultList)->
@@ -285,7 +259,7 @@
 decode_request_body_args([ArgsType|RestList],Data,State,ArgsObjList) when ArgsType== <<>> ->
     decode_request_body_args(RestList,Data,State,ArgsObjList);
 decode_request_body_args([_ArgsType|RestList],Data,State,ArgsObjList) ->
-    {Rest,ArgObj,NewState } = hessianDecode2:decode(Data,State),
+    {Rest,ArgObj,NewState } = cotton_hessian:decode(Data,State),
     ArgObj2 = dubbo_type_transfer:classobj_to_native(ArgObj,NewState),
     decode_request_body_args(RestList,Rest,NewState,ArgsObjList++[ArgObj2]).
 
diff --git a/src/dubbo_serializa_hessian.erl b/src/dubbo_serializa_hessian.erl
index d3b5514..13fc3fd 100644
--- a/src/dubbo_serializa_hessian.erl
+++ b/src/dubbo_serializa_hessian.erl
@@ -17,22 +17,22 @@
 
 
 encode_request_data(dubbo_event,Request,Data,State) ->
-    Bin = hessianEncode:encode(Data,State),
+    Bin = cotton_hessian:encode(Data,State),
     {ok,Bin};
 encode_request_data(dubbo_rpc_invocation,Request,Data,State) ->
     METHOD_NAME = Data#dubbo_rpc_invocation.methodName,
     METHOD_ARGS_TYPES = Data#dubbo_rpc_invocation.parameterDesc,
     RequestList = [
-        hessianEncode:encode(?DUBBO_VERSION, State), %% dubbo version
-        hessianEncode:encode(Data#dubbo_rpc_invocation.className, State),
-        hessianEncode:encode(Data#dubbo_rpc_invocation.classVersion, State),
-        hessianEncode:encode(METHOD_NAME, State),
-        hessianEncode:encode(METHOD_ARGS_TYPES, State)
+        cotton_hessian:encode(?DUBBO_VERSION, State), %% dubbo version
+        cotton_hessian:encode(Data#dubbo_rpc_invocation.className, State),
+        cotton_hessian:encode(Data#dubbo_rpc_invocation.classVersion, State),
+        cotton_hessian:encode(METHOD_NAME, State),
+        cotton_hessian:encode(METHOD_ARGS_TYPES, State)
     ],
     {ArgsBin,State2} = encode_arguments(Data,State),
     AttachDict = dict:from_list(Data#dubbo_rpc_invocation.attachments),
     AttachMaps = #map{dict = AttachDict },
-    {AttachBinay,_} = hessianEncode:encode(AttachMaps, State2),
+    {AttachBinay,_} = cotton_hessian:encode(AttachMaps, State2),
     RequestData = erlang:iolist_to_binary(RequestList ++ [ArgsBin,AttachBinay]),
     {ok,RequestData}.
 
@@ -60,18 +60,18 @@
     {ok,Bin} = encode_response_data(DataType,Response,Response#dubbo_response.data,State),
     {ok,Bin}.
 encode_response_data(dubbo_event,Response,Data,State) ->
-    Bin = hessianEncode:encode(Data,State),
+    Bin = cotton_hessian:encode(Data,State),
     {ok,Bin};
 encode_response_data(dubbo_rpc_invocation,Response,Data,State) ->
     Result = case Data of
                  null ->
                      [
-                         hessianEncode:encode(?RESPONSE_NULL_VALUE, State)
+                         cotton_hessian:encode(?RESPONSE_NULL_VALUE, State)
                      ];
                  _ ->
                      {ArgsBin,_State2} = encode_arguments(Data,State),
                      [
-                         hessianEncode:encode(?RESPONSE_VALUE, State),
+                         cotton_hessian:encode(?RESPONSE_VALUE, State),
                          ArgsBin
                      ]
              end,
@@ -97,7 +97,7 @@
         {StateTmpNew} end,
         {State},Data#dubbo_rpc_invocation.parameterTypes),
     {Bin,State2} = lists:foldl(fun(X,{BinTmp,StateTmp2})->
-        case hessianEncode:encode(X, StateTmp2) of
+        case cotton_hessian:encode(X, StateTmp2) of
             {ArgsBin,StateTmpNew} ->
                 {<<BinTmp/binary,ArgsBin/binary>>, StateTmpNew};
             ArgsBin2 ->
@@ -158,21 +158,21 @@
     end.
 
 decode_response(dubbo_rpc_invocation,Res,Data)->
-    {Rest,Type,State} = hessianDecode2:decode(Data,hessianDecode2:init()),
+    {Rest,Type,State} = cotton_hessian:decode(Data,cotton_hessian:init()),
     case Type of
         1 ->
-            {_,Object,DecodeState} = hessianDecode2:decode(Rest,State),
+            {_,Object,DecodeState} = cotton_hessian:decode(Rest,State),
             {ok,Res#dubbo_response{data = Object,decode_state = DecodeState}};
         2 ->
             {ok,Res#dubbo_response{data = null,decode_state = State}};
         _->
             logger:warning("decode unkonw type ~p ~p",[Type,Rest]),
-            {Rest2,Object2,DecodeState2} = hessianDecode2:decode(Rest,State),
+            {Rest2,Object2,DecodeState2} = cotton_hessian:decode(Rest,State),
             logger:warning("decode unkonw type2 ~p ~p",[Object2,Rest2]),
             {ok,Res#dubbo_response{data = Object2,decode_state = DecodeState2}}
     end;
 decode_response(dubbo_event,Res,Data)->
-    {_Rest,undefined,_NewState} = hessianDecode2:decode(Data,hessianDecode2:init()),
+    {_Rest,undefined,_NewState} = cotton_hessian:decode(Data,cotton_hessian:init()),
     {ok,Res#dubbo_response{data = undefined}}.
 
 -spec decode_request(#dubbo_request{},binary())-> {ok,#dubbo_request{}}.
@@ -185,28 +185,28 @@
     end.
 
 decode_request(dubbo_rpc_invocation,Req,Data)->
-    {ResultList,NewState,RestData} = decode_request_body(Data,hessianDecode2:init(),[dubbo,path,version,method_name,desc_and_args,attachments]),
+    {ResultList,NewState,RestData} = decode_request_body(Data,cotton_hessian:init(),[dubbo,path,version,method_name,desc_and_args,attachments]),
     [DubboVersion,Path,Version,MethodName,Desc,ArgsObj,Attachments]=ResultList,
     RpcData = #dubbo_rpc_invocation{className = Path,classVersion = Version,methodName = MethodName,parameterDesc = Data,parameters = ArgsObj,attachments = Attachments},
     Req2 = Req#dubbo_request{data = RpcData},
     {ok,Req2};
-%%    {Rest,Dubbo,State} = hessianDecode2:decode(Data,hessianDecode2:init()),
-%%    {Rest1,ClassName,State1} = hessianDecode2:decode(Data,State),
-%%    {Rest2,ClassName,State2} = hessianDecode2:decode(Rest1,State1),
+%%    {Rest,Dubbo,State} = cotton_hessian:decode(Data,cotton_hessian:init()),
+%%    {Rest1,ClassName,State1} = cotton_hessian:decode(Data,State),
+%%    {Rest2,ClassName,State2} = cotton_hessian:decode(Rest1,State1),
 %%    case Type of
 %%        1 ->
-%%            {_,Object,DecodeState} = hessianDecode2:decode(Rest,State),
+%%            {_,Object,DecodeState} = cotton_hessian:decode(Rest,State),
 %%            {ok,Req#dubbo_request{data = Object,decode_state = DecodeState}};
 %%        2 ->
 %%            {ok,Req#dubbo_request{data = null,decode_state = State}};
 %%        _->
 %%            logger:warning("decode unkonw type ~p ~p",[Type,Rest]),
-%%            {Rest2,Object2,DecodeState2} = hessianDecode2:decode(Rest,State),
+%%            {Rest2,Object2,DecodeState2} = cotton_hessian:decode(Rest,State),
 %%            logger:warning("decode unkonw type2 ~p ~p",[Object2,Rest2]),
 %%            {ok,Req#dubbo_request{data = Object2,decode_state = DecodeState2}}
 %%    end;
 decode_request(dubbo_event,Req,Data)->
-    {_Rest,undefined,_NewState} = hessianDecode2:decode(Data,hessianDecode2:init()),
+    {_Rest,undefined,_NewState} = cotton_hessian:decode(Data,cotton_hessian:init()),
     {ok,Req#dubbo_request{data = undefined}}.
 
 decode_request_body(Data,State,List)->
@@ -214,10 +214,10 @@
     {lists:reverse(ResultList),NewState,RestData}.
 decode_request_body([ParseType|List],Data,State,ResultList)
     when ParseType==dubbo;ParseType==path;ParseType==version;ParseType==method_name ->
-    {Rest,Result,NewState } = hessianDecode2:decode(Data,State),
+    {Rest,Result,NewState } = cotton_hessian:decode(Data,State),
     decode_request_body(List,Rest,NewState, [Result] ++ ResultList);
 decode_request_body([desc_and_args| List],Data,State,ResultList)->
-    {Rest,ParameterDesc,State1 } = hessianDecode2:decode(Data,State),
+    {Rest,ParameterDesc,State1 } = cotton_hessian:decode(Data,State),
     if
         size(ParameterDesc) == 0 ->
             decode_request_body(List,Rest,State1, [ [],[] ]++ ResultList);
@@ -227,7 +227,7 @@
             decode_request_body(List,RestData,NewState, [ArgsObjList,ParameterDesc]++ ResultList)
     end;
 decode_request_body([attachments|List],Data,State,ResultList)->
-    {Rest,Attachments,State1 } = hessianDecode2:decode(Data,State),
+    {Rest,Attachments,State1 } = cotton_hessian:decode(Data,State),
     AttachmentsList = dict:to_list(Attachments#map.dict),
     decode_request_body(List,Rest,State1,[AttachmentsList] ++ ResultList);
 decode_request_body([_Type1|List],Data,State,ResultList)->
@@ -241,6 +241,6 @@
 decode_request_body_args([ArgsType|RestList],Data,State,ArgsObjList) when ArgsType== <<>> ->
     decode_request_body_args(RestList,Data,State,ArgsObjList);
 decode_request_body_args([_ArgsType|RestList],Data,State,ArgsObjList) ->
-    {Rest,ArgObj,NewState } = hessianDecode2:decode(Data,State),
+    {Rest,ArgObj,NewState } = cotton_hessian:decode(Data,State),
     ArgObj2 = dubbo_type_transfer:classobj_to_native(ArgObj,NewState),
     decode_request_body_args(RestList,Rest,NewState,ArgsObjList++[ArgObj2]).
\ No newline at end of file
diff --git a/src/dubbo_type_transfer.erl b/src/dubbo_type_transfer.erl
index 9a5609d..6c7c727 100644
--- a/src/dubbo_type_transfer.erl
+++ b/src/dubbo_type_transfer.erl
@@ -26,7 +26,7 @@
 java_to_native(#object{values = ForeignData}=Data,State)->
     ForeignDataNew = [java_to_native(ValueItem,State) || ValueItem <-ForeignData ],
 
-    case hessianDecode2:get_deftype(Data#object.typeRef,State) of
+    case cotton_hessian:get_deftype(Data#object.typeRef,State) of
         #type_def{fieldnames = ObjectFields,foreign_type = ForeignType } ->
             case get_deftype(ForeignType) of
                 false->
diff --git a/src/hessianDecode2.erl b/src/hessianDecode2.erl
deleted file mode 100644
index 55c3a6a..0000000
--- a/src/hessianDecode2.erl
+++ /dev/null
@@ -1,361 +0,0 @@
--module(hessianDecode2).
-
--include("hessian.hrl").
-
--export([decode/2]).
--export([init/0]).
--export([get_deftype/2]).
--record(decoding_state,{type_pool = dict:new(), reference_pool = dict:new(),hash_pool = dict:new()}).
-
-%---------------------------------------------------------------------------
-% Decoding
-%---------------------------------------------------------------------------
-decode_str(Rest, 0, R) ->
-    {list_to_binary(xmerl_ucs:to_utf8(lists:reverse(R))), Rest};
-decode_str(<<C/utf8, Rest/binary>>, N, R) ->
-    decode_str(Rest, N-1, [C|R]).
-
-% Call
-decode(<<$H,?M,?m,$C,Bin/binary>>, State) ->
-    {Rest, Function, _State} = decode(Bin,State),
-    {Rest2, Count, __State} = decode(Rest,_State),
-    case decode(list, Rest2,Count,[], __State) of
-        {error, Encoded} ->
-            {error, Encoded};
-        {not_found, Hash} ->
-            {not_found, Hash};
-        {_Rest, Arguments, _NewState} ->
-            [Function, Arguments]
-    end;
-% Fault
-decode(<<$H,?M,?m,$F,
-    Rest/binary>>, State) ->
-    {_Rest,#map{dict=Dict},_State} = decode(Rest, State),
-    {ok, Message} = dict:find(<<"message">>, Dict),
-    {error, Message};
-% Reply
-decode(<<$H,?M,?m,$R,Args/binary>>, State) ->
-    case decode(Args,[], State) of
-        {<<>>, Decoded,_State} ->
-            TypeSet = get_type_set(_State),
-            case Decoded of
-                [Value] ->
-                    {Value,TypeSet};
-                [H|T] ->
-                    {[H|T],TypeSet}
-            end;
-        {error, Encoded} ->
-            {error, Encoded}
-    end;
-% Binaries
-decode(<<16#20,Rest/binary>>, State) -> {Rest, <<>>, State};
-decode(<<Len:8/unsigned,Rest/binary>>, State) when Len =< 16#2f, 16#20 < Len ->
-    _Len = Len - 16#20,
-    <<Bin:_Len/binary,_Rest/binary>> = Rest,
-    {_Rest, Bin, State};
-decode(<<$B,Len:16/unsigned,Bin:Len/binary,Rest/binary>>, State) -> {Rest, Bin, State};
-decode(<<$b,Rest/binary>>,State) -> decode(<<$b,Rest/binary>>, [], State);
-%% Booleans
-decode(<<$T,Rest/binary>>, State) -> {Rest, true, State};
-decode(<<$F,Rest/binary>>, State) -> {Rest, false, State};
-%% Dates
-decode(<<16#4a,Date:64/unsigned,Rest/binary>>, State) ->
-    MegaSecs = Date div ?MegaSeconds,
-    Secs = (Date - MegaSecs * ?MegaSeconds) div ?Seconds,
-    MicroSecs = (Date - MegaSecs * ?MegaSeconds - Secs * ?Seconds) * ?MicroSeconds,
-    {Rest, {MegaSecs, Secs, MicroSecs}, State};
-decode(<<16#4b,Date:32/unsigned,Rest/binary>>, State) ->
-    MegaSecs = (Date * 60000) div ?MegaSeconds,
-    Secs = (Date * 60000 - MegaSecs * ?MegaSeconds) div ?Seconds,
-    {Rest, {MegaSecs, Secs, 0}, State};
-%% Doubles
-decode(<<16#5b,Rest/binary>>, State)-> {Rest, 0.0, State};
-decode(<<16#5c,Rest/binary>>, State)-> {Rest, 1.0, State};
-decode(<<16#5d,Int:8/signed,Rest/binary>>, State)-> {Rest, float(Int), State};
-decode(<<16#5e,Int:16/signed,Rest/binary>>, State)-> {Rest, float(Int), State};
-decode(<<16#5f,Int:32/signed,Rest/binary>>, State)->
-    <<Double:64/float>> = <<Int:32,0,0,0,0>>,
-    {Rest, Double, State};
-decode(<<$D,Double:64/float,Rest/binary>>, State)-> {Rest, Double, State};
-%% Ints
-decode(<<$I,Int:32/signed,Rest/binary>>, State)-> {Rest, Int, State};
-decode(<<Int:8,Rest/binary>>, State) when Int >= 16#80, Int =< 16#bf -> {Rest, Int - 16#90, State};
-decode(<<B2:8,B1:8,B0:8,Rest/binary>>, State) when B2 >= 16#d0, B2 =< 16#d7 -> {Rest, ((B2 - 16#d4) bsl 16) + (B1 bsl 8) + B0, State};
-decode(<<B1:8,B0:8,Rest/binary>>, State) when B1 >= 16#c0, B1 =< 16#cf -> {Rest, ((B1 - 16#c8) bsl 8) + B0, State};
-%% Longs
-decode(<<$L,Long:64/signed,Rest/binary>>, State)-> {Rest, Long, State};
-decode(<<16#59,Long:32/signed,Rest/binary>>, State) -> {Rest, Long, State};
-decode(<<Long:8,Rest/binary>>, State) when Long >= 16#d8, Long =< 16#ef -> {Rest, Long - 16#e0, State};
-decode(<<B2:8,B1:8,B0:8,Rest/binary>>, State) when B2 >= 16#38, B2 =< 16#3f -> {Rest, ((B2 - 16#3c) bsl 16) + (B1 bsl 8) + B0, State};
-decode(<<B1:8,B0:8,Rest/binary>>, State) when B1 >= 16#f0, B1 =< 16#ff -> {Rest, ((B1 - 16#f8) bsl 8) + B0, State};
-%% Strings
-decode(<<0,Rest/binary>>, State) -> {Rest, <<>>, State};
-decode(<<Len:8,Rest/binary>>, State) when Len < 32 ->
-    {String, NewRest} = decode_str(Rest, Len, []),
-    {NewRest, String, State};
-decode(<<B1:8,B0:8,Rest/binary>>, State) when B1 =< 16#33,B1 >= 16#30 ->
-    Len = ((B1 - 16#30) bsl 8) + B0,
-    {String, NewRest} = decode_str(Rest, Len, []),
-    {NewRest, String, State};
-decode(<<$S,Len:16/unsigned,Rest/binary>>, State) ->
-    {String, NewRest} = decode_str(Rest, Len, []),
-    {NewRest, String, State};
-decode(<<$R,Rest/binary>>, State) -> decode(<<$R,Rest/binary>>,[], State);
-%% Nulls
-decode(<<$N,Rest/binary>>, State) -> {Rest, undefined, State};
-%% References
-decode(<<$Q,Bin/binary>>, State)->
-    {Rest, IntRef, _State} = decode(Bin,State),
-    {Rest, {ref, IntRef}, _State};
-%% Maps
-decode(<<$M,Map/binary>>, State) ->
-    {Rest,Type,_State} = decode(Map, State),
-    {_Refnum,__State} = visit(#type_def{foreign_type = map},_State),
-    {_Rest,Dict, NewState} = decode(map, Rest, dict:new(), __State),
-    {_Rest,#map{refNo=_Refnum,type=Type,dict=Dict},NewState};
-decode(<<$H,Map/binary>>, State) ->
-    {_Refnum,_State} = visit(#type_def{foreign_type = map},State),
-    {_Rest,Dict, NewState} = decode(map, Map, dict:new(), _State),
-    {_Rest,#map{refNo=_Refnum,dict=Dict},NewState};
-%% Lists
-% 'V' type int value*   # fixed-length list
-decode(<<$V,Bin/binary>>, State) ->
-    {Rest1,_Type,_State1} = decode(Bin,State),
-    {_Refnum,__State} = visit(#type_def{foreign_type = list},_State1),
-    {Rest2,Len,_State2} = decode(Rest1,__State),
-    {NewRest,List,NewState} = decode(list, Rest2, Len, [], _State2),
-    {NewRest,#list{refNo=_Refnum,len=Len,type=_Type,values=List},NewState};
-% 'X' int value*        # fixed-length untyped list
-decode(<<$X,Bin/binary>>, State) ->
-    {Rest1,Len,_State} = decode(Bin,State),
-    {_Refnum,__State} = visit(#type_def{foreign_type = list},_State),
-    {NewRest,List,NewState} = decode(list, Rest1, Len, [], __State),
-    {NewRest,#list{refNo=_Refnum,len=Len,values=List},NewState};
-% [x70-77] type value*  # fixed-length typed list
-decode(<<H:5,Len:3,Bin/binary>>, State) when H == 14 ->
-    {Rest1,_Type,_State} = decode(Bin,State),
-    {_Refnum,__State} = visit(#type_def{foreign_type = list},_State),
-    {NewRest,List,NewState} = decode(list, Rest1, Len, [], __State),
-    {NewRest,#list{refNo=_Refnum,len=Len,type=_Type,values=List},NewState};
-% [x78-7f] value*       # fixed-length untyped list
-decode(<<H:5,Len:3,Bin/binary>>, State) when H == 15 ->
-    {_Refnum,_State} = visit(#type_def{foreign_type = list},State),
-    {NewRest,List,NewState} = decode(list, Bin, Len, [], _State),
-    {NewRest,#list{refNo=_Refnum,len=Len,values=List},NewState};
-% 'U' type value* 'Z'   # variable-length list
-decode(<<$U,Bin/binary>>, State) ->
-    {Rest1,_Type,_State} = decode(Bin,State),
-    {_Refnum,__State} = visit(#type_def{foreign_type = list},_State),
-    {NewRest,List,NewState} = decode(list, Rest1, [], __State),
-    {NewRest,#list{refNo=_Refnum,type=_Type,values=List},NewState};
-% 'W' value* 'Z'        # variable-length untyped list
-decode(<<$W,Bin/binary>>, State) ->
-    {_Refnum,_State} = visit(#type_def{foreign_type = list},State),
-    {NewRest,List,NewState} = decode(list, Bin, [], _State),
-    {NewRest,#list{refNo=_Refnum,values=List},NewState};
-decode(<<$C,Bin/binary>>, State0) ->
-    {Rest1,Type,State1} = decode(Bin,State0),
-    {Rest, TypeDef, State} = decode(type_definition,Type,Rest1,State1),
-    NewState = hash_store(TypeDef,State),
-    decode(Rest,NewState);
-decode(<<$O,Bin/binary>>, State) ->
-    {Rest,Ref,_State} = decode(Bin, State),
-    case hash_lookup(Ref, _State) of
-        {not_found, Ref} ->
-            {Rest, {not_found, Ref}, _State};
-        ForeignView ->
-            #type_def{fieldnames = ForeignFieldNames} = ForeignView,
-            {_Refnum,__State} = visit(ForeignView,_State),
-            Count = count_fields(ForeignView),
-            case decode(field, Rest, Count,[], __State) of
-                {not_found,Hash} ->
-                    {not_found,Hash};
-                {_Rest,FieldValues, NewState} ->
-                    Object = project_native_view(ForeignFieldNames,FieldValues,ForeignView),
-                    {_Rest, #object{refNo=_Refnum, typeRef=Ref,values=Object}, NewState}
-            end
-    end;
-decode(<<H:4,Ref:4,Rest/binary>>, _State) when H == 6 ->
-    logger:debug("decode data find ref ~p",[Ref]),
-    case hash_lookup(Ref, _State) of
-        {not_found, Ref} ->
-            {Rest, {not_found, Ref}, _State};
-        ForeignView ->
-            #type_def{fieldnames = ForeignFieldNames} = ForeignView,
-            {_Refnum,__State} = visit(ForeignView,_State),
-            Count = count_fields(ForeignView),
-            case decode(field, Rest, Count,[], __State) of
-                {not_found,Hash} ->
-                    {not_found,Hash};
-                {_Rest,FieldValues, NewState} ->
-                    Object = project_native_view(ForeignFieldNames,FieldValues,ForeignView),
-                    {_Rest, #object{refNo=_Refnum, typeRef=Ref,values=Object}, NewState}
-            end
-    end;
-%% Anything else
-decode(<<Unexpected/binary>>, State) ->
-    {error, hessianEncode:encode(fault, <<"ProtocolException">>, unexpected_byte_sequence, Unexpected, State) }.
-decode(<<$b,Len:16/unsigned,Bin:Len/binary,$b,Rest/binary>>, Acc, State) ->
-    decode(<<$b,Rest/binary>>,Acc ++ [Bin], State);
-decode(<<$b,Len:16/unsigned,Bin:Len/binary,$B,Rest/binary>>, Acc, State) ->
-    _Acc = Acc ++ [Bin],
-    {_Rest,_Bin, State} = decode(<<$B,Rest/binary>>, State),
-    {_Rest, list_to_binary(_Acc ++ [_Bin]), State};
-decode(<<$R,Len:16/unsigned,Rest/binary>>,Acc, State) ->
-    {_String, NewRest} = decode_str(Rest, Len, []),
-    <<H:8,_/binary>> = NewRest,
-    case H of
-        $R -> decode(NewRest,list_to_binary([Acc|[_String]]), State);
-        $S -> {_Rest,_Bin, _State} = decode(NewRest, State),
-            _Acc2 =[Acc |[_String]],
-            {_Rest, list_to_binary(_Acc2 ++ [_Bin]), _State}
-    end;
-decode(<<>>, List, State) -> {<<>>, List, State};
-decode(<<$Z>>, List, State) -> {<<>>, List, State};
-decode(Args, List, State) ->
-    case decode(Args,State) of
-        {Rest,{ref, Ref}, _State} ->
-            decode(Rest, List ++ [{ref, Ref}] , _State);
-        {Rest, [H|T], _State} ->
-            decode(Rest, List ++ [H|T], _State);
-        {Rest, Result, _State} ->
-            decode(Rest, List ++ [Result], _State);
-        {error, Encoded} ->
-            {error, Encoded}
-    end.
-decode(map, <<$Z>>, Dict, State) -> {<<>>,Dict, State};
-decode(map, <<$Z,Rest/binary>>, Dict, State) -> {Rest,Dict, State};
-decode(map, Bin, Dict, State) ->
-    {_Rest, Key, _State} = decode(Bin, State),
-    case decode(_Rest, _State) of
-        {Rest, {ref, Ref}, __State} ->
-            %Value = lists:nth(Ref + 1, List),
-            Value = Ref,
-            decode(map, Rest, dict:store(Key, {ref, Value}, Dict), __State);
-        {Rest, Value, __State} ->
-            decode(map, Rest, dict:store(Key, Value, Dict), __State)
-    end;
-decode(list, <<>>, List, State) -> {<<>>,lists:reverse(List), State};
-decode(list, <<$Z>>, List, State) -> {<<>>,lists:reverse(List), State};
-decode(list, <<$Z,Rest/binary>>, List, State) -> {Rest, lists:reverse(List), State};
-decode(list, Bin, List, State) ->
-    case decode(Bin, State) of
-        {error, Encoded} ->
-            {error, Encoded};
-        {not_found,Hash} ->
-            {not_found, Hash};
-        {_Rest, {not_found, Hash}, _State} ->
-            {not_found, Hash};
-        {Rest, Value, _State} ->
-            decode(list, Rest, [Value|List], _State)
-    end;
-decode(type_definition, ForeignType, Bin, State) ->
-    {Rest,Count, _State} = decode(Bin, State),
-    {NewRest,FieldNames, NewState} = decode(field, Rest, Count, [], _State),
-    {TypeDef,NewState2} = build_foreign_view(ForeignType,FieldNames,NewState),
-    {NewRest, TypeDef, NewState2}.
-decode(list, Bin, 0, List, State) -> {Bin, lists:reverse(List), State};
-decode(list, Bin, Len, List, State) ->
-    case decode(Bin, State) of
-        {error, Encoded} ->
-            {error, Encoded};
-        {not_found,Hash} ->
-            {not_found, Hash};
-        {_Rest, {not_found, Hash}, _State} ->
-            {not_found, Hash};
-        {Rest, Value, _State} ->
-            decode(list, Rest, Len - 1, [Value|List], _State)
-    end;
-decode(field, Rest, 0, Acc, State) -> {Rest, Acc, State};
-decode(field, <<$Z,Rest/binary>>, _Count, Acc, State) -> {Rest, Acc, State};
-decode(field, Bin, Count, Acc, State) ->
-    {Rest,Field, _State} = decode(Bin, State),
-    case Field of
-        {not_found,Hash} ->
-            {not_found,Hash};
-        _ ->
-            decode(field, Rest, Count - 1, Acc ++ [Field], _State)
-    end.
-
-get_type_set(#decoding_state{type_pool = Pool}) ->
-    case dict:to_list(Pool) of
-        [] -> [];
-        Data -> [Value || {_Key,Value} <- Data]
-    end.
-
-build_foreign_view(ForeignType,FieldNames,State) ->
-    logger:debug("[DECODE] build_foreign_view ForeignType ~p FieldNames ~p",[ForeignType,FieldNames]),
-    ForeignView = FieldNames,
-    #decoding_state{type_pool = OldPool} = State,
-    Native = dict:size(OldPool),
-    NewPool = dict:store(Native,
-        #type_def{
-            defineNo = Native,
-%%            native_type = Native,
-            foreign_type = ForeignType,
-            fieldnames = ForeignView},
-        OldPool),
-    {
-        #type_def{defineNo = Native,
-%%            native_type = Native,
-            foreign_type = ForeignType,
-            fieldnames = ForeignView},
-        State#decoding_state{type_pool = NewPool}
-    }.
-
-project_native_view(ForeignView,ForeignData,
-    #type_def{native_type = _NativeType, foreign_type = _ForeignType, fieldnames = NativeView}) ->
-    AsDict = dict:from_list(lists:zip(ForeignView,ForeignData)),
-    NativeData = [dict:fetch(Key,AsDict) || Key <- NativeView],
-    NativeData.
-
-visit(TypeDef, State = #decoding_state{reference_pool = OldPool}) ->
-    logger:debug("[DECODE] visit typedef ~p",[TypeDef]),
-    Size = dict:size(OldPool),
-    NewPool = dict:store(Size, TypeDef, OldPool),
-    {Size,State#decoding_state{reference_pool = NewPool}}.
-
-hash_lookup(Hash,#decoding_state{hash_pool = HashPool} = State) ->
-    case dict:find(Hash,HashPool) of
-        error->
-            {not_found, Hash};
-        {ok,TypeDef}->
-            TypeDef
-    end.
-%%    init(false),
-%%    case ets:lookup(hashes, Hash) of
-%%        [] ->
-%%            {not_found, Hash};
-%%        [{Hash,TypeDef}] ->
-%%            TypeDef
-%%    end.
-
-hash_store(TypeDef = #type_def{defineNo = Hash}, #decoding_state{hash_pool = HashPool} = State) ->
-%%    init(false),
-%%    ets:insert(hashes,{Hash,TypeDef}),
-    logger:debug("[DECODE] hash store typedef ~p",[TypeDef]),
-    NewPool = dict:store(Hash,TypeDef,HashPool),
-    State#decoding_state{hash_pool = NewPool}.
-
-init() -> init(true).
-
-init(Delete) when is_boolean(Delete) ->
-%%    case ets:info(hashes) of
-%%        undefined ->
-%%            ets:new(hashes,[private,named_table]);
-%%        _ ->
-%%            if
-%%                Delete ->
-%%                    ets:delete(hashes),
-%%                    ets:new(hashes,[private,named_table]);
-%%                true ->
-%%                    ok
-%%            end
-%%    end,
-    #decoding_state{}.
-
-count_fields(#type_def{fieldnames = FieldNames}) -> length(FieldNames).
-
-%% extend func
-get_deftype(Ref,#decoding_state{type_pool = Pool})->
-    dict:fetch(Ref,Pool).
\ No newline at end of file
diff --git a/src/hessianEncode.erl b/src/hessianEncode.erl
deleted file mode 100755
index ecfe3c4..0000000
--- a/src/hessianEncode.erl
+++ /dev/null
@@ -1,577 +0,0 @@
--module(hessianEncode).
-
--include("hessian.hrl").
-
--export([encode/2, encode/3, encode/4, encode/5]).
--export([get_value/3, get_value/4]).
--export([wrap_class/1, encode_for_decode/2,encode_object/3]).
-
-%---------------------------------------------------------------------------
-% Encoding
-%---------------------------------------------------------------------------
-encode_for_decode(Value, [{set,SetInfo},ClassList]) when is_tuple(Value) -> encode(struct, Value, [{set,SetInfo},wrap_class(ClassList)]);
-encode_for_decode(Value, State) when is_tuple(Value) -> encode(struct, Value, wrap_class(State)).
-%---------------------------------------------------------------------------
-% encode/2	<--	** Entry **
-%---------------------------------------------------------------------------
-
-encode(undefined, _State) -> <<$N>>;
-encode(null, _State) -> <<$N>>;
-encode(true, _State) -> <<$T>>;
-encode(false, _State) -> <<$F>>;
-encode(Value, State) when is_integer(Value) -> encode(int, Value, State);
-encode(Value, State) when is_atom(Value) -> encode(string, erlang:atom_to_binary(Value,utf8), State);
-encode(Value, State) when is_float(Value) -> encode(double, Value, State);
-encode(Value, State) when is_list(Value) -> encode(string, Value, State);
-encode(Value, State) when is_binary(Value) -> encode(string, Value, State);
-encode(Value, State) when is_tuple(Value) -> encode(struct, Value, State).
-%---------------------------------------------------------------------------
-% encode/3
-%---------------------------------------------------------------------------
-encode(struct, Input, State) ->
-	case Input of
-		#list{} -> encode(list, Input, State);
-		#map{} -> encode(map, Input, State);
-		#object{} -> encode(object, Input, State);
-		#class{} -> encode(class_store, Input, State);
-		{binary, Bin} -> encode(binary, Bin, State);
-		{date, Timestamp} -> encode(date, Timestamp, State);
-		{ref, Index} ->
-			IndexBin = encode(int, Index, State),
-			<<$Q, IndexBin/binary>>;
-		_Object ->
-            logger:debug("[encode] object ~p",[Input]),
-			encode(class_object, Input, State);
-%%			{<<>>,State};
-		{K, V} ->
-			{BK,SK} = encode(K, State),
-			{BV,SV} = encode(V, SK),
-			{<<BK/binary, BV/binary>>, SV}
-	end;
-encode(int, Int, _State) when Int >= -16, Int =< 47 ->
-	_Int = Int + 16#90,
-	<<_Int:8>>;
-encode(int, Int, _State) when Int >= -2048, Int =< 2047 ->
-	<<B1:8,B0:8>> = <<Int:16>>,
-	_B1 = B1 + 16#c8,
-	<<_B1,B0>>;
-encode(int, Int, _State) when Int >= -262144, Int =< 262143 ->
-	<<B2:8,B1:8,B0:8>> = <<Int:24>>,
-	_B2 = B2 + 16#d4,
-	<<_B2,B1,B0>>;
-encode(int, Int, _State) when Int > -16#80000001, Int < 16#80000000 ->
-	<<$I,Int:32/signed>>;
-encode(int, Int, State) ->
-	encode(long, Int, State);
-encode(long, Long, _State) when Long >= -8, Long =< 15 ->
-	_Long = Long + 16#e0,
-	<<_Long:8>>;
-encode(long, Long, _State) when Long >= -2048, Long =< 2047 ->
-	<<B1:8,B0:8>> = <<Long:16>>,
-	_B1 = B1 + 16#f8,
-	<<_B1,B0>>;
-encode(long, Long, _State) when Long >= -262144, Long =< 262143 ->
-	<<B2:8,B1:8,B0:8>> = <<Long:24>>,
-	_B2 = B2 + 16#3c,
-	<<_B2,B1,B0>>;
-encode(long, Long, _State) when Long > -16#80000001, Long < 16#80000000 ->
-	<<16#59,Long:32/signed>>;
-encode(long, Long, _State) ->
-	<<$L,Long:64/signed>>;
-encode(double, 0.0, _State) ->
-	<<16#5b>>;
-encode(double, 1.0, _State) ->
-	<<16#5c>>;
-encode(double, Double, _State) when Double >= -128.0, Double =< 127.0, Double == round(Double) ->
-	Byte = round(Double),
-	<<16#5d, Byte/signed>>;
-encode(double, Double, _State) when Double >= -32768.0, Double =< 32767.0, Double == round(Double) ->
-	Byte = round(Double),
-	<<16#5e, Byte:16/signed>>;
-encode(double, Double, _State) ->
-	case <<Double/float>> of
-		<<B24,B16,B8,B0,0,0,0,0>> -> <<16#5f,B24,B16,B8,B0>>;
-		Other -> <<$D,Other/binary>>
-	end;
-encode(string, <<>>, _State) ->
-	<<0>>;
-encode(string, [], _State) ->
-	<<0>>;
-encode(string, String, State) when is_list(String)->
-	UTF8 = xmerl_ucs:from_utf8(String),
-	Length = length(UTF8),
-	encode(sub, Length, String, [UTF8|State]);
-encode(string, String, State) when is_binary(String)->
-	encode(string, binary_to_list(String), State);
-encode(binary, <<>>, _State) ->
-	<<16#20>>;
-encode(binary, Value, _State) when size(Value) < 15 ->
-	Size = 16#20 + size(Value),
-	<<Size:8/unsigned,Value/binary>>;
-encode(binary, Value, State) ->
-	encode(binary, Value, <<>>, State);
-encode(date, {MegaSeconds,Seconds,MicroSeconds}, State) ->
-	MilliSeconds = MegaSeconds * ?MegaSeconds + Seconds * ?Seconds + MicroSeconds div ?MicroSeconds,
-	encode(date, MilliSeconds, State);
-encode(date, MilliSeconds, _State) ->
-	MinuteRemain = MilliSeconds rem (?Seconds * 60),
-	case MinuteRemain of
-		0 ->
-			Minutes = MilliSeconds div (?Seconds * 60),
-			<<16#4b,Minutes:32/unsigned>>;
-		_ -> <<16#4a,MilliSeconds:64/unsigned>>
-	end;
-encode(list, Input, [{set,SetInfo},_T]=State) when is_record(Input, list) ->
-	case find_set_info(Input#list.refNo, SetInfo) of
-		not_found -> encode(list, Input#list.len, Input#list.type, Input#list.values, State);
-		List -> encode(list, List#list.len, List#list.type, List#list.values, State)
-	end;
-encode(list, Input, State) when is_record(Input, list) ->
-	encode(list, Input#list.len, Input#list.type, Input#list.values, State);
-encode(list, List, State) ->
-	ListLength = length(List),
-	encode(fixedlist, ListLength, List, State);
-encode(vlist, List, State) ->
-	case List of
-		[] -> <<$W,$Z>>;
-		_ -> encode(vlist, List, <<$W>>, State)
-	end;
-encode(map, Input, [{set,SetInfo},_T]=State) when is_record(Input, map) ->
-	case find_set_info(Input#map.refNo, Input#map.type, SetInfo) of
-		not_found -> encode(map, Input#map.dict, State);
-		Map -> encode(map, Map#map.dict, State)
-	end;
-encode(map, Input, State) when is_record(Input, map) ->
-	encode(map, Input#map.dict, State);
-encode(map, Dict, State) ->
-	List = dict:to_list(Dict),
-	Encoder = fun({Key, Value}, {AccIn, StateIn}) ->
-		% Key
-		RK = encode(Key, StateIn),
-		{KeyBin, NewStateKey} = case RK of
-			{_, _} -> RK;
-			KeyB -> {KeyB, StateIn}
-		end,
-		% Value
-		RV = encode(Value, NewStateKey),
-		{ValueBin, NewStateValue} = case RV of
-			{_, _} -> RV;
-			ValueB -> {ValueB, NewStateKey}
-		end,
-		% Acc Out
-		{<<AccIn/binary,KeyBin/binary,ValueBin/binary>>, NewStateValue}
-	end,
-	{AccOut, NewState} = lists:foldl(Encoder, {<<$H>>, State}, List),
-	{<<AccOut/binary,$Z>>, NewState};
-encode(class, #class{name=Name, fields=Fields}, State) ->
-	% type
-	NameBin = encode(Name, State),
-	% fields length
-	FieldsLen = length(Fields),
-	FieldsLenBin = encode(int, FieldsLen, State),
-	% fields
-	encode(list, Fields, <<$C,NameBin/binary,FieldsLenBin/binary>>, State);
-encode(class_store, Input, [{set,SetInfo},ClassList]=State) ->
-	{Bin, _} = encode(class, Input, State),
-	{Bin, [{set,SetInfo},[Input#class{encoded=true}|ClassList]]};
-encode(class_store, Input, State) ->
-	{Bin, _} = encode(class, Input, State),
-%%	{Bin, [Input#class{encoded=true}|State]};
-	{Bin, State};
-encode(object, Input, [{set,SetInfo},T]=State) when is_record(Input, object) ->
-	ClassRes = class(Input#object.typeRef, Input#object.class, [], T),
-	{BaseBin, TypeNum, C, NewState} = case ClassRes of
-		{encoded, Class, TypeNo} -> {<<>>, TypeNo, Class, State};
-		{Class, TypeNo, NewST} ->
-			{Bin, NewClassST} = encode(class, Class, NewST),
-			{Bin, TypeNo, Class, [{set,SetInfo},NewClassST]}
-	end,
-	case find_set_info(Input#object.refNo, C#class.name, SetInfo) of
-		not_found -> encode(object, BaseBin, TypeNum, Input#object.values, NewState);
-		Obj -> encode(object, BaseBin, TypeNum, Obj#object.values, NewState)
-	end;
-encode(object, Input, State) when is_record(Input, object) ->
-	ClassRes = class(Input#object.typeRef, Input#object.class, [], State),
-
-	{BaseBin, TypeNum, NewState} = case ClassRes of
-		{encoded, _Class, TypeNo} -> {<<>>, TypeNo, State};
-		{Class, TypeNo, NewST} ->
-			{Bin, NewClassST} = encode(class, Class, NewST),
-			{Bin, TypeNo, NewClassST}
-	end,
-	encode(object, BaseBin, TypeNum, Input#object.values, NewState);
-encode(class_object,Input,State)->
-	[NativeType|Values] = tuple_to_list(Input),
-	{ClassEncodingBin, EncodedRef, NewState} =
-		case type_encoding:visit(NativeType,State) of
-			{ref, Ref} ->
-%%				encode_object(type_information, {ref, Ref}, State);
-				%% todo 还未验证
-				{<<>>,Ref,State};
-			{hash, Ref, Typedef , State0} ->
-				Class = typedef_to_class(Typedef,Ref),
-				{Bin,NewStateClass} = encode(class_store,Class,State0),
-				{Bin,Ref,NewStateClass}
-%%				encode(type_information, {hash, Ref,Typedef }, State0)
-		end,
-	encode(object, ClassEncodingBin, EncodedRef, Values, NewState);
-%%	{AccOut, _NewState} = lists:foldl(fun encode/2,{<<>>, NewState},Values),
-%%	{<<ClassEncodingBin/binary,$o,EncodedRef/binary,AccOut/binary>>, _NewState};
-
-encode(method, Method, State) when is_atom(Method) ->
-	String = atom_to_list(Method),
-	encode(method, String, State);
-encode(method, Method, _State) when is_binary(Method) ->
-	CamMethod = erlang_to_camel_case(Method),
-	Size = size(CamMethod),
-	<<$m,Size:16/unsigned,CamMethod/binary>>;
-encode(method, String, _State) when is_list(String) ->
-	CamString = erlang_to_camel_case(String),
-	Length = string:len(CamString),
-	Bin = list_to_binary(CamString),
-	<<$m,Length:16/unsigned,Bin/binary>>;
-encode(reply, ok, _State) -> 
-	<<$H,16#02,16#00,$R,16#01,$N>>;
-encode(reply, {ok, Object}, State) ->
-	encode(reply, Object, State);
-encode(reply, {error, {Error, Reason} }, State) ->
-	encode(fault, Error, Reason, State);
-encode(reply, Object, State) ->
-	case encode(Object, State) of
-		{Bin, _NewState} -> Bin;
-		Bin -> Bin
-	end,
-	<<$H,16#02,16#00,$R,Bin/binary>>.
-%---------------------------------------------------------------------------
-% encode/4
-%---------------------------------------------------------------------------
-encode(sub, Length, String, _State) when Length < 32 ->
-	Bin = list_to_binary(String),
-	<<Length:8,Bin/binary>>;
-encode(sub, Length, String, _State) when Length < 256 ->
-	Bin = list_to_binary(String),
-	<<16#30,Length:8,Bin/binary>>;
-encode(sub, Length, String, _State) when Length < 512 ->
-	Bin = list_to_binary(String),
-	<<16#31,(Length-256):8,Bin/binary>>;
-encode(sub, Length, String, _State) when Length < 768 ->
-	Bin = list_to_binary(String),
-	<<16#32,(Length-512):8,Bin/binary>>;
-encode(sub, Length, String, _State) when Length < ?CHUNK_SIZE ->
-	Bin = list_to_binary(String),
-	<<16#33,(Length-768):8,Bin/binary>>;
-encode(sub, Length, String, _State) when Length =:= ?CHUNK_SIZE ->
-	Bin = list_to_binary(String),
-	<<$S,Length:16,Bin/binary>>;
-encode(sub, Length, _String, [UTF8|State]) ->
-	encode(string, Length, UTF8, <<>>, State);
-encode(binary, Value, <<>>, _State) when size(Value) =< ?CHUNK_SIZE ->
-	Size = size(Value),
-	<<$B,Size:16,Value/binary>>;
-encode(binary, Value, Acc, _State) when size(Value) =< ?CHUNK_SIZE ->
-	Size = size(Value),
-	<<Acc/binary,$B,Size:16,Value/binary>>;
-encode(binary, Value, <<>>, State) ->
-	<<Chunk:?CHUNK_SIZE/binary,Rest/binary>> = Value,
-encode(binary, Rest, <<$b,?CHUNK_SIZE:16,Chunk/binary>>, State);
-encode(binary, Value, Acc, State) ->
-	<<Chunk:?CHUNK_SIZE/binary,Rest/binary>> = Value,
-	encode(binary, Rest, <<Acc/binary,$b,?CHUNK_SIZE:16,Chunk/binary>>, State);
-encode(list, List, Acc0, State) when is_binary(Acc0) ->
-	lists:foldl(fun encode_accumulate/2, {Acc0,State}, List);
-encode(list, Type, List, State) ->
-	ListLength = length(List),
-	encode(list, ListLength, Type, List, State);
-encode(vlist, List, Acc0, State) when is_binary(Acc0) ->
-	{AccOut, NewState} = lists:foldl(fun encode_accumulate/2, {Acc0,State}, List),
-	{<<AccOut/binary,$Z>>, NewState};
-encode(vlist, Type, List, State) ->
-	TypeBin = encode(Type, State),
-	case List of
-		[] -> <<$U,TypeBin/binary,$Z>>;
-		_ -> encode(vlist, List, <<$U,TypeBin/binary>>, State)
-	end;
-encode(fixedlist, ListLength, List, State) ->
-	case ListLength < 8 of
-		true ->
-			ListLengthFlag = 16#78 + ListLength,
-			case List of
-				[] -> <<ListLengthFlag:8>>;
-				_ -> encode(list, List, <<ListLengthFlag:8>>, State)
-			end;
-		false ->
-			ListLengthBin = encode(int, ListLength, State),
-			encode(list, List, <<$X,ListLengthBin/binary>>, State)
-	end;
-encode(fault, _Error, _Reason, State) ->
-	encode(fault, <<"ServiceException">>, _Error, _Reason, State);
-encode(call, Method, Args, State) ->
-	encode(call, Method, Args, fun encode_accumulate/2, State).
-%---------------------------------------------------------------------------
-% encode/5
-%---------------------------------------------------------------------------
-encode(string, Length, UTF8, Acc, _State) when Length =< ?CHUNK_SIZE ->
-	Bin = list_to_binary(xmerl_ucs:to_utf8(UTF8)),
-	<<Acc/binary,$S,Length:16,Bin/binary>>;
-encode(string, Length, UTF8, Acc, State) ->
-	{Chunk, Rest} = lists:split(?CHUNK_SIZE, UTF8),
-	ChunkBin = list_to_binary(xmerl_ucs:to_utf8(Chunk)),
-	encode(string, (Length-?CHUNK_SIZE), Rest, <<Acc/binary,$R,?CHUNK_SIZE:16,ChunkBin/binary>>, State);
-encode(list, -1, untyped, List, State) ->
-	encode(vlist, List, State);
-encode(list, -1, Type, List, State) ->
-	encode(vlist, Type, List, State);
-encode(list, Len, untyped, List, State) ->
-	encode(fixedlist, Len, List, State);
-encode(list, Len, Type, List, State) ->
-	TypeBin = encode(Type, State),
-	if
-		Len < 8 ->
-			ListLengthFlag = 16#70 + Len,
-			case List of
-				[] -> <<ListLengthFlag:8,TypeBin/binary>>;
-				_ -> encode(list, List, <<ListLengthFlag:8,TypeBin/binary>>, State)
-			end;
-		true ->
-			ListLengthBin = encode(int, Len, State),
-			encode(list, List, <<$V,TypeBin/binary,ListLengthBin/binary>>, State)
-	end;
-encode(object, BaseBin, TypeNo, Values, State) ->
-	IndexBin = if
-		TypeNo < 16 ->
-			logger:debug("[encode] encode object TypeNo ~p",[TypeNo]),
-			IndexWrap = TypeNo + 16#60,
-			<<IndexWrap:8>>;
-		true ->
-			IndexWrap = encode(int, TypeNo, State),
-			<<$O, IndexWrap/binary>>
-	end,
-	{Bin, NewState} = encode(list, Values, IndexBin, State),
-	{<<BaseBin/binary,Bin/binary>>, NewState};
-encode(call, Method, Args, Fun, State) when is_function(Fun) ->
-	MethodBin = encode(string, Method, State),
-	ArgsCount = encode(int, erlang:length(Args), State),
-	{Bin, _NewState} = lists:foldl(Fun, {<<>>, State}, Args),
-	<<$H,2,0,$C,MethodBin/binary,ArgsCount/binary,Bin/binary>>;
-encode(fault, Code, _Error, _Reason, State) ->
-	EncodedCode = encode(string,Code, State),
-	<<131,100,_L2:16/unsigned,Error/binary>> = term_to_binary(_Error),
-	EncodedError = encode(string,Error, State),
-	<<$H,16#02,16#00,$F,$H,4,"code",EncodedCode/binary,7,"message",EncodedError/binary,6,"detail",31,"Stack trace not yet implemented",$Z>>.
-
-%---------------------------------------------------------------------------
-% Utility methods
-%---------------------------------------------------------------------------
-erlang_to_camel_case(String) when is_binary(String) ->
-	AsList = binary_to_list(String),
-	AsCamel = lists:foldl(fun camelize/2,[],AsList),
-	list_to_binary(AsCamel);
-erlang_to_camel_case(String) when is_atom(String) ->
-	AsList = atom_to_list(String),
-	AsCamel = lists:foldl(fun camelize/2,[],AsList),
-	list_to_binary(AsCamel).    
-
-camelize(Element,Acc) when Element == $_ -> [$_|Acc];
-camelize(Element,[$_|Acc]) -> lists:append(Acc,[Element - 16#20]);
-camelize(Element,Acc) -> lists:append(Acc,[Element]).
-
-encode_accumulate(Value, {Acc, State}) ->
-    logger:debug("[encode] encode_accumulate value ~p",[Value]),
-	case encode(Value, State) of 
-		{Encoded,NewState} -> {<<Acc/binary,Encoded/binary>>,NewState};
-		Encoded -> {<<Acc/binary,Encoded/binary>>,State}
-	end.
-
-find_set_info(RefNo, SetInfo) ->
-	find_set_info(RefNo, untyped, SetInfo).
-find_set_info(_RefNo, _Type, []) ->
-	not_found;
-find_set_info(RefNo, Type, [Set|SetInfo]) ->
-	if
-		RefNo =:= Set#set.ref -> Set#set.value;
-		true ->
-			case equal(Type, Set#set.ref) of
-				true -> Set#set.value;
-				false -> find_set_info(RefNo, Type, SetInfo)
-			end
-	end.
-
-type_index(Type, [CurrentType|RestTypes]) when is_record(Type, class) ->
-	case equal(Type#class.name, CurrentType#class.name) of
-		true -> length(RestTypes);
-		false -> type_index(Type, RestTypes)
-	end;
-type_index(Type, [CurrentType|RestTypes]) ->
-	case equal(Type, CurrentType#class.name) of
-		true -> length(RestTypes);
-		false -> type_index(Type, RestTypes)
-	end.
-
-get_class(Where, ClassList) ->
-	SortClassList = lists:reverse(ClassList),
-	case Where#object.typeRef of
-		-1 ->
-			if
-			Where#object.class =:= auto -> hd(ClassList);
-			true ->
-				Index = type_index(Where#object.class, ClassList),
-				lists:nth(Index+1, SortClassList)
-			end;
-		TypeRef ->
-			lists:nth(TypeRef+1, SortClassList)
-	end.
-
-get_type_no(C, RestClasses) when is_record(C, class) ->
-	case C#class.typeNo of
-		-1 -> length(RestClasses);
-		_ -> C#class.typeNo
-	end.
-
-get_type(CListH, C, CListE) when is_record(C, class) ->
-	TypeNo = get_type_no(C, CListE),
-	case C#class.encoded of
-		true -> {encoded, C, TypeNo};
-		false -> {C, TypeNo, CListH++[C#class{encoded=true}|CListE]}
-	end.
-
-class(-1, auto, [], [C|CListE]) ->
-	get_type([], C, CListE);
-class(-1, Class, CListH, [C|CListE]) when is_record(Class, class) ->
-	case Class#class.name of
-		auto ->
-			case CListH of
-				[] -> get_type([], C, CListE);
-				[H|T] ->get_type([], H, T++[C|CListE])
-			end;
-		_ ->
-			case equal(Class#class.name, C#class.name) of
-				true -> get_type(CListH, C, CListE);
-				false -> class(-1, Class, CListH++[C], CListE)
-			end
-	end;
-class(-1, Class, CListH, [C|CListE]) ->
-	case equal(Class, C#class.name) of
-		true -> get_type(CListH, C, CListE);
-		false -> class(-1, Class, CListH++[C], CListE)
-	end;
-class(RefNo, _Class, CListH, [C|CListE]) ->
-	if
-		RefNo =:= length(CListE) -> get_type(CListH, C, CListE);
-		true -> class(RefNo, _Class, CListH++[C], CListE)
-	end.
-
-equal(S1, S2) when is_binary(S1) ->
-	if
-		S1 =:= S2 -> true;
-		true ->
-			S1List = binary_to_list(S1),
-			if
-				S1List =:= S2 -> true;
-				true -> false
-			end
-	end;
-equal(S1, S2) when is_list(S1) ->
-	if
-		S1 =:= S2 -> true;
-		true ->
-			S1Binary = list_to_binary(S1),
-			if
-				S1Binary =:= S2 -> true;
-				true -> false
-			end
-	end;
-equal(_S1, _S2) ->
-	false.
-
-wrap_class(ClassList) ->
-	Fun = fun(OldClass, AccIn) -> 
-		[#class{typeNo=OldClass#type_def.native_type, name=OldClass#type_def.foreign_type, fields=OldClass#type_def.fieldnames}|AccIn]
-	end,
-	lists:foldl(Fun, [], ClassList).
-
-get_value(Where, Ref, Field) ->
-	get_value(Where, Ref, Field, [], []).
-get_value(Where, Ref, Field, ClassList) ->
-	get_value(Where, Ref, Field, wrap_class(ClassList), []).
-get_value(Where, Ref, Field, ClassList, ObjVlues) when is_record(Where, list) ->
-	get_value(Where#list.values, Ref, Field, ClassList, ObjVlues);
-get_value(Where, Ref, Field, ClassList, _ObjVlues) when is_record(Where, map) ->
-	List = dict:to_list(Where#map.dict),
-	get_value(List, Ref, Field, ClassList, Where#map.refNo);
-get_value(Where, _Ref, _Field, ClassList, _ObjVlues) when is_record(Where, type_def) ->
-	{class, [#class{typeNo=Where#type_def.native_type, name=Where#type_def.foreign_type, fields=Where#type_def.fieldnames}|ClassList]};
-get_value(Where, _Ref, _Field, ClassList, _ObjVlues) when is_record(Where, class) ->
-	{class, [Where|ClassList]};
-get_value(Where, Ref, Field, ClassList, _ObjVlues) when is_record(Where, object) ->
-	Class = get_class(Where, ClassList),
-	if
-		Where#object.refNo =:= Ref -> get_value(Class#class.fields, Ref, Field, ClassList, Where#object.values);
-		Class =:= Ref -> get_value(Class#class.fields, Ref, Field, ClassList, Where#object.values);
-		true ->
-			case equal(Class#class.name, Ref) of
-				true -> get_value(Class#class.fields, Ref, Field, ClassList, Where#object.values);
-				false -> get_value(Where#object.values, Ref, Field, ClassList, skip)
-			end
-	end;
-get_value(Where, _RefNo, _Field, _ClassList, skip) when is_binary(Where) ->
-	next;
-get_value(Where, _RefNo, Field, _ClassList, Value) when is_binary(Where) ->
-	case equal(Where, Field) of
-		true -> {return, Value};
-		false -> next
-	end;
-get_value(Where, _RefNo, _Field, _ClassList, _Value) when is_atom(Where) ->
-	next;
-get_value(Where, _RefNo, _Field, _ClassList, _Value) when is_integer(Where) ->
-	next;
-get_value({ref, _No}, _RefNo, _Field, _ClassList, _ObjVlues) ->
-	next;
-get_value({K, V}, RefNo, Field, ClassList, MapRefNo) ->
-	case is_binary(K) of
-		true ->
-			if
-				RefNo =/= MapRefNo -> R = next;
-				true -> R = get_value(K, RefNo, Field, ClassList, V)
-			end;
-		false -> R = get_value(K, RefNo, Field, ClassList, [])
-	end,
-	case R of
-		next -> get_value(V, RefNo, Field, ClassList, []);
-		_ -> R
-	end;
-get_value([], _RefNo, _Field, _ClassList, _ObjVlues) ->
-	not_found;
-get_value([CurrentField|Fields], RefNo, Field, ClassList, [Value|Values]) ->
-	R = get_value(CurrentField, RefNo, Field, ClassList, Value),
-	case R of
-		{return, _} -> R;
-		{class, NewClassList} -> get_value(Fields, RefNo, Field, NewClassList, Values);
-		_ -> get_value(Fields, RefNo, Field, ClassList, Values)
-	end;
-get_value([Item|T], RefNo, Field, ClassList, Option)->
-	R = get_value(Item, RefNo, Field, ClassList, Option),
-	case R of
-		{return, _} -> R;
-		{class, NewClassList} -> get_value(T, RefNo, Field, NewClassList, Option);
-		_ -> get_value(T, RefNo, Field, ClassList, Option)
-	end.
-
-encode_object(object, Object, State) when is_tuple(Object) ->
-	[NativeType|Values] = tuple_to_list(Object),
-	{TypeEncoding, EncodedRef, NewState} =
-		case type_encoding:visit(NativeType,State) of
-			{ref, Ref} ->
-				encode_object(type_information, {ref, Ref}, State);
-			{hash, Hash, Ref, State0} ->
-				encode(type_information, {hash, Hash, Ref}, State0)
-		end,
-	{AccOut, _NewState} = lists:foldl(fun encode/2,{<<>>, NewState},Values),
-	{<<TypeEncoding/binary,$o,EncodedRef/binary,AccOut/binary>>, _NewState};
-encode_object(type_information, {ref, Ref}, State) ->
-	{<<>>, encode(int, Ref, State), State};
-encode_object(type_information, {hash, Hash, Ref}, State) ->
-	EncodedRef = encode(int, Ref, State),
-	{<<$O,Hash:32/unsigned>>, EncodedRef, State}.
-
-typedef_to_class(Typedef,DefineNo)->
-	#class{typeNo=DefineNo, name=Typedef#type_def.foreign_type, fields=Typedef#type_def.fieldnames}.
\ No newline at end of file
diff --git a/src/type_register.erl b/src/type_register.erl
index 4dc52cf..a338510 100644
--- a/src/type_register.erl
+++ b/src/type_register.erl
@@ -1,13 +1,20 @@
-%%%-------------------------------------------------------------------
-%%% @author dlive
-%%% @copyright (C) 2018, <COMPANY>
-%%% @doc
-%%%
-%%% @end
-%%% Created : 05. Mar 2018 2:06 PM
-%%%-------------------------------------------------------------------
+% ---------------------------------------------------------------------------
+%   Copyright (C) 2008 0x6e6562
+%
+%   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.
+% ---------------------------------------------------------------------------
+
 -module(type_register).
--author("dlive").
 %% API
 -export([init/0,regiest_foreign_native/1,lookup_foreign_type/1,lookup_native_type/1]).
 -include("hessian.hrl").
diff --git a/test/hessian_encode_tests.erl b/test/hessian_encode_tests.erl
index fb14186..df4c0af 100644
--- a/test/hessian_encode_tests.erl
+++ b/test/hessian_encode_tests.erl
@@ -26,11 +26,11 @@
 %%    ?debugFmt("state:~p~n",[EncodingState0]),
     RequestArg0 = #de_TestReq{name = <<"nameinfo">>, nick = <<"nickname">> ,age=10 },
 
-    {Bin, State0} = hessianEncode:encode(RequestArg0, EncodingState0),
+    {Bin, State0} = cotton_hessian:encode(RequestArg0, EncodingState0),
 
     type_register:init(),
     dubbo_type_transfer:pre_process_typedef(de_TestReq,<<"com.ifcoder.demo.bean.UserInfoRequest">>,record_info(fields,de_TestReq)),
-    {<<>>,Data,State2 } = hessianDecode2:decode(Bin,hessianDecode2:init()),
+    {<<>>,Data,State2 } = cotton_hessian:decode(Bin,cotton_hessian:init()),
     DecodeResult = dubbo_type_transfer:java_to_native(Data,State2),
     ?assert(is_record(DecodeResult,de_TestReq)),
     ?assertEqual(DecodeResult#de_TestReq.name,<<"nameinfo">>),