anchor.diff:      %% then do the updating here, keeping recursion to be only in this function
       %% thus sending down fewer args to auxiliary subfunctions
       %% Inline subfunctions??
  -    case {WireType, lists:keyfind(FieldNum, #field.fnum, MsgDef)} of
  -        {0, #field{type=sint32} = FieldDef} ->
  -            add_zigzag32_varint(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {0, #field{type=sint64} = FieldDef} ->
  -            add_zigzag64_varint(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {0, #field{type=int32} = FieldDef} ->
  -            add_2compl32_varint(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {0, #field{type=int64} = FieldDef} ->
  -            add_2compl64_varint(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {0, #field{type=uint32} = FieldDef} ->
  -            add_unsigned32_varint(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {0, #field{type=uint64} = FieldDef} ->
  -            add_unsigned64_varint(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {0, #field{type=bool} = FieldDef} ->
  -            add_bool_varint(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {0, #field{type={enum,EnumName}} = FieldDef} ->
  -            add_enum_varint(Rest, EnumName, FieldDef, MsgDef, MsgDefs, Msg);
  -        {1, #field{type=fixed64} = FieldDef} ->
  -            add_unsigned64(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {1, #field{type=sfixed64} = FieldDef} ->
  -            add_signed64(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {1, #field{type=double} = FieldDef} ->
  -            add_double(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {2, #field{type=string} = FieldDef} ->
  -            add_string(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {2, #field{type=bytes} = FieldDef} ->
  -            add_bytes(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {2, #field{type={msg,SubMsgName}} = FieldDef} ->
  -            add_embedded_msg(Rest, SubMsgName, FieldDef, MsgDef, MsgDefs, Msg);
  -        {2, #field{type=packed_repeated} = FieldDef} ->
  -            add_packed_repeated(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {5, #field{type=fixed32} = FieldDef} ->
  -            add_unsigned32(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {5, #field{type=sfixed32} = FieldDef} ->
  -            add_signed32(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {5, #field{type=float} = FieldDef} ->
  -            add_float(Rest, FieldDef, MsgDef, MsgDefs, Msg);
  -        {0, false} ->
  -            skip_varint(Rest, MsgDef, MsgDefs, Msg);
  -        {1, false} ->
  -            skip_64bits(Rest, MsgDef, MsgDefs, Msg);
  -        {2, false} ->
  -            skip_length_delimited(Rest, MsgDef, MsgDefs, Msg);
  -        {5, false} ->
  -            skip_32bits(Rest, MsgDef, MsgDefs, Msg)
  +    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}) ->
  +decode_field(<<>>, MsgDef, _MsgDefs, {MsgName, Fields}) ->
       %% Reverse any repeated fields.
       RepeatedFNames = [N || #field{name=N, occurrence=repeated} <- MsgDef],
       {MsgName, lists:foldl(fun(FName, Acc) ->
  
positive.code:                           Fields,
                            RepeatedFNames)}.
  
  add_zigzag32_varint(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      {NV, Rest} = decode_varint(Bin),
      N = decode_zigzag(NV),
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_zigzag64_varint(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      {NV, Rest} = decode_varint(Bin),
      N = decode_zigzag(NV),
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_2compl32_varint(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      %% This doc says: "If you use int32 or int64 as the type for a
      %% negative number, the resulting varint is always ten bytes long --
      %% it is, effectively, treated like a very large unsigned integer."
      %% http://code.google.com/apis/protocolbuffers/docs/encoding.html
      add_2compl64_varint(Bin, FieldDef, MsgDef, MsgDefs, Msg).
  
  add_2compl64_varint(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      {NV, Rest} = decode_varint(Bin),
      <<N:64/signed>> = <<NV:64>>,
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_unsigned32_varint(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      {N, Rest} = decode_varint(Bin),
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_unsigned64_varint(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      {N, Rest} = decode_varint(Bin),
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_bool_varint(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      {N, Rest} = decode_varint(Bin),
      add_field(N =/= 0, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_enum_varint(_Bin, _EnumName, _FieldDef, _MsgDef, _MsgDefs, _Msg) -> fixme.
  
  add_unsigned64(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      <<N:64/little, Rest/binary>> = Bin,
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_signed64(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      <<N:64/little-signed, Rest/binary>> = Bin,
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_double(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      <<N:64/little-float, Rest/binary>> = Bin,
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_string(_Bin, _FieldDef, _MsgDef, _MsgDefs, _Msg) -> fixme. % utf8?
  add_bytes(_Bin, _FieldDef, _MsgDef, _MsgDefs, _Msg) -> fixme.
  add_embedded_msg(_Bin, _SubMsgName, _FieldDef, _MsgDef, _MsgDefs, _Msg) -> fixme.
  add_packed_repeated(_Bin, _FieldDef, _MsgDef, _MsgDefs, _Msg) -> fixme.
  
  add_unsigned32(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      <<N:32/little, Rest/binary>> = Bin,
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_signed32(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      <<N:32/little-signed, Rest/binary>> = Bin,
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  add_float(Bin, FieldDef, MsgDef, MsgDefs, Msg) ->
      <<N:32/little-float, Rest/binary>> = Bin,
      add_field(N, FieldDef, MsgDef, MsgDefs, Msg, Rest).
  
  skip_varint(Bin, MsgDef, MsgDefs, Msg) ->
      {_N, Rest} = decode_varint(Bin),
      decode_field(MsgDef, MsgDefs, Rest, Msg).
  
  skip_64bits(Bin, MsgDef, MsgDefs, Msg) ->
      <<_:64, Rest/binary>> = Bin,
      decode_field(MsgDef, MsgDefs, Rest, Msg).
  
  skip_length_delimited(Bin, MsgDef, MsgDefs, Msg) ->
      {Len, Rest} = decode_varint(Bin),
      <<_:Len/binary, Rest2>> = Rest,
      decode_field(MsgDef, MsgDefs, Rest2, Msg).
  
  skip_32bits(Bin, MsgDef, MsgDefs, Msg) ->
      <<_:32, Rest/binary>> = Bin,
      decode_field(MsgDef, MsgDefs, Rest, Msg).
  
  add_field(Value, FieldDef, MsgDef, MsgDefs, {MsgName, Fields}, Rest) ->
      %% FIXME: what about bytes?? "For numeric types and strings, if
      %% the same value appears multiple times, the parser accepts the
      %% last value it sees." But what about bytes?
      %% http://code.google.com/apis/protocolbuffers/docs/encoding.html
      NewFields =
          case FieldDef of
              #field{name = FName, occurrence = required, type={msg,FMsgName}}->
                  merge_field(FName, Value, Fields, FMsgName, MsgDefs);
              #field{name = FName, occurrence = optional, type={msg,FMsgName}}->
                  merge_field(FName, Value, Fields, FMsgName, MsgDefs);
              #field{name = FName, occurrence = required}->
                  replace_field(FName, Value, Fields);
              #field{name = FName, occurrence = optional}->
                  replace_field(FName, Value, Fields);
              #field{name = FName, occurrence = repeated} ->
                  append_to_field(FName, Value, Fields)
          end,
      decode_field(MsgDef, MsgDefs, Rest, {MsgName, NewFields}).
  
  merge_field(FName, NewMsg, Fields, FMsgName, MsgDefs) ->
      case keyfetch(FName, Fields) of
  
negative.code: %% * Add a new_default_msg that sets default values according to
  %%   type (and optionalness) as docoumented on the google web:
  %%   strings="", booleans=false, integers=0, enums=<first value> and so on.
  %%
  %%   Message fields can also have default values specified in the .proto file.
  %%
  %% * Optionally non-crash on type-mismatches spec<-->actual-wire-contents
  %%   Ignore/skip instead of crash?
  