anchor.diff:      {128, <<255>>} = decode_varint(<<128, 1, 255>>),
       {150, <<255>>} = decode_varint(<<150, 1, 255>>).
   
  +
  +-record(m1,{a}).
  +
   decode_msg_simple_occurrence_test() ->
  -    {t1,[{a,undefined}]} =
  +    #m1{a = undefined} =
           decode_msg(<<>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type=int32,
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a, type=int32,
                                          occurrence=optional, opts=[]}]}]),
  -    {t1,[{a,150}]} =
  +    #m1{a = 150} =
           decode_msg(<<8,150,1>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type=int32,
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a, type=int32,
                                          occurrence=required, opts=[]}]}]),
  -    {t1,[{a,[150, 151]}]} =
  +    #m1{a = [150, 151]} =
           decode_msg(<<8,150,1, 8,151,1>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type=int32,
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a, type=int32,
                                          occurrence=repeated, opts=[]}]}]),
       ok.
   
   decode_msg_with_enum_field_test() ->
  -    {t1, [{a,v2}]} =
  +    #m1{a = v2} =
           decode_msg(<<8,150,1>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type={enum,e},
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a,
  +                                       type={enum,e},
                                          occurrence=required, opts=[]}]},
                       {{enum,e}, [{v1, 100},
                                   {v2, 150}]}]).
   
   decode_msg_with_bool_field_test() ->
  -    {t1, [{a,true}]} =
  +    #m1{a = true} =
           decode_msg(<<8,1>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type=bool,
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a, type=bool,
                                          occurrence=required, opts=[]}]}]),
  -    {t1, [{a,false}]} =
  +    #m1{a = false} =
           decode_msg(<<8,0>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type=bool,
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a, type=bool,
                                          occurrence=required, opts=[]}]}]).
  +
   decode_msg_with_string_field_test() ->
  -    {t1, [{a,"abc\345\344\366"++[1022]}]} =
  +    #m1{a = "abc\345\344\366"++[1022]} =
           decode_msg(<<10,11,
                       $a,$b,$c,$\303,$\245,$\303,$\244,$\303,$\266,$\317,$\276>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type=string,
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a, type=string,
                                          occurrence=required, opts=[]}]}]).
   
   decode_msg_with_bytes_field_test() ->
  -    {t1, [{a,<<0,0,0,0>>}]} =
  +    #m1{a = <<0,0,0,0>>} =
           decode_msg(<<10,4,0,0,0,0>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type=bytes,
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a, type=bytes,
                                          occurrence=required, opts=[]}]}]).
   
  +-record(m2, {b}).
  +
   decode_msg_with_sub_msg_field_test() ->
  -    {t1, [{a, {t2, [{b,150}]}}]} =
  +    #m1{a = #m2{b = 150}} =
           decode_msg(<<10,3, 8,150,1>>,
  -                   t1,
  -                   [{{msg,t1}, [#field{name=a, fnum=1, type={msg,t2},
  +                   m1,
  +                   [{{msg,m1}, [#field{name=a, fnum=1, rnum=#m1.a,
  +                                       type={msg,m2},
                                          occurrence=required, opts=[]}]},
  -                    {{msg,t2}, [#field{name=b, fnum=1, type=uint32,
  +                    {{msg,m2}, [#field{name=b, fnum=1, rnum=#m2.b, type=uint32,
                                          occurrence=required, opts=[]}]}]).
   
  +-record(m3, {a,b,c,d,e}).
  +-record(m4, {x,y}).
  +
   merge_msg_test() ->
  -    {m1, [{a, 20},
  -          {b, 22},
  -          {c, 13},
  -          {d, [11,12, 21,22]},
  -          {e, {m2, [{x, 210},
  -                    {y, [111,112, 211,212]}]}}]} =
  -        merge_msgs({m1, [{a, 10},
  -                         {b, undefined},
  -                         {c, 13},
  -                         {d, [11,12]},
  -                         {e, {m2, [{x, 110},
  -                                   {y, [111, 112]}]}}]},
  -                   {m1, [{a, 20},             %% overwrites integers
  -                         {b, 22},             %% overwrites undefined
  -                         {c, undefined},      %% undefined does not overwrite
  -                         {d, [21,22]},        %% sequences appends
  -                         {e, {m2, [{x, 210},  %% merging recursively
  -                                   {y, [211, 212]}]}}]},
  -                   [{{msg,m1}, [#field{name=a,fnum=1, type=uint32,
  +    #m3{a = 20,
  +        b = 22,
  +        c = 13,
  +        d = [11,12, 21,22],
  +        e = #m4{x = 210,
  +                y = [111,112, 211,212]}} =
  +        merge_msgs(#m3{a = 10,
  +                       b = undefined,
  +                       c = 13,
  +                       d = [11,12],
  +                       e = #m4{x = 110,
  +                               y = [111, 112]}},
  +                   #m3{a = 20,             %% overwrites integers
  +                       b = 22,             %% overwrites undefined
  +                       c = undefined,      %% undefined does not overwrite
  +                       d = [21,22],        %% sequences appends
  +                       e = #m4{x = 210,    %% merging recursively
  +                               y = [211, 212]}},
  +                   [{{msg,m3}, [#field{name=a,fnum=1, rnum=#m3.a, type=uint32,
                                          occurrence=required, opts=[]},
  -                                #field{name=b,fnum=2, type=uint32,
  +                                #field{name=b,fnum=2, rnum=#m3.b, type=uint32,
                                          occurrence=optional, opts=[]},
  -                                #field{name=c,fnum=3, type=uint32,
  +                                #field{name=c,fnum=3, rnum=#m3.c, type=uint32,
                                          occurrence=optional, opts=[]},
  -                                #field{name=d,fnum=4, type=uint32,
  +                                #field{name=d,fnum=4, rnum=#m3.d, type=uint32,
                                          occurrence=repeated, opts=[]},
  -                                #field{name=e,fnum=5, type={msg,m2},
  +                                #field{name=e,fnum=5, rnum=#m3.e,
  +                                       type={msg,m4},
                                          occurrence=optional, opts=[]}]},
  -                    {{msg,m2}, [#field{name=x, fnum=1, type=uint32,
  +                    {{msg,m4}, [#field{name=x, fnum=1, rnum=#m4.x, type=uint32,
                                          occurrence=optional, opts=[]},
  -                                #field{name=y, fnum=w, type=uint32,
  +                                #field{name=y, fnum=w, rnum=#m4.y, type=uint32,
                                          occurrence=repeated, opts=[]}]}]).
  
positive.code: -include_lib("eunit/include/eunit.hrl").
  
  %% TODO:
  %%
  %% * Support records on the erlang side:
  %%   let #fields have a record field index number: #record.field
  %%   and do setelement instead of keyfetch and replace_field
  %%
  %% * Add a new_default_msg that sets default values according to
  %%   type (and optionalness) as docoumented on the google web:
  
negative.code: %%   but this has been under debate on the erlang mailing list since it
  %%   was unexpected. Related: principle of least astonishment.
  -record(field,
          {name, fnum, rnum, type, occurrence, opts}).
  
  decode_msg(Bin, MsgName, MsgDefs) ->
      MsgKey = {msg,MsgName},
  