anchor.diff:  
   handle(Packet = ?PUBLISH_PACKET(?QOS_2, Topic, PacketId, _Payload),
            State = #proto_state{clientid = ClientId, session = Session}) ->
  -    case emqttd_access_control:check_acl(client(State), publish, Topic) of
  +    case check_acl(publish, Topic, State) of
           allow -> 
               NewSession = emqttd_session:publish(Session, ClientId, {?QOS_2, emqtt_message:from_packet(Packet)}),
               send(?PUBACK_PACKET(?PUBREC, PacketId), State#proto_state{session = NewSession});
  
positive.code: 	{ok, NewState};
  
  handle(?SUBSCRIBE_PACKET(PacketId, TopicTable), State = #proto_state{clientid = ClientId, session = Session}) ->
      AllowDenies = [emqttd_access_control:check_acl(client(State), subscribe, Topic) || {Topic, _Qos} <- TopicTable],
      case lists:member(deny, AllowDenies) of
          true ->
              %%TODO: return 128 QoS when deny...
  
negative.code: 
  try_unregister(undefined, _) -> ok;
  try_unregister(ClientId, _) -> emqttd_cm:unregister(ClientId).
  
  %% publish ACL is cached in process dictionary.
  check_acl(publish, Topic, State) ->
      case get({acl, publish, Topic}) of
          undefined ->
              AllowDeny = emqttd_access_control:check_acl(client(State), publish, Topic),
              put({acl, publish, Topic}, AllowDeny),
              AllowDeny;
          AllowDeny ->
              AllowDeny
      end;
  
  check_acl(subscribe, Topic, State) ->
      emqttd_access_control:check_acl(client(State), subscribe, Topic).
  
  sent_stats(?PACKET(Type)) ->
      emqttd_metrics:inc('packets/sent'), 
  