anchor.diff:  -export([key_rrset_signer/2, zone_rrset_signer/2]).
   -export([rrsig_for_zone_rrset/2]).
   
  +%% @doc Apply DNSSEC records to the given message if the zone is signed
  +%% and DNSSEC is requested.
  +-spec(handle(dns:message(), erldns:zone(), dns:name(), dns:type()) -> dns:message()).
   handle(Message, Zone, Qname, Qtype) ->
     handle(Message, Zone, Qname, Qtype, proplists:get_bool(dnssec, erldns_edns:get_opts(Message)), Zone#zone.keysets).
   
   handle(Message, _Zone, _Qname, _Qtype, _DnssecRequested = true, []) ->
     % DNSSEC requested, zone unsigned
     Message;
  -handle(Message, Zone, Qname, Qtype, _DnssecRequested = true, _Keysets) ->
  +handle(Message, Zone, Qname, _Qtype, _DnssecRequested = true, _Keysets) ->
     lager:debug("DNSSEC requested for ~p", [Zone#zone.name]),
     Authority = lists:last(Zone#zone.authority),
     Ttl = Authority#dns_rr.data#dns_rrdata_soa.minimum,
  -  Records = erldns_zone_cache:get_records_by_name(Qname),
  +  {ok, ZoneWithRecords} = erldns_zone_cache:get_zone_with_records(Zone#zone.name),
     case Message#dns_message.answers of
       [] ->
         ApexRecords = erldns_zone_cache:get_records_by_name(Zone#zone.name),
  
positive.code: rrsig_for_zone_rrset(Zone, RRs) ->
    lists:flatten(lists:map(zone_rrset_signer(Zone#zone.name, RRs), Zone#zone.keysets)).
  
  key_rrset_signer(ZoneName, RRs) ->
    fun(Keyset) ->
        Keytag = Keyset#keyset.key_signing_key_tag,
  
negative.code:       SoaRRSigRecords = lists:filter(match_type_covered(?DNS_TYPE_SOA), ApexRRSigRecords),
  
        NextDname = dns:labels_to_dname([<<"\000">>] ++ dns:dname_to_labels(Qname)),
        Types = lists:usort(lists:map(fun(RR) -> RR#dns_rr.type end, ZoneWithRecords#zone.records) ++ [?DNS_TYPE_RRSIG, ?DNS_TYPE_NSEC]),
        NsecRecords = [#dns_rr{name = Qname, type = ?DNS_TYPE_NSEC, ttl = Ttl, data = #dns_rrdata_nsec{next_dname = NextDname, types = Types}}],
        NsecRRSigRecords = rrsig_for_zone_rrset(Zone, NsecRecords),
  
        Message#dns_message{ad = true, authority = Message#dns_message.authority ++ NsecRecords ++ SoaRRSigRecords ++ NsecRRSigRecords};
      _ ->
        RRSigs = find_rrsigs(Message, ZoneWithRecords#zone.records),
        Message#dns_message{ad = true, answers = Message#dns_message.answers ++ RRSigs}
    end;
  handle(Message, _Zone, _Qname, _Qtype, _DnssecRequest = false, _) ->
    Message.
  
  -spec(find_rrsigs(dns:message(), [dns:rr()]) -> [dns:rr()]).
  find_rrsigs(Message, Records) ->
    NamesAndTypes = lists:usort(lists:map(fun(RR) -> {RR#dns_rr.name, RR#dns_rr.type} end, Message#dns_message.answers)),
    lists:flatten(
      lists:map(
        fun({Name, Type}) ->
            NamedRRSigs = lists:filter(erldns_records:match_name_and_type(Name, ?DNS_TYPE_RRSIG), Records),
            lists:filter(match_type_covered(Type), NamedRRSigs)
        end, NamesAndTypes)).
  
  -spec(match_type_covered(dns:type()) -> fun((dns:rr()) -> boolean())).
  match_type_covered(Qtype) ->
    fun(RRSig) ->
        RRSig#dns_rr.data#dns_rrdata_rrsig.type_covered =:= Qtype
  