anchor.diff:  %%% INTERNAL
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   
  -check_version(?MQTT_PROTO_MAJOR) -> true;
  +check_version(3) -> true;
  +check_version(4) -> true;
   check_version(_) -> false.
   
   send_connack(ReturnCode, State) ->
  
positive.code:        will_topic=WillTopic,
         will_msg=WillMsg} = Var,
  
      case check_version(Version) of
          true ->
              %% auth_on_register hook must return either:
              %%  ok | next | {error, invalid_credentials | not_authorized}
              case emqttd_hook:only(auth_on_register,
                                    [Peer, Id, User, Password]) of
                  ok ->
                      case emqttd_reg:register_client(Id, CleanSession) of
                          ok ->
                              emqttd_hook:all(on_register,
                                              [Peer, Id, User, Password]),
                              {connected,
                               send_connack(?CONNACK_ACCEPT,
                                            State#state{
                                              client_id=Id,
                                              username=User,
                                              will_qos=WillQoS,
                                              will_topic=combine_mp(MountPoint, WillTopic),
                                              will_msg=WillMsg})};
  
negative.code: clean_mp(MountPoint, MountedTopic) ->
      lists:sublist(MountedTopic, length(MountPoint) + 1, length(MountedTopic)).
  
  get_random_clientid_if_empty("") ->
      lists:flatten(["anon-", base64:encode_to_string(crypto:rand_bytes(20))]);
  get_random_clientid_if_empty(Id) -> Id.
  
  