anchor.diff:  
   decode_msg_simple_occurrence_test() ->
       {t1,[{a,undefined}]} =
  -        gpb:decode_msg(t1,
  -                       [{t1, [#field{name=a, fnum=1, type=int32,
  -                                     occurrence=optional, opts=[]}]}],
  -                       <<>>),
  +        decode_msg(<<>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type=int32,
  +                                       occurrence=optional, opts=[]}]}]),
       {t1,[{a,150}]} =
  -        gpb:decode_msg(t1,
  -                       [{t1, [#field{name=a, fnum=1, type=int32,
  -                                     occurrence=required, opts=[]}]}],
  -                       <<8,150,1>>),
  +        decode_msg(<<8,150,1>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type=int32,
  +                                       occurrence=required, opts=[]}]}]),
       {t1,[{a,[150, 151]}]} =
  -        gpb:decode_msg(t1,
  -                       [{t1, [#field{name=a, fnum=1, type=int32,
  -                                     occurrence=repeated, opts=[]}]}],
  -                       <<8,150,1, 8,151,1>>).
  +        decode_msg(<<8,150,1, 8,151,1>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type=int32,
  +                                       occurrence=repeated, opts=[]}]}]),
  +    ok.
  +
  +decode_msg_with_enum_field_test() ->
  +    {t1, [{a,v2}]} =
  +        decode_msg(<<8,150,1>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type={enum,e},
  +                                       occurrence=required, opts=[]}]},
  +                    {{enum,e}, [{v1, 100},
  +                                {v2, 150}]}]).
  +
  +decode_msg_with_bool_field_test() ->
  +    {t1, [{a,true}]} =
  +        decode_msg(<<8,1>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type=bool,
  +                                       occurrence=required, opts=[]}]}]),
  +    {t1, [{a,false}]} =
  +        decode_msg(<<8,0>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type=bool,
  +                                       occurrence=required, opts=[]}]}]).
  +decode_msg_with_string_field_test() ->
  +    {t1, [{a,"abc"}]} =
  +        decode_msg(<<10,9,$a,$b,$c,$\303,$\245,$\303,$\244,$\303,$\266>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type=string,
  +                                       occurrence=required, opts=[]}]}]).
  +
  +decode_msg_with_bytes_field_test() ->
  +    {t1, [{a,<<0,0,0,0>>}]} =
  +        decode_msg(<<10,4,0,0,0,0>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type=bytes,
  +                                       occurrence=required, opts=[]}]}]).
  +
  +decode_msg_with_sub_msg_field_test() ->
  +    {t1, [{a, {t2, [{b,150}]}}]} =
  +        decode_msg(<<10,3, 8,150,1>>,
  +                   t1,
  +                   [{{msg,t1}, [#field{name=a, fnum=1, type={msg,t2},
  +                                       occurrence=required, opts=[]}]},
  +                    {{msg,t2}, [#field{name=b, fnum=1, type=uint32,
  +                                       occurrence=required, opts=[]}]}]).
  
positive.code: -record(field,
          {name, fnum, type, occurrence, opts}).
  
  decode_msg(MsgName, MsgDefs, Bin) ->
      Msg    = new_initial_msg(MsgName, MsgDefs),
      MsgDef = keyfetch(MsgName, MsgDefs),
      decode_field(MsgDef, MsgDefs, Bin, Msg).
  
  new_initial_msg(MsgName, MsgDefs) ->
      MsgDef = keyfetch(MsgName, MsgDefs),
      {MsgName, lists:map(fun(#field{name=FName, occurrence=repeated}) ->
                                  {FName, []};
                             (#field{name=FName, type={msg,FieldMsgName}}) ->
                                  {FName, new_initial_msg(FieldMsgName, MsgDefs)};
                             (#field{name=FName}) ->
                                  {FName, undefined}
                          end,
                          MsgDef)}.
  
  decode_field(MsgDef, MsgDefs, Bin, Msg) when size(Bin) > 0 ->
      {Key, Rest} = decode_varint(Bin),
      FieldNum = Key bsr 3,
      WireType = Key band 7,
  
negative.code:     %% then do the updating here, keeping recursion to be only in this function
      %% thus sending down fewer args to auxiliary subfunctions
      %% Inline subfunctions??
      case lists:keyfind(FieldNum, #field.fnum, MsgDef) of
          false ->
              Rest2 = skip_field(Rest, WireType),
              decode_field(MsgDef, MsgDefs, Rest2, Msg);
          #field{type = FieldType} = FieldDef ->
              {NewValue, Rest2} = decode_type(FieldType, WireType, Rest, MsgDefs),
              NewMsg = add_field(NewValue, FieldDef, MsgDefs, Msg),
              decode_field(Rest2, MsgDef, MsgDefs, NewMsg)
      end;
  decode_field(<<>>, MsgDef, _MsgDefs, {MsgName, Fields}) ->
      %% Reverse any repeated fields.
      RepeatedFNames = [N || #field{name=N, occurrence=repeated} <- MsgDef],
      {MsgName, lists:foldl(fun(FName, Acc) ->
  