BIND 10 trac2268, updated. 31fdd062b59d6ac480ff48cde57e5abad2b3487c Merge branch 'master' into trac2268

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Oct 11 13:23:28 UTC 2012


The branch, trac2268 has been updated
       via  31fdd062b59d6ac480ff48cde57e5abad2b3487c (commit)
       via  5fadea676fc73e068977173bb62b58d04fedf52c (commit)
       via  532ac3d0054f6a11b91ee369964f3a84dabc6040 (commit)
       via  e2d1490eb82b26c501df4d0ed7323478b46a1cca (commit)
       via  f2b4e736bb7d4612c33aa2a648b0b9640a015154 (commit)
       via  88db890d8d1c64de49be87f03c24a2021bcf63da (commit)
       via  65cddb545cbf31c0372ab09e59a727d7cfdf1f89 (commit)
       via  99fd73694c6768e36d79563be991d9132adbdd74 (commit)
       via  b6cfd9d20c49a0f292d37e663801987632e9d2a6 (commit)
       via  a0b7dd977eba590ecd94d4f08ed774a0727fbed0 (commit)
       via  7565788d06f216ab254008ffdfae16678bcd00e5 (commit)
       via  183ea20803b1dfc0bb6e932c75623864cd0a0def (commit)
       via  fe827c7e47a642f3aead3b5414c6e8cf3a9970b4 (commit)
       via  c6391ad769265a1f5c2d5594dcdb113420c7eb4d (commit)
       via  86e4008ac1623aef96fd0c6140e5496841c3b9f0 (commit)
       via  f496bbe69fbff9228c48fc7bf9cc986ed7f420e4 (commit)
       via  74911480e9ff1f21f63365ac789ecd30f67891b8 (commit)
       via  d12ce3c245fc86e3c34a5fdd5950d899cdf889af (commit)
       via  d78dd497ecb846ab2545ce1cb7b6e41341ff5995 (commit)
       via  3a6ee0d12d06c1f9e5b9f261b3fcaab444a9ae80 (commit)
       via  7888a2127db48e004cb1cce24552db230cb3d685 (commit)
       via  bcf2117983fa80d3f4bb9a13f896963497553b85 (commit)
       via  fb5aa58dabb47c1ef51890bee7da070c6a567f69 (commit)
       via  5879860e006e809fa75fdb78b61f82fdffd69b97 (commit)
       via  1e93f1db983cc35b118853b88ab2919decafe2c5 (commit)
       via  3a68ea2e8de8d6df97d95c077ff9e2874ca0d9c3 (commit)
       via  4e159ffca0b633c817472101087be4a235a42af0 (commit)
       via  7b053fd99e6503d3a0a8fb7dbb9d3139df942565 (commit)
       via  04db154ec2fdd1d768fe716b0ccabaa1660e872b (commit)
       via  c7ab107ab6a5f079475085e87851d940863481dc (commit)
       via  dd191127774034a51d658dfe6799ccb397916103 (commit)
       via  4973e638d354d8b56dcadf71123ef23c15662021 (commit)
       via  d41d8af0c726bb923a48948feb6a8f4f6775ea3e (commit)
       via  869d14d7056ee7b0c3cf1dd0db1b375be755bba7 (commit)
       via  9a9260c2589a8468b73f2ecc16929acd66aeb81c (commit)
       via  daedcaea541b1193018cb71d3cc68ba3ba9ff59c (commit)
       via  432064bc3ec7c67797898a182c52add8f6012232 (commit)
       via  1ab996e4c54f1449b8e72cce411331193868e78c (commit)
       via  bf260bbc80a813c30bb7499b8a085d7390d83e83 (commit)
       via  f8261d10f177e52b19af56343ddb5e7548f30195 (commit)
       via  7bcaf2b7903ea5a51c2049579f6dc4670746527f (commit)
       via  f5bd1368b73131abd6e0562e57482310d26ff3eb (commit)
       via  00d3de1af86efe6b4df1310a039adad8f6a719ae (commit)
       via  73900f62a74bf769b5f6ea7b3cf43428baa19842 (commit)
       via  7a628baa1a158b5837d6f383e10b30542d2ac59b (commit)
       via  915576b6aa27d020faadf7fbfc4e4d9bb1df129e (commit)
       via  e1b4bf1cb50160c436f2e5440fd774680b91b7a2 (commit)
       via  76243c3ccd7a30484da8478f7457e18fce485492 (commit)
       via  86a4bae1ffa68eb38921d6cb3f16dad43b616009 (commit)
       via  0b6e74f544b522943436bfdff79c2fa06273b49d (commit)
       via  d7846ea4a9d811c35641f77384d9825f12488e71 (commit)
       via  5d61dba1dc3e51d66ba40d82b1bc378577783dc0 (commit)
       via  c286e0dec766c3d9b2fff6a8bd55539ec976aae9 (commit)
       via  d664fca786643e2345d9722da6d8fd35996bbea1 (commit)
       via  a0a5e207d4a05738f278df6124172f415a43d4ad (commit)
       via  b160122e462422d82fd122839f9fff1e861aa21d (commit)
       via  44d9dfa8aad85d583b7b90fa01c50613a9d9d1a5 (commit)
       via  fbc8d38199a95cc51704c40269d0c4c6625ec6b0 (commit)
       via  7a40926af1fd90e0fd685a8db05795f699560245 (commit)
       via  f8a03432904899e1874f2696ff036322be539022 (commit)
       via  74cc637858d0879f33f1828aabbb1f78e9636d4f (commit)
       via  fa1d1161f76487ceea122baf4dac79c407a07ba8 (commit)
       via  17bffd083824af840b8af99a043bcf55e4c0f555 (commit)
       via  0ff7d113ebb54889bbcd9be91c37a0e5ffcc2fc4 (commit)
       via  3584fbbffa6a633df2988ef8e52a4f367cdc814c (commit)
       via  bff3846230660040790debeacf8d9432ac302fb9 (commit)
       via  a1d9278fd64f74a4a0657a2292851157ad3bb43a (commit)
       via  93e596c474ed1c637da7d6653eaa8c499b0b6a6d (commit)
       via  f037ebb23cb966f86d11c07bb0f4a80b6043c9b0 (commit)
       via  3a8ea5fd501d131e99ec02c4be10a874a94f2d83 (commit)
       via  86b1a2387a10ff8e5e646b117c289ebb2e9e57ec (commit)
       via  1d3b7eabbb5fa3b6674789428b36d7501768b635 (commit)
       via  41538b7ce9d6ab4131b572b79d84292884cf4a11 (commit)
       via  78dfd7dcd6d76cb75d288a3887e8b099c12f3080 (commit)
       via  b1d4ff896a7781d98513fab8d171090ac3d6a1e4 (commit)
       via  6b99a39f0ab27939c29a05b0332d5ec255bc0764 (commit)
       via  47c013b000db7235e1ab798eadebc3b42984b06e (commit)
       via  c91bffdd00deb8b7f3ceda9954a84e31c0cfb9f1 (commit)
       via  ec6cf17e571f9cf23fd1e7bcd573df55106550b1 (commit)
       via  746376902a020e0711bc85fc29a2b339a85b3db2 (commit)
       via  05136b55f90375a1a7e3a76570cb95bf0590c0ad (commit)
       via  0d4a6b6be1e6ba8b3b5681b5c3be7c86d56c076f (commit)
       via  686eb4e9edb4adee0cee357762fe9448fb0cb6bd (commit)
       via  3d68f767731a682d4a80e9ba74d953502c2ada7d (commit)
       via  f802291f6461f3fa7e13fcf3364bb39b4be42c06 (commit)
       via  fa51dffbe444e5d2ac6a768da001b60ad16d0341 (commit)
       via  9cfcbb9475e1f42b5c8953a5a037b833edc5aa69 (commit)
       via  0c38d26f6acc7d156dc6c6871b4fa332e30728ee (commit)
       via  b89e44112425a8d5ab44c26ce988cfb08087ff7e (commit)
       via  98692b1e0663b4d167670b7808f26b1bb718851c (commit)
       via  1886c9f3083ce3e04d42b8a91e46838ee5a1e774 (commit)
       via  37fd8a72b131d5de9a6fbe612d3dc3d19bafdf83 (commit)
       via  1fb24f540ade83926d311316e77e1a6c8bef8432 (commit)
       via  c4c3946bad5bf1e9be0f375ac1029e1f95e94d94 (commit)
       via  5c975417200358c916a62415caf51a1a73e0d470 (commit)
       via  538a160ef48f7dbe927f75cafc335e470a82db33 (commit)
       via  e45115237b2c8c12f0c2fd3c62ae0aff01248cc9 (commit)
       via  a072ee8db55261a67dc7041c7c17d0536f8def0b (commit)
       via  473e340929d0869bf71d972e1a1843dc81b0fbfa (commit)
       via  94656c03d42d0339c79d10be8ccedaea6da55028 (commit)
       via  a6748eee324ebb4cf4ba99aa225df51d71458c81 (commit)
       via  5acf0ff36e8503de33ce04fe16e279ec6ee871f1 (commit)
       via  14680316801f9274e5b4d099a4dfbf63d7cb110b (commit)
       via  d25bb8d27cf235603cb8a1d789066b2aa993eccd (commit)
       via  f2b62e24805e97f66aeac4f9ab3db2d9778c9314 (commit)
       via  4fa694dbee3372b8c310aca2c2dafc3ca7550e80 (commit)
       via  b4bdc9b1f5ec444d1bc4002fe7d65a50acc9d897 (commit)
       via  e0ce6d2f3010bfc5998e6c7da202258cbe28c6c6 (commit)
       via  d73842ed35d5aea29466e25a9a6b2dfb4e550e97 (commit)
       via  5c74085e2f4c16655e77e1bcbc308d4fb0a694f8 (commit)
       via  4babe763de5b20437e32829024f25a1b902df82f (commit)
       via  2bed6220f561fa39358fb81fde8a2ee0a1b85c38 (commit)
       via  274eddb40bacdf8d5933058e33b7d469cb9258c2 (commit)
       via  f00da76cb77226e6a6b7487f6c5c0bc62d0c3f48 (commit)
       via  75ee32436fa5bae4a8f15e25e587d94bf41a59fd (commit)
       via  ef8ecac02aa21192fb4af8d573daa11b09b3685a (commit)
       via  8f7c28971b48c4ee0ab89a3f88d84c4b6fed8185 (commit)
       via  1ab6aafab6660d60a5f2e7cf7125d59d5807f2e5 (commit)
       via  a38fe354acb2ba6e641d91bec364a22989f30b16 (commit)
       via  66f45b3d67dbcb714d445fb3511e19b83cbc8b05 (commit)
       via  f284e18628afb282c1f5c9feec74b36abd9352be (commit)
       via  5bc38109a4c2775a2a2a8389023836facfe8400d (commit)
       via  27e2b20fc709884a145df81553504bfc90b8d539 (commit)
       via  805fda7d95ada6af81f17fca2816b3a1fe4a3008 (commit)
       via  370861e432e88669b2382954b15dbecf1672e032 (commit)
       via  8e51d2165fb35be71aee1a0c381fc71f08a821b5 (commit)
       via  718888317b9fb6b24c20d8d417ea540ff23257c5 (commit)
      from  ed2b8eb0e3f827c89ba16200312424384a54a9a7 (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 31fdd062b59d6ac480ff48cde57e5abad2b3487c
Merge: ed2b8eb 5fadea6
Author: Mukund Sivaraman <muks at isc.org>
Date:   Thu Oct 11 18:39:13 2012 +0530

    Merge branch 'master' into trac2268
    
    Conflicts:
    	src/lib/datasrc/memory/Makefile.am
    	src/lib/datasrc/memory/memory_client.cc
    	src/lib/datasrc/memory/memory_client.h
    	src/lib/datasrc/tests/memory/memory_client_unittest.cc

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

Summary of changes:
 ChangeLog                                          |   33 +++
 configure.ac                                       |    5 +-
 NEWS => examples/AUTHORS                           |    0
 COPYING => examples/COPYING                        |    8 +-
 TODO => examples/ChangeLog                         |    0
 examples/INSTALL                                   |    9 +
 examples/Makefile.am                               |    4 +
 NEWS => examples/NEWS                              |    0
 examples/README                                    |   32 +++
 examples/configure.ac                              |   28 +++
 {src/bin => examples}/host/.gitignore              |    0
 examples/host/Makefile.am                          |    6 +
 {src/bin => examples}/host/README                  |    0
 {src/bin => examples}/host/b10-host.xml            |    0
 {src/bin => examples}/host/host.cc                 |    0
 examples/m4/ax_boost_include.m4                    |   64 ++++++
 examples/m4/ax_isc_bind10.m4                       |  122 +++++++++++
 src/bin/Makefile.am                                |    2 +-
 src/bin/auth/Makefile.am                           |    2 +-
 src/bin/auth/auth_srv.cc                           |   69 +++---
 src/bin/auth/auth_srv.h                            |   69 +++---
 src/bin/auth/benchmarks/Makefile.am                |    1 +
 src/bin/auth/benchmarks/query_bench.cc             |   44 ++--
 src/bin/auth/command.cc                            |    5 +-
 .../{resolver/common.h => auth/datasrc_config.cc}  |   18 +-
 src/bin/auth/datasrc_config.h                      |   83 +++++++
 src/bin/auth/datasrc_configurator.h                |  226 --------------------
 src/bin/auth/main.cc                               |   86 ++++++--
 src/bin/auth/tests/Makefile.am                     |    3 +-
 src/bin/auth/tests/auth_srv_unittest.cc            |  147 +++++++------
 src/bin/auth/tests/command_unittest.cc             |   69 ++++--
 ...ator_unittest.cc => datasrc_config_unittest.cc} |  206 +++++++++---------
 src/bin/auth/tests/query_unittest.cc               |   17 +-
 src/bin/bind10/bind10_messages.mes                 |   10 +
 src/bin/bind10/bind10_src.py.in                    |    9 +-
 src/bin/bind10/tests/bind10_test.py.in             |   35 +++
 src/bin/dbutil/dbutil.py.in                        |    9 +-
 src/bin/dbutil/tests/Makefile.am                   |    2 +
 src/bin/dbutil/tests/dbutil_test.sh.in             |    6 +-
 src/bin/dbutil/tests/testdata/Makefile.am          |    1 +
 .../{empty_version.sqlite3 => v2_1.sqlite3}        |  Bin 13312 -> 15360 bytes
 src/bin/dhcp4/tests/Makefile.am                    |    1 +
 src/bin/dhcp6/tests/Makefile.am                    |    1 +
 src/bin/host/Makefile.am                           |   37 ----
 src/cppcheck-suppress.lst                          |   15 ++
 src/lib/acl/dns.cc                                 |   23 +-
 src/lib/cache/tests/rrset_entry_unittest.cc        |    3 -
 src/lib/cc/data.cc                                 |    8 +-
 src/lib/config/ccsession.cc                        |    6 +-
 src/lib/config/ccsession.h                         |   13 +-
 src/lib/datasrc/database.cc                        |   16 +-
 src/lib/datasrc/memory/Makefile.am                 |    3 +
 src/lib/datasrc/memory/domaintree.h                |   72 +------
 src/lib/datasrc/memory/memory_client.cc            |   40 +---
 src/lib/datasrc/memory/memory_client.h             |   29 ---
 src/lib/datasrc/memory/zone_finder.cc              |   20 +-
 src/lib/datasrc/memory/zone_table.cc               |   44 ++--
 src/lib/datasrc/memory/zone_table.h                |   63 +++---
 .../memory/zone_table_segment.cc}                  |   44 ++--
 src/lib/datasrc/memory/zone_table_segment.h        |  110 ++++++++++
 .../memory/zone_table_segment_local.cc}            |   47 ++--
 src/lib/datasrc/memory/zone_table_segment_local.h  |   66 ++++++
 src/lib/datasrc/memory_datasrc.cc                  |   12 +-
 src/lib/datasrc/sqlite3_accessor.cc                |  134 +++++++-----
 src/lib/datasrc/tests/memory/Makefile.am           |    2 +
 .../datasrc/tests/memory/domaintree_unittest.cc    |   31 +--
 .../datasrc/tests/memory/memory_client_unittest.cc |   10 +-
 src/lib/datasrc/tests/memory/zone_data_unittest.cc |    2 +-
 .../tests/memory/zone_table_segment_unittest.cc    |   83 +++++++
 .../datasrc/tests/memory/zone_table_unittest.cc    |   90 ++++++--
 src/lib/datasrc/tests/memory_datasrc_unittest.cc   |    1 -
 src/lib/datasrc/tests/sqlite3_accessor_unittest.cc |   15 +-
 src/lib/datasrc/tests/testdata/contexttest.zone    |    3 +-
 src/lib/datasrc/tests/testdata/example.org.sqlite3 |  Bin 16384 -> 15360 bytes
 src/lib/datasrc/zone.h                             |  130 ++++++++---
 src/lib/datasrc/zone_finder_context.cc             |   17 +-
 src/lib/dhcp/tests/.gitignore                      |    1 +
 src/lib/dhcp/tests/iface_mgr_unittest.cc           |    2 +-
 src/lib/dns/Makefile.am                            |    3 +-
 src/lib/dns/benchmarks/message_renderer_bench.cc   |    2 +-
 src/lib/dns/benchmarks/rdatarender_bench.cc        |    5 +-
 src/lib/dns/python/edns_python.cc                  |    3 +-
 src/lib/dns/rdata/generic/afsdb_18.cc              |    1 -
 src/lib/dns/rrsetlist.cc                           |   60 ------
 src/lib/dns/rrsetlist.h                            |  132 ------------
 src/lib/dns/tests/Makefile.am                      |    2 +-
 src/lib/dns/tests/labelsequence_unittest.cc        |    8 +-
 src/lib/dns/tests/rrparamregistry_unittest.cc      |    5 +-
 src/lib/dns/tests/rrsetlist_unittest.cc            |  188 ----------------
 src/lib/log/compiler/message.cc                    |   10 +-
 src/lib/log/tests/logger_example.cc                |    1 -
 src/lib/python/isc/bind10/component.py             |   36 +++-
 src/lib/python/isc/bind10/tests/component_test.py  |   65 ++++--
 src/lib/python/isc/datasrc/sqlite3_ds.py           |    3 +-
 src/lib/resolve/recursive_query.cc                 |   40 ++--
 src/lib/resolve/tests/recursive_query_unittest.cc  |   39 +---
 .../resolve/tests/recursive_query_unittest_2.cc    |   13 +-
 .../resolve/tests/recursive_query_unittest_3.cc    |   15 +-
 .../server_common/tests/socket_requestor_test.cc   |    4 +-
 src/lib/util/Makefile.am                           |    3 +
 src/lib/util/hash/sha1.cc                          |    4 +-
 src/lib/util/io/fd_share.cc                        |    1 +
 src/lib/util/tests/fd_tests.cc                     |    4 +-
 src/lib/util/tests/lru_list_unittest.cc            |    6 +-
 src/lib/util/threads/Makefile.am                   |    2 +-
 src/lib/util/threads/lock.cc                       |    8 +-
 .../auth => lib/util/threads}/tests/.gitignore     |    0
 src/lib/util/threads/tests/Makefile.am             |    4 +-
 src/lib/util/threads/thread.cc                     |    4 +-
 tests/tools/perfdhcp/templates/.gitignore          |    5 +
 110 files changed, 1773 insertions(+), 1527 deletions(-)
 copy NEWS => examples/AUTHORS (100%)
 copy COPYING => examples/COPYING (68%)
 rename TODO => examples/ChangeLog (100%)
 create mode 100644 examples/INSTALL
 create mode 100644 examples/Makefile.am
 rename NEWS => examples/NEWS (100%)
 create mode 100644 examples/README
 create mode 100644 examples/configure.ac
 rename {src/bin => examples}/host/.gitignore (100%)
 create mode 100644 examples/host/Makefile.am
 rename {src/bin => examples}/host/README (100%)
 rename {src/bin => examples}/host/b10-host.xml (100%)
 rename {src/bin => examples}/host/host.cc (100%)
 create mode 100644 examples/m4/ax_boost_include.m4
 create mode 100644 examples/m4/ax_isc_bind10.m4
 copy src/bin/{resolver/common.h => auth/datasrc_config.cc} (66%)
 create mode 100644 src/bin/auth/datasrc_config.h
 delete mode 100644 src/bin/auth/datasrc_configurator.h
 rename src/bin/auth/tests/{datasrc_configurator_unittest.cc => datasrc_config_unittest.cc} (59%)
 copy src/bin/dbutil/tests/testdata/{empty_version.sqlite3 => v2_1.sqlite3} (75%)
 delete mode 100644 src/bin/host/Makefile.am
 copy src/lib/{python/isc/datasrc/configurableclientlist_python.h => datasrc/memory/zone_table_segment.cc} (60%)
 create mode 100644 src/lib/datasrc/memory/zone_table_segment.h
 copy src/lib/{python/isc/datasrc/configurableclientlist_python.h => datasrc/memory/zone_table_segment_local.cc} (60%)
 create mode 100644 src/lib/datasrc/memory/zone_table_segment_local.h
 create mode 100644 src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc
 delete mode 100644 src/lib/dns/rrsetlist.cc
 delete mode 100644 src/lib/dns/rrsetlist.h
 delete mode 100644 src/lib/dns/tests/rrsetlist_unittest.cc
 copy src/{bin/auth => lib/util/threads}/tests/.gitignore (100%)
 create mode 100644 tests/tools/perfdhcp/templates/.gitignore

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index bad54da..1ee100d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+489.	[func]		muks
+	The isc::dns::RRsetList class has been removed. It was now unused
+	inside the BIND 10 codebase, and the interface was considered
+	prone to misuse.
+	(Trac #2266, git 532ac3d0054f6a11b91ee369964f3a84dabc6040)
+
+488.	[build]		jinmei
+	On configure, changed the search order for Python executable.
+	It first ties more specific file names such as "python3.2" before
+	more generic "python3".  This will prevent configure failure on
+	Mac OS X that installs Python3 via recent versions of Homebrew.
+	(Trac #2339, git 88db890d8d1c64de49be87f03c24a2021bcf63da)
+
+487.	[bug]		jinmei
+	The bind10 process now terminates a component (subprocess) by the
+	"config remove Boss/components" bindctl command even if the
+	process crashes immediately before the command is sent to bind10.
+	Previously this led to an inconsistent state between the
+	configuration and an internal component list of bind10, and bind10
+	kept trying to restart the component.  A known specific case of
+	this problem is that b10-ddns could keep failing (due to lack of
+	dependency modules) and the administrator couldn't stop the
+	restart via bindctl.
+	(Trac #2244, git 7565788d06f216ab254008ffdfae16678bcd00e5)
+
+486.	[bug]*		jinmei
+	All public header files for libb10-dns++ are now installed.
+	Template configure.ac and utility AC macros for external projects
+	using the library are provided under the "examples" directory.
+	The src/bin/host was moved as part of the examples (and not
+	installed with other BIND 10 programs any more).
+	(Trac #1870, git 4973e638d354d8b56dcadf71123ef23c15662021)
+
 485.	[bug]		jelte
 	Several bugs have been fixed in bindctl; tab-completion now works
 	within configuration lists, the problem where sometimes the
diff --git a/NEWS b/NEWS
deleted file mode 100644
index e69de29..0000000
diff --git a/TODO b/TODO
deleted file mode 100644
index e69de29..0000000
diff --git a/configure.ac b/configure.ac
index c6a2f01..9fb813c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
 AC_PREREQ([2.59])
 AC_INIT(bind10-devel, 20120817, bind10-dev at isc.org)
 AC_CONFIG_SRCDIR(README)
-AM_INIT_AUTOMAKE
+AM_INIT_AUTOMAKE([foreign])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])dnl be backward compatible
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_MACRO_DIR([m4macros])
@@ -132,7 +132,7 @@ AM_CONDITIONAL(SET_ENV_LIBRARY_PATH, test $SET_ENV_LIBRARY_PATH = yes)
 AC_SUBST(SET_ENV_LIBRARY_PATH)
 AC_SUBST(ENV_LIBRARY_PATH)
 
-m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3 python3.1 python3.2])
+m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3.2 python3.1 python3])
 AC_ARG_WITH([pythonpath],
 AC_HELP_STRING([--with-pythonpath=PATH],
   [specify an absolute path to python executable when automatic version check (incorrectly) fails]),
@@ -1099,7 +1099,6 @@ AC_CONFIG_FILES([Makefile
                  src/bin/dbutil/Makefile
                  src/bin/dbutil/tests/Makefile
                  src/bin/dbutil/tests/testdata/Makefile
-                 src/bin/host/Makefile
                  src/bin/loadzone/Makefile
                  src/bin/loadzone/tests/correct/Makefile
                  src/bin/loadzone/tests/error/Makefile
diff --git a/examples/AUTHORS b/examples/AUTHORS
new file mode 100644
index 0000000..e69de29
diff --git a/examples/COPYING b/examples/COPYING
new file mode 100644
index 0000000..f3febbe
--- /dev/null
+++ b/examples/COPYING
@@ -0,0 +1,13 @@
+Copyright (C) 2012  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.
diff --git a/examples/ChangeLog b/examples/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/examples/INSTALL b/examples/INSTALL
new file mode 100644
index 0000000..43436c2
--- /dev/null
+++ b/examples/INSTALL
@@ -0,0 +1,9 @@
+If using git (not the tarball), build the "configure" file:
+    autoreconf --install
+
+To then build from source:
+    ./configure
+    make
+
+You may have to specify the location of BIND 10 header files and
+library objects.  See configure options by ./configure --help.
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..ef437eb
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS = host
+
+# Make sure macros under m4 will be included
+ACLOCAL_AMFLAGS = -I m4
diff --git a/examples/NEWS b/examples/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/examples/README b/examples/README
new file mode 100644
index 0000000..65f777b
--- /dev/null
+++ b/examples/README
@@ -0,0 +1,32 @@
+This is the top directory for sample programs that can be developed
+using public BIND 10 libraries outside of the BIND 10 project.  It's
+intended to be built with installed BIND 10 header files and library
+objects, so it's not a target of the main build tree, and does not
+refer to any other part of the BIND 10 source tree that contains
+this directory.
+
+On the top (sub) directory (where this README file is stored), we
+provide a sample configure.ac and Makefile.am files for GNU automake
+environments with helper autoconf macros to detect the availability and
+location of BIND 10 header files and library objects.
+
+You can use the configure.ac and Makefile.am files with macros under
+the "m4" subdirectory as a template for your own project.  The key is
+to call the AX_ISC_BIND10 function (as the sample configure.ac does)
+from your configure.ac.  Then it will check the availability of
+necessary stuff and set some corresponding AC variables.  You can then
+use the resulting variables in your Makefile.in or Makefile.ac.
+
+If you use automake, don't forget adding the following line to the top
+level Makefile.am:
+
+ACLOCAL_AMFLAGS = -I m4
+
+This is necessary to incorporate the helper macro definitions.
+
+If you don't use automake but autoconf, make sure to add the following
+to the configure.ac file:
+
+sinclude(m4/ax_boost_include.m4)
+sinclude(m4/ax_isc_bind10.m4)
+(and same for other m4 files as they are added under m4/)
diff --git a/examples/configure.ac b/examples/configure.ac
new file mode 100644
index 0000000..9379687
--- /dev/null
+++ b/examples/configure.ac
@@ -0,0 +1,28 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.59])
+AC_INIT(bind10-examples, 20120817, bind10-dev at isc.org)
+AC_CONFIG_SRCDIR([README])
+AM_INIT_AUTOMAKE
+AC_CONFIG_HEADERS([config.h])
+
+# Checks for programs.
+AC_PROG_CXX
+AC_LANG([C++])
+
+# Checks for BIND 10 headers and libraries
+AX_ISC_BIND10
+
+# For the example host program, we require the BIND 10 DNS library
+if test "x$BIND10_DNS_LIB" = "x"; then
+   AC_MSG_ERROR([unable to find BIND 10 DNS library needed to build 'host'])
+fi
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+
+AC_CONFIG_FILES([Makefile
+                 host/Makefile])
+
+AC_OUTPUT
diff --git a/examples/host/.gitignore b/examples/host/.gitignore
new file mode 100644
index 0000000..01ef357
--- /dev/null
+++ b/examples/host/.gitignore
@@ -0,0 +1,2 @@
+/b10-host
+/b10-host.1
diff --git a/examples/host/Makefile.am b/examples/host/Makefile.am
new file mode 100644
index 0000000..dbd57a2
--- /dev/null
+++ b/examples/host/Makefile.am
@@ -0,0 +1,6 @@
+AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(BIND10_CPPFLAGS)
+
+bin_PROGRAMS = b10-host
+b10_host_SOURCES = host.cc
+b10_host_LDFLAGS = ${BIND10_LDFLAGS}
+b10_host_LDADD = ${BIND10_DNS_LIB}
diff --git a/examples/host/README b/examples/host/README
new file mode 100644
index 0000000..5cc4068
--- /dev/null
+++ b/examples/host/README
@@ -0,0 +1,4 @@
+Rewriting host(1) in C++ from scratch using BIND 10's libdns++.
+
+The bugs and incompatibilities are listed in the manual page
+and in the source code.
diff --git a/examples/host/b10-host.xml b/examples/host/b10-host.xml
new file mode 100644
index 0000000..a17ef67
--- /dev/null
+++ b/examples/host/b10-host.xml
@@ -0,0 +1,196 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+	       [<!ENTITY mdash "—">]>
+<!--
+ - 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$ -->
+<refentry>
+
+  <refentryinfo>
+    <date>May 4, 2011</date>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>b10-host</refentrytitle>
+    <manvolnum>1</manvolnum>
+    <refmiscinfo>BIND10</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>b10-host</refname>
+    <refpurpose>DNS lookup utility</refpurpose>
+  </refnamediv>
+
+  <docinfo>
+    <copyright>
+      <year>2011</year>
+      <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+    </copyright>
+  </docinfo>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>b10-host</command>
+      <arg><option>-a</option></arg>
+      <arg><option>-c <replaceable>class</replaceable></option></arg>
+      <arg><option>-d</option></arg>
+      <arg><option>-p <replaceable>port</replaceable></option></arg>
+      <arg><option>-r</option></arg>
+      <arg><option>-t <replaceable>type</replaceable></option></arg>
+      <arg><option>-v</option></arg>
+      <arg><replaceable>name</replaceable></arg>
+      <arg><option><replaceable>server</replaceable></option></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+    <para>
+      The <command>b10-host</command> utility does DNS lookups.
+      Its initial goal is to be a
+      <citerefentry><refentrytitle>host</refentrytitle>
+        <manvolnum>1</manvolnum></citerefentry>
+      clone, but also add a few features useful for BIND 10 development
+      testing.
+    </para>
+
+    <para>
+      By default, it looks up the A, AAAA, and MX record sets for the
+      <replaceable>name</replaceable>.
+      Optionally, you may select a name server to query against by adding
+      the <replaceable>server</replaceable> argument.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <para>The arguments are as follows:</para>
+
+    <variablelist>
+
+      <varlistentry>
+        <term><option>-a</option></term>
+        <listitem><para>
+          Enable verbose mode and do a query for type ANY.
+          (If the <option>-t</option> option is also set, then the
+          ANY query is not done, but it still uses verbose mode.)
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-c <replaceable>class</replaceable></option></term>
+        <listitem><para>
+          Define the class for the query.
+          The default is IN (Internet).
+<!-- TODO: bug if class is unknown causes seg fault and possible core dump -->
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-d</option></term>
+        <listitem><para>
+	  Enable verbose output mode, including elapsed time in
+	  milliseconds.
+          Verbose mode shows the header, question, answer, authority,
+          and additional sections (if provided).
+          (Same as <option>-v</option>.)
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-p <replaceable>port</replaceable></option></term>
+        <listitem><para>
+          Select an alternative port for the query.
+          This may be a number or a service name.
+          The default is 53 (domain).
+          This is not a standard feature of
+          <citerefentry><refentrytitle>host</refentrytitle>
+            <manvolnum>1</manvolnum></citerefentry>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-r</option></term>
+        <listitem><para>
+          Disable recursive processing by not setting the
+          Recursion Desired flag in the query.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-t <replaceable>type</replaceable></option></term>
+        <listitem><para>
+          Select a specific resource record type for the query.
+          By default, it looks up the A, AAAA, and MX record sets.
+<!-- TODO: bug if class is unknown causes seg fault and possible core dump -->
+          (This overrides the <option>-a</option> option.)
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-v</option></term>
+        <listitem><para>
+	  Same as <option>-d</option> option.
+        </para></listitem>
+      </varlistentry>
+
+    </variablelist>
+
+  </refsect1>
+
+  <refsect1>
+    <title>COMPATIBILITY / BUGS</title>
+    <para>
+      <command>b10-host</command> does not do reverse lookups by
+      default yet (by detecting if name is a IPv4 or IPv6 address).
+    </para>
+
+    <para>
+      Unknown <option>-c</option> class or <option>-t</option> type
+      causes <command>b10-host</command> to Abort.
+    </para>
+
+    <para>
+      Not all types are supported yet for formatting.
+      Not all switches are supported yet.
+    </para>
+
+    <para>
+      It doesn't use <filename>/etc/resolv.conf</filename> at this time.
+      The default name server used is 127.0.0.1.
+    </para>
+
+    <para>
+      <option>-p</option> is not a standard feature.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>HISTORY</title>
+    <para>
+      The C++ version of <command>b10-host</command> was started in
+      October 2009 by Jeremy C. Reed of ISC.
+      Its usage and output were based on the standard <command>host</command>
+      command.
+    </para>
+  </refsect1>
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/examples/host/host.cc b/examples/host/host.cc
new file mode 100644
index 0000000..a5c6522
--- /dev/null
+++ b/examples/host/host.cc
@@ -0,0 +1,253 @@
+// Copyright (C) 2010-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.
+
+// host rewritten in C++ using BIND 10 DNS library
+
+#include <arpa/inet.h>
+#include <netdb.h>          // for getaddrinfo
+#include <sys/time.h>       // for gettimeofday
+#include <sys/socket.h>     // networking functions and definitions on FreeBSD
+
+#include <unistd.h>
+
+#include <string>
+#include <iostream>
+
+#include <util/buffer.h>
+
+#include <dns/name.h>
+#include <dns/message.h>
+#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
+#include <dns/rrclass.h>
+#include <dns/rrtype.h>
+#include <dns/rrset.h>
+#include <dns/message.h>
+
+using namespace std;
+using namespace isc::dns;
+using namespace isc::util;
+
+namespace {
+char* dns_type = NULL;    // not set, so A, AAAA, MX
+const char* server = "127.0.0.1";
+const char* server_port = "53";
+const char* dns_class  = "IN";
+bool verbose = false;
+bool dns_any = false;
+int first_time = 1;
+bool recursive_bit = true;
+struct timeval before_time, after_time;
+
+int
+host_lookup(const char* const name, const char* const dns_class,
+            const char* const type, bool any) {
+
+    Message msg(Message::RENDER);
+
+    msg.setQid(0); // does this matter?
+
+    // TODO: add switch for this
+    msg.setOpcode(Opcode::QUERY());
+    msg.setRcode(Rcode::NOERROR());
+    if (recursive_bit) {
+        msg.setHeaderFlag(Message::HEADERFLAG_RD); // set recursive bit
+    }
+
+    msg.addQuestion(Question(Name(name),
+                             RRClass(dns_class),
+                             any ? RRType::ANY() : RRType(type)));  // if NULL then:
+
+    MessageRenderer renderer;
+    msg.toWire(renderer);
+
+    struct addrinfo hints, *res;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_DGRAM;
+    hints.ai_flags = 0; // not using AI_NUMERICHOST in case to bootstrap
+    if (getaddrinfo(server, server_port, &hints, &res) != 0) {
+        cerr << "address/port conversion for " << server << ":"
+             << server_port << " failed" << endl;
+        return (1);
+    }
+
+    if (verbose) {
+        cout << "Trying \"" << name << "\"\n";
+    }
+
+    if (verbose && first_time) {
+        // this is only output the first time
+        first_time = 0;
+        cout << "Using domain server:\n";
+        cout << "Name: " << server << "\n";
+        // TODO: I guess I have to do a lookup to get that address and aliases
+        // too
+        //cout << "Address: " << address << "\n" ; // "#" << port << "\n";
+        //cout << "Aliases: " << server << "\n";
+    }
+
+    int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+    if (s < 0) {
+        cerr << "failed to open socket" << endl;
+        return (1);
+    }
+
+    if (verbose) {
+        gettimeofday(&before_time, NULL);
+    }
+
+    sendto(s, renderer.getData(), renderer.getLength(), 0, res->ai_addr,
+           res->ai_addrlen);
+
+    struct sockaddr_storage ss;
+    struct sockaddr* sa;
+    socklen_t sa_len;
+
+    sa_len = sizeof(ss);
+    sa = static_cast<struct sockaddr*>((void*)&ss);
+
+    char recvbuf[4096];
+    int cc;
+    if ((cc = recvfrom(s, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) {
+        try {
+            Message rmsg(Message::PARSE);
+            InputBuffer ibuffer(recvbuf, cc);
+
+            rmsg.fromWire(ibuffer);
+            if (!verbose) {
+                string description = "";
+                for (RRsetIterator it =
+                         rmsg.beginSection(Message::SECTION_ANSWER);
+                     it != rmsg.endSection(Message::SECTION_ANSWER);
+                     ++it) {
+
+                      if ((*it)->getType() == RRType::A()) {
+                          description = "has address";
+                      }
+                      else if ((*it)->getType() == RRType::AAAA()) {
+                          description = "has IPv6 address";
+                      }
+                      else if ((*it)->getType() == RRType::MX()) {
+                          description = "mail is handled by";
+                      }
+                      else if ((*it)->getType() == RRType::TXT()) {
+                          description = "descriptive text";
+                      }
+
+                      RdataIteratorPtr rit = (*it)->getRdataIterator();
+                      for (; !rit->isLast(); rit->next()) {
+                          // instead of using my name, maybe use returned label?
+                          cout << name << " "  << description << " " <<
+                              (*rit).getCurrent().toText() << endl;
+                      }
+                  }
+            } else {
+                gettimeofday(&after_time, NULL);
+
+                // HEADER and QUESTION, ANSWER, AUTHORITY, and ADDITIONAL
+                std::cout << rmsg.toText() << std::endl;
+
+                if (before_time.tv_usec > after_time.tv_usec) {
+                    after_time.tv_usec += 1000000;
+                    --after_time.tv_sec;
+                }
+
+                int elapsed_time =
+                    (after_time.tv_sec - before_time.tv_sec)
+                    + ((after_time.tv_usec - before_time.tv_usec))/1000;
+
+                // TODO: if NXDOMAIN, host(1) doesn't show HEADER
+                // Host hsdjkfhksjhdfkj not found: 3(NXDOMAIN)
+                // TODO: test if NXDOMAIN
+
+                std::cout << "Received " << cc <<
+                    " bytes in " << elapsed_time << " ms\n";
+                // TODO: " bytes from 127.0.0.1#53 in 0 ms
+
+            } //verbose
+/*
+TODO: handle InvalidRRClass
+TODO: handle invalid type exception
+        } catch (InvalidType ivt) {
+            std::cerr << "invalid type:" << ivt.what();
+*/
+        } catch (const exception& ex) {
+            std::cerr << "parse failed for " <<
+                string(name) << "/" << type << ": " << ex.what() << std::endl;
+        } catch (...) {
+            std::cerr << "parse failed for " << string(name) << "/" << type;
+        }
+    }
+
+    freeaddrinfo(res);
+
+    return (0);
+} // host_lookup()
+}
+
+int
+main(int argc, char* argv[]) {
+    int c;
+
+    while ((c = getopt(argc, argv, "ac:dp:rt:v")) != -1)
+        switch (c) {
+        case 'a':
+            dns_any = true;
+            verbose = true;
+            break;
+        case 'c':
+            dns_class = optarg;
+            break;
+	// p for port is a non-standard switch
+        case 'p':
+            server_port = optarg;
+            break;
+        case 'r':
+            recursive_bit = false;
+            break;
+        case 't':
+            dns_type = optarg;
+            break;
+        case 'd':
+            // drop through to v, because debug and verbose are equivalent
+        case 'v':
+            verbose = true;
+            break;
+    }
+    argc -= optind;
+    argv += optind;
+
+    if (argc < 1) {
+        cout << "Usage: host [-adrv] [-c class] [-p port] [-t type] hostname [server]\n";
+        exit(1);
+    }
+
+    if (argc >= 2) {
+      server = argv[1];
+    }
+
+    if (dns_type == NULL) {
+        host_lookup(argv[0], dns_class, "A", dns_any);
+        // TODO: don't do next if A doesn't exist
+        host_lookup(argv[0], dns_class, "AAAA", dns_any);
+        host_lookup(argv[0], dns_class, "MX", dns_any);
+    } else {
+        // -t overrides -a, regardless of order
+        host_lookup(argv[0], dns_class, dns_type, false);
+    }
+    return (0);
+}
diff --git a/examples/m4/ax_boost_include.m4 b/examples/m4/ax_boost_include.m4
new file mode 100644
index 0000000..e41614d
--- /dev/null
+++ b/examples/m4/ax_boost_include.m4
@@ -0,0 +1,64 @@
+dnl @synopsis AX_BOOST_INCLUDE
+dnl
+dnl Test for the Boost C++ header files
+dnl
+dnl If no path to the installed boost header files is given via the
+dnl --with-boost-include option,  the macro searchs under
+dnl /usr/local /usr/pkg /opt /opt/local directories.
+dnl
+dnl This macro calls:
+dnl
+dnl   AC_SUBST(BOOST_CPPFLAGS)
+dnl
+
+AC_DEFUN([AX_BOOST_INCLUDE], [
+AC_LANG_SAVE
+AC_LANG([C++])
+
+#
+# Configure Boost header path
+#
+# If explicitly specified, use it.
+AC_ARG_WITH([boost-include],
+  AS_HELP_STRING([--with-boost-include=PATH],
+    [specify exact directory for Boost headers]),
+    [boost_include_path="$withval"])
+# If not specified, try some common paths.
+if test -z "$with_boost_include"; then
+	boostdirs="/usr/local /usr/pkg /opt /opt/local"
+	for d in $boostdirs
+	do
+		if test -f $d/include/boost/shared_ptr.hpp; then
+			boost_include_path=$d/include
+			break
+		fi
+	done
+fi
+CPPFLAGS_SAVES="$CPPFLAGS"
+if test "${boost_include_path}" ; then
+	BOOST_CPPFLAGS="-I${boost_include_path}"
+	CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+fi
+# Make sure some commonly used headers are available
+AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/bind.hpp boost/function.hpp],,
+  AC_MSG_ERROR([Missing required Boost header files.]))
+
+# Detect whether Boost tries to use threads by default, and, if not,
+# make it sure explicitly.  In some systems the automatic detection
+# may depend on preceding header files, and if inconsistency happens
+# it could lead to a critical disruption.
+AC_MSG_CHECKING([whether Boost tries to use threads])
+AC_TRY_COMPILE([
+#include <boost/config.hpp>
+#ifdef BOOST_HAS_THREADS
+#error "boost will use threads"
+#endif],,
+[AC_MSG_RESULT(no)
+ CPPFLAGS_BOOST_THREADCONF="-DBOOST_DISABLE_THREADS=1"],
+[AC_MSG_RESULT(yes)])
+
+CPPFLAGS="$CPPFLAGS_SAVES $CPPFLAGS_BOOST_THREADCONF"
+AC_SUBST(BOOST_CPPFLAGS)
+
+AC_LANG_RESTORE
+])dnl AX_BOOST_INCLUDE
diff --git a/examples/m4/ax_isc_bind10.m4 b/examples/m4/ax_isc_bind10.m4
new file mode 100644
index 0000000..63e028c
--- /dev/null
+++ b/examples/m4/ax_isc_bind10.m4
@@ -0,0 +1,122 @@
+dnl @synopsis AX_BIND10
+dnl
+dnl @summary figure out how to build C++ programs using ISC BIND 10 libraries
+dnl
+dnl If no path to the installed BIND 10 header files or libraries is given
+dnl via the --with-bind10-include  or --with-bind10-lib option, the macro
+dnl searchs under /usr/local/{include, lib}, /usr/pkg/{include, lib},
+dnl /opt/{include, lib}, /opt/local/{include, lib} directories, respectively.
+dnl
+dnl This macro calls:
+dnl
+dnl   AC_SUBST(BIND10_CPPFLAGS)
+dnl   AC_SUBST(BIND10_LDFLAGS)
+dnl   AC_SUBST(BIND10_COMMON_LIB)
+dnl   AC_SUBST(BIND10_DNS_LIB)
+dnl
+dnl If this macro finds CPPFLAGS, LDFLAGS or COMMON_LIB unavailable, it treats
+dnl that as a fatal error.
+dnl Checks for other BIND 10 module libraries are option, as not all
+dnl applications need all libraries.  The main configure.ac can handle any
+dnl missing library as fatal by checking whether the corresponding
+dnl BIND10_xxx_LIB is defined.
+
+AC_DEFUN([AX_ISC_BIND10], [
+AC_REQUIRE([AX_BOOST_INCLUDE])
+AC_LANG_SAVE
+AC_LANG([C++])
+
+# Check for BIND10 common headers
+
+AC_ARG_WITH(bind10-include,
+  AS_HELP_STRING([--with-bind10-include=PATH],
+  [specify a path to BIND 10 header files]),
+    bind10_inc_path="$withval", bind10_inc_path="no")
+# If not specified, try some common paths.
+if test "$bind10_inc_path" = "no"; then
+   for d in /usr/local /usr/pkg /opt /opt/local
+   do
+	if test -f $d/include/util/buffer.h; then
+	   bind10_inc_path=$d
+	   break
+	fi
+   done
+fi
+CPPFLAGS_SAVES="$CPPFLAGS"
+if test "${bind10_inc_path}" != "no"; then
+   BIND10_CPPFLAGS="-I${bind10_inc_path}"
+   CPPFLAGS="$CPPFLAGS $BIND10_CPPFLAGS"
+fi
+AC_CHECK_HEADERS([util/buffer.h],,
+  AC_MSG_ERROR([Missing a commonly used BIND 10 header files]))
+CPPFLAGS="$CPPFLAGS_SAVES"
+AC_SUBST(BIND10_CPPFLAGS)
+
+# Check for BIND10 libraries
+CPPFLAGS_SAVED="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $BIND10_CPPFLAGS"
+
+AC_ARG_WITH(bind10-lib,
+  AS_HELP_STRING([--with-bind10-lib=PATH],
+  [specify a path to BIND 10 library files]),
+    bind10_lib_path="$withval", bind10_lib_path="no")
+if test $bind10_lib_path != "no"; then
+   bind10_lib_dirs=$bind10_lib_path
+else
+   # If not specified, try some common paths.
+   bind10_lib_dirs="/usr/local/lib /usr/pkg/lib /opt/lib /opt/local/lib"
+fi
+
+# make sure we have buildable libraries
+AC_MSG_CHECKING([for BIND 10 common library])
+BIND10_COMMON_LIB="-lb10-util -lb10-exceptions"
+LDFLAGS="$LDFLAGS $BIND10_LDFLAGS"
+LIBS="$LIBS $BIND10_COMMON_LIB"
+for d in $bind10_lib_dirs
+do
+  LDFLAGS_SAVED="$LDFLAGS"
+  LDFLAGS="$LDFLAGS -L$d"
+  AC_TRY_LINK([
+#include <util/buffer.h>
+],[
+isc::util::OutputBuffer buffer(0);
+], [BIND10_LDFLAGS="-L${d}"])
+  if test "x$BIND10_LDFLAGS" != "x"; then
+     break
+  fi
+  LDFLAGS="$LDFLAGS_SAVED"
+done
+if test "x$BIND10_LDFLAGS" != "x"; then
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+  AC_MSG_ERROR([unable to find required BIND 10 libraries])
+fi
+
+# restore LIBS once at this point
+LIBS="$LIBS_SAVES"
+
+AC_SUBST(BIND10_LDFLAGS)
+AC_SUBST(BIND10_COMMON_LIB)
+
+# Check per-module BIND 10 libraries
+
+# DNS library
+AC_MSG_CHECKING([for BIND 10 DNS library])
+LIBS="$LIBS $BIND10_COMMON_LIB -lb10-dns++"
+AC_TRY_LINK([
+#include <dns/rrtype.h>
+],[
+isc::dns::RRType rrtype(1);
+], [BIND10_DNS_LIB="-lb10-dns++"
+    AC_MSG_RESULT(yes)],
+   [AC_MSG_RESULT(no)])
+LIBS="$LIBS_SAVES"
+AC_SUBST(BIND10_DNS_LIB)
+
+# Restore other flags
+CPPFLAGS="$CPPFLAGS_SAVED"
+LDFLAGS="$LDFLAGS_SAVES"
+
+AC_LANG_RESTORE
+])dnl AX_ISC_BIND10
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index 7af44f9..0b4c1ae 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = bind10 bindctl cfgmgr ddns loadzone msgq host cmdctl auth xfrin \
+SUBDIRS = bind10 bindctl cfgmgr ddns loadzone msgq cmdctl auth xfrin \
 	xfrout usermgr zonemgr stats tests resolver sockcreator dhcp4 dhcp6 \
 	dbutil sysinfo
 
diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am
index 6128a4c..9eee9d4 100644
--- a/src/bin/auth/Makefile.am
+++ b/src/bin/auth/Makefile.am
@@ -55,7 +55,7 @@ b10_auth_SOURCES += auth_config.cc auth_config.h
 b10_auth_SOURCES += command.cc command.h
 b10_auth_SOURCES += common.h common.cc
 b10_auth_SOURCES += statistics.cc statistics.h
-b10_auth_SOURCES += datasrc_configurator.h
+b10_auth_SOURCES += datasrc_config.h datasrc_config.cc
 b10_auth_SOURCES += main.cc
 
 nodist_b10_auth_SOURCES = auth_messages.h auth_messages.cc
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index b870ae2..e73eb52 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -69,6 +69,8 @@
 
 using namespace std;
 
+using boost::shared_ptr;
+
 using namespace isc;
 using namespace isc::cc;
 using namespace isc::datasrc;
@@ -264,23 +266,22 @@ public:
     AddressList listen_addresses_;
 
     /// The TSIG keyring
-    const boost::shared_ptr<TSIGKeyRing>* keyring_;
+    const shared_ptr<TSIGKeyRing>* keyring_;
 
-    /// The client list
-    std::map<RRClass, boost::shared_ptr<ConfigurableClientList> >
-        client_lists_;
+    /// The data source client list
+    AuthSrv::DataSrcClientListsPtr datasrc_client_lists_;
 
-    boost::shared_ptr<ConfigurableClientList> getClientList(const RRClass&
-                                                            rrclass)
+    shared_ptr<ConfigurableClientList> getDataSrcClientList(
+        const RRClass& rrclass)
     {
         // TODO: Debug-build only check
         if (!mutex_.locked()) {
             isc_throw(isc::Unexpected, "Not locked!");
         }
-        const std::map<RRClass, boost::shared_ptr<ConfigurableClientList> >::
-            const_iterator it(client_lists_.find(rrclass));
-        if (it == client_lists_.end()) {
-            return (boost::shared_ptr<ConfigurableClientList>());
+        const std::map<RRClass, shared_ptr<ConfigurableClientList> >::
+            const_iterator it(datasrc_client_lists_->find(rrclass));
+        if (it == datasrc_client_lists_->end()) {
+            return (shared_ptr<ConfigurableClientList>());
         } else {
             return (it->second);
         }
@@ -335,6 +336,8 @@ AuthSrvImpl::AuthSrvImpl(AbstractXfroutClient& xfrout_client,
     xfrin_session_(NULL),
     counters_(),
     keyring_(NULL),
+    datasrc_client_lists_(new std::map<RRClass,
+                          shared_ptr<ConfigurableClientList> >()),
     ddns_base_forwarder_(ddns_forwarder),
     ddns_forwarder_(NULL),
     xfrout_connected_(false),
@@ -645,13 +648,13 @@ AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
     }
     // Lock the client lists and keep them under the lock until the processing
     // and rendering is done (this is the same mutex as from
-    // AuthSrv::getClientListMutex()).
+    // AuthSrv::getDataSrcClientListMutex()).
     isc::util::thread::Mutex::Locker locker(mutex_);
 
     try {
         const ConstQuestionPtr question = *message.beginQuestion();
-        const boost::shared_ptr<datasrc::ClientList>
-            list(getClientList(question->getClass()));
+        const shared_ptr<datasrc::ClientList>
+            list(getDataSrcClientList(question->getClass()));
         if (list) {
             const RRType& qtype = question->getType();
             const Name& qname = question->getName();
@@ -911,7 +914,7 @@ AuthSrv::setDNSService(isc::asiodns::DNSServiceBase& dnss) {
 }
 
 void
-AuthSrv::setTSIGKeyRing(const boost::shared_ptr<TSIGKeyRing>* keyring) {
+AuthSrv::setTSIGKeyRing(const shared_ptr<TSIGKeyRing>* keyring) {
     impl_->keyring_ = keyring;
 }
 
@@ -930,43 +933,23 @@ AuthSrv::destroyDDNSForwarder() {
     }
 }
 
-void
-AuthSrv::setClientList(const RRClass& rrclass,
-                       const boost::shared_ptr<ConfigurableClientList>& list) {
+AuthSrv::DataSrcClientListsPtr
+AuthSrv::swapDataSrcClientLists(DataSrcClientListsPtr new_lists) {
     // TODO: Debug-build only check
     if (!impl_->mutex_.locked()) {
-        isc_throw(isc::Unexpected, "Not locked");
-    }
-
-    if (list) {
-        impl_->client_lists_[rrclass] = list;
-    } else {
-        impl_->client_lists_.erase(rrclass);
+        isc_throw(isc::Unexpected, "Not locked!");
     }
-}
-boost::shared_ptr<ConfigurableClientList>
-AuthSrv::getClientList(const RRClass& rrclass) {
-    return (impl_->getClientList(rrclass));
+    std::swap(new_lists, impl_->datasrc_client_lists_);
+    return (new_lists);
 }
 
-vector<RRClass>
-AuthSrv::getClientListClasses() const {
-    // TODO: Debug-build only check
-    if (!impl_->mutex_.locked()) {
-        isc_throw(isc::Unexpected, "Not locked");
-    }
-
-    vector<RRClass> result;
-    for (std::map<RRClass, boost::shared_ptr<ConfigurableClientList> >::
-         const_iterator it(impl_->client_lists_.begin());
-         it != impl_->client_lists_.end(); ++it) {
-        result.push_back(it->first);
-    }
-    return (result);
+shared_ptr<ConfigurableClientList>
+AuthSrv::getDataSrcClientList(const RRClass& rrclass) {
+    return (impl_->getDataSrcClientList(rrclass));
 }
 
 util::thread::Mutex&
-AuthSrv::getClientListMutex() const {
+AuthSrv::getDataSrcClientListMutex() const {
     return (impl_->mutex_);
 }
 
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index ee7bd52..0849bdd 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -15,10 +15,11 @@
 #ifndef __AUTH_SRV_H
 #define __AUTH_SRV_H 1
 
-#include <string>
-
 #include <config/ccsession.h>
+
 #include <datasrc/factory.h>
+#include <datasrc/client_list.h>
+
 #include <dns/message.h>
 #include <dns/opcode.h>
 #include <util/buffer.h>
@@ -35,6 +36,11 @@
 #include <server_common/portconfig.h>
 #include <auth/statistics.h>
 
+#include <boost/shared_ptr.hpp>
+
+#include <map>
+#include <string>
+
 namespace isc {
 namespace util {
 namespace io {
@@ -296,31 +302,46 @@ public:
     /// If there was no forwarder yet, this method does nothing.
     void destroyDDNSForwarder();
 
-    /// \brief Sets the currently used list for data sources of given
-    ///     class.
+    /// \brief Shortcut typedef used for swapDataSrcClientLists().
+    typedef boost::shared_ptr<std::map<
+        isc::dns::RRClass, boost::shared_ptr<
+                               isc::datasrc::ConfigurableClientList> > >
+    DataSrcClientListsPtr;
+
+    /// \brief Swap the currently used set of data source client lists with
+    /// given one.
+    ///
+    /// The "set" of lists is actually given in the form of map from
+    /// RRClasses to shared pointers to isc::datasrc::ConfigurableClientList.
+    ///
+    /// This method returns the swapped set of lists, which was previously
+    /// used by the server.
+    ///
+    /// This method is intended to be used by a separate method to update
+    /// the data source configuration "at once".  The caller must hold
+    /// a lock for the mutex object returned by  \c getDataSrcClientListMutex()
+    /// before calling this method.
     ///
-    /// Replaces the internally used client list with a new one. Other
-    /// classes are not changed.
+    /// The ownership of the returned pointer is transferred to the caller.
+    /// The caller is generally expected to release the resources used in
+    /// the old lists.  Note that it could take longer time if some of the
+    /// data source clients contain a large size of in-memory data.
     ///
-    /// \param rrclass The class to modify.
-    /// \param list Shared pointer to the client list. If it is NULL,
-    ///     the list is removed instead.
-    void setClientList(const isc::dns::RRClass& rrclass, const
-                       boost::shared_ptr<isc::datasrc::ConfigurableClientList>&
-                       list);
+    /// The caller can pass a NULL pointer.  This effectively disables
+    /// any data source for the server.
+    ///
+    /// \param new_lists Shared pointer to a new set of data source client
+    /// lists.
+    /// \return The previous set of lists.  It can be NULL.
+    DataSrcClientListsPtr swapDataSrcClientLists(DataSrcClientListsPtr
+                                                 new_lists);
 
     /// \brief Returns the currently used client list for the class.
     ///
     /// \param rrclass The class for which to get the list.
     /// \return The list, or NULL if no list is set for the class.
     boost::shared_ptr<isc::datasrc::ConfigurableClientList>
-        getClientList(const isc::dns::RRClass& rrclass);
-
-    /// \brief Returns a list of classes that have a client list.
-    ///
-    /// \return List of classes for which a non-NULL client list
-    ///     has been set by setClientList.
-    std::vector<isc::dns::RRClass> getClientListClasses() const;
+        getDataSrcClientList(const isc::dns::RRClass& rrclass);
 
     /// \brief Return a mutex for the client lists.
     ///
@@ -331,9 +352,9 @@ public:
     /// is correct:
     /// \code
     /// {
-    ///  Mutex::Locker locker(auth->getClientListMutex());
+    ///  Mutex::Locker locker(auth->getDataSrcClientListMutex());
     ///  boost::shared_ptr<isc::datasrc::ConfigurableClientList>
-    ///    list(auth->getClientList(RRClass::IN()));
+    ///    list(auth->getDataSrcClientList(RRClass::IN()));
     ///  // Do some processing here
     /// }
     /// \endcode
@@ -342,8 +363,8 @@ public:
     /// \code
     /// boost::shared_ptr<isc::datasrc::ConfigurableClientList> list;
     /// {
-    ///     Mutex::Locker locker(auth->getClientListMutex());
-    ///     list = auth->getClientList(RRClass::IN()));
+    ///     Mutex::Locker locker(auth->getDataSrcClientListMutex());
+    ///     list = auth->getDataSrcClientList(RRClass::IN()));
     /// }
     /// // Do some processing here
     /// \endcode
@@ -352,7 +373,7 @@ public:
     ///    (lock) the mutex. It's because locking of the mutex is not really
     ///    a modification of the server object and it is needed to protect the
     ///    lists even on read-only operations.
-    isc::util::thread::Mutex& getClientListMutex() const;
+    isc::util::thread::Mutex& getDataSrcClientListMutex() const;
 
     /// \brief Sets the timeout for incoming TCP connections
     ///
diff --git a/src/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am
index 48e552a..c525b66 100644
--- a/src/bin/auth/benchmarks/Makefile.am
+++ b/src/bin/auth/benchmarks/Makefile.am
@@ -17,6 +17,7 @@ query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc
 query_bench_SOURCES += ../auth_config.h ../auth_config.cc
 query_bench_SOURCES += ../statistics.h ../statistics.cc
 query_bench_SOURCES += ../auth_log.h ../auth_log.cc
+query_bench_SOURCES += ../datasrc_config.h ../datasrc_config.cc
 
 nodist_query_bench_SOURCES = ../auth_messages.h ../auth_messages.cc
 
diff --git a/src/bin/auth/benchmarks/query_bench.cc b/src/bin/auth/benchmarks/query_bench.cc
index 93253db..37976a3 100644
--- a/src/bin/auth/benchmarks/query_bench.cc
+++ b/src/bin/auth/benchmarks/query_bench.cc
@@ -18,6 +18,8 @@
 #include <bench/benchmark_util.h>
 
 #include <util/buffer.h>
+#include <util/threads/lock.h>
+
 #include <dns/message.h>
 #include <dns/name.h>
 #include <dns/question.h>
@@ -30,7 +32,7 @@
 
 #include <auth/auth_srv.h>
 #include <auth/auth_config.h>
-#include <auth/datasrc_configurator.h>
+#include <auth/datasrc_config.h>
 #include <auth/query.h>
 
 #include <asiodns/asiodns.h>
@@ -125,13 +127,15 @@ public:
                           OutputBuffer& buffer) :
         QueryBenchMark(queries, query_message, buffer)
     {
-        DataSourceConfigurator::testReconfigure(
-            server_.get(),
-            Element::fromJSON("{\"IN\":"
-                              "  [{\"type\": \"sqlite3\","
-                              "    \"params\": {"
-                              "      \"database_file\": \"" +
-                              string(datasrc_file) + "\"}}]}"));
+        isc::util::thread::Mutex::Locker locker(
+                server_->getDataSrcClientListMutex());
+        server_->swapDataSrcClientLists(
+            configureDataSource(
+                Element::fromJSON("{\"IN\":"
+                                  "  [{\"type\": \"sqlite3\","
+                                  "    \"params\": {"
+                                  "      \"database_file\": \"" +
+                                  string(datasrc_file) + "\"}}]}")));
     }
 };
 
@@ -139,19 +143,21 @@ class MemoryQueryBenchMark  : public QueryBenchMark {
 public:
     MemoryQueryBenchMark(const char* const zone_file,
                          const char* const zone_origin,
-                          const BenchQueries& queries,
-                          Message& query_message,
-                          OutputBuffer& buffer) :
+                         const BenchQueries& queries,
+                         Message& query_message,
+                         OutputBuffer& buffer) :
         QueryBenchMark(queries, query_message, buffer)
     {
-        DataSourceConfigurator::testReconfigure(
-            server_.get(),
-            Element::fromJSON("{\"IN\":"
-                              "  [{\"type\": \"MasterFiles\","
-                              "    \"cache-enable\": true, "
-                              "    \"params\": {\"" +
-                              string(zone_origin) + "\": \"" +
-                              string(zone_file) + "\"}}]}"));
+        isc::util::thread::Mutex::Locker locker(
+                server_->getDataSrcClientListMutex());
+        server_->swapDataSrcClientLists(
+            configureDataSource(
+                Element::fromJSON("{\"IN\":"
+                                  "  [{\"type\": \"MasterFiles\","
+                                  "    \"cache-enable\": true, "
+                                  "    \"params\": {\"" +
+                                  string(zone_origin) + "\": \"" +
+                                  string(zone_file) + "\"}}]}")));
     }
 };
 
diff --git a/src/bin/auth/command.cc b/src/bin/auth/command.cc
index 448a31b..d26cf09 100644
--- a/src/bin/auth/command.cc
+++ b/src/bin/auth/command.cc
@@ -192,9 +192,10 @@ public:
 
         // We're going to work with the client lists. They may be used
         // from a different thread too, protect them.
-        isc::util::thread::Mutex::Locker locker(server.getClientListMutex());
+        isc::util::thread::Mutex::Locker locker(
+            server.getDataSrcClientListMutex());
         const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
-            list(server.getClientList(zone_class));
+            list(server.getDataSrcClientList(zone_class));
 
         if (!list) {
             isc_throw(AuthCommandError, "There's no client list for "
diff --git a/src/bin/auth/datasrc_config.cc b/src/bin/auth/datasrc_config.cc
new file mode 100644
index 0000000..62c3c7a
--- /dev/null
+++ b/src/bin/auth/datasrc_config.cc
@@ -0,0 +1,25 @@
+// Copyright (C) 2012  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 <cc/data.h>
+#include "auth_srv.h"
+#include "datasrc_config.h"
+
+// This is a trivial specialization for the commonly used version.
+// Defined in .cc to avoid accidental creation of multiple copies.
+AuthSrv::DataSrcClientListsPtr
+configureDataSource(const isc::data::ConstElementPtr& config) {
+    return (configureDataSourceGeneric<
+            isc::datasrc::ConfigurableClientList>(config));
+}
diff --git a/src/bin/auth/datasrc_config.h b/src/bin/auth/datasrc_config.h
new file mode 100644
index 0000000..5707c6c
--- /dev/null
+++ b/src/bin/auth/datasrc_config.h
@@ -0,0 +1,83 @@
+// Copyright (C) 2012  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.
+
+#ifndef DATASRC_CONFIG_H
+#define DATASRC_CONFIG_H
+
+#include "auth_srv.h"
+
+#include <cc/data.h>
+#include <datasrc/client_list.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <utility>
+#include <set>
+
+/// \brief Configure data source client lists
+///
+/// This will hook into the data_sources module configuration and it will
+/// return a new set (in the form of a shared pointer to map) of data source
+/// client lists corresponding to the configuration.
+///
+/// This function is templated. This is simply because of easier testing.
+/// You don't need to pay attention to it, use the configureDataSource
+/// specialization instead.
+///
+/// \note In future we may want to make the reconfiguration more efficient
+/// by only creating newly configured data and just moving the rest from
+/// the running configuration if they are used in the new configuration
+/// without any parameter change.  We could probably do it by passing
+/// the old lists in addition to the new config, but further details are
+/// still to be defined yet.  It will surely require changes in the
+/// data source library, too.  So, right now, we don't introduce the
+/// possibility in the function interface.  If and when we decide to introduce
+/// the optimization, we'll extend the interface.
+///
+/// \param config The configuration value to parse. It is in the form
+///     as an update from the config manager.
+/// \return A map from RR classes to configured lists.
+template<class List>
+boost::shared_ptr<std::map<isc::dns::RRClass,
+                           boost::shared_ptr<List> > > // = ListMap below
+configureDataSourceGeneric(const isc::data::ConstElementPtr& config) {
+    typedef boost::shared_ptr<List> ListPtr;
+    typedef std::map<std::string, isc::data::ConstElementPtr> Map;
+    typedef std::map<isc::dns::RRClass, ListPtr> ListMap;
+
+    boost::shared_ptr<ListMap> new_lists(new ListMap);
+
+    // Go through the configuration and create corresponding list.
+    const Map& map(config->mapValue());
+    for (Map::const_iterator it(map.begin()); it != map.end(); ++it) {
+        const isc::dns::RRClass rrclass(it->first);
+        ListPtr list(new List(rrclass));
+        list->configure(it->second, true);
+        new_lists->insert(std::pair<isc::dns::RRClass, ListPtr>(rrclass,
+                                                                list));
+    }
+
+    return (new_lists);
+}
+
+/// \brief Concrete version of configureDataSource() for the
+///     use with authoritative server implementation.
+AuthSrv::DataSrcClientListsPtr
+configureDataSource(const isc::data::ConstElementPtr& config);
+
+#endif  // DATASRC_CONFIG_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/bin/auth/datasrc_configurator.h b/src/bin/auth/datasrc_configurator.h
deleted file mode 100644
index 6b2f582..0000000
--- a/src/bin/auth/datasrc_configurator.h
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright (C) 2012  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.
-
-#ifndef DATASRC_CONFIGURATOR_H
-#define DATASRC_CONFIGURATOR_H
-
-#include "auth_srv.h"
-
-#include <datasrc/client_list.h>
-#include <config/ccsession.h>
-#include <cc/data.h>
-#include <util/threads/lock.h>
-
-#include <set>
-
-/// \brief A class to configure the authoritative server's data source lists
-///
-/// This will hook into the data_sources module configuration and it will
-/// keep the local copy of data source clients in the list in the authoritative
-/// server.
-///
-/// The class is slightly unusual. Due to some technical limitations, the hook
-/// needs to be static method. Therefore it is not possible to create instances
-/// of the class.
-///
-/// Also, the class is a template. This is simply because of easier testing.
-/// You don't need to pay attention to it, use the DataSourceConfigurator
-/// type alias instead.
-template<class Server, class List>
-class DataSourceConfiguratorGeneric {
-private:
-    /// \brief Disallow creation of instances
-    DataSourceConfiguratorGeneric();
-    /// \brief Internal method to hook into the ModuleCCSession
-    ///
-    /// It simply calls reconfigure.
-    static void reconfigureInternal(const std::string&,
-                                    isc::data::ConstElementPtr config,
-                                    const isc::config::ConfigData&)
-    {
-        if (config->contains("classes")) {
-            reconfigure(config->get("classes"));
-        }
-    }
-    static Server* server_;
-    static isc::config::ModuleCCSession* session_;
-    typedef boost::shared_ptr<List> ListPtr;
-public:
-    /// \brief Initializes the class.
-    ///
-    /// This configures which session and server should be used.
-    /// It hooks to the session now and downloads the configuration.
-    /// It is synchronous (it may block for some time).
-    ///
-    /// Note that you need to call cleanup before the server or
-    /// session dies, otherwise it might access them after they
-    /// are destroyed.
-    ///
-    /// \param session The session to hook into and to access the configuration
-    ///     through.
-    /// \param server It is the server to configure.
-    /// \throw isc::InvalidOperation if this is called when already initialized.
-    /// \throw isc::InvalidParameter if any of the parameters is NULL
-    /// \throw isc::config::ModuleCCError if the remote configuration is not
-    ///     available for some reason.
-    static void init(isc::config::ModuleCCSession* session,
-                     Server* server)
-    {
-        if (session == NULL) {
-            isc_throw(isc::InvalidParameter, "The session must not be NULL");
-        }
-        if (server == NULL) {
-            isc_throw(isc::InvalidParameter, "The server must not be NULL");
-        }
-        if (server_ != NULL) {
-            isc_throw(isc::InvalidOperation,
-                      "The configurator is already initialized");
-        }
-        server_ = server;
-        session_ = session;
-        session->addRemoteConfig("data_sources", reconfigureInternal, false);
-    }
-    /// \brief Deinitializes the class.
-    ///
-    /// This detaches from the session and removes the server from internal
-    /// storage. The current configuration in the server is preserved.
-    ///
-    /// This can be called even if it is not initialized currently. You
-    /// can initialize it again after this.
-    static void cleanup() {
-        if (session_ != NULL) {
-            session_->removeRemoteConfig("data_sources");
-        }
-        session_ = NULL;
-        server_ = NULL;
-    }
-    /// \brief Reads new configuration and replaces the old one.
-    ///
-    /// It instructs the server to replace the lists with new ones as needed.
-    /// You don't need to call it directly (but you could, though the benefit
-    /// is unknown and it would be questionable at least). It is called
-    /// automatically on normal updates.
-    ///
-    /// \param config The configuration value to parse. It is in the form
-    ///     as an update from the config manager.
-    /// \throw InvalidOperation if it is called when not initialized.
-    static void reconfigure(const isc::data::ConstElementPtr& config) {
-        if (server_ == NULL) {
-            isc_throw(isc::InvalidOperation,
-                      "Can't reconfigure while not initialized by init()");
-        }
-        // Lock the client lists, we're going to manipulate them.
-        isc::util::thread::Mutex::Locker locker(server_->getClientListMutex());
-        typedef std::map<std::string, isc::data::ConstElementPtr> Map;
-        typedef std::pair<isc::dns::RRClass, ListPtr> RollbackPair;
-        typedef std::pair<isc::dns::RRClass, isc::data::ConstElementPtr>
-            RollbackConfiguration;
-        // Some structures to be able to perform a rollback
-        std::vector<RollbackPair> rollback_sets;
-        std::vector<RollbackConfiguration> rollback_configurations;
-        try {
-            // Get the configuration and current state.
-            const Map& map(config->mapValue());
-            const std::vector<isc::dns::RRClass>
-                activeVector(server_->getClientListClasses());
-            std::set<isc::dns::RRClass> active(activeVector.begin(),
-                                               activeVector.end());
-            // Go through the configuration and change everything.
-            for (Map::const_iterator it(map.begin()); it != map.end(); ++it) {
-                isc::dns::RRClass rrclass(it->first);
-                active.erase(rrclass);
-                ListPtr list(server_->getClientList(rrclass));
-                bool need_set(false);
-                if (list) {
-                    rollback_configurations.
-                        push_back(RollbackConfiguration(rrclass,
-                            list->getConfiguration()));
-                } else {
-                    list.reset(new List(rrclass));
-                    need_set = true;
-                    rollback_sets.push_back(RollbackPair(rrclass, ListPtr()));
-                }
-                list->configure(it->second, true);
-                if (need_set) {
-                    server_->setClientList(rrclass, list);
-                }
-            }
-            // Remove the ones that are not in the configuration.
-            for (std::set<isc::dns::RRClass>::iterator it(active.begin());
-                 it != active.end(); ++it) {
-                // There seems to be no way the setClientList could throw.
-                // But this is just to make sure in case it did to restore
-                // the original.
-                rollback_sets.push_back(
-                    RollbackPair(*it, server_->getClientList(*it)));
-                server_->setClientList(*it, ListPtr());
-            }
-        } catch (...) {
-            // Perform a rollback of the changes. The old configuration should
-            // work.
-            for (typename std::vector<RollbackPair>::const_iterator
-                 it(rollback_sets.begin()); it != rollback_sets.end(); ++it) {
-                server_->setClientList(it->first, it->second);
-            }
-            for (typename std::vector<RollbackConfiguration>::const_iterator
-                 it(rollback_configurations.begin());
-                 it != rollback_configurations.end(); ++it) {
-                server_->getClientList(it->first)->configure(it->second, true);
-            }
-            throw;
-        }
-    }
-    /// \brief Version of reconfigure for easier testing.
-    ///
-    /// This method can be used to reconfigure a server without first
-    /// initializing the configurator. This does not need a session.
-    /// Otherwise, it acts the same as reconfigure.
-    ///
-    /// This is not meant for production code. Do not use there.
-    ///
-    /// \param server The server to configure.
-    /// \param config The config to use.
-    /// \throw isc::InvalidOperation if the configurator is initialized.
-    /// \throw anything that reconfigure does.
-    static void testReconfigure(Server* server,
-                                const isc::data::ConstElementPtr& config)
-    {
-        if (server_ != NULL) {
-            isc_throw(isc::InvalidOperation, "Currently initialized.");
-        }
-        try {
-            server_ = server;
-            reconfigure(config);
-            server_ = NULL;
-        } catch (...) {
-            server_ = NULL;
-            throw;
-        }
-    }
-};
-
-template<class Server, class List>
-isc::config::ModuleCCSession*
-DataSourceConfiguratorGeneric<Server, List>::session_(NULL);
-
-template<class Server, class List>
-Server* DataSourceConfiguratorGeneric<Server, List>::server_(NULL);
-
-/// \brief Concrete version of DataSourceConfiguratorGeneric for the
-///     use in authoritative server.
-typedef DataSourceConfiguratorGeneric<AuthSrv,
-        isc::datasrc::ConfigurableClientList>
-    DataSourceConfigurator;
-
-#endif
diff --git a/src/bin/auth/main.cc b/src/bin/auth/main.cc
index 3cca3c0..9908066 100644
--- a/src/bin/auth/main.cc
+++ b/src/bin/auth/main.cc
@@ -14,21 +14,11 @@
 
 #include <config.h>
 
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <cassert>
-#include <iostream>
-
 #include <exceptions/exceptions.h>
 
 #include <util/buffer.h>
 #include <util/io/socketsession.h>
+#include <util/threads/lock.h>
 
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
@@ -45,13 +35,26 @@
 #include <auth/command.h>
 #include <auth/auth_srv.h>
 #include <auth/auth_log.h>
-#include <auth/datasrc_configurator.h>
+#include <auth/datasrc_config.h>
 #include <asiodns/asiodns.h>
 #include <asiolink/asiolink.h>
 #include <log/logger_support.h>
 #include <server_common/keyring.h>
 #include <server_common/socket_request.h>
 
+#include <boost/bind.hpp>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <cassert>
+#include <iostream>
+
 using namespace std;
 using namespace isc::asiodns;
 using namespace isc::asiolink;
@@ -70,7 +73,7 @@ namespace {
 /* need global var for config/command handlers.
  * todo: turn this around, and put handlers in the authserver
  * class itself? */
-AuthSrv *auth_server;
+AuthSrv* auth_server;
 
 ConstElementPtr
 my_config_handler(ConstElementPtr new_config) {
@@ -84,6 +87,42 @@ my_command_handler(const string& command, ConstElementPtr args) {
 }
 
 void
+datasrcConfigHandler(AuthSrv* server, bool* first_time,
+                     ModuleCCSession* config_session, const std::string&,
+                     isc::data::ConstElementPtr config,
+                     const isc::config::ConfigData&)
+{
+    assert(server != NULL);
+    if (config->contains("classes")) {
+        AuthSrv::DataSrcClientListsPtr lists;
+
+        if (*first_time) {
+            // HACK: The default is not passed to the handler in the first
+            // callback. This one will get the default (or, current value).
+            // Further updates will work the usual way.
+            assert(config_session != NULL);
+            *first_time = false;
+            lists = configureDataSource(
+                config_session->getRemoteConfigValue("data_sources",
+                                                     "classes"));
+        } else {
+            lists = configureDataSource(config->get("classes"));
+        }
+
+        // Replace the server's lists.  The returned lists will be stored
+        // in a local variable 'lists', and will be destroyed outside of
+        // the temporary block for the lock scope.  That way we can minimize
+        // the range of the critical section.
+        {
+            isc::util::thread::Mutex::Locker locker(
+                server->getDataSrcClientListMutex());
+            lists = server->swapDataSrcClientLists(lists);
+        }
+        // The previous lists are destroyed here.
+    }
+}
+
+void
 usage() {
     cerr << "Usage:  b10-auth [-v]"
          << endl;
@@ -191,13 +230,15 @@ main(int argc, char* argv[]) {
         isc::server_common::initKeyring(*config_session);
         auth_server->setTSIGKeyRing(&isc::server_common::keyring);
 
-        // Start the data source configuration
-        DataSourceConfigurator::init(config_session, auth_server);
-        // HACK: The default is not passed to the handler. This one will
-        // get the default (or, current value). Further updates will work
-        // the usual way.
-        DataSourceConfigurator::reconfigure(
-            config_session->getRemoteConfigValue("data_sources", "classes"));
+        // Start the data source configuration.  We pass first_time and
+        // config_session for the hack described in datasrcConfigHandler.
+        bool first_time = true;
+        config_session->addRemoteConfig("data_sources",
+                                        boost::bind(datasrcConfigHandler,
+                                                    auth_server, &first_time,
+                                                    config_session,
+                                                    _1, _2, _3),
+                                        false);
 
         // Now start asynchronous read.
         config_session->start();
@@ -221,7 +262,10 @@ main(int argc, char* argv[]) {
         xfrin_session->disconnect();
     }
 
-    DataSourceConfigurator::cleanup();
+    // If we haven't registered callback for data sources, this will be just
+    // no-op.
+    config_session->removeRemoteConfig("data_sources");
+
     delete xfrin_session;
     delete config_session;
     delete cc_session;
diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am
index 7c01a6b..6b9d385 100644
--- a/src/bin/auth/tests/Makefile.am
+++ b/src/bin/auth/tests/Makefile.am
@@ -42,6 +42,7 @@ run_unittests_SOURCES += ../auth_config.h ../auth_config.cc
 run_unittests_SOURCES += ../command.h ../command.cc
 run_unittests_SOURCES += ../common.h ../common.cc
 run_unittests_SOURCES += ../statistics.h ../statistics.cc
+run_unittests_SOURCES += ../datasrc_config.h ../datasrc_config.cc
 run_unittests_SOURCES += datasrc_util.h datasrc_util.cc
 run_unittests_SOURCES += auth_srv_unittest.cc
 run_unittests_SOURCES += config_unittest.cc
@@ -50,7 +51,7 @@ run_unittests_SOURCES += command_unittest.cc
 run_unittests_SOURCES += common_unittest.cc
 run_unittests_SOURCES += query_unittest.cc
 run_unittests_SOURCES += statistics_unittest.cc
-run_unittests_SOURCES += datasrc_configurator_unittest.cc
+run_unittests_SOURCES += datasrc_config_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 
 nodist_run_unittests_SOURCES = ../auth_messages.h ../auth_messages.cc
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index e6e3ef7..e248e81 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -36,7 +36,7 @@
 #include <auth/command.h>
 #include <auth/common.h>
 #include <auth/statistics.h>
-#include <auth/datasrc_configurator.h>
+#include <auth/datasrc_config.h>
 
 #include <util/unittests/mock_socketsession.h>
 #include <util/threads/lock.h>
@@ -63,6 +63,7 @@
 using namespace std;
 using namespace isc::cc;
 using namespace isc::dns;
+using namespace isc::datasrc;
 using namespace isc::util;
 using namespace isc::util::io::internal;
 using namespace isc::util::unittests;
@@ -90,6 +91,9 @@ const char* const STATIC_DSRC_FILE = DSRC_DIR "/static.zone";
 // a signed example zone.
 const char* const CONFIG_INMEMORY_EXAMPLE = TEST_DATA_DIR "/rfc5155-example.zone.signed";
 
+// shortcut commonly used in tests
+typedef boost::shared_ptr<ConfigurableClientList> ListPtr;
+
 class AuthSrvTest : public SrvTestBase {
 protected:
     AuthSrvTest() :
@@ -722,17 +726,25 @@ TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
 }
 
 void
-updateDatabase(AuthSrv* server, const char* params) {
+installDataSrcClientLists(AuthSrv& server,
+                          AuthSrv::DataSrcClientListsPtr lists)
+{
+    thread::Mutex::Locker locker(server.getDataSrcClientListMutex());
+    server.swapDataSrcClientLists(lists);
+}
+
+void
+updateDatabase(AuthSrv& server, const char* params) {
     const ConstElementPtr config(Element::fromJSON("{"
         "\"IN\": [{"
         "    \"type\": \"sqlite3\","
         "    \"params\": " + string(params) +
         "}]}"));
-    DataSourceConfigurator::testReconfigure(server, config);
+    installDataSrcClientLists(server, configureDataSource(config));
 }
 
 void
-updateInMemory(AuthSrv* server, const char* origin, const char* filename) {
+updateInMemory(AuthSrv& server, const char* origin, const char* filename) {
     const ConstElementPtr config(Element::fromJSON("{"
         "\"IN\": [{"
         "   \"type\": \"MasterFiles\","
@@ -745,17 +757,17 @@ updateInMemory(AuthSrv* server, const char* origin, const char* filename) {
         "   \"type\": \"static\","
         "   \"params\": \"" + string(STATIC_DSRC_FILE) + "\""
         "}]}"));
-    DataSourceConfigurator::testReconfigure(server, config);
+    installDataSrcClientLists(server, configureDataSource(config));
 }
 
 void
-updateBuiltin(AuthSrv* server) {
+updateBuiltin(AuthSrv& server) {
     const ConstElementPtr config(Element::fromJSON("{"
         "\"CH\": [{"
         "   \"type\": \"static\","
         "   \"params\": \"" + string(STATIC_DSRC_FILE) + "\""
         "}]}"));
-    DataSourceConfigurator::testReconfigure(server, config);
+    installDataSrcClientLists(server, configureDataSource(config));
 }
 
 // Try giving the server a TSIG signed request and see it can anwer signed as
@@ -766,7 +778,7 @@ TEST_F(AuthSrvTest, DISABLED_TSIGSigned) { // Needs builtin
 TEST_F(AuthSrvTest, TSIGSigned) {
 #endif
     // Prepare key, the client message, etc
-    updateBuiltin(&server);
+    updateBuiltin(server);
     const TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
     TSIGContext context(key);
     UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
@@ -814,7 +826,7 @@ TEST_F(AuthSrvTest, DISABLED_builtInQueryViaDNSServer) {
 #else
 TEST_F(AuthSrvTest, builtInQueryViaDNSServer) {
 #endif
-    updateBuiltin(&server);
+    updateBuiltin(server);
     UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                        default_qid, Name("VERSION.BIND."),
                                        RRClass::CH(), RRType::TXT());
@@ -846,7 +858,7 @@ TEST_F(AuthSrvTest, DISABLED_builtInQuery) {
 #else
 TEST_F(AuthSrvTest, builtInQuery) {
 #endif
-    updateBuiltin(&server);
+    updateBuiltin(server);
     UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                        default_qid, Name("VERSION.BIND."),
                                        RRClass::CH(), RRType::TXT());
@@ -867,7 +879,7 @@ TEST_F(AuthSrvTest, DISABLED_iqueryViaDNSServer) { // Needs builtin
 #else
 TEST_F(AuthSrvTest, iqueryViaDNSServer) { // Needs builtin
 #endif
-    updateBuiltin(&server);
+    updateBuiltin(server);
     createDataFromFile("iquery_fromWire.wire");
     (*server.getDNSLookupProvider())(*io_message, parse_message,
                                      response_message,
@@ -889,7 +901,7 @@ TEST_F(AuthSrvTest, DISABLED_updateConfig) {
 #else
 TEST_F(AuthSrvTest, updateConfig) {
 #endif
-    updateDatabase(&server, CONFIG_TESTDB);
+    updateDatabase(server, CONFIG_TESTDB);
 
     // query for existent data in the installed data source.  The resulting
     // response should have the AA flag on, and have an RR in each answer
@@ -907,7 +919,7 @@ TEST_F(AuthSrvTest, DISABLED_datasourceFail) {
 #else
 TEST_F(AuthSrvTest, datasourceFail) {
 #endif
-    updateDatabase(&server, CONFIG_TESTDB);
+    updateDatabase(server, CONFIG_TESTDB);
 
     // This query will hit a corrupted entry of the data source (the zoneload
     // tool and the data source itself naively accept it).  This will result
@@ -927,10 +939,10 @@ TEST_F(AuthSrvTest, DISABLED_updateConfigFail) {
 TEST_F(AuthSrvTest, updateConfigFail) {
 #endif
     // First, load a valid data source.
-    updateDatabase(&server, CONFIG_TESTDB);
+    updateDatabase(server, CONFIG_TESTDB);
 
     // Next, try to update it with a non-existent one.  This should fail.
-    EXPECT_THROW(updateDatabase(&server, BADCONFIG_TESTDB),
+    EXPECT_THROW(updateDatabase(server, BADCONFIG_TESTDB),
                  isc::datasrc::DataSourceError);
 
     // The original data source should still exist.
@@ -953,7 +965,7 @@ TEST_F(AuthSrvTest, updateWithInMemoryClient) {
         "   \"params\": {},"
         "   \"cache-enable\": true"
         "}]}"));
-    DataSourceConfigurator::testReconfigure(&server, config);
+    installDataSrcClientLists(server, configureDataSource(config));
     // after successful configuration, we should have one (with empty zoneset).
 
     // The memory data source is empty, should return REFUSED rcode.
@@ -974,7 +986,7 @@ TEST_F(AuthSrvTest, queryWithInMemoryClientNoDNSSEC) {
     // query handler class, and confirm it returns no error and a non empty
     // answer section.  Detailed examination on the response content
     // for various types of queries are tested in the query tests.
-    updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
+    updateInMemory(server, "example.", CONFIG_INMEMORY_EXAMPLE);
 
     createDataFromFile("nsec3query_nodnssec_fromWire.wire");
     server.processMessage(*io_message, *parse_message, *response_obuffer,
@@ -993,7 +1005,7 @@ TEST_F(AuthSrvTest, queryWithInMemoryClientDNSSEC) {
     // Similar to the previous test, but the query has the DO bit on.
     // The response should contain RRSIGs, and should have more RRs than
     // the previous case.
-    updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
+    updateInMemory(server, "example.", CONFIG_INMEMORY_EXAMPLE);
 
     createDataFromFile("nsec3query_fromWire.wire");
     server.processMessage(*io_message, *parse_message, *response_obuffer,
@@ -1013,7 +1025,7 @@ TEST_F(AuthSrvTest,
     )
 {
     // Set up the in-memory
-    updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
+    updateInMemory(server, "example.", CONFIG_INMEMORY_EXAMPLE);
 
     // This shouldn't affect the result of class CH query
     UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
@@ -1287,7 +1299,7 @@ public:
         if (fake_rrset_ && fake_rrset_->getName() == name &&
             fake_rrset_->getType() == type)
         {
-            return (ZoneFinderContextPtr(new ZoneFinder::Context(
+            return (ZoneFinderContextPtr(new ZoneFinder::GenericContext(
                                              *this, options,
                                              ResultContext(SUCCESS,
                                                            fake_rrset_))));
@@ -1425,13 +1437,16 @@ TEST_F(AuthSrvTest,
     )
 {
     // Set real inmem client to proxy
-    updateInMemory(&server, "example.", CONFIG_INMEMORY_EXAMPLE);
+    updateInMemory(server, "example.", CONFIG_INMEMORY_EXAMPLE);
     {
-        isc::util::thread::Mutex::Locker locker(server.getClientListMutex());
+        isc::util::thread::Mutex::Locker locker(
+            server.getDataSrcClientListMutex());
         boost::shared_ptr<isc::datasrc::ConfigurableClientList>
-            list(new FakeList(server.getClientList(RRClass::IN()), THROW_NEVER,
-                              false));
-        server.setClientList(RRClass::IN(), list);
+            list(new FakeList(server.getDataSrcClientList(RRClass::IN()),
+                              THROW_NEVER, false));
+        AuthSrv::DataSrcClientListsPtr lists(new std::map<RRClass, ListPtr>);
+        lists->insert(pair<RRClass, ListPtr>(RRClass::IN(), list));
+        server.swapDataSrcClientLists(lists);
     }
 
     createDataFromFile("nsec3query_nodnssec_fromWire.wire");
@@ -1450,16 +1465,19 @@ TEST_F(AuthSrvTest,
 // If non null rrset is given, it will be passed to the proxy so it can
 // return some faked response.
 void
-setupThrow(AuthSrv* server, ThrowWhen throw_when, bool isc_exception,
+setupThrow(AuthSrv& server, ThrowWhen throw_when, bool isc_exception,
            ConstRRsetPtr rrset = ConstRRsetPtr())
 {
     updateInMemory(server, "example.", CONFIG_INMEMORY_EXAMPLE);
 
-    isc::util::thread::Mutex::Locker locker(server->getClientListMutex());
+    isc::util::thread::Mutex::Locker locker(
+        server.getDataSrcClientListMutex());
     boost::shared_ptr<isc::datasrc::ConfigurableClientList>
-        list(new FakeList(server->getClientList(RRClass::IN()), throw_when,
-                          isc_exception, rrset));
-    server->setClientList(RRClass::IN(), list);
+        list(new FakeList(server.getDataSrcClientList(RRClass::IN()),
+                          throw_when, isc_exception, rrset));
+    AuthSrv::DataSrcClientListsPtr lists(new std::map<RRClass, ListPtr>);
+    lists->insert(pair<RRClass, ListPtr>(RRClass::IN(), list));
+    server.swapDataSrcClientLists(lists);
 }
 
 TEST_F(AuthSrvTest,
@@ -1482,11 +1500,11 @@ TEST_F(AuthSrvTest,
                                              RRClass::IN(), RRType::TXT());
     for (ThrowWhen* when(throws); *when != THROW_NEVER; ++when) {
         createRequestPacket(request_message, IPPROTO_UDP);
-        setupThrow(&server, *when, true);
+        setupThrow(server, *when, true);
         processAndCheckSERVFAIL();
         // To be sure, check same for non-isc-exceptions
         createRequestPacket(request_message, IPPROTO_UDP);
-        setupThrow(&server, *when, false);
+        setupThrow(server, *when, false);
         processAndCheckSERVFAIL();
     }
 }
@@ -1502,7 +1520,7 @@ TEST_F(AuthSrvTest,
     )
 {
     createDataFromFile("nsec3query_nodnssec_fromWire.wire");
-    setupThrow(&server, THROW_AT_GET_CLASS, true);
+    setupThrow(server, THROW_AT_GET_CLASS, true);
 
     // getClass is not called so it should just answer
     server.processMessage(*io_message, *parse_message, *response_obuffer,
@@ -1526,7 +1544,7 @@ TEST_F(AuthSrvTest,
     ConstRRsetPtr empty_rrset(new RRset(Name("foo.example"),
                                         RRClass::IN(), RRType::TXT(),
                                         RRTTL(0)));
-    setupThrow(&server, THROW_NEVER, true, empty_rrset);
+    setupThrow(server, THROW_NEVER, true, empty_rrset);
 
     // Repeat the query processing two times.  Due to the faked RRset,
     // toWire() should throw, and it should result in SERVFAIL.
@@ -1771,46 +1789,51 @@ TEST_F(AuthSrvTest, clientList) {
     // We need to lock the mutex to make the (get|set)ClientList happy.
     // There's a debug-build only check in them to make sure everything
     // locks them and we call them directly here.
-    isc::util::thread::Mutex::Locker locker(server.getClientListMutex());
+    isc::util::thread::Mutex::Locker locker(
+        server.getDataSrcClientListMutex());
+
+    AuthSrv::DataSrcClientListsPtr lists; // initially empty
+
     // The lists don't exist. Therefore, the list of RRClasses is empty.
-    // We also have no IN list.
-    EXPECT_TRUE(server.getClientListClasses().empty());
-    EXPECT_EQ(boost::shared_ptr<const isc::datasrc::ClientList>(),
-              server.getClientList(RRClass::IN()));
+    EXPECT_TRUE(server.swapDataSrcClientLists(lists)->empty());
+
     // Put something in.
-    const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
-        list(new isc::datasrc::ConfigurableClientList(RRClass::IN()));
-    const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
-        list2(new isc::datasrc::ConfigurableClientList(RRClass::CH()));
-    server.setClientList(RRClass::IN(), list);
-    server.setClientList(RRClass::CH(), list2);
-    // There are two things in the list and they are IN and CH
-    vector<RRClass> classes(server.getClientListClasses());
-    ASSERT_EQ(2, classes.size());
-    EXPECT_EQ(RRClass::IN(), classes[0]);
-    EXPECT_EQ(RRClass::CH(), classes[1]);
+    const ListPtr list(new ConfigurableClientList(RRClass::IN()));
+    const ListPtr list2(new ConfigurableClientList(RRClass::CH()));
+
+    lists.reset(new std::map<RRClass, ListPtr>);
+    lists->insert(pair<RRClass, ListPtr>(RRClass::IN(), list));
+    lists->insert(pair<RRClass, ListPtr>(RRClass::CH(), list2));
+    server.swapDataSrcClientLists(lists);
+
     // And the lists can be retrieved.
-    EXPECT_EQ(list, server.getClientList(RRClass::IN()));
-    EXPECT_EQ(list2, server.getClientList(RRClass::CH()));
-    // Remove one of them
-    server.setClientList(RRClass::CH(),
-        boost::shared_ptr<isc::datasrc::ConfigurableClientList>());
-    // This really got deleted, including the class.
-    classes = server.getClientListClasses();
-    ASSERT_EQ(1, classes.size());
-    EXPECT_EQ(RRClass::IN(), classes[0]);
-    EXPECT_EQ(list, server.getClientList(RRClass::IN()));
+    EXPECT_EQ(list, server.getDataSrcClientList(RRClass::IN()));
+    EXPECT_EQ(list2, server.getDataSrcClientList(RRClass::CH()));
+
+    // Replace the lists with new lists containing only one list.
+    lists.reset(new std::map<RRClass, ListPtr>);
+    lists->insert(pair<RRClass, ListPtr>(RRClass::IN(), list));
+    lists = server.swapDataSrcClientLists(lists);
+
+    // Old one had two lists.  That confirms our swap for IN and CH classes
+    // (i.e., no other entries were there).
+    EXPECT_EQ(2, lists->size());
+
+    // The CH list really got deleted.
+    EXPECT_EQ(list, server.getDataSrcClientList(RRClass::IN()));
+    EXPECT_FALSE(server.getDataSrcClientList(RRClass::CH()));
 }
 
 // We just test the mutex can be locked (exactly once).
 TEST_F(AuthSrvTest, mutex) {
-    isc::util::thread::Mutex::Locker l1(server.getClientListMutex());
+    isc::util::thread::Mutex::Locker l1(server.getDataSrcClientListMutex());
     // TODO: Once we have non-debug build, this one will not work, since
     // we currently use the fact that we can't lock twice from the same
     // thread. In the non-debug mode, this would deadlock.
     // Skip then.
     EXPECT_THROW({
-        isc::util::thread::Mutex::Locker l2(server.getClientListMutex());
+        isc::util::thread::Mutex::Locker l2(
+            server.getDataSrcClientListMutex());
     }, isc::InvalidOperation);
 }
 
diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc
index e57de93..8aa2322 100644
--- a/src/bin/auth/tests/command_unittest.cc
+++ b/src/bin/auth/tests/command_unittest.cc
@@ -16,10 +16,12 @@
 
 #include "datasrc_util.h"
 
+#include <util/threads/lock.h>
+
 #include <auth/auth_srv.h>
 #include <auth/auth_config.h>
 #include <auth/command.h>
-#include <auth/datasrc_configurator.h>
+#include <auth/datasrc_config.h>
 
 #include <dns/name.h>
 #include <dns/rrclass.h>
@@ -174,22 +176,32 @@ TEST_F(AuthCommandTest, shutdownIncorrectPID) {
 // zones, and checks the zones are correctly loaded.
 void
 zoneChecks(AuthSrv& server) {
-    isc::util::thread::Mutex::Locker locker(server.getClientListMutex());
-    EXPECT_EQ(ZoneFinder::SUCCESS, server.getClientList(RRClass::IN())->
+    isc::util::thread::Mutex::Locker locker(
+        server.getDataSrcClientListMutex());
+    EXPECT_EQ(ZoneFinder::SUCCESS, server.getDataSrcClientList(RRClass::IN())->
               find(Name("ns.test1.example")).finder_->
               find(Name("ns.test1.example"), RRType::A())->code);
-    EXPECT_EQ(ZoneFinder::NXRRSET, server.getClientList(RRClass::IN())->
+    EXPECT_EQ(ZoneFinder::NXRRSET, server.getDataSrcClientList(RRClass::IN())->
               find(Name("ns.test1.example")).finder_->
               find(Name("ns.test1.example"), RRType::AAAA())->code);
-    EXPECT_EQ(ZoneFinder::SUCCESS, server.getClientList(RRClass::IN())->
+    EXPECT_EQ(ZoneFinder::SUCCESS, server.getDataSrcClientList(RRClass::IN())->
               find(Name("ns.test2.example")).finder_->
               find(Name("ns.test2.example"), RRType::A())->code);
-    EXPECT_EQ(ZoneFinder::NXRRSET, server.getClientList(RRClass::IN())->
+    EXPECT_EQ(ZoneFinder::NXRRSET, server.getDataSrcClientList(RRClass::IN())->
               find(Name("ns.test2.example")).finder_->
               find(Name("ns.test2.example"), RRType::AAAA())->code);
 }
 
 void
+installDataSrcClientLists(AuthSrv& server,
+                          AuthSrv::DataSrcClientListsPtr lists)
+{
+    isc::util::thread::Mutex::Locker locker(
+        server.getDataSrcClientListMutex());
+    server.swapDataSrcClientLists(lists);
+}
+
+void
 configureZones(AuthSrv& server) {
     ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR "/test1.zone.in "
                         TEST_DATA_BUILDDIR "/test1.zone.copied"));
@@ -208,27 +220,29 @@ configureZones(AuthSrv& server) {
         "   \"cache-enable\": true"
         "}]}"));
 
-    DataSourceConfigurator::testReconfigure(&server, config);
+    installDataSrcClientLists(server, configureDataSource(config));
 
     zoneChecks(server);
 }
 
 void
 newZoneChecks(AuthSrv& server) {
-    isc::util::thread::Mutex::Locker locker(server.getClientListMutex());
-    EXPECT_EQ(ZoneFinder::SUCCESS, server.getClientList(RRClass::IN())->
+    isc::util::thread::Mutex::Locker locker(
+        server.getDataSrcClientListMutex());
+    EXPECT_EQ(ZoneFinder::SUCCESS, server.getDataSrcClientList(RRClass::IN())->
               find(Name("ns.test1.example")).finder_->
               find(Name("ns.test1.example"), RRType::A())->code);
     // now test1.example should have ns/AAAA
-    EXPECT_EQ(ZoneFinder::SUCCESS, server.getClientList(RRClass::IN())->
+    EXPECT_EQ(ZoneFinder::SUCCESS, server.getDataSrcClientList(RRClass::IN())->
               find(Name("ns.test1.example")).finder_->
               find(Name("ns.test1.example"), RRType::AAAA())->code);
 
     // test2.example shouldn't change
-    EXPECT_EQ(ZoneFinder::SUCCESS, server.getClientList(RRClass::IN())->
+    EXPECT_EQ(ZoneFinder::SUCCESS, server.getDataSrcClientList(RRClass::IN())->
               find(Name("ns.test2.example")).finder_->
               find(Name("ns.test2.example"), RRType::A())->code);
-    EXPECT_EQ(ZoneFinder::NXRRSET, server.getClientList(RRClass::IN())->
+    EXPECT_EQ(ZoneFinder::NXRRSET,
+              server.getDataSrcClientList(RRClass::IN())->
               find(Name("ns.test2.example")).finder_->
               find(Name("ns.test2.example"), RRType::AAAA())->code);
 }
@@ -271,12 +285,14 @@ TEST_F(AuthCommandTest,
         "    \"cache-enable\": true,"
         "    \"cache-zones\": [\"example.org\"]"
         "}]}"));
-    DataSourceConfigurator::testReconfigure(&server_, config);
+    installDataSrcClientLists(server_, configureDataSource(config));
 
     {
-        isc::util::thread::Mutex::Locker locker(server_.getClientListMutex());
+        isc::util::thread::Mutex::Locker locker(
+            server_.getDataSrcClientListMutex());
         // Check that the A record at www.example.org does not exist
-        EXPECT_EQ(ZoneFinder::NXDOMAIN, server_.getClientList(RRClass::IN())->
+        EXPECT_EQ(ZoneFinder::NXDOMAIN,
+                  server_.getDataSrcClientList(RRClass::IN())->
                   find(Name("example.org")).finder_->
                   find(Name("www.example.org"), RRType::A())->code);
 
@@ -296,7 +312,8 @@ TEST_F(AuthCommandTest,
         sql_updater->addRRset(*rrset);
         sql_updater->commit();
 
-        EXPECT_EQ(ZoneFinder::NXDOMAIN, server_.getClientList(RRClass::IN())->
+        EXPECT_EQ(ZoneFinder::NXDOMAIN,
+                  server_.getDataSrcClientList(RRClass::IN())->
                   find(Name("example.org")).finder_->
                   find(Name("www.example.org"), RRType::A())->code);
     }
@@ -308,9 +325,11 @@ TEST_F(AuthCommandTest,
     checkAnswer(0, "Successful load");
 
     {
-        isc::util::thread::Mutex::Locker locker(server_.getClientListMutex());
+        isc::util::thread::Mutex::Locker locker(
+            server_.getDataSrcClientListMutex());
         // And now it should be present too.
-        EXPECT_EQ(ZoneFinder::SUCCESS, server_.getClientList(RRClass::IN())->
+        EXPECT_EQ(ZoneFinder::SUCCESS,
+                  server_.getDataSrcClientList(RRClass::IN())->
                   find(Name("example.org")).finder_->
                   find(Name("www.example.org"), RRType::A())->code);
     }
@@ -321,9 +340,11 @@ TEST_F(AuthCommandTest,
     checkAnswer(1, "example.com");
 
     {
-        isc::util::thread::Mutex::Locker locker(server_.getClientListMutex());
+        isc::util::thread::Mutex::Locker locker(
+            server_.getDataSrcClientListMutex());
         // The previous zone is not hurt in any way
-        EXPECT_EQ(ZoneFinder::SUCCESS, server_.getClientList(RRClass::IN())->
+        EXPECT_EQ(ZoneFinder::SUCCESS,
+                  server_.getDataSrcClientList(RRClass::IN())->
                   find(Name("example.org")).finder_->
                   find(Name("example.org"), RRType::SOA())->code);
     }
@@ -335,16 +356,18 @@ TEST_F(AuthCommandTest,
         "    \"cache-enable\": true,"
         "    \"cache-zones\": [\"example.com\"]"
         "}]}"));
-    EXPECT_THROW(DataSourceConfigurator::testReconfigure(&server_, config2),
+    EXPECT_THROW(configureDataSource(config2),
                  ConfigurableClientList::ConfigurationError);
 
     result_ = execAuthServerCommand(server_, "loadzone",
         Element::fromJSON("{\"origin\": \"example.com\"}"));
     checkAnswer(1, "Unreadable");
 
-    isc::util::thread::Mutex::Locker locker(server_.getClientListMutex());
+    isc::util::thread::Mutex::Locker locker(
+        server_.getDataSrcClientListMutex());
     // The previous zone is not hurt in any way
-    EXPECT_EQ(ZoneFinder::SUCCESS, server_.getClientList(RRClass::IN())->
+    EXPECT_EQ(ZoneFinder::SUCCESS,
+              server_.getDataSrcClientList(RRClass::IN())->
               find(Name("example.org")).finder_->
               find(Name("example.org"), RRType::SOA())->code);
 }
diff --git a/src/bin/auth/tests/datasrc_config_unittest.cc b/src/bin/auth/tests/datasrc_config_unittest.cc
new file mode 100644
index 0000000..877f921
--- /dev/null
+++ b/src/bin/auth/tests/datasrc_config_unittest.cc
@@ -0,0 +1,305 @@
+// Copyright (C) 2012  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 <auth/datasrc_config.h>
+
+#include <config/tests/fake_session.h>
+#include <config/ccsession.h>
+#include <util/threads/lock.h>
+
+#include <gtest/gtest.h>
+
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <memory>
+
+using namespace isc;
+using namespace isc::cc;
+using namespace isc::config;
+using namespace isc::data;
+using namespace isc::dns;
+using namespace std;
+using namespace boost;
+
+namespace {
+
+class DatasrcConfigTest;
+
+class FakeList {
+public:
+    FakeList(const RRClass&) :
+        configuration_(new ListElement)
+    {}
+    void configure(const ConstElementPtr& configuration, bool allow_cache) {
+        EXPECT_TRUE(allow_cache);
+        conf_ = configuration->get(0)->get("type")->stringValue();
+        configuration_ = configuration;
+    }
+    const string& getConf() const {
+        return (conf_);
+    }
+    ConstElementPtr getConfiguration() const {
+        return (configuration_);
+    }
+private:
+    string conf_;
+    ConstElementPtr configuration_;
+};
+
+typedef shared_ptr<FakeList> ListPtr;
+
+// Forward declaration.  We need precise definition of DatasrcConfigTest
+// to complete this function.
+void
+testConfigureDataSource(DatasrcConfigTest& test,
+                        const isc::data::ConstElementPtr& config);
+
+void
+datasrcConfigHandler(DatasrcConfigTest* fake_server, const std::string&,
+                     isc::data::ConstElementPtr config,
+                     const isc::config::ConfigData&)
+{
+    if (config->contains("classes")) {
+        testConfigureDataSource(*fake_server, config->get("classes"));
+    }
+}
+
+class DatasrcConfigTest : public ::testing::Test {
+public:
+    // These pretend to be the server
+    isc::util::thread::Mutex& getDataSrcClientListMutex() const {
+        return (mutex_);
+    }
+    void swapDataSrcClientLists(shared_ptr<std::map<dns::RRClass, ListPtr> >
+                                new_lists)
+    {
+        lists_.clear();         // first empty it
+
+        // Record the operation and results.  Note that map elements are
+        // sorted by RRClass, so the ordering should be predictable.
+        for (std::map<dns::RRClass, ListPtr>::const_iterator it =
+                 new_lists->begin();
+             it != new_lists->end();
+             ++it)
+        {
+            const RRClass rrclass = it->first;
+            ListPtr list = it->second;
+            log_ += "set " + rrclass.toText() + " " +
+                (list ? list->getConf() : "") + "\n";
+            lists_[rrclass] = list;
+        }
+    }
+
+protected:
+    DatasrcConfigTest() :
+        session(ElementPtr(new ListElement), ElementPtr(new ListElement),
+                ElementPtr(new ListElement)),
+        specfile(string(TEST_OWN_DATA_DIR) + "/spec.spec")
+    {
+        initSession();
+    }
+    void initSession() {
+        session.getMessages()->add(createAnswer());
+        mccs.reset(new ModuleCCSession(specfile, session, NULL, NULL, false,
+                                       false));
+    }
+    void TearDown() {
+        // Make sure no matter what we did, it is cleaned up.  Also check
+        // we really have subscribed to the configuration, and after removing
+        // it we actually cancel it.
+        EXPECT_TRUE(session.haveSubscription("data_sources", "*"));
+        mccs->removeRemoteConfig("data_sources");
+        EXPECT_FALSE(session.haveSubscription("data_sources", "*"));
+    }
+    void SetUp() {
+        session.getMessages()->
+            add(createAnswer(0,
+                             moduleSpecFromFile(string(PLUGIN_DATA_PATH) +
+                                                "/datasrc.spec").
+                             getFullSpec()));
+        session.getMessages()->add(createAnswer(0,
+                                                ElementPtr(new MapElement)));
+        mccs->addRemoteConfig("data_sources",
+                              boost::bind(datasrcConfigHandler,
+                                          this, _1, _2, _3), false);
+    }
+    ElementPtr buildConfig(const string& config) const {
+        const ElementPtr internal(Element::fromJSON(config));
+        const ElementPtr external(Element::fromJSON("{\"version\": 1}"));
+        external->set("classes", internal);
+        return (external);
+    }
+    void initializeINList() {
+        const ConstElementPtr
+            config(buildConfig("{\"IN\": [{\"type\": \"xxx\"}]}"));
+        session.addMessage(createCommand("config_update", config),
+                           "data_sources", "*");
+        mccs->checkCommand();
+        // Check that the passed config is stored.
+        EXPECT_EQ("set IN xxx\n", log_);
+        EXPECT_EQ(1, lists_.size());
+    }
+    FakeSession session;
+    auto_ptr<ModuleCCSession> mccs;
+    const string specfile;
+    std::map<RRClass, ListPtr> lists_;
+    string log_;
+    mutable isc::util::thread::Mutex mutex_;
+};
+
+void
+testConfigureDataSource(DatasrcConfigTest& test,
+                        const isc::data::ConstElementPtr& config)
+{
+    // We use customized (faked lists) for the List type.  This makes it
+    // possible to easily look that they were called.
+    shared_ptr<std::map<dns::RRClass, ListPtr> > lists =
+        configureDataSourceGeneric<FakeList>(config);
+    test.swapDataSrcClientLists(lists);
+}
+
+// Push there a configuration with a single list.
+TEST_F(DatasrcConfigTest, createList) {
+    initializeINList();
+}
+
+TEST_F(DatasrcConfigTest, modifyList) {
+    // First, initialize the list, and confirm the current config
+    initializeINList();
+    EXPECT_EQ("xxx", lists_[RRClass::IN()]->getConf());
+
+    // And now change the configuration of the list
+    const ElementPtr
+        config(buildConfig("{\"IN\": [{\"type\": \"yyy\"}]}"));
+    session.addMessage(createCommand("config_update", config), "data_sources",
+                       "*");
+    log_ = "";
+    mccs->checkCommand();
+    // Now the new one should be installed.
+    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
+    EXPECT_EQ(1, lists_.size());
+}
+
+// Check we can have multiple lists at once
+TEST_F(DatasrcConfigTest, multiple) {
+    const ElementPtr
+        config(buildConfig("{\"IN\": [{\"type\": \"yyy\"}], "
+                                 "\"CH\": [{\"type\": \"xxx\"}]}"));
+    session.addMessage(createCommand("config_update", config), "data_sources",
+                       "*");
+    mccs->checkCommand();
+    // We have set commands for both classes.
+    EXPECT_EQ("set IN yyy\nset CH xxx\n", log_);
+    // We should have both there
+    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
+    EXPECT_EQ("xxx", lists_[RRClass::CH()]->getConf());
+    EXPECT_EQ(2, lists_.size());
+}
+
+// Check we can add another one later and the old one does not get
+// overwritten.
+//
+// It's almost like above, but we initialize first with single-list
+// config.
+TEST_F(DatasrcConfigTest, updateAdd) {
+    initializeINList();
+    const ElementPtr
+        config(buildConfig("{\"IN\": [{\"type\": \"yyy\"}], "
+                           "\"CH\": [{\"type\": \"xxx\"}]}"));
+    session.addMessage(createCommand("config_update", config), "data_sources",
+                       "*");
+    log_ = "";
+    mccs->checkCommand();
+    EXPECT_EQ("set IN yyy\nset CH xxx\n", log_);
+    EXPECT_EQ("xxx", lists_[RRClass::CH()]->getConf());
+    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
+    EXPECT_EQ(2, lists_.size());
+}
+
+// We delete a class list in this test.
+TEST_F(DatasrcConfigTest, updateDelete) {
+    initializeINList();
+    const ElementPtr
+        config(buildConfig("{}"));
+    session.addMessage(createCommand("config_update", config), "data_sources",
+                       "*");
+    log_ = "";
+    mccs->checkCommand();
+
+    // No operation takes place in the configuration, and the old one is
+    // just dropped
+    EXPECT_EQ("", log_);
+    EXPECT_TRUE(lists_.empty());
+}
+
+// Check that broken new configuration doesn't break the running configuration.
+TEST_F(DatasrcConfigTest, brokenConfigForAdd) {
+    initializeINList();
+    // The configuration is wrong. However, the CH one will be handled
+    // without an error first.
+    const ElementPtr
+        config(buildConfig("{\"IN\": [{\"type\": 13}], "
+                           "\"CH\": [{\"type\": \"xxx\"}]}"));
+    session.addMessage(createCommand("config_update", config), "data_sources",
+                       "*");
+    log_ = "";
+    // It does not throw, as it is handled in the ModuleCCSession.
+    // Throwing from the reconfigure is checked in other tests.
+    EXPECT_NO_THROW(mccs->checkCommand());
+    // Anyway, the result should not contain CH now and the original IN should
+    // be there.
+    EXPECT_EQ("xxx", lists_[RRClass::IN()]->getConf());
+    EXPECT_FALSE(lists_[RRClass::CH()]);
+}
+
+// Similar to the previous one, but the broken config would delete part of
+// the running config.
+TEST_F(DatasrcConfigTest, brokenConfigForDelete) {
+    initializeINList();
+    // Put the CH there
+    const ElementPtr
+        config1(Element::fromJSON("{\"IN\": [{\"type\": \"yyy\"}], "
+                                  "\"CH\": [{\"type\": \"xxx\"}]}"));
+    testConfigureDataSource(*this, config1);
+    const ElementPtr
+        config2(Element::fromJSON("{\"IN\": [{\"type\": 13}]}"));
+    // This would delete CH. However, the new config is broken, so it won't
+    // actually apply.
+    EXPECT_THROW(testConfigureDataSource(*this, config2), TypeError);
+    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
+    EXPECT_EQ("xxx", lists_[RRClass::CH()]->getConf());
+}
+
+// Similar to the previous cases, but the broken config would modify the
+// running config of one of the classes.
+TEST_F(DatasrcConfigTest, brokenConfigForModify) {
+    initializeINList();
+    // Put the CH there
+    const ElementPtr
+        config1(Element::fromJSON("{\"IN\": [{\"type\": \"yyy\"}], "
+                                  "\"CH\": [{\"type\": \"xxx\"}]}"));
+    testConfigureDataSource(*this, config1);
+    // Now, the CH change will be handled first without an error, then
+    // the change to the IN class will fail, and the none of the changes
+    // will apply.
+    const ElementPtr
+        config2(Element::fromJSON("{\"IN\": [{\"type\": 13}], "
+                                  "\"CH\": [{\"type\": \"yyy\"}]}"));
+    EXPECT_THROW(testConfigureDataSource(*this, config2), TypeError);
+    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
+    EXPECT_EQ("xxx", lists_[RRClass::CH()]->getConf());
+}
+
+}
diff --git a/src/bin/auth/tests/datasrc_configurator_unittest.cc b/src/bin/auth/tests/datasrc_configurator_unittest.cc
deleted file mode 100644
index 254b238..0000000
--- a/src/bin/auth/tests/datasrc_configurator_unittest.cc
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (C) 2012  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 <auth/datasrc_configurator.h>
-
-#include <config/tests/fake_session.h>
-#include <config/ccsession.h>
-#include <util/threads/lock.h>
-
-#include <gtest/gtest.h>
-#include <memory>
-#include <boost/shared_ptr.hpp>
-
-using namespace isc;
-using namespace isc::cc;
-using namespace isc::config;
-using namespace isc::data;
-using namespace isc::dns;
-using namespace std;
-using namespace boost;
-
-namespace {
-
-class DatasrcConfiguratorTest;
-
-class FakeList {
-public:
-    FakeList(const RRClass&) :
-        configuration_(new ListElement)
-    {}
-    void configure(const ConstElementPtr& configuration, bool allow_cache) {
-        EXPECT_TRUE(allow_cache);
-        conf_ = configuration->get(0)->get("type")->stringValue();
-        configuration_ = configuration;
-    }
-    const string& getConf() const {
-        return (conf_);
-    }
-    ConstElementPtr getConfiguration() const {
-        return (configuration_);
-    }
-private:
-    string conf_;
-    ConstElementPtr configuration_;
-};
-
-typedef shared_ptr<FakeList> ListPtr;
-
-// We use the test fixture as both parameters, this makes it possible
-// to easily fake all needed methods and look that they were called.
-typedef DataSourceConfiguratorGeneric<DatasrcConfiguratorTest,
-        FakeList> Configurator;
-
-class DatasrcConfiguratorTest : public ::testing::Test {
-public:
-    // These pretend to be the server
-    ListPtr getClientList(const RRClass& rrclass) {
-        log_ += "get " + rrclass.toText() + "\n";
-        return (lists_[rrclass]);
-    }
-    void setClientList(const RRClass& rrclass, const ListPtr& list) {
-        log_ += "set " + rrclass.toText() + " " +
-            (list ? list->getConf() : "") + "\n";
-        lists_[rrclass] = list;
-    }
-    vector<RRClass> getClientListClasses() const {
-        vector<RRClass> result;
-        for (std::map<RRClass, ListPtr>::const_iterator it(lists_.begin());
-             it != lists_.end(); ++it) {
-            result.push_back(it->first);
-        }
-        return (result);
-    }
-    isc::util::thread::Mutex& getClientListMutex() const {
-        return (mutex_);
-    }
-protected:
-    DatasrcConfiguratorTest() :
-        session(ElementPtr(new ListElement), ElementPtr(new ListElement),
-                ElementPtr(new ListElement)),
-        specfile(string(TEST_OWN_DATA_DIR) + "/spec.spec")
-    {
-        initSession();
-    }
-    void initSession() {
-        session.getMessages()->add(createAnswer());
-        mccs.reset(new ModuleCCSession(specfile, session, NULL, NULL, false,
-                                       false));
-    }
-    void TearDown() {
-        // Make sure no matter what we did, it is cleaned up.
-        Configurator::cleanup();
-    }
-    void init(const ElementPtr& config = ElementPtr()) {
-        session.getMessages()->
-            add(createAnswer(0,
-                             moduleSpecFromFile(string(PLUGIN_DATA_PATH) +
-                                                "/datasrc.spec").
-                             getFullSpec()));
-        if (config) {
-            session.getMessages()->add(createAnswer(0, config));
-        } else {
-            session.getMessages()->
-                add(createAnswer(0, ElementPtr(new MapElement)));
-        }
-        Configurator::init(mccs.get(), this);
-    }
-    void SetUp() {
-        init();
-    }
-    ElementPtr buildConfig(const string& config) const {
-        const ElementPtr internal(Element::fromJSON(config));
-        const ElementPtr external(Element::fromJSON("{\"version\": 1}"));
-        external->set("classes", internal);
-        return (external);
-    }
-    void initializeINList() {
-        const ElementPtr
-            config(buildConfig("{\"IN\": [{\"type\": \"xxx\"}]}"));
-        session.addMessage(createCommand("config_update", config), "data_sources",
-                           "*");
-        mccs->checkCommand();
-        // Check it called the correct things (check that there's no IN yet and
-        // set a new one.
-        EXPECT_EQ("get IN\nset IN xxx\n", log_);
-        EXPECT_EQ(1, lists_.size());
-    }
-    FakeSession session;
-    auto_ptr<ModuleCCSession> mccs;
-    const string specfile;
-    std::map<RRClass, ListPtr> lists_;
-    string log_;
-    mutable isc::util::thread::Mutex mutex_;
-};
-
-// Check the initialization (and cleanup)
-TEST_F(DatasrcConfiguratorTest, initialization) {
-    // It can't be initialized again
-    EXPECT_THROW(init(), InvalidOperation);
-    EXPECT_TRUE(session.haveSubscription("data_sources", "*"));
-    // Deinitialize to make the tests reasonable
-    Configurator::cleanup();
-    EXPECT_FALSE(session.haveSubscription("data_sources", "*"));
-    // We can't reconfigure now (not even manually)
-    EXPECT_THROW(Configurator::reconfigure(ElementPtr(new MapElement())),
-                 InvalidOperation);
-    // If one of them is NULL, it does not work
-    EXPECT_THROW(Configurator::init(NULL, this), InvalidParameter);
-    EXPECT_FALSE(session.haveSubscription("data_sources", "*"));
-    EXPECT_THROW(Configurator::init(mccs.get(), NULL), InvalidParameter);
-    EXPECT_FALSE(session.haveSubscription("data_sources", "*"));
-    // But we can initialize it again now
-    EXPECT_NO_THROW(init());
-    EXPECT_TRUE(session.haveSubscription("data_sources", "*"));
-}
-
-// Push there a configuration with a single list.
-TEST_F(DatasrcConfiguratorTest, createList) {
-    initializeINList();
-}
-
-TEST_F(DatasrcConfiguratorTest, modifyList) {
-    // First, initialize the list
-    initializeINList();
-    // And now change the configuration of the list
-    const ElementPtr
-        config(buildConfig("{\"IN\": [{\"type\": \"yyy\"}]}"));
-    session.addMessage(createCommand("config_update", config), "data_sources",
-                       "*");
-    log_ = "";
-    mccs->checkCommand();
-    // This one does not set
-    EXPECT_EQ("get IN\n", log_);
-    // But this should contain the yyy configuration
-    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
-    EXPECT_EQ(1, lists_.size());
-}
-
-// Check we can have multiple lists at once
-TEST_F(DatasrcConfiguratorTest, multiple) {
-    const ElementPtr
-        config(buildConfig("{\"IN\": [{\"type\": \"yyy\"}], "
-                                 "\"CH\": [{\"type\": \"xxx\"}]}"));
-    session.addMessage(createCommand("config_update", config), "data_sources",
-                       "*");
-    mccs->checkCommand();
-    // We have set commands for both classes.
-    EXPECT_EQ("get CH\nset CH xxx\nget IN\nset IN yyy\n", log_);
-    // We should have both there
-    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
-    EXPECT_EQ("xxx", lists_[RRClass::CH()]->getConf());
-    EXPECT_EQ(2, lists_.size());
-}
-
-// Check we can add another one later and the old one does not get
-// overwritten.
-//
-// It's almost like above, but we initialize first with single-list
-// config.
-TEST_F(DatasrcConfiguratorTest, updateAdd) {
-    initializeINList();
-    const ElementPtr
-        config(buildConfig("{\"IN\": [{\"type\": \"yyy\"}], "
-                           "\"CH\": [{\"type\": \"xxx\"}]}"));
-    session.addMessage(createCommand("config_update", config), "data_sources",
-                       "*");
-    log_ = "";
-    mccs->checkCommand();
-    // The CH is set, IN not
-    EXPECT_EQ("get CH\nset CH xxx\nget IN\n", log_);
-    // But this should contain the yyy configuration
-    EXPECT_EQ("xxx", lists_[RRClass::CH()]->getConf());
-    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
-    EXPECT_EQ(2, lists_.size());
-}
-
-// We delete a class list in this test.
-TEST_F(DatasrcConfiguratorTest, updateDelete) {
-    initializeINList();
-    const ElementPtr
-        config(buildConfig("{}"));
-    session.addMessage(createCommand("config_update", config), "data_sources",
-                       "*");
-    log_ = "";
-    mccs->checkCommand();
-    EXPECT_EQ("get IN\nset IN \n", log_);
-    EXPECT_FALSE(lists_[RRClass::IN()]);
-    // In real auth server, the NULL one would be removed. However, we just
-    // store it, so the IN bucket is still in there. This checks there's nothing
-    // else.
-    EXPECT_EQ(1, lists_.size());
-}
-
-// Check that we can rollback an addition if something else fails
-TEST_F(DatasrcConfiguratorTest, rollbackAddition) {
-    initializeINList();
-    // The configuration is wrong. However, the CH one will get done first.
-    const ElementPtr
-        config(buildConfig("{\"IN\": [{\"type\": 13}], "
-                           "\"CH\": [{\"type\": \"xxx\"}]}"));
-    session.addMessage(createCommand("config_update", config), "data_sources",
-                       "*");
-    log_ = "";
-    // It does not throw, as it is handled in the ModuleCCSession.
-    // Throwing from the reconfigure is checked in other tests.
-    EXPECT_NO_THROW(mccs->checkCommand());
-    // Anyway, the result should not contain CH now and the original IN should
-    // be there.
-    EXPECT_EQ("xxx", lists_[RRClass::IN()]->getConf());
-    EXPECT_FALSE(lists_[RRClass::CH()]);
-}
-
-// Check that we can rollback a deletion if something else fails
-TEST_F(DatasrcConfiguratorTest, rollbackDeletion) {
-    initializeINList();
-    // Put the CH there
-    const ElementPtr
-        config1(Element::fromJSON("{\"IN\": [{\"type\": \"yyy\"}], "
-                                  "\"CH\": [{\"type\": \"xxx\"}]}"));
-    Configurator::reconfigure(config1);
-    const ElementPtr
-        config2(Element::fromJSON("{\"IN\": [{\"type\": 13}]}"));
-    // This would delete CH. However, the IN one fails.
-    // As the deletions happen after the additions/settings
-    // and there's no known way to cause an exception during the
-    // deletions, it is not a true rollback, but the result should
-    // be the same.
-    EXPECT_THROW(Configurator::reconfigure(config2), TypeError);
-    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
-    EXPECT_EQ("xxx", lists_[RRClass::CH()]->getConf());
-}
-
-// Check that we can roll back configuration change if something
-// fails later on.
-TEST_F(DatasrcConfiguratorTest, rollbackConfiguration) {
-    initializeINList();
-    // Put the CH there
-    const ElementPtr
-        config1(Element::fromJSON("{\"IN\": [{\"type\": \"yyy\"}], "
-                                  "\"CH\": [{\"type\": \"xxx\"}]}"));
-    Configurator::reconfigure(config1);
-    // Now, the CH happens first. But nevertheless, it should be
-    // restored to the previoeus version.
-    const ElementPtr
-        config2(Element::fromJSON("{\"IN\": [{\"type\": 13}], "
-                                  "\"CH\": [{\"type\": \"yyy\"}]}"));
-    EXPECT_THROW(Configurator::reconfigure(config2), TypeError);
-    EXPECT_EQ("yyy", lists_[RRClass::IN()]->getConf());
-    EXPECT_EQ("xxx", lists_[RRClass::CH()]->getConf());
-}
-
-}
diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc
index 603bf5c..84b7f8a 100644
--- a/src/bin/auth/tests/query_unittest.cc
+++ b/src/bin/auth/tests/query_unittest.cc
@@ -442,10 +442,9 @@ public:
                        ConstRRsetPtr rrset)
     {
         nsec_name_ = nsec_name;
-        nsec_context_.reset(new Context(*this,
-                                        FIND_DEFAULT, // a fake value
-                                        ResultContext(code, rrset,
-                                                      RESULT_NSEC_SIGNED)));
+        nsec_context_.reset(
+            new GenericContext(*this, FIND_DEFAULT, // a fake value
+                               ResultContext(code, rrset, RESULT_NSEC_SIGNED)));
     }
 
     // Once called, the findNSEC3 will return the provided result for the next
@@ -487,8 +486,8 @@ protected:
     {
         ConstRRsetPtr rp = stripRRsigs(rrset, options);
         return (ZoneFinderContextPtr(
-                    new Context(*this, options,
-                                ResultContext(code, rp, flags))));
+                    new GenericContext(*this, options,
+                                       ResultContext(code, rp, flags))));
     }
 
 private:
@@ -604,9 +603,9 @@ MockZoneFinder::findAll(const Name& name, std::vector<ConstRRsetPtr>& target,
                 target.push_back(stripRRsigs(found_rrset->second, options));
             }
             return (ZoneFinderContextPtr(
-                        new Context(*this, options,
-                                    ResultContext(SUCCESS, RRsetPtr()),
-                                    target)));
+                        new GenericContext(*this, options,
+                                           ResultContext(SUCCESS, RRsetPtr()),
+                                           target)));
         }
     }
 
diff --git a/src/bin/bind10/bind10_messages.mes b/src/bin/bind10/bind10_messages.mes
index c751583..2f48325 100644
--- a/src/bin/bind10/bind10_messages.mes
+++ b/src/bin/bind10/bind10_messages.mes
@@ -141,6 +141,16 @@ it now. The new configuration is printed.
 % BIND10_RECEIVED_SIGNAL received signal %1
 The boss module received the given signal.
 
+% BIND10_RESTART_COMPONENT_SKIPPED Skipped restarting a component %1
+The boss module tried to restart a component after it failed (crashed)
+unexpectedly, but the boss then found that the component had been removed
+from its local configuration of components to run.  This is an unusal
+situation but can happen if the administrator removes the component from
+the configuration after the component's crash and before the restart time.
+The boss module simply skipped restarting that module, and the whole system
+went back to the expected state (except that the crash itself is likely
+to be a bug).
+
 % BIND10_RESURRECTED_PROCESS resurrected %1 (PID %2)
 The given process has been restarted successfully, and is now running
 with the given process id.
diff --git a/src/bin/bind10/bind10_src.py.in b/src/bin/bind10/bind10_src.py.in
index bb2edaf..32c3152 100755
--- a/src/bin/bind10/bind10_src.py.in
+++ b/src/bin/bind10/bind10_src.py.in
@@ -739,7 +739,7 @@ class BoB:
                 component = self.components.pop(pid)
                 logger.info(BIND10_PROCESS_ENDED, component.name(), pid,
                             exit_status)
-                if component.running() and self.runnable:
+                if component.is_running() and self.runnable:
                     # Tell it it failed. But only if it matters (we are
                     # not shutting down and the component considers itself
                     # to be running.
@@ -771,7 +771,12 @@ class BoB:
         next_restart_time = None
         now = time.time()
         for component in self.components_to_restart:
-            if not component.restart(now):
+            # If the component was removed from the configurator between since
+            # scheduled to restart, just ignore it.  The object will just be
+            # dropped here.
+            if not self._component_configurator.has_component(component):
+                logger.info(BIND10_RESTART_COMPONENT_SKIPPED, component.name())
+            elif not component.restart(now):
                 still_dead.append(component)
                 if next_restart_time is None or\
                    next_restart_time > component.get_restart_time():
diff --git a/src/bin/bind10/tests/bind10_test.py.in b/src/bin/bind10/tests/bind10_test.py.in
index 9a40e42..0b11960 100644
--- a/src/bin/bind10/tests/bind10_test.py.in
+++ b/src/bin/bind10/tests/bind10_test.py.in
@@ -929,7 +929,14 @@ class MockComponent:
         self.name = lambda: name
         self.pid = lambda: pid
         self.address = lambda: address
+        self.restarted = False
 
+    def get_restart_time(self):
+        return 0                # arbitrary dummy value
+
+    def restart(self, now):
+        self.restarted = True
+        return True
 
 class TestBossCmd(unittest.TestCase):
     def test_ping(self):
@@ -1266,6 +1273,34 @@ class TestBossComponents(unittest.TestCase):
         bob.start_all_components()
         self.__check_extended(self.__param)
 
+    def __setup_restart(self, bob, component):
+        '''Common procedure for restarting a component used below.'''
+        bob.components_to_restart = { component }
+        component.restarted = False
+        bob.restart_processes()
+
+    def test_restart_processes(self):
+        '''Check some behavior on restarting processes.'''
+        bob = MockBob()
+        bob.runnable = True
+        component = MockComponent('test', 53)
+
+        # A component to be restarted will actually be restarted iff it's
+        # in the configurator's configuration.
+        # We bruteforce the configurator internal below; ugly, but the easiest
+        # way for the test.
+        bob._component_configurator._components['test'] = (None, component)
+        self.__setup_restart(bob, component)
+        self.assertTrue(component.restarted)
+        self.assertFalse(component in bob.components_to_restart)
+
+        # Remove the component from the configuration.  It won't be restarted
+        # even if scheduled, nor will remain in the to-be-restarted list.
+        del bob._component_configurator._components['test']
+        self.__setup_restart(bob, component)
+        self.assertFalse(component.restarted)
+        self.assertFalse(component in bob.components_to_restart)
+
 class SocketSrvTest(unittest.TestCase):
     """
     This tests some methods of boss related to the unix domain sockets used
diff --git a/src/bin/dbutil/dbutil.py.in b/src/bin/dbutil/dbutil.py.in
index 4b76a56..a844484 100755
--- a/src/bin/dbutil/dbutil.py.in
+++ b/src/bin/dbutil/dbutil.py.in
@@ -193,10 +193,17 @@ UPGRADES = [
             "ALTER TABLE schema_version " +
                 "ADD COLUMN minor INTEGER NOT NULL DEFAULT 0"
         ]
+     },
+
+    {'from': (2, 0), 'to': (2, 1),
+     'statements': [
+            "CREATE INDEX nsec3_byhash_and_rdtype ON nsec3 " +
+                "(hash, rdtype)"
+        ]
     }
 
 # To extend this, leave the above statements in place and add another
-# dictionary to the list.  The "from" version should be (2, 0), the "to"
+# dictionary to the list.  The "from" version should be (2, 1), the "to"
 # version whatever the version the update is to, and the SQL statements are
 # the statements required to perform the upgrade.  This way, the upgrade
 # program will be able to upgrade both a V1.0 and a V2.0 database.
diff --git a/src/bin/dbutil/tests/Makefile.am b/src/bin/dbutil/tests/Makefile.am
index b4231b3..aaa57cc 100644
--- a/src/bin/dbutil/tests/Makefile.am
+++ b/src/bin/dbutil/tests/Makefile.am
@@ -2,6 +2,8 @@ SUBDIRS = . testdata
 
 # Tests of the update script.
 
+noinst_SCRIPTS = dbutil_test.sh
+
 check-local:
 	B10_LOCKFILE_DIR_FROM_BUILD=$(abs_top_builddir) \
 	$(SHELL) $(abs_builddir)/dbutil_test.sh
diff --git a/src/bin/dbutil/tests/dbutil_test.sh.in b/src/bin/dbutil/tests/dbutil_test.sh.in
index f82eeb0..35314e8 100755
--- a/src/bin/dbutil/tests/dbutil_test.sh.in
+++ b/src/bin/dbutil/tests/dbutil_test.sh.in
@@ -165,7 +165,7 @@ upgrade_ok_test() {
     if [ $? -eq 0 ]
     then
         # Compare schema with the reference
-        get_schema $testdata/v2_0.sqlite3
+        get_schema $testdata/v2_1.sqlite3
         expected_schema=$db_schema
         get_schema $tempfile
         actual_schema=$db_schema
@@ -177,7 +177,7 @@ upgrade_ok_test() {
         fi
 
         # Check the version is set correctly
-        check_version $tempfile "V2.0"
+        check_version $tempfile "V2.1"
 
         # Check that a backup was made
         check_backup $1 $2
@@ -449,7 +449,7 @@ copy_file $testdata/old_v1.sqlite3 $tempfile
 Yes
 .
 passzero $?
-check_version $tempfile "V2.0"
+check_version $tempfile "V2.1"
 rm -f $tempfile $backupfile
 
 echo "13.4 Interactive prompt - no"
diff --git a/src/bin/dbutil/tests/testdata/Makefile.am b/src/bin/dbutil/tests/testdata/Makefile.am
index 0d850a7..f4873f4 100644
--- a/src/bin/dbutil/tests/testdata/Makefile.am
+++ b/src/bin/dbutil/tests/testdata/Makefile.am
@@ -10,3 +10,4 @@ EXTRA_DIST += old_v1.sqlite3
 EXTRA_DIST += README
 EXTRA_DIST += too_many_version.sqlite3
 EXTRA_DIST += v2_0.sqlite3
+EXTRA_DIST += v2_1.sqlite3
diff --git a/src/bin/dbutil/tests/testdata/v2_1.sqlite3 b/src/bin/dbutil/tests/testdata/v2_1.sqlite3
new file mode 100644
index 0000000..ca2dee9
Binary files /dev/null and b/src/bin/dbutil/tests/testdata/v2_1.sqlite3 differ
diff --git a/src/bin/dhcp4/tests/Makefile.am b/src/bin/dhcp4/tests/Makefile.am
index 906b5d1..ddc3000 100644
--- a/src/bin/dhcp4/tests/Makefile.am
+++ b/src/bin/dhcp4/tests/Makefile.am
@@ -16,6 +16,7 @@ check-local:
 	for pytest in $(PYTESTS) ; do \
 	echo Running test: $$pytest ; \
 	PYTHONPATH=$(COMMON_PYTHON_PATH):$(abs_top_srcdir)/src/bin:$(abs_top_builddir)/src/bin/bind10:$(abs_top_builddir)/src/lib/util/io/.libs \
+	B10_LOCKFILE_DIR_FROM_BUILD=$(abs_top_builddir) \
 	$(LIBRARY_PATH_PLACEHOLDER) \
 		$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
 	done
diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am
index 1d9308f..de87582 100644
--- a/src/bin/dhcp6/tests/Makefile.am
+++ b/src/bin/dhcp6/tests/Makefile.am
@@ -15,6 +15,7 @@ check-local:
 	for pytest in $(PYTESTS) ; do \
 	echo Running test: $$pytest ; \
 	$(LIBRARY_PATH_PLACEHOLDER) \
+	B10_LOCKFILE_DIR_FROM_BUILD=$(abs_top_builddir) \
 	PYTHONPATH=$(COMMON_PYTHON_PATH):$(abs_top_srcdir)/src/bin:$(abs_top_builddir)/src/bin/bind10:$(abs_top_builddir)/src/lib/util/io/.libs \
 		$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
 	done
diff --git a/src/bin/host/.gitignore b/src/bin/host/.gitignore
deleted file mode 100644
index 01ef357..0000000
--- a/src/bin/host/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/b10-host
-/b10-host.1
diff --git a/src/bin/host/Makefile.am b/src/bin/host/Makefile.am
deleted file mode 100644
index 42ef954..0000000
--- a/src/bin/host/Makefile.am
+++ /dev/null
@@ -1,37 +0,0 @@
-AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-AM_CPPFLAGS += $(BOOST_INCLUDES)
-
-AM_CXXFLAGS = $(B10_CXXFLAGS)
-
-if USE_STATIC_LINK
-AM_LDFLAGS = -static
-endif
-
-CLEANFILES = *.gcno *.gcda
-
-bin_PROGRAMS = b10-host
-b10_host_SOURCES = host.cc
-b10_host_LDADD = $(top_builddir)/src/lib/dns/libb10-dns++.la
-b10_host_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
-b10_host_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
-
-man_MANS = b10-host.1
-DISTCLEANFILES = $(man_MANS)
-EXTRA_DIST = $(man_MANS) b10-host.xml
-
-.PHONY: man
-if GENERATE_DOCS
-
-man: b10-host.1
-
-b10-host.1: b10-host.xml
-	@XSLTPROC@ --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/b10-host.xml
-
-else
-
-$(man_MANS):
-	@echo Man generation disabled.  Creating dummy $@.  Configure with --enable-generate-docs to enable it.
-	@echo Man generation disabled.  Remove this file, configure with --enable-generate-docs, and rebuild BIND 10 > $@
-
-endif
diff --git a/src/bin/host/README b/src/bin/host/README
deleted file mode 100644
index 5cc4068..0000000
--- a/src/bin/host/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Rewriting host(1) in C++ from scratch using BIND 10's libdns++.
-
-The bugs and incompatibilities are listed in the manual page
-and in the source code.
diff --git a/src/bin/host/b10-host.xml b/src/bin/host/b10-host.xml
deleted file mode 100644
index a17ef67..0000000
--- a/src/bin/host/b10-host.xml
+++ /dev/null
@@ -1,196 +0,0 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
-	       [<!ENTITY mdash "—">]>
-<!--
- - 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$ -->
-<refentry>
-
-  <refentryinfo>
-    <date>May 4, 2011</date>
-  </refentryinfo>
-
-  <refmeta>
-    <refentrytitle>b10-host</refentrytitle>
-    <manvolnum>1</manvolnum>
-    <refmiscinfo>BIND10</refmiscinfo>
-  </refmeta>
-
-  <refnamediv>
-    <refname>b10-host</refname>
-    <refpurpose>DNS lookup utility</refpurpose>
-  </refnamediv>
-
-  <docinfo>
-    <copyright>
-      <year>2011</year>
-      <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
-    </copyright>
-  </docinfo>
-
-  <refsynopsisdiv>
-    <cmdsynopsis>
-      <command>b10-host</command>
-      <arg><option>-a</option></arg>
-      <arg><option>-c <replaceable>class</replaceable></option></arg>
-      <arg><option>-d</option></arg>
-      <arg><option>-p <replaceable>port</replaceable></option></arg>
-      <arg><option>-r</option></arg>
-      <arg><option>-t <replaceable>type</replaceable></option></arg>
-      <arg><option>-v</option></arg>
-      <arg><replaceable>name</replaceable></arg>
-      <arg><option><replaceable>server</replaceable></option></arg>
-    </cmdsynopsis>
-  </refsynopsisdiv>
-
-  <refsect1>
-    <title>DESCRIPTION</title>
-    <para>
-      The <command>b10-host</command> utility does DNS lookups.
-      Its initial goal is to be a
-      <citerefentry><refentrytitle>host</refentrytitle>
-        <manvolnum>1</manvolnum></citerefentry>
-      clone, but also add a few features useful for BIND 10 development
-      testing.
-    </para>
-
-    <para>
-      By default, it looks up the A, AAAA, and MX record sets for the
-      <replaceable>name</replaceable>.
-      Optionally, you may select a name server to query against by adding
-      the <replaceable>server</replaceable> argument.
-    </para>
-  </refsect1>
-
-  <refsect1>
-    <title>OPTIONS</title>
-
-    <para>The arguments are as follows:</para>
-
-    <variablelist>
-
-      <varlistentry>
-        <term><option>-a</option></term>
-        <listitem><para>
-          Enable verbose mode and do a query for type ANY.
-          (If the <option>-t</option> option is also set, then the
-          ANY query is not done, but it still uses verbose mode.)
-        </para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><option>-c <replaceable>class</replaceable></option></term>
-        <listitem><para>
-          Define the class for the query.
-          The default is IN (Internet).
-<!-- TODO: bug if class is unknown causes seg fault and possible core dump -->
-        </para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><option>-d</option></term>
-        <listitem><para>
-	  Enable verbose output mode, including elapsed time in
-	  milliseconds.
-          Verbose mode shows the header, question, answer, authority,
-          and additional sections (if provided).
-          (Same as <option>-v</option>.)
-        </para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><option>-p <replaceable>port</replaceable></option></term>
-        <listitem><para>
-          Select an alternative port for the query.
-          This may be a number or a service name.
-          The default is 53 (domain).
-          This is not a standard feature of
-          <citerefentry><refentrytitle>host</refentrytitle>
-            <manvolnum>1</manvolnum></citerefentry>.
-        </para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><option>-r</option></term>
-        <listitem><para>
-          Disable recursive processing by not setting the
-          Recursion Desired flag in the query.
-        </para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><option>-t <replaceable>type</replaceable></option></term>
-        <listitem><para>
-          Select a specific resource record type for the query.
-          By default, it looks up the A, AAAA, and MX record sets.
-<!-- TODO: bug if class is unknown causes seg fault and possible core dump -->
-          (This overrides the <option>-a</option> option.)
-        </para></listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><option>-v</option></term>
-        <listitem><para>
-	  Same as <option>-d</option> option.
-        </para></listitem>
-      </varlistentry>
-
-    </variablelist>
-
-  </refsect1>
-
-  <refsect1>
-    <title>COMPATIBILITY / BUGS</title>
-    <para>
-      <command>b10-host</command> does not do reverse lookups by
-      default yet (by detecting if name is a IPv4 or IPv6 address).
-    </para>
-
-    <para>
-      Unknown <option>-c</option> class or <option>-t</option> type
-      causes <command>b10-host</command> to Abort.
-    </para>
-
-    <para>
-      Not all types are supported yet for formatting.
-      Not all switches are supported yet.
-    </para>
-
-    <para>
-      It doesn't use <filename>/etc/resolv.conf</filename> at this time.
-      The default name server used is 127.0.0.1.
-    </para>
-
-    <para>
-      <option>-p</option> is not a standard feature.
-    </para>
-  </refsect1>
-
-  <refsect1>
-    <title>HISTORY</title>
-    <para>
-      The C++ version of <command>b10-host</command> was started in
-      October 2009 by Jeremy C. Reed of ISC.
-      Its usage and output were based on the standard <command>host</command>
-      command.
-    </para>
-  </refsect1>
-</refentry><!--
- - Local variables:
- - mode: sgml
- - End:
--->
diff --git a/src/bin/host/host.cc b/src/bin/host/host.cc
deleted file mode 100644
index a5c6522..0000000
--- a/src/bin/host/host.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (C) 2010-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.
-
-// host rewritten in C++ using BIND 10 DNS library
-
-#include <arpa/inet.h>
-#include <netdb.h>          // for getaddrinfo
-#include <sys/time.h>       // for gettimeofday
-#include <sys/socket.h>     // networking functions and definitions on FreeBSD
-
-#include <unistd.h>
-
-#include <string>
-#include <iostream>
-
-#include <util/buffer.h>
-
-#include <dns/name.h>
-#include <dns/message.h>
-#include <dns/messagerenderer.h>
-#include <dns/opcode.h>
-#include <dns/rcode.h>
-#include <dns/rrclass.h>
-#include <dns/rrtype.h>
-#include <dns/rrset.h>
-#include <dns/message.h>
-
-using namespace std;
-using namespace isc::dns;
-using namespace isc::util;
-
-namespace {
-char* dns_type = NULL;    // not set, so A, AAAA, MX
-const char* server = "127.0.0.1";
-const char* server_port = "53";
-const char* dns_class  = "IN";
-bool verbose = false;
-bool dns_any = false;
-int first_time = 1;
-bool recursive_bit = true;
-struct timeval before_time, after_time;
-
-int
-host_lookup(const char* const name, const char* const dns_class,
-            const char* const type, bool any) {
-
-    Message msg(Message::RENDER);
-
-    msg.setQid(0); // does this matter?
-
-    // TODO: add switch for this
-    msg.setOpcode(Opcode::QUERY());
-    msg.setRcode(Rcode::NOERROR());
-    if (recursive_bit) {
-        msg.setHeaderFlag(Message::HEADERFLAG_RD); // set recursive bit
-    }
-
-    msg.addQuestion(Question(Name(name),
-                             RRClass(dns_class),
-                             any ? RRType::ANY() : RRType(type)));  // if NULL then:
-
-    MessageRenderer renderer;
-    msg.toWire(renderer);
-
-    struct addrinfo hints, *res;
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_socktype = SOCK_DGRAM;
-    hints.ai_flags = 0; // not using AI_NUMERICHOST in case to bootstrap
-    if (getaddrinfo(server, server_port, &hints, &res) != 0) {
-        cerr << "address/port conversion for " << server << ":"
-             << server_port << " failed" << endl;
-        return (1);
-    }
-
-    if (verbose) {
-        cout << "Trying \"" << name << "\"\n";
-    }
-
-    if (verbose && first_time) {
-        // this is only output the first time
-        first_time = 0;
-        cout << "Using domain server:\n";
-        cout << "Name: " << server << "\n";
-        // TODO: I guess I have to do a lookup to get that address and aliases
-        // too
-        //cout << "Address: " << address << "\n" ; // "#" << port << "\n";
-        //cout << "Aliases: " << server << "\n";
-    }
-
-    int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-
-    if (s < 0) {
-        cerr << "failed to open socket" << endl;
-        return (1);
-    }
-
-    if (verbose) {
-        gettimeofday(&before_time, NULL);
-    }
-
-    sendto(s, renderer.getData(), renderer.getLength(), 0, res->ai_addr,
-           res->ai_addrlen);
-
-    struct sockaddr_storage ss;
-    struct sockaddr* sa;
-    socklen_t sa_len;
-
-    sa_len = sizeof(ss);
-    sa = static_cast<struct sockaddr*>((void*)&ss);
-
-    char recvbuf[4096];
-    int cc;
-    if ((cc = recvfrom(s, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) {
-        try {
-            Message rmsg(Message::PARSE);
-            InputBuffer ibuffer(recvbuf, cc);
-
-            rmsg.fromWire(ibuffer);
-            if (!verbose) {
-                string description = "";
-                for (RRsetIterator it =
-                         rmsg.beginSection(Message::SECTION_ANSWER);
-                     it != rmsg.endSection(Message::SECTION_ANSWER);
-                     ++it) {
-
-                      if ((*it)->getType() == RRType::A()) {
-                          description = "has address";
-                      }
-                      else if ((*it)->getType() == RRType::AAAA()) {
-                          description = "has IPv6 address";
-                      }
-                      else if ((*it)->getType() == RRType::MX()) {
-                          description = "mail is handled by";
-                      }
-                      else if ((*it)->getType() == RRType::TXT()) {
-                          description = "descriptive text";
-                      }
-
-                      RdataIteratorPtr rit = (*it)->getRdataIterator();
-                      for (; !rit->isLast(); rit->next()) {
-                          // instead of using my name, maybe use returned label?
-                          cout << name << " "  << description << " " <<
-                              (*rit).getCurrent().toText() << endl;
-                      }
-                  }
-            } else {
-                gettimeofday(&after_time, NULL);
-
-                // HEADER and QUESTION, ANSWER, AUTHORITY, and ADDITIONAL
-                std::cout << rmsg.toText() << std::endl;
-
-                if (before_time.tv_usec > after_time.tv_usec) {
-                    after_time.tv_usec += 1000000;
-                    --after_time.tv_sec;
-                }
-
-                int elapsed_time =
-                    (after_time.tv_sec - before_time.tv_sec)
-                    + ((after_time.tv_usec - before_time.tv_usec))/1000;
-
-                // TODO: if NXDOMAIN, host(1) doesn't show HEADER
-                // Host hsdjkfhksjhdfkj not found: 3(NXDOMAIN)
-                // TODO: test if NXDOMAIN
-
-                std::cout << "Received " << cc <<
-                    " bytes in " << elapsed_time << " ms\n";
-                // TODO: " bytes from 127.0.0.1#53 in 0 ms
-
-            } //verbose
-/*
-TODO: handle InvalidRRClass
-TODO: handle invalid type exception
-        } catch (InvalidType ivt) {
-            std::cerr << "invalid type:" << ivt.what();
-*/
-        } catch (const exception& ex) {
-            std::cerr << "parse failed for " <<
-                string(name) << "/" << type << ": " << ex.what() << std::endl;
-        } catch (...) {
-            std::cerr << "parse failed for " << string(name) << "/" << type;
-        }
-    }
-
-    freeaddrinfo(res);
-
-    return (0);
-} // host_lookup()
-}
-
-int
-main(int argc, char* argv[]) {
-    int c;
-
-    while ((c = getopt(argc, argv, "ac:dp:rt:v")) != -1)
-        switch (c) {
-        case 'a':
-            dns_any = true;
-            verbose = true;
-            break;
-        case 'c':
-            dns_class = optarg;
-            break;
-	// p for port is a non-standard switch
-        case 'p':
-            server_port = optarg;
-            break;
-        case 'r':
-            recursive_bit = false;
-            break;
-        case 't':
-            dns_type = optarg;
-            break;
-        case 'd':
-            // drop through to v, because debug and verbose are equivalent
-        case 'v':
-            verbose = true;
-            break;
-    }
-    argc -= optind;
-    argv += optind;
-
-    if (argc < 1) {
-        cout << "Usage: host [-adrv] [-c class] [-p port] [-t type] hostname [server]\n";
-        exit(1);
-    }
-
-    if (argc >= 2) {
-      server = argv[1];
-    }
-
-    if (dns_type == NULL) {
-        host_lookup(argv[0], dns_class, "A", dns_any);
-        // TODO: don't do next if A doesn't exist
-        host_lookup(argv[0], dns_class, "AAAA", dns_any);
-        host_lookup(argv[0], dns_class, "MX", dns_any);
-    } else {
-        // -t overrides -a, regardless of order
-        host_lookup(argv[0], dns_class, dns_type, false);
-    }
-    return (0);
-}
diff --git a/src/cppcheck-suppress.lst b/src/cppcheck-suppress.lst
index ff4a79a..9dc8d99 100644
--- a/src/cppcheck-suppress.lst
+++ b/src/cppcheck-suppress.lst
@@ -11,3 +11,18 @@ missingInclude
 //
 //    // cppcheck-suppress duplicateExpression
 //    EXPECT_FALSE(small_name < small_name);
+
+// With cppcheck 1.56, there are a number of false positives, which
+// All of these should be checked and hopefully removed after upgrading
+// cppcheck past 1.56
+
+// eraseDereference: This is a known false positive, which has been
+// fixed in the current development version of cppcheck
+eraseDereference
+
+// Unused functions: there suddenly are a lot of unused function errors
+// We could address those by adding for instance early declarations or
+// (unnecessary) header files, but they were all somewhat false positives
+// When we upgrade past 1.56, we should re-check this, and perhaps enable
+// unused-functions again.
+unusedFunction
diff --git a/src/lib/acl/dns.cc b/src/lib/acl/dns.cc
index d16ec65..5466dad 100644
--- a/src/lib/acl/dns.cc
+++ b/src/lib/acl/dns.cc
@@ -12,12 +12,6 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <boost/shared_ptr.hpp>
-
 #include <exceptions/exceptions.h>
 
 #include <dns/name.h>
@@ -31,6 +25,13 @@
 #include <acl/loader.h>
 #include <acl/logic_check.h>
 
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+
+#include <memory>
+#include <string>
+#include <vector>
+
 using namespace std;
 using namespace isc::dns;
 using namespace isc::data;
@@ -106,10 +107,12 @@ internal::RequestCheckCreator::create(const string& name,
 
 RequestLoader&
 getRequestLoader() {
-    static RequestLoader* loader(NULL);
-    if (loader == NULL) {
+    // To ensure that the singleton gets destroyed at the end of the
+    // program's lifetime, we put it in a static scoped_ptr.
+    static boost::scoped_ptr<RequestLoader> loader(NULL);
+    if (loader.get() == NULL) {
         // Creator registration may throw, so we first store the new loader
-        // in an auto pointer in order to provide the strong exception
+        // in a second auto pointer in order to provide the strong exception
         // guarantee.
         auto_ptr<RequestLoader> loader_ptr =
             auto_ptr<RequestLoader>(new RequestLoader(REJECT));
@@ -129,7 +132,7 @@ getRequestLoader() {
                 new LogicCreator<AllOfSpec, RequestContext>("ALL")));
 
         // From this point there shouldn't be any exception thrown
-        loader = loader_ptr.release();
+        loader.reset(loader_ptr.release());
     }
 
     return (*loader);
diff --git a/src/lib/cache/tests/rrset_entry_unittest.cc b/src/lib/cache/tests/rrset_entry_unittest.cc
index c7c3c6e..a6ac27e 100644
--- a/src/lib/cache/tests/rrset_entry_unittest.cc
+++ b/src/lib/cache/tests/rrset_entry_unittest.cc
@@ -50,9 +50,6 @@ class DerivedRRsetEntry: public RRsetEntry {
 public:
     DerivedRRsetEntry(const isc::dns::RRset& rrset, const RRsetTrustLevel& level) : RRsetEntry(rrset, level) {};
 
-    void updateTTLForTest() {
-
-    }
 };
 
 #define TEST_TTL 100
diff --git a/src/lib/cc/data.cc b/src/lib/cc/data.cc
index 6ec243a..47b1eb1 100644
--- a/src/lib/cc/data.cc
+++ b/src/lib/cc/data.cc
@@ -413,7 +413,7 @@ from_stringstream_number(std::istream &in, int &pos) {
             isc_throw(JSONError, std::string("Number overflow: ") + number);
         }
     }
-    
+
     if (is_double) {
         return (Element::create(d));
     } else {
@@ -501,7 +501,7 @@ from_stringstream_map(std::istream &in, const std::string& file, int& line,
 
             ConstElementPtr value = Element::fromJSON(in, file, line, pos);
             map->set(key, value);
-            
+
             skip_to(in, file, line, pos, ",}", WHITESPACE);
             c = in.get();
             pos++;
@@ -942,7 +942,7 @@ removeIdentical(ConstElementPtr a, ConstElementPtr b) {
     if (!b) {
         return (result);
     }
-    
+
     if (a->getType() != Element::map || b->getType() != Element::map) {
         isc_throw(TypeError, "Non-map Elements passed to removeIdentical");
     }
@@ -965,7 +965,7 @@ merge(ElementPtr element, ConstElementPtr other) {
         other->getType() != Element::map) {
         isc_throw(TypeError, "merge arguments not MapElements");
     }
-    
+
     const std::map<std::string, ConstElementPtr>& m = other->mapValue();
     for (std::map<std::string, ConstElementPtr>::const_iterator it = m.begin();
          it != m.end() ; ++it) {
diff --git a/src/lib/config/ccsession.cc b/src/lib/config/ccsession.cc
index daec005..8516d6c 100644
--- a/src/lib/config/ccsession.cc
+++ b/src/lib/config/ccsession.cc
@@ -338,7 +338,7 @@ getRelatedLoggers(ConstElementPtr loggers) {
 
     // Now find the wildcard names (the one that start with "*").
     BOOST_FOREACH(ConstElementPtr cur_logger, loggers->listValue()) {
-        std::string cur_name = cur_logger->get("name")->stringValue();
+        const std::string cur_name = cur_logger->get("name")->stringValue();
         // If name is '*', or starts with '*.', replace * with root
         // logger name.
         if (cur_name == "*" || cur_name.length() > 1 &&
@@ -671,9 +671,7 @@ ModuleCCSession::fetchRemoteSpec(const std::string& module, bool is_filename) {
 
 std::string
 ModuleCCSession::addRemoteConfig(const std::string& spec_name,
-                                 void (*handler)(const std::string& module,
-                                                 ConstElementPtr,
-                                                 const ConfigData&),
+                                 RemoteHandler handler,
                                  bool spec_is_filename)
 {
     // First get the module name, specification and default config
diff --git a/src/lib/config/ccsession.h b/src/lib/config/ccsession.h
index e96a33d..4b99a44 100644
--- a/src/lib/config/ccsession.h
+++ b/src/lib/config/ccsession.h
@@ -283,7 +283,7 @@ public:
      *                  the configuration manager must know it). If
      *                  spec_is_filename is true (the default), then a
      *                  filename is assumed, otherwise a module name.
-     * \param handler The handler function called whenever there's a change.
+     * \param handler The handler functor called whenever there's a change.
      *                Called once initally from this function. May be NULL
      *                if you don't want any handler to be called and you're
      *                fine with requesting the data through
@@ -296,11 +296,11 @@ public:
      * \return The name of the module specified in the given specification
      *         file
      */
+    typedef boost::function<void(const std::string&,
+                                 isc::data::ConstElementPtr,
+                                 const ConfigData&)> RemoteHandler;
     std::string addRemoteConfig(const std::string& spec_name,
-                                void (*handler)(const std::string& module_name,
-                                                isc::data::ConstElementPtr
-                                                update,
-                                                const ConfigData& config_data) = NULL,
+                                RemoteHandler handler = RemoteHandler(),
                                 bool spec_is_filename = true);
 
     /**
@@ -513,9 +513,6 @@ private:
         const std::string& command,
         isc::data::ConstElementPtr args);
 
-    typedef void (*RemoteHandler)(const std::string&,
-                                  isc::data::ConstElementPtr,
-                                  const ConfigData&);
     std::map<std::string, ConfigData> remote_module_configs_;
     std::map<std::string, RemoteHandler> remote_module_handlers_;
 
diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc
index ede7aa3..fbada44 100644
--- a/src/lib/datasrc/database.cc
+++ b/src/lib/datasrc/database.cc
@@ -386,10 +386,11 @@ DatabaseClient::Finder::findAll(const isc::dns::Name& name,
                                 std::vector<isc::dns::ConstRRsetPtr>& target,
                                 const FindOptions options)
 {
-    return (ZoneFinderContextPtr(new Context(*this, options,
-                                             findInternal(name, RRType::ANY(),
-                                                          &target, options),
-                                             target)));
+    return (ZoneFinderContextPtr(new GenericContext(
+                                     *this, options,
+                                     findInternal(name, RRType::ANY(),
+                                                  &target, options),
+                                     target)));
 }
 
 ZoneFinderContextPtr
@@ -400,9 +401,10 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
     if (type == RRType::ANY()) {
         isc_throw(isc::Unexpected, "Use findAll to answer ANY");
     }
-    return (ZoneFinderContextPtr(new Context(*this, options,
-                                             findInternal(name, type, NULL,
-                                                          options))));
+    return (ZoneFinderContextPtr(new GenericContext(
+                                     *this, options,
+                                     findInternal(name, type, NULL,
+                                                  options))));
 }
 
 DatabaseClient::Finder::DelegationSearchResult
diff --git a/src/lib/datasrc/memory/Makefile.am b/src/lib/datasrc/memory/Makefile.am
index d46a907..205f137 100644
--- a/src/lib/datasrc/memory/Makefile.am
+++ b/src/lib/datasrc/memory/Makefile.am
@@ -19,8 +19,11 @@ libdatasrc_memory_la_SOURCES += segment_object_holder.h
 libdatasrc_memory_la_SOURCES += logger.h logger.cc
 libdatasrc_memory_la_SOURCES += zone_table.h zone_table.cc
 libdatasrc_memory_la_SOURCES += zone_finder.h zone_finder.cc
+libdatasrc_memory_la_SOURCES += zone_table_segment.h zone_table_segment.cc
+libdatasrc_memory_la_SOURCES += zone_table_segment_local.h zone_table_segment_local.cc
 libdatasrc_memory_la_SOURCES += zone_data_updater.h zone_data_updater.cc
 libdatasrc_memory_la_SOURCES += memory_client.h memory_client.cc
+
 nodist_libdatasrc_memory_la_SOURCES = memory_messages.h memory_messages.cc
 
 EXTRA_DIST  = rdata_serialization_priv.cc
diff --git a/src/lib/datasrc/memory/domaintree.h b/src/lib/datasrc/memory/domaintree.h
index 20f4693..272245d 100644
--- a/src/lib/datasrc/memory/domaintree.h
+++ b/src/lib/datasrc/memory/domaintree.h
@@ -947,7 +947,7 @@ public:
         PARTIALMATCH, ///< A superdomain node was found
         NOTFOUND,   ///< Not even any superdomain was found
         /// \brief Returned by insert() if a node of the name already exists
-        ALREADYEXISTS,
+        ALREADYEXISTS
     };
 
     /// \brief Allocate and construct \c DomainTree
@@ -1080,55 +1080,25 @@ public:
     ///    of it. In that case, node parameter is left intact.
     //@{
 
-    /// \brief Simple find.
+    /// \brief Simple find
     ///
     /// Acts as described in the \ref find section.
     Result find(const isc::dns::Name& name,
-                DomainTreeNode<T>** node) const {
-        DomainTreeNodeChain<T> node_path;
-        const isc::dns::LabelSequence ls(name);
-        return (find<void*>(ls, node, node_path, NULL, NULL));
-    }
-
-    /// \brief Simple find returning immutable node.
-    ///
-    /// Acts as described in the \ref find section, but returns immutable node
-    /// pointer.
-    Result find(const isc::dns::Name& name,
                 const DomainTreeNode<T>** node) const {
         DomainTreeNodeChain<T> node_path;
-        DomainTreeNode<T> *target_node = NULL;
         const isc::dns::LabelSequence ls(name);
-        Result ret = (find<void*>(ls, &target_node, node_path, NULL, NULL));
-        if (ret != NOTFOUND) {
-            *node = target_node;
-        }
+        Result ret = (find<void*>(ls, node, node_path, NULL, NULL));
         return (ret);
     }
 
     /// \brief Simple find, with node_path tracking
     ///
     /// Acts as described in the \ref find section.
-    Result find(const isc::dns::Name& name, DomainTreeNode<T>** node,
-                DomainTreeNodeChain<T>& node_path) const
-    {
-        const isc::dns::LabelSequence ls(name);
-        return (find<void*>(ls, node, node_path, NULL, NULL));
-    }
-
-    /// \brief Simple find returning immutable node, with node_path tracking
-    ///
-    /// Acts as described in the \ref find section, but returns immutable node
-    /// pointer.
     Result find(const isc::dns::Name& name, const DomainTreeNode<T>** node,
                 DomainTreeNodeChain<T>& node_path) const
     {
-        DomainTreeNode<T> *target_node = NULL;
         const isc::dns::LabelSequence ls(name);
-        Result ret = (find<void*>(ls, &target_node, node_path, NULL, NULL));
-        if (ret != NOTFOUND) {
-            *node = target_node;
-        }
+        Result ret = (find<void*>(ls, node, node_path, NULL, NULL));
         return (ret);
     }
 
@@ -1143,13 +1113,9 @@ public:
                 bool (*callback)(const DomainTreeNode<T>&, CBARG),
                 CBARG callback_arg) const
     {
-        DomainTreeNode<T>* target_node = NULL;
         const isc::dns::LabelSequence ls(name);
-        Result ret = find(ls, &target_node, node_path, callback,
+        Result ret = find(ls, node, node_path, callback,
                           callback_arg);
-        if (ret != NOTFOUND) {
-            *node = target_node;
-        }
         return (ret);
     }
 
@@ -1229,30 +1195,10 @@ public:
     ///     \c true, it returns immediately with the current node.
     template <typename CBARG>
     Result find(const isc::dns::LabelSequence& target_labels_orig,
-                DomainTreeNode<T>** node,
-                DomainTreeNodeChain<T>& node_path,
-                bool (*callback)(const DomainTreeNode<T>&, CBARG),
-                CBARG callback_arg) const;
-
-    /// \brief Simple find returning immutable node.
-    ///
-    /// Acts as described in the \ref find section, but returns immutable
-    /// node pointer.
-    template <typename CBARG>
-    Result find(const isc::dns::LabelSequence& target_labels,
                 const DomainTreeNode<T>** node,
                 DomainTreeNodeChain<T>& node_path,
                 bool (*callback)(const DomainTreeNode<T>&, CBARG),
-                CBARG callback_arg) const
-    {
-        DomainTreeNode<T>* target_node = NULL;
-        Result ret = find(target_labels, &target_node, node_path,
-                          callback, callback_arg);
-        if (ret != NOTFOUND) {
-            *node = target_node;
-        }
-        return (ret);
-    }
+                CBARG callback_arg) const;
     //@}
 
     /// \brief return the next bigger node in DNSSEC order from a given node
@@ -1515,7 +1461,7 @@ template <typename T>
 template <typename CBARG>
 typename DomainTree<T>::Result
 DomainTree<T>::find(const isc::dns::LabelSequence& target_labels_orig,
-                    DomainTreeNode<T>** target,
+                    const DomainTreeNode<T>** target,
                     DomainTreeNodeChain<T>& node_path,
                     bool (*callback)(const DomainTreeNode<T>&, CBARG),
                     CBARG callback_arg) const
@@ -1526,11 +1472,11 @@ DomainTree<T>::find(const isc::dns::LabelSequence& target_labels_orig,
                   " and label sequence");
     }
 
-    DomainTreeNode<T>* node;
+    const DomainTreeNode<T>* node;
 
     if (!node_path.isEmpty()) {
         // Get the top node in the node chain
-        node = const_cast<DomainTreeNode<T>*>(node_path.top());
+        node = node_path.top();
         // Start searching from its down pointer
         node = node->getDown();
     } else {
diff --git a/src/lib/datasrc/memory/memory_client.cc b/src/lib/datasrc/memory/memory_client.cc
index 0857541..d6b2803 100644
--- a/src/lib/datasrc/memory/memory_client.cc
+++ b/src/lib/datasrc/memory/memory_client.cc
@@ -32,7 +32,6 @@
 #include <dns/name.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
-#include <dns/rrsetlist.h>
 #include <dns/masterload.h>
 
 #include <boost/bind.hpp>
@@ -133,22 +132,20 @@ InMemoryClient::load(const Name& zone_name,
     // node must point to a valid node now
     assert(node != NULL);
 
-    std::string* tstr = node->setData(new std::string(filename));
+    const std::string* tstr = node->setData(new std::string(filename));
     delete tstr;
 
-    ZoneTable::AddResult result(zone_table_->addZone(mem_sgmt_, rrclass_,
-                                                     zone_name));
+    const ZoneTable::AddResult result(zone_table_->addZone(mem_sgmt_, rrclass_,
+                                                           zone_name,
+                                                           holder.release()));
     if (result.code == result::SUCCESS) {
         // Only increment the zone count if the zone doesn't already
         // exist.
         ++zone_count_;
     }
-
-    ZoneTable::FindResult fr(zone_table_->setZoneData(zone_name,
-                                                      holder.release()));
-    assert(fr.code == result::SUCCESS);
-    if (fr.zone_data != NULL) {
-        ZoneData::destroy(mem_sgmt_, fr.zone_data, rrclass_);
+    // Destroy the old instance of the zone if there was any
+    if (result.zone_data != NULL) {
+        ZoneData::destroy(mem_sgmt_, result.zone_data, rrclass_);
     }
 
     return (result.code);
@@ -232,8 +229,8 @@ InMemoryClient::load(const isc::dns::Name& zone_name,
 
 const std::string
 InMemoryClient::getFileName(const isc::dns::Name& zone_name) const {
-    FileNameNode* node(NULL);
-    FileNameTree::Result result = file_name_tree_->find(zone_name, &node);
+    const FileNameNode* node(NULL);
+    const FileNameTree::Result result = file_name_tree_->find(zone_name, &node);
     if (result == FileNameTree::EXACTMATCH) {
         return (*node->getData());
     } else {
@@ -241,25 +238,6 @@ InMemoryClient::getFileName(const isc::dns::Name& zone_name) const {
     }
 }
 
-result::Result
-InMemoryClient::add(const isc::dns::Name& zone_name,
-                    const ConstRRsetPtr& rrset)
-{
-    const ZoneTable::FindResult result = zone_table_->findZone(zone_name);
-    if (result.code != result::SUCCESS) {
-        isc_throw(DataSourceError, "No such zone: " + zone_name.toText());
-    }
-
-    const ConstRRsetPtr sig_rrset =
-        rrset ? rrset->getRRsig() : ConstRRsetPtr();
-
-    ZoneDataUpdater updater(mem_sgmt_, rrclass_, zone_name, *result.zone_data);
-    updater.add(rrset, sig_rrset);
-
-    // add() doesn't allow duplicate add, so we always return SUCCESS.
-    return (result::SUCCESS);
-}
-
 namespace {
 
 class MemoryIterator : public ZoneIterator {
diff --git a/src/lib/datasrc/memory/memory_client.h b/src/lib/datasrc/memory/memory_client.h
index edd3837..9b3113e 100644
--- a/src/lib/datasrc/memory/memory_client.h
+++ b/src/lib/datasrc/memory/memory_client.h
@@ -159,35 +159,6 @@ public:
     /// zone from a file before.
     const std::string getFileName(const isc::dns::Name& zone_name) const;
 
-    /// \brief Inserts an rrset into the zone.
-    ///
-    /// It puts another RRset into the zone.
-    ///
-    /// In the current implementation, this method doesn't allow an existing
-    /// RRset to be updated or overridden.  So the caller must make sure that
-    /// all RRs of the same type and name must be given in the form of a
-    /// single RRset.  The current implementation will also require that
-    /// when an RRSIG is added, the RRset to be covered has already been
-    /// added.  These restrictions are probably too strict when this data
-    /// source accepts various forms of input, so they should be revisited
-    /// later.
-    ///
-    /// 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
-    ///    exists).
-    result::Result add(const isc::dns::Name& zone_name,
-                       const isc::dns::ConstRRsetPtr& rrset);
-
     /// Returns a \c ZoneFinder result that best matches the given name.
     ///
     /// This derived version of the method never throws an exception.
diff --git a/src/lib/datasrc/memory/zone_finder.cc b/src/lib/datasrc/memory/zone_finder.cc
index c318f70..11188a0 100644
--- a/src/lib/datasrc/memory/zone_finder.cc
+++ b/src/lib/datasrc/memory/zone_finder.cc
@@ -428,7 +428,7 @@ FindNodeResult findNode(const ZoneData& zone_data,
                         ZoneFinder::FindOptions options,
                         bool out_of_zone_ok = false)
 {
-    ZoneNode* node = NULL;
+    const ZoneNode* node = NULL;
     FindState state((options & ZoneFinder::FIND_GLUE_OK) != 0);
 
     const ZoneTree& tree(zone_data.getZoneTree());
@@ -534,17 +534,26 @@ FindNodeResult findNode(const ZoneData& zone_data,
 /// context.
 class InMemoryZoneFinder::Context : public ZoneFinder::Context {
 public:
-    Context(ZoneFinder& finder, ZoneFinder::FindOptions options,
+    Context(InMemoryZoneFinder& finder, ZoneFinder::FindOptions options,
             const RRClass& rrclass, const ZoneFinderResultContext& result) :
-        ZoneFinder::Context(finder, options,
-                            ResultContext(result.code, result.rrset,
-                                          result.flags)),
+        ZoneFinder::Context(options, ResultContext(result.code, result.rrset,
+                                                   result.flags)),
+        finder_(finder), // NOTE: when entire #2283 is done we won't need this
         rrclass_(rrclass), zone_data_(result.zone_data),
         found_node_(result.found_node),
         found_rdset_(result.found_rdset)
     {}
 
 protected:
+    // When all tickets in #2283 are done this can simply return NULL.
+    virtual ZoneFinder* getFinder() { return (&finder_); }
+
+    // We don't use the default protected methods that rely on this method,
+    // so we can simply return NULL.
+    virtual const std::vector<isc::dns::ConstRRsetPtr>* getAllRRsets() const {
+        return (NULL);
+    }
+
     virtual void getAdditionalImpl(const std::vector<RRType>& requested_types,
                                    std::vector<ConstRRsetPtr>& result)
     {
@@ -626,6 +635,7 @@ private:
     }
 
 private:
+    InMemoryZoneFinder& finder_;
     const RRClass rrclass_;
     const ZoneData* const zone_data_;
     const ZoneNode* const found_node_;
diff --git a/src/lib/datasrc/memory/zone_table.cc b/src/lib/datasrc/memory/zone_table.cc
index a74a61d..836b020 100644
--- a/src/lib/datasrc/memory/zone_table.cc
+++ b/src/lib/datasrc/memory/zone_table.cc
@@ -69,17 +69,13 @@ ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable,
 
 ZoneTable::AddResult
 ZoneTable::addZone(util::MemorySegment& mem_sgmt, RRClass zone_class,
-                   const Name& zone_name)
+                   const Name& zone_name, ZoneData* content)
 {
-    // Create a new ZoneData instance first.  If the specified name already
-    // exists in the table, the new data will soon be destroyed, but we want
-    // to make sure if this allocation fails the tree won't be changed to
-    // provide as strong guarantee as possible.  In practice, we generally
-    // expect the caller tries to add a zone only when it's a new one, so
-    // this should be a minor concern.
-    SegmentObjectHolder<ZoneData, RRClass> holder(
-        mem_sgmt, ZoneData::create(mem_sgmt, zone_name), zone_class);
-
+    if (content == NULL) {
+        isc_throw(isc::BadValue, "Zone content must not be NULL");
+    }
+    SegmentObjectHolder<ZoneData, RRClass> holder(mem_sgmt, content,
+                                                  zone_class);
     // Get the node where we put the zone
     ZoneTableNode* node(NULL);
     switch (zones_->insert(mem_sgmt, zone_name, &node)) {
@@ -94,18 +90,18 @@ ZoneTable::addZone(util::MemorySegment& mem_sgmt, RRClass zone_class,
     // Can Not Happen
     assert(node != NULL);
 
-    // Is it empty? We either just created it or it might be nonterminal
-    if (node->isEmpty()) {
-        node->setData(holder.get());
-        return (AddResult(result::SUCCESS, holder.release()));
-    } else { // There's something there already
-        return (AddResult(result::EXIST, node->getData()));
+    // We can release now, setData never throws
+    ZoneData* old = node->setData(holder.release());
+    if (old != NULL) {
+        return (AddResult(result::EXIST, old));
+    } else {
+        return (AddResult(result::SUCCESS, NULL));
     }
 }
 
 ZoneTable::FindResult
 ZoneTable::findZone(const Name& name) const {
-    ZoneTableNode* node(NULL);
+    const ZoneTableNode* node(NULL);
     result::Result my_result;
 
     // Translate the return codes
@@ -132,20 +128,6 @@ ZoneTable::findZone(const Name& name) const {
     return (FindResult(my_result, node->getData()));
 }
 
-ZoneTable::FindResult
-ZoneTable::setZoneData(const Name& name, ZoneData* data)
-{
-    ZoneTableNode* node(NULL);
-
-    ZoneTableTree::Result result(zones_->find(name, &node));
-
-    if (result != ZoneTableTree::EXACTMATCH) {
-        return (FindResult(result::NOTFOUND, NULL));
-    } else {
-        return (FindResult(result::SUCCESS, node->setData(data)));
-    }
-}
-
 } // end of namespace memory
 } // end of namespace datasrc
 } // end of namespace isc
diff --git a/src/lib/datasrc/memory/zone_table.h b/src/lib/datasrc/memory/zone_table.h
index 8ad6213..024558e 100644
--- a/src/lib/datasrc/memory/zone_table.h
+++ b/src/lib/datasrc/memory/zone_table.h
@@ -74,23 +74,23 @@ private:
     typedef DomainTreeNode<ZoneData> ZoneTableNode;
 
 public:
-    /// \brief Result data of addZone() method.
-    struct AddResult {
-        AddResult(result::Result param_code, ZoneData* param_zone_data) :
-            code(param_code), zone_data(param_zone_data)
-        {}
-        const result::Result code;
-        ZoneData* const zone_data;
-    };
+     /// \brief Result data of addZone() method.
+     struct AddResult {
+         AddResult(result::Result param_code, ZoneData* param_zone_data) :
+             code(param_code), zone_data(param_zone_data)
+         {}
+         const result::Result code;
+         ZoneData* const zone_data;
+     };
 
     /// \brief Result data of findZone() method.
     struct FindResult {
         FindResult(result::Result param_code,
-                   ZoneData* param_zone_data) :
+                   const ZoneData* param_zone_data) :
             code(param_code), zone_data(param_zone_data)
         {}
         const result::Result code;
-        ZoneData* const zone_data;
+        const ZoneData* const zone_data;
     };
 
 private:
@@ -140,30 +140,29 @@ public:
 
     /// Add a new zone to the \c ZoneTable.
     ///
-    /// This method creates a new \c ZoneData for the given zone name and
-    /// holds it in the internal table.  The newly created zone data will be
-    /// returned via the \c zone_data member of the return value.  If the given
-    /// zone name already exists in the table, a new data object won't be
-    /// created; instead, the existing corresponding data will be returned.
-    ///
-    /// The zone table keeps the ownership of the created zone data; the
-    /// caller must not try to destroy it directly.  (We'll eventually
-    /// add an interface to delete specific zone data from the table).
+    /// This method adds a given zone data to the internal table.
     ///
     /// \throw std::bad_alloc Internal resource allocation fails.
     ///
     /// \param mem_sgmt The \c MemorySegment to allocate zone data to be
-    /// created.  It must be the same segment that was used to create
-    /// the zone table at the time of create().
+    ///     created.  It must be the same segment that was used to create
+    ///     the zone table at the time of create().
     /// \param zone_name The name of the zone to be added.
     /// \param zone_class The RR class of the zone.  It must be the RR class
-    /// that is supposed to be associated to the zone table.
+    ///     that is supposed to be associated to the zone table.
+    /// \param content This one should hold the zone content (the ZoneData).
+    ///     The ownership is passed onto the zone table. Must not be null.
+    ///     Must correspond to the name and class and must be allocated from
+    ///     mem_sgmt.
     /// \return \c result::SUCCESS If the zone is successfully
-    /// added to the zone table.
-    /// \return \c result::EXIST The zone table already contains
-    /// zone of the same origin.
-    AddResult addZone(util::MemorySegment& mem_sgmt, dns::RRClass zone_class,
-                      const dns::Name& zone_name);
+    ///     added to the zone table.
+    /// \return \c result::EXIST The zone table already contained
+    ///     zone of the same origin. The old data is replaced and returned
+    ///     inside the result.
+    AddResult addZone(util::MemorySegment& mem_sgmt,
+                      dns::RRClass zone_class,
+                      const dns::Name& zone_name,
+                      ZoneData* content);
 
     /// Find a zone that best matches the given name in the \c ZoneTable.
     ///
@@ -185,16 +184,6 @@ public:
     /// \return A \c FindResult object enclosing the search result (see above).
     FindResult findZone(const isc::dns::Name& name) const;
 
-    /// Override the ZoneData for a node (zone) in the zone tree.
-    ///
-    /// \throw none
-    ///
-    /// \param name A domain name for which the zone data is set.
-    /// \param data The new zone data to set.
-    /// \return A \c FindResult object containing the old data if the
-    /// zone was found.
-    FindResult setZoneData(const isc::dns::Name& name, ZoneData* data);
-
 private:
     boost::interprocess::offset_ptr<ZoneTableTree> zones_;
 };
diff --git a/src/lib/datasrc/memory/zone_table_segment.cc b/src/lib/datasrc/memory/zone_table_segment.cc
new file mode 100644
index 0000000..7a80e3c
--- /dev/null
+++ b/src/lib/datasrc/memory/zone_table_segment.cc
@@ -0,0 +1,38 @@
+// Copyright (C) 2012  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 <datasrc/memory/zone_table_segment.h>
+#include <datasrc/memory/zone_table_segment_local.h>
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+
+ZoneTableSegment*
+ZoneTableSegment::create(const isc::data::Element&) {
+    /// FIXME: For now, we always return ZoneTableSegmentLocal. This
+    /// should be updated eventually to parse the passed Element
+    /// argument and construct a corresponding ZoneTableSegment
+    /// implementation.
+    return (new ZoneTableSegmentLocal);
+}
+
+void
+ZoneTableSegment::destroy(ZoneTableSegment *segment) {
+    delete segment;
+}
+
+} // namespace memory
+} // namespace datasrc
+} // namespace isc
diff --git a/src/lib/datasrc/memory/zone_table_segment.h b/src/lib/datasrc/memory/zone_table_segment.h
new file mode 100644
index 0000000..7fd1310
--- /dev/null
+++ b/src/lib/datasrc/memory/zone_table_segment.h
@@ -0,0 +1,110 @@
+// Copyright (C) 2012  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.
+
+#ifndef __ZONE_TABLE_SEGMENT_H__
+#define __ZONE_TABLE_SEGMENT_H__
+
+#include <datasrc/memory/zone_table.h>
+#include <cc/data.h>
+#include <util/memory_segment.h>
+
+#include <boost/interprocess/offset_ptr.hpp>
+
+#include <stdlib.h>
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+
+/// \brief Memory-management independent entry point that contains a
+/// pointer to a zone table in memory.
+///
+/// An instance of this type lives inside a ZoneTableSegment
+/// implementation. It contains an offset pointer to the zone table (a
+/// map from domain names to zone locators) in memory.
+struct ZoneTableHeader {
+public:
+    /// \brief Returns a pointer to the underlying zone table.
+    ZoneTable* getTable() {
+        return (table.get());
+    }
+
+    /// \brief const version of \c getTable().
+    const ZoneTable* getTable() const {
+        return (table.get());
+    }
+
+private:
+    boost::interprocess::offset_ptr<ZoneTable> table;
+};
+
+/// \brief Manages a ZoneTableHeader, an entry point into a table of
+/// zones
+///
+/// This class specifies an interface for derived implementations which
+/// return a pointer to an object of type ZoneTableHeader, an entry
+/// point into a table of zones regardless of the underlying memory
+/// management implementation. Derived classes would implement the
+/// interface for specific memory-implementation behavior.
+class ZoneTableSegment {
+protected:
+    /// \brief Protected constructor
+    ///
+    /// An instance implementing this interface is expected to be
+    /// created by the factory method (\c create()), so this constructor
+    /// is protected.
+    ZoneTableSegment()
+    {}
+public:
+    /// \brief Destructor
+    virtual ~ZoneTableSegment() {}
+
+    /// \brief Return the ZoneTableHeader for the zone table segment.
+    virtual ZoneTableHeader& getHeader() = 0;
+
+    /// \brief const version of \c getHeader().
+    virtual const ZoneTableHeader& getHeader() const = 0;
+
+    /// \brief Return the MemorySegment for the zone table segment.
+    virtual isc::util::MemorySegment& getMemorySegment() = 0;
+
+    /// \brief Create an instance depending on the memory segment model
+    ///
+    /// This is a factory method to create a derived ZoneTableSegment
+    /// object based on the \c config passed. The method returns a
+    /// dynamically-allocated object. The caller is responsible for
+    /// destroying it with \c ZoneTableSegment::destroy().
+    ///
+    /// FIXME: For now, we always return ZoneTableSegmentLocal
+    /// regardless of the passed \c config.
+    ///
+    /// \param config The configuration based on which a derived object
+    ///               is returned.
+    /// \return Returns a ZoneTableSegment object
+    static ZoneTableSegment* create(const isc::data::Element& config);
+
+    /// \brief Destroy a ZoneTableSegment
+    ///
+    /// This method destroys the passed ZoneTableSegment. It must be
+    /// passed a segment previously created by \c ZoneTableSegment::create().
+    ///
+    /// \param segment The segment to destroy.
+    static void destroy(ZoneTableSegment* segment);
+};
+
+} // namespace memory
+} // namespace datasrc
+} // namespace isc
+
+#endif // __ZONE_TABLE_SEGMENT_H__
diff --git a/src/lib/datasrc/memory/zone_table_segment_local.cc b/src/lib/datasrc/memory/zone_table_segment_local.cc
new file mode 100644
index 0000000..589c9af
--- /dev/null
+++ b/src/lib/datasrc/memory/zone_table_segment_local.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2012  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 <datasrc/memory/zone_table_segment_local.h>
+
+using namespace isc::util;
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+
+// After more methods' definitions are added here, it would be a good
+// idea to move getHeader() and getMemorySegment() definitions to the
+// header file.
+ZoneTableHeader&
+ZoneTableSegmentLocal::getHeader() {
+     return (header_);
+}
+
+const ZoneTableHeader&
+ZoneTableSegmentLocal::getHeader() const {
+     return (header_);
+}
+
+MemorySegment&
+ZoneTableSegmentLocal::getMemorySegment() {
+     return (mem_sgmt_);
+}
+
+} // namespace memory
+} // namespace datasrc
+} // namespace isc
diff --git a/src/lib/datasrc/memory/zone_table_segment_local.h b/src/lib/datasrc/memory/zone_table_segment_local.h
new file mode 100644
index 0000000..de776a9
--- /dev/null
+++ b/src/lib/datasrc/memory/zone_table_segment_local.h
@@ -0,0 +1,66 @@
+// Copyright (C) 2012  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.
+
+#ifndef __ZONE_TABLE_SEGMENT_LOCAL_H__
+#define __ZONE_TABLE_SEGMENT_LOCAL_H__
+
+#include <datasrc/memory/zone_table_segment.h>
+#include <util/memory_segment_local.h>
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+
+/// \brief Local implementation of ZoneTableSegment class
+///
+/// This class specifies a concrete implementation for a
+/// MemorySegmentLocal based ZoneTableSegment. Please see the
+/// ZoneTableSegment class documentation for usage.
+class ZoneTableSegmentLocal : public ZoneTableSegment {
+    // This is so that ZoneTableSegmentLocal can be instantiated from
+    // ZoneTableSegment::create().
+    friend class ZoneTableSegment;
+protected:
+    /// \brief Protected constructor
+    ///
+    /// Instances are expected to be created by the factory method
+    /// (\c ZoneTableSegment::create()), so this constructor is
+    /// protected.
+    ZoneTableSegmentLocal()
+    {}
+public:
+    /// \brief Destructor
+    virtual ~ZoneTableSegmentLocal() {}
+
+    /// \brief Return the ZoneTableHeader for the local zone table
+    /// segment implementation.
+    virtual ZoneTableHeader& getHeader();
+
+    /// \brief const version of \c getHeader().
+    virtual const ZoneTableHeader& getHeader() const;
+
+    /// \brief Return the MemorySegment for the local zone table segment
+    /// implementation (a MemorySegmentLocal instance).
+    virtual isc::util::MemorySegment& getMemorySegment();
+
+private:
+    ZoneTableHeader header_;
+    isc::util::MemorySegmentLocal mem_sgmt_;
+};
+
+} // namespace memory
+} // namespace datasrc
+} // namespace isc
+
+#endif // __ZONE_TABLE_SEGMENT_LOCAL_H__
diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc
index e38a487..686dd94 100644
--- a/src/lib/datasrc/memory_datasrc.cc
+++ b/src/lib/datasrc/memory_datasrc.cc
@@ -20,7 +20,6 @@
 #include <dns/nsec3hash.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
-#include <dns/rrsetlist.h>
 #include <dns/masterload.h>
 
 #include <datasrc/memory_datasrc.h>
@@ -792,13 +791,19 @@ public:
     /// context.
     Context(ZoneFinder& finder, ZoneFinder::FindOptions options,
             const RBNodeResultContext& result) :
-        ZoneFinder::Context(finder, options,
+        ZoneFinder::Context(options,
                             ResultContext(result.code, result.rrset,
                                           result.flags)),
-        rrset_(result.rrset), found_node_(result.found_node)
+        finder_(finder), rrset_(result.rrset), found_node_(result.found_node)
     {}
 
 protected:
+    virtual ZoneFinder* getFinder() { return (&finder_); }
+
+    virtual const std::vector<isc::dns::ConstRRsetPtr>* getAllRRsets() const {
+        return (NULL);
+    }
+
     virtual void getAdditionalImpl(const vector<RRType>& requested_types,
                                    vector<ConstRRsetPtr>& result)
     {
@@ -866,6 +871,7 @@ private:
         }
     }
 
+    ZoneFinder& finder_;
     const ConstRBNodeRRsetPtr rrset_;
     const DomainNode* const found_node_;
 };
diff --git a/src/lib/datasrc/sqlite3_accessor.cc b/src/lib/datasrc/sqlite3_accessor.cc
index 672121e..68d6554 100644
--- a/src/lib/datasrc/sqlite3_accessor.cc
+++ b/src/lib/datasrc/sqlite3_accessor.cc
@@ -44,7 +44,7 @@ namespace {
 // program may not be taking advantage of features (possibly performance
 // improvements) added to the database.
 const int SQLITE_SCHEMA_MAJOR_VERSION = 2;
-const int SQLITE_SCHEMA_MINOR_VERSION = 0;
+const int SQLITE_SCHEMA_MINOR_VERSION = 1;
 }
 
 namespace isc {
@@ -65,19 +65,20 @@ enum StatementID {
     DEL_ZONE_RECORDS = 6,
     ADD_RECORD = 7,
     DEL_RECORD = 8,
-    ITERATE = 9,
-    FIND_PREVIOUS = 10,
-    ADD_RECORD_DIFF = 11,
-    LOW_DIFF_ID = 12,
-    HIGH_DIFF_ID = 13,
-    DIFF_RECS = 14,
-    NSEC3 = 15,
-    NSEC3_PREVIOUS = 16,
-    NSEC3_LAST = 17,
-    ADD_NSEC3_RECORD = 18,
-    DEL_ZONE_NSEC3_RECORDS = 19,
-    DEL_NSEC3_RECORD = 20,
-    NUM_STATEMENTS = 21
+    ITERATE_RECORDS = 9,
+    ITERATE_NSEC3 = 10,
+    FIND_PREVIOUS = 11,
+    ADD_RECORD_DIFF = 12,
+    LOW_DIFF_ID = 13,
+    HIGH_DIFF_ID = 14,
+    DIFF_RECS = 15,
+    NSEC3 = 16,
+    NSEC3_PREVIOUS = 17,
+    NSEC3_LAST = 18,
+    ADD_NSEC3_RECORD = 19,
+    DEL_ZONE_NSEC3_RECORDS = 20,
+    DEL_NSEC3_RECORD = 21,
+    NUM_STATEMENTS = 22
 };
 
 const char* const text_statements[NUM_STATEMENTS] = {
@@ -102,19 +103,17 @@ const char* const text_statements[NUM_STATEMENTS] = {
         "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
     "DELETE FROM records WHERE zone_id=?1 AND name=?2 " // DEL_RECORD
         "AND rdtype=?3 AND rdata=?4",
-    // The following iterates the whole zone. As the NSEC3 records
-    // (and corresponding RRSIGs) live in separate table, we need to
-    // take both of them. As the RRSIGs are for NSEC3s in the other
-    // table, we can easily hardcode the sigtype.
-    //
-    // The extra column is so we can order it by rname. This is to
-    // preserve the previous order, mostly for tests.
-    // TODO: Is it possible to get rid of the ordering?
-    "SELECT rdtype, ttl, sigtype, rdata, name, rname FROM records " // ITERATE
-        "WHERE zone_id = ?1 "
-        "UNION "
-        "SELECT rdtype, ttl, \"NSEC3\", rdata, owner, owner FROM nsec3 "
-        "WHERE zone_id = ?1 ORDER by rname, rdtype",
+
+    // ITERATE_RECORDS:
+    // The following iterates the whole zone in the records table.
+    "SELECT rdtype, ttl, sigtype, rdata, name FROM records "
+        "WHERE zone_id = ?1 ORDER BY rname, rdtype",
+
+    // ITERATE_NSEC3:
+    // The following iterates the whole zone in the nsec3 table. As the
+    // RRSIGs are for NSEC3s, we can hardcode the sigtype.
+    "SELECT rdtype, ttl, \"NSEC3\", rdata, owner FROM nsec3 "
+        "WHERE zone_id = ?1 ORDER BY hash, rdtype",
     /*
      * This one looks for previous name with NSEC record. It is done by
      * using the reversed name. The NSEC is checked because we need to
@@ -332,7 +331,7 @@ public:
 const char* const SCHEMA_LIST[] = {
     "CREATE TABLE schema_version (version INTEGER NOT NULL, "
         "minor INTEGER NOT NULL DEFAULT 0)",
-    "INSERT INTO schema_version VALUES (2, 0)",
+    "INSERT INTO schema_version VALUES (2, 1)",
     "CREATE TABLE zones (id INTEGER PRIMARY KEY, "
     "name TEXT NOT NULL COLLATE NOCASE, "
     "rdclass TEXT NOT NULL COLLATE NOCASE DEFAULT 'IN', "
@@ -358,6 +357,7 @@ const char* const SCHEMA_LIST[] = {
         "ttl INTEGER NOT NULL, rdtype TEXT NOT NULL COLLATE NOCASE, "
         "rdata TEXT NOT NULL)",
     "CREATE INDEX nsec3_byhash ON nsec3 (hash)",
+    "CREATE INDEX nsec3_byhash_and_rdtype ON nsec3 (hash, rdtype)",
     "CREATE TABLE diffs (id INTEGER PRIMARY KEY, "
         "zone_id INTEGER NOT NULL, "
         "version INTEGER NOT NULL, "
@@ -642,11 +642,21 @@ public:
         iterator_type_(ITT_ALL),
         accessor_(accessor),
         statement_(NULL),
+        statement2_(NULL),
+        rc_(SQLITE_OK),
+        rc2_(SQLITE_OK),
         name_("")
     {
-        // We create the statement now and then just keep getting data from it
+        // We create the statements now and then just keep getting data
+        // from them.
         statement_ = prepare(accessor->dbparameters_->db_,
-                             text_statements[ITERATE]);
+                             text_statements[ITERATE_NSEC3]);
+        bindZoneId(id);
+
+        std::swap(statement_, statement2_);
+
+        statement_ = prepare(accessor->dbparameters_->db_,
+                             text_statements[ITERATE_RECORDS]);
         bindZoneId(id);
     }
 
@@ -665,6 +675,9 @@ public:
         iterator_type_(qtype == QT_NSEC3 ? ITT_NSEC3 : ITT_NAME),
         accessor_(accessor),
         statement_(NULL),
+        statement2_(NULL),
+        rc_(SQLITE_OK),
+        rc2_(SQLITE_OK),
         name_(name)
     {
         // Choose the statement text depending on the query type, and
@@ -703,29 +716,35 @@ public:
         // If there's another row, get it
         // If finalize has been called (e.g. when previous getNext() got
         // SQLITE_DONE), directly return false
-        if (statement_ == NULL) {
-            return false;
-        }
-        const int rc(sqlite3_step(statement_));
-        if (rc == SQLITE_ROW) {
-            // For both types, we copy the first four columns
-            copyColumn(data, TYPE_COLUMN);
-            copyColumn(data, TTL_COLUMN);
-            // The NSEC3 lookup does not provide the SIGTYPE, it is not
-            // necessary and not contained in the table.
-            if (iterator_type_ != ITT_NSEC3) {
-                copyColumn(data, SIGTYPE_COLUMN);
+        while (statement_ != NULL) {
+            rc_ = sqlite3_step(statement_);
+            if (rc_ == SQLITE_ROW) {
+                // For both types, we copy the first four columns
+                copyColumn(data, TYPE_COLUMN);
+                copyColumn(data, TTL_COLUMN);
+                // The NSEC3 lookup does not provide the SIGTYPE, it is not
+                // necessary and not contained in the table.
+                if (iterator_type_ != ITT_NSEC3) {
+                    copyColumn(data, SIGTYPE_COLUMN);
+                }
+                copyColumn(data, RDATA_COLUMN);
+                // Only copy Name if we are iterating over every record
+                if (iterator_type_ == ITT_ALL) {
+                    copyColumn(data, NAME_COLUMN);
+                }
+                return (true);
+            } else if (rc_ != SQLITE_DONE) {
+                isc_throw(DataSourceError,
+                          "Unexpected failure in sqlite3_step: " <<
+                          sqlite3_errmsg(accessor_->dbparameters_->db_));
             }
-            copyColumn(data, RDATA_COLUMN);
-            // Only copy Name if we are iterating over every record
-            if (iterator_type_ == ITT_ALL) {
-                copyColumn(data, NAME_COLUMN);
+            // We are done with statement_. If statement2_ has not been
+            // used yet, try that one now.
+            if ((statement2_ == NULL) || (rc2_ != SQLITE_OK)) {
+                break;
             }
-            return (true);
-        } else if (rc != SQLITE_DONE) {
-            isc_throw(DataSourceError,
-                      "Unexpected failure in sqlite3_step: " <<
-                      sqlite3_errmsg(accessor_->dbparameters_->db_));
+            std::swap(statement_, statement2_);
+            std::swap(rc_, rc2_);
         }
         finalize();
         return (false);
@@ -771,13 +790,22 @@ private:
     }
 
     void finalize() {
-        sqlite3_finalize(statement_);
-        statement_ = NULL;
+        if (statement_ != NULL) {
+             sqlite3_finalize(statement_);
+             statement_ = NULL;
+        }
+        if (statement2_ != NULL) {
+             sqlite3_finalize(statement2_);
+             statement2_ = NULL;
+        }
     }
 
     const IteratorType iterator_type_;
     boost::shared_ptr<const SQLite3Accessor> accessor_;
     sqlite3_stmt* statement_;
+    sqlite3_stmt* statement2_;
+    int rc_;
+    int rc2_;
     const std::string name_;
 };
 
diff --git a/src/lib/datasrc/tests/memory/Makefile.am b/src/lib/datasrc/tests/memory/Makefile.am
index 00d5594..37e9043 100644
--- a/src/lib/datasrc/tests/memory/Makefile.am
+++ b/src/lib/datasrc/tests/memory/Makefile.am
@@ -32,12 +32,14 @@ run_unittests_SOURCES += ../../tests/faked_nsec3.h ../../tests/faked_nsec3.cc
 run_unittests_SOURCES += memory_segment_test.h
 run_unittests_SOURCES += segment_object_holder_unittest.cc
 run_unittests_SOURCES += memory_client_unittest.cc
+run_unittests_SOURCES += zone_table_segment_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
 
 run_unittests_LDADD = $(top_builddir)/src/lib/datasrc/libb10-datasrc.la
 run_unittests_LDADD += $(top_builddir)/src/lib/dns/libb10-dns++.la
+run_unittests_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
 run_unittests_LDADD += $(top_builddir)/src/lib/testutils/libb10-testutils.la
diff --git a/src/lib/datasrc/tests/memory/domaintree_unittest.cc b/src/lib/datasrc/tests/memory/domaintree_unittest.cc
index cb16e02..45e256a 100644
--- a/src/lib/datasrc/tests/memory/domaintree_unittest.cc
+++ b/src/lib/datasrc/tests/memory/domaintree_unittest.cc
@@ -256,8 +256,8 @@ TEST_F(DomainTreeTest, subTreeRoot) {
 
     // "g.h" is not a subtree root
     EXPECT_EQ(TestDomainTree::EXACTMATCH,
-              dtree_expose_empty_node.find(Name("g.h"), &dtnode));
-    EXPECT_FALSE(dtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
+              dtree_expose_empty_node.find(Name("g.h"), &cdtnode));
+    EXPECT_FALSE(cdtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
 
     // fission the node "g.h"
     EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
@@ -270,8 +270,8 @@ TEST_F(DomainTreeTest, subTreeRoot) {
 
     // "g.h" should be a subtree root now.
     EXPECT_EQ(TestDomainTree::EXACTMATCH,
-              dtree_expose_empty_node.find(Name("g.h"), &dtnode));
-    EXPECT_TRUE(dtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
+              dtree_expose_empty_node.find(Name("g.h"), &cdtnode));
+    EXPECT_TRUE(cdtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
 }
 
 TEST_F(DomainTreeTest, additionalNodeFission) {
@@ -286,8 +286,8 @@ TEST_F(DomainTreeTest, additionalNodeFission) {
 
     // "t.0" is not a subtree root
     EXPECT_EQ(TestDomainTree::EXACTMATCH,
-              dtree_expose_empty_node.find(Name("t.0"), &dtnode));
-    EXPECT_FALSE(dtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
+              dtree_expose_empty_node.find(Name("t.0"), &cdtnode));
+    EXPECT_FALSE(cdtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
 
     // fission the node "t.0"
     EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
@@ -300,8 +300,8 @@ TEST_F(DomainTreeTest, additionalNodeFission) {
 
     // "t.0" should be a subtree root now.
     EXPECT_EQ(TestDomainTree::EXACTMATCH,
-              dtree_expose_empty_node.find(Name("t.0"), &dtnode));
-    EXPECT_TRUE(dtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
+              dtree_expose_empty_node.find(Name("t.0"), &cdtnode));
+    EXPECT_TRUE(cdtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
 }
 
 TEST_F(DomainTreeTest, findName) {
@@ -328,10 +328,10 @@ TEST_F(DomainTreeTest, findName) {
     EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               dtree_expose_empty_node.find(Name("m.d.e.f"), &cdtnode));
 
-    // find dtnode
+    // find cdtnode
     EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("q.w.y.d.e.f"),
-                                                   &dtnode));
-    EXPECT_EQ(Name("q"), dtnode->getName());
+                                                   &cdtnode));
+    EXPECT_EQ(Name("q"), cdtnode->getName());
 }
 
 TEST_F(DomainTreeTest, findError) {
@@ -411,11 +411,12 @@ performCallbackTest(TestDomainTree& dtree,
                                                         Name("example"),
                                                         &parentdtnode));
     // the child/parent nodes shouldn't "inherit" the callback flag.
-    // "dtnode" may be invalid due to the insertion, so we need to re-find
-    // it.
+    // "dtnode" should still validly point to "callback.example", but we
+    // explicitly confirm it.
     EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("callback.example"),
-                                                   &dtnode));
-    EXPECT_TRUE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
+                                                     &cdtnode));
+    ASSERT_EQ(dtnode, cdtnode);
+    EXPECT_TRUE(cdtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
     EXPECT_FALSE(subdtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
     EXPECT_FALSE(parentdtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
 
diff --git a/src/lib/datasrc/tests/memory/memory_client_unittest.cc b/src/lib/datasrc/tests/memory/memory_client_unittest.cc
index 4a34bad..295c44c 100644
--- a/src/lib/datasrc/tests/memory/memory_client_unittest.cc
+++ b/src/lib/datasrc/tests/memory/memory_client_unittest.cc
@@ -22,7 +22,6 @@
 #include <dns/nsec3hash.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
-#include <dns/rrsetlist.h>
 #include <dns/rrttl.h>
 #include <dns/masterload.h>
 
@@ -547,6 +546,8 @@ TEST_F(MemoryClientTest, loadRRSIGs) {
     EXPECT_EQ(1, client_->getZoneCount());
 }
 
+#if 0 // FIXME
+
 TEST_F(MemoryClientTest, loadRRSIGsRdataMixedCoveredTypes) {
     client_->load(Name("example.org"),
                   TEST_DATA_DIR "/example.org-rrsigs.zone");
@@ -570,6 +571,8 @@ TEST_F(MemoryClientTest, loadRRSIGsRdataMixedCoveredTypes) {
     // Teardown checks for memory segment leaks
 }
 
+#endif
+
 TEST_F(MemoryClientTest, getZoneCount) {
     EXPECT_EQ(0, client_->getZoneCount());
     client_->load(Name("example.org"), TEST_DATA_DIR "/example.org-empty.zone");
@@ -659,6 +662,8 @@ TEST_F(MemoryClientTest, getIteratorGetSOAThrowsNotImplemented) {
     EXPECT_THROW(iterator->getSOA(), isc::NotImplemented);
 }
 
+#if 0 // FIXME
+
 TEST_F(MemoryClientTest, addRRsetToNonExistentZoneThrows) {
     // The zone "example.org" doesn't exist, so we can't add an RRset to
     // it.
@@ -728,6 +733,8 @@ TEST_F(MemoryClientTest, add) {
     EXPECT_EQ(ConstRRsetPtr(), iterator->getNextRRset());
 }
 
+#endif
+
 TEST_F(MemoryClientTest, findZoneData) {
     client_->load(Name("example.org"),
                   TEST_DATA_DIR "/example.org-rrsigs.zone");
@@ -778,4 +785,5 @@ TEST_F(MemoryClientTest, getJournalReaderNotImplemented) {
     EXPECT_THROW(client_->getJournalReader(Name("."), 0, 0),
                  isc::NotImplemented);
 }
+
 }
diff --git a/src/lib/datasrc/tests/memory/zone_data_unittest.cc b/src/lib/datasrc/tests/memory/zone_data_unittest.cc
index d15fe8b..3c28cec 100644
--- a/src/lib/datasrc/tests/memory/zone_data_unittest.cc
+++ b/src/lib/datasrc/tests/memory/zone_data_unittest.cc
@@ -108,7 +108,7 @@ void
 checkFindRdataSet(const ZoneTree& tree, const Name& name, RRType type,
                   const RdataSet* expected_set)
 {
-    ZoneNode* node = NULL;
+    const ZoneNode* node = NULL;
     tree.find(name, &node);
     ASSERT_NE(static_cast<ZoneNode*>(NULL), node);
     EXPECT_EQ(expected_set, RdataSet::find(node->getData(), type));
diff --git a/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc b/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc
new file mode 100644
index 0000000..6bdd737
--- /dev/null
+++ b/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc
@@ -0,0 +1,83 @@
+// Copyright (C) 2012  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 <datasrc/memory/zone_table_segment.h>
+#include <gtest/gtest.h>
+
+using namespace isc::datasrc::memory;
+using namespace isc::data;
+using namespace isc::util;
+using namespace std;
+
+namespace {
+
+class ZoneTableSegmentTest : public ::testing::Test {
+protected:
+    ZoneTableSegmentTest() :
+        config_(Element::fromJSON("{}")),
+        segment_(ZoneTableSegment::create((*config_.get())))
+    {}
+
+    ~ZoneTableSegmentTest() {
+        if (segment_ != NULL) {
+            ZoneTableSegment::destroy(segment_);
+        }
+    }
+
+    void TearDown() {
+        // Catch any future leaks here.
+        const MemorySegment& mem_sgmt = segment_->getMemorySegment();
+        EXPECT_TRUE(mem_sgmt.allMemoryDeallocated());
+
+        ZoneTableSegment::destroy(segment_);
+        segment_ = NULL;
+    }
+
+    const ElementPtr config_;
+    ZoneTableSegment* segment_;
+};
+
+
+TEST_F(ZoneTableSegmentTest, create) {
+    // By default, a local zone table segment is created.
+    EXPECT_NE(static_cast<void*>(NULL), segment_);
+}
+
+// Helper function to check const and non-const methods.
+template <typename TS, typename TH, typename TT>
+void
+testGetHeader(ZoneTableSegment* segment) {
+    TH& header = static_cast<TS*>(segment)->getHeader();
+
+    // The zone table is unset.
+    TT* table = header.getTable();
+    EXPECT_EQ(static_cast<void*>(NULL), table);
+}
+
+TEST_F(ZoneTableSegmentTest, getHeader) {
+    // non-const version.
+    testGetHeader<ZoneTableSegment, ZoneTableHeader, ZoneTable>(segment_);
+
+    // const version.
+    testGetHeader<const ZoneTableSegment, const ZoneTableHeader,
+                  const ZoneTable>(segment_);
+}
+
+TEST_F(ZoneTableSegmentTest, getMemorySegment) {
+    // This doesn't do anything fun except test the API.
+    MemorySegment& mem_sgmt = segment_->getMemorySegment();
+    EXPECT_TRUE(mem_sgmt.allMemoryDeallocated());
+}
+
+} // anonymous namespace
diff --git a/src/lib/datasrc/tests/memory/zone_table_unittest.cc b/src/lib/datasrc/tests/memory/zone_table_unittest.cc
index a8ee614..80f2a6e 100644
--- a/src/lib/datasrc/tests/memory/zone_table_unittest.cc
+++ b/src/lib/datasrc/tests/memory/zone_table_unittest.cc
@@ -24,6 +24,7 @@
 #include <datasrc/result.h>
 #include <datasrc/memory/zone_data.h>
 #include <datasrc/memory/zone_table.h>
+#include <datasrc/memory/segment_object_holder.h>
 
 #include <gtest/gtest.h>
 
@@ -32,6 +33,7 @@
 using namespace isc::dns;
 using namespace isc::datasrc;
 using namespace isc::datasrc::memory;
+using namespace isc::datasrc::memory::detail;
 
 namespace {
 class ZoneTableTest : public ::testing::Test {
@@ -68,46 +70,89 @@ TEST_F(ZoneTableTest, create) {
 }
 
 TEST_F(ZoneTableTest, addZone) {
+    // It doesn't accept empty (NULL) zones
+    EXPECT_THROW(zone_table->addZone(mem_sgmt_, zclass_, zname1, NULL),
+                 isc::BadValue);
+
+    SegmentObjectHolder<ZoneData, RRClass> holder1(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, zname1), zclass_);
+    const ZoneData* data1(holder1.get());
     // Normal successful case.
-    const ZoneTable::AddResult result1 =
-        zone_table->addZone(mem_sgmt_, zclass_, zname1);
+    const ZoneTable::AddResult result1(zone_table->addZone(mem_sgmt_, zclass_,
+                                                           zname1,
+                                                           holder1.release()));
     EXPECT_EQ(result::SUCCESS, result1.code);
+    EXPECT_EQ(static_cast<const ZoneData*>(NULL), result1.zone_data);
+    // It got released by it
+    EXPECT_EQ(static_cast<const ZoneData*>(NULL), holder1.get());
 
     // Duplicate add doesn't replace the existing data.
-    EXPECT_EQ(result::EXIST, zone_table->addZone(mem_sgmt_, zclass_,
-                                                 zname1).code);
-    EXPECT_EQ(result1.zone_data,
-              zone_table->addZone(mem_sgmt_, zclass_, zname1).zone_data);
+    SegmentObjectHolder<ZoneData, RRClass> holder2(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, zname1), zclass_);
+    const ZoneTable::AddResult result2(zone_table->addZone(mem_sgmt_, zclass_,
+                                                           zname1,
+                                                           holder2.release()));
+    EXPECT_EQ(result::EXIST, result2.code);
+    // The old one gets out
+    EXPECT_EQ(data1, result2.zone_data);
+    // It releases this one even when we replace the old zone
+    EXPECT_EQ(static_cast<const ZoneData*>(NULL), holder2.get());
+    // We need to release the old one manually
+    ZoneData::destroy(mem_sgmt_, result2.zone_data, zclass_);
+
+    SegmentObjectHolder<ZoneData, RRClass> holder3(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, Name("EXAMPLE.COM")),
+                                    zclass_);
     // names are compared in a case insensitive manner.
-    EXPECT_EQ(result::EXIST, zone_table->addZone(mem_sgmt_, zclass_,
-                                                 Name("EXAMPLE.COM")).code);
+    const ZoneTable::AddResult result3(zone_table->addZone(mem_sgmt_, zclass_,
+                                                           Name("EXAMPLE.COM"),
+                                                           holder3.release()));
+    EXPECT_EQ(result::EXIST, result3.code);
+    ZoneData::destroy(mem_sgmt_, result3.zone_data, zclass_);
     // Add some more different ones.  Should just succeed.
+    SegmentObjectHolder<ZoneData, RRClass> holder4(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, zname2), zclass_);
     EXPECT_EQ(result::SUCCESS,
-              zone_table->addZone(mem_sgmt_, zclass_, zname2).code);
+              zone_table->addZone(mem_sgmt_, zclass_, zname2,
+                                  holder4.release()).code);
+    SegmentObjectHolder<ZoneData, RRClass> holder5(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, zname3), zclass_);
     EXPECT_EQ(result::SUCCESS,
-              zone_table->addZone(mem_sgmt_, zclass_, zname3).code);
+              zone_table->addZone(mem_sgmt_, zclass_, zname3,
+                                  holder5.release()).code);
 
     // Have the memory segment throw an exception in extending the internal
     // tree.  It still shouldn't cause memory leak (which would be detected
     // in TearDown()).
-    mem_sgmt_.setThrowCount(2);
-    EXPECT_THROW(zone_table->addZone(mem_sgmt_, zclass_, Name("example.org")),
+    SegmentObjectHolder<ZoneData, RRClass> holder6(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, Name("example.org")), zclass_);
+    mem_sgmt_.setThrowCount(1);
+    EXPECT_THROW(zone_table->addZone(mem_sgmt_, zclass_, Name("example.org"),
+                                     holder6.release()),
                  std::bad_alloc);
 }
 
 TEST_F(ZoneTableTest, findZone) {
-    const ZoneTable::AddResult add_result1 =
-        zone_table->addZone(mem_sgmt_, zclass_, zname1);
-    EXPECT_EQ(result::SUCCESS, add_result1.code);
+    SegmentObjectHolder<ZoneData, RRClass> holder1(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, zname1), zclass_);
+    ZoneData* zone_data = holder1.get();
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zclass_, zname1,
+                                                   holder1.release()).code);
+    SegmentObjectHolder<ZoneData, RRClass> holder2(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, zname2), zclass_);
     EXPECT_EQ(result::SUCCESS,
-              zone_table->addZone(mem_sgmt_, zclass_, zname2).code);
+              zone_table->addZone(mem_sgmt_, zclass_, zname2,
+                                  holder2.release()).code);
+    SegmentObjectHolder<ZoneData, RRClass> holder3(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, zname3), zclass_);
     EXPECT_EQ(result::SUCCESS,
-              zone_table->addZone(mem_sgmt_, zclass_, zname3).code);
+              zone_table->addZone(mem_sgmt_, zclass_, zname3,
+                                  holder3.release()).code);
 
     const ZoneTable::FindResult find_result1 =
         zone_table->findZone(Name("example.com"));
     EXPECT_EQ(result::SUCCESS, find_result1.code);
-    EXPECT_EQ(add_result1.zone_data, find_result1.zone_data);
+    EXPECT_EQ(zone_data, find_result1.zone_data);
 
     EXPECT_EQ(result::NOTFOUND,
               zone_table->findZone(Name("example.org")).code);
@@ -118,14 +163,17 @@ TEST_F(ZoneTableTest, findZone) {
     // and the code should be PARTIALMATCH.
     EXPECT_EQ(result::PARTIALMATCH,
               zone_table->findZone(Name("www.example.com")).code);
-    EXPECT_EQ(add_result1.zone_data,
+    EXPECT_EQ(zone_data,
               zone_table->findZone(Name("www.example.com")).zone_data);
 
     // make sure the partial match is indeed the longest match by adding
     // a zone with a shorter origin and query again.
+    SegmentObjectHolder<ZoneData, RRClass> holder4(
+        mem_sgmt_, ZoneData::create(mem_sgmt_, Name("com")), zclass_);
     EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zclass_,
-                                                   Name("com")).code);
-    EXPECT_EQ(add_result1.zone_data,
+                                                   Name("com"),
+                                                   holder4.release()).code);
+    EXPECT_EQ(zone_data,
               zone_table->findZone(Name("www.example.com")).zone_data);
 }
 }
diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
index 958c9e1..5223d83 100644
--- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc
+++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
@@ -22,7 +22,6 @@
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
-#include <dns/rrsetlist.h>
 #include <dns/rrttl.h>
 #include <dns/masterload.h>
 
diff --git a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
index 718d29b..100a0dd 100644
--- a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
+++ b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc
@@ -191,6 +191,11 @@ TEST_F(SQLite3AccessorTest, iterator) {
     checkRR(context, "sub.example.org.", "3600", "NS", "ns.sub.example.org.");
     checkRR(context, "ns.sub.example.org.", "3600", "A", "192.0.2.101");
     checkRR(context, "www.example.org.", "3600", "A", "192.0.2.1");
+    checkRR(context, "ns3.example.org.", "3600", "NSEC3",
+            "1 1 12 aabbccdd 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR A RRSIG");
+    checkRR(context, "ns3.example.org.", "3600", "RRSIG",
+            "NSEC3 5 3 3600 20000101000000 20000201000000 "
+            "12345 ns3.example.org. FAKEFAKEFAKE");
 
     // Check there's no other
     EXPECT_FALSE(context->getNext(data));
@@ -665,16 +670,16 @@ TEST_F(SQLite3Create, creationtest) {
 TEST_F(SQLite3Create, emptytest) {
     ASSERT_FALSE(isReadable(SQLITE_NEW_DBFILE));
 
-    // open one manualle
+    // open one manually
     sqlite3* db;
     ASSERT_EQ(SQLITE_OK, sqlite3_open(SQLITE_NEW_DBFILE, &db));
 
-    // empty, but not locked, so creating it now should work
+    // empty, but not locked, so creating another accessor should work
     SQLite3Accessor accessor2(SQLITE_NEW_DBFILE, "IN");
 
     sqlite3_close(db);
 
-    // should work now that we closed it
+    // should still work now that we closed it
     SQLite3Accessor accessor3(SQLITE_NEW_DBFILE, "IN");
 }
 
@@ -692,8 +697,10 @@ TEST_F(SQLite3Create, lockedtest) {
 
     sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
 
-    // should work now that we closed it
+    // should work now that the transaction has been rolled back
     SQLite3Accessor accessor3(SQLITE_NEW_DBFILE, "IN");
+
+    ASSERT_EQ(SQLITE_OK, sqlite3_close(db));
 }
 
 TEST_F(SQLite3AccessorTest, clone) {
diff --git a/src/lib/datasrc/tests/testdata/contexttest.zone b/src/lib/datasrc/tests/testdata/contexttest.zone
index a39649d..0c1393c 100644
--- a/src/lib/datasrc/tests/testdata/contexttest.zone
+++ b/src/lib/datasrc/tests/testdata/contexttest.zone
@@ -1,9 +1,10 @@
 ;; test zone file used for ZoneFinderContext tests.
 ;; RRSIGs are (obviouslly) faked ones for testing.
 
-example.org. 3600 IN SOA	ns1.example.org. bugs.x.w.example.org. 71 3600 300 3600000 3600
+example.org. 3600 IN SOA	ns1.example.org. bugs.x.w.example.org. 74 3600 300 3600000 3600
 example.org.			      3600 IN NS	ns1.example.org.
 example.org.			      3600 IN NS	ns2.example.org.
+example.org.			      3600 IN RRSIG	NS 7 3 3600 20150420235959 20051021000000 40430 example.org. FAKEFAKEFAKE
 example.org.			      3600 IN MX	1 mx1.example.org.
 example.org.			      3600 IN MX	2 mx2.example.org.
 example.org.			      3600 IN MX	3 mx.a.example.org.
diff --git a/src/lib/datasrc/tests/testdata/example.org.sqlite3 b/src/lib/datasrc/tests/testdata/example.org.sqlite3
index c7388ff..c799d2e 100644
Binary files a/src/lib/datasrc/tests/testdata/example.org.sqlite3 and b/src/lib/datasrc/tests/testdata/example.org.sqlite3 differ
diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h
index 2330412..36a1cff 100644
--- a/src/lib/datasrc/zone.h
+++ b/src/lib/datasrc/zone.h
@@ -168,48 +168,25 @@ public:
     /// can define a derived class of the base Context and override the
     /// specific virtual method.
     ///
+    /// This base class defines these common protected methods along with
+    /// some helper pure virtual methods that would be necessary for the
+    /// common methods.  If a derived class wants to use the common version
+    /// of the protected method, it needs to provide expected result through
+    /// their implementation of the pure virtual methods.
+    ///
     /// This class object is generally expected to be associated with the
     /// ZoneFinder that originally performed the \c find() call, and expects
     /// the finder is valid throughout the lifetime of this object.  It's
     /// caller's responsibility to ensure that assumption.
     class Context {
     public:
-        /// \brief The constructor for the normal find call.
-        ///
-        /// This constructor is expected to be called from the \c find()
-        /// method when it constructs the return value.
+        /// \brief The constructor.
         ///
-        /// \param finder The ZoneFinder on which find() is called.
         /// \param options The find options specified for the find() call.
         /// \param result The result of the find() call.
-        Context(ZoneFinder& finder, FindOptions options,
-                const ResultContext& result) :
-            code(result.code), rrset(result.rrset),
-            finder_(finder), flags_(result.flags), options_(options)
-        {}
-
-        /// \brief The constructor for the normal findAll call.
-        ///
-        /// This constructor is expected to be called from the \c findAll()
-        /// method when it constructs the return value.
-        ///
-        /// It copies the vector that is to be returned to the caller of
-        /// \c findAll() for possible subsequent use.  Note that it cannot
-        /// simply hold a reference to the vector because the caller may
-        /// alter it after the \c findAll() call.
-        ///
-        /// \param finder The ZoneFinder on which findAll() is called.
-        /// \param options The find options specified for the findAll() call.
-        /// \param result The result of the findAll() call (whose rrset is
-        ///        expected to be NULL).
-        /// \param all_set Reference to the vector given by the caller of
-        ///       \c findAll(), storing the RRsets to be returned.
-        Context(ZoneFinder& finder, FindOptions options,
-                const ResultContext& result,
-                const std::vector<isc::dns::ConstRRsetPtr> &all_set) :
+        Context(FindOptions options, const ResultContext& result) :
             code(result.code), rrset(result.rrset),
-            finder_(finder), flags_(result.flags), options_(options),
-            all_set_(all_set)
+            flags_(result.flags), options_(options)
         {}
 
         /// \brief The destructor.
@@ -292,21 +269,108 @@ public:
         }
 
     protected:
+        /// \brief Return the \c ZoneFinder that created this \c Context.
+        ///
+        /// A derived class implementation can return NULL if it defines
+        /// other protected methods that require a non NULL result from
+        /// this method.  Otherwise it must return a valid, non NULL pointer
+        /// to the \c ZoneFinder object.
+        ///
+        /// When returning non NULL, the ownership of the pointed object
+        /// was not transferred to the caller; it cannot be assumed to be
+        /// valid after the originating \c Context object is destroyed.
+        /// Also, the caller must not try to delete the returned object.
+        virtual ZoneFinder* getFinder() = 0;
+
+        /// \brief Return a vector of RRsets corresponding to findAll() result.
+        ///
+        /// This method returns a set of RRsets that correspond to the
+        /// returned RRsets to a prior \c findAll() call.
+        ///
+        /// A derived class implementation can return NULL if it defines
+        /// other protected methods that require a non NULL result from
+        /// this method.  Otherwise it must return a valid, non NULL pointer
+        /// to a vector that correspond to the expected set of RRsets.
+        ///
+        /// When returning non NULL, the ownership of the pointed object
+        /// was not transferred to the caller; it cannot be assumed to be
+        /// valid after the originating \c Context object is destroyed.
+        /// Also, the caller must not try to delete the returned object.
+        virtual const std::vector<isc::dns::ConstRRsetPtr>*
+        getAllRRsets() const = 0;
+
         /// \brief Actual implementation of getAdditional().
         ///
         /// This base class defines a default implementation that can be
         /// used for any type of data sources.  A data source implementation
         /// can override it.
+        ///
+        /// The default version of this implementation requires both
+        /// \c getFinder() and \c getAllRRsets() return valid results.
         virtual void getAdditionalImpl(
             const std::vector<isc::dns::RRType>& requested_types,
             std::vector<isc::dns::ConstRRsetPtr>& result);
 
     private:
-        ZoneFinder& finder_;
         const FindResultFlags flags_;
     protected:
         const FindOptions options_;
+    };
+
+    /// \brief Generic ZoneFinder context that works for all implementations.
+    ///
+    /// This is a concrete derived class of \c ZoneFinder::Context that
+    /// only use the generic (default) versions of the protected methods
+    /// and therefore work for any data source implementation.
+    ///
+    /// A data source implementation can use this class to create a
+    /// \c Context object as a return value of \c find() or \c findAll()
+    /// method if it doesn't have to optimize specific protected methods.
+    class GenericContext : public Context {
+    public:
+        /// \brief The constructor for the normal find call.
+        ///
+        /// This constructor is expected to be called from the \c find()
+        /// method when it constructs the return value.
+        ///
+        /// \param finder The ZoneFinder on which find() is called.
+        /// \param options See the \c Context class.
+        /// \param result See the \c Context class.
+        GenericContext(ZoneFinder& finder, FindOptions options,
+                       const ResultContext& result) :
+            Context(options, result), finder_(finder)
+        {}
+
+        /// \brief The constructor for the normal findAll call.
+        ///
+        /// This constructor is expected to be called from the \c findAll()
+        /// method when it constructs the return value.
+        ///
+        /// It copies the vector that is to be returned to the caller of
+        /// \c findAll() for possible subsequent use.  Note that it cannot
+        /// simply hold a reference to the vector because the caller may
+        /// alter it after the \c findAll() call.
+        ///
+        /// \param finder The ZoneFinder on which findAll() is called.
+        /// \param options See the \c Context class.
+        /// \param result See the \c Context class.
+        /// \param all_set Reference to the vector given by the caller of
+        ///       \c findAll(), storing the RRsets to be returned.
+        GenericContext(ZoneFinder& finder, FindOptions options,
+                       const ResultContext& result,
+                       const std::vector<isc::dns::ConstRRsetPtr>& all_set) :
+            Context(options, result), finder_(finder), all_set_(all_set)
+        {}
+
+    protected:
+        virtual ZoneFinder* getFinder() { return (&finder_); }
+        virtual const std::vector<isc::dns::ConstRRsetPtr>*
+        getAllRRsets() const {
+            return (&all_set_);
+        }
+
     private:
+        ZoneFinder& finder_;
         std::vector<isc::dns::ConstRRsetPtr> all_set_;
     };
 
diff --git a/src/lib/datasrc/zone_finder_context.cc b/src/lib/datasrc/zone_finder_context.cc
index 7913d71..482eb65 100644
--- a/src/lib/datasrc/zone_finder_context.cc
+++ b/src/lib/datasrc/zone_finder_context.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <exceptions/exceptions.h>
+
 #include <dns/rdata.h>
 #include <dns/rrset.h>
 #include <dns/rrtype.h>
@@ -87,13 +89,22 @@ ZoneFinder::Context::getAdditionalImpl(const vector<RRType>& requested_types,
 {
     // If rrset is non NULL, it should have been SUCCESS/DELEGATION; otherwise
     // we should have responded to type ANY query.
+    ZoneFinder* finder = getFinder();
+    if (finder == NULL) {
+        // This is a bug of the derived class implementation.
+        isc_throw(isc::Unexpected, "NULL ZoneFinder in finder Context");
+    }
     if (rrset) {
-        getAdditionalForRRset(finder_, *rrset, requested_types, result,
+        getAdditionalForRRset(*finder, *rrset, requested_types, result,
                               options_);
         return;
     }
-    BOOST_FOREACH(ConstRRsetPtr rrset_in_set, all_set_) {
-        getAdditionalForRRset(finder_, *rrset_in_set, requested_types, result,
+    const vector<ConstRRsetPtr>* all_sets = getAllRRsets();
+    if (all_sets == NULL) {     // bug of the derived class implementation.
+        isc_throw(isc::Unexpected, "All RRsets is NULL in finder Context");
+    }
+    BOOST_FOREACH(ConstRRsetPtr rrset_in_set, *getAllRRsets()) {
+        getAdditionalForRRset(*finder, *rrset_in_set, requested_types, result,
                               options_);
     }
 }
diff --git a/src/lib/dhcp/tests/.gitignore b/src/lib/dhcp/tests/.gitignore
index 313429d..89ea505 100644
--- a/src/lib/dhcp/tests/.gitignore
+++ b/src/lib/dhcp/tests/.gitignore
@@ -1 +1,2 @@
 /libdhcp++_unittests
+/libdhcpsrv_unittests
diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc
index 2c7b86b..462910b 100644
--- a/src/lib/dhcp/tests/iface_mgr_unittest.cc
+++ b/src/lib/dhcp/tests/iface_mgr_unittest.cc
@@ -1096,7 +1096,7 @@ void parse_ifconfig(const std::string& textFile, IfaceMgr::IfaceCollection& ifac
             addr = addr.substr(0, addr.find_first_of(" "));
             IOAddress a(addr);
             iface->addAddress(a);
-        } else if(line.find("Metric")) {
+        } else if(line.find("Metric") != string::npos) {
             // flags
             if (line.find("UP") != string::npos) {
                 iface->flag_up_ = true;
diff --git a/src/lib/dns/Makefile.am b/src/lib/dns/Makefile.am
index 38809e0..977854d 100644
--- a/src/lib/dns/Makefile.am
+++ b/src/lib/dns/Makefile.am
@@ -107,7 +107,6 @@ libb10_dns___la_SOURCES += rdatafields.h rdatafields.cc
 libb10_dns___la_SOURCES += rrclass.cc
 libb10_dns___la_SOURCES += rrparamregistry.h
 libb10_dns___la_SOURCES += rrset.h rrset.cc
-libb10_dns___la_SOURCES += rrsetlist.h rrsetlist.cc
 libb10_dns___la_SOURCES += rrttl.h rrttl.cc
 libb10_dns___la_SOURCES += rrtype.cc
 libb10_dns___la_SOURCES += question.h question.cc
@@ -149,11 +148,11 @@ libdns___include_HEADERS = \
 	messagerenderer.h \
 	name.h \
 	question.h \
+	opcode.h \
 	rcode.h \
 	rdata.h \
 	rrparamregistry.h \
 	rrset.h \
-	rrsetlist.h \
 	rrttl.h \
 	tsigkey.h
 # Purposely not installing these headers:
diff --git a/src/lib/dns/benchmarks/message_renderer_bench.cc b/src/lib/dns/benchmarks/message_renderer_bench.cc
index 6376498..abf3192 100644
--- a/src/lib/dns/benchmarks/message_renderer_bench.cc
+++ b/src/lib/dns/benchmarks/message_renderer_bench.cc
@@ -39,7 +39,7 @@ public:
         renderer_(NULL),
         names_(names)
     {}
-    MessageRendererBenchMark() {
+    ~MessageRendererBenchMark() {
         delete renderer_;
     }
     unsigned int run() {
diff --git a/src/lib/dns/benchmarks/rdatarender_bench.cc b/src/lib/dns/benchmarks/rdatarender_bench.cc
index 38ee2ac..65576ee 100644
--- a/src/lib/dns/benchmarks/rdatarender_bench.cc
+++ b/src/lib/dns/benchmarks/rdatarender_bench.cc
@@ -42,9 +42,10 @@ template <typename T>
 class RdataRenderBenchMark {
 public:
     RdataRenderBenchMark(const vector<T>& dataset) :
-        dataset_(dataset)
+        dataset_(dataset),
+        renderer_(NULL)
     {}
-    RdataRenderBenchMark() {
+    ~RdataRenderBenchMark() {
         delete renderer_;
     }
     unsigned int run() {
diff --git a/src/lib/dns/python/edns_python.cc b/src/lib/dns/python/edns_python.cc
index 8f0f1a4..e9d54c1 100644
--- a/src/lib/dns/python/edns_python.cc
+++ b/src/lib/dns/python/edns_python.cc
@@ -269,7 +269,6 @@ EDNS_createFromRR(const s_EDNS* null_self, PyObject* args) {
     const PyObject* rrtype;
     const PyObject* rrttl;
     const PyObject* rdata;
-    s_EDNS* edns_obj = NULL;
 
     assert(null_self == NULL);
 
@@ -277,7 +276,7 @@ EDNS_createFromRR(const s_EDNS* null_self, PyObject* args) {
                          &rrclass_type, &rrclass, &rrtype_type, &rrtype,
                          &rrttl_type, &rrttl, &rdata_type, &rdata)) {
         uint8_t extended_rcode;
-        edns_obj = PyObject_New(s_EDNS, &edns_type);
+        s_EDNS* edns_obj = PyObject_New(s_EDNS, &edns_type);
         if (edns_obj == NULL) {
             return (NULL);
         }
diff --git a/src/lib/dns/rdata/generic/afsdb_18.cc b/src/lib/dns/rdata/generic/afsdb_18.cc
index 6afc4de..ec76ee0 100644
--- a/src/lib/dns/rdata/generic/afsdb_18.cc
+++ b/src/lib/dns/rdata/generic/afsdb_18.cc
@@ -57,7 +57,6 @@ AFSDB::AFSDB(const std::string& afsdb_str) :
     try {
         const uint32_t subtype = tokenToNum<int32_t, 16>(getToken(iss));
         const Name servername(getToken(iss));
-        string server;
 
         if (!iss.eof()) {
             isc_throw(InvalidRdataText, "Unexpected input for AFSDB"
diff --git a/src/lib/dns/rrsetlist.cc b/src/lib/dns/rrsetlist.cc
deleted file mode 100644
index fcdcfbb..0000000
--- a/src/lib/dns/rrsetlist.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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 <vector>
-
-#include <boost/foreach.hpp>
-
-#include <exceptions/exceptions.h>
-
-#include <dns/rrclass.h>
-#include <dns/rrtype.h>
-#include <dns/rrset.h>
-#include <dns/rrsetlist.h>
-
-namespace isc {
-namespace dns {
-
-void
-RRsetList::addRRset(RRsetPtr rrsetptr) {
-    ConstRRsetPtr rrset_found = findRRset(rrsetptr->getType(),
-                                          rrsetptr->getClass());
-    if (rrset_found != NULL) {
-        isc_throw(DuplicateRRset, "RRset is being doubly added to RRsetList: "
-                  "type=" << rrsetptr->getType() << ", class=" <<
-                  rrsetptr->getClass());
-    }
-    rrsets_.push_back(rrsetptr);
-}
-
-void
-RRsetList::append(RRsetList& source) {
-    BOOST_FOREACH(RRsetPtr rrset, source) {
-        addRRset(rrset);
-    }
-}
-
-RRsetPtr
-RRsetList::findRRset(const RRType& rrtype, const RRClass& rrclass) {
-    BOOST_FOREACH(RRsetPtr rrsetptr, rrsets_) {
-        if ((rrsetptr->getClass() == rrclass) &&
-            (rrsetptr->getType() == rrtype)) {
-            return (rrsetptr);
-        }
-    }
-    return (RRsetPtr());
-}
-
-}
-}
diff --git a/src/lib/dns/rrsetlist.h b/src/lib/dns/rrsetlist.h
deleted file mode 100644
index 0e05b5b..0000000
--- a/src/lib/dns/rrsetlist.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// 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.
-
-#ifndef __RRSETLIST_H
-#define __RRSETLIST_H 1
-
-#include <iostream>
-#include <iterator>
-#include <vector>
-
-#include <boost/shared_ptr.hpp>
-
-#include <dns/rrset.h>
-#include <dns/rrclass.h>
-#include <dns/rrtype.h>
-
-namespace isc {
-namespace dns {
-
-class DuplicateRRset : public Exception {
-public:
-    DuplicateRRset(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-template <typename T, typename P, typename R>
-class RRsetListIterator :
-        public std::iterator<std::input_iterator_tag, RRsetPtr> {
-public:
-    RRsetListIterator() {}
-    explicit RRsetListIterator(const T& it) :
-        it_(it) {}
-    RRsetListIterator& operator++()
-    {
-        ++it_;
-        return (*this);
-    }
-    RRsetListIterator operator++(int)
-    {
-        RRsetListIterator tmp(*this);
-        ++it_;
-        return (tmp);
-    }
-    R operator*() const
-    {
-        return (*it_);
-    }
-    P operator->() const
-    {
-        return (&(operator*()));
-    }
-    bool operator==(const RRsetListIterator& other)
-    {
-        return (it_ == other.it_);
-    }
-    bool operator!=(const RRsetListIterator& other)
-    {
-        return (it_ != other.it_);
-    }
-    
-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);
-    RRsetList& operator=(const RRsetList& source);
-public:
-    RRsetList() {}
-    void addRRset(RRsetPtr new_rrsetptr);
-    void append(RRsetList& source);
-    RRsetPtr findRRset(const RRType& rrtype, const RRClass& rrclass);
-
-    typedef RRsetListIterator<std::vector<RRsetPtr>::iterator,
-                              RRsetPtr*,
-                              RRsetPtr&> iterator;
-    typedef RRsetListIterator<std::vector<RRsetPtr>::const_iterator,
-                              const RRsetPtr*,
-                              const RRsetPtr&> const_iterator;
-
-    const_iterator begin() const { return (const_iterator(rrsets_.begin())); }
-    const_iterator end() const { return (const_iterator(rrsets_.end())); }
-
-    iterator begin() { return (iterator(rrsets_.begin())); }
-    iterator end() { return (iterator(rrsets_.end())); }
-
-    size_t size() const { return (rrsets_.size()); }
-
-private:
-    std::vector<RRsetPtr> rrsets_;
-};
-
-} // end of namespace dns
-} // end of namespace isc
-#endif  // __RRSETLIST_H
-
-// Local Variables: 
-// mode: c++
-// End: 
diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am
index 0abb389..e8cbe10 100644
--- a/src/lib/dns/tests/Makefile.am
+++ b/src/lib/dns/tests/Makefile.am
@@ -56,7 +56,7 @@ run_unittests_SOURCES += rdata_minfo_unittest.cc
 run_unittests_SOURCES += rdata_tsig_unittest.cc
 run_unittests_SOURCES += rdata_naptr_unittest.cc
 run_unittests_SOURCES += rdata_hinfo_unittest.cc
-run_unittests_SOURCES += rrset_unittest.cc rrsetlist_unittest.cc
+run_unittests_SOURCES += rrset_unittest.cc
 run_unittests_SOURCES += question_unittest.cc
 run_unittests_SOURCES += rrparamregistry_unittest.cc
 run_unittests_SOURCES += masterload_unittest.cc
diff --git a/src/lib/dns/tests/labelsequence_unittest.cc b/src/lib/dns/tests/labelsequence_unittest.cc
index 90d470d..62cbcec 100644
--- a/src/lib/dns/tests/labelsequence_unittest.cc
+++ b/src/lib/dns/tests/labelsequence_unittest.cc
@@ -860,8 +860,12 @@ TEST_F(LabelSequenceTest, badDeserialize) {
     const uint8_t toomany_offsets[] = { Name::MAX_LABELS + 1 };
     EXPECT_THROW(LabelSequence ls(toomany_offsets), isc::BadValue);
 
-    // exceed MAX_LABEL_LEN
-    const uint8_t offsets_toolonglabel[] = { 2, 0, 64 };
+    // (second) offset does not match actual label length
+    const uint8_t offsets_wrongoffset[] = { 2, 0, 64, 1 };
+    EXPECT_THROW(LabelSequence ls(offsets_wrongoffset), isc::BadValue);
+
+    // offset matches, but exceeds MAX_LABEL_LEN
+    const uint8_t offsets_toolonglabel[] = { 2, 0, 64, 64 };
     EXPECT_THROW(LabelSequence ls(offsets_toolonglabel), isc::BadValue);
 
     // Inconsistent data: an offset is lower than the previous offset
diff --git a/src/lib/dns/tests/rrparamregistry_unittest.cc b/src/lib/dns/tests/rrparamregistry_unittest.cc
index d2bec5c..c155b53 100644
--- a/src/lib/dns/tests/rrparamregistry_unittest.cc
+++ b/src/lib/dns/tests/rrparamregistry_unittest.cc
@@ -37,6 +37,7 @@ protected:
     {
         ostringstream oss1;
         oss1 << test_class_code;
+        // cppcheck-suppress useInitializationList
         test_class_unknown_str = "CLASS" + oss1.str();
 
         ostringstream oss2;
@@ -60,7 +61,7 @@ protected:
 
     // we assume class/type numbers are officially unassigned.  If not we'll
     // need to update the test cases.
-    static const uint16_t test_class_code = 65533; 
+    static const uint16_t test_class_code = 65533;
     static const uint16_t test_type_code = 65534;
     static const string test_class_str;
     static const string test_type_str;
@@ -77,7 +78,7 @@ TEST_F(RRParamRegistryTest, addRemove) {
 
     // the first removal attempt should succeed
     EXPECT_TRUE(RRParamRegistry::getRegistry().removeType(test_type_code));
-    // then toText() should treat it as an "unknown" 
+    // then toText() should treat it as an "unknown"
     EXPECT_EQ(test_type_unknown_str, RRType(test_type_code).toText());
     // attempt of removing non-existent mapping should result in 'false'
     EXPECT_FALSE(RRParamRegistry::getRegistry().removeType(test_type_code));
diff --git a/src/lib/dns/tests/rrsetlist_unittest.cc b/src/lib/dns/tests/rrsetlist_unittest.cc
deleted file mode 100644
index 080f888..0000000
--- a/src/lib/dns/tests/rrsetlist_unittest.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// 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 <vector>
-#include <boost/foreach.hpp>
-
-#include <dns/rdata.h>
-#include <dns/rdataclass.h>
-#include <dns/rrclass.h>
-#include <dns/rrtype.h>
-#include <dns/rrsetlist.h>
-#include <dns/rrset.h>
-#include <dns/rrttl.h>
-
-#include <gtest/gtest.h>
-
-using namespace std;
-using namespace isc::dns;
-using namespace isc::dns::rdata;
-
-namespace {
-class RRsetListTest : public ::testing::Test {
-protected:
-    RRsetListTest() : example_name(Name("example.com")),
-                      example_ttl(RRTTL(3600))
-    {}
-    void setupList(RRsetList& list);
-    Name example_name;
-    RRTTL example_ttl;
-};
-
-const in::A rdata_in_a("192.0.2.1");
-const in::AAAA rdata_in_aaaa("2001:db8::1234");
-const generic::NS rdata_ns("ns.example.com");
-const generic::SOA rdata_soa(Name("ns.example.com"), Name("root.example.com"),
-                             2010012601, 3600, 300, 3600000, 1200);
-const generic::CNAME rdata_cname("target.example.com");
-const generic::DNAME rdata_dname("dtarget.example.com");
-
-void
-RRsetListTest::setupList(RRsetList& list) {
-    RRsetPtr a(new RRset(Name("example.com"), RRClass::IN(),
-                         RRType::A(), example_ttl));
-    RRsetPtr aaaa(new RRset(Name("example.com"), RRClass::IN(),
-                            RRType::AAAA(), example_ttl));
-    RRsetPtr ns(new RRset(Name("example.com"), RRClass::IN(),
-                          RRType::NS(), example_ttl));
-    RRsetPtr soa(new RRset(Name("example.com"), RRClass::IN(),
-                           RRType::SOA(), example_ttl));
-    RRsetPtr cname(new RRset(Name("example.com"), RRClass::IN(),
-                             RRType::CNAME(), example_ttl));
-
-    a->addRdata(rdata_in_a);
-    aaaa->addRdata(rdata_in_aaaa);
-    ns->addRdata(rdata_ns);
-    soa->addRdata(rdata_soa);
-    cname->addRdata(rdata_cname);
-
-    list.addRRset(a);
-    list.addRRset(aaaa);
-    list.addRRset(ns);
-    list.addRRset(soa);
-    list.addRRset(cname);
-}
-
-TEST_F(RRsetListTest, emptyOnInitialCreate) {
-    RRsetList list;
-    EXPECT_EQ(list.size(), 0);
-}
-
-TEST_F(RRsetListTest, addRRsets) {
-    RRsetList list;
-    setupList(list);
-    EXPECT_EQ(list.size(), 5);
-}
-
-TEST_F(RRsetListTest, append) {
-    RRsetList list1;
-    setupList(list1);
-    RRsetList list2;
-    RRsetPtr dname(new RRset(Name("example.com"), RRClass::IN(),
-                             RRType::DNAME(), example_ttl));
-    dname->addRdata(rdata_dname);
-    list2.addRRset(dname);
-    list1.append(list2);
-    EXPECT_EQ(list2.size(), 1);
-    EXPECT_EQ(list1.size(), 6);
-
-    RRsetPtr rrset = list1.findRRset(RRType::DNAME(), RRClass::IN());
-    EXPECT_EQ(RRType::DNAME(), rrset->getType());
-
-    EXPECT_THROW(list1.append(list2), DuplicateRRset);
-}
-
-TEST_F(RRsetListTest, extraRRset) {
-    RRsetList list;
-    setupList(list);
-    RRsetPtr cname(new RRset(Name("another.example.com"), RRClass::IN(),
-                             RRType::CNAME(), example_ttl));
-    EXPECT_THROW(list.addRRset(cname), DuplicateRRset);
-}
-
-void
-checkFindResult(RRsetList& list, const Name& name,
-                const RRType& rrtype, const RRClass& rrclass,
-                const RRTTL& rrttl)
-{
-    RRsetPtr rrset = list.findRRset(rrtype, rrclass);;
-    EXPECT_EQ(name, rrset->getName());
-    EXPECT_EQ(rrtype, rrset->getType());
-    EXPECT_EQ(rrclass, rrset->getClass());
-    EXPECT_EQ(rrttl, rrset->getTTL());
-}
-
-TEST_F(RRsetListTest, findRRset) {
-    RRsetList list;
-    setupList(list);
- 
-    checkFindResult(list, example_name, RRType::A(), RRClass::IN(),
-                    example_ttl);
-    checkFindResult(list, example_name, RRType::CNAME(), RRClass::IN(),
-                    example_ttl);
-    checkFindResult(list, example_name, RRType::AAAA(), RRClass::IN(),
-                    example_ttl);
-    checkFindResult(list, example_name, RRType::NS(), RRClass::IN(),
-                    example_ttl);
-    checkFindResult(list, example_name, RRType::SOA(), RRClass::IN(),
-                    example_ttl);
-}
-
-TEST_F(RRsetListTest, checkData) {
-    RRsetList list;
-    RRsetPtr a(new RRset(Name("example.com"), RRClass::IN(),
-                         RRType::A(), example_ttl));
-    a->addRdata(rdata_in_a);
-    list.addRRset(a);
-
-    RdataIteratorPtr it =
-        list.findRRset(RRType::A(), RRClass::IN())->getRdataIterator();
-    EXPECT_FALSE(it->isLast());
-    EXPECT_EQ("192.0.2.1", it->getCurrent().toText());
-}
-
-TEST_F(RRsetListTest, iterate) {
-    RRsetList list;
-    setupList(list);
-
-    bool has_a = false, has_aaaa = false, has_ns = false, has_soa = false,
-        has_cname = false;
-    int i = 0;
-    BOOST_FOREACH(RRsetPtr rrset, list) {
-        if (rrset->getType() == RRType::A()) {
-            has_a = true;
-        }
-        if (rrset->getType() == RRType::AAAA()) {
-            has_aaaa = true;
-        }
-        if (rrset->getType() == RRType::NS()) {
-            has_ns = true;
-        }
-        if (rrset->getType() == RRType::SOA()) {
-            has_soa = true;
-        }
-        if (rrset->getType() == RRType::CNAME()) {
-            has_cname = true;
-        }
-        ++i;
-    }
-    EXPECT_TRUE(has_a);
-    EXPECT_TRUE(has_aaaa);
-    EXPECT_TRUE(has_ns);
-    EXPECT_TRUE(has_soa);
-    EXPECT_TRUE(has_cname);
-    EXPECT_TRUE(i == 5);
-}
-
-}
diff --git a/src/lib/log/compiler/message.cc b/src/lib/log/compiler/message.cc
index 86c5f20..ef62b2f 100644
--- a/src/lib/log/compiler/message.cc
+++ b/src/lib/log/compiler/message.cc
@@ -109,11 +109,13 @@ currentTime() {
     // Get a text representation of the current time.
     time_t curtime;
     time(&curtime);
-    char* buffer = ctime(&curtime);
+    struct tm* timeinfo;
+    timeinfo = localtime(&curtime);
 
-    // Convert to string and strip out the trailing newline
-    string current_time = buffer;
-    return (isc::util::str::trim(current_time));
+    char buffer[80];
+    strftime(buffer, 80, "%a %b %d %Y %H:%M", timeinfo);
+
+    return (std::string(buffer));
 }
 
 
diff --git a/src/lib/log/tests/logger_example.cc b/src/lib/log/tests/logger_example.cc
index 6f95e5d..08c9084 100644
--- a/src/lib/log/tests/logger_example.cc
+++ b/src/lib/log/tests/logger_example.cc
@@ -118,7 +118,6 @@ int main(int argc, char** argv) {
     LoggerSpecification cur_spec(ROOT_NAME);// Current specification
     OutputOption        cur_opt;            // Current output option
     vector<LoggerSpecification> loggers;    // Set of logger specifications
-    vector<OutputOption>        options;    // Output options for logger
     std::string                 severity;   // Severity set for logger
 
     // Initialize logging system - set the root logger name.
diff --git a/src/lib/python/isc/bind10/component.py b/src/lib/python/isc/bind10/component.py
index 9c29ace..1f7006c 100644
--- a/src/lib/python/isc/bind10/component.py
+++ b/src/lib/python/isc/bind10/component.py
@@ -45,6 +45,7 @@ COMPONENT_RESTART_DELAY = 10
 
 STATE_DEAD = 'dead'
 STATE_STOPPED = 'stopped'
+STATE_RESTARTING = 'restarting'
 STATE_RUNNING = 'running'
 
 def get_signame(signal_number):
@@ -68,6 +69,7 @@ class BaseComponent:
       explicitly).
     - Running - after start() was called, it started successfully and is
       now running.
+    - Restarting - the component failed (crashed) and is waiting for a restart
     - Dead - it failed and can not be resurrected.
 
     Init
@@ -79,11 +81,11 @@ class BaseComponent:
                     |            |                |
                     |failure     | failed()       |
                     |            |                |
-                    v            |                |
+                    v            |                | start()/restart()
                     +<-----------+                |
                     |                             |
                     |  kind == dispensable or kind|== needed and failed late
-                    +-----------------------------+
+                    +-----------------------> Restarting
                     |
                     | kind == core or kind == needed and it failed too soon
                     v
@@ -163,7 +165,7 @@ class BaseComponent:
         """
         if self.__state == STATE_DEAD:
             raise ValueError("Can't resurrect already dead component")
-        if self.running():
+        if self.is_running():
             raise ValueError("Can't start already running component")
         logger.info(BIND10_COMPONENT_START, self.name())
         self.__state = STATE_RUNNING
@@ -188,7 +190,7 @@ class BaseComponent:
         """
         # This is not tested. It talks with the outher world, which is out
         # of scope of unittests.
-        if not self.running():
+        if not self.is_running():
             raise ValueError("Can't stop a component which is not running")
         logger.info(BIND10_COMPONENT_STOP, self.name())
         self.__state = STATE_STOPPED
@@ -234,9 +236,9 @@ class BaseComponent:
 
         logger.error(BIND10_COMPONENT_FAILED, self.name(), self.pid(),
                      exit_str)
-        if not self.running():
+        if not self.is_running():
             raise ValueError("Can't fail component that isn't running")
-        self.__state = STATE_STOPPED
+        self.__state = STATE_RESTARTING # tentatively set, maybe changed to DEAD
         self._failed_internal()
         # If it is a core component or the needed component failed to start
         # (including it stopped really soon)
@@ -284,7 +286,7 @@ class BaseComponent:
         else:
             return False
 
-    def running(self):
+    def is_running(self):
         """
         Informs if the component is currently running. It assumes the failed
         is called whenever the component really fails and there might be some
@@ -296,6 +298,15 @@ class BaseComponent:
         """
         return self.__state == STATE_RUNNING
 
+    def is_restarting(self):
+        """Informs if the component has failed and is waiting for a restart.
+
+        Unlike the case of is_running(), if this returns True it always means
+        the corresponding process has died and not yet restarted.
+
+        """
+        return self.__state == STATE_RESTARTING
+
     def _start_internal(self):
         """
         This method does the actual starting of a process. You need to override
@@ -560,6 +571,13 @@ class Configurator:
         self._running = False
         self.__reconfigure_internal(self._components, {})
 
+    def has_component(self, component):
+        '''Return if a specified component is configured.'''
+        # Values of self._components are tuples of (config, component).
+        # Extract the components of the tuples and see if the given one
+        # is included.
+        return component in map(lambda x: x[1], self._components.values())
+
     def reconfigure(self, configuration):
         """
         Changes configuration from the current one to the provided. It
@@ -591,7 +609,7 @@ class Configurator:
         for cname in old.keys():
             if cname not in new:
                 component = self._components[cname][1]
-                if component.running():
+                if component.is_running() or component.is_restarting():
                     plan.append({
                         'command': STOP_CMD,
                         'component': component,
@@ -674,7 +692,7 @@ class Configurator:
                     self._components[task['name']] = (task['config'],
                                                       component)
                 elif command == STOP_CMD:
-                    if component.running():
+                    if component.is_running():
                         component.stop()
                     del self._components[task['name']]
                 else:
diff --git a/src/lib/python/isc/bind10/tests/component_test.py b/src/lib/python/isc/bind10/tests/component_test.py
index 3f26870..18efea7 100644
--- a/src/lib/python/isc/bind10/tests/component_test.py
+++ b/src/lib/python/isc/bind10/tests/component_test.py
@@ -191,7 +191,8 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.assertFalse(self.__start_called)
         self.assertFalse(self.__stop_called)
         self.assertFalse(self.__failed_called)
-        self.assertFalse(component.running())
+        self.assertFalse(component.is_running())
+        self.assertFalse(component.is_restarting())
         # We can't stop or fail the component yet
         self.assertRaises(ValueError, component.stop)
         self.assertRaises(ValueError, component.failed, 1)
@@ -204,7 +205,8 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.assertTrue(self.__start_called)
         self.assertFalse(self.__stop_called)
         self.assertFalse(self.__failed_called)
-        self.assertTrue(component.running())
+        self.assertTrue(component.is_running())
+        self.assertFalse(component.is_restarting())
 
     def __check_dead(self, component):
         """
@@ -215,7 +217,8 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.assertFalse(self.__stop_called)
         self.assertTrue(self.__failed_called)
         self.assertEqual(1, self._exitcode)
-        self.assertFalse(component.running())
+        self.assertFalse(component.is_running())
+        self.assertFalse(component.is_restarting())
         # Surely it can't be stopped when already dead
         self.assertRaises(ValueError, component.stop)
         # Nor started
@@ -234,7 +237,8 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.assertTrue(self.__start_called)
         self.assertFalse(self.__stop_called)
         self.assertTrue(self.__failed_called)
-        self.assertTrue(component.running())
+        self.assertTrue(component.is_running())
+        self.assertFalse(component.is_restarting())
         # Check it can't be started again
         self.assertRaises(ValueError, component.start)
 
@@ -246,7 +250,8 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.assertTrue(self.__start_called)
         self.assertFalse(self.__stop_called)
         self.assertTrue(self.__failed_called)
-        self.assertFalse(component.running())
+        self.assertFalse(component.is_running())
+        self.assertTrue(component.is_restarting())
 
     def __do_start_stop(self, kind):
         """
@@ -270,7 +275,8 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.assertTrue(self.__start_called)
         self.assertTrue(self.__stop_called)
         self.assertFalse(self.__failed_called)
-        self.assertFalse(component.running())
+        self.assertFalse(component.is_running())
+        self.assertFalse(component.is_restarting())
         # Check it can't be stopped twice
         self.assertRaises(ValueError, component.stop)
         # Or failed
@@ -553,10 +559,10 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.assertIsNone(component.pid())
         self.assertEqual(['hello'], component._params)
         self.assertEqual('Address', component._address)
-        self.assertFalse(component.running())
+        self.assertFalse(component.is_running())
         self.assertEqual({}, self.__registered_processes)
         component.start()
-        self.assertTrue(component.running())
+        self.assertTrue(component.is_running())
         # Some versions of unittest miss assertIsInstance
         self.assertTrue(isinstance(component._procinfo, TestProcInfo))
         self.assertEqual(42, component.pid())
@@ -580,11 +586,11 @@ class ComponentTests(BossUtils, unittest.TestCase):
         """
         component = Component('component', self, 'needed', 'Address')
         component.start()
-        self.assertTrue(component.running())
+        self.assertTrue(component.is_running())
         self.assertEqual('component', self.__start_simple_params)
         component.pid = lambda: 42
         component.stop()
-        self.assertFalse(component.running())
+        self.assertFalse(component.is_running())
         self.assertEqual(('component', 'Address', 42),
                          self.__stop_process_params)
 
@@ -609,7 +615,7 @@ class ComponentTests(BossUtils, unittest.TestCase):
         component = Component('component', self, 'needed', 'Address',
                               [], ProcInfo)
         component.start()
-        self.assertTrue(component.running())
+        self.assertTrue(component.is_running())
         component.kill()
         self.assertTrue(process.terminated)
         self.assertFalse(process.killed)
@@ -872,12 +878,13 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
             'priority': 6,
             'special': 'test',
             'process': 'additional',
-            'kind': 'needed'
+            'kind': 'dispensable' # need to be dispensable so it could restart
         }
         self.log = []
         plan = configurator._build_plan(self.__build_components(self.__core),
                                         bigger)
-        self.assertEqual([('additional', 'init'), ('additional', 'needed')],
+        self.assertEqual([('additional', 'init'),
+                          ('additional', 'dispensable')],
                          self.log)
         self.assertEqual(1, len(plan))
         self.assertTrue('component' in plan[0])
@@ -888,15 +895,29 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
         # Now remove the one component again
         # We run the plan so the component is wired into internal structures
         configurator._run_plan(plan)
-        self.log = []
-        plan = configurator._build_plan(self.__build_components(bigger),
-                                        self.__core)
-        self.assertEqual([], self.log)
-        self.assertEqual([{
-            'command': 'stop',
-            'name': 'additional',
-            'component': component
-        }], plan)
+        # We should have the 'additional' component in the configurator.
+        self.assertTrue(configurator.has_component(component))
+        for count in [0, 1]:    # repeat two times, see below
+            self.log = []
+            plan = configurator._build_plan(self.__build_components(bigger),
+                                            self.__core)
+            self.assertEqual([], self.log)
+            self.assertEqual([{
+                        'command': 'stop',
+                        'name': 'additional',
+                        'component': component
+                        }], plan)
+
+            if count is 0:
+                # We then emulate unexpected failure of the component (but
+                # before it restarts).  It shouldn't confuse the
+                # configurator in the second phase of the test
+                component.failed(0)
+        # Run the plan, confirm the specified component is gone.
+        configurator._run_plan(plan)
+        self.assertFalse(configurator.has_component(component))
+        # There shouldn't be any other object that has the same name
+        self.assertFalse('additional' in configurator._components)
 
         # We want to switch a component. So, prepare the configurator so it
         # holds one
diff --git a/src/lib/python/isc/datasrc/sqlite3_ds.py b/src/lib/python/isc/datasrc/sqlite3_ds.py
index f9b47c0..dc80afd 100644
--- a/src/lib/python/isc/datasrc/sqlite3_ds.py
+++ b/src/lib/python/isc/datasrc/sqlite3_ds.py
@@ -25,7 +25,7 @@ RR_RDATA_INDEX = 7
 
 # Current major and minor versions of schema
 SCHEMA_MAJOR_VERSION = 2
-SCHEMA_MINOR_VERSION = 0
+SCHEMA_MINOR_VERSION = 1
 
 class Sqlite3DSError(Exception):
     """ Define exceptions."""
@@ -81,6 +81,7 @@ def create(cur):
                     rdtype TEXT NOT NULL COLLATE NOCASE,
                     rdata TEXT NOT NULL)""")
         cur.execute("CREATE INDEX nsec3_byhash ON nsec3 (hash)")
+        cur.execute("CREATE INDEX nsec3_byhash_and_rdtype ON nsec3 (hash, rdtype)")
         cur.execute("""CREATE TABLE diffs (id INTEGER PRIMARY KEY,
                     zone_id INTEGER NOT NULL,
                     version INTEGER NOT NULL,
diff --git a/src/lib/resolve/recursive_query.cc b/src/lib/resolve/recursive_query.cc
index 8d03c1c..c5b280f 100644
--- a/src/lib/resolve/recursive_query.cc
+++ b/src/lib/resolve/recursive_query.cc
@@ -176,7 +176,7 @@ class RunningQuery : public IOFetch::Callback {
 class ResolverNSASCallback : public isc::nsas::AddressRequestCallback {
 public:
     ResolverNSASCallback(RunningQuery* rq) : rq_(rq) {}
-    
+
     void success(const isc::nsas::NameserverAddress& address) {
         // Success callback, send query to found namesever
         LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CB, RESLIB_RUNQ_SUCCESS)
@@ -184,7 +184,7 @@ public:
         rq_->nsasCallbackCalled();
         rq_->sendTo(address);
     }
-    
+
     void unreachable() {
         // Nameservers unreachable: drop query or send servfail?
         LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CB, RESLIB_RUNQ_FAIL);
@@ -261,7 +261,7 @@ private:
     bool done_;
 
     // If we have a client timeout, we call back with a failure message,
-    // but we do not stop yet. We use this variable to make sure we 
+    // but we do not stop yet. We use this variable to make sure we
     // don't call back a second time later
     bool callback_called_;
 
@@ -270,7 +270,7 @@ private:
 
     // Reference to our cache
     isc::cache::ResolverCache& cache_;
-    
+
     // the 'current' zone we are in (i.e.) we start out at the root,
     // and for each delegation this gets updated with the zone the
     // delegation points to.
@@ -278,7 +278,7 @@ private:
     // of the call we use it in take a string, we need update those
     // too).
     std::string cur_zone_;
-    
+
     // This is the handler we pass on to the NSAS; it is called when
     // the NSAS has an address for us to query
     boost::shared_ptr<ResolverNSASCallback> nsas_callback_;
@@ -295,7 +295,7 @@ private:
 
     // The moment in time we sent a query to the nameserver above.
     struct timeval current_ns_qsent_time;
-    
+
     // RunningQuery deletes itself when it is done. In order for us
     // to do this safely, we must make sure that there are no events
     // that might call back to it. There are two types of events in
@@ -365,7 +365,7 @@ private:
             io_.get_io_service().post(query);
         }
     }
-    
+
     // 'general' send, ask the NSAS to give us an address.
     void send(IOFetch::Protocol protocol = IOFetch::UDP, bool edns = true) {
         protocol_ = protocol;   // Store protocol being used for this
@@ -397,7 +397,7 @@ private:
             nsas_.lookup(cur_zone_, question_.getClass(), nsas_callback_);
         }
     }
-    
+
     // Called by our NSAS callback handler so we know we do not have
     // an outstanding NSAS call anymore.
     void nsasCallbackCalled() {
@@ -422,13 +422,13 @@ private:
         // here (classify() will set it when it walks through
         // the cname chain to verify it).
         Name cname_target(question_.getName());
-        
+
         isc::resolve::ResponseClassifier::Category category =
             isc::resolve::ResponseClassifier::classify(
                 question_, incoming, cname_target, cname_count_);
 
         bool found_ns = false;
-            
+
         switch (category) {
         case isc::resolve::ResponseClassifier::ANSWER:
         case isc::resolve::ResponseClassifier::ANSWERCNAME:
@@ -569,7 +569,7 @@ private:
                 // SERVFAIL if we get FORMERR instead
             }
             goto SERVFAIL;
-            
+
         default:
 SERVFAIL:
             // Some error in received packet it.  Report it and return SERVFAIL
@@ -718,7 +718,7 @@ public:
             ++outstanding_events_;
             lookup_timer.async_wait(boost::bind(&RunningQuery::lookupTimeout, this));
         }
-        
+
         // Setup the timer to send an answer (client_timeout)
         if (client_timeout >= 0) {
             client_timer.expires_from_now(
@@ -726,7 +726,7 @@ public:
             ++outstanding_events_;
             client_timer.async_wait(boost::bind(&RunningQuery::clientTimeout, this));
         }
-        
+
         doLookup();
     }
 
@@ -741,7 +741,7 @@ public:
         --outstanding_events_;
         stop();
     }
-    
+
     // called if we have a client timeout; if our callback has
     // not been called, call it now. But do not stop.
     void clientTimeout() {
@@ -810,7 +810,7 @@ public:
         // XXX is this the place for TCP retry?
         assert(outstanding_events_ > 0);
         --outstanding_events_;
-        
+
         if (!done_ && result != IOFetch::TIME_OUT) {
             // we got an answer
 
@@ -890,7 +890,7 @@ public:
             stop();
         }
     }
-    
+
     // Clear the answer parts of answer_message, and set the rcode
     // to servfail
     void makeSERVFAIL() {
@@ -1096,7 +1096,7 @@ RecursiveQuery::resolve(const QuestionPtr& question,
         // Message found, return that
         LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CACHE, RESLIB_RECQ_CACHE_FIND)
                   .arg(questionText(*question)).arg(1);
-        
+
         // TODO: err, should cache set rcode as well?
         answer_message->setRcode(Rcode::NOERROR());
         callback->success(answer_message);
@@ -1146,11 +1146,11 @@ RecursiveQuery::resolve(const Question& question,
     // TODO: general 'prepareinitialanswer'
     answer_message->setOpcode(isc::dns::Opcode::QUERY());
     answer_message->addQuestion(question);
-    
+
     // First try to see if we have something cached in the messagecache
     LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_TRACE, RESLIB_RESOLVE)
               .arg(questionText(question)).arg(2);
-    
+
     if (cache_.lookup(question.getName(), question.getType(),
                       question.getClass(), *answer_message) &&
         answer_message->getRRCount(Message::SECTION_ANSWER) > 0) {
@@ -1181,7 +1181,7 @@ RecursiveQuery::resolve(const Question& question,
             // delete itself when it is done
             LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_TRACE, RESLIB_RECQ_CACHE_NO_FIND)
                       .arg(questionText(question)).arg(2);
-            new RunningQuery(io, question, answer_message, 
+            new RunningQuery(io, question, answer_message,
                              test_server_, buffer, crs, query_timeout_,
                              client_timeout_, lookup_timeout_, retries_,
                              nsas_, cache_, rtt_recorder_);
diff --git a/src/lib/resolve/tests/recursive_query_unittest.cc b/src/lib/resolve/tests/recursive_query_unittest.cc
index 02721f1..4513458 100644
--- a/src/lib/resolve/tests/recursive_query_unittest.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest.cc
@@ -218,7 +218,7 @@ protected:
     }
 
     // Receive a UDP packet from a mock server; used for testing
-    // recursive lookup.  The caller must place a RecursiveQuery 
+    // recursive lookup.  The caller must place a RecursiveQuery
     // on the IO Service queue before running this routine.
     void recvUDP(const int family, void* buffer, size_t& size) {
         ScopedAddrInfo sai(resolveAddress(family, IPPROTO_UDP, true));
@@ -267,7 +267,7 @@ protected:
         if (ret < 0) {
             isc_throw(IOError, "recvfrom failed: " << strerror(errno));
         }
-        
+
         // Pass the message size back via the size parameter
         size = ret;
     }
@@ -693,37 +693,6 @@ createTestSocket() {
     return (sock.release());
 }
 
-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 RecursiveQueryTest::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;
-}
-
 // Mock resolver callback for testing forward query.
 class MockResolverCallback : public isc::resolve::ResolverInterface::Callback {
 public:
@@ -904,7 +873,7 @@ TEST_F(RecursiveQueryTest, lowtimeouts) {
 TEST_F(RecursiveQueryTest, DISABLED_recursiveSendOk) {
     setDNSService(true, false);
     bool done;
-    
+
     MockServerStop server(io_service_, &done);
     vector<pair<string, uint16_t> > empty_vector;
     RecursiveQuery rq(*dns_service_, *nsas_, cache_, empty_vector,
@@ -930,7 +899,7 @@ TEST_F(RecursiveQueryTest, DISABLED_recursiveSendOk) {
 TEST_F(RecursiveQueryTest, DISABLED_recursiveSendNXDOMAIN) {
     setDNSService(true, false);
     bool done;
-    
+
     MockServerStop server(io_service_, &done);
     vector<pair<string, uint16_t> > empty_vector;
     RecursiveQuery rq(*dns_service_, *nsas_, cache_, empty_vector,
diff --git a/src/lib/resolve/tests/recursive_query_unittest_2.cc b/src/lib/resolve/tests/recursive_query_unittest_2.cc
index 2b3d129..6cb404d 100644
--- a/src/lib/resolve/tests/recursive_query_unittest_2.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest_2.cc
@@ -76,14 +76,17 @@ using namespace std;
 /// directed to one or other of the "servers" in the RecursiveQueryTest2 class,
 /// regardless of the glue returned in referrals.
 
+namespace {
+const char* const TEST_ADDRESS = "127.0.0.1"; ///< Servers are on this address
+const uint16_t TEST_PORT = 5301;              ///< ... and this port
+const size_t BUFFER_SIZE = 1024;              ///< For all buffers
+const char* const WWW_EXAMPLE_ORG = "192.0.2.254";
+                                              ///< Address of www.example.org
+} //end anonymous namespace
+
 namespace isc {
 namespace asiodns {
 
-const std::string TEST_ADDRESS = "127.0.0.1";   ///< Servers are on this address
-const uint16_t TEST_PORT = 5301;                ///< ... and this port
-const size_t BUFFER_SIZE = 1024;                ///< For all buffers
-const char* WWW_EXAMPLE_ORG = "192.0.2.254";    ///< Address of www.example.org
-
 // As the test is fairly long and complex, debugging "print" statements have
 // been left in although they are disabled.  Set the following to "true" to
 // enable them.
diff --git a/src/lib/resolve/tests/recursive_query_unittest_3.cc b/src/lib/resolve/tests/recursive_query_unittest_3.cc
index 168ec80..abfea9a 100644
--- a/src/lib/resolve/tests/recursive_query_unittest_3.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest_3.cc
@@ -69,15 +69,16 @@ using namespace std;
 /// By using the "test_server_" element of RecursiveQuery, all queries are
 /// directed to one or other of the "servers" in the RecursiveQueryTest3 class.
 
-namespace isc {
-namespace asiodns {
-
-const std::string TEST_ADDRESS3 = "127.0.0.1"; 
-                                               ///< Servers are on this address
+namespace {
+const char* const TEST_ADDRESS3 = "127.0.0.1"; ///< Servers are on this address
 const uint16_t TEST_PORT3 = 5303;              ///< ... and this port
-const size_t BUFFER_SIZE = 1024;              ///< For all buffers
+const size_t BUFFER_SIZE = 1024;               ///< For all buffers
 
-const std::string DUMMY_ADDR3 = "1.2.3.4";     ///< address to return as A
+const char* const DUMMY_ADDR3 = "1.2.3.4";     ///< address to return as A
+} // end anonymous namespace
+
+namespace isc {
+namespace asiodns {
 
 class MockResolver3 : public isc::resolve::ResolverInterface {
 public:
diff --git a/src/lib/server_common/tests/socket_requestor_test.cc b/src/lib/server_common/tests/socket_requestor_test.cc
index 9878c63..ac1731f 100644
--- a/src/lib/server_common/tests/socket_requestor_test.cc
+++ b/src/lib/server_common/tests/socket_requestor_test.cc
@@ -410,7 +410,8 @@ private:
             isc_throw(Unexpected,
                       "mkstemp() created a filename too long for sun_path");
         }
-        strncpy(socket_address.sun_path, path_, len);
+        strncpy(socket_address.sun_path, path_,
+                sizeof(socket_address.sun_path));
 #ifdef HAVE_SA_LEN
         socket_address.sun_len = len;
 #endif
@@ -542,7 +543,6 @@ TEST_F(SocketRequestorTest, testSocketPassing) {
         EXPECT_EQ("foo", socket_id.second);
         EXPECT_EQ(0, close(socket_id.first));
     }
-
     // Create a second socket server, to test that multiple different
     // domains sockets would work as well (even though we don't actually
     // use that feature)
diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am
index fe1b327..13f8f7b 100644
--- a/src/lib/util/Makefile.am
+++ b/src/lib/util/Makefile.am
@@ -33,3 +33,6 @@ EXTRA_DIST = python/pycppwrapper_util.h
 
 libb10_util_la_LIBADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
 CLEANFILES = *.gcno *.gcda
+
+libb10_util_includedir = $(includedir)/$(PACKAGE_NAME)/util
+libb10_util_include_HEADERS = buffer.h
diff --git a/src/lib/util/hash/sha1.cc b/src/lib/util/hash/sha1.cc
index 091e293..1fdadfd 100644
--- a/src/lib/util/hash/sha1.cc
+++ b/src/lib/util/hash/sha1.cc
@@ -48,7 +48,7 @@
  *      merchantability of this software or the suitability of this
  *      software for any particular purpose.  It is provided "as is"
  *      without express or implied warranty of any kind.
- *      
+ *
  */
 #include <util/hash/sha1.h>
 
@@ -79,7 +79,7 @@ SHA_Parity(const uint32_t x, const uint32_t y, const uint32_t z) {
     return ((x) ^ (y) ^ (z));
 }
 
-static inline int 
+static inline int
 SHA1CircularShift(uint8_t bits, uint32_t word) {
     return ((word << bits) | (word >> (32 - bits)));
 }
diff --git a/src/lib/util/io/fd_share.cc b/src/lib/util/io/fd_share.cc
index 7adbbbe..8666441 100644
--- a/src/lib/util/io/fd_share.cc
+++ b/src/lib/util/io/fd_share.cc
@@ -142,6 +142,7 @@ send_fd(const int sock, const int fd) {
     if (msghdr.msg_control == NULL) {
         return (FD_OTHER_ERROR);
     }
+    std::memset(msghdr.msg_control, 0, msghdr.msg_controllen);
 
     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
     cmsg->cmsg_len = cmsg_len(sizeof(int));
diff --git a/src/lib/util/tests/fd_tests.cc b/src/lib/util/tests/fd_tests.cc
index 6ba2766..b709405 100644
--- a/src/lib/util/tests/fd_tests.cc
+++ b/src/lib/util/tests/fd_tests.cc
@@ -34,7 +34,9 @@ class FDTest : public ::testing::Test {
             // We do not care what is inside, we just need it to be the same
             data(new unsigned char[TEST_DATA_SIZE]),
             buffer(NULL)
-        { }
+        {
+            memset(data, 0, TEST_DATA_SIZE);
+        }
         ~ FDTest() {
             delete[] data;
             delete[] buffer;
diff --git a/src/lib/util/tests/lru_list_unittest.cc b/src/lib/util/tests/lru_list_unittest.cc
index bfb3b4d..c0201ea 100644
--- a/src/lib/util/tests/lru_list_unittest.cc
+++ b/src/lib/util/tests/lru_list_unittest.cc
@@ -168,7 +168,7 @@ protected:
         entry7_(new TestEntry("eta", 1))
     {}
 
-    virtual ~LruListTest() 
+    virtual ~LruListTest()
     {}
 
     boost::shared_ptr<TestEntry>    entry1_;
@@ -355,7 +355,7 @@ TEST_F(LruListTest, Dropped) {
     lru.add(entry5_);
     EXPECT_NE(0, (entry2_->getCode() & 0x8000));
 
-    // Delete an entry and check that the handler does not run. 
+    // Delete an entry and check that the handler does not run.
     EXPECT_EQ(0, (entry3_->getCode() & 0x8000));
     lru.remove(entry3_);
     EXPECT_EQ(0, (entry3_->getCode() & 0x8000));
@@ -386,7 +386,7 @@ TEST_F(LruListTest, Clear) {
     EXPECT_NE(0, (entry1_->getCode() & 0x8000));
     EXPECT_NE(0, (entry2_->getCode() & 0x8000));
     EXPECT_NE(0, (entry3_->getCode() & 0x8000));
- 
+
     EXPECT_EQ(0, lru.size());
 }
 
diff --git a/src/lib/util/threads/Makefile.am b/src/lib/util/threads/Makefile.am
index 85f70b9..7b9fb8f 100644
--- a/src/lib/util/threads/Makefile.am
+++ b/src/lib/util/threads/Makefile.am
@@ -2,7 +2,7 @@ SUBDIRS = . tests
 AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
 
 lib_LTLIBRARIES = libb10-threads.la
 libb10_threads_la_SOURCES  = lock.h lock.cc
diff --git a/src/lib/util/threads/lock.cc b/src/lib/util/threads/lock.cc
index de7bf07..6a165aa 100644
--- a/src/lib/util/threads/lock.cc
+++ b/src/lib/util/threads/lock.cc
@@ -67,14 +67,14 @@ Mutex::Mutex() :
         case ENOMEM:
             throw std::bad_alloc();
         default:
-            isc_throw(isc::InvalidOperation, strerror(result));
+            isc_throw(isc::InvalidOperation, std::strerror(result));
     }
     Deinitializer deinitializer(attributes);
     // TODO: Distinguish if debug mode is enabled in compilation.
     // If so, it should be PTHREAD_MUTEX_NORMAL or NULL
     result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_ERRORCHECK);
     if (result != 0) {
-        isc_throw(isc::InvalidOperation, strerror(result));
+        isc_throw(isc::InvalidOperation, std::strerror(result));
     }
     auto_ptr<Impl> impl(new Impl);
     result = pthread_mutex_init(&impl->mutex, &attributes);
@@ -86,7 +86,7 @@ Mutex::Mutex() :
         case EAGAIN:
             throw std::bad_alloc();
         default:
-            isc_throw(isc::InvalidOperation, strerror(result));
+            isc_throw(isc::InvalidOperation, std::strerror(result));
     }
 }
 
@@ -114,7 +114,7 @@ Mutex::lock() {
     assert(impl_ != NULL);
     const int result = pthread_mutex_lock(&impl_->mutex);
     if (result != 0) {
-        isc_throw(isc::InvalidOperation, strerror(result));
+        isc_throw(isc::InvalidOperation, std::strerror(result));
     }
     ++impl_->locked_count; // Only in debug mode
 }
diff --git a/src/lib/util/threads/tests/.gitignore b/src/lib/util/threads/tests/.gitignore
new file mode 100644
index 0000000..d6d1ec8
--- /dev/null
+++ b/src/lib/util/threads/tests/.gitignore
@@ -0,0 +1 @@
+/run_unittests
diff --git a/src/lib/util/threads/tests/Makefile.am b/src/lib/util/threads/tests/Makefile.am
index e86aedc..2d9d4f9 100644
--- a/src/lib/util/threads/tests/Makefile.am
+++ b/src/lib/util/threads/tests/Makefile.am
@@ -1,7 +1,7 @@
 SUBDIRS = .
 
 AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
 # XXX: we'll pollute the top builddir for creating a temporary test file
 # # used to bind a UNIX domain socket so we can minimize the risk of exceeding
 # # the limit of file name path size.
@@ -25,7 +25,7 @@ run_unittests_SOURCES += thread_unittest.cc
 run_unittests_SOURCES += lock_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_LDFLAGS)
 
 run_unittests_LDADD = $(top_builddir)/src/lib/util/threads/libb10-threads.la
 run_unittests_LDADD += \
diff --git a/src/lib/util/threads/thread.cc b/src/lib/util/threads/thread.cc
index 3382fe2..c1c9cdf 100644
--- a/src/lib/util/threads/thread.cc
+++ b/src/lib/util/threads/thread.cc
@@ -115,7 +115,7 @@ Thread::Thread(const boost::function<void ()>& main) :
         case EAGAIN:
             throw std::bad_alloc();
         default: // Other errors. They should not happen.
-            isc_throw(isc::InvalidOperation, strerror(result));
+            isc_throw(isc::InvalidOperation, std::strerror(result));
     }
 }
 
@@ -139,7 +139,7 @@ Thread::wait() {
 
     const int result = pthread_join(impl_->tid_, NULL);
     if (result != 0) {
-        isc_throw(isc::InvalidOperation, strerror(result));
+        isc_throw(isc::InvalidOperation, std::strerror(result));
     }
 
     // Was there an exception in the thread?
diff --git a/tests/tools/perfdhcp/templates/.gitignore b/tests/tools/perfdhcp/templates/.gitignore
new file mode 100644
index 0000000..6f865da
--- /dev/null
+++ b/tests/tools/perfdhcp/templates/.gitignore
@@ -0,0 +1,5 @@
+/test1.hex
+/test2.hex
+/test3.hex
+/test4.hex
+/test5.hex



More information about the bind10-changes mailing list