BIND 10 jreed-docs, updated. d351fe6ec30972595d70135cee24e6dd6d990d33 Just add a comment to remove print_settings.

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Feb 2 17:11:17 UTC 2011


The branch, jreed-docs has been updated
       via  d351fe6ec30972595d70135cee24e6dd6d990d33 (commit)
       via  a697043708acddf2f9757615d173b514c98de9a4 (commit)
       via  00dab940cb413e50ac20df693d8a05053608aa40 (commit)
       via  8909387beb99136bc5ec22574515c84e8ef526da (commit)
       via  952124e0f4d2b64d8b3a47b52163edca7c3546ab (commit)
       via  73a679d7b03fc3c53fb4826a95ee099321fb4c4d (commit)
       via  af4b23610ff5cb55748737dff2b67c4f905b2480 (commit)
       via  c5d416a01e152b936c0023fcc65d3d468250388b (commit)
       via  d6113a313ff848124a3ecd2e58b17bb04b5bcbee (commit)
       via  578ea7f4ba94dc0d8a3d39231dad2be118e125a2 (commit)
       via  1dbc33e995c77185505e91387359f0f4ff7adadd (commit)
       via  661ee8d341d0a24b6cab13302b028a9efb40daa4 (commit)
       via  1dd7c3d6806b8694fa315f55c105884245e486ea (commit)
       via  5720ab60da4b443e9414852234d65acccd8e9e4e (commit)
       via  f4b2e3f8f7404dc3739a211d23022336f33609f8 (commit)
       via  95861564f241fa7f657eb7c34449c3095fba1930 (commit)
       via  ad011294186315051152f2f2bb9d9af09b8f338d (commit)
       via  94b0beeb606dedc3c8fc44856e0a6f2d3c9754b4 (commit)
       via  424bb3df5cd1e1cf8b64f76ff5f0118da05de9e6 (commit)
       via  5d03cd4b844bf1288032ee9a148aef5077a167f3 (commit)
       via  c8e84e56caeb809f91c7823ae1c4e9aa30e49c57 (commit)
       via  239c9694953dcd1dc1ffdd60b7205fca5fdd651c (commit)
       via  5823a2ff954e0965048c5d4cc33314d9bb2ae637 (commit)
       via  c30cd00cf1afde68776d7320cb283a8f9a911163 (commit)
       via  6f6f5892046cb552bf334d2e5f84cf575dde3da5 (commit)
       via  a2a812ede6d3df4a70d6309437c6715cb09a7670 (commit)
       via  749c26e2c6cdc98abf0f7d6dc693acf122e5d9f5 (commit)
       via  a5bd8c03942d981b01fb0be3f8ea54ebcd960945 (commit)
       via  acc6a3ab370cd5c22ad37bb79f819578bb1e6e97 (commit)
       via  3e5f772632f1472a1125e0cd725adf6709635e8c (commit)
       via  a07e078b4feeb01949133fc88c9939254c38aa7c (commit)
       via  748885cd80a12aad0f02fc7b53943c2620d9eb22 (commit)
       via  c5e46db3463427504c4814d1ad712e3f09ea9c36 (commit)
       via  5609b0c697b2f3d4684ced27d35fcb91721a48e0 (commit)
       via  93697f58e4d912fa87bc7f9a591c1febc9e0d139 (commit)
       via  4b4813d5873856044ce28b91b1e14c8a0f84b59f (commit)
       via  d85c19ad4f3a92897eba8f2868f5a661bbc9a177 (commit)
       via  7b84de4c0e11f4a070e038ca4f093486e55622af (commit)
       via  90ede89d895da7a088715ee315b12dfb843ee2fe (commit)
       via  18491370576e7438c7893f8551bbb8647001be9c (commit)
       via  b9b7ef39987bc2f0031bb7f46b9002665a62607a (commit)
       via  98d6a12c51d58d7712c6876dde8c548162cbcbdd (commit)
       via  ed69c4be96f940b86a45823fa2efd010f53a357c (commit)
       via  83033bbfd1298a45240e073c25bae9b0bb2f4e6f (commit)
       via  6e9d5c8b61fff0b1f2a1dfb9d685bbd6ce090e8a (commit)
       via  1133c5a571d5bbddaeb44c2313cce75ebd624eeb (commit)
       via  1243b751048365abdb5cec845a92674e0469b7b4 (commit)
       via  bfa3f83286dd88d263e6c12c74ed3f2073210e03 (commit)
       via  51d35705f42ab9b20a315edbc5dd8a9541b0483c (commit)
       via  3e3bcbeb2f3ceae0863e9ad943f589ac4c8e0ec3 (commit)
       via  344dcf64d70d10d47d405b4e88e3cefca777aa64 (commit)
       via  a039907d688e2ae82af39369baa72a9c43805eb1 (commit)
       via  57ba31639cd4f5686b220adbba6e91f80d3626c0 (commit)
       via  fd9e8511f7759b0eecab6e0a2447dfbea2b2de1a (commit)
       via  3c337419ad37fb4af2d14e7d470e7c9c35790b40 (commit)
       via  dd37e9539f78bb16e4a044f4df3a7a6c8b284856 (commit)
       via  88369b5ed0c0b023b1c985fa01964500a4c37a1f (commit)
       via  bc2a7f57b5a7dc127045309f7f2ff42badc4bb95 (commit)
       via  d6d7f1157668e98a1f849d53258b8f9c1dee1c78 (commit)
       via  b20ba8d51b2d395da64857e71151e0ef2f018b25 (commit)
       via  e5febac1248d25e3a026889ae2914fdb868361da (commit)
       via  e3e59cf1f240c7ab556ff8f827888f13d698e677 (commit)
       via  1916a92fba92220b3a7b2149a325fc7eefca2c72 (commit)
       via  30838487e181829182543e1a32e25ad313172b89 (commit)
       via  a8793f5ce8927d0a746c41636dc7ab414f8d21ff (commit)
       via  77c5ed7fa2654d2740477b6e9e15c23fb635032a (commit)
       via  1a11edc24cdbea4f90653cf0cd94344084b9f568 (commit)
       via  3ccbc9347eb6fc3ea9d3b3ac9e181a1e1b94e42d (commit)
       via  8f23ba4a72eed354852b023a4d41adfe4a62bb0c (commit)
       via  b3ec8dc3523bf2573cdc33a73eb21605d8a32305 (commit)
       via  36b738c03eaba27228285a9ee00a424b799b1f61 (commit)
       via  21e8607873dc52d860e3b82d00b0ab7a9eaa6deb (commit)
       via  61aedbfffa0a5edf8e9e7076b54fafb927ddf3c2 (commit)
       via  b39bfceed83508b4e0a9932f864d15da1787c3f9 (commit)
       via  93f50d1a63829198f9afc280dbd9e12057c434ed (commit)
       via  f9ceab26e3c573ccdabff7658b8221fbbe9a6122 (commit)
       via  692c6b15659b6af9b092dfb6263d152421cf05a7 (commit)
       via  107229aeffecbac4278fdbf6515513c391e8ad2d (commit)
       via  90c89f6d435109f6228f309ae1824e0b8c552416 (commit)
       via  273d03db595f480800e4d071da9997cebbe976e9 (commit)
       via  ce2fead07b25247d05b3175a30863a898b819db1 (commit)
       via  3e151d447774c4d1cc1cbf854f29a75aaa43d6ce (commit)
       via  928d2871d02f7f9c17b27b2c91ae4e1314a72d24 (commit)
       via  43adf3a50adde888fe01661f69069d4b8d690b18 (commit)
       via  6ed7ca08bb751d131db2b3d7837e0c02e4704145 (commit)
       via  1c6d27d61112ae3cfd1663d51863c58e37d5e675 (commit)
       via  cd2d518fbcb19a0119553f71593b7a9d908b90c3 (commit)
       via  ef811c6e76fe84505141ceb053af0b110a87c0b8 (commit)
       via  d37301004adbac7209e1b9ad1a2fe6cfa0ea9354 (commit)
       via  395bbc339365b2d512eed63a04179845bc36c308 (commit)
       via  7a8bfbdd24317e216fc10ae01d9a41fd791a8795 (commit)
       via  66ace85fab74d0c2d5760f1d01a40e440161ddb7 (commit)
       via  bd45814672cd96ddb708af3eead4461a3870c440 (commit)
       via  d0a9b15c2cc5a9f61b2a3f136d54192d6c4b212c (commit)
       via  c4f0d38193a1a6719bd31af29a60b51e405678d5 (commit)
       via  5ed5d8034e14418db7f473d966cad68dc1629262 (commit)
       via  a1210be107e45632b7e4fb47d74d627a5ae18901 (commit)
       via  ea084ffdffb800600ccd66a2afe84579e36749d3 (commit)
       via  29bfd26b74745ed3d0278bfbad06a1defadff657 (commit)
       via  c772a141d7963b2d327287c37a0720fa65a192ae (commit)
       via  ee96cc0479b7fbb8a90817d43b4a778e94c28fdc (commit)
       via  caf6ca1dc4f8e014f975d168af370cf7a35a5fbf (commit)
       via  6e4c7c07b7d6dc58213df0c67100ead14932c1ea (commit)
       via  e9c8b1402a1bd1834209c1f29aa121cc514388ce (commit)
       via  435b7a283437aa13047cc69c1b9e28284a3de46c (commit)
       via  294251d62ece34da011ecf662df9dd0c1b141a53 (commit)
       via  34a083b7721a2b32177ff9b4a4f768f03435a326 (commit)
       via  f11adb59bb8be08e4ee47340ff5be153646afbcd (commit)
       via  1efc3bee0b08fe1abaabcee82f4391591b1be2a3 (commit)
       via  59270dc809d9013d502f7ab66788e900eab53a3b (commit)
       via  d2a4816b0595fa3b8b0a3b9b55228108cddfa82f (commit)
       via  848b1823fc4c893f7f398759e3b6b9dde35b05f9 (commit)
       via  7b4bd8aae373869067f7d8b5156925c87c37df8f (commit)
       via  cdf66cc9c391019d5d76c8685a719f38a06c5610 (commit)
      from  c14c4741b754a1eb226d3bdc3a7abbc4c5d727c0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d351fe6ec30972595d70135cee24e6dd6d990d33
Author: Jeremy C. Reed <jreed at ISC.org>
Date:   Mon Jan 31 07:31:40 2011 -0600

    Just add a comment to remove print_settings.

commit a697043708acddf2f9757615d173b514c98de9a4
Author: Jeremy C. Reed <jreed at ISC.org>
Date:   Mon Jan 31 07:19:31 2011 -0600

    Remove mention of Y1. It is not year one any more.

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |   40 ++
 Makefile.am                                        |    8 +-
 configure.ac                                       |    1 +
 doc/Doxyfile                                       |    2 +-
 doc/Makefile.am                                    |    3 +
 doc/guide/Makefile.am                              |    4 +
 doc/guide/bind10-guide.html                        |    8 +-
 doc/guide/bind10-guide.xml                         |    2 +
 src/bin/auth/auth_srv.cc                           |   12 +-
 src/bin/auth/auth_srv.h                            |    2 -
 src/bin/auth/b10-auth.xml                          |    3 +-
 src/bin/auth/benchmarks/query_bench.cc             |    2 -
 src/bin/auth/change_user.cc                        |    2 -
 src/bin/auth/change_user.h                         |    2 -
 src/bin/auth/common.h                              |    2 -
 src/bin/auth/main.cc                               |    2 -
 src/bin/auth/query.cc                              |   41 +-
 src/bin/auth/statistics.cc                         |    2 -
 src/bin/auth/statistics.h                          |    2 -
 src/bin/auth/tests/auth_srv_unittest.cc            |    9 +-
 src/bin/auth/tests/change_user_unittest.cc         |    2 -
 src/bin/auth/tests/query_unittest.cc               |  727 +++++++++++---------
 src/bin/auth/tests/run_unittests.cc                |    2 -
 src/bin/auth/tests/statistics_unittest.cc          |    2 -
 src/bin/bind10/bind10.xml                          |    3 +-
 src/bin/bindctl/bindctl.xml                        |    1 -
 src/bin/cfgmgr/b10-cfgmgr.py.in                    |    2 -
 src/bin/cfgmgr/b10-cfgmgr.xml                      |    1 -
 src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in         |    2 -
 src/bin/cmdctl/b10-cmdctl.xml                      |    1 -
 src/bin/loadzone/b10-loadzone.xml                  |    1 -
 src/bin/loadzone/tests/correct/mix1.db             |    1 -
 src/bin/loadzone/tests/correct/ttlext.db           |    1 -
 src/bin/msgq/msgq.py.in                            |  120 +++-
 src/bin/msgq/msgq.xml                              |    1 -
 src/bin/msgq/tests/msgq_test.py                    |  129 ++++-
 src/bin/resolver/Makefile.am                       |    1 +
 src/bin/resolver/b10-resolver.xml                  |    1 -
 src/bin/resolver/main.cc                           |    2 -
 src/bin/resolver/resolver.cc                       |  313 +++++----
 src/bin/resolver/resolver.h                        |   61 ++-
 src/bin/resolver/resolver.spec.pre.in              |   40 +-
 src/bin/resolver/response_classifier.cc            |  259 +++++++
 src/bin/resolver/response_classifier.h             |  138 ++++
 src/bin/resolver/tests/Makefile.am                 |    2 +
 src/bin/resolver/tests/resolver_config_unittest.cc |   79 ++-
 src/bin/resolver/tests/resolver_unittest.cc        |   18 +-
 .../resolver/tests/response_classifier_unittest.cc |  494 +++++++++++++
 src/bin/stats/b10-stats.xml                        |    1 -
 src/bin/stats/stats.py.in                          |    1 -
 src/bin/stats/stats_stub.py.in                     |    1 -
 src/bin/stats/tests/b10-stats_stub_test.py         |    1 -
 src/bin/stats/tests/b10-stats_test.py              |    1 -
 src/bin/stats/tests/fake_time.py                   |    1 -
 src/bin/stats/tests/isc/cc/session.py              |    1 -
 src/bin/stats/tests/isc/config/ccsession.py        |    1 -
 src/bin/stats/tests/isc/util/process.py            |    2 -
 src/bin/stats/tests/isc/utils/process.py           |    2 -
 src/bin/usermgr/b10-cmdctl-usermgr.xml             |    1 -
 src/bin/xfrin/b10-xfrin.xml                        |    3 +-
 src/bin/xfrin/tests/xfrin_test.py                  |    2 -
 src/bin/xfrin/xfrin.py.in                          |    2 -
 src/bin/xfrout/b10-xfrout.xml                      |    1 -
 src/bin/zonemgr/b10-zonemgr.xml                    |    1 -
 src/lib/asiolink/asiolink.cc                       |  276 +++++++-
 src/lib/asiolink/asiolink.h                        |   23 +-
 src/lib/asiolink/internal/tcpdns.h                 |    5 +-
 src/lib/asiolink/internal/udpdns.h                 |    9 +-
 src/lib/asiolink/ioaddress.cc                      |    2 -
 src/lib/asiolink/ioaddress.h                       |    2 -
 src/lib/asiolink/ioendpoint.cc                     |    2 -
 src/lib/asiolink/ioendpoint.h                      |    2 -
 src/lib/asiolink/iomessage.h                       |    2 -
 src/lib/asiolink/iosocket.cc                       |    2 -
 src/lib/asiolink/iosocket.h                        |    2 -
 src/lib/asiolink/tcpdns.cc                         |   11 +-
 src/lib/asiolink/tests/asiolink_unittest.cc        |  255 ++++++-
 src/lib/asiolink/tests/run_unittests.cc            |    2 -
 src/lib/asiolink/udpdns.cc                         |   14 +-
 src/lib/bench/benchmark.h                          |    2 -
 src/lib/bench/benchmark_util.cc                    |    2 -
 src/lib/bench/benchmark_util.h                     |    2 -
 src/lib/bench/example/search_bench.cc              |    2 -
 src/lib/bench/tests/benchmark_unittest.cc          |    2 -
 src/lib/bench/tests/loadquery_unittest.cc          |    2 -
 src/lib/bench/tests/run_unittests.cc               |    2 -
 src/lib/cc/data.cc                                 |    2 -
 src/lib/cc/data.h                                  |    2 -
 src/lib/cc/session.cc                              |    2 -
 src/lib/cc/session.h                               |    2 -
 src/lib/cc/tests/data_unittests.cc                 |    2 -
 src/lib/cc/tests/run_unittests.cc                  |    2 -
 src/lib/cc/tests/session_unittests.cc              |    2 -
 src/lib/config/ccsession.cc                        |    2 -
 src/lib/config/ccsession.h                         |    2 -
 src/lib/config/config_data.cc                      |    2 -
 src/lib/config/config_data.h                       |    2 -
 src/lib/config/tests/ccsession_unittests.cc        |    2 -
 src/lib/config/tests/config_data_unittests.cc      |    2 -
 src/lib/config/tests/fake_session.cc               |    2 -
 src/lib/config/tests/fake_session.h                |    2 -
 src/lib/config/tests/module_spec_unittests.cc      |    2 -
 src/lib/config/tests/run_unittests.cc              |    2 -
 src/lib/datasrc/cache.cc                           |    2 -
 src/lib/datasrc/cache.h                            |    2 -
 src/lib/datasrc/data_source.cc                     |    2 -
 src/lib/datasrc/data_source.h                      |    2 -
 src/lib/datasrc/memory_datasrc.cc                  |   63 ++-
 src/lib/datasrc/memory_datasrc.h                   |   35 +-
 src/lib/datasrc/query.cc                           |    2 -
 src/lib/datasrc/query.h                            |    2 -
 src/lib/datasrc/sqlite3_datasrc.cc                 |    2 -
 src/lib/datasrc/sqlite3_datasrc.h                  |    2 -
 src/lib/datasrc/static_datasrc.cc                  |    2 -
 src/lib/datasrc/static_datasrc.h                   |    8 +-
 src/lib/datasrc/tests/cache_unittest.cc            |    2 -
 src/lib/datasrc/tests/datasrc_unittest.cc          |    2 -
 src/lib/datasrc/tests/memory_datasrc_unittest.cc   |  135 ++++-
 src/lib/datasrc/tests/query_unittest.cc            |    2 -
 src/lib/datasrc/tests/run_unittests.cc             |    2 -
 src/lib/datasrc/tests/sqlite3_unittest.cc          |    2 -
 src/lib/datasrc/tests/static_unittest.cc           |    2 -
 src/lib/datasrc/tests/test_datasrc.cc              |    2 -
 src/lib/datasrc/tests/test_datasrc.h               |    2 -
 src/lib/datasrc/tests/testdata/mkbrokendb.c        |    2 -
 src/lib/datasrc/zone.h                             |   24 +-
 src/lib/dns/buffer.h                               |    2 -
 src/lib/dns/dnssectime.cc                          |    2 -
 src/lib/dns/dnssectime.h                           |    2 -
 src/lib/dns/edns.cc                                |    2 -
 src/lib/dns/edns.h                                 |    2 -
 src/lib/dns/exceptions.cc                          |    2 -
 src/lib/dns/exceptions.h                           |    2 -
 src/lib/dns/gen-rdatacode.py.in                    |    2 -
 src/lib/dns/message.cc                             |    2 -
 src/lib/dns/message.h                              |    5 +-
 src/lib/dns/messagerenderer.cc                     |    2 -
 src/lib/dns/messagerenderer.h                      |    2 -
 src/lib/dns/name.cc                                |    2 -
 src/lib/dns/name.h                                 |    2 -
 src/lib/dns/opcode.cc                              |    2 -
 src/lib/dns/opcode.h                               |    2 -
 src/lib/dns/python/edns_python.cc                  |    2 -
 src/lib/dns/python/message_python.cc               |    2 -
 src/lib/dns/python/messagerenderer_python.cc       |    2 -
 src/lib/dns/python/name_python.cc                  |    2 -
 src/lib/dns/python/opcode_python.cc                |    2 -
 src/lib/dns/python/pydnspp.cc                      |    2 -
 src/lib/dns/python/pydnspp_common.cc               |    2 -
 src/lib/dns/python/pydnspp_common.h                |    2 -
 src/lib/dns/python/question_python.cc              |    2 -
 src/lib/dns/python/rcode_python.cc                 |    2 -
 src/lib/dns/python/rdata_python.cc                 |    2 -
 src/lib/dns/python/rrclass_python.cc               |    2 -
 src/lib/dns/python/rrset_python.cc                 |    2 -
 src/lib/dns/python/rrttl_python.cc                 |    2 -
 src/lib/dns/python/rrtype_python.cc                |    2 -
 src/lib/dns/python/tests/edns_python_test.py       |    2 -
 src/lib/dns/python/tests/testutil.py               |    2 -
 src/lib/dns/python/tests/tsigkey_python_test.py    |    2 -
 src/lib/dns/python/tsigkey_python.cc               |    2 -
 src/lib/dns/question.cc                            |    2 -
 src/lib/dns/question.h                             |   26 +-
 src/lib/dns/rcode.cc                               |    2 -
 src/lib/dns/rcode.h                                |    2 -
 src/lib/dns/rdata.cc                               |    2 -
 src/lib/dns/rdata.h                                |    2 -
 src/lib/dns/rdata/any_255/tsig_250.cc              |    2 -
 src/lib/dns/rdata/any_255/tsig_250.h               |    2 -
 src/lib/dns/rdata/ch_3/a_1.cc                      |    2 -
 src/lib/dns/rdata/ch_3/a_1.h                       |    2 -
 src/lib/dns/rdata/generic/cname_5.cc               |    2 -
 src/lib/dns/rdata/generic/cname_5.h                |    2 -
 src/lib/dns/rdata/generic/dname_39.cc              |    2 -
 src/lib/dns/rdata/generic/dname_39.h               |    2 -
 src/lib/dns/rdata/generic/dnskey_48.cc             |    2 -
 src/lib/dns/rdata/generic/dnskey_48.h              |    2 -
 src/lib/dns/rdata/generic/ds_43.cc                 |    2 -
 src/lib/dns/rdata/generic/ds_43.h                  |    2 -
 src/lib/dns/rdata/generic/mx_15.cc                 |    2 -
 src/lib/dns/rdata/generic/mx_15.h                  |    2 -
 src/lib/dns/rdata/generic/ns_2.cc                  |    2 -
 src/lib/dns/rdata/generic/ns_2.h                   |    2 -
 src/lib/dns/rdata/generic/nsec3_50.cc              |    2 -
 src/lib/dns/rdata/generic/nsec3_50.h               |    2 -
 src/lib/dns/rdata/generic/nsec3param_51.cc         |    2 -
 src/lib/dns/rdata/generic/nsec3param_51.h          |    2 -
 src/lib/dns/rdata/generic/nsec_47.cc               |    2 -
 src/lib/dns/rdata/generic/nsec_47.h                |    2 -
 src/lib/dns/rdata/generic/opt_41.cc                |    2 -
 src/lib/dns/rdata/generic/opt_41.h                 |    2 -
 src/lib/dns/rdata/generic/ptr_12.cc                |    2 -
 src/lib/dns/rdata/generic/ptr_12.h                 |    2 -
 src/lib/dns/rdata/generic/rrsig_46.cc              |    2 -
 src/lib/dns/rdata/generic/rrsig_46.h               |    2 -
 src/lib/dns/rdata/generic/soa_6.cc                 |    2 -
 src/lib/dns/rdata/generic/soa_6.h                  |    2 -
 src/lib/dns/rdata/generic/txt_16.cc                |    2 -
 src/lib/dns/rdata/generic/txt_16.h                 |    2 -
 src/lib/dns/rdata/hs_4/a_1.cc                      |    2 -
 src/lib/dns/rdata/hs_4/a_1.h                       |    2 -
 src/lib/dns/rdata/in_1/a_1.cc                      |    2 -
 src/lib/dns/rdata/in_1/a_1.h                       |    2 -
 src/lib/dns/rdata/in_1/aaaa_28.cc                  |    2 -
 src/lib/dns/rdata/in_1/aaaa_28.h                   |    2 -
 src/lib/dns/rdata/template.cc                      |    2 -
 src/lib/dns/rdata/template.h                       |    2 -
 src/lib/dns/rrclass-placeholder.h                  |    2 -
 src/lib/dns/rrclass.cc                             |    2 -
 src/lib/dns/rrparamregistry-placeholder.cc         |    2 -
 src/lib/dns/rrparamregistry.h                      |    2 -
 src/lib/dns/rrset.cc                               |    2 -
 src/lib/dns/rrset.h                                |    2 -
 src/lib/dns/rrsetlist.cc                           |    2 -
 src/lib/dns/rrsetlist.h                            |   23 +-
 src/lib/dns/rrttl.cc                               |    2 -
 src/lib/dns/rrttl.h                                |    2 -
 src/lib/dns/rrtype-placeholder.h                   |    2 -
 src/lib/dns/rrtype.cc                              |    2 -
 src/lib/dns/tests/base32hex_unittest.cc            |    2 -
 src/lib/dns/tests/base64_unittest.cc               |    2 -
 src/lib/dns/tests/buffer_unittest.cc               |    2 -
 src/lib/dns/tests/dnssectime_unittest.cc           |    2 -
 src/lib/dns/tests/edns_unittest.cc                 |    2 -
 src/lib/dns/tests/hex_unittest.cc                  |    2 -
 src/lib/dns/tests/message_unittest.cc              |    2 -
 src/lib/dns/tests/messagerenderer_unittest.cc      |    2 -
 src/lib/dns/tests/name_unittest.cc                 |    2 -
 src/lib/dns/tests/opcode_unittest.cc               |    2 -
 src/lib/dns/tests/question_unittest.cc             |   35 +-
 src/lib/dns/tests/rcode_unittest.cc                |    2 -
 src/lib/dns/tests/rdata_cname_unittest.cc          |    2 -
 src/lib/dns/tests/rdata_dname_unittest.cc          |    2 -
 src/lib/dns/tests/rdata_dnskey_unittest.cc         |    2 -
 src/lib/dns/tests/rdata_ds_unittest.cc             |    2 -
 src/lib/dns/tests/rdata_in_a_unittest.cc           |    2 -
 src/lib/dns/tests/rdata_in_aaaa_unittest.cc        |    2 -
 src/lib/dns/tests/rdata_mx_unittest.cc             |    2 -
 src/lib/dns/tests/rdata_ns_unittest.cc             |    2 -
 src/lib/dns/tests/rdata_nsec3_unittest.cc          |    2 -
 src/lib/dns/tests/rdata_nsec3param_unittest.cc     |    2 -
 src/lib/dns/tests/rdata_nsec_unittest.cc           |    2 -
 src/lib/dns/tests/rdata_opt_unittest.cc            |    2 -
 src/lib/dns/tests/rdata_ptr_unittest.cc            |    2 -
 src/lib/dns/tests/rdata_rrsig_unittest.cc          |    2 -
 src/lib/dns/tests/rdata_soa_unittest.cc            |    2 -
 src/lib/dns/tests/rdata_tsig_unittest.cc           |    2 -
 src/lib/dns/tests/rdata_txt_unittest.cc            |    2 -
 src/lib/dns/tests/rdata_unittest.cc                |    2 -
 src/lib/dns/tests/rdata_unittest.h                 |    2 -
 src/lib/dns/tests/rrclass_unittest.cc              |    2 -
 src/lib/dns/tests/rrparamregistry_unittest.cc      |    2 -
 src/lib/dns/tests/rrset_unittest.cc                |    2 -
 src/lib/dns/tests/rrsetlist_unittest.cc            |    2 -
 src/lib/dns/tests/rrttl_unittest.cc                |    2 -
 src/lib/dns/tests/rrtype_unittest.cc               |    2 -
 src/lib/dns/tests/run_unittests.cc                 |    2 -
 src/lib/dns/tests/sha1_unittest.cc                 |    2 -
 src/lib/dns/tests/unittest_util.cc                 |    2 -
 src/lib/dns/tests/unittest_util.h                  |    2 -
 src/lib/dns/tsigkey.cc                             |    2 -
 src/lib/dns/tsigkey.h                              |    2 -
 src/lib/dns/util/base32hex.h                       |    2 -
 src/lib/dns/util/base64.h                          |    2 -
 src/lib/dns/util/base_n.cc                         |    2 -
 src/lib/dns/util/hex.h                             |    2 -
 src/lib/exceptions/exceptions.cc                   |    2 -
 src/lib/exceptions/exceptions.h                    |    2 -
 src/lib/exceptions/tests/exceptions_unittest.cc    |    2 -
 src/lib/exceptions/tests/run_unittests.cc          |    2 -
 src/lib/nsas/address_entry.cc                      |    2 -
 src/lib/nsas/address_entry.h                       |    2 -
 src/lib/nsas/address_request_callback.h            |    2 -
 src/lib/nsas/asiolink.h                            |    2 -
 src/lib/nsas/fetchable.h                           |    2 -
 src/lib/nsas/hash.cc                               |    2 -
 src/lib/nsas/hash.h                                |    2 -
 src/lib/nsas/hash_deleter.h                        |    2 -
 src/lib/nsas/hash_key.cc                           |    2 -
 src/lib/nsas/hash_key.h                            |    2 -
 src/lib/nsas/hash_table.h                          |    2 -
 src/lib/nsas/lru_list.h                            |    2 -
 src/lib/nsas/nameserver_address.cc                 |    2 -
 src/lib/nsas/nameserver_address.h                  |    2 -
 src/lib/nsas/nameserver_address_store.cc           |    2 -
 src/lib/nsas/nameserver_address_store.h            |    2 -
 src/lib/nsas/nameserver_entry.cc                   |    2 -
 src/lib/nsas/nameserver_entry.h                    |    2 -
 src/lib/nsas/nsas_entry.h                          |    2 -
 src/lib/nsas/nsas_entry_compare.h                  |    2 -
 src/lib/nsas/nsas_types.h                          |    2 -
 src/lib/nsas/random_number_generator.h             |    2 -
 src/lib/nsas/resolver_interface.h                  |    2 -
 src/lib/nsas/tests/address_entry_unittest.cc       |    1 -
 src/lib/nsas/tests/fetchable_unittest.cc           |    1 -
 src/lib/nsas/tests/hash_deleter_unittest.cc        |    1 -
 src/lib/nsas/tests/hash_key_unittest.cc            |    1 -
 src/lib/nsas/tests/hash_table_unittest.cc          |    1 -
 src/lib/nsas/tests/hash_unittest.cc                |    1 -
 src/lib/nsas/tests/lru_list_unittest.cc            |    1 -
 .../tests/nameserver_address_store_unittest.cc     |    1 -
 src/lib/nsas/tests/nameserver_address_unittest.cc  |    1 -
 src/lib/nsas/tests/nameserver_entry_unittest.cc    |    1 -
 src/lib/nsas/tests/nsas_entry_compare_unittest.cc  |    1 -
 src/lib/nsas/tests/nsas_test.h                     |    2 -
 .../nsas/tests/random_number_generator_unittest.cc |    1 -
 src/lib/nsas/tests/run_unittests.cc                |    1 -
 src/lib/nsas/tests/zone_entry_unittest.cc          |    1 -
 src/lib/nsas/zone_entry.cc                         |    2 -
 src/lib/nsas/zone_entry.h                          |    2 -
 src/lib/python/isc/config/tests/ccsession_test.py  |    2 -
 src/lib/python/isc/config/tests/cfgmgr_test.py     |    2 -
 .../python/isc/config/tests/config_data_test.py    |    2 -
 .../python/isc/config/tests/module_spec_test.py    |    2 -
 .../isc/config/tests/unittest_fakesession.py       |    2 -
 src/lib/python/isc/datasrc/master.py               |    2 -
 src/lib/python/isc/datasrc/sqlite3_ds.py           |    2 -
 src/lib/testutils/Makefile.am                      |    1 +
 src/lib/testutils/dnsmessage_test.cc               |  115 +++
 src/lib/testutils/dnsmessage_test.h                |  304 ++++++++
 src/lib/testutils/mockups.h                        |    4 +-
 src/lib/testutils/srv_test.cc                      |   40 +-
 src/lib/testutils/srv_test.h                       |   11 +-
 src/lib/xfr/fd_share.cc                            |    2 -
 src/lib/xfr/fd_share.h                             |    2 -
 src/lib/xfr/fdshare_python.cc                      |    2 -
 src/lib/xfr/python_xfr.cc                          |    2 -
 src/lib/xfr/xfrout_client.cc                       |    2 -
 src/lib/xfr/xfrout_client.h                        |    2 -
 329 files changed, 3213 insertions(+), 1256 deletions(-)
 create mode 100644 doc/Makefile.am
 mode change 100644 => 100755 src/bin/cfgmgr/b10-cfgmgr.py.in
 mode change 100644 => 100755 src/bin/msgq/msgq.py.in
 create mode 100644 src/bin/resolver/response_classifier.cc
 create mode 100644 src/bin/resolver/response_classifier.h
 create mode 100644 src/bin/resolver/tests/response_classifier_unittest.cc
 mode change 100644 => 100755 src/bin/stats/stats.py.in
 mode change 100644 => 100755 src/bin/stats/stats_stub.py.in
 create mode 100644 src/lib/testutils/dnsmessage_test.cc
 create mode 100644 src/lib/testutils/dnsmessage_test.h

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index f29349d..53b3cc2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+  160.  [func]		jelte
+  	Updated the resolver to take 3 different timeout values;
+	timeout_query for outstanding queries we sent while resolving
+	timeout_client for sending an answer back to the client
+	timeout_lookup for stopping the resolving
+	(currently 2 and 3 have the same final effect)
+	(Trac 489, git 578ea7f4ba94dc0d8a3d39231dad2be118e125a2)
+
+  159.	[func]		smann
+	The resolver now has a configurable set of root servers to start
+	resolving at (called root_addresses). By default these are not
+	(yet) filled in. If empty, a hardcoded address for f-root will be
+	used right now.
+	(Trac #483, git a07e078b4feeb01949133fc88c9939254c38aa7c)
+
+  158.	[func]		jelte
+	The Resolver module will now do (very limited) resolving, if not
+	set to forwarding mode (i.e. if the configuration option
+	forward_addresses is left empty). It only supports referrals that
+	contain glue addresses at this point, and does no other processing
+	of authoritative answers.
+	(Trac #484, git 7b84de4c0e11f4a070e038ca4f093486e55622af)
+
+  157.  [bug]       vorner
+	One frozen process no longer freezes the whole b10-msgq. It caused the
+	whole system to stop working.
+	(Trac #420, git 93697f58e4d912fa87bc7f9a591c1febc9e0d139)
+
+  156.	[func]		stephen
+	Added ResponseClassifier class to examine response from
+	a server and classify it into one of several categories.
+	(Trac #487, git 18491370576e7438c7893f8551bbb8647001be9c)
+
+bind10-devel-20110120 released on January 20, 2011
+
+  155.	[doc]		jreed
+	Miscellaneous documentation improvements for man pages and
+	the guide, including auth, resolver, stats, xfrout, and
+	zonemgr.  (git c14c4741b754a1eb226d3bdc3a7abbc4c5d727c0)
+
   154.	[bug]		jinmei
 	b10-xfrin/b10-zonemgr: Fixed a bug where these programs didn't
 	receive command responses from CC sessions.  Eventually the
diff --git a/Makefile.am b/Makefile.am
index e49b1f0..93a7498 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = src
+SUBDIRS = doc src
 USE_LCOV=@USE_LCOV@
 LCOV=@LCOV@
 GENHTML=@GENHTML@
@@ -282,9 +282,3 @@ EXTRA_DIST += ext/asio/asio/is_write_buffered.hpp
 EXTRA_DIST += ext/asio/asio/buffered_read_stream_fwd.hpp
 EXTRA_DIST += ext/asio/asio/socket_acceptor_service.hpp
 EXTRA_DIST += ext/asio/asio.hpp
-
-## include the guide in tarball, later will include the other parts there
-## but they cleanup.
-EXTRA_DIST += doc/guide/bind10-guide.css
-EXTRA_DIST += doc/guide/bind10-guide.html
-EXTRA_DIST += doc/guide/bind10-guide.xml
diff --git a/configure.ac b/configure.ac
index f065fdb..f08f044 100644
--- a/configure.ac
+++ b/configure.ac
@@ -574,6 +574,7 @@ AC_ARG_ENABLE(install-configurations,
 AM_CONDITIONAL(INSTALL_CONFIGURATIONS, test x$install_configurations = xyes || test x$install_configurations = xtrue)
 
 AC_CONFIG_FILES([Makefile
+                 doc/Makefile
                  doc/guide/Makefile
                  src/Makefile
                  src/bin/Makefile
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 0e1ab00..6ab2001 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -568,7 +568,7 @@ WARN_LOGFILE           =
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas
+INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/bin/resolver ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas ../src/lib/testutils
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..31d0cfa
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = guide
+
+EXTRA_DIST = version.ent.in
diff --git a/doc/guide/Makefile.am b/doc/guide/Makefile.am
index 098e287..c790139 100644
--- a/doc/guide/Makefile.am
+++ b/doc/guide/Makefile.am
@@ -1,3 +1,7 @@
+EXTRA_DIST = bind10-guide.css
+EXTRA_DIST += bind10-guide.html
+EXTRA_DIST += bind10-guide.xml
+
 # This is not a "man" manual, but reuse this for now for docbook.
 if ENABLE_MAN
 
diff --git a/doc/guide/bind10-guide.html b/doc/guide/bind10-guide.html
index 849cd06..98c7e46 100644
--- a/doc/guide/bind10-guide.html
+++ b/doc/guide/bind10-guide.html
@@ -1,10 +1,10 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="./bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the reference guide for BIND 10 version 20101201. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168230298903"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="releaseinfo">This is the referenc
 e guide for BIND 10 version
-        20101201.</p></div><div><p class="copyright">Copyright © 2010 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a Domain Name System (DNS) suite managed by
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="./bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the reference guide for BIND 10 version 20110120. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168230298903"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="releaseinfo">This is the referenc
 e guide for BIND 10 version
+        20110120.</p></div><div><p class="copyright">Copyright © 2010 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a Domain Name System (DNS) suite managed by
 	Internet Systems Consortium (ISC). It includes DNS libraries
 	and modular components for controlling authoritative and
 	recursive DNS servers.
       </p><p>
-        This is the reference guide for BIND 10 version 20101201.
+        This is the reference guide for BIND 10 version 20110120.
 	The most up-to-date version of this document, along with
 	other documents for BIND 10, can be found at <a class="ulink" href="http://bind10.isc.org/docs" target="_top">http://bind10.isc.org/docs</a>.  </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230299042">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230299068">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284843">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">In
 stallation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230285029">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168230285048">Retrieve from Git</a></span></dt><dt><span class="section"><a href="#id1168230285109">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230285206">Build</a></span></dt><dt><span class="section"><a href="#id1168230285222">Install</a></span></dt><dt><span class="section"><a href="#id1168230285245">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a hr
 ef="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specification for b10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230285821">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230285886">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230285917">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#zonemgr">11. Secondary Manager</a></span></dt><dt><span class="chapter"><a href="#resolverserver">12. Recursive Name Server<
 /a></span></dt><dt><span class="chapter"><a href="#statistics">13. Statistics</a></span></dt></dl></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230299042">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230299068">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
       BIND is the popular implementation of a DNS server, developer
@@ -13,7 +13,7 @@
       and provides a modular environment for serving and maintaining DNS.
     </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
         This guide covers the experimental prototype of
-        BIND 10 version 20101201.
+        BIND 10 version 20110120.
       </p></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
         BIND 10 provides a EDNS0- and DNSSEC-capable
         authoritative DNS server and a forwarding DNS server.
diff --git a/doc/guide/bind10-guide.xml b/doc/guide/bind10-guide.xml
index 70f6a30..3670c46 100644
--- a/doc/guide/bind10-guide.xml
+++ b/doc/guide/bind10-guide.xml
@@ -982,6 +982,8 @@ accounts_file
       <para>
         The control commands are:
 print_settings
+<!-- TODO: remove that -->
+
 shutdown
       </para>
 <!-- TODO -->
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index bd2d4c8..b8d5730 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <netinet/in.h>
@@ -161,9 +159,13 @@ AuthSrvImpl::~AuthSrvImpl() {
 class MessageLookup : public DNSLookup {
 public:
     MessageLookup(AuthSrv* srv) : server_(srv) {}
-    virtual void operator()(const IOMessage& io_message, MessagePtr message,
-                            OutputBufferPtr buffer, DNSServer* server) const
+    virtual void operator()(const IOMessage& io_message,
+                            MessagePtr message,
+                            MessagePtr answer_message,
+                            OutputBufferPtr buffer,
+                            DNSServer* server) const
     {
+        (void) answer_message;
         server_->processMessage(io_message, message, buffer, server);
     }
 private:
@@ -182,7 +184,7 @@ class MessageAnswer : public DNSAnswer {
 public:
     MessageAnswer(AuthSrv*) {}
     virtual void operator()(const IOMessage&, MessagePtr,
-                            OutputBufferPtr) const
+                            MessagePtr, OutputBufferPtr) const
     {}
 };
 
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index 2e47843..7806be9 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __AUTH_SRV_H
 #define __AUTH_SRV_H 1
 
diff --git a/src/bin/auth/b10-auth.xml b/src/bin/auth/b10-auth.xml
index 04ae7cf..b22d24d 100644
--- a/src/bin/auth/b10-auth.xml
+++ b/src/bin/auth/b10-auth.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
@@ -135,7 +134,7 @@
         <listitem><para>
           The port number it listens on.
           The default is 5300.</para>
-	  <note><simpara>The Y1 prototype runs on all interfaces
+	  <note><simpara>This prototype runs on all interfaces
 	  and on this nonstandard port.</simpara></note>
         </listitem>
       </varlistentry>
diff --git a/src/bin/auth/benchmarks/query_bench.cc b/src/bin/auth/benchmarks/query_bench.cc
index f68eab2..7f643f3 100644
--- a/src/bin/auth/benchmarks/query_bench.cc
+++ b/src/bin/auth/benchmarks/query_bench.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdlib.h>
 
 #include <iostream>
diff --git a/src/bin/auth/change_user.cc b/src/bin/auth/change_user.cc
index 049715a..253b8fb 100644
--- a/src/bin/auth/change_user.cc
+++ b/src/bin/auth/change_user.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <errno.h>
 #include <string.h>
 #include <pwd.h>
diff --git a/src/bin/auth/change_user.h b/src/bin/auth/change_user.h
index 7a18926..e4fc5ee 100644
--- a/src/bin/auth/change_user.h
+++ b/src/bin/auth/change_user.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __CHANGE_USER_H
 #define __CHANGE_USER_H 1
 
diff --git a/src/bin/auth/common.h b/src/bin/auth/common.h
index 5ff2c7e..6af09fb 100644
--- a/src/bin/auth/common.h
+++ b/src/bin/auth/common.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __COMMON_H
 #define __COMMON_H 1
 
diff --git a/src/bin/auth/main.cc b/src/bin/auth/main.cc
index 30c8a48..10e1194 100644
--- a/src/bin/auth/main.cc
+++ b/src/bin/auth/main.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/select.h>
diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc
index cb7e3e0..e85c31a 100644
--- a/src/bin/auth/query.cc
+++ b/src/bin/auth/query.cc
@@ -66,7 +66,8 @@ Query::findAddrs(const Zone& zone, const Name& qname,
 
     // Find A rrset
     if (qname_ != qname || qtype_ != RRType::A()) {
-        Zone::FindResult a_result = zone.find(qname, RRType::A(), options);
+        Zone::FindResult a_result = zone.find(qname, RRType::A(), NULL,
+                                              options);
         if (a_result.code == Zone::SUCCESS) {
             response_.addRRset(Message::SECTION_ADDITIONAL,
                     boost::const_pointer_cast<RRset>(a_result.rrset));
@@ -76,7 +77,7 @@ Query::findAddrs(const Zone& zone, const Name& qname,
     // Find AAAA rrset
     if (qname_ != qname || qtype_ != RRType::AAAA()) {
         Zone::FindResult aaaa_result =
-            zone.find(qname, RRType::AAAA(), options);
+            zone.find(qname, RRType::AAAA(), NULL, options);
         if (aaaa_result.code == Zone::SUCCESS) {
             response_.addRRset(Message::SECTION_ADDITIONAL,
                     boost::const_pointer_cast<RRset>(aaaa_result.rrset));
@@ -121,6 +122,8 @@ Query::getAuthAdditional(const Zone& zone) const {
 void
 Query::process() const {
     bool keep_doing = true;
+    const bool qtype_is_any = (qtype_ == RRType::ANY());
+
     response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
     const MemoryDataSrc::FindResult result =
         memory_datasrc_.findZone(qname_);
@@ -140,20 +143,41 @@ Query::process() const {
     response_.setHeaderFlag(Message::HEADERFLAG_AA);
     while (keep_doing) {
         keep_doing = false;
-        Zone::FindResult db_result = result.zone->find(qname_, qtype_);
+        std::auto_ptr<RRsetList> target(qtype_is_any ? new RRsetList : NULL);
+        Zone::FindResult db_result =
+            result.zone->find(qname_, qtype_, target.get());
+
         switch (db_result.code) {
+            case Zone::CNAME:
+                /*
+                 * We don't do chaining yet. Therefore handling a CNAME is
+                 * mostly the same as handling SUCCESS, but we didn't get
+                 * what we expected. It means no exceptions in ANY or NS
+                 * on the origin (though CNAME in origin is probably
+                 * forbidden anyway).
+                 */
+                // No break; here, fall trough.
             case Zone::SUCCESS:
                 response_.setRcode(Rcode::NOERROR());
-                response_.addRRset(Message::SECTION_ANSWER,
-                    boost::const_pointer_cast<RRset>(db_result.rrset));
-                // Handle additional for answer section
-                getAdditional(*result.zone, *db_result.rrset);
+                if (qtype_is_any) {
+                    // If quety type is ANY, insert all RRs under the domain
+                    // into answer section.
+                    BOOST_FOREACH(RRsetPtr rrset, *target) {
+                        response_.addRRset(Message::SECTION_ANSWER, rrset);
+                    }
+                } else {
+                    response_.addRRset(Message::SECTION_ANSWER,
+                        boost::const_pointer_cast<RRset>(db_result.rrset));
+                    // Handle additional for answer section
+                    getAdditional(*result.zone, *db_result.rrset);
+                }
                 // If apex NS records haven't been provided in the answer
                 // section, insert apex NS records into the authority section
                 // and AAAA/A RRS of each of the NS RDATA into the additional
                 // section.
                 if (qname_ != result.zone->getOrigin() ||
-                    (qtype_ != RRType::NS() && qtype_ != RRType::ANY()))
+                    db_result.code != Zone::SUCCESS ||
+                    (qtype_ != RRType::NS() && !qtype_is_any))
                 {
                     getAuthAdditional(*result.zone);
                 }
@@ -175,7 +199,6 @@ Query::process() const {
                 response_.setRcode(Rcode::NOERROR());
                 putSOA(*result.zone);
                 break;
-            case Zone::CNAME:
             case Zone::DNAME:
                 // TODO : replace qname, continue lookup
                 break;
diff --git a/src/bin/auth/statistics.cc b/src/bin/auth/statistics.cc
index ed4a6c7..e68793c 100644
--- a/src/bin/auth/statistics.cc
+++ b/src/bin/auth/statistics.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <auth/statistics.h>
 
 #include <cc/data.h>
diff --git a/src/bin/auth/statistics.h b/src/bin/auth/statistics.h
index 7ce2e01..9e5240e 100644
--- a/src/bin/auth/statistics.h
+++ b/src/bin/auth/statistics.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __STATISTICS_H
 #define __STATISTICS_H 1
 
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index 5ec9bde..576799c 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <vector>
@@ -34,6 +32,7 @@
 #include <auth/statistics.h>
 
 #include <dns/tests/unittest_util.h>
+#include <testutils/dnsmessage_test.h>
 #include <testutils/srv_test.h>
 
 using namespace std;
@@ -139,9 +138,10 @@ TEST_F(AuthSrvTest, builtInQueryViaDNSServer) {
     createRequestPacket(request_message, IPPROTO_UDP);
 
     (*server.getDNSLookupProvider())(*io_message, parse_message,
+                                     response_message,
                                      response_obuffer, &dnsserv);
     (*server.getDNSAnswerProvider())(*io_message, parse_message,
-                                     response_obuffer);
+                                     response_message, response_obuffer);
 
     createBuiltinVersionResponse(default_qid, response_data);
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
@@ -154,9 +154,10 @@ TEST_F(AuthSrvTest, builtInQueryViaDNSServer) {
 TEST_F(AuthSrvTest, iqueryViaDNSServer) {
     createDataFromFile("iquery_fromWire.wire");
     (*server.getDNSLookupProvider())(*io_message, parse_message,
+                                     response_message,
                                      response_obuffer, &dnsserv);
     (*server.getDNSAnswerProvider())(*io_message, parse_message,
-                                     response_obuffer);
+                                     response_message, response_obuffer);
 
     UnitTestUtil::readWireData("iquery_response_fromWire.wire",
                                response_data);
diff --git a/src/bin/auth/tests/change_user_unittest.cc b/src/bin/auth/tests/change_user_unittest.cc
index 299b521..33897b6 100644
--- a/src/bin/auth/tests/change_user_unittest.cc
+++ b/src/bin/auth/tests/change_user_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdlib.h>
 #include <unistd.h>             // for getuid
 
diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc
index f1f3a56..3bf4142 100644
--- a/src/bin/auth/tests/query_unittest.cc
+++ b/src/bin/auth/tests/query_unittest.cc
@@ -12,8 +12,16 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <sstream>
+#include <vector>
+#include <map>
+
+#include <boost/bind.hpp>
+
+#include <dns/masterload.h>
 #include <dns/message.h>
 #include <dns/name.h>
+#include <dns/opcode.h>
 #include <dns/rcode.h>
 #include <dns/rrttl.h>
 #include <dns/rrtype.h>
@@ -23,162 +31,172 @@
 
 #include <auth/query.h>
 
+#include <testutils/dnsmessage_test.h>
+
 #include <gtest/gtest.h>
 
+using namespace std;
 using namespace isc::dns;
+using namespace isc::dns::rdata;
 using namespace isc::datasrc;
 using namespace isc::auth;
+using namespace isc::testutils;
 
 namespace {
 
-RRsetPtr a_rrset = RRsetPtr(new RRset(Name("www.example.com"),
-                                      RRClass::IN(), RRType::A(),
-                                      RRTTL(3600)));
-RRsetPtr soa_rrset = RRsetPtr(new RRset(Name("example.com"),
-                                        RRClass::IN(), RRType::SOA(),
-                                        RRTTL(3600)));
-RRsetPtr ns_rrset(RRsetPtr(new RRset(Name("ns.example.com"),
-                                     RRClass::IN(), RRType::NS(),
-                                     RRTTL(3600))));
-RRsetPtr glue_a_rrset(RRsetPtr(new RRset(Name("glue.ns.example.com"),
-                                         RRClass::IN(), RRType::A(),
-                                         RRTTL(3600))));
-RRsetPtr glue_aaaa_rrset(RRsetPtr(new RRset(Name("glue.ns.example.com"),
-                                            RRClass::IN(), RRType::AAAA(),
-                                            RRTTL(3600))));
-RRsetPtr noglue_a_rrset(RRsetPtr(new RRset(Name("noglue.example.com"),
-                                           RRClass::IN(), RRType::A(),
-                                           RRTTL(3600))));
-RRsetPtr delegated_mx_a_rrset(RRsetPtr(new RRset(
-    Name("mx.delegation.example.com"), RRClass::IN(), RRType::A(),
-    RRTTL(3600))));
+// This is the content of the mock zone (see below).
+// It's a sequence of textual RRs that is supposed to be parsed by
+// dns::masterLoad().  Some of the RRs are also used as the expected
+// data in specific tests, in which case they are referenced via specific
+// local variables (such as soa_txt).
+const char* const soa_txt = "example.com. 3600 IN SOA . . 0 0 0 0 0\n";
+const char* const zone_ns_txt =
+    "example.com. 3600 IN NS glue.delegation.example.com.\n"
+    "example.com. 3600 IN NS noglue.example.com.\n"
+    "example.com. 3600 IN NS example.net.\n";
+const char* const ns_addrs_txt =
+    "glue.delegation.example.com. 3600 IN A 192.0.2.153\n"
+    "glue.delegation.example.com. 3600 IN AAAA 2001:db8::53\n"
+    "noglue.example.com. 3600 IN A 192.0.2.53\n";
+const char* const delegation_txt =
+    "delegation.example.com. 3600 IN NS glue.delegation.example.com.\n"
+    "delegation.example.com. 3600 IN NS noglue.example.com.\n"
+    "delegation.example.com. 3600 IN NS cname.example.com.\n"
+    "delegation.example.com. 3600 IN NS example.org.\n";
+const char* const mx_txt =
+    "mx.example.com. 3600 IN MX 10 www.example.com.\n"
+    "mx.example.com. 3600 IN MX 20 mailer.example.org.\n"
+    "mx.example.com. 3600 IN MX 30 mx.delegation.example.com.\n";
+const char* const www_a_txt = "www.example.com. 3600 IN A 192.0.2.80\n";
+const char* const cname_txt =
+    "cname.example.com. 3600 IN CNAME www.example.com.\n";
+const char* const cname_nxdom_txt =
+    "cnamenxdom.example.com. 3600 IN CNAME nxdomain.example.com.\n";
+// CNAME Leading out of zone
+const char* const cname_out_txt =
+    "cnameout.example.com. 3600 IN CNAME www.example.org.\n";
+// The rest of data won't be referenced from the test cases.
+const char* const other_zone_rrs =
+    "cnamemailer.example.com. 3600 IN CNAME www.example.com.\n"
+    "cnamemx.example.com. 3600 IN MX 10 cnamemailer.example.com.\n"
+    "mx.delegation.example.com. 3600 IN A 192.0.2.100\n";
 
 // This is a mock Zone class for testing.
-// It is a derived class of Zone, and simply hardcodes the results of find()
-// See the find() implementation if you want to know its content.
+// It is a derived class of Zone for the convenient of tests.
+// Its find() method emulates the common behavior of protocol compliant
+// zone classes, but simplifies some minor cases and also supports broken
+// behavior.
+// For simplicity, most names are assumed to be "in zone"; there's only
+// one zone cut at the point of name "delegation.example.com".
+// It doesn't handle empty non terminal nodes (if we need to test such cases
+// find() should have specialized code for it).
 class MockZone : public Zone {
 public:
-    MockZone(bool has_SOA = true, bool has_apex_NS = true) :
+    MockZone() :
         origin_(Name("example.com")),
-        has_SOA_(has_SOA),
-        has_apex_NS_(has_apex_NS),
-        delegation_rrset(RRsetPtr(new RRset(Name("delegation.example.com"),
-                                            RRClass::IN(), RRType::NS(),
-                                            RRTTL(3600)))),
-        cname_rrset(RRsetPtr(new RRset(Name("cname.example.com"),
-                                       RRClass::IN(), RRType::CNAME(),
-                                       RRTTL(3600)))),
-        auth_ns_rrset(RRsetPtr(new RRset(Name("example.com"),
-                                         RRClass::IN(), RRType::NS(),
-                                         RRTTL(3600)))),
-        mx_cname_rrset_(new RRset(Name("cnamemailer.example.com"),
-            RRClass::IN(), RRType::CNAME(), RRTTL(3600))),
-        mx_rrset_(new RRset(Name("mx.example.com"), RRClass::IN(),
-            RRType::MX(), RRTTL(3600)))
+        delegation_name_("delegation.example.com"),
+        has_SOA_(true),
+        has_apex_NS_(true),
+        rrclass_(RRClass::IN())
     {
-        delegation_rrset->addRdata(rdata::generic::NS(
-                          Name("glue.ns.example.com")));
-        delegation_rrset->addRdata(rdata::generic::NS(
-                          Name("noglue.example.com")));
-        delegation_rrset->addRdata(rdata::generic::NS(
-                          Name("cname.example.com")));
-        delegation_rrset->addRdata(rdata::generic::NS(
-                          Name("example.org")));
-        cname_rrset->addRdata(rdata::generic::CNAME(
-                          Name("www.example.com")));
-        auth_ns_rrset->addRdata(rdata::generic::NS(
-                          Name("glue.ns.example.com")));
-        auth_ns_rrset->addRdata(rdata::generic::NS(
-                          Name("noglue.example.com")));
-        auth_ns_rrset->addRdata(rdata::generic::NS(
-                          Name("example.net")));
-        mx_rrset_->addRdata(isc::dns::rdata::generic::MX(10,
-            Name("www.example.com")));
-        mx_rrset_->addRdata(isc::dns::rdata::generic::MX(20,
-            Name("mailer.example.org")));
-        mx_rrset_->addRdata(isc::dns::rdata::generic::MX(30,
-            Name("mx.delegation.example.com")));
-        mx_cname_rrset_->addRdata(rdata::generic::CNAME(
-            Name("mx.example.com")));
+        stringstream zone_stream;
+        zone_stream << soa_txt << zone_ns_txt << ns_addrs_txt <<
+            delegation_txt << mx_txt << www_a_txt << cname_txt <<
+            cname_nxdom_txt << cname_out_txt << other_zone_rrs;
+
+        masterLoad(zone_stream, origin_, rrclass_,
+                   boost::bind(&MockZone::loadRRset, this, _1));
     }
-    virtual const isc::dns::Name& getOrigin() const;
-    virtual const isc::dns::RRClass& getClass() const;
+    virtual const isc::dns::Name& getOrigin() const { return (origin_); }
+    virtual const isc::dns::RRClass& getClass() const { return (rrclass_); }
+    virtual FindResult find(const isc::dns::Name& name,
+                            const isc::dns::RRType& type,
+                            RRsetList* target = NULL,
+                            const FindOptions options = FIND_DEFAULT) const;
+
+    // If false is passed, it makes the zone broken as if it didn't have the
+    // SOA.
+    void setSOAFlag(bool on) { has_SOA_ = on; }
 
-    FindResult find(const isc::dns::Name& name,
-                    const isc::dns::RRType& type,
-                    const FindOptions options = FIND_DEFAULT) const;
+    // If false is passed, it makes the zone broken as if it didn't have
+    // the apex NS.
+    void setApexNSFlag(bool on) { has_apex_NS_ = on; }
 
 private:
-    Name origin_;
+    typedef map<RRType, ConstRRsetPtr> RRsetStore;
+    typedef map<Name, RRsetStore> Domains;
+    Domains domains_;
+    void loadRRset(ConstRRsetPtr rrset) {
+        domains_[rrset->getName()][rrset->getType()] = rrset;
+        if (rrset->getName() == delegation_name_ &&
+            rrset->getType() == RRType::NS()) {
+            delegation_rrset_ = rrset;
+        }
+    }
+
+    const Name origin_;
+    const Name delegation_name_;
     bool has_SOA_;
     bool has_apex_NS_;
-    RRsetPtr delegation_rrset;
-    RRsetPtr cname_rrset;
-    RRsetPtr auth_ns_rrset;
-    RRsetPtr mx_cname_rrset_;
-    RRsetPtr mx_rrset_;
+    ConstRRsetPtr delegation_rrset_;
+    const RRClass rrclass_;
 };
 
-const Name&
-MockZone::getOrigin() const {
-    return (origin_);
-}
-
-const RRClass&
-MockZone::getClass() const {
-    return (RRClass::IN());
-}
-
 Zone::FindResult
 MockZone::find(const Name& name, const RRType& type,
-               const FindOptions options) const
+               RRsetList* target, const FindOptions options) const
 {
-    // hardcode the find results
-    if (name == Name("www.example.com") && type == RRType::A()) {
-        return (FindResult(SUCCESS, a_rrset));
-    } else if (name == Name("www.example.com")) {
-        return (FindResult(NXRRSET, RRsetPtr()));
-    } else if (name == Name("glue.ns.example.com") && type == RRType::A() &&
-        (options & FIND_GLUE_OK) != 0) {
-        return (FindResult(SUCCESS, glue_a_rrset));
-    } else if (name == Name("noglue.example.com") && (type == RRType::A() ||
-        type == RRType::ANY())) {
-        return (FindResult(SUCCESS, noglue_a_rrset));
-    } else if (name == Name("glue.ns.example.com") && type == RRType::AAAA() &&
-        (options & FIND_GLUE_OK) != 0) {
-        return (FindResult(SUCCESS, glue_aaaa_rrset));
-    } else if (name == Name("example.com") && type == RRType::SOA() &&
-        has_SOA_)
-    {
-        return (FindResult(SUCCESS, soa_rrset));
-    } else if (name == Name("example.com") && type == RRType::NS() &&
-        has_apex_NS_)
-    {
-        return (FindResult(SUCCESS, auth_ns_rrset));
-    } else if (name == Name("mx.delegation.example.com") &&
-        type == RRType::A() && (options & FIND_GLUE_OK) != 0)
-    {
-        return (FindResult(SUCCESS, delegated_mx_a_rrset));
-    } else if (name == Name("delegation.example.com") ||
-        name.compare(Name("delegation.example.com")).getRelation() ==
-        NameComparisonResult::SUBDOMAIN)
-    {
-        return (FindResult(DELEGATION, delegation_rrset));
-    } else if (name == Name("ns.example.com")) {
-        return (FindResult(DELEGATION, ns_rrset));
-    } else if (name == Name("nxdomain.example.com")) {
+    // Emulating a broken zone: mandatory apex RRs are missing if specifically
+    // configured so (which are rare cases).
+    if (name == origin_ && type == RRType::SOA() && !has_SOA_) {
+        return (FindResult(NXDOMAIN, RRsetPtr()));
+    } else if (name == origin_ && type == RRType::NS() && !has_apex_NS_) {
         return (FindResult(NXDOMAIN, RRsetPtr()));
-    } else if (name == Name("nxrrset.example.com")) {
+    }
+
+    // Special case for names on or under a zone cut
+    if ((options & FIND_GLUE_OK) == 0 &&
+        (name == delegation_name_ ||
+         name.compare(delegation_name_).getRelation() ==
+         NameComparisonResult::SUBDOMAIN)) {
+        return (FindResult(DELEGATION, delegation_rrset_));
+    }
+
+    // normal cases.  names are searched for only per exact-match basis
+    // for simplicity.
+    const Domains::const_iterator found_domain = domains_.find(name);
+    if (found_domain != domains_.end()) {
+        // First, try exact match.
+        RRsetStore::const_iterator found_rrset =
+            found_domain->second.find(type);
+        if (found_rrset != found_domain->second.end()) {
+            return (FindResult(SUCCESS, found_rrset->second));
+        }
+
+        // If not found but we have a target, fill it with all RRsets here
+        if (!found_domain->second.empty() && target != NULL) {
+            for (found_rrset = found_domain->second.begin();
+                 found_rrset != found_domain->second.end(); found_rrset++)
+            {
+                // Insert RRs under the domain name into target
+                target->addRRset(
+                    boost::const_pointer_cast<RRset>(found_rrset->second));
+            }
+            return (FindResult(SUCCESS, found_domain->second.begin()->second));
+        }
+
+        // Otherwise, if this domain name has CNAME, return it.
+        found_rrset = found_domain->second.find(RRType::CNAME());
+        if (found_rrset != found_domain->second.end()) {
+            return (FindResult(CNAME, found_rrset->second));
+        }
+
+        // Otherwise it's NXRRSET case.
         return (FindResult(NXRRSET, RRsetPtr()));
-    } else if ((name == Name("cname.example.com"))) {
-        return (FindResult(CNAME, cname_rrset));
-    } else if (name == Name("cnamemailer.example.com")) {
-        return (FindResult(CNAME, mx_cname_rrset_));
-    } else if (name == Name("mx.example.com")) {
-        return (FindResult(SUCCESS, mx_rrset_));
-    } else {
-        return (FindResult(DNAME, RRsetPtr()));
     }
+
+    // query name isn't found in our domains.  returns NXDOMAIN.
+    return (FindResult(NXDOMAIN, RRsetPtr()));
 }
 
 class QueryTest : public ::testing::Test {
@@ -186,195 +204,174 @@ protected:
     QueryTest() :
         qname(Name("www.example.com")), qclass(RRClass::IN()),
         qtype(RRType::A()), response(Message::RENDER),
-        query(memory_datasrc, qname, qtype, response)
+        qid(response.getQid()), query_code(Opcode::QUERY().getCode())
     {
         response.setRcode(Rcode::NOERROR());
+        response.setOpcode(Opcode::QUERY());
+        // create and add a matching zone.
+        mock_zone = new MockZone();
+        memory_datasrc.addZone(ZonePtr(mock_zone));
     }
+    MockZone* mock_zone;
     MemoryDataSrc memory_datasrc;
     const Name qname;
     const RRClass qclass;
     const RRType qtype;
     Message response;
-    Query query;
+    const qid_t qid;
+    const uint16_t query_code;
 };
 
+// A wrapper to check resulting response message commonly used in
+// tests below.
+// check_origin needs to be specified only when the authority section has
+// an SOA RR.  The interface is not generic enough but should be okay
+// for our test cases in practice.
+void
+responseCheck(Message& response, const isc::dns::Rcode& rcode,
+              unsigned int flags, const unsigned int ancount,
+              const unsigned int nscount, const unsigned int arcount,
+              const char* const expected_answer,
+              const char* const expected_authority,
+              const char* const expected_additional,
+              const Name& check_origin = Name::ROOT_NAME())
+{
+    // In our test cases QID, Opcode, and QDCOUNT should be constant, so
+    // we don't bother the test cases specifying these values.
+    headerCheck(response, response.getQid(), rcode, Opcode::QUERY().getCode(),
+                flags, 0, ancount, nscount, arcount);
+    if (expected_answer != NULL) {
+        rrsetsCheck(expected_answer,
+                    response.beginSection(Message::SECTION_ANSWER),
+                    response.endSection(Message::SECTION_ANSWER),
+                    check_origin);
+    }
+    if (expected_authority != NULL) {
+        rrsetsCheck(expected_authority,
+                    response.beginSection(Message::SECTION_AUTHORITY),
+                    response.endSection(Message::SECTION_AUTHORITY),
+                    check_origin);
+    }
+    if (expected_additional != NULL) {
+        rrsetsCheck(expected_additional,
+                    response.beginSection(Message::SECTION_ADDITIONAL),
+                    response.endSection(Message::SECTION_ADDITIONAL));
+    }
+}
+
 TEST_F(QueryTest, noZone) {
     // There's no zone in the memory datasource.  So the response should have
     // REFUSED.
-    EXPECT_NO_THROW(query.process());
+    MemoryDataSrc empty_memory_datasrc;
+    Query nozone_query(empty_memory_datasrc, qname, qtype, response);
+    EXPECT_NO_THROW(nozone_query.process());
     EXPECT_EQ(Rcode::REFUSED(), response.getRcode());
 }
 
 TEST_F(QueryTest, exactMatch) {
-    // add a matching zone.
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
+    Query query(memory_datasrc, qname, qtype, response);
     EXPECT_NO_THROW(query.process());
     // find match rrset
-    EXPECT_TRUE(response.getHeaderFlag(Message::HEADERFLAG_AA));
-    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
-                                  Name("www.example.com"), RRClass::IN(),
-                                  RRType::A()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
-                                  Name("example.com"), RRClass::IN(),
-                                  RRType::NS()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::A()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::AAAA()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("noglue.example.com"),
-                                  RRClass::IN(), RRType::A()));
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+                  www_a_txt, zone_ns_txt, ns_addrs_txt);
 }
 
 TEST_F(QueryTest, exactAddrMatch) {
     // find match rrset, omit additional data which has already been provided
     // in the answer section from the additional.
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    const Name noglue_name(Name("noglue.example.com"));
-    Query noglue_query(memory_datasrc, noglue_name, qtype, response);
-    EXPECT_NO_THROW(noglue_query.process());
-    EXPECT_TRUE(response.getHeaderFlag(Message::HEADERFLAG_AA));
-    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
-                                  Name("noglue.example.com"), RRClass::IN(),
-                                  RRType::A()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
-                                  Name("example.com"), RRClass::IN(),
-                                  RRType::NS()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::A()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::AAAA()));
-    EXPECT_FALSE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("noglue.example.com"),
-                                  RRClass::IN(), RRType::A()));
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("noglue.example.com"), qtype,
+                          response).process());
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 2,
+                  "noglue.example.com. 3600 IN A 192.0.2.53\n", zone_ns_txt,
+                  "glue.delegation.example.com. 3600 IN A 192.0.2.153\n"
+                  "glue.delegation.example.com. 3600 IN AAAA 2001:db8::53\n");
 }
 
 TEST_F(QueryTest, apexNSMatch) {
     // find match rrset, omit authority data which has already been provided
     // in the answer section from the authority section.
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    const Name apex_name(Name("example.com"));
-    Query apex_ns_query(memory_datasrc, apex_name, RRType::NS(), response);
-    EXPECT_NO_THROW(apex_ns_query.process());
-    EXPECT_TRUE(response.getHeaderFlag(Message::HEADERFLAG_AA));
-    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
-                                  Name("example.com"), RRClass::IN(),
-                                  RRType::NS()));
-    EXPECT_FALSE(response.hasRRset(Message::SECTION_AUTHORITY,
-                                  Name("example.com"), RRClass::IN(),
-                                  RRType::NS()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::A()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::AAAA()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("noglue.example.com"),
-                                  RRClass::IN(), RRType::A()));
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("example.com"), RRType::NS(),
+                          response).process());
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 3, 0, 3,
+                  zone_ns_txt, NULL, ns_addrs_txt);
 }
 
+// test type any query logic
 TEST_F(QueryTest, exactAnyMatch) {
     // find match rrset, omit additional data which has already been provided
     // in the answer section from the additional.
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    const Name noglue_name(Name("noglue.example.com"));
-    Query noglue_query(memory_datasrc, noglue_name, RRType::ANY(), response);
-    EXPECT_NO_THROW(noglue_query.process());
-    EXPECT_TRUE(response.getHeaderFlag(Message::HEADERFLAG_AA));
-    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
-                                  Name("noglue.example.com"), RRClass::IN(),
-                                  RRType::A()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
-                                  Name("example.com"), RRClass::IN(),
-                                  RRType::NS()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::A()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::AAAA()));
-    EXPECT_FALSE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("noglue.example.com"),
-                                  RRClass::IN(), RRType::A()));
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("noglue.example.com"),
+                          RRType::ANY(), response).process());
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 2,
+                  "noglue.example.com. 3600 IN A 192.0.2.53\n",
+                  zone_ns_txt,
+                  "glue.delegation.example.com. 3600 IN A 192.0.2.153\n"
+                  "glue.delegation.example.com. 3600 IN AAAA 2001:db8::53\n");
+}
+
+TEST_F(QueryTest, apexAnyMatch) {
+    // find match rrset, omit additional data which has already been provided
+    // in the answer section from the additional.
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("example.com"),
+                          RRType::ANY(), response).process());
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 4, 0, 0,
+                  "example.com. 3600 IN SOA . . 0 0 0 0 0\n"
+                  "example.com. 3600 IN NS glue.delegation.example.com.\n"
+                  "example.com. 3600 IN NS noglue.example.com.\n"
+                  "example.com. 3600 IN NS example.net.\n",
+                  NULL, NULL, mock_zone->getOrigin());
+}
+
+TEST_F(QueryTest, glueANYMatch) {
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("delegation.example.com"),
+                          RRType::ANY(), response).process());
+    responseCheck(response, Rcode::NOERROR(), 0, 0, 4, 3,
+                  NULL, delegation_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, nodomainANY) {
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("nxdomain.example.com"),
+                          RRType::ANY(), response).process());
+    responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 1, 0,
+                  NULL, soa_txt, NULL, mock_zone->getOrigin());
 }
 
 // This tests that when we need to look up Zone's apex NS records for
 // authoritative answer, and there is no apex NS records. It should
 // throw in that case.
 TEST_F(QueryTest, noApexNS) {
-    // Add a zone without apex NS records
-    memory_datasrc.addZone(ZonePtr(new MockZone(true, false)));
-    const Name noglue_name(Name("noglue.example.com"));
-    Query noglue_query(memory_datasrc, noglue_name, qtype, response);
-    EXPECT_THROW(noglue_query.process(), Query::NoApexNS);
-    // We don't look into the response, as it throwed
+    // Disable apex NS record
+    mock_zone->setApexNSFlag(false);
+
+    EXPECT_THROW(Query(memory_datasrc, Name("noglue.example.com"), qtype,
+                       response).process(), Query::NoApexNS);
+    // We don't look into the response, as it threw
 }
 
 TEST_F(QueryTest, delegation) {
-    // add a matching zone.
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    const Name delegation_name(Name("delegation.example.com"));
-    Query delegation_query(memory_datasrc, delegation_name, qtype, response);
-    EXPECT_NO_THROW(delegation_query.process());
-    EXPECT_FALSE(response.getHeaderFlag(Message::HEADERFLAG_AA));
-    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
-                                  Name("delegation.example.com"),
-                                  RRClass::IN(), RRType::NS()));
-    // glue address records
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::A()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("glue.ns.example.com"),
-                                  RRClass::IN(), RRType::AAAA()));
-    // noglue address records
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("noglue.example.com"),
-                                  RRClass::IN(), RRType::A()));
-    // NS name has a CNAME
-    EXPECT_FALSE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("www.example.com"),
-                                  RRClass::IN(), RRType::A()));
-    // NS name is out of zone
-    EXPECT_FALSE(response.hasRRset(Message::SECTION_ADDITIONAL,
-                                  Name("example.org"),
-                                  RRClass::IN(), RRType::A()));
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("delegation.example.com"),
+                          qtype, response).process());
+
+    responseCheck(response, Rcode::NOERROR(), 0, 0, 4, 3,
+                  NULL, delegation_txt, ns_addrs_txt);
 }
 
 TEST_F(QueryTest, nxdomain) {
-    // add a matching zone.
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    const Name nxdomain_name(Name("nxdomain.example.com"));
-    Query nxdomain_query(memory_datasrc, nxdomain_name, qtype, response);
-    EXPECT_NO_THROW(nxdomain_query.process());
-    EXPECT_EQ(Rcode::NXDOMAIN(), response.getRcode());
-    EXPECT_EQ(0, response.getRRCount(Message::SECTION_ANSWER));
-    EXPECT_EQ(0, response.getRRCount(Message::SECTION_ADDITIONAL));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
-        Name("example.com"), RRClass::IN(), RRType::SOA()));
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("nxdomain.example.com"), qtype,
+                          response).process());
+    responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 1, 0,
+                  NULL, soa_txt, NULL, mock_zone->getOrigin());
 }
 
 TEST_F(QueryTest, nxrrset) {
-    // add a matching zone.
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    const Name nxrrset_name(Name("nxrrset.example.com"));
-    Query nxrrset_query(memory_datasrc, nxrrset_name, qtype, response);
-    EXPECT_NO_THROW(nxrrset_query.process());
-    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
-    EXPECT_EQ(0, response.getRRCount(Message::SECTION_ANSWER));
-    EXPECT_EQ(0, response.getRRCount(Message::SECTION_ADDITIONAL));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
-        Name("example.com"), RRClass::IN(), RRType::SOA()));
+    EXPECT_NO_THROW(Query(memory_datasrc, Name("www.example.com"),
+                          RRType::TXT(), response).process());
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 1, 0,
+                  NULL, soa_txt, NULL, mock_zone->getOrigin());
 }
 
 /*
@@ -382,27 +379,23 @@ TEST_F(QueryTest, nxrrset) {
  * throw in that case.
  */
 TEST_F(QueryTest, noSOA) {
-    memory_datasrc.addZone(ZonePtr(new MockZone(false)));
+    // disable zone's SOA RR.
+    mock_zone->setSOAFlag(false);
 
     // The NX Domain
-    const Name nxdomain_name(Name("nxdomain.example.com"));
-    Query nxdomain_query(memory_datasrc, nxdomain_name, qtype, response);
-    EXPECT_THROW(nxdomain_query.process(), Query::NoSOA);
+    EXPECT_THROW(Query(memory_datasrc, Name("nxdomain.example.com"),
+                       qtype, response).process(), Query::NoSOA);
     // Of course, we don't look into the response, as it throwed
 
     // NXRRSET
-    const Name nxrrset_name(Name("nxrrset.example.com"));
-    Query nxrrset_query(memory_datasrc, nxrrset_name, qtype, response);
-    EXPECT_THROW(nxrrset_query.process(), Query::NoSOA);
+    EXPECT_THROW(Query(memory_datasrc, Name("nxrrset.example.com"),
+                       qtype, response).process(), Query::NoSOA);
 }
 
 TEST_F(QueryTest, noMatchZone) {
     // there's a zone in the memory datasource but it doesn't match the qname.
     // should result in REFUSED.
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    const Name nomatch_name(Name("example.org"));
-    Query nomatch_query(memory_datasrc, nomatch_name, qtype, response);
-    nomatch_query.process();
+    Query(memory_datasrc, Name("example.org"), qtype, response).process();
     EXPECT_EQ(Rcode::REFUSED(), response.getRcode());
 }
 
@@ -413,76 +406,124 @@ TEST_F(QueryTest, noMatchZone) {
  * A record, other to unknown out of zone one.
  */
 TEST_F(QueryTest, MX) {
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    Name qname("mx.example.com");
-    Query mx_query(memory_datasrc, qname, RRType::MX(), response);
-    EXPECT_NO_THROW(mx_query.process());
-    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
-        Name("mx.example.com"), RRClass::IN(), RRType::MX()));
-    EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
-        Name("www.example.com"), RRClass::IN(), RRType::A()));
-    // We want to skip the additional ones related to authoritative
-    RRsetPtr ns;
-    for (SectionIterator<RRsetPtr> ai(response.beginSection(
-        Message::SECTION_AUTHORITY)); ai != response.endSection(
-        Message::SECTION_AUTHORITY); ++ai)
-    {
-        if ((*ai)->getName() == Name("example.com") && (*ai)->getType() ==
-            RRType::NS())
-        {
-            ns = *ai;
-            break;
-        }
-    }
-    /*
-     * In fact, the MX RRset mentions three names, but we don't know anything
-     * about one of them and one is under a zone cut, so we should have just
-     * one RRset (A for www.example.com)
-     */
-    // We can't use getRRCount, as it counts RRs, not RRsets
-    unsigned additional_count(0);
-    for (SectionIterator<RRsetPtr> ai(response.beginSection(
-        Message::SECTION_ADDITIONAL)); ai != response.endSection(
-        Message::SECTION_ADDITIONAL); ++ai)
-    {
-        // Skip the ones for the NS record
-        if (ns) {
-            for (RdataIteratorPtr nsi(ns->getRdataIterator()); !nsi->isLast();
-                nsi->next())
-            {
-                if ((*ai)->getName() ==
-                    dynamic_cast<const isc::dns::rdata::generic::NS&>(
-                    nsi->getCurrent()).getNSName())
-                {
-                    goto NS_ADDITIONAL_DATA;
-                }
-            }
-        }
-        // It is not related to the NS, then it must be related to the MX
-        ++additional_count;
-        EXPECT_EQ(Name("www.example.com"), (*ai)->getName());
-        EXPECT_EQ(RRType::A(), (*ai)->getType());
-        NS_ADDITIONAL_DATA:;
-    }
-    EXPECT_EQ(1, additional_count);
+    Query(memory_datasrc, Name("mx.example.com"), RRType::MX(),
+          response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 3, 3, 4,
+                  mx_txt, NULL,
+                  (string(ns_addrs_txt) + string(www_a_txt)).c_str());
 }
 
 /*
- * Test when we ask for MX and encounter an alias (CNAME in this case).
+ * Test when we ask for MX whose exchange is an alias (CNAME in this case).
  *
- * This should not trigger the additional processing.
+ * This should not trigger the additional processing for the exchange.
  */
 TEST_F(QueryTest, MXAlias) {
-    memory_datasrc.addZone(ZonePtr(new MockZone()));
-    Name qname("cnamemailer.example.com");
-    Query mx_query(memory_datasrc, qname, RRType::MX(), response);
-    EXPECT_NO_THROW(mx_query.process());
-    EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
-    // We should not have the IP address in additional section
-    // Currently, the section should be completely empty
-    EXPECT_TRUE(response.beginSection(Message::SECTION_ADDITIONAL) ==
-        response.endSection(Message::SECTION_ADDITIONAL));
+    Query(memory_datasrc, Name("cnamemx.example.com"), RRType::MX(),
+          response).process();
+
+    // there shouldn't be no additional RRs for the exchanges (we have 3
+    // RRs for the NS).  The normal MX case is tested separately so we don't
+    // bother to examine the answer (and authority) sections.
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+                  NULL, NULL, ns_addrs_txt);
+}
+
+/*
+ * Tests encountering a cname.
+ *
+ * There are tests leading to successful answers, NXRRSET, NXDOMAIN and
+ * out of the zone.
+ *
+ * TODO: We currently don't do chaining, so only the CNAME itself should be
+ * returned.
+ */
+TEST_F(QueryTest, CNAME) {
+    Query(memory_datasrc, Name("cname.example.com"), RRType::A(),
+        response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+        cname_txt, zone_ns_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, explicitCNAME) {
+    // same owner name as the CNAME test but explicitly query for CNAME RR.
+    // expect the same response as we don't provide a full chain yet.
+    Query(memory_datasrc, Name("cname.example.com"), RRType::CNAME(),
+        response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+        cname_txt, zone_ns_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, CNAME_NX_RRSET) {
+    // Leads to www.example.com, it doesn't have TXT
+    // note: with chaining, what should be expected is not trivial:
+    // BIND 9 returns the CNAME in answer and SOA in authority, no additional.
+    // NSD returns the CNAME, NS in authority, A/AAAA for NS in additional.
+    Query(memory_datasrc, Name("cname.example.com"), RRType::TXT(),
+        response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+        cname_txt, zone_ns_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, explicitCNAME_NX_RRSET) {
+    // same owner name as the NXRRSET test but explicitly query for CNAME RR.
+    Query(memory_datasrc, Name("cname.example.com"), RRType::CNAME(),
+        response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+        cname_txt, zone_ns_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, CNAME_NX_DOMAIN) {
+    // Leads to nxdomain.example.com
+    // note: with chaining, what should be expected is not trivial:
+    // BIND 9 returns the CNAME in answer and SOA in authority, no additional,
+    // RCODE being NXDOMAIN.
+    // NSD returns the CNAME, NS in authority, A/AAAA for NS in additional,
+    // RCODE being NOERROR.
+    Query(memory_datasrc, Name("cnamenxdom.example.com"), RRType::A(),
+        response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+        cname_nxdom_txt, zone_ns_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, explicitCNAME_NX_DOMAIN) {
+    // same owner name as the NXDOMAIN test but explicitly query for CNAME RR.
+    Query(memory_datasrc, Name("cnamenxdom.example.com"), RRType::CNAME(),
+        response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+        cname_nxdom_txt, zone_ns_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, CNAME_OUT) {
+    /*
+     * This leads out of zone. This should have only the CNAME even
+     * when we do chaining.
+     *
+     * TODO: We should be able to have two zones in the mock data source.
+     * Then the same test should be done with .org included there and
+     * see what it does (depends on what we want to do)
+     */
+    Query(memory_datasrc, Name("cnameout.example.com"), RRType::A(),
+        response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+        cname_out_txt, zone_ns_txt, ns_addrs_txt);
+}
+
+TEST_F(QueryTest, explicitCNAME_OUT) {
+    // same owner name as the OUT test but explicitly query for CNAME RR.
+    Query(memory_datasrc, Name("cnameout.example.com"), RRType::CNAME(),
+        response).process();
+
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+        cname_out_txt, zone_ns_txt, ns_addrs_txt);
 }
 
 }
diff --git a/src/bin/auth/tests/run_unittests.cc b/src/bin/auth/tests/run_unittests.cc
index 4bc529c..6ae848d 100644
--- a/src/bin/auth/tests/run_unittests.cc
+++ b/src/bin/auth/tests/run_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <dns/tests/unittest_util.h>
diff --git a/src/bin/auth/tests/statistics_unittest.cc b/src/bin/auth/tests/statistics_unittest.cc
index 1bb3cd2..062b70d 100644
--- a/src/bin/auth/tests/statistics_unittest.cc
+++ b/src/bin/auth/tests/statistics_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <gtest/gtest.h>
diff --git a/src/bin/bind10/bind10.xml b/src/bin/bind10/bind10.xml
index 25a8804..dfc8acf 100644
--- a/src/bin/bind10/bind10.xml
+++ b/src/bin/bind10/bind10.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
@@ -132,7 +131,7 @@
             daemon to listen on.
             The default is 5300.</para>
 <!-- TODO: -->
-	    <note><simpara>The Y1 prototype release uses a non-default
+	    <note><simpara>This prototype release uses a non-default
 	    port for domain service.</simpara></note>
          </listitem>
       </varlistentry>
diff --git a/src/bin/bindctl/bindctl.xml b/src/bin/bindctl/bindctl.xml
index d4036f2..98d65f9 100644
--- a/src/bin/bindctl/bindctl.xml
+++ b/src/bin/bindctl/bindctl.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/cfgmgr/b10-cfgmgr.py.in b/src/bin/cfgmgr/b10-cfgmgr.py.in
old mode 100644
new mode 100755
index 73906b7..659426d
--- a/src/bin/cfgmgr/b10-cfgmgr.py.in
+++ b/src/bin/cfgmgr/b10-cfgmgr.py.in
@@ -15,8 +15,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 import sys; sys.path.append ('@@PYTHONPATH@@')
 
 from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError
diff --git a/src/bin/cfgmgr/b10-cfgmgr.xml b/src/bin/cfgmgr/b10-cfgmgr.xml
index 20224dc..9505eee 100644
--- a/src/bin/cfgmgr/b10-cfgmgr.xml
+++ b/src/bin/cfgmgr/b10-cfgmgr.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in b/src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in
index c2687ff..8847b18 100644
--- a/src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in
+++ b/src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: cfgmgr_test.py 2126 2010-06-16 14:40:22Z jelte $
-
 #
 # Tests for the configuration manager run script
 #
diff --git a/src/bin/cmdctl/b10-cmdctl.xml b/src/bin/cmdctl/b10-cmdctl.xml
index c0ac36a..06953a4 100644
--- a/src/bin/cmdctl/b10-cmdctl.xml
+++ b/src/bin/cmdctl/b10-cmdctl.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/loadzone/b10-loadzone.xml b/src/bin/loadzone/b10-loadzone.xml
index 3bed19e..25e23a5 100644
--- a/src/bin/loadzone/b10-loadzone.xml
+++ b/src/bin/loadzone/b10-loadzone.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/loadzone/tests/correct/mix1.db b/src/bin/loadzone/tests/correct/mix1.db
index da562ff..a9d58a8 100644
--- a/src/bin/loadzone/tests/correct/mix1.db
+++ b/src/bin/loadzone/tests/correct/mix1.db
@@ -1,4 +1,3 @@
-; $Id: ttl1.db,v 1.6 2007/06/19 23:47:04 tbox Exp $
 $ORIGIN mix1.
 @			IN SOA	ns hostmaster (
 				1        ; serial
diff --git a/src/bin/loadzone/tests/correct/ttlext.db b/src/bin/loadzone/tests/correct/ttlext.db
index 8ad6103..f8b96ea 100644
--- a/src/bin/loadzone/tests/correct/ttlext.db
+++ b/src/bin/loadzone/tests/correct/ttlext.db
@@ -1,4 +1,3 @@
-; $Id: ttl1.db,v 1.6 2007/06/19 23:47:04 tbox Exp $
 $ORIGIN ttlext.
 @			IN SOA	ns hostmaster (
 				1        ; serial
diff --git a/src/bin/msgq/msgq.py.in b/src/bin/msgq/msgq.py.in
old mode 100644
new mode 100755
index fad5b1f..8a8362a
--- a/src/bin/msgq/msgq.py.in
+++ b/src/bin/msgq/msgq.py.in
@@ -127,6 +127,7 @@ class MsgQ:
         self.hostname = socket.gethostname()
         self.subs = SubscriptionManager()
         self.lnames = {}
+        self.sendbuffs = {}
 
     def setup_poller(self):
         """Set up the poll thing.  Internal function."""
@@ -135,12 +136,29 @@ class MsgQ:
         except AttributeError:
             self.kqueue = select.kqueue()
     
-    def add_kqueue_socket(self, socket):
-        event = select.kevent(socket.fileno(),
-                              select.KQ_FILTER_READ,
+    def add_kqueue_socket(self, socket, write_filter=False):
+        """Add a kquque filter for a socket.  By default the read
+        filter is used; if write_filter is set to True, the write
+        filter is used.  We use a boolean value instead of a specific
+        filter constant, because kqueue filter values do not seem to
+        be defined on some systems.  The use of boolean makes the
+        interface restrictive because there are other filters, but this
+        method is mostly only for our internal use, so it should be
+        acceptable at least for now."""
+        filter_type = select.KQ_FILTER_WRITE if write_filter else \
+            select.KQ_FILTER_READ
+        event = select.kevent(socket.fileno(), filter_type,
                               select.KQ_EV_ADD | select.KQ_EV_ENABLE)
         self.kqueue.control([event], 0)
 
+    def delete_kqueue_socket(self, socket, write_filter=False):
+        """Delete a kqueue filter for socket.  See add_kqueue_socket()
+        for the semantics and notes about write_filter."""
+        filter_type = select.KQ_FILTER_WRITE if write_filter else \
+            select.KQ_FILTER_READ
+        event = select.kevent(socket.fileno(), filter_type,
+                              select.KQ_EV_DELETE)
+        self.kqueue.control([event], 0)
 
     def setup_listener(self):
         """Set up the listener socket.  Internal function."""
@@ -187,6 +205,12 @@ class MsgQ:
         # TODO: When we have logging, we might want
         # to add a debug message here that a new connection
         # was made
+        self.register_socket(newsocket)
+
+    def register_socket(self, newsocket):
+        """
+        Internal function to insert a socket. Used by process_accept and some tests.
+        """
         self.sockets[newsocket.fileno()] = newsocket
         lname = self.newlname()
         self.lnames[lname] = newsocket
@@ -198,10 +222,10 @@ class MsgQ:
 
     def process_socket(self, fd):
         """Process a read on a socket."""
-        sock = self.sockets[fd]
-        if sock == None:
+        if not fd in self.sockets:
             sys.stderr.write("[b10-msgq] Got read on Strange Socket fd %d\n" % fd)
             return
+        sock = self.sockets[fd]
 #        sys.stderr.write("[b10-msgq] Got read on fd %d\n" %fd)
         self.process_packet(fd, sock)
 
@@ -213,7 +237,9 @@ class MsgQ:
         lname = [ k for k, v in self.lnames.items() if v == sock ][0]
         del self.lnames[lname]
         sock.close()
-        self.sockets[fd] = None
+        del self.sockets[fd]
+        if fd in self.sendbuffs:
+            del self.sendbuffs[fd]
         sys.stderr.write("[b10-msgq] Closing socket fd %d\n" % fd)
 
     def getbytes(self, fd, sock, length):
@@ -287,6 +313,9 @@ class MsgQ:
             self.process_command_unsubscribe(sock, routing, data)
         elif cmd == 'getlname':
             self.process_command_getlname(sock, routing, data)
+        elif cmd == 'ping':
+            # Command for testing purposes
+            self.process_command_ping(sock, routing, data)
         else:
             sys.stderr.write("[b10-msgq] Invalid command: %s\n" % cmd)
 
@@ -305,10 +334,67 @@ class MsgQ:
         return ret
 
     def sendmsg(self, sock, env, msg = None):
-        sock.send(self.preparemsg(env, msg))
+        self.send_prepared_msg(sock, self.preparemsg(env, msg))
+
+    def __send_data(self, sock, data):
+        try:
+            # We set the socket nonblocking, MSG_DONTWAIT doesn't exist
+            # on some OSes
+            sock.setblocking(0)
+            return sock.send(data)
+        except socket.error as e:
+            if e.errno == errno.EAGAIN or e.errno == errno.EWOULDBLOCK:
+                return 0
+            else:
+                raise e
+        finally:
+            # And set it back again
+            sock.setblocking(1)
 
     def send_prepared_msg(self, sock, msg):
-        sock.send(msg)
+        # Try to send the data, but only if there's nothing waiting
+        fileno = sock.fileno()
+        if fileno in self.sendbuffs:
+            amount_sent = 0
+        else:
+            amount_sent = self.__send_data(sock, msg)
+
+        # Still something to send
+        if amount_sent < len(msg):
+            now = time.clock()
+            # Append it to buffer (but check the data go away)
+            if fileno in self.sendbuffs:
+                (last_sent, buff) = self.sendbuffs[fileno]
+                if now - last_sent > 0.1:
+                    self.kill_socket(fileno, sock)
+                    return
+                buff += msg
+            else:
+                buff = msg[amount_sent:]
+                last_sent = now
+                if self.poller:
+                    self.poller.register(fileno, select.POLLIN |
+                        select.POLLOUT)
+                else:
+                    self.add_kqueue_socket(sock, True)
+            self.sendbuffs[fileno] = (last_sent, buff)
+
+    def __process_write(self, fileno):
+        # Try to send some data from the buffer
+        (_, msg) = self.sendbuffs[fileno]
+        sock = self.sockets[fileno]
+        amount_sent = self.__send_data(sock, msg)
+        # Keep the rest
+        msg = msg[amount_sent:]
+        if len(msg) == 0:
+            # If there's no more, stop requesting for write availability
+            if self.poller:
+                self.poller.register(fileno, select.POLLIN)
+            else:
+                self.delete_kqueue_socket(sock, True)
+            del self.sendbuffs[fileno]
+        else:
+            self.sendbuffs[fileno] = (time.clock(), msg)
 
     def newlname(self):
         """Generate a unique connection identifier for this socket.
@@ -317,6 +403,9 @@ class MsgQ:
         self.connection_counter += 1
         return "%x_%x@%s" % (time.time(), self.connection_counter, self.hostname)
 
+    def process_command_ping(self, sock, routing, data):
+        self.sendmsg(sock, { "type" : "pong" }, data)
+
     def process_command_getlname(self, sock, routing, data):
         lname = [ k for k, v in self.lnames.items() if v == sock ][0]
         self.sendmsg(sock, { "type" : "getlname" }, { "lname" : lname })
@@ -379,22 +468,29 @@ class MsgQ:
                 if fd == self.listen_socket.fileno():
                     self.process_accept()
                 else:
-                    self.process_socket(fd)
+                    if event & select.POLLOUT:
+                        self.__process_write(fd)
+                    if event & select.POLLIN:
+                        self.process_socket(fd)
 
     def run_kqueue(self):
         while True:
             events = self.kqueue.control(None, 10)
             if not events:
                 raise RuntimeError('serve: kqueue returned no events')
-            
+
             for event in events:
                 if event.ident == self.listen_socket.fileno():
                     self.process_accept()
                 else:
-                    if event.flags & select.KQ_FILTER_READ and event.data > 0:
+                    if event.filter == select.KQ_FILTER_WRITE:
+                        self.__process_write(event.ident)
+                    if event.filter == select.KQ_FILTER_READ and \
+                            event.data > 0:
                         self.process_socket(event.ident)
                     elif event.flags & select.KQ_EV_EOF:
-                        self.kill_socket(event.ident, self.sockets[event.ident])
+                        self.kill_socket(event.ident,
+                                         self.sockets[event.ident])
 
     def shutdown(self):
         """Stop the MsgQ master."""
diff --git a/src/bin/msgq/msgq.xml b/src/bin/msgq/msgq.xml
index dc60a01..fd9518d 100644
--- a/src/bin/msgq/msgq.xml
+++ b/src/bin/msgq/msgq.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/msgq/tests/msgq_test.py b/src/bin/msgq/tests/msgq_test.py
index 2c10ed2..efae151 100644
--- a/src/bin/msgq/tests/msgq_test.py
+++ b/src/bin/msgq/tests/msgq_test.py
@@ -3,10 +3,14 @@ from msgq import SubscriptionManager, MsgQ
 import unittest
 import os
 import socket
+import signal
+import sys
+import time
+import isc.cc
 
 #
-# Currently only the subscription part is implemented...  I'd have to mock
-# out a socket, which, while not impossible, is not trivial.
+# Currently only the subscription part and some sending is implemented...
+# I'd have to mock out a socket, which, while not impossible, is not trivial.
 #
 
 class TestSubscriptionManager(unittest.TestCase):
@@ -108,5 +112,126 @@ class TestSubscriptionManager(unittest.TestCase):
         msgq = MsgQ("/does/not/exist")
         self.assertRaises(socket.error, msgq.setup)
 
+class SendNonblock(unittest.TestCase):
+    """
+    Tests that the whole thing will not get blocked if someone does not read.
+    """
+
+    def terminate_check(self, task, timeout = 10):
+        """
+        Runs task in separate process (task is a function) and checks
+        it terminates sooner than timeout.
+        """
+        task_pid = os.fork()
+        if task_pid == 0:
+            # Kill the forked process after timeout by SIGALRM
+            signal.alarm(timeout)
+            # Run the task
+            # If an exception happens or we run out of time, we terminate
+            # with non-zero
+            task()
+            # If we got here, then everything worked well and in time
+            # In that case, we terminate successfully
+            sys.exit()
+        else:
+            (pid, status) = os.waitpid(task_pid, 0)
+            self.assertEqual(0, status,
+                "The task did not complete successfully in time")
+
+    def infinite_sender(self, sender):
+        """
+        Sends data until an exception happens. socket.error is caught,
+        as it means the socket got closed. Sender is called to actually
+        send the data.
+        """
+        msgq = MsgQ()
+        # We do only partial setup, so we don't create the listening socket
+        msgq.setup_poller()
+        (read, write) = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
+        msgq.register_socket(write)
+        # Keep sending while it is not closed by the msgq
+        try:
+            while True:
+                sender(msgq, write)
+        except socket.error:
+            pass
+
+    def test_infinite_sendmsg(self):
+        """
+        Tries sending messages (and not reading them) until it either times
+        out (in blocking call, wrong) or closes it (correct).
+        """
+        data = "data"
+        for i in range(1, 10):
+            data += data
+        self.terminate_check(lambda: self.infinite_sender(
+            lambda msgq, socket: msgq.sendmsg(socket, {}, {"message" : data})))
+
+    def test_infinite_sendprepared(self):
+        """
+        Tries sending data (and not reading them) until it either times
+        out (in blocking call, wrong) or closes it (correct).
+        """
+        data = b"data"
+        for i in range(1, 10):
+            data += data
+        self.terminate_check(lambda: self.infinite_sender(
+            lambda msgq, socket: msgq.send_prepared_msg(socket, data)))
+
+    def send_many(self, data):
+        """
+        Tries that sending a command many times and getting an answer works.
+        """
+        msgq = MsgQ()
+        # msgq.run needs to compare with the listen_socket, so we provide
+        # a replacement
+        class DummySocket:
+            def fileno():
+                return -1
+        msgq.listen_socket = DummySocket
+        (queue, out) = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
+        def run():
+            length = len(data)
+            queue_pid = os.fork()
+            if queue_pid == 0:
+                signal.alarm(30)
+                msgq.setup_poller()
+                msgq.register_socket(queue)
+                msgq.run()
+            else:
+                try:
+                    def killall(signum, frame):
+                        os.kill(queue_pid, signal.SIGTERM)
+                        sys.exit(1)
+                    signal.signal(signal.SIGALRM, killall)
+                    msg = msgq.preparemsg({"type" : "ping"}, data)
+                    now = time.clock()
+                    while time.clock() - now < 0.2:
+                        out.sendall(msg)
+                        # Check the answer
+                        (routing, received) = msgq.read_packet(out.fileno(),
+                            out)
+                        self.assertEqual({"type" : "pong"},
+                            isc.cc.message.from_wire(routing))
+                        self.assertEqual(data, received)
+                finally:
+                    os.kill(queue_pid, signal.SIGTERM)
+        self.terminate_check(run)
+
+    def test_small_sends(self):
+        """
+        Tests sending small data many times.
+        """
+        self.send_many(b"data")
+
+    def test_large_sends(self):
+        """
+        Tests sending large data many times.
+        """
+        data = b"data"
+        for i in range(1, 20):
+            data = data + data
+        self.send_many(data)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/src/bin/resolver/Makefile.am b/src/bin/resolver/Makefile.am
index eaecfe2..dc6deed 100644
--- a/src/bin/resolver/Makefile.am
+++ b/src/bin/resolver/Makefile.am
@@ -37,6 +37,7 @@ spec_config.h: spec_config.h.pre
 BUILT_SOURCES = spec_config.h 
 pkglibexec_PROGRAMS = b10-resolver
 b10_resolver_SOURCES = resolver.cc resolver.h
+b10_resolver_SOURCES += response_classifier.cc response_classifier.h
 b10_resolver_SOURCES += $(top_builddir)/src/bin/auth/change_user.h
 b10_resolver_SOURCES += $(top_builddir)/src/bin/auth/common.h
 b10_resolver_SOURCES += main.cc
diff --git a/src/bin/resolver/b10-resolver.xml b/src/bin/resolver/b10-resolver.xml
index fb2d536..dc2b724 100644
--- a/src/bin/resolver/b10-resolver.xml
+++ b/src/bin/resolver/b10-resolver.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/resolver/main.cc b/src/bin/resolver/main.cc
index 29d91f5..03f9ab7 100644
--- a/src/bin/resolver/main.cc
+++ b/src/bin/resolver/main.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/select.h>
diff --git a/src/bin/resolver/resolver.cc b/src/bin/resolver/resolver.cc
index 37c979f..4fd887e 100644
--- a/src/bin/resolver/resolver.cc
+++ b/src/bin/resolver/resolver.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <netinet/in.h>
@@ -66,7 +64,9 @@ private:
 public:
     ResolverImpl() :
         config_session_(NULL),
-        timeout_(2000),
+        query_timeout_(2000),
+        client_timeout_(4000),
+        lookup_timeout_(30000),
         retries_(3),
         rec_query_(NULL)
     {}
@@ -78,7 +78,12 @@ public:
     void querySetup(DNSService& dnss) {
         assert(!rec_query_); // queryShutdown must be called first
         dlog("Query setup");
-        rec_query_ = new RecursiveQuery(dnss, upstream_, timeout_, retries_);
+        rec_query_ = new RecursiveQuery(dnss, upstream_,
+                                        upstream_root_,
+                                        query_timeout_,
+                                        client_timeout_,
+                                        lookup_timeout_,
+                                        retries_);
     }
 
     void queryShutdown() {
@@ -97,20 +102,37 @@ public:
     {
         upstream_ = upstream;
         if (dnss) {
-            if (upstream_.empty()) {
-                dlog("Asked to do full recursive, but not implemented yet. "
-                    "I'll do nothing.",true);
-            } else {
+            if (!upstream_.empty()) {
                 dlog("Setting forward addresses:");
                 BOOST_FOREACH(const addr_t& address, upstream) {
                     dlog(" " + address.first + ":" +
                         boost::lexical_cast<string>(address.second));
                 }
+            } else {
+                dlog("No forward addresses, running in recursive mode");
             }
         }
     }
 
-    void processNormalQuery(const Question& question, MessagePtr message,
+    void setRootAddresses(const vector<addr_t>& upstream_root,
+                          DNSService *dnss)
+    {
+        upstream_root_ = upstream_root;
+        if (dnss) {
+            if (!upstream_root_.empty()) {
+                dlog("Setting root addresses:");
+                BOOST_FOREACH(const addr_t& address, upstream_root) {
+                    dlog(" " + address.first + ":" +
+                        boost::lexical_cast<string>(address.second));
+                }
+            } else {
+                dlog("No root addresses");
+            }
+        }
+    }
+
+    void processNormalQuery(const Question& question,
+                            MessagePtr answer_message,
                             OutputBufferPtr buffer,
                             DNSServer* server);
 
@@ -119,13 +141,20 @@ public:
 
     /// These members are public because Resolver accesses them directly.
     ModuleCCSession* config_session_;
+    /// Addresses of the root nameserver(s)
+    vector<addr_t> upstream_root_;
     /// Addresses of the forward nameserver
     vector<addr_t> upstream_;
     /// Addresses we listen on
     vector<addr_t> listen_;
 
-    /// Time in milliseconds, to timeout
-    int timeout_;
+    /// Timeout for outgoing queries in milliseconds
+    int query_timeout_;
+    /// Timeout for incoming client queries in milliseconds
+    int client_timeout_;
+    /// Timeout for lookup processing in milliseconds
+    int lookup_timeout_;
+    
     /// Number of retries after timeout
     unsigned retries_;
 
@@ -151,20 +180,6 @@ public:
     MessagePtr message_;
 };
 
-class SectionInserter {
-public:
-    SectionInserter(MessagePtr message, const Message::Section sect) :
-        message_(message), section_(sect)
-    {}
-    void operator()(const RRsetPtr rrset) {
-        //dlog("Adding RRSet to message section " +
-        //    boost::lexical_cast<string>(section_));
-        message_->addRRset(section_, rrset, true);
-    }
-    MessagePtr message_;
-    const Message::Section section_;
-};
-
 void
 makeErrorMessage(MessagePtr message, OutputBufferPtr buffer,
                  const Rcode& rcode)
@@ -212,10 +227,14 @@ public:
     MessageLookup(Resolver* srv) : server_(srv) {}
 
     // \brief Handle the DNS Lookup
-    virtual void operator()(const IOMessage& io_message, MessagePtr message,
-                            OutputBufferPtr buffer, DNSServer* server) const
+    virtual void operator()(const IOMessage& io_message,
+                            MessagePtr query_message,
+                            MessagePtr answer_message,
+                            OutputBufferPtr buffer,
+                            DNSServer* server) const
     {
-        server_->processMessage(io_message, message, buffer, server);
+        server_->processMessage(io_message, query_message,
+                                answer_message, buffer, server);
     }
 private:
     Resolver* server_;
@@ -228,76 +247,62 @@ private:
 class MessageAnswer : public DNSAnswer {
 public:
     virtual void operator()(const IOMessage& io_message,
-                            MessagePtr message,
+                            MessagePtr query_message,
+                            MessagePtr answer_message,
                             OutputBufferPtr buffer) const
     {
-        const qid_t qid = message->getQid();
-        const bool rd = message->getHeaderFlag(Message::HEADERFLAG_RD);
-        const bool cd = message->getHeaderFlag(Message::HEADERFLAG_CD);
-        const Opcode& opcode = message->getOpcode();
-        const Rcode& rcode = message->getRcode();
-        vector<QuestionPtr> questions;
-        questions.assign(message->beginQuestion(), message->endQuestion());
+        const qid_t qid = query_message->getQid();
+        const bool rd = query_message->getHeaderFlag(Message::HEADERFLAG_RD);
+        const bool cd = query_message->getHeaderFlag(Message::HEADERFLAG_CD);
+        const Opcode& opcode = query_message->getOpcode();
 
-        message->clear(Message::RENDER);
-        message->setQid(qid);
-        message->setOpcode(opcode);
-        message->setRcode(rcode);
+        // Fill in the final details of the answer message
+        answer_message->setQid(qid);
+        answer_message->setOpcode(opcode);
 
-        message->setHeaderFlag(Message::HEADERFLAG_QR);
-        message->setHeaderFlag(Message::HEADERFLAG_RA);
+        answer_message->setHeaderFlag(Message::HEADERFLAG_QR);
+        answer_message->setHeaderFlag(Message::HEADERFLAG_RA);
         if (rd) {
-            message->setHeaderFlag(Message::HEADERFLAG_RD);
+            answer_message->setHeaderFlag(Message::HEADERFLAG_RD);
         }
         if (cd) {
-            message->setHeaderFlag(Message::HEADERFLAG_CD);
-        }
-
-
-        // Copy the question section.
-        for_each(questions.begin(), questions.end(), QuestionInserter(message));
-
-        // If the buffer already has an answer in it, copy RRsets from
-        // that into the new message, then clear the buffer and render
-        // the new message into it.
-        if (buffer->getLength() != 0) {
-            try {
-                Message incoming(Message::PARSE);
-                InputBuffer ibuf(buffer->getData(), buffer->getLength());
-                incoming.fromWire(ibuf);
-                message->setRcode(incoming.getRcode());
-                for_each(incoming.beginSection(Message::SECTION_ANSWER),
-                         incoming.endSection(Message::SECTION_ANSWER),
-                         SectionInserter(message, Message::SECTION_ANSWER));
-                for_each(incoming.beginSection(Message::SECTION_AUTHORITY),
-                         incoming.endSection(Message::SECTION_AUTHORITY),
-                         SectionInserter(message, Message::SECTION_AUTHORITY));
-                for_each(incoming.beginSection(Message::SECTION_ADDITIONAL),
-                         incoming.endSection(Message::SECTION_ADDITIONAL),
-                         SectionInserter(message, Message::SECTION_ADDITIONAL));
-            } catch (const Exception& ex) {
-                // Incoming message couldn't be read, we just SERVFAIL
-                message->setRcode(Rcode::SERVFAIL());
-            }
+            answer_message->setHeaderFlag(Message::HEADERFLAG_CD);
         }
 
+        vector<QuestionPtr> questions;
+        questions.assign(query_message->beginQuestion(), query_message->endQuestion());
+        for_each(questions.begin(), questions.end(), QuestionInserter(answer_message));
+        
         // Now we can clear the buffer and render the new message into it
         buffer->clear();
         MessageRenderer renderer(*buffer);
 
+        ConstEDNSPtr edns(query_message->getEDNS());
+        const bool dnssec_ok = edns && edns->getDNSSECAwareness();
+        if (edns) {
+            EDNSPtr edns_response(new EDNS());
+            edns_response->setDNSSECAwareness(dnssec_ok);
+
+            // TODO: We should make our own edns bufsize length configurable
+            edns_response->setUDPSize(Message::DEFAULT_MAX_EDNS0_UDPSIZE);
+            answer_message->setEDNS(edns_response);
+        }
+        
         if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
-            ConstEDNSPtr edns(message->getEDNS());
-            renderer.setLengthLimit(edns ? edns->getUDPSize() :
-                Message::DEFAULT_MAX_UDPSIZE);
+            if (edns) {
+                renderer.setLengthLimit(edns->getUDPSize());
+            } else {
+                renderer.setLengthLimit(Message::DEFAULT_MAX_UDPSIZE);
+            }
         } else {
             renderer.setLengthLimit(65535);
         }
 
-        message->toWire(renderer);
+        answer_message->toWire(renderer);
 
         dlog(string("sending a response (") +
             boost::lexical_cast<string>(renderer.getLength()) + "bytes): \n" +
-            message->toText());
+            answer_message->toText());
     }
 };
 
@@ -347,18 +352,21 @@ Resolver::getConfigSession() const {
 }
 
 void
-Resolver::processMessage(const IOMessage& io_message, MessagePtr message,
-                        OutputBufferPtr buffer, DNSServer* server)
+Resolver::processMessage(const IOMessage& io_message,
+                         MessagePtr query_message,
+                         MessagePtr answer_message,
+                         OutputBufferPtr buffer,
+                         DNSServer* server)
 {
     dlog("Got a DNS message");
     InputBuffer request_buffer(io_message.getData(), io_message.getDataSize());
     // First, check the header part.  If we fail even for the base header,
     // just drop the message.
     try {
-        message->parseHeader(request_buffer);
+        query_message->parseHeader(request_buffer);
 
         // Ignore all responses.
-        if (message->getHeaderFlag(Message::HEADERFLAG_QR)) {
+        if (query_message->getHeaderFlag(Message::HEADERFLAG_QR)) {
             dlog("Received unexpected response, ignoring");
             server->resume(false);
             return;
@@ -371,52 +379,53 @@ Resolver::processMessage(const IOMessage& io_message, MessagePtr message,
 
     // Parse the message.  On failure, return an appropriate error.
     try {
-        message->fromWire(request_buffer);
+        query_message->fromWire(request_buffer);
     } catch (const DNSProtocolError& error) {
         dlog(string("returning ") + error.getRcode().toText() + ": " + 
             error.what());
-        makeErrorMessage(message, buffer, error.getRcode());
+        makeErrorMessage(query_message, buffer, error.getRcode());
         server->resume(true);
         return;
     } catch (const Exception& ex) {
         dlog(string("returning SERVFAIL: ") + ex.what());
-        makeErrorMessage(message, buffer, Rcode::SERVFAIL());
+        makeErrorMessage(query_message, buffer, Rcode::SERVFAIL());
         server->resume(true);
         return;
     } // other exceptions will be handled at a higher layer.
 
-    dlog("received a message:\n" + message->toText());
+    dlog("received a message:\n" + query_message->toText());
 
     // Perform further protocol-level validation.
     bool sendAnswer = true;
-    if (message->getOpcode() == Opcode::NOTIFY()) {
-        makeErrorMessage(message, buffer, Rcode::NOTAUTH());
+    if (query_message->getOpcode() == Opcode::NOTIFY()) {
+        makeErrorMessage(query_message, buffer, Rcode::NOTAUTH());
         dlog("Notify arrived, but we are not authoritative");
-    } else if (message->getOpcode() != Opcode::QUERY()) {
-        dlog("Unsupported opcode (got: " + message->getOpcode().toText() +
+    } else if (query_message->getOpcode() != Opcode::QUERY()) {
+        dlog("Unsupported opcode (got: " + query_message->getOpcode().toText() +
             ", expected: " + Opcode::QUERY().toText());
-        makeErrorMessage(message, buffer, Rcode::NOTIMP());
-    } else if (message->getRRCount(Message::SECTION_QUESTION) != 1) {
+        makeErrorMessage(query_message, buffer, Rcode::NOTIMP());
+    } else if (query_message->getRRCount(Message::SECTION_QUESTION) != 1) {
         dlog("The query contained " +
-            boost::lexical_cast<string>(message->getRRCount(
+            boost::lexical_cast<string>(query_message->getRRCount(
             Message::SECTION_QUESTION) + " questions, exactly one expected"));
-        makeErrorMessage(message, buffer, Rcode::FORMERR());
+        makeErrorMessage(query_message, buffer, Rcode::FORMERR());
     } else {
-        ConstQuestionPtr question = *message->beginQuestion();
+        ConstQuestionPtr question = *query_message->beginQuestion();
         const RRType &qtype = question->getType();
         if (qtype == RRType::AXFR()) {
             if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
-                makeErrorMessage(message, buffer, Rcode::FORMERR());
+                makeErrorMessage(query_message, buffer, Rcode::FORMERR());
             } else {
-                makeErrorMessage(message, buffer, Rcode::NOTIMP());
+                makeErrorMessage(query_message, buffer, Rcode::NOTIMP());
             }
         } else if (qtype == RRType::IXFR()) {
-            makeErrorMessage(message, buffer, Rcode::NOTIMP());
+            makeErrorMessage(query_message, buffer, Rcode::NOTIMP());
         } else {
             // The RecursiveQuery object will post the "resume" event to the
             // DNSServer when an answer arrives, so we don't have to do it now.
             sendAnswer = false;
-            impl_->processNormalQuery(*question, message, buffer, server);
+            impl_->processNormalQuery(*question, answer_message,
+                                      buffer, server);
         }
     }
 
@@ -426,23 +435,13 @@ Resolver::processMessage(const IOMessage& io_message, MessagePtr message,
 }
 
 void
-ResolverImpl::processNormalQuery(const Question& question, MessagePtr message,
-                                 OutputBufferPtr buffer, DNSServer* server)
+ResolverImpl::processNormalQuery(const Question& question,
+                                 MessagePtr answer_message,
+                                 OutputBufferPtr buffer,
+                                 DNSServer* server)
 {
     dlog("Processing normal query");
-    ConstEDNSPtr edns(message->getEDNS());
-    const bool dnssec_ok = edns && edns->getDNSSECAwareness();
-
-    message->makeResponse();
-    message->setHeaderFlag(Message::HEADERFLAG_RA);
-    message->setRcode(Rcode::NOERROR());
-    if (edns) {
-        EDNSPtr edns_response(new EDNS());
-        edns_response->setDNSSECAwareness(dnssec_ok);
-        edns_response->setUDPSize(ResolverImpl::DEFAULT_LOCAL_UDPSIZE);
-        message->setEDNS(edns_response);
-    }
-    rec_query_->sendQuery(question, buffer, server);
+    rec_query_->sendQuery(question, answer_message, buffer, server);
 }
 
 namespace {
@@ -477,7 +476,7 @@ parseAddresses(ConstElementPtr addresses) {
             }
         } else if (addresses->getType() != Element::null) {
             isc_throw(TypeError,
-                "forward_addresses config element must be a list");
+                "root_addresses, forward_addresses, and listen_on config element must be a list");
         }
     }
     return (result);
@@ -491,21 +490,41 @@ Resolver::updateConfig(ConstElementPtr config) {
 
     try {
         // Parse forward_addresses
+        ConstElementPtr rootAddressesE(config->get("root_addresses"));
+        vector<addr_t> rootAddresses(parseAddresses(rootAddressesE));
         ConstElementPtr forwardAddressesE(config->get("forward_addresses"));
         vector<addr_t> forwardAddresses(parseAddresses(forwardAddressesE));
         ConstElementPtr listenAddressesE(config->get("listen_on"));
         vector<addr_t> listenAddresses(parseAddresses(listenAddressesE));
         bool set_timeouts(false);
-        int timeout = impl_->timeout_;
+        int qtimeout = impl_->query_timeout_;
+        int ctimeout = impl_->client_timeout_;
+        int ltimeout = impl_->lookup_timeout_;
         unsigned retries = impl_->retries_;
-        ConstElementPtr timeoutE(config->get("timeout")),
-            retriesE(config->get("retries"));
-        if (timeoutE) {
+        ConstElementPtr qtimeoutE(config->get("timeout_query")),
+                        ctimeoutE(config->get("timeout_client")),
+                        ltimeoutE(config->get("timeout_lookup")),
+                        retriesE(config->get("retries"));
+        if (qtimeoutE) {
             // It should be safe to just get it, the config manager should
             // check for us
-            timeout = timeoutE->intValue();
-            if (timeout < -1) {
-                isc_throw(BadValue, "Timeout too small");
+            qtimeout = qtimeoutE->intValue();
+            if (qtimeout < -1) {
+                isc_throw(BadValue, "Query timeout too small");
+            }
+            set_timeouts = true;
+        }
+        if (ctimeoutE) {
+            ctimeout = ctimeoutE->intValue();
+            if (ctimeout < -1) {
+                isc_throw(BadValue, "Client timeout too small");
+            }
+            set_timeouts = true;
+        }
+        if (ltimeoutE) {
+            ltimeout = ltimeoutE->intValue();
+            if (ltimeout < -1) {
+                isc_throw(BadValue, "Lookup timeout too small");
             }
             set_timeouts = true;
         }
@@ -528,8 +547,12 @@ Resolver::updateConfig(ConstElementPtr config) {
             setForwardAddresses(forwardAddresses);
             need_query_restart = true;
         }
+        if (rootAddressesE) {
+            setRootAddresses(rootAddresses);
+            need_query_restart = true;
+        }
         if (set_timeouts) {
-            setTimeouts(timeout, retries);
+            setTimeouts(qtimeout, ctimeout, ltimeout, retries);
             need_query_restart = true;
         }
 
@@ -550,6 +573,12 @@ Resolver::setForwardAddresses(const vector<addr_t>& addresses)
     impl_->setForwardAddresses(addresses, dnss_);
 }
 
+void
+Resolver::setRootAddresses(const vector<addr_t>& addresses)
+{
+    impl_->setRootAddresses(addresses, dnss_);
+}
+
 bool
 Resolver::isForwarding() const {
     return (!impl_->upstream_.empty());
@@ -560,6 +589,11 @@ Resolver::getForwardAddresses() const {
     return (impl_->upstream_);
 }
 
+vector<addr_t>
+Resolver::getRootAddresses() const {
+    return (impl_->upstream_root_);
+}
+
 namespace {
 
 void
@@ -605,15 +639,36 @@ Resolver::setListenAddresses(const vector<addr_t>& addresses) {
 }
 
 void
-Resolver::setTimeouts(int timeout, unsigned retries) {
-    dlog("Setting timeout to " + boost::lexical_cast<string>(timeout) +
-        " and retry count to " + boost::lexical_cast<string>(retries));
-    impl_->timeout_ = timeout;
+Resolver::setTimeouts(int query_timeout, int client_timeout,
+                      int lookup_timeout, unsigned retries) {
+    dlog("Setting query timeout to " + boost::lexical_cast<string>(query_timeout) +
+         ", client timeout to " + boost::lexical_cast<string>(client_timeout) +
+         ", lookup timeout to " + boost::lexical_cast<string>(lookup_timeout) +
+         " and retry count to " + boost::lexical_cast<string>(retries));
+    impl_->query_timeout_ = query_timeout;
+    impl_->client_timeout_ = client_timeout;
+    impl_->lookup_timeout_ = lookup_timeout;
     impl_->retries_ = retries;
 }
-pair<int, unsigned>
-Resolver::getTimeouts() const {
-    return (pair<int, unsigned>(impl_->timeout_, impl_->retries_));
+
+int
+Resolver::getQueryTimeout() const {
+    return impl_->query_timeout_;
+}
+
+int
+Resolver::getClientTimeout() const {
+    return impl_->client_timeout_;
+}
+
+int
+Resolver::getLookupTimeout() const {
+    return impl_->lookup_timeout_;
+}
+
+int
+Resolver::getRetries() const {
+    return impl_->retries_;
 }
 
 vector<addr_t>
diff --git a/src/bin/resolver/resolver.h b/src/bin/resolver/resolver.h
index 606b1e4..5bce24d 100644
--- a/src/bin/resolver/resolver.h
+++ b/src/bin/resolver/resolver.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __RESOLVER_H
 #define __RESOLVER_H 1
 
@@ -65,7 +63,8 @@ public:
     /// \param buffer Pointer to an \c OutputBuffer for the resposne
     /// \param server Pointer to the \c DNSServer
     void processMessage(const asiolink::IOMessage& io_message,
-                        isc::dns::MessagePtr message,
+                        isc::dns::MessagePtr query_message,
+                        isc::dns::MessagePtr answer_message,
                         isc::dns::OutputBufferPtr buffer,
                         asiolink::DNSServer* server);
 
@@ -113,6 +112,24 @@ public:
     bool isForwarding() const;
 
     /**
+     * \brief Specify the list of root nameservers.
+     *
+     * Specify the list of addresses of root nameservers
+     *
+     * @param addresses The list of addresses to use (each one is the address
+     * and port pair).
+     */
+    void setRootAddresses(const std::vector<std::pair<std::string,
+                          uint16_t> >& addresses);
+
+    /**
+     * \short Get list of root addresses.
+     *
+     * \see setRootAddresses.
+     */
+    std::vector<std::pair<std::string, uint16_t> > getRootAddresses() const;
+
+    /**
      * Set and get the addresses we listen on.
      */
     void setListenAddresses(const std::vector<std::pair<std::string,
@@ -127,7 +144,10 @@ public:
      * \param retries The number of retries (0 means try the first time only,
      *     do not retry).
      */
-    void setTimeouts(int timeout = -1, unsigned retries = 0);
+    void setTimeouts(int query_timeout = 2000,
+                     int client_timeout = 4000,
+                     int lookup_timeout = 30000,
+                     unsigned retries = 3);
 
     /**
      * \short Get info about timeouts.
@@ -136,6 +156,39 @@ public:
      */
     std::pair<int, unsigned> getTimeouts() const;
 
+    /**
+     * \brief Get the timeout for outgoing queries
+     *
+     * \returns Timeout for outgoing queries
+     */
+    int getQueryTimeout() const;
+
+    /**
+     * \brief Get the timeout for incoming client queries
+     *
+     * After this timeout, a SERVFAIL shall be sent back
+     * (internal resolving on the query will continue, see
+     * \c getLookupTimeout())
+     * 
+     * \returns Timeout for outgoing queries
+     */
+    int getClientTimeout() const;
+
+    /**
+     * \brief Get the timeout for lookups
+     *
+     * After this timeout, internal processing shall stop
+     */
+    int getLookupTimeout() const;
+
+    /**
+     * \brief Get the number of retries for outgoing queries
+     *
+     * If a query times out (value of \c getQueryTimeout()), we
+     * will retry this number of times
+     */
+    int getRetries() const;
+
 private:
     ResolverImpl* impl_;
     asiolink::DNSService* dnss_;
diff --git a/src/bin/resolver/resolver.spec.pre.in b/src/bin/resolver/resolver.spec.pre.in
index 9e9f136..a249009 100644
--- a/src/bin/resolver/resolver.spec.pre.in
+++ b/src/bin/resolver/resolver.spec.pre.in
@@ -4,12 +4,24 @@
     "module_description": "Recursive service",
     "config_data": [
       {
-        "item_name": "timeout",
+        "item_name": "timeout_query",
         "item_type": "integer",
         "item_optional": False,
         "item_default": 2000
       },
       {
+        "item_name": "timeout_client",
+        "item_type": "integer",
+        "item_optional": False,
+        "item_default": 4000
+      },
+      {
+        "item_name": "timeout_lookup",
+        "item_type": "integer",
+        "item_optional": False,
+        "item_default": 30000
+      },
+      {
         "item_name": "retries",
         "item_type": "integer",
         "item_optional": False,
@@ -42,6 +54,32 @@
         }
       },
       {
+        "item_name": "root_addresses",
+        "item_type": "list",
+        "item_optional": True,
+        "item_default": [],
+        "list_item_spec" : {
+          "item_name": "address",
+          "item_type": "map",
+          "item_optional": False,
+          "item_default": {},
+          "map_item_spec": [
+            {
+              "item_name": "address",
+              "item_type": "string",
+              "item_optional": False,
+              "item_default": "::1"
+            },
+            {
+              "item_name": "port",
+              "item_type": "integer",
+              "item_optional": False,
+              "item_default": 53
+            }
+          ]
+        }
+      },
+      {
         "item_name": "listen_on",
         "item_type": "list",
         "item_optional": False,
diff --git a/src/bin/resolver/response_classifier.cc b/src/bin/resolver/response_classifier.cc
new file mode 100644
index 0000000..2d21407
--- /dev/null
+++ b/src/bin/resolver/response_classifier.cc
@@ -0,0 +1,259 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// $Id$
+
+#include <cstddef>
+#include <vector>
+
+#include <resolver/response_classifier.h>
+#include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
+#include <dns/rrset.h>
+
+using namespace isc::dns;
+using namespace std;
+
+// Classify the response in the "message" object.
+
+ResponseClassifier::Category ResponseClassifier::classify(
+    const Question& question, const MessagePtr& message, bool tcignore)
+{
+    // Check header bits
+    if (!message->getHeaderFlag(Message::HEADERFLAG_QR)) {
+        return (NOTRESPONSE);   // Query-response bit not set in the response
+    }
+
+    // We only recognise responses to queries here
+    if (message->getOpcode() != Opcode::QUERY()) {
+        return (OPCODE);
+    }
+
+    // Apparently have a response.  There must be a single question in it...
+    const vector<QuestionPtr> msgquestion(message->beginQuestion(),
+            message->endQuestion());
+    if (msgquestion.size() != 1) {
+        return (NOTONEQUEST); // Not one question in response question section
+    }
+
+    // ... and the question should be equal to the question given.
+    // XXX: This means that "question" may not be the question sent by the
+    // client.  In the case of a CNAME response, the qname of subsequent
+    // questions needs to be altered.
+    if (question != *(msgquestion[0])) {
+        return (MISMATQUEST);
+    }
+
+    // Check for Rcode-related errors.
+    const Rcode& rcode = message->getRcode();
+    if (rcode != Rcode::NOERROR()) {
+        if (rcode == Rcode::NXDOMAIN()) {
+
+            // No such domain.  According to RFC2308, the domain referred to by
+            // the QNAME does not exist, although there may be a CNAME in the
+            // answer section and there may be an SOA and/or NS RRs in the
+            // authority section (ignoring any DNSSEC RRs for now).
+            //
+            // Note the "may".  There may not be anything.  Also, note that if
+            // there is a CNAME in the answer section, the authoritative server
+            // has verified that the name given in the CNAME's RDATA field does
+            // not exist. And that if a CNAME is returned in the answer, then
+            // the QNAME of the RRs in the authority section will refer to the
+            // authority for the CNAME's RDATA and not to the original question.
+            //
+            // Without doing further classification, it is sufficient to say
+            // that if an NXDOMAIN is received, there was no translation of the
+            // QNAME available.
+            return (NXDOMAIN);  // Received NXDOMAIN from parent.
+
+        } else {
+
+            // Not NXDOMAIN but not NOERROR either.  Must be an RCODE-related
+            // error.
+            return (RCODE);
+        }
+    }
+
+    // All seems OK and we can start looking at the content.  However, one
+    // more header check remains - was the response truncated?  If so, we'll
+    // probably want to re-query over TCP.  However, in some circumstances we
+    // might want to go with what we have.  So give the caller the option of
+    // ignoring the TC bit.
+    if (message->getHeaderFlag(Message::HEADERFLAG_TC) && (!tcignore)) {
+        return (TRUNCATED);
+    }
+
+    // By the time we get here, we're assured that the packet format is correct.
+    // We now need to decide as to whether it is an answer, a CNAME, or a
+    // referral.  For this, we need to inspect the contents of the answer
+    // and authority sections.
+    const vector<RRsetPtr> answer(
+            message->beginSection(Message::SECTION_ANSWER),
+            message->endSection(Message::SECTION_ANSWER)
+            );
+    const vector<RRsetPtr> authority(
+            message->beginSection(Message::SECTION_AUTHORITY),
+            message->endSection(Message::SECTION_AUTHORITY)
+            );
+
+    // If there is nothing in the answer section, it is a referral - unless
+    // there is nothing in the authority section
+    if (answer.empty()) {
+        if (authority.empty()) {
+            return (EMPTY);
+        } else {
+            return (REFERRAL);
+        }
+    }
+
+    // Look at two cases - one RRset in the answer and multiple RRsets in
+    // the answer.
+    if (answer.size() == 1) {
+
+        // Does the name and class of the answer match that of the question?
+        if ((answer[0]->getName() == question.getName()) &&
+            (answer[0]->getClass() == question.getClass())) {
+
+            // It does.  How about the type of the response?  The response
+            // is an answer if the type matches that of the question, or if the
+            // question was for type ANY.  It is a CNAME reply if the answer
+            // type is CNAME.  And it is an error for anything else.
+            if ((answer[0]->getType() == question.getType()) ||
+                (question.getType() == RRType::ANY())) {
+                return (ANSWER);
+            } else if (answer[0]->getType() == RRType::CNAME()) {
+                return (CNAME);
+            } else {
+                return (INVTYPE);
+            }
+        }
+        else {
+
+            // Either the name and/or class of the reply don't match that of
+            // the question.
+            return (INVNAMCLASS);
+        }
+    }
+
+    // There are multiple RRsets in the answer. They should all have the same
+    // QCLASS, else there is some error in the response.
+    for (int i = 1; i < answer.size(); ++i) {
+        if (answer[0]->getClass() != answer[i]->getClass()) {
+            return (MULTICLASS);
+        }
+    }
+
+    // If the request type was ANY and they all have the same QNAME, we have
+    // an answer.  But if they don't have the same QNAME, we must have an error;
+    // the only way we could get different QNAMES in an answer is if one were a
+    // CNAME - in which case there should no other record types at that QNAME.
+    if (question.getType() == RRType::ANY()) {
+        bool all_same = true;
+        for (int i = 1; (i < answer.size()) && all_same; ++i) {
+            all_same = (answer[0]->getName() == answer[i]->getName());
+        }
+        if (all_same) {
+            return (ANSWER);
+        } else {
+            return (EXTRADATA);
+        }
+    }
+
+    // Multiple RRs in the answer, and not all the same QNAME.  This
+    // is either an answer, a CNAME (in either case, there could be multiple
+    // CNAMEs in the chain) or an error.
+    //
+    // So we need to follow the CNAME chain to resolve this.  For this to work:
+    //
+    // a) There must be one RR that matches the name, class and type of
+    //    the question, and this is a CNAME.
+    // b) The CNAME chain is followed until the end of the chain does not
+    //    exist (answer is a CNAME) or it is not of type CNAME (ANSWER).
+    //
+    // In the latter case, if there are additional RRs, it must be an error.
+
+    vector<RRsetPtr> ansrrset(answer);
+    vector<int> present(ansrrset.size(), 1);
+    return cnameChase(question.getName(), question.getType(), ansrrset, present,
+        ansrrset.size());
+}
+
+// Search the CNAME chain.
+ResponseClassifier::Category ResponseClassifier::cnameChase(
+    const Name& qname, const RRType& qtype, vector<RRsetPtr>& ansrrset,
+    vector<int>& present, size_t size)
+{
+    // Search through the vector of RRset pointers until we find one with the
+    // right QNAME.
+    for (int i = 0; i < ansrrset.size(); ++i) {
+        if (present[i]) {
+
+            // This entry has not been logically removed, so look at it.
+            if (ansrrset[i]->getName() == qname) {
+
+                // QNAME match.  If this RRset is a CNAME, remove it from
+                // further consideration.  If nothing is left, the end of the
+                // chain is a CNAME so this is a CNAME.  Otherwise replace
+                // the name with the RDATA of the CNAME and call ourself
+                // recursively.
+                if (ansrrset[i]->getType() == RRType::CNAME()) {
+
+                    // Don't consider it in the next iteration (although we
+                    // can still access it for now).
+                    present[i] = 0;
+                    --size;
+                    if (size == 0) {
+                        return (CNAME);
+                    }
+                    else {
+                        if (ansrrset[i]->getRdataCount() != 1) {
+
+                            // Multiple RDATA for a CNAME?  This is invalid.
+
+                            return (NOTSINGLE);
+                        }
+                        RdataIteratorPtr it = ansrrset[i]->getRdataIterator();
+                        Name newname(it->getCurrent().toText());
+
+                        return cnameChase(newname, qtype, ansrrset, present,
+                            size);
+                    }
+
+                } else {
+
+                    // We've got here because the element is not a CNAME.  If
+                    // this is the last element and the type is the one we are
+                    // after, we've found the answer, or it is an error.  If
+                    // there is more than one RRset left in the list we are
+                    // searching, we have extra data in the answer.
+                    if (ansrrset[i]->getType() == qtype) {
+                        if (size == 1) {
+                            return (ANSWERCNAME);
+                        } else {
+                            return (EXTRADATA);
+                        }
+                    }
+                    return (INVTYPE);
+                }
+            }
+        }
+    }
+
+    // We get here if we've dropped off the end of the list without finding the
+    // QNAME we are looking for.  This means that the CNAME chain has ended
+    // but there are additional RRsets in the data.
+
+    return (EXTRADATA);
+}
diff --git a/src/bin/resolver/response_classifier.h b/src/bin/resolver/response_classifier.h
new file mode 100644
index 0000000..394d60f
--- /dev/null
+++ b/src/bin/resolver/response_classifier.h
@@ -0,0 +1,138 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// $Id$
+
+#ifndef __RESPONSE_CLASSIFIER_H
+#define __RESPONSE_CLASSIFIER_H
+
+#include <cstddef>
+
+#include <dns/question.h>
+#include <dns/message.h>
+#include <dns/question.h>
+
+/// \brief Classify Server Response
+///
+/// This class is used in the recursive server.  It is passed an answer received
+/// from an upstream server and categorises it.
+///
+/// TODO: It is unlikely that the code can be used in this form.  Some adaption
+/// of it will be required to put it in the server.
+///
+/// TODO: The code here does not take into account any EDNS0 fields.
+
+class ResponseClassifier {
+public:
+
+    /// \brief Category of Answer
+    ///
+    /// In the valid answers, not the distinction between REFERRAL and CNAME.
+    /// A REFERRAL answer means that the answer section of the message is
+    /// empty, but there is something in the authority section.  A CNAME means
+    /// that the answer section contains one or more CNAMES in a chain that
+    /// do not end with a non-CNAME RRset.
+    enum Category {
+
+        // Codes indicating that a message is valid.
+
+        ANSWER,             ///< Response contains the answer
+        ANSWERCNAME,        ///< Response was a CNAME chain ending in an answer
+        CNAME,              ///< Response was a CNAME
+        NXDOMAIN,           ///< Response was an NXDOMAIN
+        REFERRAL,           ///< Response contains a referral
+
+        // Codes indicating that a message is invalid.  Note that the error()
+        // method relies on these appearing after the "message valid" codes.
+
+        EMPTY,              ///< No answer or authority sections
+        EXTRADATA,          ///< Answer section contains more RRsets than needed
+        INVNAMCLASS,        ///< Invalid name or class in answer
+        INVTYPE,            ///< Name/class of answer correct, type is wrong
+        MISMATQUEST,        ///< Response question section != question
+        MULTICLASS,         ///< Multiple classes in multi-RR answer
+        NOTONEQUEST,        ///< Not one question in response question section
+        NOTRESPONSE,        ///< Response has the Query/Response bit clear
+        NOTSINGLE,          ///< CNAME has multiple RDATA elements.
+        OPCODE,             ///< Opcode field does not indicate a query
+        RCODE,              ///< RCODE indicated an error
+        TRUNCATED           ///< Response was truncated
+    };
+
+    /// \brief Check Error
+    ///
+    /// An inline routine to quickly classify whether the return category is
+    /// an error or not.  This makes use of internal knowledge of the order of
+    /// codes in the Category enum.
+    ///
+    /// \param code Return category from classify()
+    ///
+    /// \return true if the category is an error, false if not.
+    static bool error(Category code) {
+        return (code > REFERRAL);
+    }
+
+    /// \brief Classify
+    ///
+    /// Classify the response in the "message" object.
+    ///
+    /// \param question Question that was sent to the server
+    /// \param message Pointer to the associated response from the server.
+    /// \param tcignore If set, the TC bit in a response packet is
+    /// ignored.  Otherwise the error code TRUNCATED will be returned.  The
+    /// only time this is likely to be used is in development where we are not
+    /// going to fail over to TCP and will want to use what is returned, even
+    /// if some of the response was lost.
+    static Category classify(const isc::dns::Question& question,
+            const isc::dns::MessagePtr& message, bool tcignore = false);
+
+private:
+    /// \brief Follow CNAMEs
+    ///
+    /// Given a QNAME and an answer section that contains CNAMEs, assume that
+    /// they form a CNAME chain and search through them.  Possible outcomes
+    /// are:
+    ///
+    /// a) All CNAMES and they form a chain.  The result is a referral.
+    /// b) All but one are CNAMES and they form a chain.  The other is pointed
+    ///    to by the last element of the chain and is the correct QTYPE.  The
+    ///    result is an answer.
+    /// c) Having followed the CNAME chain as far as we can, there is one
+    ///    remaining RRset that is of the wrong type, or there are multiple
+    ///    RRsets remaining.  return the EXTRADATA code.
+    ///
+    /// \param qname Question name we are searching for
+    /// \param qtype Question type we are search for.  (This is assumed not
+    /// to be "ANY".)
+    /// \param ansrrset Vector of RRsetPtr pointing to the RRsets we are
+    /// considering.
+    /// \param present Array of "int" the same size of ansrrset, with each
+    /// element set to "1" to allow the corresponding element of ansrrset to
+    /// be checked, and "0" to skip it.  This might be premature optimisation,
+    /// but the algorithm would otherwise involve duplicating the RRset
+    /// vector then removing elements from random positions one by one.  As
+    /// each removal involves the destruction of an "xxxPtr" element (which
+    /// presently is implemented by boost::shared_ptr), the overhad of memory
+    /// management seemed high.  This solution imposes some additional loop
+    /// cycles, but that should be minimal compared with the overhead of the
+    /// memory management.
+    /// \param size Number of elements to check.  See description of \c present
+    /// for details.
+    static Category cnameChase(const isc::dns::Name& qname,
+        const isc::dns::RRType& qtype,
+        std::vector<isc::dns::RRsetPtr>& ansrrset, std::vector<int>& present,
+        size_t size);
+};
+
+#endif // __RESPONSE_CLASSIFIER_H
diff --git a/src/bin/resolver/tests/Makefile.am b/src/bin/resolver/tests/Makefile.am
index 405a44f..8552439 100644
--- a/src/bin/resolver/tests/Makefile.am
+++ b/src/bin/resolver/tests/Makefile.am
@@ -20,8 +20,10 @@ TESTS += run_unittests
 run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
 run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
 run_unittests_SOURCES += ../resolver.h ../resolver.cc
+run_unittests_SOURCES += ../response_classifier.h ../response_classifier.cc
 run_unittests_SOURCES += resolver_unittest.cc
 run_unittests_SOURCES += resolver_config_unittest.cc
+run_unittests_SOURCES += response_classifier_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
diff --git a/src/bin/resolver/tests/resolver_config_unittest.cc b/src/bin/resolver/tests/resolver_config_unittest.cc
index 9d5940c..916396a 100644
--- a/src/bin/resolver/tests/resolver_config_unittest.cc
+++ b/src/bin/resolver/tests/resolver_config_unittest.cc
@@ -96,6 +96,31 @@ TEST_F(ResolverConfig, forwardAddressConfig) {
     EXPECT_EQ(0, server.getForwardAddresses().size());
 }
 
+TEST_F(ResolverConfig, rootAddressConfig) {
+    // Try putting there some address
+    ElementPtr config(Element::fromJSON("{"
+        "\"root_addresses\": ["
+        "   {"
+        "       \"address\": \"192.0.2.1\","
+        "       \"port\": 53"
+        "   }"
+        "]"
+        "}"));
+    ConstElementPtr result(server.updateConfig(config));
+    EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
+    ASSERT_EQ(1, server.getRootAddresses().size());
+    EXPECT_EQ("192.0.2.1", server.getRootAddresses()[0].first);
+    EXPECT_EQ(53, server.getRootAddresses()[0].second);
+
+    // And then remove all addresses
+    config = Element::fromJSON("{"
+        "\"root_addresses\": null"
+        "}");
+    result = server.updateConfig(config);
+    EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
+    EXPECT_EQ(0, server.getRootAddresses().size());
+}
+
 void
 ResolverConfig::invalidTest(const string &JOSN) {
     ElementPtr config(Element::fromJSON(JOSN));
@@ -134,8 +159,8 @@ TEST_F(ResolverConfig, listenAddresses) {
 
     // Try putting there some addresses
     vector<pair<string, uint16_t> > addresses;
-    addresses.push_back(pair<string, uint16_t>("127.0.0.1", 5300));
-    addresses.push_back(pair<string, uint16_t>("::1", 5300));
+    addresses.push_back(pair<string, uint16_t>("127.0.0.1", 5321));
+    addresses.push_back(pair<string, uint16_t>("::1", 5321));
     server.setListenAddresses(addresses);
     EXPECT_EQ(2, server.getListenAddresses().size());
     EXPECT_EQ("::1", server.getListenAddresses()[1].first);
@@ -155,7 +180,7 @@ TEST_F(ResolverConfig, DISABLED_listenAddressConfig) {
         "\"listen_on\": ["
         "   {"
         "       \"address\": \"127.0.0.1\","
-        "       \"port\": 5300"
+        "       \"port\": 5321"
         "   }"
         "]"
         "}"));
@@ -163,7 +188,7 @@ TEST_F(ResolverConfig, DISABLED_listenAddressConfig) {
     EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
     ASSERT_EQ(1, server.getListenAddresses().size());
     EXPECT_EQ("127.0.0.1", server.getListenAddresses()[0].first);
-    EXPECT_EQ(5300, server.getListenAddresses()[0].second);
+    EXPECT_EQ(5321, server.getListenAddresses()[0].second);
 
     // As this is example address, the machine should not have it on
     // any interface
@@ -174,7 +199,7 @@ TEST_F(ResolverConfig, DISABLED_listenAddressConfig) {
         "\"listen_on\": ["
         "   {"
         "       \"address\": \"192.0.2.0\","
-        "       \"port\": 5300"
+        "       \"port\": 5321"
         "   }"
         "]"
         "}");
@@ -182,7 +207,7 @@ TEST_F(ResolverConfig, DISABLED_listenAddressConfig) {
     EXPECT_FALSE(result->equals(*isc::config::createAnswer()));
     ASSERT_EQ(1, server.getListenAddresses().size());
     EXPECT_EQ("127.0.0.1", server.getListenAddresses()[0].first);
-    EXPECT_EQ(5300, server.getListenAddresses()[0].second);
+    EXPECT_EQ(5321, server.getListenAddresses()[0].second);
 }
 
 TEST_F(ResolverConfig, invalidListenAddresses) {
@@ -212,31 +237,51 @@ TEST_F(ResolverConfig, invalidListenAddresses) {
 
 // Just test it sets and gets the values correctly
 TEST_F(ResolverConfig, timeouts) {
-    server.setTimeouts(0, 1);
-    EXPECT_EQ(0, server.getTimeouts().first);
-    EXPECT_EQ(1, server.getTimeouts().second);
+    server.setTimeouts(0, 1, 2, 3);
+    EXPECT_EQ(0, server.getQueryTimeout());
+    EXPECT_EQ(1, server.getClientTimeout());
+    EXPECT_EQ(2, server.getLookupTimeout());
+    EXPECT_EQ(3, server.getRetries());
     server.setTimeouts();
-    EXPECT_EQ(-1, server.getTimeouts().first);
-    EXPECT_EQ(0, server.getTimeouts().second);
+    EXPECT_EQ(2000, server.getQueryTimeout());
+    EXPECT_EQ(4000, server.getClientTimeout());
+    EXPECT_EQ(30000, server.getLookupTimeout());
+    EXPECT_EQ(3, server.getRetries());
 }
 
 TEST_F(ResolverConfig, timeoutsConfig) {
     ElementPtr config = Element::fromJSON("{"
-            "\"timeout\": 1000,"
-            "\"retries\": 3"
+            "\"timeout_query\": 1000,"
+            "\"timeout_client\": 2000,"
+            "\"timeout_lookup\": 3000,"
+            "\"retries\": 4"
             "}");
     ConstElementPtr result(server.updateConfig(config));
     EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
-    EXPECT_EQ(1000, server.getTimeouts().first);
-    EXPECT_EQ(3, server.getTimeouts().second);
+    EXPECT_EQ(1000, server.getQueryTimeout());
+    EXPECT_EQ(2000, server.getClientTimeout());
+    EXPECT_EQ(3000, server.getLookupTimeout());
+    EXPECT_EQ(4, server.getRetries());
 }
 
 TEST_F(ResolverConfig, invalidTimeoutsConfig) {
     invalidTest("{"
-        "\"timeout\": \"error\""
+        "\"timeout_query\": \"error\""
+        "}");
+    invalidTest("{"
+        "\"timeout_query\": -2"
+        "}");
+    invalidTest("{"
+        "\"timeout_client\": \"error\""
+        "}");
+    invalidTest("{"
+        "\"timeout_client\": -2"
+        "}");
+    invalidTest("{"
+        "\"timeout_lookup\": \"error\""
         "}");
     invalidTest("{"
-        "\"timeout\": -2"
+        "\"timeout_lookup\": -2"
         "}");
     invalidTest("{"
         "\"retries\": \"error\""
diff --git a/src/bin/resolver/tests/resolver_unittest.cc b/src/bin/resolver/tests/resolver_unittest.cc
index 240c9d7..a4f11f5 100644
--- a/src/bin/resolver/tests/resolver_unittest.cc
+++ b/src/bin/resolver/tests/resolver_unittest.cc
@@ -16,6 +16,7 @@
 
 #include <resolver/resolver.h>
 #include <dns/tests/unittest_util.h>
+#include <testutils/dnsmessage_test.h>
 #include <testutils/srv_test.h>
 
 using namespace isc::dns;
@@ -29,7 +30,10 @@ class ResolverTest : public SrvTestBase{
 protected:
     ResolverTest() : server(){}
     virtual void processMessage() {
-        server.processMessage(*io_message, parse_message, response_obuffer,
+        server.processMessage(*io_message,
+                              parse_message,
+                              response_message,
+                              response_obuffer,
                               &dnsserv);
     }
     Resolver server;
@@ -82,7 +86,11 @@ TEST_F(ResolverTest, AXFRFail) {
                                        RRType::AXFR());
     createRequestPacket(request_message, IPPROTO_TCP);
     // AXFR is not implemented and should always send NOTIMP.
-    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+    server.processMessage(*io_message,
+                          parse_message,
+                          response_message,
+                          response_obuffer,
+                          &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::NOTIMP(), opcode.getCode(),
                 QR_FLAG, 1, 0, 0, 0);
@@ -97,7 +105,11 @@ TEST_F(ResolverTest, notifyFail) {
     request_message.setQid(default_qid);
     request_message.setHeaderFlag(Message::HEADERFLAG_AA);
     createRequestPacket(request_message, IPPROTO_UDP);
-    server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+    server.processMessage(*io_message,
+                          parse_message,
+                          response_message,
+                          response_obuffer,
+                          &dnsserv);
     EXPECT_TRUE(dnsserv.hasAnswer());
     headerCheck(*parse_message, default_qid, Rcode::NOTAUTH(),
                 Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
diff --git a/src/bin/resolver/tests/response_classifier_unittest.cc b/src/bin/resolver/tests/response_classifier_unittest.cc
new file mode 100644
index 0000000..ee439b1
--- /dev/null
+++ b/src/bin/resolver/tests/response_classifier_unittest.cc
@@ -0,0 +1,494 @@
+// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <iostream>
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+
+#include <resolver/response_classifier.h>
+
+#include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/question.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rcode.h>
+#include <dns/rrclass.h>
+#include <dns/rrset.h>
+#include <dns/rrtype.h>
+#include <dns/rrttl.h>
+
+using namespace std;
+using namespace isc::dns;
+using namespace rdata;
+using namespace isc::dns::rdata::generic;
+using namespace isc::dns::rdata::in;
+
+namespace {
+class ResponseClassifierTest : public ::testing::Test {
+public:
+    /// \brief Constructor
+    ///
+    /// The naming convention is:
+    ///
+    /// <category>_<class>_<type>_<name>
+    ///
+    /// <category> is "qu" (question), "rrs" (rrset),
+    /// <qclass> is self-explanatory
+    /// <qtype> is self-explanatory
+    /// <name> is the first part of the domain name (all expected to be in
+    /// example.com)
+    ///
+    /// Message variables
+    ///
+    /// msg_<qtype>  Where <qtype> is the type of query.  These are only used
+    /// in the early tests where simple messages are required.
+
+    ResponseClassifierTest() :
+        msg_a(new Message(Message::RENDER)),
+        msg_any(new Message(Message::RENDER)),
+        qu_ch_a_www(Name("www.example.com"), RRClass::CH(), RRType::A()),
+        qu_in_any_www(Name("www.example.com"), RRClass::IN(), RRType::ANY()),
+        qu_in_a_www2(Name("www2.example.com"), RRClass::IN(), RRType::A()),
+        qu_in_a_www(Name("www.example.com"), RRClass::IN(), RRType::A()),
+        qu_in_cname_www1(Name("www1.example.com"), RRClass::IN(), RRType::A()),
+        qu_in_ns_(Name("example.com"), RRClass::IN(), RRType::NS()),
+        qu_in_txt_www(Name("www.example.com"), RRClass::IN(), RRType::TXT()),
+        rrs_hs_txt_www(new RRset(Name("www.example.com"), RRClass::HS(),
+            RRType::TXT(), RRTTL(300))),
+        rrs_in_a_mail(new RRset(Name("mail.example.com"), RRClass::IN(),
+            RRType::A(), RRTTL(300))),
+        rrs_in_a_www(new RRset(Name("www.example.com"), RRClass::IN(),
+            RRType::A(), RRTTL(300))),
+        rrs_in_cname_www1(new RRset(Name("www1.example.com"), RRClass::IN(),
+            RRType::CNAME(), RRTTL(300))),
+        rrs_in_cname_www2(new RRset(Name("www2.example.com"), RRClass::IN(),
+            RRType::CNAME(), RRTTL(300))),
+        rrs_in_ns_(new RRset(Name("example.com"), RRClass::IN(),
+            RRType::NS(), RRTTL(300))),
+        rrs_in_txt_www(new RRset(Name("www.example.com"), RRClass::IN(),
+            RRType::TXT(), RRTTL(300)))
+    {
+        // Set up the message to indicate a successful response to the question
+        // "www.example.com A", but don't add in any response sections.
+        msg_a->setHeaderFlag(Message::HEADERFLAG_QR);
+        msg_a->setOpcode(Opcode::QUERY());
+        msg_a->setRcode(Rcode::NOERROR());
+        msg_a->addQuestion(qu_in_a_www);
+
+        // ditto for the query "www.example.com ANY"
+        msg_any->setHeaderFlag(Message::HEADERFLAG_QR);
+        msg_any->setOpcode(Opcode::QUERY());
+        msg_any->setRcode(Rcode::NOERROR());
+        msg_any->addQuestion(qu_in_any_www);
+
+        // The next set of assignments set up the following zone records
+        //
+        // example.com           NS     ns0.isc.org
+        //                       NS     ns0.example.org
+        //
+        // www.example.com       A      1.2.3.4
+        //                       TXT    "An example text string"
+        //
+        // mail.example.com      A      4.5.6.7
+        //
+        // www1.example.com      CNAME  www.example.com
+        //
+        // www2.example.com      CNAME  www1.example.com
+
+        // Set up an imaginary NS RRset for an authority section
+        rrs_in_ns_->addRdata(ConstRdataPtr(new NS(Name("ns0.isc.org"))));
+        rrs_in_ns_->addRdata(ConstRdataPtr(new NS(Name("ns0.example.org"))));
+
+        // Set up the records for the www host
+        rrs_in_a_www->addRdata(ConstRdataPtr(new A("1.2.3.4")));
+        rrs_in_txt_www->addRdata(ConstRdataPtr(
+            new TXT("An example text string")));
+
+        // ... for the mail host
+        rrs_in_a_mail->addRdata(ConstRdataPtr(new A("5.6.7.8")));
+
+        // ... the CNAME records
+        rrs_in_cname_www1->addRdata(ConstRdataPtr(
+            new CNAME("www.example.com")));
+        rrs_in_cname_www2->addRdata(ConstRdataPtr(
+            new CNAME("www1.example.com")));
+    }
+
+    MessagePtr  msg_a;              // Pointer to message in RENDER state
+    MessagePtr  msg_any;            // Pointer to message in RENDER state
+    Question    qu_ch_a_www;        // www.example.com CH A
+    Question    qu_in_any_www;      // www.example.com IN ANY
+    Question    qu_in_a_www2;       // www.example.com IN ANY
+    Question    qu_in_a_www;        // www.example.com IN A
+    Question    qu_in_cname_www1;   // www1.example.com IN CNAME
+    Question    qu_in_ns_;          // example.com IN NS
+    Question    qu_in_txt_www;      // www.example.com IN TXT
+    RRsetPtr    rrs_hs_txt_www;     // www.example.com HS TXT
+    RRsetPtr    rrs_in_a_mail;      // mail.example.com IN A
+    RRsetPtr    rrs_in_a_www;       // www.example.com IN A
+    RRsetPtr    rrs_in_cname_www1;  // www1.example.com IN CNAME
+    RRsetPtr    rrs_in_cname_www2;  // www2.example.com IN CNAME
+    RRsetPtr    rrs_in_ns_;         // example.com IN NS
+    RRsetPtr    rrs_in_txt_www;     // www.example.com IN TXT
+};
+
+// Test that the error() function categorises the codes correctly.
+
+TEST_F(ResponseClassifierTest, StatusCodes) {
+    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::ANSWER));
+    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::ANSWERCNAME));
+    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::CNAME));
+    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::NXDOMAIN));
+    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::REFERRAL));
+
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::EMPTY));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::EXTRADATA));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::INVNAMCLASS));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::INVTYPE));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::MISMATQUEST));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::MULTICLASS));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::NOTONEQUEST));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::NOTRESPONSE));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::NOTSINGLE));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::OPCODE));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::RCODE));
+    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::TRUNCATED));
+}
+
+// Test that the system will reject a message which is a query.
+
+TEST_F(ResponseClassifierTest, Query) {
+
+    // Set up message to indicate a query (QR flag = 0, one question).  By
+    // default the opcode will be 0 (query)
+    msg_a->setHeaderFlag(Message::HEADERFLAG_QR, false);
+
+    // Should be rejected as it is a query, not a response
+    EXPECT_EQ(ResponseClassifier::NOTRESPONSE,
+        ResponseClassifier::classify(qu_in_a_www, msg_a));
+}
+
+// Check that we get an OPCODE error on all but QUERY opcodes.
+
+TEST_F(ResponseClassifierTest, Opcode) {
+
+    uint8_t query = static_cast<uint8_t>(Opcode::QUERY().getCode());
+
+    for (uint8_t i = 0; i < (1 << 4); ++i) {
+        msg_a->setOpcode(Opcode(i));
+        if (i == query) {
+            EXPECT_NE(ResponseClassifier::OPCODE,
+                ResponseClassifier::classify(qu_in_a_www, msg_a));
+        } else {
+            EXPECT_EQ(ResponseClassifier::OPCODE,
+                ResponseClassifier::classify(qu_in_a_www, msg_a));
+        }
+    }
+}
+
+// Test that the system will reject a response with anything other than one
+// question.
+
+TEST_F(ResponseClassifierTest, MultipleQuestions) {
+
+    // Create a message object for this test that has no question section.
+    MessagePtr message(new Message(Message::RENDER));
+    message->setHeaderFlag(Message::HEADERFLAG_QR);
+    message->setOpcode(Opcode::QUERY());
+    message->setRcode(Rcode::NOERROR());
+
+    // Zero questions
+    EXPECT_EQ(ResponseClassifier::NOTONEQUEST,
+        ResponseClassifier::classify(qu_in_a_www, message));
+
+    // One question
+    message->addQuestion(qu_in_a_www);
+    EXPECT_NE(ResponseClassifier::NOTONEQUEST,
+        ResponseClassifier::classify(qu_in_a_www, message));
+
+    // Two questions
+    message->addQuestion(qu_in_ns_);
+    EXPECT_EQ(ResponseClassifier::NOTONEQUEST,
+        ResponseClassifier::classify(qu_in_a_www, message));
+
+    // And finish the check with three questions
+    message->addQuestion(qu_in_txt_www);
+    EXPECT_EQ(ResponseClassifier::NOTONEQUEST,
+        ResponseClassifier::classify(qu_in_a_www, message));
+}
+
+// Test that the question in the question section in the message response
+// is equal to the question supplied.
+
+TEST_F(ResponseClassifierTest, SameQuestion) {
+
+    EXPECT_EQ(ResponseClassifier::MISMATQUEST,
+        ResponseClassifier::classify(qu_in_ns_, msg_a));
+    EXPECT_NE(ResponseClassifier::MISMATQUEST,
+        ResponseClassifier::classify(qu_in_a_www, msg_a));
+}
+
+// Should get an NXDOMAIN response only on an NXDOMAIN RCODE.
+
+TEST_F(ResponseClassifierTest, NXDOMAIN) {
+
+    uint16_t nxdomain = static_cast<uint16_t>(Rcode::NXDOMAIN().getCode());
+
+    for (uint8_t i = 0; i < (1 << 4); ++i) {
+        msg_a->setRcode(Rcode(i));
+        if (i == nxdomain) {
+            EXPECT_EQ(ResponseClassifier::NXDOMAIN,
+                ResponseClassifier::classify(qu_in_a_www, msg_a));
+        } else {
+            EXPECT_NE(ResponseClassifier::NXDOMAIN,
+                ResponseClassifier::classify(qu_in_a_www, msg_a));
+        }
+    }
+}
+
+// Check that we get an RCODE error on all but NXDOMAIN and NOERROR responses.
+
+TEST_F(ResponseClassifierTest, RCODE) {
+
+    uint16_t nxdomain = static_cast<uint16_t>(Rcode::NXDOMAIN().getCode());
+    uint16_t noerror = static_cast<uint16_t>(Rcode::NOERROR().getCode());
+
+    for (uint8_t i = 0; i < (1 << 4); ++i) {
+        msg_a->setRcode(Rcode(i));
+        if ((i == nxdomain) || (i == noerror)) {
+            EXPECT_NE(ResponseClassifier::RCODE,
+                ResponseClassifier::classify(qu_in_a_www, msg_a));
+        } else {
+            EXPECT_EQ(ResponseClassifier::RCODE,
+                ResponseClassifier::classify(qu_in_a_www, msg_a));
+        }
+    }
+}
+
+// Test that the code will detect a truncated message.  Even if nothing else
+// is wrong, we'll want to retry the query if we receive a truncated code.
+// However, we give the option to the user of the code aws to whether they
+// want to take into account the truncated bit.
+
+TEST_F(ResponseClassifierTest, Truncated) {
+
+    // Don't expect the truncated code whatever option we ask for if the TC
+    // bit is not set.
+    msg_a->setHeaderFlag(Message::HEADERFLAG_TC, false);
+    EXPECT_NE(ResponseClassifier::TRUNCATED,
+        ResponseClassifier::classify(qu_in_a_www, msg_a, true));
+    EXPECT_NE(ResponseClassifier::TRUNCATED,
+        ResponseClassifier::classify(qu_in_a_www, msg_a, false));
+
+    // Expect the truncated code if the TC bit is set, only if we don't ignore
+    // it.
+    msg_a->setHeaderFlag(Message::HEADERFLAG_TC, true);
+    EXPECT_NE(ResponseClassifier::TRUNCATED,
+        ResponseClassifier::classify(qu_in_a_www, msg_a, true));
+    EXPECT_EQ(ResponseClassifier::TRUNCATED,
+        ResponseClassifier::classify(qu_in_a_www, msg_a, false));
+}
+
+// Check for an empty packet (i.e. no error, but with the answer and additional
+// sections empty).
+
+TEST_F(ResponseClassifierTest, Empty) {
+
+    EXPECT_EQ(ResponseClassifier::EMPTY,
+        ResponseClassifier::classify(qu_in_a_www, msg_a));
+}
+
+// Anything where we have an empty answer section but something in the
+// authority section is a referral (if the status is NOERROR).
+
+TEST_F(ResponseClassifierTest, EmptyAnswerReferral) {
+
+    msg_a->addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_);
+    EXPECT_EQ(ResponseClassifier::REFERRAL,
+        ResponseClassifier::classify(qu_in_a_www, msg_a));
+
+}
+
+// Check the case where we have a simple answer in the answer section.  This
+// occurs when the QNAME/QTYPE/QCLASS matches one of the RRsets in the
+// answer section - expect when the QTYPE is ANY, in which case the match
+// must be on the QNAME/QCLASS alone.
+
+TEST_F(ResponseClassifierTest, SingleAnswer) {
+
+    // Check a question that matches the answer
+    msg_a->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    EXPECT_EQ(ResponseClassifier::ANSWER,
+        ResponseClassifier::classify(qu_in_a_www, msg_a));
+
+    // Check an ANY question that matches the answer
+    msg_any->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    EXPECT_EQ(ResponseClassifier::ANSWER,
+        ResponseClassifier::classify(qu_in_any_www, msg_any));
+
+    // Check a CNAME response that matches the QNAME.
+    MessagePtr message_a(new Message(Message::RENDER));
+    message_a->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_a->setOpcode(Opcode::QUERY());
+    message_a->setRcode(Rcode::NOERROR());
+    message_a->addQuestion(qu_in_cname_www1);
+    message_a->addRRset(Message::SECTION_ANSWER, rrs_in_cname_www1);
+    EXPECT_EQ(ResponseClassifier::CNAME,
+        ResponseClassifier::classify(qu_in_cname_www1, message_a));
+
+    // Check if the answer QNAME does not match the question
+    // Q: www.example.com  IN A
+    // A: mail.example.com IN A
+    MessagePtr message_b(new Message(Message::RENDER));
+    message_b->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_b->setOpcode(Opcode::QUERY());
+    message_b->setRcode(Rcode::NOERROR());
+    message_b->addQuestion(qu_in_a_www);
+    message_b->addRRset(Message::SECTION_ANSWER, rrs_in_a_mail);
+    EXPECT_EQ(ResponseClassifier::INVNAMCLASS,
+        ResponseClassifier::classify(qu_in_a_www, message_b));
+
+    // Check if the answer class does not match the question
+    // Q: www.example.com CH A
+    // A: www.example.com IN A
+    MessagePtr message_c(new Message(Message::RENDER));
+    message_c->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_c->setOpcode(Opcode::QUERY());
+    message_c->setRcode(Rcode::NOERROR());
+    message_c->addQuestion(qu_ch_a_www);
+    message_c->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    EXPECT_EQ(ResponseClassifier::INVNAMCLASS,
+        ResponseClassifier::classify(qu_ch_a_www, message_c));
+
+    // Check if the answer type does not match the question
+    // Q: www.example.com IN A
+    // A: www.example.com IN TXT
+    MessagePtr message_d(new Message(Message::RENDER));
+    message_d->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_d->setOpcode(Opcode::QUERY());
+    message_d->setRcode(Rcode::NOERROR());
+    message_d->addQuestion(qu_in_a_www);
+    message_d->addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
+    EXPECT_EQ(ResponseClassifier::INVTYPE,
+        ResponseClassifier::classify(qu_in_a_www, message_d));
+}
+
+// Check what happens if we have multiple RRsets in the answer.
+
+TEST_F(ResponseClassifierTest, MultipleAnswerRRsets) {
+
+    // All the same QNAME but different types is only valid on an ANY query.
+    MessagePtr message_a(new Message(Message::RENDER));
+    message_a->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_a->setOpcode(Opcode::QUERY());
+    message_a->setRcode(Rcode::NOERROR());
+    message_a->addQuestion(qu_in_any_www);
+    message_a->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    message_a->addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
+    EXPECT_EQ(ResponseClassifier::ANSWER,
+        ResponseClassifier::classify(qu_in_any_www, message_a));
+
+    // On another type of query, it results in an EXTRADATA error
+    MessagePtr message_b(new Message(Message::RENDER));
+    message_b->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_b->setOpcode(Opcode::QUERY());
+    message_b->setRcode(Rcode::NOERROR());
+    message_b->addQuestion(qu_in_a_www);
+    message_b->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    message_b->addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
+    EXPECT_EQ(ResponseClassifier::EXTRADATA,
+        ResponseClassifier::classify(qu_in_a_www, message_b));
+
+    // Same QNAME on an ANY query is not valid with mixed classes
+    MessagePtr message_c(new Message(Message::RENDER));
+    message_c->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_c->setOpcode(Opcode::QUERY());
+    message_c->setRcode(Rcode::NOERROR());
+    message_c->addQuestion(qu_in_any_www);
+    message_c->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    message_c->addRRset(Message::SECTION_ANSWER, rrs_hs_txt_www);
+    EXPECT_EQ(ResponseClassifier::MULTICLASS,
+        ResponseClassifier::classify(qu_in_any_www, message_c));
+
+    // Mixed QNAME is not valid unless QNAME requested is a CNAME.
+    MessagePtr message_d(new Message(Message::RENDER));
+    message_d->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_d->setOpcode(Opcode::QUERY());
+    message_d->setRcode(Rcode::NOERROR());
+    message_d->addQuestion(qu_in_a_www);
+    message_d->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    message_d->addRRset(Message::SECTION_ANSWER, rrs_in_a_mail);
+    EXPECT_EQ(ResponseClassifier::EXTRADATA,
+        ResponseClassifier::classify(qu_in_a_www, message_d));
+
+    // Mixed QNAME is not valid when the query is an ANY.
+    MessagePtr message_e(new Message(Message::RENDER));
+    message_e->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_e->setOpcode(Opcode::QUERY());
+    message_e->setRcode(Rcode::NOERROR());
+    message_e->addQuestion(qu_in_any_www);
+    message_e->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    message_e->addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
+    message_e->addRRset(Message::SECTION_ANSWER, rrs_in_a_mail);
+    EXPECT_EQ(ResponseClassifier::EXTRADATA,
+        ResponseClassifier::classify(qu_in_any_www, message_e));
+}
+
+// CNAME chain is CNAME if it terminates in a CNAME, answer if it
+// does not, and error if there are RRs left over.
+TEST_F(ResponseClassifierTest, CNAMEChain) {
+
+    // Answer contains a single CNAME
+    MessagePtr message_a(new Message(Message::RENDER));
+    message_a->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_a->setOpcode(Opcode::QUERY());
+    message_a->setRcode(Rcode::NOERROR());
+    message_a->addQuestion(qu_in_a_www2);
+    message_a->addRRset(Message::SECTION_ANSWER, rrs_in_cname_www2);
+    EXPECT_EQ(ResponseClassifier::CNAME,
+        ResponseClassifier::classify(qu_in_a_www2, message_a));
+
+    // Add a CNAME for www1, and it should still return a CNAME
+    message_a->addRRset(Message::SECTION_ANSWER, rrs_in_cname_www1);
+    EXPECT_EQ(ResponseClassifier::CNAME,
+        ResponseClassifier::classify(qu_in_a_www2, message_a));
+
+    // Add the A record for www and it should be an answer
+    message_a->addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
+    EXPECT_EQ(ResponseClassifier::ANSWERCNAME,
+        ResponseClassifier::classify(qu_in_a_www2, message_a));
+
+    // Adding an unrelated TXT record should result in EXTRADATA
+    message_a->addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
+    EXPECT_EQ(ResponseClassifier::EXTRADATA,
+        ResponseClassifier::classify(qu_in_a_www2, message_a));
+
+    // Recreate the chain, but this time end with a TXT RR and not the A
+    // record.  This should return INVTYPE.
+    MessagePtr message_b(new Message(Message::RENDER));
+    message_b->setHeaderFlag(Message::HEADERFLAG_QR);
+    message_b->setOpcode(Opcode::QUERY());
+    message_b->setRcode(Rcode::NOERROR());
+    message_b->addQuestion(qu_in_a_www2);
+    message_b->addRRset(Message::SECTION_ANSWER, rrs_in_cname_www2);
+    message_b->addRRset(Message::SECTION_ANSWER, rrs_in_cname_www1);
+    message_b->addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
+
+    EXPECT_EQ(ResponseClassifier::INVTYPE,
+        ResponseClassifier::classify(qu_in_a_www2, message_b));
+}
+
+} // Anonymous namespace
diff --git a/src/bin/stats/b10-stats.xml b/src/bin/stats/b10-stats.xml
index fb82ecd..62051df 100644
--- a/src/bin/stats/b10-stats.xml
+++ b/src/bin/stats/b10-stats.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/stats/stats.py.in b/src/bin/stats/stats.py.in
old mode 100644
new mode 100755
index 2d5ff36..15e2980
--- a/src/bin/stats/stats.py.in
+++ b/src/bin/stats/stats.py.in
@@ -15,7 +15,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
 __version__ = "$Revision$"
 
 import sys; sys.path.append ('@@PYTHONPATH@@')
diff --git a/src/bin/stats/stats_stub.py.in b/src/bin/stats/stats_stub.py.in
old mode 100644
new mode 100755
index fe63916..4a4a641
--- a/src/bin/stats/stats_stub.py.in
+++ b/src/bin/stats/stats_stub.py.in
@@ -15,7 +15,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
 __version__ = "$Revision$"
 
 import sys; sys.path.append ('@@PYTHONPATH@@')
diff --git a/src/bin/stats/tests/b10-stats_stub_test.py b/src/bin/stats/tests/b10-stats_stub_test.py
index 75c5fde..b8983c5 100644
--- a/src/bin/stats/tests/b10-stats_stub_test.py
+++ b/src/bin/stats/tests/b10-stats_stub_test.py
@@ -13,7 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
 __version__ = "$Revision$"
 
 #
diff --git a/src/bin/stats/tests/b10-stats_test.py b/src/bin/stats/tests/b10-stats_test.py
index 873c24d..e4e1a1e 100644
--- a/src/bin/stats/tests/b10-stats_test.py
+++ b/src/bin/stats/tests/b10-stats_test.py
@@ -13,7 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
 __version__ = "$Revision$"
 
 #
diff --git a/src/bin/stats/tests/fake_time.py b/src/bin/stats/tests/fake_time.py
index 964097f..65e0237 100644
--- a/src/bin/stats/tests/fake_time.py
+++ b/src/bin/stats/tests/fake_time.py
@@ -13,7 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
 __version__ = "$Revision$"
 
 # This is a dummy time class against a Python standard time class.
diff --git a/src/bin/stats/tests/isc/cc/session.py b/src/bin/stats/tests/isc/cc/session.py
index ab9c296..4d12adc 100644
--- a/src/bin/stats/tests/isc/cc/session.py
+++ b/src/bin/stats/tests/isc/cc/session.py
@@ -13,7 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
 # This module is a mock-up class of isc.cc.session
 
 __version__ = "$Revision$"
diff --git a/src/bin/stats/tests/isc/config/ccsession.py b/src/bin/stats/tests/isc/config/ccsession.py
index b563e3b..fc285a7 100644
--- a/src/bin/stats/tests/isc/config/ccsession.py
+++ b/src/bin/stats/tests/isc/config/ccsession.py
@@ -13,7 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
 # This module is a mock-up class of isc.cc.session
 
 __version__ = "$Revision$"
diff --git a/src/bin/stats/tests/isc/util/process.py b/src/bin/stats/tests/isc/util/process.py
index 768528c..7274a48 100644
--- a/src/bin/stats/tests/isc/util/process.py
+++ b/src/bin/stats/tests/isc/util/process.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 # A dummy function of isc.util.process.rename()
 def rename(name=None):
     pass
diff --git a/src/bin/stats/tests/isc/utils/process.py b/src/bin/stats/tests/isc/utils/process.py
index 806c2ae..4c0cf8c 100644
--- a/src/bin/stats/tests/isc/utils/process.py
+++ b/src/bin/stats/tests/isc/utils/process.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 # A dummy function of isc.utils.process.rename()
 def rename(name=None):
     pass
diff --git a/src/bin/usermgr/b10-cmdctl-usermgr.xml b/src/bin/usermgr/b10-cmdctl-usermgr.xml
index 7549fe1..529a8db 100644
--- a/src/bin/usermgr/b10-cmdctl-usermgr.xml
+++ b/src/bin/usermgr/b10-cmdctl-usermgr.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/xfrin/b10-xfrin.xml b/src/bin/xfrin/b10-xfrin.xml
index 05ae43c..fdfe1ef 100644
--- a/src/bin/xfrin/b10-xfrin.xml
+++ b/src/bin/xfrin/b10-xfrin.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
@@ -64,7 +63,7 @@
     </para>
 
     <note><simpara>
-      The Y1 prototype release only supports AXFR. IXFR is not implemented.
+      This prototype release only supports AXFR. IXFR is not implemented.
     </simpara></note>
 
     <para>
diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py
index 4a1ae01..04d04a6 100644
--- a/src/bin/xfrin/tests/xfrin_test.py
+++ b/src/bin/xfrin/tests/xfrin_test.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 import unittest
 import socket
 from xfrin import *
diff --git a/src/bin/xfrin/xfrin.py.in b/src/bin/xfrin/xfrin.py.in
index 3977364..fdbc990 100755
--- a/src/bin/xfrin/xfrin.py.in
+++ b/src/bin/xfrin/xfrin.py.in
@@ -16,8 +16,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 import sys; sys.path.append ('@@PYTHONPATH@@')
 import os
 import signal
diff --git a/src/bin/xfrout/b10-xfrout.xml b/src/bin/xfrout/b10-xfrout.xml
index 2b5b6a1..ad71fe2 100644
--- a/src/bin/xfrout/b10-xfrout.xml
+++ b/src/bin/xfrout/b10-xfrout.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/bin/zonemgr/b10-zonemgr.xml b/src/bin/zonemgr/b10-zonemgr.xml
index 22f75e7..4d796ee 100644
--- a/src/bin/zonemgr/b10-zonemgr.xml
+++ b/src/bin/zonemgr/b10-zonemgr.xml
@@ -17,7 +17,6 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id$ -->
 <refentry>
 
   <refentryinfo>
diff --git a/src/lib/asiolink/asiolink.cc b/src/lib/asiolink/asiolink.cc
index 9c8b97e..10574a9 100644
--- a/src/lib/asiolink/asiolink.cc
+++ b/src/lib/asiolink/asiolink.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <cstdlib> // For rand(), temporary until better forwarding is done
@@ -32,6 +30,7 @@
 
 #include <dns/buffer.h>
 #include <dns/message.h>
+#include <dns/rcode.h>
 
 #include <asiolink/asiolink.h>
 #include <asiolink/internal/tcpdns.h>
@@ -39,6 +38,7 @@
 
 #include <log/dummylog.h>
 
+
 using namespace asio;
 using asio::ip::udp;
 using asio::ip::tcp;
@@ -48,8 +48,46 @@ using namespace isc::dns;
 using isc::log::dlog;
 using namespace boost;
 
+// Is this something we can use in libdns++?
+namespace {
+    class SectionInserter {
+    public:
+        SectionInserter(MessagePtr message, const Message::Section sect) :
+            message_(message), section_(sect)
+        {}
+        void operator()(const RRsetPtr rrset) {
+            message_->addRRset(section_, rrset, true);
+        }
+        MessagePtr message_;
+        const Message::Section section_;
+    };
+
+
+    /// \brief Copies the parts relevant for a DNS answer to the
+    /// target message
+    ///
+    /// This adds all the RRsets in the answer, authority and
+    /// additional sections to the target, as well as the response
+    /// code
+    void copyAnswerMessage(const Message& source, MessagePtr target) {
+        target->setRcode(source.getRcode());
+
+        for_each(source.beginSection(Message::SECTION_ANSWER),
+                 source.endSection(Message::SECTION_ANSWER),
+                 SectionInserter(target, Message::SECTION_ANSWER));
+        for_each(source.beginSection(Message::SECTION_AUTHORITY),
+                 source.endSection(Message::SECTION_AUTHORITY),
+                 SectionInserter(target, Message::SECTION_AUTHORITY));
+        for_each(source.beginSection(Message::SECTION_ADDITIONAL),
+                 source.endSection(Message::SECTION_ADDITIONAL),
+                 SectionInserter(target, Message::SECTION_ADDITIONAL));
+    }
+}
+
 namespace asiolink {
 
+typedef pair<string, uint16_t> addr_t;
+
 class IOServiceImpl {
 private:
     IOServiceImpl(const IOService& source);
@@ -245,9 +283,14 @@ typedef std::vector<std::pair<std::string, uint16_t> > AddressVector;
 }
 
 RecursiveQuery::RecursiveQuery(DNSService& dns_service,
-    const AddressVector& upstream, int timeout, unsigned retries) :
+    const AddressVector& upstream,
+    const AddressVector& upstream_root,
+    int query_timeout, int client_timeout, int lookup_timeout,
+    unsigned retries) :
     dns_service_(dns_service), upstream_(new AddressVector(upstream)),
-    timeout_(timeout), retries_(retries)
+    upstream_root_(new AddressVector(upstream_root)),
+    query_timeout_(query_timeout), client_timeout_(client_timeout),
+    lookup_timeout_(lookup_timeout), retries_(retries)
 {}
 
 namespace {
@@ -298,8 +341,17 @@ private:
 
     // Info for (re)sending the query (the question and destination)
     Question question_;
+
+    // This is where we build and store our final answer
+    MessagePtr answer_message_;
+
+    // currently we use upstream as the current list of NS records
+    // we should differentiate between forwarding and resolving
     shared_ptr<AddressVector> upstream_;
 
+    // root servers...just copied over to the zone_servers_
+    shared_ptr<AddressVector> upstream_root_;
+
     // Buffer to store the result.
     OutputBufferPtr buffer_;
 
@@ -311,12 +363,33 @@ private:
      *     computation of average RTT, increase with each retry, etc.
      */
     // Timeout information
-    int timeout_;
+    int query_timeout_;
     unsigned retries_;
 
+    // normal query state
+
+    // Not using NSAS at this moment, so we keep a list
+    // of 'current' zone servers
+    vector<addr_t> zone_servers_;
+
+    // Update the question that will be sent to the server
+    void setQuestion(const Question& new_question) {
+        question_ = new_question;
+    }
+
+    deadline_timer client_timer;
+    deadline_timer lookup_timer;
+
+    size_t queries_out_;
+
+    // If we timed out ourselves (lookup timeout), stop issuing queries
+    bool done_;
+
     // (re)send the query to the server.
     void send() {
         const int uc = upstream_->size();
+        const int zs = zone_servers_.size();
+        buffer_->clear();
         if (uc > 0) {
             int serverIndex = rand() % uc;
             dlog("Sending upstream query (" + question_.toText() +
@@ -324,37 +397,203 @@ private:
             UDPQuery query(io_, question_,
                 upstream_->at(serverIndex).first,
                 upstream_->at(serverIndex).second, buffer_, this,
-                timeout_);
+                query_timeout_);
+            ++queries_out_;
+            io_.post(query);
+        } else if (zs > 0) {
+            int serverIndex = rand() % zs;
+            dlog("Sending query to zone server (" + question_.toText() +
+                ") to " + zone_servers_.at(serverIndex).first);
+            UDPQuery query(io_, question_,
+                zone_servers_.at(serverIndex).first,
+                zone_servers_.at(serverIndex).second, buffer_, this,
+                query_timeout_);
+            ++queries_out_;
             io_.post(query);
         } else {
             dlog("Error, no upstream servers to send to.");
         }
     }
+    
+    // This function is called by operator() if there is an actual
+    // answer from a server and we are in recursive mode
+    // depending on the contents, we go on recursing or return
+    //
+    // Note that the footprint may change as this function may
+    // need to append data to the answer we are building later.
+    //
+    // returns true if we are done
+    // returns false if we are not done
+    bool handleRecursiveAnswer(const Message& incoming) {
+        if (incoming.getRRCount(Message::SECTION_ANSWER) > 0) {
+            dlog("Got final result, copying answer.");
+            copyAnswerMessage(incoming, answer_message_);
+            return true;
+        } else {
+            dlog("Got delegation, continuing");
+            // ok we need to do some more processing.
+            // the ns list should contain all nameservers
+            // while the additional may contain addresses for
+            // them.
+            // this needs to tie into NSAS of course
+            // for this very first mockup, hope there is an
+            // address in additional and just use that
+
+            // send query to the addresses in the delegation
+            bool found_ns_address = false;
+            zone_servers_.clear();
+
+            for (RRsetIterator rrsi = incoming.beginSection(Message::SECTION_ADDITIONAL);
+                 rrsi != incoming.endSection(Message::SECTION_ADDITIONAL) && !found_ns_address;
+                 rrsi++) {
+                ConstRRsetPtr rrs = *rrsi;
+                if (rrs->getType() == RRType::A()) {
+                    // found address
+                    RdataIteratorPtr rdi = rrs->getRdataIterator();
+                    // just use the first for now
+                    if (!rdi->isLast()) {
+                        std::string addr_str = rdi->getCurrent().toText();
+                        dlog("[XX] first address found: " + addr_str);
+                        // now we have one address, simply
+                        // resend that exact same query
+                        // to that address and yield, when it
+                        // returns, loop again.
+                        
+                        // should use NSAS
+                        zone_servers_.push_back(addr_t(addr_str, 53));
+                        found_ns_address = true;
+                    }
+                }
+            }
+            if (found_ns_address) {
+                // next resolver round
+                send();
+                return false;
+            } else {
+                dlog("[XX] no ready-made addresses in additional. need nsas.");
+                // this will result in answering with the delegation. oh well
+                copyAnswerMessage(incoming, answer_message_);
+                return true;
+            }
+        }
+    }
+    
+
 public:
     RunningQuery(asio::io_service& io, const Question &question,
-        shared_ptr<AddressVector> upstream,
-        OutputBufferPtr buffer, DNSServer* server, int timeout,
+        MessagePtr answer_message, shared_ptr<AddressVector> upstream,
+        shared_ptr<AddressVector> upstream_root,
+        OutputBufferPtr buffer, DNSServer* server,
+        int query_timeout, int client_timeout, int lookup_timeout,
         unsigned retries) :
         io_(io),
         question_(question),
+        answer_message_(answer_message),
         upstream_(upstream),
+        upstream_root_(upstream_root),
         buffer_(buffer),
         server_(server->clone()),
-        timeout_(timeout),
-        retries_(retries)
+        query_timeout_(query_timeout),
+        retries_(retries),
+        client_timer(io),
+        lookup_timer(io),
+        queries_out_(0),
+        done_(false)
     {
+        // Setup the timer to stop trying (lookup_timeout)
+        if (lookup_timeout >= 0) {
+            lookup_timer.expires_from_now(
+                boost::posix_time::milliseconds(lookup_timeout));
+            lookup_timer.async_wait(boost::bind(&RunningQuery::stop, this, false));
+        }
+        
+        // Setup the timer to send an answer (client_timeout)
+        if (client_timeout >= 0) {
+            client_timer.expires_from_now(
+                boost::posix_time::milliseconds(client_timeout));
+            client_timer.async_wait(boost::bind(&RunningQuery::clientTimeout, this));
+        }
+        
+        // should use NSAS for root servers
+        // Adding root servers if not a forwarder
+        if (upstream_->empty()) {
+            if (upstream_root_->empty()) { //if no root ips given, use this
+                zone_servers_.push_back(addr_t("192.5.5.241", 53));
+            }
+            else
+            {
+              //copy the list
+              dlog("Size is " + 
+                    boost::lexical_cast<string>(upstream_root_->size()) + 
+                    "\n");
+              //Use BOOST_FOREACH here? Is it faster?
+              for(AddressVector::iterator it = upstream_root_->begin();
+                   it < upstream_root_->end(); it++) {
+                zone_servers_.push_back(addr_t(it->first,it->second));
+                dlog("Put " + zone_servers_.back().first + "into root list\n");
+              }
+            }
+        }
+
         send();
     }
 
+    virtual void clientTimeout() {
+        // right now, just stop (should make SERVFAIL and send that
+        // back, but not stop)
+        stop(false);
+    }
+
+    virtual void stop(bool resume) {
+        // if we cancel our timers, we will still get an event for
+        // that, so we cannot delete ourselves just yet (those events
+        // would be bound to a deleted object)
+        // cancel them one by one, both cancels should get us back
+        // here again.
+        // same goes if we have an outstanding query (can't delete
+        // until that one comes back to us)
+        done_ = true;
+        server_->resume(resume);
+        if (lookup_timer.cancel() != 0) {
+            return;
+        }
+        if (client_timer.cancel() != 0) {
+            return;
+        }
+        if (queries_out_ > 0) {
+            return;
+        }
+        delete this;
+    }
+
     // This function is used as callback from DNSQuery.
     virtual void operator()(UDPQuery::Result result) {
-        if (result == UDPQuery::TIME_OUT && retries_ --) {
-            dlog("Resending query");
+        // XXX is this the place for TCP retry?
+        --queries_out_;
+        if (!done_ && result != UDPQuery::TIME_OUT) {
+            // we got an answer
+            Message incoming(Message::PARSE);
+            InputBuffer ibuf(buffer_->getData(), buffer_->getLength());
+            incoming.fromWire(ibuf);
+
+            if (upstream_->size() == 0 &&
+                incoming.getRcode() == Rcode::NOERROR()) {
+                done_ = handleRecursiveAnswer(incoming);
+            } else {
+                copyAnswerMessage(incoming, answer_message_);
+                done_ = true;
+            }
+            
+            if (done_) {
+                stop(result == UDPQuery::SUCCESS);
+            }
+        } else if (!done_ && retries_--) {
             // We timed out, but we have some retries, so send again
+            dlog("Timeout, resending query");
             send();
         } else {
-            server_->resume(result == UDPQuery::SUCCESS);
-            delete this;
+            // We are done
+            stop(false);
         }
     }
 };
@@ -362,7 +601,9 @@ public:
 }
 
 void
-RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer,
+RecursiveQuery::sendQuery(const Question& question,
+                          MessagePtr answer_message,
+                          OutputBufferPtr buffer,
                           DNSServer* server)
 {
     // XXX: eventually we will need to be able to determine whether
@@ -371,8 +612,9 @@ RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer,
     // we're only going to handle UDP.
     asio::io_service& io = dns_service_.get_io_service();
     // It will delete itself when it is done
-    new RunningQuery(io, question, upstream_, buffer, server,
-         timeout_, retries_);
+    new RunningQuery(io, question, answer_message, upstream_, upstream_root_,
+                         buffer, server, query_timeout_, client_timeout_,
+                         lookup_timeout_, retries_);
 }
 
 class IntervalTimerImpl {
diff --git a/src/lib/asiolink/asiolink.h b/src/lib/asiolink/asiolink.h
index 6f328e4..5e46dfc 100644
--- a/src/lib/asiolink/asiolink.h
+++ b/src/lib/asiolink/asiolink.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __ASIOLINK_H
 #define __ASIOLINK_H 1
 
@@ -414,10 +412,11 @@ public:
     /// \param DNSServer DNSServer object to use
     virtual void operator()(const IOMessage& io_message,
                             isc::dns::MessagePtr message,
+                            isc::dns::MessagePtr answer_message,
                             isc::dns::OutputBufferPtr buffer,
                             DNSServer* server) const
     {
-        (*self_)(io_message, message, buffer, server);
+        (*self_)(io_message, message, answer_message, buffer, server);
     }
 private:
     DNSLookup* self_;
@@ -467,6 +466,7 @@ public:
     /// \param buffer The result is put here
     virtual void operator()(const IOMessage& io_message,
                             isc::dns::MessagePtr message,
+                            isc::dns::MessagePtr answer_message,
                             isc::dns::OutputBufferPtr buffer) const = 0;
 };
 
@@ -538,6 +538,8 @@ public:
     ///        query on.
     /// \param upstream Addresses and ports of the upstream servers
     ///        to forward queries to.
+    /// \param upstream_root Addresses and ports of the root servers
+    ///        to use when resolving.
     /// \param timeout How long to timeout the query, in ms
     ///     -1 means never timeout (but do not use that).
     ///     TODO: This should be computed somehow dynamically in future
@@ -545,7 +547,13 @@ public:
     ///     and return if it returs).
     RecursiveQuery(DNSService& dns_service,
                    const std::vector<std::pair<std::string, uint16_t> >&
-                   upstream, int timeout = -1, unsigned retries = 0);
+                   upstream, 
+                   const std::vector<std::pair<std::string, uint16_t> >&
+                   upstream_root, 
+                   int query_timeout = 2000,
+                   int client_timeout = 4000,
+                   int lookup_timeout = 30000,
+                   unsigned retries = 3);
     //@}
 
     /// \brief Initiates an upstream query in the \c RecursiveQuery object.
@@ -559,13 +567,18 @@ public:
     /// \param buffer An output buffer into which the response can be copied
     /// \param server A pointer to the \c DNSServer object handling the client
     void sendQuery(const isc::dns::Question& question,
+                   isc::dns::MessagePtr answer_message,
                    isc::dns::OutputBufferPtr buffer,
                    DNSServer* server);
 private:
     DNSService& dns_service_;
     boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
         upstream_;
-    int timeout_;
+    boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
+        upstream_root_;
+    int query_timeout_;
+    int client_timeout_;
+    int lookup_timeout_;
     unsigned retries_;
 };
 
diff --git a/src/lib/asiolink/internal/tcpdns.h b/src/lib/asiolink/internal/tcpdns.h
index da3869f..a97ed17 100644
--- a/src/lib/asiolink/internal/tcpdns.h
+++ b/src/lib/asiolink/internal/tcpdns.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __TCPDNS_H
 #define __TCPDNS_H 1
 
@@ -197,7 +195,8 @@ private:
     // \c IOMessage and \c Message objects to be passed to the
     // DNS lookup and answer providers
     boost::shared_ptr<asiolink::IOMessage> io_message_;
-    isc::dns::MessagePtr message_;
+    isc::dns::MessagePtr query_message_;
+    isc::dns::MessagePtr answer_message_;
 
     // The buffer into which the query packet is written
     boost::shared_array<char>data_;
diff --git a/src/lib/asiolink/internal/udpdns.h b/src/lib/asiolink/internal/udpdns.h
index c41dca2..f29d5c8 100644
--- a/src/lib/asiolink/internal/udpdns.h
+++ b/src/lib/asiolink/internal/udpdns.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __UDPDNS_H
 #define __UDPDNS_H 1
 
@@ -210,7 +208,12 @@ private:
     // \c IOMessage and \c Message objects to be passed to the
     // DNS lookup and answer providers
     boost::shared_ptr<asiolink::IOMessage> io_message_;
-    isc::dns::MessagePtr message_;
+
+    // The original query as sent by the client
+    isc::dns::MessagePtr query_message_;
+
+    // The response message we are building
+    isc::dns::MessagePtr answer_message_;
 
     // The buffer into which the response is written
     isc::dns::OutputBufferPtr respbuf_;
diff --git a/src/lib/asiolink/ioaddress.cc b/src/lib/asiolink/ioaddress.cc
index 8c53c43..990524a 100644
--- a/src/lib/asiolink/ioaddress.cc
+++ b/src/lib/asiolink/ioaddress.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <unistd.h>             // for some IPC/network system calls
diff --git a/src/lib/asiolink/ioaddress.h b/src/lib/asiolink/ioaddress.h
index 884e3cf..5727041 100644
--- a/src/lib/asiolink/ioaddress.h
+++ b/src/lib/asiolink/ioaddress.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __IOADDRESS_H
 #define __IOADDRESS_H 1
 
diff --git a/src/lib/asiolink/ioendpoint.cc b/src/lib/asiolink/ioendpoint.cc
index 968ab22..2807f8d 100644
--- a/src/lib/asiolink/ioendpoint.cc
+++ b/src/lib/asiolink/ioendpoint.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <unistd.h>             // for some IPC/network system calls
diff --git a/src/lib/asiolink/ioendpoint.h b/src/lib/asiolink/ioendpoint.h
index 36aceaa..926ce50 100644
--- a/src/lib/asiolink/ioendpoint.h
+++ b/src/lib/asiolink/ioendpoint.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __IOENDPOINT_H
 #define __IOENDPOINT_H 1
 
diff --git a/src/lib/asiolink/iomessage.h b/src/lib/asiolink/iomessage.h
index f3e376b..27baa8a 100644
--- a/src/lib/asiolink/iomessage.h
+++ b/src/lib/asiolink/iomessage.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __IOMESSAGE_H
 #define __IOMESSAGE_H 1
 
diff --git a/src/lib/asiolink/iosocket.cc b/src/lib/asiolink/iosocket.cc
index dea859d..a3967d4 100644
--- a/src/lib/asiolink/iosocket.cc
+++ b/src/lib/asiolink/iosocket.cc
@@ -14,8 +14,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include "iosocket.h"
 
 #include <asio.hpp>
diff --git a/src/lib/asiolink/iosocket.h b/src/lib/asiolink/iosocket.h
index d58429d..df37d71 100644
--- a/src/lib/asiolink/iosocket.h
+++ b/src/lib/asiolink/iosocket.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __IOSOCKET_H
 #define __IOSOCKET_H 1
 
diff --git a/src/lib/asiolink/tcpdns.cc b/src/lib/asiolink/tcpdns.cc
index c998aa2..c00b87a 100644
--- a/src/lib/asiolink/tcpdns.cc
+++ b/src/lib/asiolink/tcpdns.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <unistd.h>             // for some IPC/network system calls
@@ -144,7 +142,8 @@ TCPServer::operator()(error_code ec, size_t length) {
         // Reset or instantiate objects that will be needed by the
         // DNS lookup and the write call.
         respbuf_.reset(new OutputBuffer(0));
-        message_.reset(new Message(Message::PARSE));
+        query_message_.reset(new Message(Message::PARSE));
+        answer_message_.reset(new Message(Message::RENDER));
 
         // Schedule a DNS lookup, and yield.  When the lookup is
         // finished, the coroutine will resume immediately after
@@ -159,7 +158,8 @@ TCPServer::operator()(error_code ec, size_t length) {
 
         // Call the DNS answer provider to render the answer into
         // wire format
-        (*answer_callback_)(*io_message_, message_, respbuf_);
+        (*answer_callback_)(*io_message_, query_message_,
+                            answer_message_, respbuf_);
 
         // Set up the response, beginning with two length bytes.
         lenbuf.writeUint16(respbuf_->getLength());
@@ -178,7 +178,8 @@ TCPServer::operator()(error_code ec, size_t length) {
 /// AsyncLookup<TCPServer> handler.)
 void
 TCPServer::asyncLookup() {
-    (*lookup_callback_)(*io_message_, message_, respbuf_, this);
+    (*lookup_callback_)(*io_message_, query_message_,
+                        answer_message_, respbuf_, this);
 }
 
 /// Post this coroutine on the ASIO service queue so that it will
diff --git a/src/lib/asiolink/tests/asiolink_unittest.cc b/src/lib/asiolink/tests/asiolink_unittest.cc
index f269ef7..c83c090 100644
--- a/src/lib/asiolink/tests/asiolink_unittest.cc
+++ b/src/lib/asiolink/tests/asiolink_unittest.cc
@@ -12,9 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
-
 #include <config.h>
 
 #include <sys/socket.h>
@@ -31,6 +28,7 @@
 #include <exceptions/exceptions.h>
 
 #include <dns/tests/unittest_util.h>
+#include <dns/rcode.h>
 
 #include <dns/buffer.h>
 #include <dns/message.h>
@@ -442,6 +440,7 @@ protected:
                             DNSAnswer* answer = NULL) :
             io_(io_service),
             message_(new Message(Message::PARSE)),
+            answer_message_(new Message(Message::RENDER)),
             respbuf_(new OutputBuffer(0)),
             checkin_(checkin), lookup_(lookup), answer_(answer)
         {}
@@ -450,7 +449,8 @@ protected:
                         size_t length = 0)
         {}
 
-        void resume(const bool) { // in our test this shouldn't be called
+        void resume(const bool) {
+          // should never be called in our tests
         }
 
         DNSServer* clone() {
@@ -460,7 +460,8 @@ protected:
 
         inline void asyncLookup() {
             if (lookup_) {
-                (*lookup_)(*io_message_, message_, respbuf_, this);
+                (*lookup_)(*io_message_, message_, answer_message_,
+                           respbuf_, this);
             }
         }
 
@@ -473,6 +474,7 @@ protected:
         // asynchronous lookup calls via the asyncLookup() method
         boost::shared_ptr<asiolink::IOMessage> io_message_;
         isc::dns::MessagePtr message_;
+        isc::dns::MessagePtr answer_message_;
         isc::dns::OutputBufferPtr respbuf_;
 
         // Callback functions provided by the caller
@@ -643,15 +645,17 @@ singleAddress(const string &address, uint16_t port) {
 TEST_F(ASIOLinkTest, recursiveSetupV4) {
     setDNSService(true, false);
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    EXPECT_NO_THROW(RecursiveQuery(*dns_service_, singleAddress(TEST_IPV6_ADDR,
-        port)));
+    EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
+                                   singleAddress(TEST_IPV4_ADDR, port),
+                                   singleAddress(TEST_IPV4_ADDR, port)));
 }
 
 TEST_F(ASIOLinkTest, recursiveSetupV6) {
     setDNSService(false, true);
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    EXPECT_NO_THROW(RecursiveQuery(*dns_service_, singleAddress(TEST_IPV6_ADDR,
-        port)));
+    EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
+                                   singleAddress(TEST_IPV6_ADDR, port),
+                                   singleAddress(TEST_IPV6_ADDR,port)));
 }
 
 // XXX:
@@ -659,7 +663,7 @@ TEST_F(ASIOLinkTest, recursiveSetupV6) {
 // a routine that can do this with variable address family, address, and
 // port, and with the various callbacks defined in such a way as to ensure
 // full code coverage including error cases.
-TEST_F(ASIOLinkTest, recursiveSend) {
+TEST_F(ASIOLinkTest, forwarderSend) {
     setDNSService(true, false);
 
     // Note: We use the test prot plus one to ensure we aren't binding
@@ -667,11 +671,14 @@ TEST_F(ASIOLinkTest, recursiveSend) {
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
 
     MockServer server(*io_service_);
-    RecursiveQuery rq(*dns_service_, singleAddress(TEST_IPV4_ADDR, port));
+    RecursiveQuery rq(*dns_service_,
+                      singleAddress(TEST_IPV4_ADDR, port),
+                      singleAddress(TEST_IPV4_ADDR, port));
 
     Question q(Name("example.com"), RRClass::IN(), RRType::TXT());
     OutputBufferPtr buffer(new OutputBuffer(0));
-    rq.sendQuery(q, buffer, &server);
+    MessagePtr answer(new Message(Message::RENDER));
+    rq.sendQuery(q, answer, buffer, &server);
 
     char data[4096];
     size_t size = sizeof(data);
@@ -691,20 +698,59 @@ TEST_F(ASIOLinkTest, recursiveSend) {
     EXPECT_EQ(q.getClass(), q2->getClass());
 }
 
-// Test it tries the correct amount of times before giving up
-TEST_F(ASIOLinkTest, recursiveTimeout) {
-    // Prepare the service (we do not use the common setup, we do not answer
-    setDNSService();
-
-    // Prepare the socket
-    res_ = resolveAddress(AF_INET, IPPROTO_UDP, true);
-    sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
+int
+createTestSocket()
+{
+    struct addrinfo* res_ = resolveAddress(AF_INET, IPPROTO_UDP, true);
+    int sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
     if (sock_ < 0) {
         isc_throw(IOError, "failed to open test socket");
     }
     if (bind(sock_, res_->ai_addr, res_->ai_addrlen) < 0) {
         isc_throw(IOError, "failed to bind test socket");
     }
+    return sock_;
+}
+
+int
+setSocketTimeout(int sock_, size_t tv_sec, size_t tv_usec) {
+    const struct timeval timeo = { tv_sec, tv_usec };
+    int recv_options = 0;
+    if (setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo))) {
+        if (errno == ENOPROTOOPT) { // see ASIOLinkTest::recvUDP()
+            recv_options = MSG_DONTWAIT;
+        } else {
+            isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
+        }
+    }
+    return recv_options;
+}
+
+// try to read from the socket max time
+// *num is incremented for every succesfull read
+// returns true if it can read max times, false otherwise
+bool tryRead(int sock_, int recv_options, size_t max, int* num) {
+    size_t i = 0;
+    do {
+        char inbuff[512];
+        if (recv(sock_, inbuff, sizeof(inbuff), recv_options) < 0) {
+            return false;
+        } else {
+            ++i;
+            ++*num;
+        }
+    } while (i < max);
+    return true;
+}
+
+
+// Test it tries the correct amount of times before giving up
+TEST_F(ASIOLinkTest, forwardQueryTimeout) {
+    // Prepare the service (we do not use the common setup, we do not answer
+    setDNSService();
+
+    // Prepare the socket
+    sock_ = createTestSocket();
 
     // Prepare the server
     bool done(true);
@@ -712,40 +758,171 @@ TEST_F(ASIOLinkTest, recursiveTimeout) {
 
     // Do the answer
     const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    RecursiveQuery query(*dns_service_, singleAddress(TEST_IPV4_ADDR, port),
-        10, 2);
+    RecursiveQuery query(*dns_service_,
+                         singleAddress(TEST_IPV4_ADDR, port),
+                         singleAddress(TEST_IPV4_ADDR, port),
+                         10, 4000, 3000, 2);
     Question question(Name("example.net"), RRClass::IN(), RRType::A());
     OutputBufferPtr buffer(new OutputBuffer(0));
-    query.sendQuery(question, buffer, &server);
+    MessagePtr answer(new Message(Message::RENDER));
+    query.sendQuery(question, answer, buffer, &server);
 
     // Run the test
     io_service_->run();
 
     // Read up to 3 packets.  Use some ad hoc timeout to prevent an infinite
     // block (see also recvUDP()).
-    const struct timeval timeo = { 10, 0 };
-    int recv_options = 0;
-    if (setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo))) {
-        if (errno == ENOPROTOOPT) { // see ASIOLinkTest::recvUDP()
-            recv_options = MSG_DONTWAIT;
-        } else {
-            isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
-        }
-    }
+    int recv_options = setSocketTimeout(sock_, 10, 0);
     int num = 0;
-    do {
-        char inbuff[512];
-        if (recv(sock_, inbuff, sizeof(inbuff), recv_options) < 0) {
-            num = -1;
-            break;
-        }
-    } while (++num < 3);
+    bool read_success = tryRead(sock_, recv_options, 3, &num);
 
     // The query should fail
     EXPECT_FALSE(done);
     EXPECT_EQ(3, num);
+    EXPECT_TRUE(read_success);
 }
 
+// If we set client timeout to lower than querytimeout, we should
+// get a failure answer, but still see retries
+// (no actual answer is given here yet)
+TEST_F(ASIOLinkTest, forwardClientTimeout) {
+    // Prepare the service (we do not use the common setup, we do not answer
+    setDNSService();
+
+    sock_ = createTestSocket();
+
+    // Prepare the server
+    bool done(true);
+    MockServerStop server(*io_service_, &done);
+
+    MessagePtr answer(new Message(Message::RENDER));
+
+    // Do the answer
+    const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
+    // Set it up to retry twice before client timeout fires
+    // Since the lookup timer has not fired, it should retry
+    // a third time
+    RecursiveQuery query(*dns_service_,
+                         singleAddress(TEST_IPV4_ADDR, port),
+                         singleAddress(TEST_IPV4_ADDR, port),
+                         50, 120, 1000, 3);
+    Question question(Name("example.net"), RRClass::IN(), RRType::A());
+    OutputBufferPtr buffer(new OutputBuffer(0));
+    query.sendQuery(question, answer, buffer, &server);
+
+    // Run the test
+    io_service_->run();
+
+    // we know it'll fail, so make it a shorter timeout
+    int recv_options = setSocketTimeout(sock_, 1, 0);
+
+    // Try to read 5 times, should stop after 3 reads
+    int num = 0;
+    bool read_success = tryRead(sock_, recv_options, 5, &num);
+
+    // The query should fail (for resolver it should send back servfail,
+    // but currently, and perhaps for forwarder in general, the effect
+    // will be the same as on a lookup timeout, i.e. no answer is sent
+    // back)
+    EXPECT_FALSE(done);
+    EXPECT_EQ(3, num);
+    EXPECT_FALSE(read_success);
+}
+
+// If we set lookup timeout to lower than querytimeout*retries, we should
+// fail before the full amount of retries
+TEST_F(ASIOLinkTest, forwardLookupTimeout) {
+    // Prepare the service (we do not use the common setup, we do not answer
+    setDNSService();
+
+    // Prepare the socket
+    sock_ = createTestSocket();
+
+    // Prepare the server
+    bool done(true);
+    MockServerStop server(*io_service_, &done);
+
+    MessagePtr answer(new Message(Message::RENDER));
+
+    // Do the answer
+    const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
+    // Set up the test so that it will retry 5 times, but the lookup
+    // timeout will fire after only 3 normal timeouts
+    RecursiveQuery query(*dns_service_,
+                         singleAddress(TEST_IPV4_ADDR, port),
+                         singleAddress(TEST_IPV4_ADDR, port),
+                         50, 4000, 120, 5);
+    Question question(Name("example.net"), RRClass::IN(), RRType::A());
+    OutputBufferPtr buffer(new OutputBuffer(0));
+    query.sendQuery(question, answer, buffer, &server);
+
+    // Run the test
+    io_service_->run();
+
+    int recv_options = setSocketTimeout(sock_, 1, 0);
+
+    // Try to read 5 times, should stop after 3 reads
+    int num = 0;
+    bool read_success = tryRead(sock_, recv_options, 5, &num);
+
+    // The query should fail
+    EXPECT_FALSE(done);
+    EXPECT_EQ(3, num);
+    EXPECT_FALSE(read_success);
+}
+
+// as mentioned above, we need a more better framework for this,
+// in addition to that, this sends out queries into the world
+// (which we should catch somehow and fake replies for)
+// for the skeleton code, it shouldn't be too much of a problem
+// Ok so even we don't all have access to the DNS world right now,
+// so disabling these tests too.
+TEST_F(ASIOLinkTest, DISABLED_recursiveSendOk) {
+    setDNSService(true, false);
+    bool done;
+    
+    MockServerStop server(*io_service_, &done);
+    vector<pair<string, uint16_t> > empty_vector;
+    RecursiveQuery rq(*dns_service_, empty_vector, empty_vector, 10000, 0);
+
+    Question q(Name("www.isc.org"), RRClass::IN(), RRType::A());
+    OutputBufferPtr buffer(new OutputBuffer(0));
+    MessagePtr answer(new Message(Message::RENDER));
+    rq.sendQuery(q, answer, buffer, &server);
+    io_service_->run();
+
+    // Check that the answer we got matches the one we wanted
+    EXPECT_EQ(Rcode::NOERROR(), answer->getRcode());
+    ASSERT_EQ(1, answer->getRRCount(Message::SECTION_ANSWER));
+    RRsetPtr a = *answer->beginSection(Message::SECTION_ANSWER);
+    EXPECT_EQ(q.getName(), a->getName());
+    EXPECT_EQ(q.getType(), a->getType());
+    EXPECT_EQ(q.getClass(), a->getClass());
+    EXPECT_EQ(1, a->getRdataCount());
+}
+
+// see comments at previous test
+TEST_F(ASIOLinkTest, DISABLED_recursiveSendNXDOMAIN) {
+    setDNSService(true, false);
+    bool done;
+    
+    MockServerStop server(*io_service_, &done);
+    vector<pair<string, uint16_t> > empty_vector;
+    RecursiveQuery rq(*dns_service_, empty_vector, empty_vector, 10000, 0);
+
+    Question q(Name("wwwdoesnotexist.isc.org"), RRClass::IN(), RRType::A());
+    OutputBufferPtr buffer(new OutputBuffer(0));
+    MessagePtr answer(new Message(Message::RENDER));
+    rq.sendQuery(q, answer, buffer, &server);
+    io_service_->run();
+
+    // Check that the answer we got matches the one we wanted
+    EXPECT_EQ(Rcode::NXDOMAIN(), answer->getRcode());
+    EXPECT_EQ(0, answer->getRRCount(Message::SECTION_ANSWER));
+}
+
+
+
 // This fixture is for testing IntervalTimer. Some callback functors are 
 // registered as callback function of the timer to test if they are called
 // or not.
diff --git a/src/lib/asiolink/tests/run_unittests.cc b/src/lib/asiolink/tests/run_unittests.cc
index 68f55f6..b481784 100644
--- a/src/lib/asiolink/tests/run_unittests.cc
+++ b/src/lib/asiolink/tests/run_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <dns/tests/unittest_util.h>
diff --git a/src/lib/asiolink/udpdns.cc b/src/lib/asiolink/udpdns.cc
index 7d9fd99..5641802 100644
--- a/src/lib/asiolink/udpdns.cc
+++ b/src/lib/asiolink/udpdns.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <unistd.h>             // for some IPC/network system calls
@@ -132,13 +130,16 @@ UDPServer::operator()(error_code ec, size_t length) {
         // Instantiate objects that will be needed by the
         // asynchronous DNS lookup and/or by the send call.
         respbuf_.reset(new OutputBuffer(0));
-        message_.reset(new Message(Message::PARSE));
+        query_message_.reset(new Message(Message::PARSE));
+        answer_message_.reset(new Message(Message::RENDER));
 
         // Schedule a DNS lookup, and yield.  When the lookup is
         // finished, the coroutine will resume immediately after
         // this point.
         CORO_YIELD io_.post(AsyncLookup<UDPServer>(*this));
 
+        dlog("[XX] got an answer");
+
         // The 'done_' flag indicates whether we have an answer
         // to send back.  If not, exit the coroutine permanently.
         if (!done_) {
@@ -147,7 +148,8 @@ UDPServer::operator()(error_code ec, size_t length) {
 
         // Call the DNS answer provider to render the answer into
         // wire format
-        (*answer_callback_)(*io_message_, message_, respbuf_);
+        (*answer_callback_)(*io_message_, query_message_,
+                            answer_message_, respbuf_);
 
         // Begin an asynchronous send, and then yield.  When the
         // send completes, we will resume immediately after this point
@@ -163,7 +165,8 @@ UDPServer::operator()(error_code ec, size_t length) {
 /// AsyncLookup<UDPServer> handler.)
 void
 UDPServer::asyncLookup() {
-    (*lookup_callback_)(*io_message_, message_, respbuf_, this);
+    (*lookup_callback_)(*io_message_, query_message_, answer_message_,
+                        respbuf_, this);
 }
 
 /// Post this coroutine on the ASIO service queue so that it will
@@ -253,6 +256,7 @@ UDPQuery::operator()(error_code ec, size_t length) {
                 data_->remote.address().to_string());
         }
 
+
         // If we timeout, we stop, which will shutdown everything and
         // cancel all other attempts to run inside the coroutine
         if (data_->timeout != -1) {
diff --git a/src/lib/bench/benchmark.h b/src/lib/bench/benchmark.h
index 03d126d..5eab1b7 100644
--- a/src/lib/bench/benchmark.h
+++ b/src/lib/bench/benchmark.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __BENCHMARK_H
 #define __BENCHMARK_H 1
 
diff --git a/src/lib/bench/benchmark_util.cc b/src/lib/bench/benchmark_util.cc
index cdae6fe..ca2ca1b 100644
--- a/src/lib/bench/benchmark_util.cc
+++ b/src/lib/bench/benchmark_util.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <fstream>
 #include <iostream>
 #include <string>
diff --git a/src/lib/bench/benchmark_util.h b/src/lib/bench/benchmark_util.h
index 30d3a8f..3a373f2 100644
--- a/src/lib/bench/benchmark_util.h
+++ b/src/lib/bench/benchmark_util.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __BENCHMARK_UTIL_H
 #define __BENCHMARK_UTIL_H 1
 
diff --git a/src/lib/bench/example/search_bench.cc b/src/lib/bench/example/search_bench.cc
index d830d2c..851d815 100644
--- a/src/lib/bench/example/search_bench.cc
+++ b/src/lib/bench/example/search_bench.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <unistd.h>             // for getpid
 
 #include <cassert>
diff --git a/src/lib/bench/tests/benchmark_unittest.cc b/src/lib/bench/tests/benchmark_unittest.cc
index ffd39b8..f16b47d 100644
--- a/src/lib/bench/tests/benchmark_unittest.cc
+++ b/src/lib/bench/tests/benchmark_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <unistd.h>             // for usleep
 
 #include <bench/benchmark.h>
diff --git a/src/lib/bench/tests/loadquery_unittest.cc b/src/lib/bench/tests/loadquery_unittest.cc
index e7d6cf3..3ac352a 100644
--- a/src/lib/bench/tests/loadquery_unittest.cc
+++ b/src/lib/bench/tests/loadquery_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <algorithm>
 #include <utility>
 #include <vector>
diff --git a/src/lib/bench/tests/run_unittests.cc b/src/lib/bench/tests/run_unittests.cc
index ecc077f..85d4548 100644
--- a/src/lib/bench/tests/run_unittests.cc
+++ b/src/lib/bench/tests/run_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 int
diff --git a/src/lib/cc/data.cc b/src/lib/cc/data.cc
index 39cdfc0..6f7d4a2 100644
--- a/src/lib/cc/data.cc
+++ b/src/lib/cc/data.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <cc/data.h>
diff --git a/src/lib/cc/data.h b/src/lib/cc/data.h
index 1acfcad..4f121d5 100644
--- a/src/lib/cc/data.h
+++ b/src/lib/cc/data.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef _ISC_DATA_H
 #define _ISC_DATA_H 1
 
diff --git a/src/lib/cc/session.cc b/src/lib/cc/session.cc
index 7ee90a2..e911a86 100644
--- a/src/lib/cc/session.cc
+++ b/src/lib/cc/session.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 #include <cc/session_config.h>
 
diff --git a/src/lib/cc/session.h b/src/lib/cc/session.h
index 37080cf..6d8696d 100644
--- a/src/lib/cc/session.h
+++ b/src/lib/cc/session.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef _ISC_SESSION_H
 #define _ISC_SESSION_H 1
 
diff --git a/src/lib/cc/tests/data_unittests.cc b/src/lib/cc/tests/data_unittests.cc
index cc3e121..2536682 100644
--- a/src/lib/cc/tests/data_unittests.cc
+++ b/src/lib/cc/tests/data_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 #include <boost/foreach.hpp>
 #include <boost/assign/std/vector.hpp>
diff --git a/src/lib/cc/tests/run_unittests.cc b/src/lib/cc/tests/run_unittests.cc
index 9aee35f..0908071 100644
--- a/src/lib/cc/tests/run_unittests.cc
+++ b/src/lib/cc/tests/run_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 int
diff --git a/src/lib/cc/tests/session_unittests.cc b/src/lib/cc/tests/session_unittests.cc
index fbb18e0..d61cbd3 100644
--- a/src/lib/cc/tests/session_unittests.cc
+++ b/src/lib/cc/tests/session_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: data_unittests.cc 1899 2010-05-21 12:03:59Z jelte $
-
 #include <config.h>
 
 // for some IPC/network system calls in asio/detail/pipe_select_interrupter.hpp 
diff --git a/src/lib/config/ccsession.cc b/src/lib/config/ccsession.cc
index 09a1c9c..7049565 100644
--- a/src/lib/config/ccsession.cc
+++ b/src/lib/config/ccsession.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // 
 // todo: generalize this and make it into a specific API for all modules
 //       to use (i.e. connect to cc, send config and commands, get config,
diff --git a/src/lib/config/ccsession.h b/src/lib/config/ccsession.h
index b0477a3..d8d1eeb 100644
--- a/src/lib/config/ccsession.h
+++ b/src/lib/config/ccsession.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __CCSESSION_H
 #define __CCSESSION_H 1
 
diff --git a/src/lib/config/config_data.cc b/src/lib/config/config_data.cc
index 01acd99..1fa37c1 100644
--- a/src/lib/config/config_data.cc
+++ b/src/lib/config/config_data.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config/config_data.h>
 
 #include <boost/foreach.hpp>
diff --git a/src/lib/config/config_data.h b/src/lib/config/config_data.h
index 423f0dd..29a5b5f 100644
--- a/src/lib/config/config_data.h
+++ b/src/lib/config/config_data.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __CONFIG_DATA_H
 #define __CONFIG_DATA_H 1
 
diff --git a/src/lib/config/tests/ccsession_unittests.cc b/src/lib/config/tests/ccsession_unittests.cc
index 00d09d6..4ed3ce2 100644
--- a/src/lib/config/tests/ccsession_unittests.cc
+++ b/src/lib/config/tests/ccsession_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: module_spec_unittests.cc 1321 2010-03-11 10:17:03Z jelte $
-
 #include <config.h>
 
 #include <gtest/gtest.h>
diff --git a/src/lib/config/tests/config_data_unittests.cc b/src/lib/config/tests/config_data_unittests.cc
index d5d4d53..974812d 100644
--- a/src/lib/config/tests/config_data_unittests.cc
+++ b/src/lib/config/tests/config_data_unittests.cc
@@ -13,8 +13,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <config/tests/data_def_unittests_config.h>
diff --git a/src/lib/config/tests/fake_session.cc b/src/lib/config/tests/fake_session.cc
index ad04390..29744c7 100644
--- a/src/lib/config/tests/fake_session.cc
+++ b/src/lib/config/tests/fake_session.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: session.cc 1250 2010-03-09 22:52:15Z jinmei $
-
 #include <config.h>
 
 #include <stdint.h>
diff --git a/src/lib/config/tests/fake_session.h b/src/lib/config/tests/fake_session.h
index 2150ef5..ac8e291 100644
--- a/src/lib/config/tests/fake_session.h
+++ b/src/lib/config/tests/fake_session.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: session.h 1250 2010-03-09 22:52:15Z jinmei $
-
 #ifndef _ISC_FAKESESSION_H
 #define _ISC_FAKESESSION_H 1
 
diff --git a/src/lib/config/tests/module_spec_unittests.cc b/src/lib/config/tests/module_spec_unittests.cc
index 7a55fbc..8490aa0 100644
--- a/src/lib/config/tests/module_spec_unittests.cc
+++ b/src/lib/config/tests/module_spec_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <config/module_spec.h>
diff --git a/src/lib/config/tests/run_unittests.cc b/src/lib/config/tests/run_unittests.cc
index 9aee35f..0908071 100644
--- a/src/lib/config/tests/run_unittests.cc
+++ b/src/lib/config/tests/run_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 int
diff --git a/src/lib/datasrc/cache.cc b/src/lib/datasrc/cache.cc
index 64bffb3..6fff754 100644
--- a/src/lib/datasrc/cache.cc
+++ b/src/lib/datasrc/cache.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <map>
diff --git a/src/lib/datasrc/cache.h b/src/lib/datasrc/cache.h
index 1a7d9fe..054912c 100644
--- a/src/lib/datasrc/cache.h
+++ b/src/lib/datasrc/cache.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __CACHE_H
 #define __CACHE_H
 
diff --git a/src/lib/datasrc/data_source.cc b/src/lib/datasrc/data_source.cc
index 980319f..8b2b47e 100644
--- a/src/lib/datasrc/data_source.cc
+++ b/src/lib/datasrc/data_source.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <cassert>
diff --git a/src/lib/datasrc/data_source.h b/src/lib/datasrc/data_source.h
index 411ea3d..ff695da 100644
--- a/src/lib/datasrc/data_source.h
+++ b/src/lib/datasrc/data_source.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __DATA_SOURCE_H
 #define __DATA_SOURCE_H
 
diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc
index 6fee000..f0b8b53 100644
--- a/src/lib/datasrc/memory_datasrc.cc
+++ b/src/lib/datasrc/memory_datasrc.cc
@@ -19,6 +19,7 @@
 
 #include <dns/name.h>
 #include <dns/rrclass.h>
+#include <dns/rrsetlist.h>
 #include <dns/masterload.h>
 
 #include <datasrc/memory_datasrc.h>
@@ -73,6 +74,15 @@ struct MemoryZone::MemoryZoneImpl {
         if (!rrset) {
             isc_throw(NullRRset, "The rrset provided is NULL");
         }
+        if (rrset->getType() == RRType::CNAME() &&
+            rrset->getRdataCount() > 1) {
+            // XXX: this is not only for CNAME.  We should generalize this
+            // code for all other "singleton RR types" (such as SOA) in a
+            // separate task.
+            isc_throw(AddError, "multiple RRs of singleton type for "
+                      << rrset->getName());
+        }
+
         Name name(rrset->getName());
         NameComparisonResult compare(origin_.compare(name));
         if (compare.getRelation() != NameComparisonResult::SUPERDOMAIN &&
@@ -92,7 +102,7 @@ struct MemoryZone::MemoryZoneImpl {
             default:
                 assert(0);
         }
-        assert(node);
+        assert(node != NULL);
 
         // Now get the domain
         DomainPtr domain;
@@ -104,6 +114,25 @@ struct MemoryZone::MemoryZoneImpl {
             domain = node->getData();
         }
 
+        // Ensure CNAME and other type of RR don't coexist for the same
+        // owner name.
+        // Note: when the check fails and the exception is thrown, it may
+        // break strong exception guarantee.  At the moment we prefer
+        // code simplicity and don't bother to introduce complicated
+        // recovery code.
+        if (rrset->getType() == RRType::CNAME()) {
+            // XXX: this check will become incorrect when we support DNSSEC
+            // (depending on how we support DNSSEC).  We should revisit it
+            // at that point.
+            if (!domain->empty()) {
+                isc_throw(AddError, "CNAME can't be added with other data for "
+                          << rrset->getName());
+            }
+        } else if (domain->find(RRType::CNAME()) != domain->end()) {
+            isc_throw(AddError, "CNAME and " << rrset->getType() <<
+                      " can't coexist for " << rrset->getName());
+        }
+
         // Try inserting the rrset there
         if (domain->insert(DomainPair(rrset->getType(), rrset)).second) {
             // Ok, we just put it in
@@ -185,9 +214,10 @@ struct MemoryZone::MemoryZoneImpl {
         return (false);
     }
 
+
     // Implementation of MemoryZone::find
     FindResult find(const Name& name, RRType type,
-                    const FindOptions options) const
+                    RRsetList* target, const FindOptions options) const
     {
         // Get the node
         DomainNode* node(NULL);
@@ -222,18 +252,31 @@ struct MemoryZone::MemoryZoneImpl {
             }
         }
 
+        // handle type any query
+        if (target && !node->getData()->empty()) {
+            // Empty domain will be handled as NXRRSET by normal processing
+            for (found = node->getData()->begin();
+                 found != node->getData()->end(); found++)
+            {
+                target->addRRset(
+                    boost::const_pointer_cast<RRset>(found->second));
+            }
+            return (FindResult(SUCCESS, ConstRRsetPtr()));
+        }
+
         found = node->getData()->find(type);
         if (found != node->getData()->end()) {
             // Good, it is here
             return (FindResult(SUCCESS, found->second));
         } else {
-            /*
-             * TODO Look for CNAME and DNAME (it should be OK to do so when
-             * the value is not found, as CNAME/DNAME domain should be
-             * empty otherwise.)
-             */
-            return (FindResult(NXRRSET, ConstRRsetPtr()));
+            // Next, try CNAME.
+            found = node->getData()->find(RRType::CNAME());
+            if (found != node->getData()->end()) {
+                return (FindResult(CNAME, found->second));
+            }
         }
+        // No exact match or CNAME.  Return NXRRSET.
+        return (FindResult(NXRRSET, ConstRRsetPtr()));
     }
 };
 
@@ -258,9 +301,9 @@ MemoryZone::getClass() const {
 
 Zone::FindResult
 MemoryZone::find(const Name& name, const RRType& type,
-                 const FindOptions options) const
+                 RRsetList* target, const FindOptions options) const
 {
-    return (impl_->find(name, type, options));
+    return (impl_->find(name, type, target, options));
 }
 
 result::Result
diff --git a/src/lib/datasrc/memory_datasrc.h b/src/lib/datasrc/memory_datasrc.h
index 63d25e7..5a2c74e 100644
--- a/src/lib/datasrc/memory_datasrc.h
+++ b/src/lib/datasrc/memory_datasrc.h
@@ -22,6 +22,7 @@
 namespace isc {
 namespace dns {
 class Name;
+class RRsetList;
 };
 
 namespace datasrc {
@@ -55,26 +56,35 @@ public:
 
     /// \brief Returns the origin of the zone.
     virtual const isc::dns::Name& getOrigin() const;
+
     /// \brief Returns the class of the zone.
     virtual const isc::dns::RRClass& getClass() const;
+
     /// \brief Looks up an RRset in the zone.
     ///
     /// See documentation in \c Zone.
     ///
-    /// It returns NULL pointer in case of NXDOMAIN and NXRRSET
+    /// It returns NULL pointer in case of NXDOMAIN and NXRRSET,
+    /// and also SUCCESS if target is not NULL(TYPE_ANY query).
     /// (the base class documentation does not seem to require that).
     virtual FindResult find(const isc::dns::Name& name,
                             const isc::dns::RRType& type,
+                            isc::dns::RRsetList* target = NULL,
                             const FindOptions options = FIND_DEFAULT) const;
 
     /// \brief Inserts an rrset into the zone.
     ///
     /// It puts another RRset into the zone.
     ///
-    /// It throws NullRRset or OutOfZone if the provided rrset is invalid. It
-    /// might throw standard allocation exceptions, in which case this function
-    /// does not guarantee strong exception safety (it is currently not needed,
-    /// if it is needed in future, it should be implemented).
+    /// Except for NullRRset and OutOfZone, this method does not guarantee
+    /// strong exception safety (it is currently not needed, if it is needed
+    /// in future, it should be implemented).
+    ///
+    /// \throw NullRRset \c rrset is a NULL pointer.
+    /// \throw OutOfZone The owner name of \c rrset is outside of the
+    /// origin of the zone.
+    /// \throw AddError Other general errors.
+    /// \throw Others This method might throw standard allocation exceptions.
     ///
     /// \param rrset The set to add.
     /// \return SUCCESS or EXIST (if an rrset for given name and type already
@@ -100,6 +110,21 @@ public:
         { }
     };
 
+    /// \brief General failure exception for \c add().
+    ///
+    /// This is thrown against general error cases in adding an RRset
+    /// to the zone.
+    ///
+    /// Note: this exception would cover cases for \c OutOfZone or
+    /// \c NullRRset.  We'll need to clarify and unify the granularity
+    /// of exceptions eventually.  For now, exceptions are added as
+    /// developers see the need for it.
+    struct AddError : public InvalidParameter {
+        AddError(const char* file, size_t line, const char* what) :
+            InvalidParameter(file, line, what)
+        { }
+    };
+
     /// Return the master file name of the zone
     ///
     /// This method returns the name of the zone's master file to be loaded.
diff --git a/src/lib/datasrc/query.cc b/src/lib/datasrc/query.cc
index 4d8d025..d3de5c7 100644
--- a/src/lib/datasrc/query.cc
+++ b/src/lib/datasrc/query.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/name.h>
 #include <dns/rrset.h>
diff --git a/src/lib/datasrc/query.h b/src/lib/datasrc/query.h
index 57b0bca..43b62cc 100644
--- a/src/lib/datasrc/query.h
+++ b/src/lib/datasrc/query.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __QUERY_H
 #define __QUERY_H
 
diff --git a/src/lib/datasrc/sqlite3_datasrc.cc b/src/lib/datasrc/sqlite3_datasrc.cc
index 08e7482..ab910ba 100644
--- a/src/lib/datasrc/sqlite3_datasrc.cc
+++ b/src/lib/datasrc/sqlite3_datasrc.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 #include <sstream>
 
diff --git a/src/lib/datasrc/sqlite3_datasrc.h b/src/lib/datasrc/sqlite3_datasrc.h
index 0261630..d4abef7 100644
--- a/src/lib/datasrc/sqlite3_datasrc.h
+++ b/src/lib/datasrc/sqlite3_datasrc.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __DATA_SOURCE_SQLITE3_H
 #define __DATA_SOURCE_SQLITE3_H
 
diff --git a/src/lib/datasrc/static_datasrc.cc b/src/lib/datasrc/static_datasrc.cc
index 47d3d6c..025078a 100644
--- a/src/lib/datasrc/static_datasrc.cc
+++ b/src/lib/datasrc/static_datasrc.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <cassert>
diff --git a/src/lib/datasrc/static_datasrc.h b/src/lib/datasrc/static_datasrc.h
index 0cd14c1..4d212fe 100644
--- a/src/lib/datasrc/static_datasrc.h
+++ b/src/lib/datasrc/static_datasrc.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 //
 // Sample Datasource implementation; this datasource only returns
 // static content for the queries
@@ -76,9 +74,9 @@ public:
                             isc::dns::Name& target,
                             const isc::dns::Name* zonename) const;
 
-   Result findCoveringNSEC3(const isc::dns::Name& zonename,
-                            std::string& hash,
-                            isc::dns::RRsetList& target) const;
+    Result findCoveringNSEC3(const isc::dns::Name& zonename,
+                             std::string& hash,
+                             isc::dns::RRsetList& target) const;
 
     Result init();
     Result init(isc::data::ConstElementPtr config);
diff --git a/src/lib/datasrc/tests/cache_unittest.cc b/src/lib/datasrc/tests/cache_unittest.cc
index d7192f8..96beae0 100644
--- a/src/lib/datasrc/tests/cache_unittest.cc
+++ b/src/lib/datasrc/tests/cache_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdexcept>
 
 #include <dns/name.h>
diff --git a/src/lib/datasrc/tests/datasrc_unittest.cc b/src/lib/datasrc/tests/datasrc_unittest.cc
index 8718c12..bff7949 100644
--- a/src/lib/datasrc/tests/datasrc_unittest.cc
+++ b/src/lib/datasrc/tests/datasrc_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <iostream>
diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
index 9862f29..8d1703d 100644
--- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc
+++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
@@ -15,7 +15,10 @@
 #include <exceptions/exceptions.h>
 
 #include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
 #include <dns/rrclass.h>
+#include <dns/rrsetlist.h>
 #include <dns/rrttl.h>
 #include <dns/masterload.h>
 
@@ -24,6 +27,7 @@
 #include <gtest/gtest.h>
 
 using namespace isc::dns;
+using namespace isc::dns::rdata;
 using namespace isc::datasrc;
 
 namespace {
@@ -142,6 +146,7 @@ public:
         class_(RRClass::IN()),
         origin_("example.org"),
         ns_name_("ns.example.org"),
+        cname_name_("cname.example.org"),
         child_ns_name_("child.example.org"),
         child_glue_name_("ns.child.example.org"),
         grandchild_ns_name_("grand.child.example.org"),
@@ -153,6 +158,8 @@ public:
         rr_ns_a_(new RRset(ns_name_, class_, RRType::A(), RRTTL(300))),
         rr_ns_aaaa_(new RRset(ns_name_, class_, RRType::AAAA(), RRTTL(300))),
         rr_a_(new RRset(origin_, class_, RRType::A(), RRTTL(300))),
+        rr_cname_(new RRset(cname_name_, class_, RRType::CNAME(), RRTTL(300))),
+        rr_cname_a_(new RRset(cname_name_, class_, RRType::A(), RRTTL(300))),
         rr_child_ns_(new RRset(child_ns_name_, class_, RRType::NS(),
                                RRTTL(300))),
         rr_child_glue_(new RRset(child_glue_name_, class_, RRType::A(),
@@ -165,8 +172,8 @@ public:
     }
     // Some data to test with
     const RRClass class_;
-    const Name origin_, ns_name_, child_ns_name_, child_glue_name_,
-        grandchild_ns_name_, grandchild_glue_name_;
+    const Name origin_, ns_name_, cname_name_, child_ns_name_,
+        child_glue_name_, grandchild_ns_name_, grandchild_glue_name_;
     // The zone to torture by tests
     MemoryZone zone_;
 
@@ -187,6 +194,8 @@ public:
         rr_ns_aaaa_,
         // A of example.org
         rr_a_;
+    RRsetPtr rr_cname_;         // CNAME in example.org (RDATA will be added)
+    ConstRRsetPtr rr_cname_a_; // for mixed CNAME + A case
     ConstRRsetPtr rr_child_ns_; // NS of a child domain (for delegation)
     ConstRRsetPtr rr_child_glue_; // glue RR of the child domain
     ConstRRsetPtr rr_grandchild_ns_; // NS below a zone cut (unusual)
@@ -211,7 +220,8 @@ public:
     void findTest(const Name& name, const RRType& rrtype, Zone::Result result,
                   bool check_answer = true,
                   const ConstRRsetPtr& answer = ConstRRsetPtr(),
-                  MemoryZone *zone = NULL,
+                  RRsetList* target = NULL,
+                  MemoryZone* zone = NULL,
                   Zone::FindOptions options = Zone::FIND_DEFAULT)
     {
         if (!zone) {
@@ -220,7 +230,7 @@ public:
         // The whole block is inside, because we need to check the result and
         // we can't assign to FindResult
         EXPECT_NO_THROW({
-                Zone::FindResult find_result(zone->find(name, rrtype,
+                Zone::FindResult find_result(zone->find(name, rrtype, target,
                                                         options));
                 // Check it returns correct answers
                 EXPECT_EQ(result, find_result.code);
@@ -264,6 +274,50 @@ TEST_F(MemoryZoneTest, add) {
     EXPECT_NO_THROW(EXPECT_EQ(EXIST, zone_.add(rr_ns_a_)));
 }
 
+TEST_F(MemoryZoneTest, addMultipleCNAMEs) {
+    rr_cname_->addRdata(generic::CNAME("canonical1.example.org."));
+    rr_cname_->addRdata(generic::CNAME("canonical2.example.org."));
+    EXPECT_THROW(zone_.add(rr_cname_), MemoryZone::AddError);
+}
+
+TEST_F(MemoryZoneTest, addCNAMEThenOther) {
+    rr_cname_->addRdata(generic::CNAME("canonical.example.org."));
+    EXPECT_EQ(SUCCESS, zone_.add(rr_cname_));
+    EXPECT_THROW(zone_.add(rr_cname_a_), MemoryZone::AddError);
+}
+
+TEST_F(MemoryZoneTest, addOtherThenCNAME) {
+    rr_cname_->addRdata(generic::CNAME("canonical.example.org."));
+    EXPECT_EQ(SUCCESS, zone_.add(rr_cname_a_));
+    EXPECT_THROW(zone_.add(rr_cname_), MemoryZone::AddError);
+}
+
+TEST_F(MemoryZoneTest, findCNAME) {
+    // install CNAME RR
+    rr_cname_->addRdata(generic::CNAME("canonical.example.org."));
+    EXPECT_EQ(SUCCESS, zone_.add(rr_cname_));
+
+    // Find A RR of the same.  Should match the CNAME
+    findTest(cname_name_, RRType::NS(), Zone::CNAME, true, rr_cname_);
+
+    // Find the CNAME itself.  Should result in normal SUCCESS
+    findTest(cname_name_, RRType::CNAME(), Zone::SUCCESS, true, rr_cname_);
+}
+
+TEST_F(MemoryZoneTest, findCNAMEUnderZoneCut) {
+    // There's nothing special when we find a CNAME under a zone cut
+    // (with FIND_GLUE_OK).  The behavior is different from BIND 9,
+    // so we test this case explicitly.
+    EXPECT_EQ(SUCCESS, zone_.add(rr_child_ns_));
+    RRsetPtr rr_cname_under_cut_(new RRset(Name("cname.child.example.org"),
+                                           class_, RRType::CNAME(),
+                                           RRTTL(300)));
+    EXPECT_EQ(SUCCESS, zone_.add(rr_cname_under_cut_));
+    findTest(Name("cname.child.example.org"), RRType::AAAA(),
+             Zone::CNAME, true, rr_cname_under_cut_, NULL, NULL,
+             Zone::FIND_GLUE_OK);
+}
+
 // Test adding child zones and zone cut handling
 TEST_F(MemoryZoneTest, delegationNS) {
     // add in-zone data
@@ -292,6 +346,51 @@ TEST_F(MemoryZoneTest, delegationNS) {
              Zone::DELEGATION, true, rr_child_ns_); // note: !rr_grandchild_ns_
 }
 
+TEST_F(MemoryZoneTest, findAny) {
+    EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_a_)));
+    EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_)));
+    EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_child_glue_)));
+
+    // origin
+    RRsetList origin_rrsets;
+    findTest(origin_, RRType::ANY(), Zone::SUCCESS, true,
+             ConstRRsetPtr(), &origin_rrsets);
+    EXPECT_EQ(2, origin_rrsets.size());
+    EXPECT_EQ(rr_a_, origin_rrsets.findRRset(RRType::A(), RRClass::IN()));
+    EXPECT_EQ(rr_ns_, origin_rrsets.findRRset(RRType::NS(), RRClass::IN()));
+
+    // out zone name
+    RRsetList out_rrsets;
+    findTest(Name("example.com"), RRType::ANY(), Zone::NXDOMAIN, true,
+             ConstRRsetPtr(), &out_rrsets);
+    EXPECT_EQ(0, out_rrsets.size());
+
+    RRsetList glue_child_rrsets;
+    findTest(child_glue_name_, RRType::ANY(), Zone::SUCCESS, true,
+                ConstRRsetPtr(), &glue_child_rrsets);
+    EXPECT_EQ(rr_child_glue_, glue_child_rrsets.findRRset(RRType::A(),
+                                                     RRClass::IN()));
+    EXPECT_EQ(1, glue_child_rrsets.size());
+
+    // TODO: test NXRRSET case after rbtree non-terminal logic has
+    // been implemented
+
+    // add zone cut
+    EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_child_ns_)));
+
+    // zone cut
+    RRsetList child_rrsets;
+    findTest(child_ns_name_, RRType::ANY(), Zone::DELEGATION, true,
+             rr_child_ns_, &child_rrsets);
+    EXPECT_EQ(0, child_rrsets.size());
+
+    // glue for this zone cut
+    RRsetList new_glue_child_rrsets;
+    findTest(child_glue_name_, RRType::ANY(), Zone::DELEGATION, true,
+                rr_child_ns_, &new_glue_child_rrsets);
+    EXPECT_EQ(0, new_glue_child_rrsets.size());
+}
+
 TEST_F(MemoryZoneTest, glue) {
     // install zone data:
     // a zone cut
@@ -310,15 +409,15 @@ TEST_F(MemoryZoneTest, glue) {
 
     // If we do it in the "glue OK" mode, we should find the exact match.
     findTest(child_glue_name_, RRType::A(), Zone::SUCCESS, true,
-             rr_child_glue_, NULL, Zone::FIND_GLUE_OK);
+             rr_child_glue_, NULL, NULL, Zone::FIND_GLUE_OK);
 
     // glue OK + NXRRSET case
     findTest(child_glue_name_, RRType::AAAA(), Zone::NXRRSET, true,
-             ConstRRsetPtr(), NULL, Zone::FIND_GLUE_OK);
+             ConstRRsetPtr(), NULL, NULL, Zone::FIND_GLUE_OK);
 
     // glue OK + NXDOMAIN case
     findTest(Name("www.child.example.org"), RRType::A(), Zone::DELEGATION,
-             true, rr_child_ns_, NULL, Zone::FIND_GLUE_OK);
+             true, rr_child_ns_, NULL, NULL, Zone::FIND_GLUE_OK);
 
     // TODO:
     // glue name would match a wildcard under a zone cut: wildcard match
@@ -327,12 +426,13 @@ TEST_F(MemoryZoneTest, glue) {
 
     // nested cut case.  The glue should be found.
     findTest(grandchild_glue_name_, RRType::AAAA(), Zone::SUCCESS,
-             true, rr_grandchild_glue_, NULL, Zone::FIND_GLUE_OK);    
+             true, rr_grandchild_glue_, NULL, NULL, Zone::FIND_GLUE_OK);
 
     // A non-existent name in nested cut.  This should result in delegation
     // at the highest zone cut.
     findTest(Name("www.grand.child.example.org"), RRType::TXT(),
-             Zone::DELEGATION, true, rr_child_ns_, NULL, Zone::FIND_GLUE_OK);
+             Zone::DELEGATION, true, rr_child_ns_, NULL, NULL,
+             Zone::FIND_GLUE_OK);
 }
 
 // Test adding DNAMEs and resulting delegation handling
@@ -391,14 +491,14 @@ TEST_F(MemoryZoneTest, load) {
 
     // Now see there are some rrsets (we don't look inside, though)
     findTest(Name("."), RRType::SOA(), Zone::SUCCESS, false, ConstRRsetPtr(),
-        &rootzone);
+        NULL, &rootzone);
     findTest(Name("."), RRType::NS(), Zone::SUCCESS, false, ConstRRsetPtr(),
-        &rootzone);
+        NULL, &rootzone);
     findTest(Name("a.root-servers.net."), RRType::A(), Zone::SUCCESS, false,
-        ConstRRsetPtr(), &rootzone);
+        ConstRRsetPtr(), NULL, &rootzone);
     // But this should no longer be here
     findTest(ns_name_, RRType::AAAA(), Zone::NXDOMAIN, true, ConstRRsetPtr(),
-        &rootzone);
+        NULL, &rootzone);
 
     // Try loading zone that is wrong in a different way
     EXPECT_THROW(zone_.load(TEST_DATA_DIR "/duplicate_rrset.zone"),
@@ -427,13 +527,13 @@ TEST_F(MemoryZoneTest, swap) {
     EXPECT_EQ(RRClass::IN(), zone2.getClass());
     // make sure the zone data is swapped, too
     findTest(origin_, RRType::NS(), Zone::NXDOMAIN, false, ConstRRsetPtr(),
-             &zone1);
+             NULL, &zone1);
     findTest(other_origin, RRType::TXT(), Zone::SUCCESS, false,
-             ConstRRsetPtr(), &zone1);
+             ConstRRsetPtr(), NULL, &zone1);
     findTest(origin_, RRType::NS(), Zone::SUCCESS, false, ConstRRsetPtr(),
-             &zone2);
+             NULL, &zone2);
     findTest(other_origin, RRType::TXT(), Zone::NXDOMAIN, false,
-             ConstRRsetPtr(), &zone2);
+             ConstRRsetPtr(), NULL, &zone2);
 }
 
 TEST_F(MemoryZoneTest, getFileName) {
@@ -459,4 +559,5 @@ TEST_F(MemoryZoneTest, getFileName) {
     EXPECT_EQ(TEST_DATA_DIR "/root.zone", zone_.getFileName());
     EXPECT_TRUE(rootzone.getFileName().empty());
 }
+
 }
diff --git a/src/lib/datasrc/tests/query_unittest.cc b/src/lib/datasrc/tests/query_unittest.cc
index a5758ad..fa7216b 100644
--- a/src/lib/datasrc/tests/query_unittest.cc
+++ b/src/lib/datasrc/tests/query_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <dns/buffer.h>
diff --git a/src/lib/datasrc/tests/run_unittests.cc b/src/lib/datasrc/tests/run_unittests.cc
index 20d5673..a35a646 100644
--- a/src/lib/datasrc/tests/run_unittests.cc
+++ b/src/lib/datasrc/tests/run_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <dns/tests/unittest_util.h>
diff --git a/src/lib/datasrc/tests/sqlite3_unittest.cc b/src/lib/datasrc/tests/sqlite3_unittest.cc
index 653b417..ce9413d 100644
--- a/src/lib/datasrc/tests/sqlite3_unittest.cc
+++ b/src/lib/datasrc/tests/sqlite3_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <algorithm>
diff --git a/src/lib/datasrc/tests/static_unittest.cc b/src/lib/datasrc/tests/static_unittest.cc
index 7685570..a11e889 100644
--- a/src/lib/datasrc/tests/static_unittest.cc
+++ b/src/lib/datasrc/tests/static_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 #include <string>
 #include <vector>
diff --git a/src/lib/datasrc/tests/test_datasrc.cc b/src/lib/datasrc/tests/test_datasrc.cc
index 6ed0266..8145539 100644
--- a/src/lib/datasrc/tests/test_datasrc.cc
+++ b/src/lib/datasrc/tests/test_datasrc.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <cassert>
diff --git a/src/lib/datasrc/tests/test_datasrc.h b/src/lib/datasrc/tests/test_datasrc.h
index 8335ca1..d0d67fc 100644
--- a/src/lib/datasrc/tests/test_datasrc.h
+++ b/src/lib/datasrc/tests/test_datasrc.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __TEST_DATA_SOURCE_H
 #define __TEST_DATA_SOURCE_H
 
diff --git a/src/lib/datasrc/tests/testdata/mkbrokendb.c b/src/lib/datasrc/tests/testdata/mkbrokendb.c
index aff4cd4..58f055c 100644
--- a/src/lib/datasrc/tests/testdata/mkbrokendb.c
+++ b/src/lib/datasrc/tests/testdata/mkbrokendb.c
@@ -14,8 +14,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 /*
  * This file is provided for reference purpose only.  A broken DB file, named
  * "brokendb.sqlite3" in this directory was created using this program.
diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h
index 3e72af1..f70274f 100644
--- a/src/lib/datasrc/zone.h
+++ b/src/lib/datasrc/zone.h
@@ -17,6 +17,7 @@
 #define __ZONE_H 1
 
 #include <datasrc/result.h>
+#include <dns/rrsetlist.h>
 
 namespace isc {
 namespace datasrc {
@@ -155,10 +156,19 @@ public:
     /// - If there is a matching name but no RRset of the search type, it
     ///   returns the code of \c NXRRSET, and, if DNSSEC is required,
     ///   the NSEC RRset for that name.
-    /// - If there is a matching name with CNAME, it returns the code of
-    ///   \c CNAME and that CNAME RR.
+    /// - If there is a CNAME RR of the searched name but there is no
+    ///   RR of the searched type of the name (so this type is different from
+    ///   CNAME), it returns the code of \c CNAME and that CNAME RR.
+    ///   Note that if the searched RR type is CNAME, it is considered
+    ///   a successful match, and the code of \c SUCCESS will be returned.
     /// - If the search name matches a delegation point of DNAME, it returns
     ///   the code of \c DNAME and that DNAME RR.
+    /// - If the target isn't NULL, all RRsets under the domain are inserted
+    ///   there and SUCCESS (or NXDOMAIN, in case of empty domain) is returned
+    ///   instead of normall processing. This is intended to handle ANY query.
+    ///   \note: this behavior is controversial as we discussed in
+    ///   https://lists.isc.org/pipermail/bind10-dev/2011-January/001918.html
+    ///   We should revisit the interface before we heavily rely on it.
     ///
     /// The \c options parameter specifies customized behavior of the search.
     /// Their semantics is as follows:
@@ -174,19 +184,19 @@ public:
     /// A derived version of this method may involve internal resource
     /// allocation, especially for constructing the resulting RRset, and may
     /// throw an exception if it fails.
+    /// It throws DuplicateRRset exception if there are duplicate rrsets under
+    /// the same domain.
     /// It should not throw other types of exceptions.
     ///
-    /// Note: It's quite likely that we'll need to specify search options.
-    /// For example, we should be able to specify whether to allow returning
-    /// glue records at or under a zone cut.  We leave this interface open
-    /// at this moment.
-    ///
     /// \param name The domain name to be searched for.
     /// \param type The RR type to be searched for.
+    /// \param target If target is not NULL, insert all RRs under the domain
+    /// into it.
     /// \param options The search options.
     /// \return A \c FindResult object enclosing the search result (see above).
     virtual FindResult find(const isc::dns::Name& name,
                             const isc::dns::RRType& type,
+                            isc::dns::RRsetList* target = NULL,
                             const FindOptions options
                             = FIND_DEFAULT) const = 0;
     //@}
diff --git a/src/lib/dns/buffer.h b/src/lib/dns/buffer.h
index fe24488..e100876 100644
--- a/src/lib/dns/buffer.h
+++ b/src/lib/dns/buffer.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __BUFFER_H
 #define __BUFFER_H 1
 
diff --git a/src/lib/dns/dnssectime.cc b/src/lib/dns/dnssectime.cc
index 856130a..04643e2 100644
--- a/src/lib/dns/dnssectime.cc
+++ b/src/lib/dns/dnssectime.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 #include <iomanip>
 #include <iostream>
diff --git a/src/lib/dns/dnssectime.h b/src/lib/dns/dnssectime.h
index 6999640..5069650 100644
--- a/src/lib/dns/dnssectime.h
+++ b/src/lib/dns/dnssectime.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __DNSSECTIME_H
 #define __DNSSECTIME_H 1
 
diff --git a/src/lib/dns/edns.cc b/src/lib/dns/edns.cc
index e70bb47..6e25624 100644
--- a/src/lib/dns/edns.cc
+++ b/src/lib/dns/edns.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <stdint.h>
diff --git a/src/lib/dns/edns.h b/src/lib/dns/edns.h
index 9ba9663..f9a5758 100644
--- a/src/lib/dns/edns.h
+++ b/src/lib/dns/edns.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __EDNS_H
 #define __EDNS_H 1
 
diff --git a/src/lib/dns/exceptions.cc b/src/lib/dns/exceptions.cc
index 61bbaa4..eb823b9 100644
--- a/src/lib/dns/exceptions.cc
+++ b/src/lib/dns/exceptions.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/exceptions.h>
 #include <dns/rcode.h>
 
diff --git a/src/lib/dns/exceptions.h b/src/lib/dns/exceptions.h
index c540d05..bd696a5 100644
--- a/src/lib/dns/exceptions.h
+++ b/src/lib/dns/exceptions.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // XXX: we have another exceptions.h, so we need to use a prefix "DNS_" in
 // the include guard.  More preferably, we should define a consistent naming
 // style for the header guide (e.g. module-name_file-name_H) throughout the
diff --git a/src/lib/dns/gen-rdatacode.py.in b/src/lib/dns/gen-rdatacode.py.in
index 6dc80b5..04e5c6a 100755
--- a/src/lib/dns/gen-rdatacode.py.in
+++ b/src/lib/dns/gen-rdatacode.py.in
@@ -14,8 +14,6 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 """\
 This is a supplemental script to (half) auto-generate DNS Rdata related
 classes and constants.
diff --git a/src/lib/dns/message.cc b/src/lib/dns/message.cc
index 0f5b1eb..b96e86d 100644
--- a/src/lib/dns/message.cc
+++ b/src/lib/dns/message.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <algorithm>
diff --git a/src/lib/dns/message.h b/src/lib/dns/message.h
index 3fa2c7b..153c7a9 100644
--- a/src/lib/dns/message.h
+++ b/src/lib/dns/message.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __MESSAGE_H
 #define __MESSAGE_H 1
 
@@ -511,6 +509,9 @@ public:
     ///
     /// With EDNS the maximum size can be increased per message.
     static const uint16_t DEFAULT_MAX_UDPSIZE = 512;
+
+    /// \brief The default maximum size of UDP DNS messages we can handle
+    static const uint16_t DEFAULT_MAX_EDNS0_UDPSIZE = 4096;
     //@}
 
 private:
diff --git a/src/lib/dns/messagerenderer.cc b/src/lib/dns/messagerenderer.cc
index 1ff4c25..212411a 100644
--- a/src/lib/dns/messagerenderer.cc
+++ b/src/lib/dns/messagerenderer.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <cctype>
 #include <cassert>
 #include <set>
diff --git a/src/lib/dns/messagerenderer.h b/src/lib/dns/messagerenderer.h
index c2ba9b0..9a7f149 100644
--- a/src/lib/dns/messagerenderer.h
+++ b/src/lib/dns/messagerenderer.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __MESSAGERENDERER_H
 #define __MESSAGERENDERER_H 1
 
diff --git a/src/lib/dns/name.cc b/src/lib/dns/name.cc
index 725d607..8786bcf 100644
--- a/src/lib/dns/name.cc
+++ b/src/lib/dns/name.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <cctype>
 #include <cassert>
 #include <iterator>
diff --git a/src/lib/dns/name.h b/src/lib/dns/name.h
index 84ae246..dc1b5b3 100644
--- a/src/lib/dns/name.h
+++ b/src/lib/dns/name.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NAME_H
 #define __NAME_H 1
 
diff --git a/src/lib/dns/opcode.cc b/src/lib/dns/opcode.cc
index 8141123..570dd81 100644
--- a/src/lib/dns/opcode.cc
+++ b/src/lib/dns/opcode.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 #include <ostream>
 
diff --git a/src/lib/dns/opcode.h b/src/lib/dns/opcode.h
index c5499c1..dd88062 100644
--- a/src/lib/dns/opcode.h
+++ b/src/lib/dns/opcode.h
@@ -14,8 +14,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 #include <stdint.h>
 
 #include <ostream>
diff --git a/src/lib/dns/python/edns_python.cc b/src/lib/dns/python/edns_python.cc
index dac2fb8..e54dba0 100644
--- a/src/lib/dns/python/edns_python.cc
+++ b/src/lib/dns/python/edns_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <cassert>
 
 #include <dns/edns.h>
diff --git a/src/lib/dns/python/message_python.cc b/src/lib/dns/python/message_python.cc
index 13b2644..e19547e 100644
--- a/src/lib/dns/python/message_python.cc
+++ b/src/lib/dns/python/message_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <exceptions/exceptions.h>
 #include <dns/message.h>
 using namespace isc::dns;
diff --git a/src/lib/dns/python/messagerenderer_python.cc b/src/lib/dns/python/messagerenderer_python.cc
index 3d154bd..91ab0c5 100644
--- a/src/lib/dns/python/messagerenderer_python.cc
+++ b/src/lib/dns/python/messagerenderer_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/messagerenderer.h>
 
 // For each class, we need a struct, a helper functions (init, destroy,
diff --git a/src/lib/dns/python/name_python.cc b/src/lib/dns/python/name_python.cc
index 47ea76f..3d7a196 100644
--- a/src/lib/dns/python/name_python.cc
+++ b/src/lib/dns/python/name_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 //
 // Declaration of the custom exceptions
 // Initialization and addition of these go in the module init at the
diff --git a/src/lib/dns/python/opcode_python.cc b/src/lib/dns/python/opcode_python.cc
index 3363dd1..0e2a30b 100644
--- a/src/lib/dns/python/opcode_python.cc
+++ b/src/lib/dns/python/opcode_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/opcode.h>
 
 using namespace isc::dns;
diff --git a/src/lib/dns/python/pydnspp.cc b/src/lib/dns/python/pydnspp.cc
index 0c4dce5..7b41598 100644
--- a/src/lib/dns/python/pydnspp.cc
+++ b/src/lib/dns/python/pydnspp.cc
@@ -23,8 +23,6 @@
 //
 // And of course care has to be taken that all identifiers be unique
 
-// $Id$
-
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include <structmember.h>
diff --git a/src/lib/dns/python/pydnspp_common.cc b/src/lib/dns/python/pydnspp_common.cc
index 1b10d6f..6c26367 100644
--- a/src/lib/dns/python/pydnspp_common.cc
+++ b/src/lib/dns/python/pydnspp_common.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <Python.h>
 #include <pydnspp_common.h>
 
diff --git a/src/lib/dns/python/pydnspp_common.h b/src/lib/dns/python/pydnspp_common.h
index 750e344..32e2b78 100644
--- a/src/lib/dns/python/pydnspp_common.h
+++ b/src/lib/dns/python/pydnspp_common.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __LIBDNS_PYTHON_COMMON_H
 #define __LIBDNS_PYTHON_COMMON_H 1
 
diff --git a/src/lib/dns/python/question_python.cc b/src/lib/dns/python/question_python.cc
index 378fc5d..a039284 100644
--- a/src/lib/dns/python/question_python.cc
+++ b/src/lib/dns/python/question_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: question_python.cc 1711 2010-04-14 15:14:53Z jelte $
-
 #include <dns/question.h>
 using namespace isc::dns;
 
diff --git a/src/lib/dns/python/rcode_python.cc b/src/lib/dns/python/rcode_python.cc
index 6b2b948..fce8eef 100644
--- a/src/lib/dns/python/rcode_python.cc
+++ b/src/lib/dns/python/rcode_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/rcode.h>
 
 using namespace isc::dns;
diff --git a/src/lib/dns/python/rdata_python.cc b/src/lib/dns/python/rdata_python.cc
index 3c9c45c..8579b7e 100644
--- a/src/lib/dns/python/rdata_python.cc
+++ b/src/lib/dns/python/rdata_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/rdata.h>
 using namespace isc::dns;
 using namespace isc::dns::rdata;
diff --git a/src/lib/dns/python/rrclass_python.cc b/src/lib/dns/python/rrclass_python.cc
index 66f93f2..3cfed4c 100644
--- a/src/lib/dns/python/rrclass_python.cc
+++ b/src/lib/dns/python/rrclass_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/rrclass.h>
 using namespace isc::dns;
 
diff --git a/src/lib/dns/python/rrset_python.cc b/src/lib/dns/python/rrset_python.cc
index 838e792..2292784 100644
--- a/src/lib/dns/python/rrset_python.cc
+++ b/src/lib/dns/python/rrset_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/rrset.h>
 
 //
diff --git a/src/lib/dns/python/rrttl_python.cc b/src/lib/dns/python/rrttl_python.cc
index 6885ea5..e7391d0 100644
--- a/src/lib/dns/python/rrttl_python.cc
+++ b/src/lib/dns/python/rrttl_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 
 #include <dns/rrttl.h>
diff --git a/src/lib/dns/python/rrtype_python.cc b/src/lib/dns/python/rrtype_python.cc
index 1c41a59..012f251 100644
--- a/src/lib/dns/python/rrtype_python.cc
+++ b/src/lib/dns/python/rrtype_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 
 #include <dns/rrtype.h>
diff --git a/src/lib/dns/python/tests/edns_python_test.py b/src/lib/dns/python/tests/edns_python_test.py
index a68342c..3f03c90 100644
--- a/src/lib/dns/python/tests/edns_python_test.py
+++ b/src/lib/dns/python/tests/edns_python_test.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 import unittest
 import os
 from pydnspp import *
diff --git a/src/lib/dns/python/tests/testutil.py b/src/lib/dns/python/tests/testutil.py
index 38e9762..679f827 100644
--- a/src/lib/dns/python/tests/testutil.py
+++ b/src/lib/dns/python/tests/testutil.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 #
 # helper functions for tests taken from C++ unittests
 #
diff --git a/src/lib/dns/python/tests/tsigkey_python_test.py b/src/lib/dns/python/tests/tsigkey_python_test.py
index 90b919d..06e6868 100644
--- a/src/lib/dns/python/tests/tsigkey_python_test.py
+++ b/src/lib/dns/python/tests/tsigkey_python_test.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 import unittest
 from pydnspp import *
 
diff --git a/src/lib/dns/python/tsigkey_python.cc b/src/lib/dns/python/tsigkey_python.cc
index 5e58b34..aa87909 100644
--- a/src/lib/dns/python/tsigkey_python.cc
+++ b/src/lib/dns/python/tsigkey_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <new>
 
 #include <dns/tsigkey.h>
diff --git a/src/lib/dns/question.cc b/src/lib/dns/question.cc
index 54a4262..3e14c78 100644
--- a/src/lib/dns/question.cc
+++ b/src/lib/dns/question.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <iostream>
 #include <string>
 
diff --git a/src/lib/dns/question.h b/src/lib/dns/question.h
index 3d72173..851de2c 100644
--- a/src/lib/dns/question.h
+++ b/src/lib/dns/question.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __QUESTION_H
 #define __QUESTION_H 1
 
@@ -230,10 +228,10 @@ public:
     //@}
 
     ///
-    /// \name Comparison Operator
+    /// \name Comparison Operators
     ///
     //@{
-    /// A comparison operator is needed for this class so it can
+    /// A "less than" operator is needed for this class so it can
     /// function as an index to std::map.
     bool operator <(const Question& rhs) const {
         return (rrclass_ < rhs.rrclass_ ||
@@ -241,6 +239,26 @@ public:
                  (rrtype_ < rhs.rrtype_ ||
                   (rrtype_ == rhs.rrtype_ && (name_ < rhs.name_)))));
     }
+
+    /// Equality operator.  Primarily used to compare the question section in
+    /// a response to that in the query.
+    ///
+    /// \param rhs Question to compare against
+    /// \return true if name, class and type are equal, false otherwise
+    bool operator==(const Question& rhs) const {
+        return ((rrclass_ == rhs.rrclass_) && (rrtype_ == rhs.rrtype_) &&
+                (name_ == rhs.name_));
+    }
+
+    /// Inequality operator.  Primarily used to compare the question section in
+    /// a response to that in the query.
+    ///
+    /// \param rhs Question to compare against
+    /// \return true if one or more of the name, class and type do not match,
+    /// false otherwise.
+    bool operator!=(const Question& rhs) const {
+        return (!operator==(rhs));
+    }
     //@}
 
 private:
diff --git a/src/lib/dns/rcode.cc b/src/lib/dns/rcode.cc
index c02ab6a..ee41b1e 100644
--- a/src/lib/dns/rcode.cc
+++ b/src/lib/dns/rcode.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 #include <sstream>
 #include <ostream>
diff --git a/src/lib/dns/rcode.h b/src/lib/dns/rcode.h
index 8b88b1b..0c63285 100644
--- a/src/lib/dns/rcode.h
+++ b/src/lib/dns/rcode.h
@@ -14,8 +14,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 #include <stdint.h>
 
 #include <ostream>
diff --git a/src/lib/dns/rdata.cc b/src/lib/dns/rdata.cc
index 7f66fe3..17fee25 100644
--- a/src/lib/dns/rdata.cc
+++ b/src/lib/dns/rdata.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <algorithm>
 #include <cctype>
 #include <string>
diff --git a/src/lib/dns/rdata.h b/src/lib/dns/rdata.h
index 3f4aaf9..8eaedd3 100644
--- a/src/lib/dns/rdata.h
+++ b/src/lib/dns/rdata.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __RDATA_H
 #define __RDATA_H 1
 
diff --git a/src/lib/dns/rdata/any_255/tsig_250.cc b/src/lib/dns/rdata/any_255/tsig_250.cc
index ebb2667..e025ce4 100644
--- a/src/lib/dns/rdata/any_255/tsig_250.cc
+++ b/src/lib/dns/rdata/any_255/tsig_250.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 #include <sstream>
 #include <vector>
diff --git a/src/lib/dns/rdata/any_255/tsig_250.h b/src/lib/dns/rdata/any_255/tsig_250.h
index 5887695..ff24925 100644
--- a/src/lib/dns/rdata/any_255/tsig_250.h
+++ b/src/lib/dns/rdata/any_255/tsig_250.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <stdint.h>
diff --git a/src/lib/dns/rdata/ch_3/a_1.cc b/src/lib/dns/rdata/ch_3/a_1.cc
index dda84fd..376cbdd 100644
--- a/src/lib/dns/rdata/ch_3/a_1.cc
+++ b/src/lib/dns/rdata/ch_3/a_1.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/dns/rdata/ch_3/a_1.h b/src/lib/dns/rdata/ch_3/a_1.h
index 9e827bb..6d75952 100644
--- a/src/lib/dns/rdata/ch_3/a_1.h
+++ b/src/lib/dns/rdata/ch_3/a_1.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/cname_5.cc b/src/lib/dns/rdata/generic/cname_5.cc
index d4d57c9..c7f97d0 100644
--- a/src/lib/dns/rdata/generic/cname_5.cc
+++ b/src/lib/dns/rdata/generic/cname_5.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/cname_5.h b/src/lib/dns/rdata/generic/cname_5.h
index 9630cea..92dffad 100644
--- a/src/lib/dns/rdata/generic/cname_5.h
+++ b/src/lib/dns/rdata/generic/cname_5.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/dname_39.cc b/src/lib/dns/rdata/generic/dname_39.cc
index 01e4d35..b88720e 100644
--- a/src/lib/dns/rdata/generic/dname_39.cc
+++ b/src/lib/dns/rdata/generic/dname_39.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/dname_39.h b/src/lib/dns/rdata/generic/dname_39.h
index 7a12abd..5e12167 100644
--- a/src/lib/dns/rdata/generic/dname_39.h
+++ b/src/lib/dns/rdata/generic/dname_39.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/dnskey_48.cc b/src/lib/dns/rdata/generic/dnskey_48.cc
index 5ec9b7d..16a748e 100644
--- a/src/lib/dns/rdata/generic/dnskey_48.cc
+++ b/src/lib/dns/rdata/generic/dnskey_48.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <iostream>
 #include <string>
 #include <sstream>
diff --git a/src/lib/dns/rdata/generic/dnskey_48.h b/src/lib/dns/rdata/generic/dnskey_48.h
index e676227..14fad9f 100644
--- a/src/lib/dns/rdata/generic/dnskey_48.h
+++ b/src/lib/dns/rdata/generic/dnskey_48.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/ds_43.cc b/src/lib/dns/rdata/generic/ds_43.cc
index 8b69b46..cca19ae 100644
--- a/src/lib/dns/rdata/generic/ds_43.cc
+++ b/src/lib/dns/rdata/generic/ds_43.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <iostream>
 #include <string>
 #include <sstream>
diff --git a/src/lib/dns/rdata/generic/ds_43.h b/src/lib/dns/rdata/generic/ds_43.h
index e88c339..03b19a0 100644
--- a/src/lib/dns/rdata/generic/ds_43.h
+++ b/src/lib/dns/rdata/generic/ds_43.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/mx_15.cc b/src/lib/dns/rdata/generic/mx_15.cc
index 1b87853..0ae2251 100644
--- a/src/lib/dns/rdata/generic/mx_15.cc
+++ b/src/lib/dns/rdata/generic/mx_15.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/mx_15.h b/src/lib/dns/rdata/generic/mx_15.h
index 50c8c98..1381f18 100644
--- a/src/lib/dns/rdata/generic/mx_15.h
+++ b/src/lib/dns/rdata/generic/mx_15.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <stdint.h>
diff --git a/src/lib/dns/rdata/generic/ns_2.cc b/src/lib/dns/rdata/generic/ns_2.cc
index 97d224b..0e56911 100644
--- a/src/lib/dns/rdata/generic/ns_2.cc
+++ b/src/lib/dns/rdata/generic/ns_2.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/ns_2.h b/src/lib/dns/rdata/generic/ns_2.h
index 4e7d0b7..fa44f22 100644
--- a/src/lib/dns/rdata/generic/ns_2.h
+++ b/src/lib/dns/rdata/generic/ns_2.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: rdata.h 545 2010-01-27 00:33:28Z jinmei $
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/nsec3_50.cc b/src/lib/dns/rdata/generic/nsec3_50.cc
index 369f80e..c20fda2 100644
--- a/src/lib/dns/rdata/generic/nsec3_50.cc
+++ b/src/lib/dns/rdata/generic/nsec3_50.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <iostream>
 #include <iomanip>
 #include <string>
diff --git a/src/lib/dns/rdata/generic/nsec3_50.h b/src/lib/dns/rdata/generic/nsec3_50.h
index eeec8bb..5532071 100644
--- a/src/lib/dns/rdata/generic/nsec3_50.h
+++ b/src/lib/dns/rdata/generic/nsec3_50.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: nsec_47.h 991 2010-02-26 08:53:26Z jinmei $
-
 #include <stdint.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/nsec3param_51.cc b/src/lib/dns/rdata/generic/nsec3param_51.cc
index ad38fca..639feed 100644
--- a/src/lib/dns/rdata/generic/nsec3param_51.cc
+++ b/src/lib/dns/rdata/generic/nsec3param_51.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <iostream>
 #include <string>
 #include <sstream>
diff --git a/src/lib/dns/rdata/generic/nsec3param_51.h b/src/lib/dns/rdata/generic/nsec3param_51.h
index cad236f..130c759 100644
--- a/src/lib/dns/rdata/generic/nsec3param_51.h
+++ b/src/lib/dns/rdata/generic/nsec3param_51.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/nsec_47.cc b/src/lib/dns/rdata/generic/nsec_47.cc
index 0d66e82..0859edd 100644
--- a/src/lib/dns/rdata/generic/nsec_47.cc
+++ b/src/lib/dns/rdata/generic/nsec_47.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <iostream>
 #include <string>
 #include <sstream>
diff --git a/src/lib/dns/rdata/generic/nsec_47.h b/src/lib/dns/rdata/generic/nsec_47.h
index 0140bca..b86a25b 100644
--- a/src/lib/dns/rdata/generic/nsec_47.h
+++ b/src/lib/dns/rdata/generic/nsec_47.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/opt_41.cc b/src/lib/dns/rdata/generic/opt_41.cc
index 33a6e4c..1aae810 100644
--- a/src/lib/dns/rdata/generic/opt_41.cc
+++ b/src/lib/dns/rdata/generic/opt_41.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/opt_41.h b/src/lib/dns/rdata/generic/opt_41.h
index d62d870..0cb7043 100644
--- a/src/lib/dns/rdata/generic/opt_41.h
+++ b/src/lib/dns/rdata/generic/opt_41.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/ptr_12.cc b/src/lib/dns/rdata/generic/ptr_12.cc
index 5d1abf4..dc656b8 100644
--- a/src/lib/dns/rdata/generic/ptr_12.cc
+++ b/src/lib/dns/rdata/generic/ptr_12.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/ptr_12.h b/src/lib/dns/rdata/generic/ptr_12.h
index 8fc42db..5d2d048 100644
--- a/src/lib/dns/rdata/generic/ptr_12.h
+++ b/src/lib/dns/rdata/generic/ptr_12.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/rrsig_46.cc b/src/lib/dns/rdata/generic/rrsig_46.cc
index 17f32e8..6e6c5fb 100644
--- a/src/lib/dns/rdata/generic/rrsig_46.cc
+++ b/src/lib/dns/rdata/generic/rrsig_46.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 #include <iomanip>
 #include <iostream>
diff --git a/src/lib/dns/rdata/generic/rrsig_46.h b/src/lib/dns/rdata/generic/rrsig_46.h
index 3cc254a..19acc40 100644
--- a/src/lib/dns/rdata/generic/rrsig_46.h
+++ b/src/lib/dns/rdata/generic/rrsig_46.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/soa_6.cc b/src/lib/dns/rdata/generic/soa_6.cc
index 5519030..c4b87c6 100644
--- a/src/lib/dns/rdata/generic/soa_6.cc
+++ b/src/lib/dns/rdata/generic/soa_6.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/soa_6.h b/src/lib/dns/rdata/generic/soa_6.h
index fc847ff..3f6185e 100644
--- a/src/lib/dns/rdata/generic/soa_6.h
+++ b/src/lib/dns/rdata/generic/soa_6.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/generic/txt_16.cc b/src/lib/dns/rdata/generic/txt_16.cc
index 69ecb20..0e20f4e 100644
--- a/src/lib/dns/rdata/generic/txt_16.cc
+++ b/src/lib/dns/rdata/generic/txt_16.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 #include <string.h>
 
diff --git a/src/lib/dns/rdata/generic/txt_16.h b/src/lib/dns/rdata/generic/txt_16.h
index 33a1ee2..b4c791f 100644
--- a/src/lib/dns/rdata/generic/txt_16.h
+++ b/src/lib/dns/rdata/generic/txt_16.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <stdint.h>
diff --git a/src/lib/dns/rdata/hs_4/a_1.cc b/src/lib/dns/rdata/hs_4/a_1.cc
index dda84fd..376cbdd 100644
--- a/src/lib/dns/rdata/hs_4/a_1.cc
+++ b/src/lib/dns/rdata/hs_4/a_1.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/dns/rdata/hs_4/a_1.h b/src/lib/dns/rdata/hs_4/a_1.h
index 9e827bb..6d75952 100644
--- a/src/lib/dns/rdata/hs_4/a_1.h
+++ b/src/lib/dns/rdata/hs_4/a_1.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/in_1/a_1.cc b/src/lib/dns/rdata/in_1/a_1.cc
index f9d3599..ddd03f8 100644
--- a/src/lib/dns/rdata/in_1/a_1.cc
+++ b/src/lib/dns/rdata/in_1/a_1.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: rdata.cc 545 2010-01-27 00:33:28Z jinmei $
-
 #include <stdint.h>
 #include <string.h>
 
diff --git a/src/lib/dns/rdata/in_1/a_1.h b/src/lib/dns/rdata/in_1/a_1.h
index d684267..6e98f0d 100644
--- a/src/lib/dns/rdata/in_1/a_1.h
+++ b/src/lib/dns/rdata/in_1/a_1.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: rdata.h 545 2010-01-27 00:33:28Z jinmei $
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rdata/in_1/aaaa_28.cc b/src/lib/dns/rdata/in_1/aaaa_28.cc
index f9bf54b..45c4682 100644
--- a/src/lib/dns/rdata/in_1/aaaa_28.cc
+++ b/src/lib/dns/rdata/in_1/aaaa_28.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 #include <string.h>
 
diff --git a/src/lib/dns/rdata/in_1/aaaa_28.h b/src/lib/dns/rdata/in_1/aaaa_28.h
index cf4f450..3093017 100644
--- a/src/lib/dns/rdata/in_1/aaaa_28.h
+++ b/src/lib/dns/rdata/in_1/aaaa_28.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <stdint.h>
diff --git a/src/lib/dns/rdata/template.cc b/src/lib/dns/rdata/template.cc
index f7eb08b..0e0bf46 100644
--- a/src/lib/dns/rdata/template.cc
+++ b/src/lib/dns/rdata/template.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/rdata/template.h b/src/lib/dns/rdata/template.h
index 9541af2..e85a839 100644
--- a/src/lib/dns/rdata/template.h
+++ b/src/lib/dns/rdata/template.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 // BEGIN_HEADER_GUARD
 
 #include <string>
diff --git a/src/lib/dns/rrclass-placeholder.h b/src/lib/dns/rrclass-placeholder.h
index 9d0c201..ce9a141 100644
--- a/src/lib/dns/rrclass-placeholder.h
+++ b/src/lib/dns/rrclass-placeholder.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: rrclass.h 530 2010-01-26 22:15:42Z jinmei $
-
 #ifndef __RRCLASS_H
 #define __RRCLASS_H 1
 
diff --git a/src/lib/dns/rrclass.cc b/src/lib/dns/rrclass.cc
index 27e82cf..04ff59c 100644
--- a/src/lib/dns/rrclass.cc
+++ b/src/lib/dns/rrclass.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <string>
diff --git a/src/lib/dns/rrparamregistry-placeholder.cc b/src/lib/dns/rrparamregistry-placeholder.cc
index 37a676e..19363a3 100644
--- a/src/lib/dns/rrparamregistry-placeholder.cc
+++ b/src/lib/dns/rrparamregistry-placeholder.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <cassert>
 #include <algorithm>
 #include <cctype>
diff --git a/src/lib/dns/rrparamregistry.h b/src/lib/dns/rrparamregistry.h
index 408738a..a856423 100644
--- a/src/lib/dns/rrparamregistry.h
+++ b/src/lib/dns/rrparamregistry.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __RRPARAMREGISTRY_H
 #define __RRPARAMREGISTRY_H 1
 
diff --git a/src/lib/dns/rrset.cc b/src/lib/dns/rrset.cc
index fbdffc0..b931bec 100644
--- a/src/lib/dns/rrset.cc
+++ b/src/lib/dns/rrset.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <algorithm>
 #include <string>
 #include <vector>
diff --git a/src/lib/dns/rrset.h b/src/lib/dns/rrset.h
index 2f76945..4fc6cdc 100644
--- a/src/lib/dns/rrset.h
+++ b/src/lib/dns/rrset.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __RRSET_H
 #define __RRSET_H 1
 
diff --git a/src/lib/dns/rrsetlist.cc b/src/lib/dns/rrsetlist.cc
index 8c2637c..fcdcfbb 100644
--- a/src/lib/dns/rrsetlist.cc
+++ b/src/lib/dns/rrsetlist.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 
 #include <boost/foreach.hpp>
diff --git a/src/lib/dns/rrsetlist.h b/src/lib/dns/rrsetlist.h
index a07f0fc..0e05b5b 100644
--- a/src/lib/dns/rrsetlist.h
+++ b/src/lib/dns/rrsetlist.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __RRSETLIST_H
 #define __RRSETLIST_H 1
 
@@ -75,6 +73,27 @@ private:
     T it_;
 };
 
+/// A set of RRsets.
+///
+/// \note Do not use this class unless you really understand what
+/// you're doing and you're 100% sure that this class is the best choice
+/// for your purpose.
+///
+/// Counter intuitively, this class is not a "list" of RRsets but a
+/// "set" of them; it doesn't allow multiple RRsets of the same RR
+/// type and RR class to be added at the same time.  And, for that
+/// reason, adding an RRset is more expensive than you'd expect.  The
+/// class name is confusing, but was named so as a result of
+/// compromise: "RRsetset" would look awkward; RRsets would be
+/// confusing (with RRset).
+///
+/// In any case, if you want a list like container of RRsets, your best choice
+/// would be \c std::vector<RRset> or \c std::list<RRset>, not this class.
+/// In fact, in many cases \c RRsetList will be a suboptimal choice.
+/// This class is defined publicly as part of libdns++ for a historical
+/// reason and is actually quite specific to a particular need for libdatasrc.
+/// If you are tempted to use it, think twice to assess if this class
+/// is really what you want.  Again, in many cases the answer will be no.
 class RRsetList {
 private:
     RRsetList(const RRsetList& source);
diff --git a/src/lib/dns/rrttl.cc b/src/lib/dns/rrttl.cc
index 2e57f61..78bb355 100644
--- a/src/lib/dns/rrttl.cc
+++ b/src/lib/dns/rrttl.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <sstream>
diff --git a/src/lib/dns/rrttl.h b/src/lib/dns/rrttl.h
index a3c07ea..c80030e 100644
--- a/src/lib/dns/rrttl.h
+++ b/src/lib/dns/rrttl.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __RRTTL_H
 #define __RRTTL_H 1
 
diff --git a/src/lib/dns/rrtype-placeholder.h b/src/lib/dns/rrtype-placeholder.h
index 165891f..76cb29d 100644
--- a/src/lib/dns/rrtype-placeholder.h
+++ b/src/lib/dns/rrtype-placeholder.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: rrtype.h 534 2010-01-26 23:08:23Z jinmei $
-
 #ifndef __RRTYPE_H
 #define __RRTYPE_H 1
 
diff --git a/src/lib/dns/rrtype.cc b/src/lib/dns/rrtype.cc
index 659674d..44377f5 100644
--- a/src/lib/dns/rrtype.cc
+++ b/src/lib/dns/rrtype.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <string>
diff --git a/src/lib/dns/tests/base32hex_unittest.cc b/src/lib/dns/tests/base32hex_unittest.cc
index b106533..253d310 100644
--- a/src/lib/dns/tests/base32hex_unittest.cc
+++ b/src/lib/dns/tests/base32hex_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 
 #include <cctype>
diff --git a/src/lib/dns/tests/base64_unittest.cc b/src/lib/dns/tests/base64_unittest.cc
index d3d5491..7333793 100644
--- a/src/lib/dns/tests/base64_unittest.cc
+++ b/src/lib/dns/tests/base64_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 #include <utility>
 #include <vector>
diff --git a/src/lib/dns/tests/buffer_unittest.cc b/src/lib/dns/tests/buffer_unittest.cc
index 1459ac9..2ac9fc5 100644
--- a/src/lib/dns/tests/buffer_unittest.cc
+++ b/src/lib/dns/tests/buffer_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/dnssectime_unittest.cc b/src/lib/dns/tests/dnssectime_unittest.cc
index 68b4f85..2479a29 100644
--- a/src/lib/dns/tests/dnssectime_unittest.cc
+++ b/src/lib/dns/tests/dnssectime_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <time.h>
diff --git a/src/lib/dns/tests/edns_unittest.cc b/src/lib/dns/tests/edns_unittest.cc
index 2663e24..fb9a7c2 100644
--- a/src/lib/dns/tests/edns_unittest.cc
+++ b/src/lib/dns/tests/edns_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <sstream>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/dns/tests/hex_unittest.cc b/src/lib/dns/tests/hex_unittest.cc
index 3237940..6f82b17 100644
--- a/src/lib/dns/tests/hex_unittest.cc
+++ b/src/lib/dns/tests/hex_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: rrtype_unittest.cc 476 2010-01-19 00:29:28Z jinmei $
-
 #include <stdint.h>
 
 #include <vector>
diff --git a/src/lib/dns/tests/message_unittest.cc b/src/lib/dns/tests/message_unittest.cc
index d577d66..65c5813 100644
--- a/src/lib/dns/tests/message_unittest.cc
+++ b/src/lib/dns/tests/message_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/messagerenderer_unittest.cc b/src/lib/dns/tests/messagerenderer_unittest.cc
index 056304a..c3d3edb 100644
--- a/src/lib/dns/tests/messagerenderer_unittest.cc
+++ b/src/lib/dns/tests/messagerenderer_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/name_unittest.cc b/src/lib/dns/tests/name_unittest.cc
index 3972f64..b79fd74 100644
--- a/src/lib/dns/tests/name_unittest.cc
+++ b/src/lib/dns/tests/name_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 #include <string>
 #include <sstream>
diff --git a/src/lib/dns/tests/opcode_unittest.cc b/src/lib/dns/tests/opcode_unittest.cc
index 1cf8af1..a7db654 100644
--- a/src/lib/dns/tests/opcode_unittest.cc
+++ b/src/lib/dns/tests/opcode_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 #include <sstream>
 
diff --git a/src/lib/dns/tests/question_unittest.cc b/src/lib/dns/tests/question_unittest.cc
index d2fb1f7..59a4815 100644
--- a/src/lib/dns/tests/question_unittest.cc
+++ b/src/lib/dns/tests/question_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 #include <sstream>
 
@@ -141,6 +139,39 @@ TEST_F(QuestionTest, comparison) {
     EXPECT_FALSE(Question(a, ch, ns) < Question(a, ch, ns));
     EXPECT_FALSE(Question(b, in, ns) < Question(b, in, ns));
     EXPECT_FALSE(Question(b, in, aaaa) < Question(b, in, aaaa));
+
+    // Identical questions are equal
+
+    EXPECT_TRUE(Question(a, in, ns) == Question(a, in, ns));
+    EXPECT_FALSE(Question(a, in, ns) != Question(a, in, ns));
+
+    // Components differing by one component are unequal...
+
+    EXPECT_FALSE(Question(b, in, ns) == Question(a, in, ns));
+    EXPECT_TRUE(Question(b, in, ns) != Question(a, in, ns));
+
+    EXPECT_FALSE(Question(a, ch, ns) == Question(a, in, ns));
+    EXPECT_TRUE(Question(a, ch, ns) != Question(a, in, ns));
+
+    EXPECT_FALSE(Question(a, in, aaaa) == Question(a, in, ns));
+    EXPECT_TRUE(Question(a, in, aaaa) != Question(a, in, ns));
+
+    // ... as are those differing by two components
+
+    EXPECT_FALSE(Question(b, ch, ns) == Question(a, in, ns));
+    EXPECT_TRUE(Question(b, ch, ns) != Question(a, in, ns));
+
+    EXPECT_FALSE(Question(b, in, aaaa) == Question(a, in, ns));
+    EXPECT_TRUE(Question(b, in, aaaa) != Question(a, in, ns));
+
+    EXPECT_FALSE(Question(a, ch, aaaa) == Question(a, in, ns));
+    EXPECT_TRUE(Question(a, ch, aaaa) != Question(a, in, ns));
+
+    // ... and question differing by all three
+
+    EXPECT_FALSE(Question(b, ch, aaaa) == Question(a, in, ns));
+    EXPECT_TRUE(Question(b, ch, aaaa) != Question(a, in, ns));
+
 }
 
 }
diff --git a/src/lib/dns/tests/rcode_unittest.cc b/src/lib/dns/tests/rcode_unittest.cc
index 4ccb7b0..b8d7c73 100644
--- a/src/lib/dns/tests/rcode_unittest.cc
+++ b/src/lib/dns/tests/rcode_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 #include <sstream>
 
diff --git a/src/lib/dns/tests/rdata_cname_unittest.cc b/src/lib/dns/tests/rdata_cname_unittest.cc
index 2e46cd7..e3137a7 100644
--- a/src/lib/dns/tests/rdata_cname_unittest.cc
+++ b/src/lib/dns/tests/rdata_cname_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
diff --git a/src/lib/dns/tests/rdata_dname_unittest.cc b/src/lib/dns/tests/rdata_dname_unittest.cc
index be2990f..c2384b6 100644
--- a/src/lib/dns/tests/rdata_dname_unittest.cc
+++ b/src/lib/dns/tests/rdata_dname_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
diff --git a/src/lib/dns/tests/rdata_dnskey_unittest.cc b/src/lib/dns/tests/rdata_dnskey_unittest.cc
index 38d51b9..e26bf57 100644
--- a/src/lib/dns/tests/rdata_dnskey_unittest.cc
+++ b/src/lib/dns/tests/rdata_dnskey_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/dns/tests/rdata_ds_unittest.cc b/src/lib/dns/tests/rdata_ds_unittest.cc
index 87e05f1..d7e3f88 100644
--- a/src/lib/dns/tests/rdata_ds_unittest.cc
+++ b/src/lib/dns/tests/rdata_ds_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/rdata_in_a_unittest.cc b/src/lib/dns/tests/rdata_in_a_unittest.cc
index 8c0388a..7302881 100644
--- a/src/lib/dns/tests/rdata_in_a_unittest.cc
+++ b/src/lib/dns/tests/rdata_in_a_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
diff --git a/src/lib/dns/tests/rdata_in_aaaa_unittest.cc b/src/lib/dns/tests/rdata_in_aaaa_unittest.cc
index c1b46cf..c1953d6 100644
--- a/src/lib/dns/tests/rdata_in_aaaa_unittest.cc
+++ b/src/lib/dns/tests/rdata_in_aaaa_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
diff --git a/src/lib/dns/tests/rdata_mx_unittest.cc b/src/lib/dns/tests/rdata_mx_unittest.cc
index e385361..4491f86 100644
--- a/src/lib/dns/tests/rdata_mx_unittest.cc
+++ b/src/lib/dns/tests/rdata_mx_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/messagerenderer.h>
 #include <dns/rdata.h>
diff --git a/src/lib/dns/tests/rdata_ns_unittest.cc b/src/lib/dns/tests/rdata_ns_unittest.cc
index 8aee40a..6d4a69e 100644
--- a/src/lib/dns/tests/rdata_ns_unittest.cc
+++ b/src/lib/dns/tests/rdata_ns_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
diff --git a/src/lib/dns/tests/rdata_nsec3_unittest.cc b/src/lib/dns/tests/rdata_nsec3_unittest.cc
index 3636640..6b3a0b5 100644
--- a/src/lib/dns/tests/rdata_nsec3_unittest.cc
+++ b/src/lib/dns/tests/rdata_nsec3_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/dns/tests/rdata_nsec3param_unittest.cc b/src/lib/dns/tests/rdata_nsec3param_unittest.cc
index 777d6a3..53e9126 100644
--- a/src/lib/dns/tests/rdata_nsec3param_unittest.cc
+++ b/src/lib/dns/tests/rdata_nsec3param_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/dns/tests/rdata_nsec_unittest.cc b/src/lib/dns/tests/rdata_nsec_unittest.cc
index 63e80ff..f9ad027 100644
--- a/src/lib/dns/tests/rdata_nsec_unittest.cc
+++ b/src/lib/dns/tests/rdata_nsec_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/rdata_opt_unittest.cc b/src/lib/dns/tests/rdata_opt_unittest.cc
index d957ba8..be92b91 100644
--- a/src/lib/dns/tests/rdata_opt_unittest.cc
+++ b/src/lib/dns/tests/rdata_opt_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/messagerenderer.h>
 #include <dns/rdata.h>
diff --git a/src/lib/dns/tests/rdata_ptr_unittest.cc b/src/lib/dns/tests/rdata_ptr_unittest.cc
index cb96b7f..da13dcb 100644
--- a/src/lib/dns/tests/rdata_ptr_unittest.cc
+++ b/src/lib/dns/tests/rdata_ptr_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
diff --git a/src/lib/dns/tests/rdata_rrsig_unittest.cc b/src/lib/dns/tests/rdata_rrsig_unittest.cc
index d691a88..04d9469 100644
--- a/src/lib/dns/tests/rdata_rrsig_unittest.cc
+++ b/src/lib/dns/tests/rdata_rrsig_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <exceptions/exceptions.h>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/rdata_soa_unittest.cc b/src/lib/dns/tests/rdata_soa_unittest.cc
index 999ecd1..6858a0b 100644
--- a/src/lib/dns/tests/rdata_soa_unittest.cc
+++ b/src/lib/dns/tests/rdata_soa_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/messagerenderer.h>
 #include <dns/rdata.h>
diff --git a/src/lib/dns/tests/rdata_tsig_unittest.cc b/src/lib/dns/tests/rdata_tsig_unittest.cc
index 7a8f695..5c9a14f 100644
--- a/src/lib/dns/tests/rdata_tsig_unittest.cc
+++ b/src/lib/dns/tests/rdata_tsig_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/dns/tests/rdata_txt_unittest.cc b/src/lib/dns/tests/rdata_txt_unittest.cc
index 3271d88..54993e1 100644
--- a/src/lib/dns/tests/rdata_txt_unittest.cc
+++ b/src/lib/dns/tests/rdata_txt_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <dns/buffer.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
diff --git a/src/lib/dns/tests/rdata_unittest.cc b/src/lib/dns/tests/rdata_unittest.cc
index 81dfe10..5ce4c03 100644
--- a/src/lib/dns/tests/rdata_unittest.cc
+++ b/src/lib/dns/tests/rdata_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 #include <string>
 #include <sstream>
diff --git a/src/lib/dns/tests/rdata_unittest.h b/src/lib/dns/tests/rdata_unittest.h
index 40b1eb2..748c8d3 100644
--- a/src/lib/dns/tests/rdata_unittest.h
+++ b/src/lib/dns/tests/rdata_unittest.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __RDATA_UNITTEST_H
 #define __RDATA_UNITTEST_H 1
 
diff --git a/src/lib/dns/tests/rrclass_unittest.cc b/src/lib/dns/tests/rrclass_unittest.cc
index 871909a..4eeb1e0 100644
--- a/src/lib/dns/tests/rrclass_unittest.cc
+++ b/src/lib/dns/tests/rrclass_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/rrparamregistry_unittest.cc b/src/lib/dns/tests/rrparamregistry_unittest.cc
index ac57ae7..a75eed5 100644
--- a/src/lib/dns/tests/rrparamregistry_unittest.cc
+++ b/src/lib/dns/tests/rrparamregistry_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 #include <sstream>
 
diff --git a/src/lib/dns/tests/rrset_unittest.cc b/src/lib/dns/tests/rrset_unittest.cc
index 1149480..c704cc8 100644
--- a/src/lib/dns/tests/rrset_unittest.cc
+++ b/src/lib/dns/tests/rrset_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdexcept>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/rrsetlist_unittest.cc b/src/lib/dns/tests/rrsetlist_unittest.cc
index 90d4782..080f888 100644
--- a/src/lib/dns/tests/rrsetlist_unittest.cc
+++ b/src/lib/dns/tests/rrsetlist_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <vector>
 #include <boost/foreach.hpp>
 
diff --git a/src/lib/dns/tests/rrttl_unittest.cc b/src/lib/dns/tests/rrttl_unittest.cc
index c359ce3..b8f5ac2 100644
--- a/src/lib/dns/tests/rrttl_unittest.cc
+++ b/src/lib/dns/tests/rrttl_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/rrtype_unittest.cc b/src/lib/dns/tests/rrtype_unittest.cc
index 25aa1d7..6da7381 100644
--- a/src/lib/dns/tests/rrtype_unittest.cc
+++ b/src/lib/dns/tests/rrtype_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <dns/buffer.h>
diff --git a/src/lib/dns/tests/run_unittests.cc b/src/lib/dns/tests/run_unittests.cc
index 1a6f8ee..3cdc61d 100644
--- a/src/lib/dns/tests/run_unittests.cc
+++ b/src/lib/dns/tests/run_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <gtest/gtest.h>
 
 #include <dns/tests/unittest_util.h>
diff --git a/src/lib/dns/tests/sha1_unittest.cc b/src/lib/dns/tests/sha1_unittest.cc
index 658be0d..79bc37d 100644
--- a/src/lib/dns/tests/sha1_unittest.cc
+++ b/src/lib/dns/tests/sha1_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 #include <string>
 
diff --git a/src/lib/dns/tests/unittest_util.cc b/src/lib/dns/tests/unittest_util.cc
index 14ace94..c9c0982 100644
--- a/src/lib/dns/tests/unittest_util.cc
+++ b/src/lib/dns/tests/unittest_util.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <iostream>
diff --git a/src/lib/dns/tests/unittest_util.h b/src/lib/dns/tests/unittest_util.h
index 899f28d..f85a921 100644
--- a/src/lib/dns/tests/unittest_util.h
+++ b/src/lib/dns/tests/unittest_util.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __UNITTEST_UTIL_H
 #define __UNITTEST_UTIL_H 1
 
diff --git a/src/lib/dns/tsigkey.cc b/src/lib/dns/tsigkey.cc
index e324c29..057191d 100644
--- a/src/lib/dns/tsigkey.cc
+++ b/src/lib/dns/tsigkey.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <map>
 #include <utility>
 #include <vector>
diff --git a/src/lib/dns/tsigkey.h b/src/lib/dns/tsigkey.h
index c277b19..e56fa88 100644
--- a/src/lib/dns/tsigkey.h
+++ b/src/lib/dns/tsigkey.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __TSIGKEY_H
 #define __TSIGKEY_H 1
 
diff --git a/src/lib/dns/util/base32hex.h b/src/lib/dns/util/base32hex.h
index 95df331..cba172e 100644
--- a/src/lib/dns/util/base32hex.h
+++ b/src/lib/dns/util/base32hex.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __BASE32HEX_H
 #define __BASE32HEX_H 1
 
diff --git a/src/lib/dns/util/base64.h b/src/lib/dns/util/base64.h
index ab2326e..46e10a6 100644
--- a/src/lib/dns/util/base64.h
+++ b/src/lib/dns/util/base64.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __BASE64_H
 #define __BASE64_H 1
 
diff --git a/src/lib/dns/util/base_n.cc b/src/lib/dns/util/base_n.cc
index 2f799c3..9d0c777 100644
--- a/src/lib/dns/util/base_n.cc
+++ b/src/lib/dns/util/base_n.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdint.h>
 #include <cassert>
 #include <iterator>
diff --git a/src/lib/dns/util/hex.h b/src/lib/dns/util/hex.h
index d3b3acc..e2626bf 100644
--- a/src/lib/dns/util/hex.h
+++ b/src/lib/dns/util/hex.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __HEX_H
 #define __HEX_H 1
 
diff --git a/src/lib/exceptions/exceptions.cc b/src/lib/exceptions/exceptions.cc
index 10ddad6..2a374da 100644
--- a/src/lib/exceptions/exceptions.cc
+++ b/src/lib/exceptions/exceptions.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <string>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/exceptions/exceptions.h b/src/lib/exceptions/exceptions.h
index 4d7a9e9..a42037b 100644
--- a/src/lib/exceptions/exceptions.h
+++ b/src/lib/exceptions/exceptions.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __EXCEPTIONS_H
 #define __EXCEPTIONS_H 1
 
diff --git a/src/lib/exceptions/tests/exceptions_unittest.cc b/src/lib/exceptions/tests/exceptions_unittest.cc
index 7d5990c..44cbc17 100644
--- a/src/lib/exceptions/tests/exceptions_unittest.cc
+++ b/src/lib/exceptions/tests/exceptions_unittest.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <stdexcept>
 #include <string>
 
diff --git a/src/lib/exceptions/tests/run_unittests.cc b/src/lib/exceptions/tests/run_unittests.cc
index 863ac68..0908071 100644
--- a/src/lib/exceptions/tests/run_unittests.cc
+++ b/src/lib/exceptions/tests/run_unittests.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: run_unittests.cc 476 2010-01-19 00:29:28Z jinmei $
-
 #include <gtest/gtest.h>
 
 int
diff --git a/src/lib/nsas/address_entry.cc b/src/lib/nsas/address_entry.cc
index 04b1747..24b0dd9 100644
--- a/src/lib/nsas/address_entry.cc
+++ b/src/lib/nsas/address_entry.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 /// \file address_entry.cc
 ///
 /// This file exists to define the single constant \c AddressEntry::UNREACHABLE,
diff --git a/src/lib/nsas/address_entry.h b/src/lib/nsas/address_entry.h
index 293c46e..148d479 100644
--- a/src/lib/nsas/address_entry.h
+++ b/src/lib/nsas/address_entry.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __ADDRESS_ENTRY_H
 #define __ADDRESS_ENTRY_H
 
diff --git a/src/lib/nsas/address_request_callback.h b/src/lib/nsas/address_request_callback.h
index a24a8ee..ad0630e 100644
--- a/src/lib/nsas/address_request_callback.h
+++ b/src/lib/nsas/address_request_callback.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __ADDRESS_REQUEST_CALLBACK_H
 #define __ADDRESS_REQUEST_CALLBACK_H
 
diff --git a/src/lib/nsas/asiolink.h b/src/lib/nsas/asiolink.h
index 3f1e7dc..b99ddb3 100644
--- a/src/lib/nsas/asiolink.h
+++ b/src/lib/nsas/asiolink.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __ASIOLINK_H
 #define __ASIOLINK_H
 
diff --git a/src/lib/nsas/fetchable.h b/src/lib/nsas/fetchable.h
index fffff20..e828611 100644
--- a/src/lib/nsas/fetchable.h
+++ b/src/lib/nsas/fetchable.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $id$
-
 #ifndef __FETCHABLE_H
 #define __FETCHABLE_H
 
diff --git a/src/lib/nsas/hash.cc b/src/lib/nsas/hash.cc
index 33dfc7c..dbd8eec 100644
--- a/src/lib/nsas/hash.cc
+++ b/src/lib/nsas/hash.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 /*! \file
  * Some parts of this code were copied from BIND-9, which in turn was derived
  * from universal hash function libraries of Rice University.
diff --git a/src/lib/nsas/hash.h b/src/lib/nsas/hash.h
index 6913dfc..0290c26 100644
--- a/src/lib/nsas/hash.h
+++ b/src/lib/nsas/hash.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __HASH_H
 #define __HASH_H
 
diff --git a/src/lib/nsas/hash_deleter.h b/src/lib/nsas/hash_deleter.h
index b112707..29a32d7 100644
--- a/src/lib/nsas/hash_deleter.h
+++ b/src/lib/nsas/hash_deleter.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __HASH_DELETER_H
 #define __HASH_DELETER_H
 
diff --git a/src/lib/nsas/hash_key.cc b/src/lib/nsas/hash_key.cc
index 813dd12..bf4676b 100644
--- a/src/lib/nsas/hash_key.cc
+++ b/src/lib/nsas/hash_key.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <cstring>
 
 #include <config.h>
diff --git a/src/lib/nsas/hash_key.h b/src/lib/nsas/hash_key.h
index a8e5d1d..c89b327 100644
--- a/src/lib/nsas/hash_key.h
+++ b/src/lib/nsas/hash_key.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __HASH_KEY_H
 #define __HASH_KEY_H
 
diff --git a/src/lib/nsas/hash_table.h b/src/lib/nsas/hash_table.h
index f415140..3c34ee9 100644
--- a/src/lib/nsas/hash_table.h
+++ b/src/lib/nsas/hash_table.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __HASH_TABLE_H
 #define __HASH_TABLE_H
 
diff --git a/src/lib/nsas/lru_list.h b/src/lib/nsas/lru_list.h
index 53875bf..a3e0974 100644
--- a/src/lib/nsas/lru_list.h
+++ b/src/lib/nsas/lru_list.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __LRU_LIST_H
 #define __LRU_LIST_H
 
diff --git a/src/lib/nsas/nameserver_address.cc b/src/lib/nsas/nameserver_address.cc
index 9f5f1fa..b2ed55c 100644
--- a/src/lib/nsas/nameserver_address.cc
+++ b/src/lib/nsas/nameserver_address.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $id$
-
 #include <config.h>
 
 #include "nameserver_address.h"
diff --git a/src/lib/nsas/nameserver_address.h b/src/lib/nsas/nameserver_address.h
index d609844..7752deb 100644
--- a/src/lib/nsas/nameserver_address.h
+++ b/src/lib/nsas/nameserver_address.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NAMESERVER_ADDRESS_H
 #define __NAMESERVER_ADDRESS_H
 
diff --git a/src/lib/nsas/nameserver_address_store.cc b/src/lib/nsas/nameserver_address_store.cc
index b7482f5..e52047a 100644
--- a/src/lib/nsas/nameserver_address_store.cc
+++ b/src/lib/nsas/nameserver_address_store.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 // Workaround for a problem with boost and sunstudio 5.10
diff --git a/src/lib/nsas/nameserver_address_store.h b/src/lib/nsas/nameserver_address_store.h
index 4fce3a4..b435d12 100644
--- a/src/lib/nsas/nameserver_address_store.h
+++ b/src/lib/nsas/nameserver_address_store.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NAMESERVER_ADDRESS_STORE_H
 #define __NAMESERVER_ADDRESS_STORE_H
 
diff --git a/src/lib/nsas/nameserver_entry.cc b/src/lib/nsas/nameserver_entry.cc
index 5289623..e48b9fc 100644
--- a/src/lib/nsas/nameserver_entry.cc
+++ b/src/lib/nsas/nameserver_entry.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <algorithm>
diff --git a/src/lib/nsas/nameserver_entry.h b/src/lib/nsas/nameserver_entry.h
index f3ee1ca..1024b7b 100644
--- a/src/lib/nsas/nameserver_entry.h
+++ b/src/lib/nsas/nameserver_entry.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NAMESERVER_ENTRY_H
 #define __NAMESERVER_ENTRY_H
 
diff --git a/src/lib/nsas/nsas_entry.h b/src/lib/nsas/nsas_entry.h
index 57a2384..f739e8d 100644
--- a/src/lib/nsas/nsas_entry.h
+++ b/src/lib/nsas/nsas_entry.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NSAS_ENTRY_H
 #define __NSAS_ENTRY_H
 
diff --git a/src/lib/nsas/nsas_entry_compare.h b/src/lib/nsas/nsas_entry_compare.h
index fdad262..9e9ba7d 100644
--- a/src/lib/nsas/nsas_entry_compare.h
+++ b/src/lib/nsas/nsas_entry_compare.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NSAS_ENTRY_COMPARE_H
 #define __NSAS_ENTRY_COMPARE_H
 
diff --git a/src/lib/nsas/nsas_types.h b/src/lib/nsas/nsas_types.h
index c4d8355..940cc3e 100644
--- a/src/lib/nsas/nsas_types.h
+++ b/src/lib/nsas/nsas_types.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NSAS_TYPES_H
 #define __NSAS_TYPES_H
 
diff --git a/src/lib/nsas/random_number_generator.h b/src/lib/nsas/random_number_generator.h
index 0837a96..e80ebcb 100644
--- a/src/lib/nsas/random_number_generator.h
+++ b/src/lib/nsas/random_number_generator.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NSAS_RANDOM_NUMBER_GENERATOR_H
 #define __NSAS_RANDOM_NUMBER_GENERATOR_H
 
diff --git a/src/lib/nsas/resolver_interface.h b/src/lib/nsas/resolver_interface.h
index 303b8e4..7f93487 100644
--- a/src/lib/nsas/resolver_interface.h
+++ b/src/lib/nsas/resolver_interface.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $id$
-
 #ifndef __RESOLVER_INTERFACE_H
 #define __RESOLVER_INTERFACE_H
 
diff --git a/src/lib/nsas/tests/address_entry_unittest.cc b/src/lib/nsas/tests/address_entry_unittest.cc
index 62ae383..716068c 100644
--- a/src/lib/nsas/tests/address_entry_unittest.cc
+++ b/src/lib/nsas/tests/address_entry_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <limits.h>
diff --git a/src/lib/nsas/tests/fetchable_unittest.cc b/src/lib/nsas/tests/fetchable_unittest.cc
index 90bfa7b..f94cd16 100644
--- a/src/lib/nsas/tests/fetchable_unittest.cc
+++ b/src/lib/nsas/tests/fetchable_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $id$
 #include <config.h>
 
 #include "../fetchable.h"
diff --git a/src/lib/nsas/tests/hash_deleter_unittest.cc b/src/lib/nsas/tests/hash_deleter_unittest.cc
index 7f7373c..97fecbe 100644
--- a/src/lib/nsas/tests/hash_deleter_unittest.cc
+++ b/src/lib/nsas/tests/hash_deleter_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <algorithm>
diff --git a/src/lib/nsas/tests/hash_key_unittest.cc b/src/lib/nsas/tests/hash_key_unittest.cc
index 884db42..efa5fb2 100644
--- a/src/lib/nsas/tests/hash_key_unittest.cc
+++ b/src/lib/nsas/tests/hash_key_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <algorithm>
diff --git a/src/lib/nsas/tests/hash_table_unittest.cc b/src/lib/nsas/tests/hash_table_unittest.cc
index c92adc4..7ba25b5 100644
--- a/src/lib/nsas/tests/hash_table_unittest.cc
+++ b/src/lib/nsas/tests/hash_table_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <gtest/gtest.h>
diff --git a/src/lib/nsas/tests/hash_unittest.cc b/src/lib/nsas/tests/hash_unittest.cc
index a2d3ade..251e4b1 100644
--- a/src/lib/nsas/tests/hash_unittest.cc
+++ b/src/lib/nsas/tests/hash_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <algorithm>
diff --git a/src/lib/nsas/tests/lru_list_unittest.cc b/src/lib/nsas/tests/lru_list_unittest.cc
index 0a062a2..0161f2b 100644
--- a/src/lib/nsas/tests/lru_list_unittest.cc
+++ b/src/lib/nsas/tests/lru_list_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <iostream>
diff --git a/src/lib/nsas/tests/nameserver_address_store_unittest.cc b/src/lib/nsas/tests/nameserver_address_store_unittest.cc
index fde55d2..a2b3d42 100644
--- a/src/lib/nsas/tests/nameserver_address_store_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_address_store_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 /// \brief Test Deleter Objects
diff --git a/src/lib/nsas/tests/nameserver_address_unittest.cc b/src/lib/nsas/tests/nameserver_address_unittest.cc
index 516d785..2f12f41 100644
--- a/src/lib/nsas/tests/nameserver_address_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_address_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <gtest/gtest.h>
diff --git a/src/lib/nsas/tests/nameserver_entry_unittest.cc b/src/lib/nsas/tests/nameserver_entry_unittest.cc
index 6e1213e..2f5dc2a 100644
--- a/src/lib/nsas/tests/nameserver_entry_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_entry_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <iostream>
diff --git a/src/lib/nsas/tests/nsas_entry_compare_unittest.cc b/src/lib/nsas/tests/nsas_entry_compare_unittest.cc
index e95411f..33e41b8 100644
--- a/src/lib/nsas/tests/nsas_entry_compare_unittest.cc
+++ b/src/lib/nsas/tests/nsas_entry_compare_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <algorithm>
diff --git a/src/lib/nsas/tests/nsas_test.h b/src/lib/nsas/tests/nsas_test.h
index 7fc548f..a0b86df 100644
--- a/src/lib/nsas/tests/nsas_test.h
+++ b/src/lib/nsas/tests/nsas_test.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __NSAS_TEST_H
 #define __NSAS_TEST_H
 
diff --git a/src/lib/nsas/tests/random_number_generator_unittest.cc b/src/lib/nsas/tests/random_number_generator_unittest.cc
index 6bb5773..c306b09 100644
--- a/src/lib/nsas/tests/random_number_generator_unittest.cc
+++ b/src/lib/nsas/tests/random_number_generator_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <gtest/gtest.h>
diff --git a/src/lib/nsas/tests/run_unittests.cc b/src/lib/nsas/tests/run_unittests.cc
index 52f3e13..d1277ad 100644
--- a/src/lib/nsas/tests/run_unittests.cc
+++ b/src/lib/nsas/tests/run_unittests.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id: run_unittests.cc 3020 2010-09-26 03:47:26Z jinmei $
 #include <config.h>
 
 #include <gtest/gtest.h>
diff --git a/src/lib/nsas/tests/zone_entry_unittest.cc b/src/lib/nsas/tests/zone_entry_unittest.cc
index 0fe5f34..ca19110 100644
--- a/src/lib/nsas/tests/zone_entry_unittest.cc
+++ b/src/lib/nsas/tests/zone_entry_unittest.cc
@@ -12,7 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
 #include <config.h>
 
 #include <gtest/gtest.h>
diff --git a/src/lib/nsas/zone_entry.cc b/src/lib/nsas/zone_entry.cc
index 718dc22..4009fe7 100644
--- a/src/lib/nsas/zone_entry.cc
+++ b/src/lib/nsas/zone_entry.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $id$
-
 #include <config.h>
 
 #include "zone_entry.h"
diff --git a/src/lib/nsas/zone_entry.h b/src/lib/nsas/zone_entry.h
index 758f2c9..8ae36f7 100644
--- a/src/lib/nsas/zone_entry.h
+++ b/src/lib/nsas/zone_entry.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef __ZONE_ENTRY_H
 #define __ZONE_ENTRY_H
 
diff --git a/src/lib/python/isc/config/tests/ccsession_test.py b/src/lib/python/isc/config/tests/ccsession_test.py
index e4de960..2ae37f5 100644
--- a/src/lib/python/isc/config/tests/ccsession_test.py
+++ b/src/lib/python/isc/config/tests/ccsession_test.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 #
 # Tests for the ConfigData and MultiConfigData classes
 #
diff --git a/src/lib/python/isc/config/tests/cfgmgr_test.py b/src/lib/python/isc/config/tests/cfgmgr_test.py
index 7ab151b..c992d0d 100644
--- a/src/lib/python/isc/config/tests/cfgmgr_test.py
+++ b/src/lib/python/isc/config/tests/cfgmgr_test.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 #
 # Tests for the configuration manager module
 #
diff --git a/src/lib/python/isc/config/tests/config_data_test.py b/src/lib/python/isc/config/tests/config_data_test.py
index b61a259..4710b00 100644
--- a/src/lib/python/isc/config/tests/config_data_test.py
+++ b/src/lib/python/isc/config/tests/config_data_test.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 #
 # Tests for the ConfigData and MultiConfigData classes
 #
diff --git a/src/lib/python/isc/config/tests/module_spec_test.py b/src/lib/python/isc/config/tests/module_spec_test.py
index 3d493f2..a4dcdec 100644
--- a/src/lib/python/isc/config/tests/module_spec_test.py
+++ b/src/lib/python/isc/config/tests/module_spec_test.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 #
 # Tests for the module_spec module
 #
diff --git a/src/lib/python/isc/config/tests/unittest_fakesession.py b/src/lib/python/isc/config/tests/unittest_fakesession.py
index 8bd2607..e31b436 100644
--- a/src/lib/python/isc/config/tests/unittest_fakesession.py
+++ b/src/lib/python/isc/config/tests/unittest_fakesession.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 import isc
 
 class WouldBlockForever(Exception):
diff --git a/src/lib/python/isc/datasrc/master.py b/src/lib/python/isc/datasrc/master.py
index faa2ae5..bba0805 100644
--- a/src/lib/python/isc/datasrc/master.py
+++ b/src/lib/python/isc/datasrc/master.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 import sys, re, string
 import time
 import os
diff --git a/src/lib/python/isc/datasrc/sqlite3_ds.py b/src/lib/python/isc/datasrc/sqlite3_ds.py
index 2caa209..77b0828 100644
--- a/src/lib/python/isc/datasrc/sqlite3_ds.py
+++ b/src/lib/python/isc/datasrc/sqlite3_ds.py
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 import sqlite3, re, random
 import isc
 
diff --git a/src/lib/testutils/Makefile.am b/src/lib/testutils/Makefile.am
index b1962ab..d0467ea 100644
--- a/src/lib/testutils/Makefile.am
+++ b/src/lib/testutils/Makefile.am
@@ -8,6 +8,7 @@ if HAVE_GTEST
 lib_LTLIBRARIES = libtestutils.la
 
 libtestutils_la_SOURCES = srv_test.h srv_test.cc
+libtestutils_la_SOURCES += dnsmessage_test.h dnsmessage_test.cc
 libtestutils_la_SOURCES += mockups.h
 libtestutils_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 endif
diff --git a/src/lib/testutils/dnsmessage_test.cc b/src/lib/testutils/dnsmessage_test.cc
new file mode 100644
index 0000000..af354d5
--- /dev/null
+++ b/src/lib/testutils/dnsmessage_test.cc
@@ -0,0 +1,115 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <dns/message.h>
+#include <dns/opcode.h>
+#include <dns/rdata.h>
+#include <dns/rcode.h>
+#include <dns/rrset.h>
+#include <dns/rrttl.h>
+
+#include <gtest/gtest.h>
+
+#include <testutils/dnsmessage_test.h>
+
+using namespace isc::dns;
+
+namespace isc {
+namespace testutils {
+const unsigned int QR_FLAG = 0x1;
+const unsigned int AA_FLAG = 0x2;
+const unsigned int TC_FLAG = 0x4;
+const unsigned int RD_FLAG = 0x8;
+const unsigned int RA_FLAG = 0x10;
+const unsigned int AD_FLAG = 0x20;
+const unsigned int CD_FLAG = 0x40;
+
+void
+headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
+            const uint16_t opcodeval, const unsigned int flags,
+            const unsigned int qdcount,
+            const unsigned int ancount, const unsigned int nscount,
+            const unsigned int arcount)
+{
+    EXPECT_EQ(qid, message.getQid());
+    EXPECT_EQ(rcode, message.getRcode());
+    EXPECT_EQ(opcodeval, message.getOpcode().getCode());
+    EXPECT_EQ((flags & QR_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_QR));
+    EXPECT_EQ((flags & AA_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_AA));
+    EXPECT_EQ((flags & TC_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_TC));
+    EXPECT_EQ((flags & RA_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_RA));
+    EXPECT_EQ((flags & RD_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_RD));
+    EXPECT_EQ((flags & AD_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_AD));
+    EXPECT_EQ((flags & CD_FLAG) != 0,
+              message.getHeaderFlag(Message::HEADERFLAG_CD));
+
+    EXPECT_EQ(qdcount, message.getRRCount(Message::SECTION_QUESTION));
+    EXPECT_EQ(ancount, message.getRRCount(Message::SECTION_ANSWER));
+    EXPECT_EQ(nscount, message.getRRCount(Message::SECTION_AUTHORITY));
+    EXPECT_EQ(arcount, message.getRRCount(Message::SECTION_ADDITIONAL));
+}
+
+namespace {
+::testing::AssertionResult
+matchRdata(const char*, const char*,
+           const rdata::Rdata& expected, const rdata::Rdata& actual)
+{
+    if (expected.compare(actual) != 0) {
+        ::testing::Message msg;
+        msg << "Two RDATAs are expected to be equal but not:\n"
+            << "  Actual: " << actual.toText() << "\n"
+            << "Expected: " << expected.toText();
+        return (::testing::AssertionFailure(msg));
+    }
+    return (::testing::AssertionSuccess());
+}
+}
+
+void
+rrsetCheck(isc::dns::ConstRRsetPtr expected_rrset,
+           isc::dns::ConstRRsetPtr actual_rrset)
+{
+    EXPECT_EQ(expected_rrset->getName(), actual_rrset->getName());
+    EXPECT_EQ(expected_rrset->getClass(), actual_rrset->getClass());
+    EXPECT_EQ(expected_rrset->getType(), actual_rrset->getType());
+    EXPECT_EQ(expected_rrset->getTTL(), actual_rrset->getTTL());
+
+    isc::dns::RdataIteratorPtr rdata_it = actual_rrset->getRdataIterator();
+    isc::dns::RdataIteratorPtr expected_rdata_it =
+        expected_rrset->getRdataIterator();
+    while (!expected_rdata_it->isLast()) {
+        EXPECT_FALSE(rdata_it->isLast());
+        if (rdata_it->isLast()) {
+            // buggy case, should stop here
+            break;
+        }
+
+        EXPECT_PRED_FORMAT2(matchRdata, expected_rdata_it->getCurrent(),
+                            rdata_it->getCurrent());
+
+        expected_rdata_it->next();
+        rdata_it->next();
+    }
+
+    // Make sure we have examined all sets of rrset RDATA
+    EXPECT_TRUE(rdata_it->isLast());
+}
+} // end of namespace testutils
+} // end of namespace isc
diff --git a/src/lib/testutils/dnsmessage_test.h b/src/lib/testutils/dnsmessage_test.h
new file mode 100644
index 0000000..a8b7284
--- /dev/null
+++ b/src/lib/testutils/dnsmessage_test.h
@@ -0,0 +1,304 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <algorithm>
+#include <functional>
+#include <iosfwd>
+#include <string>
+#include <vector>
+
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/masterload.h>
+#include <dns/rrclass.h>
+#include <dns/rrset.h>
+
+#include <gtest/gtest.h>
+
+namespace isc {
+namespace testutils {
+///
+/// \name Header flags
+///
+/// These are flags to indicate whether the corresponding flag bit of the
+/// DNS header is to be set in the test cases using \c headerCheck().
+/// (The flag values is irrelevant to their wire-format values).
+/// The meaning of the flags should be obvious from the variable names.
+//@{
+extern const unsigned int QR_FLAG;
+extern const unsigned int AA_FLAG;
+extern const unsigned int TC_FLAG;
+extern const unsigned int RD_FLAG;
+extern const unsigned int RA_FLAG;
+extern const unsigned int AD_FLAG;
+extern const unsigned int CD_FLAG;
+//@}
+
+/// Set of unit tests to examine a DNS message header.
+///
+/// This function takes a dns::Message object and performs various tests
+/// to confirm if the header fields of the message have the given specified
+/// value.  The \c message parameter is the Message object to be tested,
+/// and the remaining parameters specify the expected values of the fields.
+///
+/// If all fields have the expected values the test will be considered
+/// successful.  Otherwise, some of the tests will indicate a failure, which
+/// will make the test case that calls this function fail.
+///
+/// The meaning of the parameters should be obvious, but here are some notes
+/// that may not be so trivial:
+/// - \c opcode is an integer, not an \c dns::Opcode object.  This is because
+///   we can easily iterate over all possible OPCODEs in a test.
+/// - \c flags is a bitmask so that we can specify a set of header flags
+///   via a single parameter.  For example, when we expect the message has
+///   QR and AA flags are on and others are off, we'd set this parameter to
+///   <code>(QR_FLAG | AA_FLAG)</code>.
+///
+/// \param message The DNS message to be tested.
+/// \param qid The expected QID
+/// \param rcode The expected RCODE
+/// \param opcodeval The code value of the expected OPCODE
+/// \param flags Bit flags specifying header flags that are expected to be set
+/// \param qdcount The expected value of QDCOUNT
+/// \param ancount The expected value of ANCOUNT
+/// \param nscount The expected value of NSCOUNT
+/// \param arcount The expected value of ARCOUNT
+void
+headerCheck(const isc::dns::Message& message, const isc::dns::qid_t qid,
+            const isc::dns::Rcode& rcode,
+            const uint16_t opcodeval, const unsigned int flags,
+            const unsigned int qdcount,
+            const unsigned int ancount, const unsigned int nscount,
+            const unsigned int arcount);
+
+/// Set of unit tests to check equality of two RRsets
+///
+/// This function takes two RRset objects and performs detailed tests to
+/// check if these two are "equal", where equal means:
+/// - The owner name, RR class, RR type and TTL are all equal.  Names are
+///   compared in case-insensitive manner.
+/// - The number of RRs (more accurately RDATAs) is the same.
+/// - RDATAs are equal as a sequence.  That is, the first RDATA of
+///   \c expected_rrset is equal to the first RDATA of \c actual_rrset,
+///   the second RDATA of \c expected_rrset is equal to the second RDATA
+///   of \c actual_rrset, and so on.  Two RDATAs are equal iff they have
+///   the same DNSSEC sorting order as defined in RFC4034.
+///
+/// Some of the tests will fail if any of the above isn't met.
+///
+/// \note In future we may want to allow more flexible matching for RDATAs.
+/// For example, we may want to allow comparison as "sets", i.e., comparing
+/// RDATAs regardless of the ordering; we may also want to support suppressing
+/// duplicate RDATA.  For now, it's caller's responsibility to match the
+/// ordering (and any duplicates) between the expected and actual sets.
+/// Even if and when we support the flexible behavior, this "strict mode"
+/// will still be useful.
+///
+/// \param expected_rrset The expected RRset
+/// \param actual_rrset The RRset to be tested
+void rrsetCheck(isc::dns::ConstRRsetPtr expected_rrset,
+                isc::dns::ConstRRsetPtr actual_rrset);
+
+/// The definitions in this name space are not supposed to be used publicly,
+/// but are given here because they are used in templated functions.
+namespace detail {
+// Helper matching class used in rrsetsCheck()
+struct RRsetMatch : public std::unary_function<isc::dns::ConstRRsetPtr, bool> {
+    RRsetMatch(isc::dns::ConstRRsetPtr target) : target_(target) {}
+    bool operator()(isc::dns::ConstRRsetPtr rrset) const {
+        return (rrset->getType() == target_->getType() &&
+                rrset->getClass() == target_->getClass() &&
+                rrset->getName() == target_->getName());
+    }
+    const isc::dns::ConstRRsetPtr target_;
+};
+
+// Helper callback functor for masterLoad() used in rrsetsCheck (stream
+// version)
+class RRsetInserter {
+public:
+    RRsetInserter(std::vector<isc::dns::ConstRRsetPtr>& rrsets) :
+        rrsets_(rrsets)
+    {}
+    void operator()(isc::dns::ConstRRsetPtr rrset) const {
+        rrsets_.push_back(rrset);
+    }
+private:
+    std::vector<isc::dns::ConstRRsetPtr>& rrsets_;
+};
+}
+
+/// Set of unit tests to check if two sets of RRsets are identical.
+///
+/// This templated function takes two sets of sequences, each defined by
+/// two input iterators pointing to \c ConstRRsetPtr (begin and end).
+/// This function compares these two sets of RRsets as "sets", and considers
+/// they are equal when:
+/// - The number of RRsets are the same.
+/// - For any RRset in one set, there is an equivalent RRset in the other set,
+///   and vice versa, where the equivalence of two RRsets is tested using
+///   \c rrsetCheck().
+///
+/// Note that the sets of RRsets are compared as "sets", i.e, they don't have
+/// to be listed in the same order.
+///
+/// The entire tests will pass if the two sets are identical.  Otherwise
+/// some of the tests will indicate a failure.
+///
+/// \note
+/// - There is one known restriction: each set of RRsets must not have more
+///   than one RRsets for the same name, RR type and RR class.  If this
+///   condition isn't met, some of the tests will fail either against an
+///   explicit duplication check or as a result of counter mismatch.
+/// - This function uses linear searches on the expected and actual sequences,
+///   and won't be scalable for large input.  For the purpose of testing it
+///   should be acceptable, but be aware of the size of test data.
+///
+/// \param expected_begin The beginning of the expected set of RRsets
+/// \param expected_end The end of the expected set of RRsets
+/// \param actual_begin The beginning of the set of RRsets to be tested
+/// \param actual_end The end of the set of RRsets to be tested
+template<typename EXPECTED_ITERATOR, typename ACTUAL_ITERATOR>
+void
+rrsetsCheck(EXPECTED_ITERATOR expected_begin, EXPECTED_ITERATOR expected_end,
+            ACTUAL_ITERATOR actual_begin, ACTUAL_ITERATOR actual_end)
+{
+    std::vector<isc::dns::ConstRRsetPtr> checked_rrsets; // for duplicate check
+    unsigned int rrset_matched = 0;
+    ACTUAL_ITERATOR it;
+    for (it = actual_begin; it != actual_end; ++it) {
+        // Make sure there's no duplicate RRset in actual (using a naive
+        // search).  Since the actual set is guaranteed to be unique, we can
+        // detect it if the expected data has a duplicate by the match/size
+        // checks at the end of the function.
+        // Note: we cannot use EXPECT_EQ for iterators
+        EXPECT_TRUE(checked_rrsets.end() ==
+                    std::find_if(checked_rrsets.begin(), checked_rrsets.end(),
+                                 detail::RRsetMatch(*it)));
+        checked_rrsets.push_back(*it);
+
+        EXPECTED_ITERATOR found_rrset_it =
+            std::find_if(expected_begin, expected_end,
+                         detail::RRsetMatch(*it));
+        if (found_rrset_it != expected_end) {
+            rrsetCheck(*found_rrset_it, *it);
+            ++rrset_matched;
+        }
+    }
+
+    // make sure all expected RRsets are in actual sets
+    EXPECT_EQ(std::distance(expected_begin, expected_end), rrset_matched);
+    // make sure rrsets only contains expected RRsets
+    EXPECT_EQ(std::distance(expected_begin, expected_end),
+              std::distance(actual_begin, actual_end));
+}
+
+/// Set of unit tests to check if two sets of RRsets are identical using
+/// streamed expected data.
+///
+/// This templated function takes a standard input stream that produces
+/// a sequence of textural RRs and compares the entire set of RRsets
+/// with the range of RRsets specified by two input iterators.
+///
+/// This function is actually a convenient wrapper for the other version
+/// of function; it internally builds a standard vector of RRsets
+/// from the input stream and uses iterators of the vector as the expected
+/// input iterators for the backend function.
+/// Expected data in the form of input stream would be useful for testing
+/// as it can be easily hardcoded in test cases using string streams or
+/// given from a data source file.
+///
+/// One common use case of this function is to test whether a particular
+/// section of a DNS message contains an expected set of RRsets.
+/// For example, when \c message is an \c dns::Message object, the following
+/// test code will check if the additional section of \c message contains
+/// the hardcoded two RRsets (2 A RRs and 1 AAAA RR) and only contains these
+/// RRsets:
+/// \code std::stringstream expected;
+/// expected << "foo.example.com. 3600 IN A 192.0.2.1\n"
+///          << "foo.example.com. 3600 IN A 192.0.2.2\n"
+///          << "foo.example.com. 7200 IN AAAA 2001:db8::1\n"
+/// rrsetsCheck(expected, message.beginSection(Message::SECTION_ADDITIONAL),
+///                       message.endSection(Message::SECTION_ADDITIONAL));
+/// \endcode
+///
+/// The input stream is parsed using the \c dns::masterLoad() function,
+/// and notes and restrictions of that function apply.
+/// This is also the reason why this function takes \c origin and \c rrclass
+/// parameters.  The default values of these parameters should just work
+/// in many cases for usual tests, but due to a validity check on the SOA RR
+/// in \c dns::masterLoad(), if the input stream contains an SOA RR, the
+/// \c origin parameter will have to be set to the owner name of the SOA
+/// explicitly.  Likewise, all RRsets must have the same RR class.
+/// (We may have to modify \c dns::masterLoad() so that it can
+/// have an option to be more generous about these points if it turns out
+/// to be too restrictive).
+///
+/// \param expected_stream An input stream object that is to emit expected set
+/// of RRsets
+/// \param actual_begin The beginning of the set of RRsets to be tested
+/// \param actual_end The end of the set of RRsets to be tested
+/// \param origin A domain name that is a super domain of the owner name
+/// of all RRsets contained in the stream.
+/// \param rrclass The RR class of the RRsets contained in the stream.
+template<typename ACTUAL_ITERATOR>
+void
+rrsetsCheck(std::istream& expected_stream,
+            ACTUAL_ITERATOR actual_begin, ACTUAL_ITERATOR actual_end,
+            const isc::dns::Name& origin = isc::dns::Name::ROOT_NAME(),
+            const isc::dns::RRClass& rrclass = isc::dns::RRClass::IN())
+{
+    std::vector<isc::dns::ConstRRsetPtr> expected;
+    isc::dns::masterLoad(expected_stream, origin, rrclass,
+                         detail::RRsetInserter(expected));
+    rrsetsCheck(expected.begin(), expected.end(), actual_begin, actual_end);
+}
+
+/// Set of unit tests to check if two sets of RRsets are identical using
+/// expected data as string.
+///
+/// This function is a wrapper for the input stream version:
+/// \c rrsetsCheck(std::istream&, ACTUAL_ITERATOR, ACTUAL_ITERATOR, const isc::dns::Name&, const isc::dns::RRClass&)(),
+/// and takes a string object instead of a stream.
+/// While the stream version is more generic, this version would be more
+/// convenient for tests using hardcoded expected data.  Using this version,
+/// the example test case shown for the stream version would look as follows:
+/// \code
+/// rrsetsCheck("foo.example.com. 3600 IN A 192.0.2.1\n"
+///             "foo.example.com. 3600 IN A 192.0.2.2\n"
+///             "foo.example.com. 7200 IN AAAA 2001:db8::1\n",
+///             message.beginSection(Message::SECTION_ADDITIONAL),
+///             message.endSection(Message::SECTION_ADDITIONAL));
+/// \endcode
+///
+/// The semantics of parameters is the same as that of the stream version
+/// except that \c expected is a string of expected sets of RRsets.
+template<typename ACTUAL_ITERATOR>
+void
+rrsetsCheck(const std::string& expected,
+            ACTUAL_ITERATOR actual_begin, ACTUAL_ITERATOR actual_end,
+            const isc::dns::Name& origin = isc::dns::Name::ROOT_NAME(),
+            const isc::dns::RRClass& rrclass = isc::dns::RRClass::IN())
+{
+    std::stringstream expected_stream(expected);
+    rrsetsCheck(expected_stream, actual_begin, actual_end, origin,
+                rrclass);
+}
+
+} // end of namespace testutils
+} // end of namespace isc
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/testutils/mockups.h b/src/lib/testutils/mockups.h
index 0c64fc2..4bec83d 100644
--- a/src/lib/testutils/mockups.h
+++ b/src/lib/testutils/mockups.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <config.h>
 
 #include <cc/data.h>
@@ -21,6 +19,8 @@
 
 #include <xfr/xfrout_client.h>
 
+#include <asiolink/asiolink.h>
+
 // A minimal mock configuration session.  Most the methods are
 // stubbed out, except for a very basic group_sendmsg() and
 // group_recvmsg().  hasQueuedMessages() always returns false.
diff --git a/src/lib/testutils/srv_test.cc b/src/lib/testutils/srv_test.cc
index 1deb8f0..0a27eba 100644
--- a/src/lib/testutils/srv_test.cc
+++ b/src/lib/testutils/srv_test.cc
@@ -21,6 +21,7 @@
 
 #include <dns/tests/unittest_util.h>
 
+#include <testutils/dnsmessage_test.h>
 #include <testutils/srv_test.h>
 
 using namespace isc::dns;
@@ -30,14 +31,6 @@ namespace isc {
 namespace testutils {
 const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
 
-const unsigned int QR_FLAG = 0x1;
-const unsigned int AA_FLAG = 0x2;
-const unsigned int TC_FLAG = 0x4;
-const unsigned int RD_FLAG = 0x8;
-const unsigned int RA_FLAG = 0x10;
-const unsigned int AD_FLAG = 0x20;
-const unsigned int CD_FLAG = 0x40;
-
 SrvTestBase::SrvTestBase() : request_message(Message::RENDER),
                              parse_message(new Message(Message::PARSE)),
                              default_qid(0x1035),
@@ -232,37 +225,6 @@ SrvTestBase::axfrOverUDP() {
     headerCheck(*parse_message, default_qid, isc::dns::Rcode::FORMERR(),
                 opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
 }
-
-void
-headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
-            const uint16_t opcodeval, const unsigned int flags,
-            const unsigned int qdcount,
-            const unsigned int ancount, const unsigned int nscount,
-            const unsigned int arcount)
-{
-    EXPECT_EQ(qid, message.getQid());
-    EXPECT_EQ(rcode, message.getRcode());
-    EXPECT_EQ(opcodeval, message.getOpcode().getCode());
-    EXPECT_EQ((flags & QR_FLAG) != 0,
-              message.getHeaderFlag(Message::HEADERFLAG_QR));
-    EXPECT_EQ((flags & AA_FLAG) != 0,
-              message.getHeaderFlag(Message::HEADERFLAG_AA));
-    EXPECT_EQ((flags & TC_FLAG) != 0,
-              message.getHeaderFlag(Message::HEADERFLAG_TC));
-    EXPECT_EQ((flags & RA_FLAG) != 0,
-              message.getHeaderFlag(Message::HEADERFLAG_RA));
-    EXPECT_EQ((flags & RD_FLAG) != 0,
-              message.getHeaderFlag(Message::HEADERFLAG_RD));
-    EXPECT_EQ((flags & AD_FLAG) != 0,
-              message.getHeaderFlag(Message::HEADERFLAG_AD));
-    EXPECT_EQ((flags & CD_FLAG) != 0,
-              message.getHeaderFlag(Message::HEADERFLAG_CD));
-
-    EXPECT_EQ(qdcount, message.getRRCount(Message::SECTION_QUESTION));
-    EXPECT_EQ(ancount, message.getRRCount(Message::SECTION_ANSWER));
-    EXPECT_EQ(nscount, message.getRRCount(Message::SECTION_AUTHORITY));
-    EXPECT_EQ(arcount, message.getRRCount(Message::SECTION_ADDITIONAL));
-}
 } // end of namespace testutils
 } // end of namespace isc
 
diff --git a/src/lib/testutils/srv_test.h b/src/lib/testutils/srv_test.h
index be8b95a..061076d 100644
--- a/src/lib/testutils/srv_test.h
+++ b/src/lib/testutils/srv_test.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <gtest/gtest.h>
-
 #include <dns/buffer.h>
 #include <dns/name.h>
 #include <dns/message.h>
@@ -46,14 +44,6 @@ extern const unsigned int RA_FLAG;
 extern const unsigned int AD_FLAG;
 extern const unsigned int CD_FLAG;
 
-void
-headerCheck(const isc::dns::Message& message, const isc::dns::qid_t qid,
-            const isc::dns::Rcode& rcode,
-            const uint16_t opcodeval, const unsigned int flags,
-            const unsigned int qdcount,
-            const unsigned int ancount, const unsigned int nscount,
-            const unsigned int arcount);
-
 // The base class for Auth and Recurse test case
 class SrvTestBase : public ::testing::Test {
 protected:
@@ -99,6 +89,7 @@ protected:
     MockSession notify_session;
     MockServer dnsserv;
     isc::dns::Message request_message;
+    isc::dns::MessagePtr response_message;
     isc::dns::MessagePtr parse_message;
     const isc::dns::qid_t default_qid;
     const isc::dns::Opcode opcode;
diff --git a/src/lib/xfr/fd_share.cc b/src/lib/xfr/fd_share.cc
index e27027c..4e1f093 100644
--- a/src/lib/xfr/fd_share.cc
+++ b/src/lib/xfr/fd_share.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <cstring>
 #include <cstdlib>
 
diff --git a/src/lib/xfr/fd_share.h b/src/lib/xfr/fd_share.h
index 7e439b4..4ee5fd5 100644
--- a/src/lib/xfr/fd_share.h
+++ b/src/lib/xfr/fd_share.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef FD_SHARE_H_
 #define FD_SHARE_H_
 
diff --git a/src/lib/xfr/fdshare_python.cc b/src/lib/xfr/fdshare_python.cc
index 0615d88..82b1b6e 100644
--- a/src/lib/xfr/fdshare_python.cc
+++ b/src/lib/xfr/fdshare_python.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include <structmember.h>
diff --git a/src/lib/xfr/python_xfr.cc b/src/lib/xfr/python_xfr.cc
index 8ecfb58..52848ad 100644
--- a/src/lib/xfr/python_xfr.cc
+++ b/src/lib/xfr/python_xfr.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <boost/python.hpp>
 #include <boost/python/class.hpp>
 #include <boost/python/module.hpp>
diff --git a/src/lib/xfr/xfrout_client.cc b/src/lib/xfr/xfrout_client.cc
index 1dd9c60..e9e736b 100644
--- a/src/lib/xfr/xfrout_client.cc
+++ b/src/lib/xfr/xfrout_client.cc
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #include <cstdlib>
 #include <cstring>
 #include <iostream>
diff --git a/src/lib/xfr/xfrout_client.h b/src/lib/xfr/xfrout_client.h
index 6539009..bad963c 100644
--- a/src/lib/xfr/xfrout_client.h
+++ b/src/lib/xfr/xfrout_client.h
@@ -12,8 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-// $Id$
-
 #ifndef _XFROUT_CLIENT_H
 #define _XFROUT_CLIENT_H
 




More information about the bind10-changes mailing list