anchor.diff:      <<Bytes:Sz/binary,Rem/binary>> = Rest,
       {?bytes(Bytes),Rem};
   decode_obj(<<?FAST_ERROR,Rest1/binary>>) ->
  -    {Code,Rest2} = decode_type(int,Rest1),
  -    {Obj,Rest3} = decode_obj(Rest2),
  -    {?error(Code,Obj),Rest3};
  -decode_obj(<<?VARINT_ERROR,Bin/binary>>) ->
  -    {ErrCode,PostErr} = decode_type(svarint64,Bin),
  -    {Msg,Rest} = decode_obj(PostErr),
  -    {?error(ErrCode,Msg),Rest};
  +    {Code, Rest2} = decode_obj(Rest1),
  +    {Obj, Rest3} = decode_obj(Rest2),
  +    {?error(Code, Obj), Rest3};
  +decode_obj(<<?VARINT_ERROR, Bin/binary>>) ->
  +    {ErrCode, PostErr} = decode_svarint(Bin),
  +    {Msg, Rest} = decode_obj(PostErr),
  +    {?error(ErrCode, Msg), Rest};
   decode_obj(<<?VARINT_ARRAY,Bin/binary>>) ->
       {Sz,Rest} = decode_varint(Bin),
       decode_array(Rest,Sz,[]);
  
positive.code: decode_obj(<<?FALSE,Data/binary>>) ->
      {false, Data};
  decode_obj(<<?VARINT_TIME,Data/binary>>) ->
      decode_type(time,Data);
  decode_obj(<<1:4,Sz:4,Int:Sz/unsigned-unit:8,Rest/binary>>) ->
      {Int,Rest};
  decode_obj(<<0:4,Sz:4,Int:Sz/signed-unit:8,Rest/binary>>) ->
      {Int,Rest};
  decode_obj(<<Other:1/binary,_Rest/binary>>) ->
      throw({bad_tag,Other}).
  
  
  
  
  
  
  decode_chain(Bin,Types) -> decode_chain(Bin,Types,[]).
  decode_chain(Bin,[],Acc) -> {lists:reverse(Acc),Bin};
  decode_chain(Bin,[Type|Types],Acc) ->
      {Data,NewBin} = decode_type(Type,Bin),
      decode_chain(NewBin,Types,[Data|Acc]).
  
  decode_type(channel_type,<<B:1/binary,Rest/binary>>) ->
      case B of
          <<"C">> -> {call,Rest};
          <<"S">> -> {sub,Rest};
          Other -> {Other,Rest}  %% if we can't decode, leave in byte form
      end;
  decode_type(exatom,Bin) ->
      {Str,Rest} = decode_type(string,Bin),
      Atom = try binary_to_existing_atom(Str,utf8)
             catch Type:Reason -> ?lwarn("Failed to convert: ~p in to existing atom {~p,~p}",[Str,Type,Reason]), Str
             end,
      {Atom,Rest};
  decode_type(atom,Bin) ->
      {Str,Rest} = decode_type(string,Bin),
      {binary_to_atom(Str,utf8),Rest};
  decode_type(uuid,<<UUID:16/binary,Rest/binary>>) ->
      {?uuid(list_to_binary(uuid:to_string(UUID))), Rest};
  decode_type(uuid_notag,<<UUID:16/binary,Rest/binary>>) ->
      {UUID,Rest};
  decode_type(secid,<<SecID:16/binary,Rest/binary>>) ->
      {?secid(SecID),Rest};
  decode_type(bytes,Bin) ->
      {Sz,PostSz} = decode_varint(Bin),
      <<Bytes:Sz/binary,Rest/binary>> = PostSz,
      {?bytes(Bytes),Rest};
  decode_type(byte,<<B,Rest/binary>>) ->
      {?byte(B),Rest};
  decode_type(string,Bin) ->
      {Sz,PostSz} = decode_varint(Bin),
      <<Str:Sz/binary,Rest/binary>> = PostSz,
      {Str,Rest};
  decode_type(int,<<1:4,Sz:4,Int:Sz/unsigned-unit:8,Rest/binary>>) ->
      {Int,Rest};
  decode_type(int,<<0:4,Sz:4,Int:Sz/signed-unit:8,Rest/binary>>) ->
      {Int,Rest};
  decode_type(svarint32,Bin) ->
      decode_svarint(Bin);
  decode_type(svarint64,Bin) ->
      decode_svarint(Bin);
  decode_type(varint32,Bin) ->
      decode_varint(Bin);
  decode_type(varint64,Bin) ->
      decode_varint(Bin);
  decode_type(double,<<Double:64/float,Rest/binary>>) ->
      {Double,Rest};
  decode_type(float,<<Float:32/float,Rest/binary>>) ->
      {Float,Rest};
  decode_type(time,Bin) ->
      {Ts,Rest} = decode_svarint(Bin),
      {?time(Ts),Rest}.
  
  
  
  decode_map(Bin,0,Acc) ->
      {?map(lists:reverse(Acc)),Bin};
  
negative.code:     {E,Rem} = decode_obj(Bin),
      decode_array(Rem,Sz-1,[E|Acc]).
  
  decode_svarint(Bytes) ->
      {Value,Rest} = decode_varint(Bytes, 0, 0),
      {(Value bsr 1) bxor (-(Value band 1)),Rest}.
  