anchor.diff:      end.
                                   
       
  +%% @doc Projects a parsed Json Path (from jpparse) on a json object
  +%% and extracts matched values. nomatch is return if no match is found.
  +%% This function uses imem_json primitives, and as such is format neutral.
  +-spec jpp_match(JPPTree,data_object()) -> value() | ListOfValues | nomatch
  +    when JPPTree :: tuple(),
  +         ListOfValues :: [value() | ListOfValues].
  +
  +-define(OO(_X), {'{}',_X}).
  +-define(LL(_X), {'[]',_X}).
  +-define(FF(_X), {'$',_X}).
  +-define(JV, jpp_value).
  +
  +jpp_match(Tree,DataObject) when is_binary(DataObject) ->
  +    jpp_match(Tree,?FROM_JSON(DataObject));
  +jpp_match(Tree,DataObject) ->
  +    jpp_walk(Tree,DataObject).
  +
  +    %% Higher level parsing
  +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  +    jpp_walk({':',Elements},CLevel) ->
  +        jpp_walk(Elements,CLevel);
  +
  +    jpp_walk([],CLevel) -> CLevel;
  +
  +    %% Object Walking
  +    jpp_walk([Field|Tail],CLevel) when is_binary(Field) ->
  +        jpp_walk([?OO(Field)| Tail], CLevel);
  +
  +    jpp_walk([?OO([])|Tail],CLevel) ->
  +        jpp_walk([?FF(<<"values">>)|Tail], CLevel);
  +
  +    jpp_walk([?OO(ManyFields)|Tail],CLevel) when is_list(ManyFields) ->
  +        [jpp_walk([?OO(Field) | Tail],CLevel) || Field <- ManyFields];
  +
  +    jpp_walk([?OO('_')|Tail],CLevel) ->
  +        jpp_walk([Tail], CLevel);
  +
  +    jpp_walk([?OO(?FF(Any))|Tail],CLevel) ->
  +        jpp_walk([?FF(Any)|Tail], CLevel);
  +
  +    jpp_walk([{'{}',Origin,Field}|Tail],CLevel) ->
  +        jpp_walk([?OO(Origin),?OO(Field) | Tail],CLevel);
  +
  +    %% Object "Function-as-a-property"
  +    jpp_walk([?FF(<<"values">>)|Tail],CLevel) ->
  +        [jpp_walk(Tail,NLevel) || NLevel <- ?MODULE:values(CLevel)];
  +
  +    jpp_walk([?FF(<<"firstChild">>)|Tail],CLevel) ->
  +        [NLevel|_] = ?MODULE:values(CLevel),
  +        jpp_walk(Tail,NLevel);
  +
  +    %% List Walking
  +    jpp_walk([{'[]','_',Index}|Tail],CLevel) ->
  +        jpp_walk([?LL(Index)|Tail],CLevel);
  +
  +    jpp_walk([{'[]',Field,Index}|Tail],CLevel) when is_binary(Field) ->
  +        jpp_walk([?OO(Field), ?LL(Index)| Tail], CLevel);
  +
  +    jpp_walk([?LL([])|Tail],CLevel) ->
  +        jpp_walk([?LL({'-', 1, ?MODULE:size(CLevel)})| Tail], CLevel);
  +
  +    jpp_walk([?LL({'-',Start,End})|Tail],CLevel) ->
  +        Seq = lists:seq(?JV(Start), ?JV(End)),
  +        jpp_walk([?LL(Seq)| Tail], CLevel);
  +
  +
  +    jpp_walk([?LL(List)|Tail], CLevel) when is_list(List) ->
  +        [jpp_walk([?LL(Index)| Tail], CLevel) || Index <- List];
  +        
  +
  +    %% Lower level matching (and actually doing something)
  +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  +    jpp_walk([?LL(RawIndex)|Tail],CLevel) ->
  +        Index = ?JV(RawIndex),
  +        Length = ?MODULE:size(CLevel),
  +        if Index > Length -> nomatch;
  +           true -> NLevel =  lists:nth(Index,CLevel),
  +                   jpp_walk(Tail,NLevel)
  +        end;
  +    jpp_walk([?OO(RawField)|Tail],CLevel)->
  +        Field = ?JV(RawField),
  +        case ?MODULE:get(Field,CLevel) of
  +            undefined -> nomatch;
  +            NLevel -> jpp_walk(Tail,NLevel)
  +        end.
  +
  +    jpp_value(Value) when is_binary(Value) -> Value;
  +    jpp_value(Value) when is_integer(Value) -> Value.
  +         
  +        
       
   
   -ifdef(TEMP_ALLOW_MATCH).
  
positive.code: 
  %-define(TEMP_ALLOW_MATCH,true).
  
  %% Json Decoding & Encoding Library Configuration
  %% ===================================================================
  %% Format:  [{Module, DecodeFun, EncodeFun} | _ ]
  
negative.code: 
  -spec clean_null_values(data_object()) -> data_object().
  -ifdef(ALLOW_MAPS).
  clean_null_values([{_,_}|_] = DataObject) ->
      [{K,V} || {K,V} <- DataObject, V =/= null];
  clean_null_values(DataObject) when is_list(DataObject) ->
      DataObject;
  clean_null_values(DataObject) when is_map(DataObject) ->
      maps:fold(fun(_,null,OutMap) -> OutMap;
                   (K,V,OutMap) -> maps:put(K,V,OutMap) end,
  