anchor.diff:  -module(gpb).
  --compile(export_all).
  +%-compile(export_all).
   -export([decode_msg/3]).
   -include_lib("eunit/include/eunit.hrl").
   
  
positive.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 {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)
      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) ->
  
negative.code:                           Fields,
                            RepeatedFNames)}.
  
  decode_wiretype(0) -> varint;
  decode_wiretype(1) -> bits64;
  decode_wiretype(2) -> length_delimited;
  decode_wiretype(5) -> bits32.
  
  skip_field(Bin, WireType) ->
      case decode_wiretype(WireType) of
          varint ->
              {_N, Rest} = decode_varint(Bin),
              Rest;
          bits64 ->
              <<_:64, Rest/binary>> = Bin,
              Rest;
          length_delimited ->
              {Len, Rest} = decode_varint(Bin),
              <<_:Len/binary, Rest2>> = Rest,
              Rest2;
          bits32 ->
              <<_:32, Rest/binary>> = Bin,
              Rest
      end.
  
  decode_type(FieldType, WireType, Bin, MsgDefs) ->
      case {FieldType, decode_wiretype(WireType)} of
          {sint32, varint} ->
              {NV, T} = decode_varint(Bin),
              {decode_zigzag(NV), T};
          {sint64, varint} ->
              {NV, T} = decode_varint(Bin),
              {decode_zigzag(NV), T};
          {int32, varint} ->
              %% 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
              %%
              %% 10 bytes is what it takes to varint-encode a -1 as a 64
              %% bit signed int. -1 as a 32 bit signed int is only 5 bytes.
              decode_type(int64, WireType, Bin, MsgDefs);
          {int64, varint} ->
              {NV, T} = decode_varint(Bin),
              <<N:64/signed>> = <<NV:64>>,
              {N, T};
          {uint32, varint} ->
              {_N, _Rest} = decode_varint(Bin);
          {uint64, varint} ->
              {_N, _Rest} = decode_varint(Bin);
          {bool, varint} ->
              {N, Rest} = decode_varint(Bin),
              {N =/= 0, Rest};
          {{enum, _EnumName}=Key, varint} ->
              {N, Rest} = decode_varint(Bin),
              {Key, EnumValues} = lists:keyfind(Key, 1, MsgDefs),
              {value, {EnumName, N}} = lists:keysearch(N, 2, EnumValues),
              {EnumName, Rest};
          {fixed64, bits64} ->
              <<N:64/little, Rest/binary>> = Bin,
              {N, Rest};
          {sfixed64, bits64} ->
              <<N:64/little-signed, Rest/binary>> = Bin,
              {N, Rest};
          {double, bits64} ->
              <<N:64/little-float, Rest/binary>> = Bin,
              {N, Rest};
          {string, length_delimited} ->
              {Len, Rest} = decode_varint(Bin),
              <<Utf8Str:Len/binary, Rest2/binary>> = Rest,
              {unicode:characters_to_list(Utf8Str, unicode), Rest2};
          {bytes, length_delimited} ->
              {Len, Rest} = decode_varint(Bin),
              <<Bytes:Len/binary, Rest2/binary>> = Rest,
              {Bytes, Rest2};
          {{msg,MsgName}, length_delimited} ->
              {Len, Rest} = decode_varint(Bin),
              <<MsgBytes:Len/binary, Rest2/binary>> = Rest,
              {decode_msg(MsgBytes, MsgName, MsgDefs), Rest2};
          {packed, length_delimited} ->
              fixme_handle_packed;
          {fixed32, bits32} ->
              <<N:32/little, Rest/binary>> = Bin,
              {N, Rest};
          {sfixed32, bits32} ->
              <<N:32/little-signed, Rest/binary>> = Bin,
              {N, Rest};
          {float, bits32} ->
              <<N:32/little-float, Rest/binary>> = Bin,
              {N, Rest}
      end.
  
  add_field(Value, FieldDef, MsgDefs, {MsgName, Fields}) ->
      %% 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
      %% For now, we assume it works like strings.
      {MsgName,
       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}.
  
  merge_field(FName, NewMsg, Fields, FMsgName, MsgDefs) ->
      case keyfetch(FName, Fields) of
  