anchor.diff:                 <<X:SigSizeI/integer-unit:1>> = <<(merkle_tree:get_hash(Node)):SigSizeI>>,
                  X
           end,
  +    EmptyLeafHash = IsLeafHash andalso Hash =:= none,
  +    NonEmptyLeafHash = IsLeafHash andalso Hash =/= none,
       if Hash =:= NodeHash andalso IsLeafHash =:= IsLeafNode ->
              Skipped = merkle_tree:size(Node) - 1,
  -           if IsLeafHash andalso Hash =:= none ->
  -                  % empty leaf hash on both nodes - this was exact!
  +           if EmptyLeafHash -> % empty leaf hash on both nodes - this was exact!
                     HashCmpI_OUT = HashCmpI_IN,
                     HashCmpL_OUT = HashCmpL_IN;
  -              IsLeafHash ->
  +              IsLeafHash -> % both non-empty leaf nodes
                     HashCmpI_OUT = HashCmpI_IN,
                     HashCmpL_OUT = HashCmpL_IN + 1;
  -              true ->
  +              true -> % both inner nodes
                     HashCmpI_OUT = HashCmpI_IN + 1,
                     HashCmpL_OUT = HashCmpL_IN
              end,
  
positive.code:                              MySyncAccDRK, MySyncAccDRLCount, OtherSyncAccDRLCount,
                               SyncIN, AccCmp + 1, AccSkip,
                               NextLvlNodesActIN, HashCmpI_IN, HashCmpL_IN);
         (not IsLeafNode) andalso IsLeafHash -> % andalso Hash =:= none
             % inner node here, empty leaf there -> resolve directly (without a trivial sub process)
             % don't compare hashes -> this is an exact process based on the tags
             {MyKVItems, LeafCount} = merkle_tree:get_items([Node]),
             MySyncAccDRK1 = [element(1, X) || X <- MyKVItems] ++ MySyncAccDRK,
             MySyncAccDRLCount1 = MySyncAccDRLCount + LeafCount,
             merkle_check_node(TK, TN, SigSizeI, SigSizeL,
                               MyMaxItemsCount, OtherMaxItemsCount, Params, Stats,
                               <<FlagsAcc/bitstring, ?recon_fail_stop_inner:2>>, RestTreeAcc,
                               SyncAccSend, SyncAccRcv,
                               MySyncAccDRK1, MySyncAccDRLCount1, OtherSyncAccDRLCount,
                               SyncIN, AccCmp + 1, AccSkip,
                               NextLvlNodesActIN, HashCmpI_IN, HashCmpL_IN);
         IsLeafNode ->
             if IsLeafHash andalso Hash =/= none ->
                    % leaf mismatch (our node may be empty, the other is not)
                    % distinguish the case where this node is empty which is exact, too!
                    case merkle_tree:is_empty(Node) of
                        true  -> ResultCode = ?recon_fail_cont_inner,
                                 HashCmpL_OUT = HashCmpL_IN;
                        false -> ResultCode = ?recon_fail_stop_leaf,
                                 HashCmpL_OUT = HashCmpL_IN + 1
                    end,
                    SyncAccSend1 =
                        [{erlang:min(Params#merkle_params.bucket_size,
                                     OtherMaxItemsCount), merkle_tree:get_bucket(Node),
                          merkle_tree:get_item_count(Node)} | SyncAccSend],
                    MySyncAccDRK1 = MySyncAccDRK,
                    MySyncAccDRLCount1 = MySyncAccDRLCount;
                IsLeafHash -> % andalso Hash =:= none
                    % empty leaf hash on the other node - we can resolve this
                    % case directly, i.e. without a trivial sub process
                    ResultCode = ?recon_fail_stop_leaf,
                    SyncAccSend1 = SyncAccSend,
                    MySyncAccDRK1 =
                        [element(1, X) || X <- merkle_tree:get_bucket(Node)]
                            ++ MySyncAccDRK,
                    MySyncAccDRLCount1 = MySyncAccDRLCount + 1,
                    HashCmpL_OUT = HashCmpL_IN;
                true ->
                    % leaf node and inner hash
                    ResultCode = ?recon_fail_stop_leaf,
                    SyncAccSend1 =
                        [{OtherMaxItemsCount, merkle_tree:get_bucket(Node),
                          merkle_tree:get_item_count(Node)} | SyncAccSend],
                    MySyncAccDRK1 = MySyncAccDRK,
                    MySyncAccDRLCount1 = MySyncAccDRLCount,
                    HashCmpL_OUT = HashCmpL_IN
             end,
             merkle_check_node(TK, TN, SigSizeI, SigSizeL,
                               MyMaxItemsCount, OtherMaxItemsCount, Params, Stats,
                               <<FlagsAcc/bitstring, ResultCode:2>>, RestTreeAcc,
                               SyncAccSend1, SyncAccRcv,
                               MySyncAccDRK1, MySyncAccDRLCount1, OtherSyncAccDRLCount,
                               SyncIN, AccCmp + 1, AccSkip,
                               NextLvlNodesActIN, HashCmpI_IN, HashCmpL_OUT)
      end.
  
  %% @doc Processes compare results from merkle_check_node/21 on the initiator.
  
