anchor.diff:  ftopics(Topics) ->
       lists:foldl(
         fun({Topic, QoS}, Acc) when is_integer(QoS), is_list(Topic) ->
  -              [{"    q:~p, t: \"~s\"~n", [QoS, jtopic(Topic)]}|Acc]
  +              [{"    q:~p, t: \"~s\"~n", [QoS, jtopic(Topic)]}|Acc];
  +         ({Topic, {QoS, SubOpts}}, Acc) ->
  +              NL = maps:get(no_local, SubOpts, undefined),
  +              RAP = maps:get(rap, SubOpts, undefined),
  +              RH = maps:get(retain_handling, SubOpts, undefined),
  +              [{"    q:~p, no_local:~p, rap:~p, rh:~p~n"
  +                "    t: \"~s\"~n", [QoS, NL, RAP, RH, jtopic(Topic)]}|Acc];
  +         (#mqtt5_subscribe_topic{
  +             topic = Topic,
  +             qos = QoS,
  +             no_local = NL,
  +             rap = RAP,
  +             retain_handling = RH
  +            }, Acc) ->
  +              [{"    q:~p, no_local:~p, rap:~p, rh:~p~n"
  +                "    t: \"~s\"~n", [QoS, NL, RAP, RH, jtopic(Topic)]}|Acc]
         end,
         [],
         Topics).
  
positive.code: format_all_till_ok_ret_(Other,_Opts) ->
      {"Hook returned ~p~n", [Other]}.
  
  format_mqtt(Direction, Pid, SId, M, Opts) ->
      [fpid(Pid), r(" "), dir(Direction), r(" "),
       sid(SId), r(" "), format_mqtt_(M, Opts)].
  
  format_lwt(Present, _QoS, _Topic, _Msg, _Opts)
    when Present =:= false; Present =:= undefined ->
      [];
  format_lwt(Present, QoS, Topic, Msg, #{payload_limit := Limit}) ->
      {"    with LWT(wr: ~p, wq: ~p, wt: ~s) with payload:~n"
       "    ~s~n",
       [Present, QoS, jtopic(Topic), trunc_payload(Msg, Limit)]}.
  
  format_mqtt_(#mqtt_pingreq{}, _) ->
      {"PINGREQ()~n", []};
  format_mqtt_(#mqtt_pingresp{}, _) ->
      {"PINGRESP()~n", []};
  format_mqtt_(#mqtt_connect{proto_ver = Ver, username = Username,
                             password = Password, clean_session = CleanSession,
                             keep_alive = KeepAlive, client_id = ClientId, will_retain = WillRetain,
                             will_qos = WillQoS, will_topic = WillTopic, will_msg = WillMsg}, Opts) ->
      [{"CONNECT(c: ~s, v: ~p, u: ~s, p: ~s, cs: ~p, ka: ~p)~n",
        [ClientId, Ver, Username, Password, CleanSession, KeepAlive]},
       format_lwt(WillRetain, WillQoS, WillTopic, WillMsg, Opts)];
  format_mqtt_(#mqtt_connack{session_present = SP, return_code = RC}, _) ->
      {"CONNACK(sp: ~p, rc: ~p)~n", [fflag(SP), RC]};
  format_mqtt_(#mqtt_publish{message_id = MId, topic = Topic, qos = QoS, retain = Retain,
                              dup = Dup, payload = Payload}, #{payload_limit := Limit}) ->
      {"PUBLISH(d~p, q~p, r~p, m~p, \"~s\") with payload:~n"
       "    ~s~n", [fflag(Dup), QoS, fflag(Retain), fmid(MId), jtopic(Topic), trunc_payload(Payload, Limit)]};
  format_mqtt_(#mqtt_puback{message_id = MId}, _) ->
      {"PUBACK(m~p)~n", [fmid(MId)]};
  format_mqtt_(#mqtt_pubrec{message_id = MId}, _) ->
      {"PUBREC(m~p)~n", [fmid(MId)]};
  format_mqtt_(#mqtt_pubrel{message_id = MId}, _) ->
      {"PUBREL(m~p)~n", [fmid(MId)]};
  format_mqtt_(#mqtt_pubcomp{message_id = MId}, _) ->
      {"PUBCOMP(m~p)~n", [fmid(MId)]};
  format_mqtt_(#mqtt_subscribe{message_id = MId, topics = Topics}, _) ->
      [{"SUBSCRIBE(m~p) with topics:~n", [fmid(MId)]}, ftopics(Topics)];
  format_mqtt_(#mqtt_suback{message_id = MId, qos_table = QoSTable}, _) ->
      {"SUBACK(m~p, qt~p)~n", [fmid(MId), QoSTable]};
  format_mqtt_(#mqtt_unsubscribe{message_id = MId}, _) ->
      {"UNSUBSCRIBE(m~p)~n", [fmid(MId)]};
  format_mqtt_(#mqtt_unsuback{message_id = MId}, _) ->
      {"UNSUBACK(m~p)~n", [fmid(MId)]};
  format_mqtt_(#mqtt_disconnect{}, _) ->
      {"DISCONNECT()~n", []}.
  
  trunc_payload(Payload, Limit) when byte_size(Payload) =< Limit ->
      Payload;
  
negative.code:      [Hook, User, SubscriberId, QoS, jtopic(Topic), IsRetain, Payload]};
  format_all_till_ok_(auth_on_subscribe = Hook, [User, SubscriberId, Topics], _Opts) ->
      [{"Calling ~p(~s,~p) with topics:~n",
        [Hook, User, SubscriberId]}, ftopics(Topics)];
  
  format_all_till_ok_(auth_on_register_m5 = Hook,
                      [Peer, SubscriberId, User, Password, CleanStart, Props], Opts) ->
      [{"Calling ~p(~p,~p,~s,~s,~p) ~n",
       [Hook, Peer, SubscriberId, User, Password, CleanStart]},
       format_props(Props, Opts)];
  format_all_till_ok_(auth_on_publish_m5 = Hook,
                      [User, SubscriberId, QoS, Topic, Payload, IsRetain, Props],
                      Opts) ->
      [{"Calling ~p(~s,~p,~p,~s,~p) with payload:~n"
        "    ~s~n",
        [Hook, User, SubscriberId, QoS, jtopic(Topic), IsRetain, Payload]},
       format_props(Props, Opts)];
  format_all_till_ok_(auth_on_subscribe_m5 = Hook, [User, SubscriberId, Topics, Props], Opts) ->
      [{"Calling ~p(~s,~p) with topics:~n",
        [Hook, User, SubscriberId]}, ftopics(Topics), format_props(Props, Opts)].
  
  
  format_all_till_ok_ret(Ret, Pid, Opts) ->
      [fpid(Pid), r(" "), format_all_till_ok_ret_(Ret, Opts)].
  