anchor.diff:      %API
       request() |
       %tree sync msgs
  -    {check_nodes, InitiatorPid::comm:mypid(), [merkle_cmp_request()]} |
  +    {check_nodes, InitiatorPid::comm:mypid(), [merkle_cmp_requst()]} |
       {check_nodes_response, [merkle_cmp_result()]} |
       %dht node response
       {get_state_response, intervals:interval()} |
  
positive.code:          }).
  -type state() :: #rr_recon_state{}.
  
  -type merkle_cmp_request() :: {intervals:interval(), merkle_tree:mt_node_key()}.
  -type merkle_cmp_result()  ::
            {intervals:interval(), ok_inner | ok_leaf | not_found | fail_leaf} |
            {intervals:interval(), fail_inner, [merkle_tree:mt_node_key()]}.
  
  -type request() :: 
      {start, method(), DestKey::recon_dest()} |
  
negative.code: % Merkle Tree specific
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  -spec check_node([merkle_cmp_requst()], merkle_tree:merkle_tree() | RestTree) 
          -> {[merkle_cmp_result()], RestTree}
      when
          is_subtype(RestTree, [merkle_tree:mt_node()]).
  check_node(L, Tree) ->
      case merkle_tree:is_merkle_tree(Tree) of
          false -> p_check_node(L, Tree, {[], []});
          true -> p_check_node(L, [Tree], {[], []})
      end.
  
  -spec p_check_node([merkle_cmp_requst()], [merkle_tree:mt_node()], Acc::Res) -> Res
      when
          is_subtype(Res, {[merkle_cmp_result()], [merkle_tree:mt_node()]}).
  p_check_node([], [], {AccR, AccN}) ->
      {lists:reverse(AccR), lists:reverse(AccN)};
  p_check_node([?omit | TK], [_Node | TN], Acc) ->
      p_check_node(TK, TN, Acc);
  p_check_node([Hash | TK], [Node | TN], {AccR, AccN}) ->
      IsLeaf = merkle_tree:is_leaf(Node),
      case merkle_tree:get_hash(Node) =:= Hash of
          true when IsLeaf -> p_check_node(TK, TN, {[?ok_leaf | AccR], AccN});
          true when not IsLeaf -> p_check_node(TK, TN, {[?ok_inner | AccR], AccN});
          false when IsLeaf -> p_check_node(TK, TN, {[?fail_leaf | AccR], AccN});
          false when not IsLeaf ->
              Childs = merkle_tree:get_childs(Node),
              p_check_node(TK, TN, {[?fail_inner | AccR], 
                                    lists:append(lists:reverse(Childs), AccN)}) 
      end.
  
  -spec process_tree_cmp_result([merkle_cmp_result()], merkle_tree:merkle_tree() | RestTree, pos_integer(), Stats) ->
            {Requests, Resolve, New::Stats, New::RestTree}
      when
        is_subtype(RestTree,  [merkle_tree:mt_node()]),
        is_subtype(Stats,     rr_recon_stats:stats()),
        is_subtype(Requests,  [merkle_cmp_requst()]),
        is_subtype(Resolve,   [merkle_tree:mt_node()]).
  process_tree_cmp_result(CmpResult, Tree, BranchSize, Stats) ->
      Compared = length(CmpResult),
      NStats = rr_recon_stats:inc([{tree_compareLeft, -Compared}, 
                                   {tree_nodesCompared, Compared}], Stats),
      case merkle_tree:is_merkle_tree(Tree) of
          false -> p_process_tree_cmp_result(CmpResult, Tree, BranchSize, NStats, {[], [], []});
          true -> p_process_tree_cmp_result(CmpResult, [Tree], BranchSize, NStats, {[], [], []})
      end.
  
  -spec p_process_tree_cmp_result([merkle_tree:mt_node_key()], RestTree, BranchSize, Stats, {Acc::Req, Acc::Res, AccRTree::Res}) 
          -> {Req, Res, Stats, RestTree::Res}           
      when
        is_subtype(BranchSize,pos_integer()),
        is_subtype(Stats,     rr_recon_stats:stats()),
        is_subtype(Req,       [merkle_tree:mt_node_key()]),
        is_subtype(Res,       [merkle_tree:mt_node()]),
        is_subtype(RestTree,  [merkle_tree:mt_node()]).
  p_process_tree_cmp_result([], [], _, Stats, {Req, Res, RTree}) ->
      {lists:reverse(Req), Res, Stats, lists:reverse(RTree)};
  p_process_tree_cmp_result([?ok_inner | TR], [Node | TN], BS, Stats, Acc) ->
      NStats = rr_recon_stats:inc([{tree_compareSkipped, merkle_tree:size(Node)}], Stats),
      p_process_tree_cmp_result(TR, TN, BS, NStats, Acc);
  p_process_tree_cmp_result([?ok_leaf | TR], [_Node | TN], BS, Stats, Acc) ->
      NStats = rr_recon_stats:inc([{tree_compareSkipped, 1}], Stats),
      p_process_tree_cmp_result(TR, TN, BS, NStats, Acc);
  p_process_tree_cmp_result([?fail_leaf | TR], [Node | TN], BS, Stats, {Req, Res, RTree}) ->
      p_process_tree_cmp_result(TR, TN, BS, Stats, {Req, [Node | Res], RTree});
  p_process_tree_cmp_result([?fail_inner | TR], [Node | TN], BS, Stats, {Req, Res, RTree}) ->
      case merkle_tree:is_leaf(Node) of
          false -> 
              Childs = merkle_tree:get_childs(Node),
              NewReq = [merkle_tree:get_hash(X) || X <- Childs],
              NStats = rr_recon_stats:inc([{tree_compareLeft, length(Childs)}], Stats),
              p_process_tree_cmp_result(TR, TN, BS, NStats, 
                                        {lists:append(lists:reverse(NewReq), Req), 
                                         Res, 
                                         lists:append(lists:reverse(Childs), RTree)});
          true -> 
              NewReq = [?omit || _ <- lists:seq(1, BS)],
              p_process_tree_cmp_result(TR, TN, BS, Stats, 
                                        {lists:append(NewReq, Req), [Node | Res], RTree})
      end.
  
  % @doc Starts one resolve process per leaf node in a given node
  