negative.code:                   RestTreeAcc, SyncAccSend, SyncAccRcv,
                    MySyncAccDRK, MySyncAccDRLCount, OtherSyncAccDRLCount,
                    AccCmp, AccSkip, NextLvlNodesActIN, HashCmpI_IN, HashCmpL_IN) ->
      % either cont_inner or stop_empty_leaf4
      case merkle_tree:is_leaf(Node) of
          false -> % cont_inner
              % inner hash on both nodes
              Childs = merkle_tree:get_childs(Node),
              NextLvlNodesActOUT = NextLvlNodesActIN + Params#merkle_params.branch_factor,
              HashCmpI_OUT = HashCmpI_IN + 1,
              RestTreeAcc1 = lists:reverse(Childs, RestTreeAcc),
              MySyncAccDRK1 = MySyncAccDRK,
              MySyncAccDRLCount1 = MySyncAccDRLCount;
          true -> % stop_empty_leaf4
              ?DBG_ASSERT(not merkle_tree:is_empty(Node)),
              % non-empty leaf on this node, empty leaf on the other node
              % -> resolve directly here, i.e. without a trivial sub process
              NextLvlNodesActOUT = NextLvlNodesActIN,
              HashCmpI_OUT = HashCmpI_IN,
              RestTreeAcc1 = RestTreeAcc,
              MyKVItems = merkle_tree:get_bucket(Node),
              MySyncAccDRK1 = [element(1, X) || X <- MyKVItems] ++ MySyncAccDRK,
              MySyncAccDRLCount1 = MySyncAccDRLCount + 1
      end,
      merkle_cmp_result(TR, TN, SigSizeI, SigSizeL,
                        MyMaxItemsCount, OtherMaxItemsCount, SyncIn, Params, Stats,
                        RestTreeAcc1, SyncAccSend, SyncAccRcv,
                        MySyncAccDRK1, MySyncAccDRLCount1, OtherSyncAccDRLCount,
                        AccCmp + 1, AccSkip,
                        NextLvlNodesActOUT, HashCmpI_OUT, HashCmpL_IN);
  merkle_cmp_result(<<?recon_fail_stop_inner:2, TR/bitstring>>, [Node | TN],
                    SigSizeI, SigSizeL,
                    MyMaxItemsCount, OtherMaxItemsCount, SyncIn, Params, Stats,
                    RestTreeAcc, SyncAccSend, SyncAccRcv,
                    MySyncAccDRK, MySyncAccDRLCount, OtherSyncAccDRLCount, AccCmp, AccSkip,
                    NextLvlNodesActIN, HashCmpI_IN, HashCmpL_IN) ->
      % either stop_inner or stop_empty_leaf1 or stop_empty_leaf3
      % NOTE: all these mismatches are exact process based on the tags
      IsLeafNode = merkle_tree:is_leaf(Node),
      EmptyLeafNode = IsLeafNode andalso merkle_tree:is_empty(Node),
      
      if IsLeafNode andalso (not EmptyLeafNode) -> % stop_inner
             SyncAccSend1 = [{OtherMaxItemsCount, merkle_tree:get_bucket(Node),
                              merkle_tree:get_item_count(Node)} | SyncAccSend],
             OtherSyncAccDRLCount1 = OtherSyncAccDRLCount,
             MySyncAccDRK1 = MySyncAccDRK,
             MySyncAccDRLCount1 = MySyncAccDRLCount;
         EmptyLeafNode -> % stop_empty_leaf1
             % -> resolved directly at the other node, i.e. without a trivial sub process
             SyncAccSend1 = SyncAccSend,
             OtherSyncAccDRLCount1 = OtherSyncAccDRLCount + 1, % this will deviate from the other node!
             MySyncAccDRK1 = MySyncAccDRK,
             MySyncAccDRLCount1 = MySyncAccDRLCount;
         not IsLeafNode -> % stop_empty_leaf3
             % -> resolve directly here, i.e. without a trivial sub process
             SyncAccSend1 = SyncAccSend,
             OtherSyncAccDRLCount1 = OtherSyncAccDRLCount,
             {MyKVItems, LeafCount} = merkle_tree:get_items([Node]),
             MySyncAccDRK1 = [element(1, X) || X <- MyKVItems] ++ MySyncAccDRK,
             MySyncAccDRLCount1 = MySyncAccDRLCount + LeafCount
      end,
      merkle_cmp_result(TR, TN, SigSizeI, SigSizeL,
                        MyMaxItemsCount, OtherMaxItemsCount, SyncIn, Params, Stats,
                        RestTreeAcc, SyncAccSend1, SyncAccRcv,
                        MySyncAccDRK1, MySyncAccDRLCount1, OtherSyncAccDRLCount1,
                        AccCmp + 1, AccSkip,
                        NextLvlNodesActIN, HashCmpI_IN, HashCmpL_IN);
  merkle_cmp_result(<<?recon_fail_stop_leaf:2, TR/bitstring>>, [Node | TN],
  