anchor.diff:  -copyright('Copyright (c) 2016 - 2017 SigScale Global Inc.').
   
   -export([date/1, iso8601/1, etag/1]).
  --export([parse/1, pointer/1, patch/2]).
  +-export([pointer/1, patch/2]).
   -export([parse_query/1, filter/2, range/1]).
  -
  --record(pob, {op, path, value}).
  -
  --type op_values() :: string() | integer() | boolean()
  -		| {array, [{struct, [tuple()]}]} | {struct, [tuple()]}.
   
   %% support deprecated_time_unit()
   -define(MILLISECOND, milli_seconds).
  
positive.code: 	lists:reverse(Acc) ++ [{Name, Value} | T];
  patch_replace(Path, Value, [H | T], Acc) ->
  	patch_replace(Path, Value, T, [H | Acc]).
  
  -spec parse(Oplists) -> Result
  	when
  		Oplists		:: [{struct, OPLObject}],
  		OPLObject	:: [{Key, Value}],
  		Result		:: [Operations] | {error, invalid_format},
  		Key			:: string(),
  		Value			:: op_values(),
  		Operations	:: {OP, Path, Value},
  		OP				:: replace | add | remove | move | copy | test,
  		Path			:: list().
  parse(Oplists) ->
  	parse1(lists:map(fun decode_operations/1, Oplists), []).
  %% @hidden
  parse1([], Acc) ->
  	Acc;
  parse1([#pob{op = "replace", path = Path, value = Value} | T], Acc) ->
  	parse1(T, [{replace, parse_path(Path), Value} | Acc]);
  parse1([#pob{op = "add", path = Path, value = Value} | T], Acc) ->
  	parse1(T, [{add, parse_path(Path), Value} | Acc]);
  parse1([#pob{op = "remove", path = Path, value = Value} | T], Acc) ->
  	parse1(T, [{remove, parse_path(Path), Value} | Acc]);
  parse1([#pob{op = "move", path = Path, value = Value} | T], Acc) ->
  	parse1(T, [{move, parse_path(Path), Value} | Acc]);
  parse1([#pob{op = "copy", path = Path, value = Value} | T], Acc) ->
  	parse1(T, [{copy, parse_path(Path), Value} | Acc]);
  parse1([#pob{op = "test", path = Path, value = Value} | T], Acc) ->
  	parse1(T, [{test, parse_path(Path), Value} | Acc]);
  parse1(_, _) ->
  	{error, invalid_format}.
  
  -spec merge_patch(Target, Patch) -> Result
  	when
  		Target :: {struct, list()},
  		Patch		:: {struct, list()} | {array, list()},
  		Result :: {struct, list()} | {array, list()}.
  %% @doc Psudo code implementation for RFC7386 Section 2
  merge_patch(Target, Patch) ->
  	case is_object(Patch) of
  		true ->
  			Target1 = case is_object(Target) of
  				true ->
  					Target;
  				false ->
  					{struct, []}
  			end,
  			do_merge(get_patch_keys(Patch), Patch, Target1);
  		false ->
  			Patch
  	end.
  
  %%----------------------------------------------------------------------
  %%  internal functions
  
negative.code: split([], Acc) ->
  	lists:reverse(Acc).
  
  