BIND 10 trac2980, updated. e61a5182aa295c0a96428d09e1d259c9b8b09d0d [2980] Added runUnload tests

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Jun 19 19:39:20 UTC 2013


The branch, trac2980 has been updated
       via  e61a5182aa295c0a96428d09e1d259c9b8b09d0d (commit)
       via  8e94ab0a3baabd2b20f181243626168df4a56ec1 (commit)
       via  390c1a763df3dbfcf0f24394464c0db89aaede9f (commit)
       via  0a4612cfe59ee2149b885550e467f4de42236bbb (commit)
       via  03db051a722775e59b803bd44e02d1faad2a0a9a (commit)
       via  5b6251fb9bb2cd793fd9f86719d1e359aa427cca (commit)
       via  6e6cff79121a939cc961c8f36a489cbb2d0b7074 (commit)
       via  7ef14b47d3bd773155e4b6d9c5a739b0213e8f28 (commit)
      from  2419d18342284ebc4e7099e65f9a8ce2d3dce15c (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 e61a5182aa295c0a96428d09e1d259c9b8b09d0d
Author: Stephen Morris <stephen at isc.org>
Date:   Wed Jun 19 20:38:50 2013 +0100

    [2980] Added runUnload tests
    
    runUnload() still has to be added.

commit 8e94ab0a3baabd2b20f181243626168df4a56ec1
Author: Stephen Morris <stephen at isc.org>
Date:   Wed Jun 19 19:52:26 2013 +0100

    [2980] Extended library manager functionality
    
    Added ability to run the load function and checked that it can
    register callouts.

commit 390c1a763df3dbfcf0f24394464c0db89aaede9f
Author: Stephen Morris <stephen at isc.org>
Date:   Wed Jun 19 16:44:19 2013 +0100

    [2980] Basic library manager functionality added
    
    Also started to add logging.

commit 0a4612cfe59ee2149b885550e467f4de42236bbb
Author: Stephen Morris <stephen at isc.org>
Date:   Tue Jun 18 11:30:07 2013 +0100

    [2980] Basic library manager functionality present
    
    Able to open and close libraries, check for the version()
    function and call it.

commit 03db051a722775e59b803bd44e02d1faad2a0a9a
Author: Stephen Morris <stephen at isc.org>
Date:   Mon Jun 17 19:41:33 2013 +0100

    [2980] LibraryManager basic unit tests written

commit 5b6251fb9bb2cd793fd9f86719d1e359aa427cca
Author: Stephen Morris <stephen at isc.org>
Date:   Mon Jun 17 18:42:22 2013 +0100

    [2980] Move files into isc::hooks namespace

commit 6e6cff79121a939cc961c8f36a489cbb2d0b7074
Author: Stephen Morris <stephen at isc.org>
Date:   Mon Jun 17 18:07:43 2013 +0100

    [2980] Updates to ServerHooks
    
    a) This is now a non-copyable singleton class, and pointers
    to a ServerHooks object have been removed from other classes.
    b) Added a getHookName() method to the CalloutHandle class to allow
    callouts to determine the hook to which they are attached. (This
    change was made principally to aid writing test cases.

commit 7ef14b47d3bd773155e4b6d9c5a739b0213e8f28
Author: Stephen Morris <stephen at isc.org>
Date:   Mon Jun 17 14:21:22 2013 +0100

    [2980] Moved files to "hooks" directory
    
    The hooks framework now has its own directory in "lib" instead of
    living in "util".

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

Summary of changes:
 configure.ac                                       |    4 +
 src/lib/Makefile.am                                |    2 +-
 src/lib/hooks/Makefile.am                          |   53 +++
 src/lib/{util => }/hooks/callout_handle.cc         |   32 +-
 src/lib/{util => }/hooks/callout_handle.h          |   13 +-
 src/lib/{util => }/hooks/callout_manager.cc        |   22 +-
 src/lib/{util => }/hooks/callout_manager.h         |   36 +-
 .../bench/dummy_work.cc => lib/hooks/hooks.h}      |   18 +-
 src/lib/{nsas/nsas_log.cc => hooks/hooks_log.cc}   |    8 +-
 .../{resolve/resolve_log.h => hooks/hooks_log.h}   |   39 +-
 src/lib/hooks/hooks_messages.mes                   |   63 +++
 src/lib/{util => }/hooks/library_handle.cc         |    6 +-
 src/lib/{util => }/hooks/library_handle.h          |    2 +-
 src/lib/hooks/library_manager.cc                   |  197 +++++++++
 src/lib/hooks/library_manager.h                    |  188 +++++++++
 src/lib/{util => }/hooks/server_hooks.cc           |   63 ++-
 src/lib/{util => }/hooks/server_hooks.h            |   62 ++-
 src/lib/hooks/tests/Makefile.am                    |   86 ++++
 src/lib/hooks/tests/basic_callout_library.cc       |  116 ++++++
 .../tests/callout_handle_unittest.cc               |   20 +-
 .../tests/callout_manager_unittest.cc              |   50 +--
 src/lib/{util => hooks}/tests/handles_unittest.cc  |   69 +++-
 .../hooks/tests/incorrect_version_library.cc}      |   21 +-
 src/lib/hooks/tests/library_manager_unittest.cc.in |  424 ++++++++++++++++++++
 src/lib/hooks/tests/load_callout_library.cc        |  121 ++++++
 .../hooks/tests/load_error_callout_library.cc}     |   45 ++-
 .../hooks/tests/marker_file.h.in}                  |   21 +-
 .../hooks/tests/no_version_library.cc}             |   21 +-
 src/lib/{nsas => hooks}/tests/run_unittests.cc     |    3 +-
 .../{util => hooks}/tests/server_hooks_unittest.cc |   74 +++-
 .../hooks/tests/unload_callout_library.cc}         |   55 +--
 src/lib/util/Makefile.am                           |    4 -
 src/lib/util/tests/Makefile.am                     |    4 -
 33 files changed, 1701 insertions(+), 241 deletions(-)
 create mode 100644 src/lib/hooks/Makefile.am
 rename src/lib/{util => }/hooks/callout_handle.cc (83%)
 rename src/lib/{util => }/hooks/callout_handle.h (96%)
 rename src/lib/{util => }/hooks/callout_manager.cc (92%)
 rename src/lib/{util => }/hooks/callout_manager.h (94%)
 copy src/{bin/resolver/bench/dummy_work.cc => lib/hooks/hooks.h} (81%)
 copy src/lib/{nsas/nsas_log.cc => hooks/hooks_log.cc} (88%)
 copy src/lib/{resolve/resolve_log.h => hooks/hooks_log.h} (55%)
 create mode 100644 src/lib/hooks/hooks_messages.mes
 rename src/lib/{util => }/hooks/library_handle.cc (93%)
 rename src/lib/{util => }/hooks/library_handle.h (99%)
 create mode 100644 src/lib/hooks/library_manager.cc
 create mode 100644 src/lib/hooks/library_manager.h
 rename src/lib/{util => }/hooks/server_hooks.cc (79%)
 rename src/lib/{util => }/hooks/server_hooks.h (81%)
 create mode 100644 src/lib/hooks/tests/Makefile.am
 create mode 100644 src/lib/hooks/tests/basic_callout_library.cc
 rename src/lib/{util => hooks}/tests/callout_handle_unittest.cc (96%)
 rename src/lib/{util => hooks}/tests/callout_manager_unittest.cc (96%)
 rename src/lib/{util => hooks}/tests/handles_unittest.cc (94%)
 copy src/{bin/resolver/bench/dummy_work.cc => lib/hooks/tests/incorrect_version_library.cc} (71%)
 create mode 100644 src/lib/hooks/tests/library_manager_unittest.cc.in
 create mode 100644 src/lib/hooks/tests/load_callout_library.cc
 copy src/{bin/resolver/bench/dummy_work.h => lib/hooks/tests/load_error_callout_library.cc} (57%)
 copy src/{bin/resolver/bench/dummy_work.cc => lib/hooks/tests/marker_file.h.in} (75%)
 copy src/{bin/resolver/bench/dummy_work.cc => lib/hooks/tests/no_version_library.cc} (78%)
 copy src/lib/{nsas => hooks}/tests/run_unittests.cc (99%)
 rename src/lib/{util => hooks}/tests/server_hooks_unittest.cc (78%)
 copy src/{bin/resolver/bench/naive_resolver.h => lib/hooks/tests/unload_callout_library.cc} (51%)

-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index fc216c4..ff54312 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1298,6 +1298,8 @@ AC_CONFIG_FILES([Makefile
                  src/lib/datasrc/tests/memory/testdata/Makefile
                  src/lib/xfr/Makefile
                  src/lib/xfr/tests/Makefile
+                 src/lib/hooks/Makefile
+                 src/lib/hooks/tests/Makefile
                  src/lib/log/Makefile
                  src/lib/log/interprocess/Makefile
                  src/lib/log/interprocess/tests/Makefile
@@ -1400,6 +1402,8 @@ AC_OUTPUT([doc/version.ent
            src/lib/cc/session_config.h.pre
            src/lib/cc/tests/session_unittests_config.h
            src/lib/datasrc/datasrc_config.h.pre
+           src/lib/hooks/tests/library_manager_unittest.cc
+           src/lib/hooks/tests/marker_file.h
            src/lib/log/tests/console_test.sh
            src/lib/log/tests/destination_test.sh
            src/lib/log/tests/init_logger_test.sh
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index f636c0d..79a8263 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = exceptions util log cryptolink dns cc config acl xfr bench \
+SUBDIRS = exceptions util log hooks cryptolink dns cc config acl xfr bench \
           asiolink asiodns nsas cache resolve testutils datasrc \
           server_common python dhcp dhcpsrv statistics
diff --git a/src/lib/hooks/Makefile.am b/src/lib/hooks/Makefile.am
new file mode 100644
index 0000000..eee2a72
--- /dev/null
+++ b/src/lib/hooks/Makefile.am
@@ -0,0 +1,53 @@
+SUBDIRS = . tests
+
+AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS  = $(B10_CXXFLAGS)
+
+# Some versions of GCC warn about some versions of Boost regarding
+# missing initializer for members in its posix_time.
+# https://svn.boost.org/trac/boost/ticket/3477
+# But older GCC compilers don't have the flag.
+AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
+
+
+# Define rule to build logging source files from message file
+hooks_messages.h hooks_messages.cc: hooks_messages.mes
+	$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/hooks/hooks_messages.mes
+
+# Tell automake that the message files are built as part of the build process
+# (so that they are built before the main library is built).
+BUILT_SOURCES = hooks_messages.h hooks_messages.cc
+
+# Ensure that the message file is included in the distribution
+EXTRA_DIST = hooks_messages.mes
+
+# Get rid of generated message files on a clean
+CLEANFILES = *.gcno *.gcda hooks_messages.h hooks_messages.cc
+
+lib_LTLIBRARIES = libb10-hooks.la
+libb10_hooks_la_SOURCES  =
+libb10_hooks_la_SOURCES += callout_handle.cc callout_handle.h
+libb10_hooks_la_SOURCES += callout_manager.cc callout_manager.h
+libb10_hooks_la_SOURCES += hooks.h
+libb10_hooks_la_SOURCES += hooks_log.cc hooks_log.h
+libb10_hooks_la_SOURCES += library_handle.cc library_handle.h
+libb10_hooks_la_SOURCES += library_manager.cc library_manager.h
+libb10_hooks_la_SOURCES += server_hooks.cc server_hooks.h
+
+nodist_libb10_hooks_la_SOURCES = hooks_messages.cc hooks_messages.h
+
+libb10_hooks_la_CXXFLAGS = $(AM_CXXFLAGS)
+libb10_hooks_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+libb10_hooks_la_LDFLAGS  = $(AM_LDFLAGS) -ldl
+libb10_hooks_la_LIBADD  =
+libb10_hooks_la_LIBADD += $(top_builddir)/src/lib/log/libb10-log.la
+libb10_hooks_la_LIBADD += $(top_builddir)/src/lib/util/libb10-util.la
+libb10_hooks_la_LIBADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
+
+
+if USE_CLANGPP
+# Disable unused parameter warning caused by some of the
+# Boost headers when compiling with clang.
+libb10_hooks_la_CXXFLAGS += -Wno-unused-parameter
+endif
diff --git a/src/lib/hooks/callout_handle.cc b/src/lib/hooks/callout_handle.cc
new file mode 100644
index 0000000..27d76d7
--- /dev/null
+++ b/src/lib/hooks/callout_handle.cc
@@ -0,0 +1,141 @@
+// Copyright (C) 2013  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 <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+#include <hooks/library_handle.h>
+#include <hooks/server_hooks.h>
+
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace std;
+
+namespace isc {
+namespace hooks {
+
+// Constructor.
+CalloutHandle::CalloutHandle(const boost::shared_ptr<CalloutManager>& manager)
+    : arguments_(), context_collection_(), manager_(manager), skip_(false) {
+
+    // Call the "context_create" hook.  We should be OK doing this - although
+    // the constructor has not finished running, all the member variables
+    // have been created.
+    manager_->callCallouts(ServerHooks::CONTEXT_CREATE, *this);
+}
+
+// Destructor
+CalloutHandle::~CalloutHandle() {
+
+    // Call the "context_destroy" hook.  We should be OK doing this - although
+    // the destructor is being called, all the member variables are still in
+    // existence.
+    manager_->callCallouts(ServerHooks::CONTEXT_DESTROY, *this);
+}
+
+// Return the name of all argument items.
+
+vector<string>
+CalloutHandle::getArgumentNames() const {
+
+    vector<string> names;
+    for (ElementCollection::const_iterator i = arguments_.begin();
+         i != arguments_.end(); ++i) {
+        names.push_back(i->first);
+    }
+
+    return (names);
+}
+
+// Return the library handle allowing the callout to access the CalloutManager
+// registration/deregistration functions.
+
+LibraryHandle&
+CalloutHandle::getLibraryHandle() const {
+    return (manager_->getLibraryHandle());
+}
+
+// Return the context for the currently pointed-to library.  This version is
+// used by the "setContext()" method and creates a context for the current
+// library if it does not exist.
+
+CalloutHandle::ElementCollection&
+CalloutHandle::getContextForLibrary() {
+    int libindex = manager_->getLibraryIndex();
+
+    // Access a reference to the element collection for the given index,
+    // creating a new element collection if necessary, and return it.
+    return (context_collection_[libindex]);
+}
+
+// The "const" version of the above, used by the "getContext()" method.  If
+// the context for the current library doesn't exist, throw an exception.
+
+const CalloutHandle::ElementCollection&
+CalloutHandle::getContextForLibrary() const {
+    int libindex = manager_->getLibraryIndex();
+
+    ContextCollection::const_iterator libcontext =
+        context_collection_.find(libindex);
+    if (libcontext == context_collection_.end()) {
+        isc_throw(NoSuchCalloutContext, "unable to find callout context "
+                  "associated with the current library index (" << libindex <<
+                  ")");
+    }
+
+    // Return a reference to the context's element collection.
+    return (libcontext->second);
+}
+
+// Return the name of all items in the context associated with the current]
+// library.
+
+vector<string>
+CalloutHandle::getContextNames() const {
+
+    vector<string> names;
+
+    const ElementCollection& elements = getContextForLibrary();
+    for (ElementCollection::const_iterator i = elements.begin();
+         i != elements.end(); ++i) {
+        names.push_back(i->first);
+    }
+
+    return (names);
+}
+
+// Return name of current hook (the hook to which the current callout is
+// attached) or the empty string if not called within the context of a
+// callout.
+
+string
+CalloutHandle::getHookName() const {
+    // Get the current hook index.
+    int index = manager_->getHookIndex();
+
+    // ... and look up the hook.
+    string hook = "";
+    try {
+        hook = ServerHooks::getServerHooks().getName(index);
+    } catch (const NoSuchHook&) {
+        // Hook index is invalid, so probably called outside of a callout.
+        // This is a no-op.
+    }
+
+    return (hook);
+}
+
+} // namespace util
+} // namespace isc
diff --git a/src/lib/hooks/callout_handle.h b/src/lib/hooks/callout_handle.h
new file mode 100644
index 0000000..9603f5c
--- /dev/null
+++ b/src/lib/hooks/callout_handle.h
@@ -0,0 +1,360 @@
+// Copyright (C) 2013  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 CALLOUT_HANDLE_H
+#define CALLOUT_HANDLE_H
+
+#include <exceptions/exceptions.h>
+#include <hooks/library_handle.h>
+
+#include <boost/any.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace isc {
+namespace hooks {
+
+/// @brief No such argument
+///
+/// Thrown if an attempt is made access an argument that does not exist.
+
+class NoSuchArgument : public Exception {
+public:
+    NoSuchArgument(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
+/// @brief No such callout context item
+///
+/// Thrown if an attempt is made to get an item of data from this callout's
+/// context and either the context or an item in the context with that name
+/// does not exist.
+
+class NoSuchCalloutContext : public Exception {
+public:
+    NoSuchCalloutContext(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
+// Forward declaration of the library handle and related collection classes.
+
+class CalloutManager;
+class LibraryHandle;
+
+/// @brief Per-packet callout handle
+///
+/// An object of this class is associated with every packet (or request)
+/// processed by the server.  It forms the principle means of passing data
+/// between the server and the user-library callouts.
+///
+/// The class allows access to the following information:
+///
+/// - Arguments.  When the callouts associated with a hook are called, they
+///   are passed information by the server (and can return information to it)
+///   through name/value pairs.  Each of these pairs is an argument and the
+///   information is accessed through the {get,set}Argument() methods.
+///
+/// - Per-packet context.  Each packet has a context associated with it, this
+///   context being  on a per-library basis.  In other words, As a packet passes
+///   through the callouts associated with a given library, the callouts can
+///   associate and retrieve information with the packet.  The per-library
+///   nature of the context means that the callouts within a given library can
+///   pass packet-specific information between one another, but they cannot pass
+///   information to callous within another library.  Typically such context
+///   is created in the "context_create" callout and destroyed in the
+///   "context_destroy" callout.  The information is accessed through the
+///   {get,set}Context() methods.
+///
+/// - Per-library handle.  Allows the callout to dynamically register and
+///   deregister callouts. (In the latter case, only functions registered by
+///   functions in the same library as the callout doing the deregistration
+///   can be removed: callouts registered by other libraries cannot be
+///   modified.)
+
+class CalloutHandle {
+public:
+
+    /// Typedef to allow abbreviation of iterator specification in methods.
+    /// The std::string is the argument name and the "boost::any" is the
+    /// corresponding value associated with it.
+    typedef std::map<std::string, boost::any> ElementCollection;
+
+    /// Typedef to allow abbreviations in specifications when accessing
+    /// context.  The ElementCollection is the name/value collection for
+    /// a particular context.  The "int" corresponds to the index of an
+    /// associated library - there is a 1:1 correspondence between libraries
+    /// and a name.value collection.
+    ///
+    /// The collection of contexts is stored in a map, as not every library
+    /// will require creation of a context associated with each packet.  In
+    /// addition, the structure is more flexible in that the size does not
+    /// need to be set when the CalloutHandle is constructed.
+    typedef std::map<int, ElementCollection> ContextCollection;
+
+    /// @brief Constructor
+    ///
+    /// Creates the object and calls the callouts on the "context_create"
+    /// hook.
+    ///
+    /// @param manager Pointer to the callout manager object.
+    CalloutHandle(const boost::shared_ptr<CalloutManager>& manager);
+
+    /// @brief Destructor
+    ///
+    /// Calls the context_destroy callback to release any per-packet context.
+    ~CalloutHandle();
+
+    /// @brief Set argument
+    ///
+    /// Sets the value of an argument.  The argument is created if it does not
+    /// already exist.
+    ///
+    /// @param name Name of the argument.
+    /// @param value Value to set.  That can be of any data type.
+    template <typename T>
+    void setArgument(const std::string& name, T value) {
+        arguments_[name] = value;
+    }
+
+    /// @brief Get argument
+    ///
+    /// Gets the value of an argument.
+    ///
+    /// @param name Name of the element in the argument list to get.
+    /// @param value [out] Value to set.  The type of "value" is important:
+    ///        it must match the type of the value set.
+    ///
+    /// @throw NoSuchArgument No argument with the given name is present.
+    /// @throw boost::bad_any_cast An argument with the given name is present,
+    ///        but the data type of the value is not the same as the type of
+    ///        the variable provided to receive the value.
+    template <typename T>
+    void getArgument(const std::string& name, T& value) const {
+        ElementCollection::const_iterator element_ptr = arguments_.find(name);
+        if (element_ptr == arguments_.end()) {
+            isc_throw(NoSuchArgument, "unable to find argument with name " <<
+                      name);
+        }
+
+        value = boost::any_cast<T>(element_ptr->second);
+    }
+    
+    /// @brief Get argument names
+    ///
+    /// Returns a vector holding the names of arguments in the argument
+    /// vector.
+    ///
+    /// @return Vector of strings reflecting argument names.
+    std::vector<std::string> getArgumentNames() const;
+
+    /// @brief Delete argument
+    ///
+    /// Deletes an argument of the given name.  If an argument of that name
+    /// does not exist, the method is a no-op.
+    ///
+    /// N.B. If the element is a raw pointer, the pointed-to data is NOT deleted
+    /// by this method.
+    ///
+    /// @param name Name of the element in the argument list to set.
+    void deleteArgument(const std::string& name) {
+        static_cast<void>(arguments_.erase(name));
+    }
+
+    /// @brief Delete all arguments
+    ///
+    /// Deletes all arguments associated with this context.
+    ///
+    /// N.B. If any elements are raw pointers, the pointed-to data is NOT
+    /// deleted by this method.
+    void deleteAllArguments() {
+        arguments_.clear();
+    }
+
+    /// @brief Set skip flag
+    ///
+    /// Sets the "skip" variable in the callout handle.  This variable is
+    /// interrogated by the server to see if the remaining callouts associated
+    /// with the current hook should be bypassed.
+    ///
+    /// @param skip New value of the "skip" flag.
+    void setSkip(bool skip) {
+        skip_ = skip;
+    }
+
+    /// @brief Get skip flag
+    ///
+    /// Gets the current value of the "skip" flag.
+    ///
+    /// @return Current value of the skip flag.
+    bool getSkip() const {
+        return (skip_);
+    }
+
+    /// @brief Access current library handle
+    ///
+    /// Returns a reference to the current library handle.  This function is
+    /// only available when called by a callout (which in turn is called
+    /// through the "callCallouts" method), as it is only then that the current
+    /// library index is valid.  A callout uses the library handle to
+    /// dynamically register or deregister callouts.
+    ///
+    /// @return Reference to the library handle.
+    ///
+    /// @throw InvalidIndex thrown if this method is called when the current
+    ///        library index is invalid (typically if it is called outside of
+    ///        the active callout).
+    LibraryHandle& getLibraryHandle() const;
+
+    /// @brief Set context
+    ///
+    /// Sets an element in the context associated with the current library.  If
+    /// an element of the name is already present, it is replaced.
+    ///
+    /// @param name Name of the element in the context to set.
+    /// @param value Value to set.
+    template <typename T>
+    void setContext(const std::string& name, T value) {
+        getContextForLibrary()[name] = value;
+    }
+
+    /// @brief Get context
+    ///
+    /// Gets an element from the context associated with the current library.
+    ///
+    /// @param name Name of the element in the context to get.
+    /// @param value [out] Value to set.  The type of "value" is important:
+    ///        it must match the type of the value set.
+    ///
+    /// @throw NoSuchCalloutContext Thrown if no context element with the name
+    ///        "name" is present.
+    /// @throw boost::bad_any_cast Thrown if the context element is present
+    ///        but the type of the data is not the same as the type of the
+    ///        variable provided to receive its value.
+    template <typename T>
+    void getContext(const std::string& name, T& value) const {
+        const ElementCollection& lib_context = getContextForLibrary();
+
+        ElementCollection::const_iterator element_ptr = lib_context.find(name);
+        if (element_ptr == lib_context.end()) {
+            isc_throw(NoSuchCalloutContext, "unable to find callout context "
+                      "item " << name << " in the context associated with "
+                      "current library");
+        }
+
+        value = boost::any_cast<T>(element_ptr->second);
+    }
+    
+    /// @brief Get context names
+    ///
+    /// Returns a vector holding the names of items in the context associated
+    /// with the current library.
+    ///
+    /// @return Vector of strings reflecting the names of items in the callout
+    ///         context associated with the current library.
+    std::vector<std::string> getContextNames() const;
+
+    /// @brief Delete context element
+    ///
+    /// Deletes an item of the given name from the context associated with the
+    /// current library.  If an item  of that name does not exist, the method is
+    /// a no-op.
+    ///
+    /// N.B. If the element is a raw pointer, the pointed-to data is NOT deleted
+    /// by this.
+    ///
+    /// @param name Name of the context item to delete.
+    void deleteContext(const std::string& name) {
+        static_cast<void>(getContextForLibrary().erase(name));
+    }
+
+    /// @brief Delete all context items
+    ///
+    /// Deletes all items from the context associated with the current library.
+    ///
+    /// N.B. If any elements are raw pointers, the pointed-to data is NOT
+    /// deleted by this.
+    void deleteAllContext() {
+        getContextForLibrary().clear();
+    }
+
+    /// @brief Get hook name
+    ///
+    /// Get the name of the hook to which the current callout is attached.
+    /// This can be the null string if the CalloutHandle is being accessed
+    /// outside of the CalloutManager's "callCallouts" method.
+    ///
+    /// @return Name of the current hook or the empty string if none.
+    std::string getHookName() const;
+
+private:
+    /// @brief Check index
+    ///
+    /// Gets the current library index, throwing an exception if it is not set
+    /// or is invalid for the current library collection.
+    ///
+    /// @return Current library index, valid for this library collection.
+    ///
+    /// @throw InvalidIndex current library index is not valid for the library
+    ///        handle collection.
+    int getLibraryIndex() const;
+
+    /// @brief Return reference to context for current library
+    ///
+    /// Called by all context-setting functions, this returns a reference to
+    /// the callout context for the current library, creating a context if it
+    /// does not exist.
+    ///
+    /// @return Reference to the collection of name/value pairs associated
+    ///         with the current library.
+    ///
+    /// @throw InvalidIndex current library index is not valid for the library
+    ///        handle collection.
+    ElementCollection& getContextForLibrary();
+
+    /// @brief Return reference to context for current library (const version)
+    ///
+    /// Called by all context-accessing functions, this a reference to the
+    /// callout context for the current library.  An exception is thrown if
+    /// it does not exist.
+    ///
+    /// @return Reference to the collection of name/value pairs associated
+    ///         with the current library.
+    ///
+    /// @throw NoSuchCalloutContext Thrown if there is no ElementCollection
+    ///        associated with the current library.
+    const ElementCollection& getContextForLibrary() const;
+
+    // Member variables
+
+    /// Collection of arguments passed to the callouts
+    ElementCollection arguments_;
+
+    /// Context collection - there is one entry per library context.
+    ContextCollection context_collection_;
+
+    /// Callout manager.
+    boost::shared_ptr<CalloutManager> manager_;
+
+    /// "Skip" flag, indicating if the caller should bypass remaining callouts.
+    bool skip_;
+};
+
+} // namespace util
+} // namespace isc
+
+
+#endif // CALLOUT_HANDLE_H
diff --git a/src/lib/hooks/callout_manager.cc b/src/lib/hooks/callout_manager.cc
new file mode 100644
index 0000000..6071d25
--- /dev/null
+++ b/src/lib/hooks/callout_manager.cc
@@ -0,0 +1,186 @@
+// Copyright (C) 2013  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 <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+
+#include <boost/static_assert.hpp>
+
+#include <algorithm>
+#include <functional>
+#include <utility>
+
+using namespace std;
+
+namespace isc {
+namespace hooks {
+
+// Register a callout for the current library.
+
+void
+CalloutManager::registerCallout(const std::string& name, CalloutPtr callout) {
+    // Sanity check that the current library index is set to a valid value.
+    checkLibraryIndex(current_library_);
+
+    // Get the index associated with this hook (validating the name in the
+    // process).
+    int hook_index = ServerHooks::getServerHooks().getIndex(name);
+
+    // Iterate through the callout vector for the hook from start to end,
+    // looking for the first entry where the library index is greater than
+    // the present index.
+    for (CalloutVector::iterator i = hook_vector_[hook_index].begin();
+         i != hook_vector_[hook_index].end(); ++i) {
+        if (i->first > current_library_) {
+            // Found an element whose library index number is greater than the
+            // current index, so insert the new element ahead of this one.
+            hook_vector_[hook_index].insert(i, make_pair(current_library_,
+                                                         callout));
+            return;
+        }
+    }
+
+    // Reached the end of the vector, so there is no element in the (possibly
+    // empty) set of callouts with a library index greater than the current
+    // library index.  Inset the callout at the end of the list.
+    hook_vector_[hook_index].push_back(make_pair(current_library_, callout));
+}
+
+// Check if callouts are present for a given hook index.
+
+bool
+CalloutManager::calloutsPresent(int hook_index) const {
+    // Validate the hook index.
+    if ((hook_index < 0) || (hook_index >= hook_vector_.size())) {
+        isc_throw(NoSuchHook, "hook index " << hook_index <<
+                  " is not valid for the list of registered hooks");
+    }
+
+    // Valid, so are there any callouts associated with that hook?
+    return (!hook_vector_[hook_index].empty());
+}
+
+// Call all the callouts for a given hook.
+
+void
+CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
+
+    // Only initialize and iterate if there are callouts present.  This check
+    // also catches the case of an invalid index.
+    if (calloutsPresent(hook_index)) {
+
+        // Clear the "skip" flag so we don't carry state from a previous call.
+        callout_handle.setSkip(false);
+
+        // Set the current hook index.  This is used should a callout wish to
+        // determine to what hook it is attached.
+        current_hook_ = hook_index;
+
+        // Duplicate the callout vector for this hook and work through that.
+        // This step is needed because we allow dynamic registration and
+        // deregistration of callouts.  If a callout attached to a hook modified
+        // the list of callouts on that hook, the underlying CalloutVector would
+        // change and potentially affect the iteration through that vector.
+        CalloutVector callouts(hook_vector_[hook_index]);
+
+        // Call all the callouts.
+        for (CalloutVector::const_iterator i = callouts.begin();
+             i != callouts.end(); ++i) {
+            // In case the callout tries to register or deregister a callout,
+            // set the current library index to the index associated with the
+            // library that registered the callout being called.
+            current_library_ = i->first;
+
+            // Call the callout
+            // @todo Log the return status if non-zero
+            static_cast<void>((*i->second)(callout_handle));
+        }
+
+        // Reset the current hook and library indexs to an invalid value to
+        // catch any programming errors.
+        current_hook_ = -1;
+        current_library_ = -1;
+    }
+}
+
+// Deregister a callout registered by the current library on a particular hook.
+
+bool
+CalloutManager::deregisterCallout(const std::string& name, CalloutPtr callout) {
+    // Sanity check that the current library index is set to a valid value.
+    checkLibraryIndex(current_library_);
+
+    // Get the index associated with this hook (validating the name in the
+    // process).
+    int hook_index = ServerHooks::getServerHooks().getIndex(name);
+
+    /// Construct a CalloutEntry matching the current library and the callout
+    /// we want to remove.
+    CalloutEntry target(current_library_, callout);
+
+    /// To decide if any entries were removed, we'll record the initial size
+    /// of the callout vector for the hook, and compare it with the size after
+    /// the removal.
+    size_t initial_size = hook_vector_[hook_index].size();
+
+    // The next bit is standard STL (see "Item 33" in "Effective STL" by
+    // Scott Meyers).
+    //
+    // remove_if reorders the hook vector so that all items not matching
+    // the predicate are at the start of the vector and returns a pointer
+    // to the next element. (In this case, the predicate is that the item
+    // is equal to the value of the passed callout.)  The erase() call
+    // removes everything from that element to the end of the vector, i.e.
+    // all the matching elements.
+    hook_vector_[hook_index].erase(remove_if(hook_vector_[hook_index].begin(),
+                                             hook_vector_[hook_index].end(),
+                                             bind1st(equal_to<CalloutEntry>(),
+                                                     target)),
+                                   hook_vector_[hook_index].end());
+
+    // Return an indication of whether anything was removed.
+    return (initial_size != hook_vector_[hook_index].size());
+}
+
+// Deregister all callouts on a given hook.
+
+bool
+CalloutManager::deregisterAllCallouts(const std::string& name) {
+
+    // Get the index associated with this hook (validating the name in the
+    // process).
+    int hook_index = ServerHooks::getServerHooks().getIndex(name);
+
+    /// Construct a CalloutEntry matching the current library (the callout
+    /// pointer is NULL as we are not checking that).
+    CalloutEntry target(current_library_, NULL);
+
+    /// To decide if any entries were removed, we'll record the initial size
+    /// of the callout vector for the hook, and compare it with the size after
+    /// the removal.
+    size_t initial_size = hook_vector_[hook_index].size();
+
+    // Remove all callouts matching this library.
+    hook_vector_[hook_index].erase(remove_if(hook_vector_[hook_index].begin(),
+                                             hook_vector_[hook_index].end(),
+                                             bind1st(CalloutLibraryEqual(),
+                                                     target)),
+                                   hook_vector_[hook_index].end());
+
+    // Return an indication of whether anything was removed.
+    return (initial_size != hook_vector_[hook_index].size());
+}
+
+} // namespace util
+} // namespace isc
diff --git a/src/lib/hooks/callout_manager.h b/src/lib/hooks/callout_manager.h
new file mode 100644
index 0000000..f28bc1c
--- /dev/null
+++ b/src/lib/hooks/callout_manager.h
@@ -0,0 +1,305 @@
+// Copyright (C) 2013  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 CALLOUT_MANAGER_H
+#define CALLOUT_MANAGER_H
+
+#include <exceptions/exceptions.h>
+#include <hooks/library_handle.h>
+#include <hooks/server_hooks.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <map>
+#include <string>
+
+namespace isc {
+namespace hooks {
+
+/// @brief No such library
+///
+/// Thrown if an attempt is made to set the current library index to a value
+/// that is invalid for the number of loaded libraries.
+class NoSuchLibrary : public Exception {
+public:
+    NoSuchLibrary(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
+
+/// @brief Callout Manager
+///
+/// This class manages the registration, deregistration and execution of the
+/// library callouts.
+///
+/// In operation, the class needs to know two items of data:
+///
+/// - The list of server hooks, which is used in two ways.  Firstly, when a
+///   callout registers or deregisters a hook, it does so by name: the
+///   @ref isc::util::ServerHooks object supplies the names of registered
+///   hooks.  Secondly, when the callouts associated with a hook are called by
+///   the server, the server supplies the index of the relevant hook: this is
+///   validated by reference to the list of hook.
+///
+/// - The number of loaded libraries.  Each callout registered by a user
+///   library is associated with that library, the callout manager storing both
+///   a pointer to the callout and the index of the library in the list of
+///   loaded libraries.  Callouts are allowed to dynamically register and
+///   deregister callouts in the same library (including themselves): they
+///   cannot affect callouts registered by another library.  When calling a
+///   callout, the callout manager maintains the idea of a "current library
+///   index": if the callout calls one of the callout registration functions 
+///   (indirectly via the @ref LibraryHandle object), the registration
+///   functions use the "current library index" in their processing.
+///
+/// These two items of data are supplied when an object of this class is
+/// constructed.
+///
+/// Note that the callout function do not access the library manager: instead,
+/// they use a LibraryHandle object.  This contains an internal pointer to
+/// the CalloutManager, but provides a restricted interface.  In that way,
+/// callouts are unable to affect callouts supplied by other libraries.
+
+class CalloutManager {
+private:
+
+    // Private typedefs
+
+    /// Element in the vector of callouts.  The elements in the pair are the
+    /// index of the library from which this callout was registered, and a#
+    /// pointer to the callout itself.
+    typedef std::pair<int, CalloutPtr> CalloutEntry;
+
+    /// An element in the hook vector. Each element is a vector of callouts
+    /// associated with a given hook.
+    typedef std::vector<CalloutEntry> CalloutVector;
+
+public:
+
+    /// @brief Constructor
+    ///
+    /// Initializes member variables, in particular sizing the hook vector
+    /// (the vector of callout vectors) to the appropriate size.
+    ///
+    /// @param num_libraries Number of loaded libraries.
+    ///
+    /// @throw isc::BadValue if the number of libraries is less than or equal
+    ///        to 0, or if the pointer to the server hooks object is empty.
+    CalloutManager(int num_libraries)
+        : current_hook_(-1), current_library_(-1), hook_vector_(),
+          library_handle_(this), num_libraries_(num_libraries)
+    {
+        if (num_libraries <= 0) {
+            isc_throw(isc::BadValue, "number of libraries passed to the "
+                      "CalloutManager must be >= 0");
+        }
+
+        // Parameters OK, do operations that depend on them.
+        hook_vector_.resize(ServerHooks::getServerHooks().getCount());
+    }
+
+    /// @brief Register a callout on a hook for the current library
+    ///
+    /// Registers a callout function for the current library with a given hook
+    /// (the index of the "current library" being given by the current_library_
+    /// member).  The callout is added to the end of the callouts for this
+    /// library that are associated with that hook.
+    ///
+    /// @param name Name of the hook to which the callout is added.
+    /// @param callout Pointer to the callout function to be registered.
+    ///
+    /// @throw NoSuchHook The hook name is unrecognised.
+    /// @throw Unexpected The hook name is valid but an internal data structure
+    ///        is of the wrong size.
+    void registerCallout(const std::string& name, CalloutPtr callout);
+
+    /// @brief De-Register a callout on a hook for the current library
+    ///
+    /// Searches through the functions registered by the the current library
+    /// (the index of the "current library" being given by the current_library_
+    /// member) with the named hook and removes all entries matching the
+    /// callout.
+    ///
+    /// @param name Name of the hook from which the callout is removed.
+    /// @param callout Pointer to the callout function to be removed.
+    ///
+    /// @return true if a one or more callouts were deregistered.
+    ///
+    /// @throw NoSuchHook The hook name is unrecognised.
+    /// @throw Unexpected The hook name is valid but an internal data structure
+    ///        is of the wrong size.
+    bool deregisterCallout(const std::string& name, CalloutPtr callout);
+
+    /// @brief Removes all callouts on a hook for the current library
+    ///
+    /// Removes all callouts associated with a given hook that were registered
+    /// by the current library (the index of the "current library" being given
+    /// by the current_library_ member).
+    ///
+    /// @param name Name of the hook from which the callouts are removed.
+    ///
+    /// @return true if one or more callouts were deregistered.
+    ///
+    /// @throw NoSuchHook Thrown if the hook name is unrecognised.
+    bool deregisterAllCallouts(const std::string& name);
+
+    /// @brief Checks if callouts are present on a hook
+    ///
+    /// Checks all loaded libraries and returns true if at least one callout
+    /// has been registered by any of them for the given hook.
+    ///
+    /// @param hook_index Hook index for which callouts are checked.
+    ///
+    /// @return true if callouts are present, false if not.
+    ///
+    /// @throw NoSuchHook Given index does not correspond to a valid hook.
+    bool calloutsPresent(int hook_index) const;
+
+    /// @brief Calls the callouts for a given hook
+    ///
+    /// Iterates through the libray handles and calls the callouts associated
+    /// with the given hook index.
+    ///
+    /// @note This method invalidates the current library index set with
+    ///       setLibraryIndex().
+    ///
+    /// @param hook_index Index of the hook to call.
+    /// @param callout_handle Reference to the CalloutHandle object for the
+    ///        current object being processed.
+    void callCallouts(int hook_index, CalloutHandle& callout_handle);
+
+    /// @brief Get current hook index
+    ///
+    /// Made available during callCallouts, this is the index of the hook
+    /// on which callouts are being called.
+    int getHookIndex() const {
+        return (current_hook_);
+    }
+
+    /// @brief Get number of libraries
+    ///
+    /// Returns the number of libraries that this CalloutManager is expected
+    /// to serve.  This is the number passed to its constructor.
+    ///
+    /// @return Number of libraries server by this CalloutManager.
+    int getNumLibraries() const {
+        return (num_libraries_);
+    }
+
+    /// @brief Get current library index
+    ///
+    /// Returns the index of the "current" library.  This the index associated
+    /// with the currently executing callout when callCallouts is executing.
+    /// When callCallouts() is not executing (as is the case when the load()
+    /// function in a user-library is called during the library load process),
+    /// the index can be set by setLibraryIndex().
+    ///
+    /// @note The value set by this method is lost after a call to
+    ///       callCallouts.
+    ///
+    /// @return Current library index.
+    int getLibraryIndex() const {
+        return (current_library_);
+    }
+
+    /// @brief Set current library index
+    ///
+    /// Sets the current library index.  This must be in the range 0 to
+    /// (numlib - 1), where "numlib" is the number of libraries loaded in the
+    /// system, this figure being passed to this object at construction time.
+    ///
+    /// @param library_index New library index.
+    ///
+    /// @throw NoSuchLibrary if the index is not valid.
+    void setLibraryIndex(int library_index) {
+        checkLibraryIndex(library_index);
+        current_library_ = library_index;
+    }
+
+    /// @brief Return library handle
+    ///
+    /// The library handle is available to the user callout via the callout
+    /// handle object.  It provides a cut-down view of the CalloutManager,
+    /// allowing the callout to register and deregister callouts in the
+    /// library of which it is part, whilst denying access to anything that
+    /// may affect other libraries.
+    ///
+    /// @return Reference to callout handle for this manager
+    LibraryHandle& getLibraryHandle() {
+        return (library_handle_);
+    }
+
+private:
+    /// @brief Check library index
+    ///
+    /// Ensures that the current library index is valid.  This is called by
+    /// the hook registration functions.
+    ///
+    /// @param library_index Value to check for validity as a library index.
+    ///
+    /// @throw NoSuchLibrary Library index is not valid.
+    void checkLibraryIndex(int library_index) const {
+        if ((library_index < 0) || (library_index >= num_libraries_)) {
+            isc_throw(NoSuchLibrary, "library index " << library_index <<
+                      " is not valid for the number of loaded libraries (" <<
+                      num_libraries_ << ")");
+        }
+    }
+
+    /// @brief Compare two callout entries for library equality
+    ///
+    /// This is used in callout removal code when all callouts on a hook for a
+    /// given library are being removed.  It checks whether two callout entries
+    /// have the same library index.
+    ///
+    /// @param ent1 First callout entry to check
+    /// @param ent2 Second callout entry to check
+    ///
+    /// @return bool true if the library entries are the same
+    class CalloutLibraryEqual :
+        public std::binary_function<CalloutEntry, CalloutEntry, bool> {
+    public:
+        bool operator()(const CalloutEntry& ent1,
+                        const CalloutEntry& ent2) const {
+            return (ent1.first == ent2.first);
+        }
+    };
+
+    /// Current hook.  When a call is made to callCallouts, this holds the
+    /// index of the current hook.  It is set to an invalid value (-1)
+    /// otherwise.
+    int current_hook_;
+
+    /// Current library index.  When a call is made to any of the callout
+    /// registration methods, this variable indicates the index of the user
+    /// library that should be associated with the call.
+    int current_library_;
+
+    /// Vector of callout vectors.  There is one entry in this outer vector for
+    /// each hook. Each element is itself a vector, with one entry for each
+    /// callout registered for that hook.
+    std::vector<CalloutVector>  hook_vector_;
+
+    /// LibraryHandle object user by the callout to access the callout
+    /// registration methods on this CalloutManager object.
+    LibraryHandle library_handle_;
+
+    /// Number of libraries.
+    int num_libraries_;
+};
+
+} // namespace util
+} // namespace isc
+
+#endif // CALLOUT_MANAGER_H
diff --git a/src/lib/hooks/hooks.h b/src/lib/hooks/hooks.h
new file mode 100644
index 0000000..bb41a5b
--- /dev/null
+++ b/src/lib/hooks/hooks.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2013  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 HOOKS_H
+#define HOOKS_H
+
+#include <hooks/callout_handle.h>
+#include <hooks/library_handle.h>
+
+// Version 1.0
+static const int BIND10_HOOKS_VERSION = 1;
+
+#endif  // HOOKS_H
diff --git a/src/lib/hooks/hooks_log.cc b/src/lib/hooks/hooks_log.cc
new file mode 100644
index 0000000..360394c
--- /dev/null
+++ b/src/lib/hooks/hooks_log.cc
@@ -0,0 +1,26 @@
+// 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.
+
+/// Defines the logger used by the NSAS
+
+#include "hooks/hooks_log.h"
+
+namespace isc {
+namespace hooks {
+
+isc::log::Logger hooks_logger("hooks");
+
+} // namespace hooks
+} // namespace isc
+
diff --git a/src/lib/hooks/hooks_log.h b/src/lib/hooks/hooks_log.h
new file mode 100644
index 0000000..3555469
--- /dev/null
+++ b/src/lib/hooks/hooks_log.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2013  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 HOOKS_LOG_H
+#define HOOKS_LOG_H
+
+#include <log/macros.h>
+#include <hooks/hooks_messages.h>
+
+namespace isc {
+namespace hooks {
+
+/// \brief Hooks system Logging
+///
+/// Defines the levels used to output debug messages in the Hooks framework.
+/// Note that higher numbers equate to more verbose (and detailed) output.
+
+// The first level traces normal operations,
+const int HOOKS_DBG_TRACE = DBGLVL_TRACE_BASIC;
+
+// The next level traces each call to hook code.
+const int HOOKS_DBG_CALLS = DBGLVL_TRACE_BASIC_DATA;
+
+// Additional information on the calls.  Report each call to a callout (even
+// if there are multiple callouts on a hook) and each status return.
+const int HOOKS_DBG_EXTENDED_CALLS = DBGLVL_TRACE_DETAIL_DATA;
+
+
+/// \brief HOOKS Logger
+///
+/// Define the logger used to log messages.  We could define it in multiple
+/// modules, but defining in a single module and linking to it saves time and
+/// space.
+extern isc::log::Logger hooks_logger;    // isc::hooks::logger is the HOOKS logger
+
+} // namespace hooks
+} // namespace isc
+
+#endif // HOOKS_LOG_H
diff --git a/src/lib/hooks/hooks_messages.mes b/src/lib/hooks/hooks_messages.mes
new file mode 100644
index 0000000..8973f58
--- /dev/null
+++ b/src/lib/hooks/hooks_messages.mes
@@ -0,0 +1,63 @@
+# Copyright (C) 2013  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.
+
+$NAMESPACE isc::hooks
+
+% HOOKS_CLOSE_ERROR failed to close hook library %1: %2
+BIND 10 has failed to close the named hook library for the stated reason.
+Although this is an error, this should not affect the running system other
+than as a loss of resources.  If this error persists, you should restart
+BIND 10.
+
+% HOOKS_INCORRECT_VERSION hook library %1 is at version %2, require version %3
+BIND 10 has detected that the named hook library has been built against
+a version of BIND 10 that is incompatible with the version of BIND 10
+running on your system.  It has not loaded the library.
+
+This is most likely due to the installation of a new version of BIND 10
+without rebuilding the hook library.  A rebuild and re-install of the library
+should fix the problem in most cases.
+
+% HOOKS_LOAD 'load' function in hook library %1 found and successfully called
+This is a debug message issued when the "load" function has been found in a
+hook library and has been successfully called.
+
+% HOOKS_LOAD_ERROR hook library %1 has 'load' function returing error code %2
+A "load" function was found in the library named in the message and was
+called.  The function returned a non-zero status (also given in the message)
+which was interpreted as an error.  The library has been unloaded and
+no callouts from it will be installed.
+
+% HOOKS_NO_LOAD no 'load' function found in hook library %1
+This is a debug message saying that the specified library was loaded but
+no function called "load" was found in it.  Providing the library contained
+some "standard" functions (i.e. functions with the names of the hooks for
+the given server), this is not an issue.
+
+% HOOKS_NO_VERSION no 'version' function found in hook library %1
+The shared library named in the message was found and successfully loaded, but
+BIND 10 did not find a function named "version" in it.  This function is
+required and should return the version of BIND 10 against which the library
+was built.  The value is used to check that the library was built against a
+compatible version of BIND 10.  The library has not been loaded.
+
+% HOOKS_OPEN_ERROR failed to open hook library %1: %2
+BIND 10 failed to open the specified hook library for the stated reason. The
+library has not been loaded.  BIND 10 will continue to function, but without
+the services offered by the library.
+
+% HOOKS_REGISTER_CALLOUT library %1 has registered a callout for hook '%2'
+This is a debug message, output when the library loading function has located
+a standard callout (a callout with the same name as a hook point) and
+registered it.
diff --git a/src/lib/hooks/library_handle.cc b/src/lib/hooks/library_handle.cc
new file mode 100644
index 0000000..8a78707
--- /dev/null
+++ b/src/lib/hooks/library_handle.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2013  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 <hooks/callout_manager.h>
+#include <hooks/library_handle.h>
+
+namespace isc {
+namespace hooks {
+
+// Callout manipulation - all deferred to the CalloutManager.
+
+void
+LibraryHandle::registerCallout(const std::string& name, CalloutPtr callout) {
+    callout_manager_->registerCallout(name, callout);
+}
+
+bool
+LibraryHandle::deregisterCallout(const std::string& name, CalloutPtr callout) {
+    return (callout_manager_->deregisterCallout(name, callout));
+}
+
+bool
+LibraryHandle::deregisterAllCallouts(const std::string& name) {
+    return (callout_manager_->deregisterAllCallouts(name));
+}
+
+} // namespace util
+} // namespace isc
diff --git a/src/lib/hooks/library_handle.h b/src/lib/hooks/library_handle.h
new file mode 100644
index 0000000..1f20986
--- /dev/null
+++ b/src/lib/hooks/library_handle.h
@@ -0,0 +1,115 @@
+// Copyright (C) 2013  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 LIBRARY_HANDLE_H
+#define LIBRARY_HANDLE_H
+
+#include <string>
+
+namespace isc {
+namespace hooks {
+
+// Forward declarations
+class CalloutHandle;
+class CalloutManager;
+
+/// Typedef for a callout pointer.  (Callouts must have "C" linkage.)
+extern "C" {
+    typedef int (*CalloutPtr)(CalloutHandle&);
+};
+
+/// @brief Library handle
+///
+/// This class is accessed by the user library when registering callouts,
+/// either by the library's load() function, or by one of the callouts
+/// themselves.
+///
+/// It is really little more than a shell around the CalloutManager.  By
+/// presenting this object to the user-library callouts, callouts can manage
+/// the callout list for their own library, but cannot affect the callouts
+/// registered by other libraries.
+///
+/// (This restriction is achieved by the CalloutManager maintaining the concept
+/// of the "current library".  When a callout is registered - either by the
+/// library's load() function, or by a callout in the library - the registration
+/// information includes the library active at the time.  When that callout is
+/// called, the CalloutManager uses that information to set the "current
+/// library": the registration functions only operator on data whose
+/// associated library is equal to the "current library".)
+
+class LibraryHandle {
+public:
+
+    /// @brief Constructor
+    ///
+    /// @param manager Back pointer to the containing CalloutManager.
+    ///        This pointer is used to access appropriate methods in that
+    ///        object.  Note that the "raw" pointer is safe - the only
+    ///        instance of the LibraryHandle in the system is as a member of
+    ///        the CalloutManager to which it points.
+    LibraryHandle(CalloutManager* manager) : callout_manager_(manager)
+    {}
+
+    /// @brief Register a callout on a hook
+    ///
+    /// Registers a callout function with a given hook.  The callout is added
+    /// to the end of the callouts for the current library that are associated
+    /// with that hook.
+    ///
+    /// @param name Name of the hook to which the callout is added.
+    /// @param callout Pointer to the callout function to be registered.
+    ///
+    /// @throw NoSuchHook The hook name is unrecognised.
+    /// @throw Unexpected The hook name is valid but an internal data structure
+    ///        is of the wrong size.
+    void registerCallout(const std::string& name, CalloutPtr callout);
+
+    /// @brief De-Register a callout on a hook
+    ///
+    /// Searches through the functions registered by the current library with
+    /// the named hook and removes all entries matching the callout.  It does
+    /// not affect callouts registered by other libraries.
+    ///
+    /// @param name Name of the hook from which the callout is removed.
+    /// @param callout Pointer to the callout function to be removed.
+    ///
+    /// @return true if a one or more callouts were deregistered.
+    ///
+    /// @throw NoSuchHook The hook name is unrecognised.
+    /// @throw Unexpected The hook name is valid but an internal data structure
+    ///        is of the wrong size.
+    bool deregisterCallout(const std::string& name, CalloutPtr callout);
+
+    /// @brief Removes all callouts on a hook
+    ///
+    /// Removes all callouts associated with a given hook that were registered.
+    /// by the current library.  It does not affect callouts that were
+    /// registered by other libraries.
+    ///
+    /// @param name Name of the hook from which the callouts are removed.
+    ///
+    /// @return true if one or more callouts were deregistered.
+    ///
+    /// @throw NoSuchHook Thrown if the hook name is unrecognised.
+    bool deregisterAllCallouts(const std::string& name);
+
+private:
+    /// Back pointer to the collection object for the library
+    CalloutManager* callout_manager_;
+};
+
+} // namespace util
+} // namespace isc
+
+#endif // LIBRARY_HANDLE_H
diff --git a/src/lib/hooks/library_manager.cc b/src/lib/hooks/library_manager.cc
new file mode 100644
index 0000000..6132dfa
--- /dev/null
+++ b/src/lib/hooks/library_manager.cc
@@ -0,0 +1,197 @@
+// Copyright (C) 2013  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 <hooks/hooks.h>
+#include <hooks/hooks_log.h>
+#include <hooks/callout_manager.h>
+#include <hooks/library_handle.h>
+#include <hooks/library_manager.h>
+#include <hooks/server_hooks.h>
+
+#include <string>
+#include <vector>
+
+#include <dlfcn.h>
+
+namespace {
+
+// String constants
+
+const char* LOAD_FUNCTION_NAME = "load";
+// const char* UNLOAD = "unload";
+const char* VERSION_FUNCTION_NAME = "version";
+}
+
+using namespace std;
+
+namespace isc {
+namespace hooks {
+
+// Open the library
+
+bool
+LibraryManager::openLibrary() {
+
+    // Open the library.  We'll resolve names now, so that if there are any
+    // issues we don't bugcheck in the middle of apparently unrelated code.
+    dl_handle_ = dlopen(library_name_.c_str(), RTLD_NOW | RTLD_DEEPBIND);
+    if (dl_handle_ == NULL) {
+        LOG_ERROR(hooks_logger, HOOKS_OPEN_ERROR).arg(library_name_)
+                  .arg(dlerror());
+    }
+
+    return (dl_handle_ != NULL);
+}
+
+// Close the library if not already open
+
+bool
+LibraryManager::closeLibrary() {
+
+    // Close the library if it is open. (If not, this is a no-op.)
+    int status = 0;
+    if (dl_handle_ != NULL) {
+        status = dlclose(dl_handle_);
+        dl_handle_ = NULL;
+        if (status != 0) {
+            LOG_ERROR(hooks_logger, HOOKS_CLOSE_ERROR).arg(library_name_)
+                      .arg(dlerror());
+        }
+    }
+
+    return (status == 0);
+}
+
+// Check the version of the library
+
+bool
+LibraryManager::checkVersion() const {
+
+    // Look up the "version" string in the library.  This is returned as
+    // "void*": without any other information, we must assume that it is of
+    // the correct type of version_function_ptr.
+    //
+    // Note that converting between void* and function pointers in C++ is
+    // fraught with difficulty and pitfalls (e.g. see
+    // https://groups.google.com/forum/?hl=en&fromgroups#!topic/
+    // comp.lang.c++/37o0l8rtEE0)
+    // The method given in that article - convert using a union is used here.
+    union {
+        version_function_ptr    ver_ptr;
+        void*                   dlsym_ptr;
+    } pointers;
+
+    // Zero the union, whatever the size of the pointers.
+    pointers.ver_ptr = NULL;
+    pointers.dlsym_ptr = NULL;
+
+    // Get the pointer to the "version" function.
+    pointers.dlsym_ptr = dlsym(dl_handle_, VERSION_FUNCTION_NAME);
+    if (pointers.ver_ptr != NULL) {
+        int version = (*pointers.ver_ptr)();
+        if (version == BIND10_HOOKS_VERSION) {
+            // All OK, version checks out
+            return (true);
+
+        } else {
+            LOG_ERROR(hooks_logger, HOOKS_INCORRECT_VERSION).arg(library_name_)
+                      .arg(version).arg(BIND10_HOOKS_VERSION);
+        }
+    } else {
+        LOG_ERROR(hooks_logger, HOOKS_NO_VERSION).arg(library_name_);
+    }
+
+    return (false);
+}
+
+// Register the standard callouts
+
+void
+LibraryManager::registerStandardCallouts() {
+    // Create a library handle for doing the registration.  We also need to
+    // set the current library index to indicate the current library.
+    manager_->setLibraryIndex(index_);
+    LibraryHandle library_handle(manager_.get());
+
+    // Iterate through the list of known hooks
+    vector<string> hook_names = ServerHooks::getServerHooks().getHookNames();
+    for (int i = 0; i < hook_names.size(); ++i) {
+
+        // Convert void* to function pointers using the same tricks as
+        // described above.
+        union {
+            CalloutPtr  callout_ptr;
+            void*       dlsym_ptr;
+        } pointers;
+        pointers.callout_ptr = NULL;
+        pointers.dlsym_ptr = NULL;
+
+        // Look up the symbol
+        pointers.dlsym_ptr = dlsym(dl_handle_, hook_names[i].c_str());
+        if (pointers.callout_ptr != NULL) {
+            // Found a symbol, so register it.
+            //library_handle.registerCallout(hook_names[i], callout_ptr);
+            LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_REGISTER_CALLOUT)
+                .arg(library_name_).arg(hook_names[i]);
+            library_handle.registerCallout(hook_names[i], pointers.callout_ptr);
+
+        }
+    }
+}
+
+// Run the "load" function if present.
+
+bool
+LibraryManager::runLoad() {
+
+    // Look up the "load" function in the library.  The code here is similar
+    // to that in "checkVersion".
+    union {
+        load_function_ptr   load_ptr;
+        void*               dlsym_ptr;
+    } pointers;
+
+    // Zero the union, whatever the size of the pointers.
+    pointers.load_ptr = NULL;
+    pointers.dlsym_ptr = NULL;
+
+    // Get the pointer to the "load" function.
+    pointers.dlsym_ptr = dlsym(dl_handle_, LOAD_FUNCTION_NAME);
+    if (pointers.load_ptr != NULL) {
+
+        // Call the load() function with the library handle.  We need to set
+        // the CalloutManager's index appropriately.  We'll invalidate it
+        // afterwards.
+        manager_->setLibraryIndex(index_);
+        int status = (*pointers.load_ptr)(manager_->getLibraryHandle());
+        manager_->setLibraryIndex(index_);
+        if (status != 0) {
+            LOG_ERROR(hooks_logger, HOOKS_LOAD_ERROR).arg(library_name_)
+                      .arg(status);
+            return (false);
+        } else {
+        LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_LOAD)
+            .arg(library_name_);
+        }
+    } else {
+        LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_NO_LOAD)
+            .arg(library_name_);
+    }
+
+    return (true);
+}
+
+
+} // namespace hooks
+} // namespace isc
diff --git a/src/lib/hooks/library_manager.h b/src/lib/hooks/library_manager.h
new file mode 100644
index 0000000..2660ebc
--- /dev/null
+++ b/src/lib/hooks/library_manager.h
@@ -0,0 +1,188 @@
+// Copyright (C) 2013  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 LIBRARY_MANAGER_H
+#define LIBRARY_MANAGER_H
+
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+
+namespace isc {
+namespace hooks {
+
+class CalloutManager;
+class LibraryManager;
+
+/// @brief Library manager
+///
+/// This class handles the loading and unloading of a specific library.
+///
+/// On loading, it opens the library using dlopen and checks the version (set
+/// with the "version" method.  If all is OK, it iterates through the list of
+/// known hooks and locates their symbols, registering each callout as it
+/// does so.  Finally it locates the "load" and "unload" functions (if present),
+/// calling the "load" callout if present.
+///
+/// On unload, it calls the "unload" method if one was located, clears the
+/// callouts from all hooks and closes the library.
+///
+/// @note Caution needs to be exercised whtn using the unload method. During
+///       use, data will pass between the server and the library.  In this
+///       process, the library may allocate memory and pass it back to the
+///       server.  This could happen by the server setting arguments or context
+///       in the CalloutHandle object, or by the library modifying the content
+///       of pointed-to data. A problem arises when the library is unloaded,
+///       because the addresses of allocated day may lie in the virtual
+///       address space deleted in that process.  If this happens, any
+///       reference to the memory will cause a segmentation fault.  This can
+///       occur in a quite obscure place, for example in the middle of a
+///       destructor of an STL class when it is deleting memory allocated
+///       when the data structure was extended.
+///
+/// @par  The only safe way to run the "unload" function is to ensure that all
+///       possible references to it are removed first.  This means that all
+///       CalloutHandles must be destroyed, as must any data items that were
+///       passed to the callouts.  In practice, it could mean that a server
+///       suspends processing of new requests until all existing ones have
+///       been serviced and all packet/context structures destroyed before
+///       reloading the libraries.
+
+class LibraryManager {
+private:
+    /// Useful typedefs for the framework functions
+    typedef int (*version_function_ptr)();            ///< version() signature
+    typedef int (*load_function_ptr)(LibraryHandle&); ///< load() signature
+    typedef int (*unload_function_ptr)();             ///< unload() signature
+
+public:
+    /// @brief Constructor
+    ///
+    /// Stores the library name.  The actual loading is done in loadLibrary().
+    ///
+    /// @param name Name of the library to load.  This should be an absolute
+    ///        path name.
+    /// @param index Index of this library
+    /// @param manager CalloutManager object
+    LibraryManager(const std::string& name, int index,
+                   const boost::shared_ptr<CalloutManager>& manager)
+        : dl_handle_(NULL), index_(index), manager_(manager),
+          library_name_(name)
+    {}
+
+    /// @brief Destructor
+    ///
+    /// If the library is open, closes it.  This is principally a safety
+    /// feature to ensure closure in the case of an exception destroying
+    /// this object.
+    ///
+    /// However, see the caveat in the class header about when it is safe
+    /// to unload libraries.
+    ~LibraryManager() {
+        static_cast<void>(unloadLibrary());
+    }
+
+    /// @brief Loads a library
+    ///
+    /// Open the library and check the version.  If all is OK, load all
+    /// standard symbols then call "load" if present.
+    bool loadLibrary() {return true;}
+
+    /// @brief Unloads a library
+    ///
+    /// Calls the libraries "unload" function if present, the closes the
+    /// library.
+    ///
+    /// However, see the caveat in the class header about when it is safe
+    /// to unload libraries.
+    bool unloadLibrary() {return false;}
+
+    /// @brief Return library name
+    ///
+    /// @return Name of this library
+    std::string getName() const {
+        return (library_name_);
+    }
+
+protected:
+    // The following methods are protected as they are accessed in testing.
+
+    /// @brief Open library
+    ///
+    /// Opens the library associated with this LibraryManager.  A message is
+    /// logged on an error.
+    ///
+    /// @return true if the library opened successfully, false otherwise.
+    bool openLibrary();
+
+    /// @brief Close library
+    ///
+    /// Closes the library associated with this LibraryManager.  A message is
+    /// logged on an error.
+    ///
+    /// @return true if the library closed successfully, false otherwise.
+    ///         "true" is also returned if the library were already closed
+    ///         when this method was called.
+    bool closeLibrary();
+
+    /// @brief Check library version
+    ///
+    /// With the library open, accesses the "version()" function and, if
+    /// present, checks the returned value against the hooks version symbol
+    /// for the currently running BIND 10.
+    ///
+    /// If there is no version() function, or if there is a mismatch in
+    /// version number, a message logged.
+    ///
+    /// @return bool true if the check succeeded
+    bool checkVersion() const;
+
+    /// @brief Register standard callouts
+    ///
+    /// Loops through the list of hook names and searches the library for
+    /// functions with those names.  Any that are found are registered as
+    /// callouts for that hook.
+    void registerStandardCallouts();
+
+    /// @brief Run the load function if present
+    ///
+    /// Searches for the "load" framework function and, if present, runs it.
+    ///
+    /// @return bool true if not found or found and run successfully,
+    ///         false on an error.  In this case, an error message will
+    ///         have been output.
+    bool runLoad();
+
+    /// @brief Run the unload function if present
+    ///
+    /// Searches for the "unload" framework function and, if present, runs it.
+    ///
+    /// @return bool true if not found or found and run successfully,
+    ///         false on an error.  In this case, an error message will
+    ///         have been output.
+    bool runUnload() {return false;}
+
+private:
+    void*       dl_handle_;     ///< Handle returned by dlopen
+    int         index_;         ///< Index associated with this library
+    boost::shared_ptr<CalloutManager> manager_;
+                                ///< Callout manager for registration
+    std::string library_name_;  ///< Name of the library
+
+};
+
+} // namespace hooks
+} // namespace isc
+
+#endif  // LIBRARY_MANAGER_H
diff --git a/src/lib/hooks/server_hooks.cc b/src/lib/hooks/server_hooks.cc
new file mode 100644
index 0000000..36cbb3a
--- /dev/null
+++ b/src/lib/hooks/server_hooks.cc
@@ -0,0 +1,162 @@
+// Copyright (C) 2013  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 <exceptions/exceptions.h>
+#include <hooks/server_hooks.h>
+
+#include <utility>
+#include <vector>
+
+using namespace std;
+using namespace isc;
+
+namespace isc {
+namespace hooks {
+
+// Constructor - register the pre-defined hooks and check that the indexes
+// assigned to them are as expected.
+
+ServerHooks::ServerHooks() {
+    reset();
+}
+
+// Register a hook.  The index assigned to the hook is the current number
+// of entries in the collection, so ensuring that hook indexes are unique
+// and non-negative.
+
+int
+ServerHooks::registerHook(const string& name) {
+
+    // Determine index for the new element and insert.
+    int index = hooks_.size();
+    pair<HookCollection::iterator, bool> result =
+        hooks_.insert(make_pair(name, index));
+
+    if (!result.second) {
+        // New element was not inserted because an element with the same name
+        // already existed.
+        isc_throw(DuplicateHook, "hook with name " << name <<
+                  " is already registered");
+    }
+
+    // Element was inserted, so add to the inverse hooks collection.
+    inverse_hooks_[index] = name;
+
+    // ... and return numeric index.
+    return (index);
+}
+
+// Reset ServerHooks object to initial state.
+
+void
+ServerHooks::reset() {
+    // Clear out the name->index and index->name maps.
+    hooks_.clear();
+    inverse_hooks_.clear();
+
+    // Register the pre-defined hooks.
+    int create = registerHook("context_create");
+    int destroy = registerHook("context_destroy");
+
+    // Check registration went as expected.
+    if ((create != CONTEXT_CREATE) || (destroy != CONTEXT_DESTROY)) {
+        isc_throw(Unexpected, "pre-defined hook indexes are not as expected. "
+                  "context_create: expected = " << CONTEXT_CREATE <<
+                  ", actual = " << create <<
+                  ". context_destroy: expected = " << CONTEXT_DESTROY <<
+                  ", actual = " << destroy);
+    }
+}
+
+// Find the name associated with a hook index.
+
+std::string
+ServerHooks::getName(int index) const {
+
+    // Get iterator to matching element.
+    InverseHookCollection::const_iterator i = inverse_hooks_.find(index);
+    if (i == inverse_hooks_.end()) {
+        isc_throw(NoSuchHook, "hook index " << index << " is not recognised");
+    }
+
+    return (i->second);
+}
+
+// Find the index associated with a hook name.
+
+int
+ServerHooks::getIndex(const string& name) const {
+
+    // Get iterator to matching element.
+    HookCollection::const_iterator i = hooks_.find(name);
+    if (i == hooks_.end()) {
+        isc_throw(NoSuchHook, "hook name " << name << " is not recognised");
+    }
+
+    return (i->second);
+}
+
+// Return vector of hook names.  The names are not sorted - it is up to the
+// caller to perform sorting if required.
+
+vector<string>
+ServerHooks::getHookNames() const {
+
+    vector<string> names;
+    HookCollection::const_iterator i;
+    for (i = hooks_.begin(); i != hooks_.end(); ++i) {
+        names.push_back(i->first);
+    }
+
+    return (names);
+}
+
+// Hook registration function methods
+
+// Access the hook registration function vector itself
+
+std::vector<HookRegistrationFunction::RegistrationFunctionPtr>&
+HookRegistrationFunction::getFunctionVector() {
+    static std::vector<RegistrationFunctionPtr> reg_functions;
+    return (reg_functions);
+}
+
+// Constructor - add a registration function to the function vector
+
+HookRegistrationFunction::HookRegistrationFunction(
+    HookRegistrationFunction::RegistrationFunctionPtr reg_func) {
+    getFunctionVector().push_back(reg_func);
+}
+
+// Execute all registered registration functions
+
+void
+HookRegistrationFunction::execute(ServerHooks& hooks) {
+    std::vector<RegistrationFunctionPtr>& reg_functions = getFunctionVector();
+    for (int i = 0; i < reg_functions.size(); ++i) {
+        (*reg_functions[i])(hooks);
+    }
+}
+
+// Return global ServerHooks object
+
+ServerHooks&
+ServerHooks::getServerHooks() {
+    static ServerHooks hooks;
+    return (hooks);
+}
+
+
+} // namespace util
+} // namespace isc
diff --git a/src/lib/hooks/server_hooks.h b/src/lib/hooks/server_hooks.h
new file mode 100644
index 0000000..12eb475
--- /dev/null
+++ b/src/lib/hooks/server_hooks.h
@@ -0,0 +1,251 @@
+// Copyright (C) 2013  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 SERVER_HOOKS_H
+#define SERVER_HOOKS_H
+
+#include <exceptions/exceptions.h>
+
+#include <boost/noncopyable.hpp>
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace isc {
+namespace hooks {
+
+/// @brief Duplicate hook
+///
+/// Thrown if an attempt is made to register a hook with the same name as a
+/// previously-registered hook.
+class DuplicateHook : public Exception {
+public:
+    DuplicateHook(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
+/// @brief Invalid hook
+///
+/// Thrown if an attempt is made to get the index for an invalid hook.
+class NoSuchHook : public Exception {
+public:
+    NoSuchHook(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
+
+/// @brief Server hook collection
+///
+/// This class is used by the server-side code to register hooks - points in the
+/// server processing at which libraries can register functions (callouts) that
+/// the server will call.  These functions can modify data and so affect the
+/// processing of the server.
+///
+/// The ServerHooks class is little more than a wrapper around the std::map
+/// class.  It stores a hook, assigning to it a unique index number.  This
+/// number is then used by the server code to identify the hook being called.
+/// (Although it would be feasible to use a name as an index, using an integer
+/// will speed up the time taken to locate the callouts, which may make a
+/// difference in a frequently-executed piece of code.)
+///
+/// ServerHooks is a singleton object and is only accessible by the static
+/// method getserverHooks().
+
+class ServerHooks : public boost::noncopyable {
+public:
+
+    /// Index numbers for pre-defined hooks.
+    static const int CONTEXT_CREATE = 0;
+    static const int CONTEXT_DESTROY = 1;
+
+    /// @brief Reset to Initial State
+    ///
+    /// Resets the collection of hooks to the initial state, with just the
+    /// context_create and context_destroy hooks set.  This used during
+    /// construction. It is also used during testing to reset the global
+    /// ServerHooks object.
+    ///
+    /// @throws isc::Unexpected if the registration of the pre-defined hooks
+    ///         fails in some way.
+    void reset();
+
+    /// @brief Register a hook
+    ///
+    /// Registers a hook and returns the hook index.
+    ///
+    /// @param name Name of the hook
+    ///
+    /// @return Index of the hook, to be used in subsequent hook-related calls.
+    ///         This will be greater than or equal to zero (so allowing a
+    ///         negative value to indicate an invalid index).
+    ///
+    /// @throws DuplicateHook A hook with the same name has already been
+    ///         registered.
+    int registerHook(const std::string& name);
+
+    /// @brief Get hook name
+    ///
+    /// Returns the name of a hook given the index.  This is most likely to be
+    /// used in log messages.
+    ///
+    /// @param index Index of the hoold
+    ///
+    /// @return Name of the hook.
+    ///
+    /// @throw NoSuchHook if the hook index is invalid.
+    std::string getName(int index) const;
+
+    /// @brief Get hook index
+    ///
+    /// Returns the index of a hook.
+    ///
+    /// @param name Name of the hook
+    ///
+    /// @return Index of the hook, to be used in subsequent calls.
+    ///
+    /// @throw NoSuchHook if the hook name is unknown to the caller.
+    int getIndex(const std::string& name) const;
+
+    /// @brief Return number of hooks
+    ///
+    /// Returns the total number of hooks registered.
+    ///
+    /// @return Number of hooks registered.
+    int getCount() const {
+        return (hooks_.size());
+    }
+
+    /// @brief Get hook names
+    ///
+    /// Return list of hooks registered in the object.
+    ///
+    /// @return Vector of strings holding hook names.
+    std::vector<std::string> getHookNames() const;
+
+    /// @brief Return ServerHookms object
+    ///
+    /// Returns the global ServerHooks object.
+    ///
+    /// @return Reference to the global ServerHooks object.
+    static ServerHooks& getServerHooks();
+
+private:
+    /// @brief Constructor
+    ///
+    /// This pre-registers two hooks, context_create and context_destroy, which
+    /// are called by the server before processing a packet and after processing
+    /// for the packet has completed.  They allow the server code to allocate
+    /// and destroy per-packet context.
+    ///
+    /// Constructor is declared private to enforce the singleton nature of
+    /// the object.  A reference to the singleton is obtainable through the
+    /// ggetServerHooks() static method.
+    ///
+    /// @throws isc::Unexpected if the registration of the pre-defined hooks
+    ///         fails in some way.
+    ServerHooks();
+
+    /// Useful typedefs.
+    typedef std::map<std::string, int> HookCollection;
+    typedef std::map<int, std::string> InverseHookCollection;
+
+    /// Two maps, one for name->index, the other for index->name.  (This is
+    /// simpler than using a multi-indexed container.)
+    HookCollection  hooks_;                 ///< Hook name/index collection
+    InverseHookCollection inverse_hooks_;   ///< Hook index/name collection
+};
+
+
+/// @brief Hooks Registration
+///
+/// All hooks must be registered before libraries are loaded and callouts
+/// assigned to them.  One way of doing this is to have a global list of hooks:
+/// the addition of any hook anywhere would require updating the list. This
+/// is possible and, if desired, the author of a server can do it.
+///
+/// An alternative is the option provided here, where each component of BIND 10
+/// registers the hooks they are using.  To do this, the component should
+/// create a hook registration function of the form:
+///
+/// @code
+/// static int hook1_num = -1;  // Initialize number for hook 1
+/// static int hook2_num = -1;  // Initialize number for hook 2
+///
+/// void myModuleRegisterHooks(ServerHooks& hooks) {
+///     hook1_num = hooks.registerHook("hook1");
+///     hook2_num = hooks.registerHook("hook2");
+/// }
+/// @endcode
+///
+/// ... which registers the hooks and stores the associated hook index. To
+/// avoid the need to add an explicit call to each of the hook registration
+/// functions to the server initialization code, the component should declare
+/// an object of this class in the same file as the registration function,
+/// but outside of any function.  The declaration should include the name
+/// of the registration function, i.e.
+///
+/// @code
+/// HookRegistrationFunction f(myModuleRegisterHooks);
+/// @code
+///
+/// The constructor of this object will run prior to main() getting called and
+/// will add the registration function to a list of such functions.  The server
+/// then calls the static class method "execute()" to run all the declared
+/// registration functions.
+
+class HookRegistrationFunction {
+public:
+    /// @brief Pointer to a hook registration function
+    typedef void (*RegistrationFunctionPtr)(ServerHooks&);
+
+    /// @brief Constructor
+    ///
+    /// For variables declared outside functions or methods, the constructors
+    /// are run after the program is loaded and before main() is called. This
+    /// constructor adds the passed pointer to a vector of such pointers.
+    HookRegistrationFunction(RegistrationFunctionPtr reg_func);
+
+    /// @brief Access registration function vector
+    ///
+    /// One of the problems with functions run prior to starting main() is the
+    /// "static initialization fiasco".  This occurs because the order in which
+    /// objects outside functions are constructed is not defined.  So if this
+    /// constructor were to depend on a vector declared externally, we would
+    /// not be able to guarantee that the vector had been initialised properly
+    /// before we used it.
+    ///
+    /// To get round this situation, the vector is declared statically within
+    /// a static function.  The first time the function is called, the vector
+    /// is initialized before it is used.
+    ///
+    /// This function returns a reference to the vector used to hold the
+    /// pointers.
+    ///
+    /// @return Reference to the (static) list of registration functions
+    static std::vector<RegistrationFunctionPtr>& getFunctionVector();
+
+    /// @brief Execute registration functions
+    ///
+    /// Called by the server initialization code, this function executes all
+    /// registered hook registration functions.
+    ///
+    /// @param hooks ServerHooks object to which hook information will be added.
+    static void execute(ServerHooks& hooks);
+};
+
+} // namespace util
+} // namespace isc
+
+#endif  // SERVER_HOOKS_H
diff --git a/src/lib/hooks/tests/Makefile.am b/src/lib/hooks/tests/Makefile.am
new file mode 100644
index 0000000..b6c0d84
--- /dev/null
+++ b/src/lib/hooks/tests/Makefile.am
@@ -0,0 +1,86 @@
+SUBDIRS = .
+
+AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
+AM_LDFLAGS = $(PTHREAD_LDFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS += -static
+endif
+
+# Some versions of GCC warn about some versions of Boost regarding
+# missing initializer for members in its posix_time.
+# https://svn.boost.org/trac/boost/ticket/3477
+# But older GCC compilers don't have the flag.     
+AM_CXXFLAGS  = $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
+
+if USE_CLANGPP
+# see ../Makefile.am
+AM_CXXFLAGS += -Wno-unused-parameter
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS_ENVIRONMENT = \
+	$(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
+
+TESTS =
+if HAVE_GTEST
+# Build shared libraries for testing.
+lib_LTLIBRARIES = libnvl.la libivl.la libbcl.la liblcl.la liblecl.la \
+                  libucl.la
+ 
+# No version function
+libnvl_la_SOURCES  = no_version_library.cc
+libnvl_la_CXXFLAGS = $(AM_CXXFLAGS)
+libnvl_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+ 
+# Incorrect version function
+libivl_la_SOURCES  = incorrect_version_library.cc
+libivl_la_CXXFLAGS = $(AM_CXXFLAGS)
+libilv_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+
+# The basic callout library - contains standard callouts
+libbcl_la_SOURCES  = basic_callout_library.cc
+libbcl_la_CXXFLAGS = $(AM_CXXFLAGS)
+libbcl_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+
+# The load callout library - contains a load function
+liblcl_la_SOURCES  = load_callout_library.cc
+liblcl_la_CXXFLAGS = $(AM_CXXFLAGS)
+liblcl_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+
+# The load error callout library - contains a load function that returns
+# an error.
+liblecl_la_SOURCES  = load_error_callout_library.cc
+liblecl_la_CXXFLAGS = $(AM_CXXFLAGS)
+liblecl_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+
+# The unload callout library - contains an unload function that
+# creates a marker file.
+libucl_la_SOURCES  = unload_callout_library.cc
+libucl_la_CXXFLAGS = $(AM_CXXFLAGS)
+libucl_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+
+TESTS += run_unittests
+run_unittests_SOURCES  = run_unittests.cc
+run_unittests_SOURCES += callout_handle_unittest.cc
+run_unittests_SOURCES += callout_manager_unittest.cc
+run_unittests_SOURCES += handles_unittest.cc
+run_unittests_SOURCES += library_manager_unittest.cc
+run_unittests_SOURCES += server_hooks_unittest.cc
+
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+run_unittests_LDADD    = $(AM_LDADD)    $(GTEST_LDADD)
+
+run_unittests_LDADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
+run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
+run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
+run_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
+run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+endif
+
+noinst_PROGRAMS = $(TESTS)
+
+EXTRA_DIST = library_manager_unittest.cc.in marker_file.h.in
diff --git a/src/lib/hooks/tests/basic_callout_library.cc b/src/lib/hooks/tests/basic_callout_library.cc
new file mode 100644
index 0000000..7c99e77
--- /dev/null
+++ b/src/lib/hooks/tests/basic_callout_library.cc
@@ -0,0 +1,116 @@
+// Copyright (C) 2013  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.
+
+/// @file
+/// @brief Basic Callout Library
+///
+/// This is a test file for the LibraryManager test.  It produces a library
+/// that allows for tests of the basic library manager functions.
+///
+/// The characteristics of this library are:
+///
+/// - Only the "version" framework function is supplied.
+///
+/// - A context_create callout is supplied.
+///
+/// - Three "standard" callouts are supplied corresponding to the hooks
+///   "lm_one", "lm_two", "lm_three".  All do some trivial calculations
+///   on the arguments supplied to it and the context variables, returning
+///   intermediate results through the "result" argument. The result of
+///   the calculation is:
+///
+///   @f[ (10 + data_1) * data_2 - data_3 @f]
+///
+///   ...where data_1, data_2 and data_3 are the values passed in arguments
+///   of the same name to the three callouts (data_1 passed to lm_one,
+///   data_2 to lm_two etc.) and the result is returned in the argument
+///   "result".
+
+#include <hooks/hooks.h>
+#include <iostream>
+
+using namespace isc::hooks;
+
+extern "C" {
+
+// Callouts
+
+int
+context_create(CalloutHandle& handle) {
+    handle.setContext("result", static_cast<int>(10));
+    handle.setArgument("result", static_cast<int>(10));
+    return (0);
+}
+
+// First callout adds the passed "data_1" argument to the initialized context
+// value of 10.
+
+int
+lm_one(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_1", data);
+
+    int result;
+    handle.getContext("result", result);
+
+    result += data;
+    handle.setContext("result", result);
+    handle.setArgument("result", result);
+
+    return (0);
+}
+
+// Second callout multiplies the current context value by the "data_2"
+// argument.
+
+int
+lm_two(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_2", data);
+
+    int result;
+    handle.getContext("result", result);
+
+    result *= data;
+    handle.setContext("result", result);
+    handle.setArgument("result", result);
+
+    return (0);
+}
+
+// Final callout subtracts the result in "data_3" and.
+
+int
+lm_three(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_3", data);
+
+    int result;
+    handle.getContext("result", result);
+
+    result -= data;
+    handle.setArgument("result", result);
+
+    return (0);
+}
+
+// Framework functions
+
+int
+version() {
+    return (BIND10_HOOKS_VERSION);
+}
+
+};
+
diff --git a/src/lib/hooks/tests/callout_handle_unittest.cc b/src/lib/hooks/tests/callout_handle_unittest.cc
new file mode 100644
index 0000000..69622d1
--- /dev/null
+++ b/src/lib/hooks/tests/callout_handle_unittest.cc
@@ -0,0 +1,329 @@
+// Copyright (C) 2013  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 <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+#include <hooks/library_handle.h>
+#include <hooks/server_hooks.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <gtest/gtest.h>
+
+using namespace isc::hooks;
+using namespace std;
+
+namespace {
+
+/// @file
+/// @brief Holds the CalloutHandle argument tests
+///
+/// Additional testing of the CalloutHandle - together with the interaction
+/// of the LibraryHandle - is done in the handles_unittests set of tests.
+
+class CalloutHandleTest : public ::testing::Test {
+public:
+
+    /// @brief Constructor
+    ///
+    /// Sets up a callout manager to be referenced by the CalloutHandle in
+    /// these tests. (The "4" for the number of libraries in the
+    /// CalloutManager is arbitrary - it is not used in these tests.)
+    CalloutHandleTest() : manager_(new CalloutManager(4))
+    {}
+
+    /// Obtain hook manager
+    boost::shared_ptr<CalloutManager>& getCalloutManager() {
+        return (manager_);
+    }
+
+private:
+    /// Callout manager accessed by this CalloutHandle.
+    boost::shared_ptr<CalloutManager> manager_;
+};
+
+// *** Argument Tests ***
+//
+// The first set of tests check that the CalloutHandle can store and retrieve
+// arguments.  These are very similar to the LibraryHandle context tests.
+
+// Test that we can store multiple values of the same type and that they
+// are distinct.
+
+TEST_F(CalloutHandleTest, ArgumentDistinctSimpleType) {
+    CalloutHandle handle(getCalloutManager());
+
+    // Store and retrieve an int (random value).
+    int a = 42;
+    handle.setArgument("integer1", a);
+    EXPECT_EQ(42, a);
+
+    int b = 0;
+    handle.getArgument("integer1", b);
+    EXPECT_EQ(42, b);
+
+    // Add another integer (another random value).
+    int c = 142;
+    handle.setArgument("integer2", c);
+    EXPECT_EQ(142, c);
+
+    int d = 0;
+    handle.getArgument("integer2", d);
+    EXPECT_EQ(142, d);
+
+    // Add a short (random value).
+    short e = -81; 
+    handle.setArgument("short", e);
+    EXPECT_EQ(-81, e);
+
+    short f = 0;
+    handle.getArgument("short", f);
+    EXPECT_EQ(-81, f);
+}
+
+// Test that trying to get an unknown argument throws an exception.
+
+TEST_F(CalloutHandleTest, ArgumentUnknownName) {
+    CalloutHandle handle(getCalloutManager());
+
+    // Set an integer
+    int a = 42;
+    handle.setArgument("integer1", a);
+    EXPECT_EQ(42, a);
+
+    // Check we can retrieve it
+    int b = 0;
+    handle.getArgument("integer1", b);
+    EXPECT_EQ(42, b);
+
+    // Check that getting an unknown name throws an exception.
+    int c = 0;
+    EXPECT_THROW(handle.getArgument("unknown", c), NoSuchArgument);
+}
+
+// Test that trying to get an argument with an incorrect type throws an
+// exception.
+
+TEST_F(CalloutHandleTest, ArgumentIncorrectType) {
+    CalloutHandle handle(getCalloutManager());
+
+    // Set an integer
+    int a = 42;
+    handle.setArgument("integer1", a);
+    EXPECT_EQ(42, a);
+
+    // Check we can retrieve it
+    long b = 0;
+    EXPECT_THROW(handle.getArgument("integer1", b), boost::bad_any_cast);
+}
+
+// Now try with some very complex types.  The types cannot be defined within
+// the function and they should contain a copy constructor.  For this reason,
+// a simple "struct" is used.
+
+struct Alpha {
+    int a;
+    int b;
+    Alpha(int first = 0, int second = 0) : a(first), b(second) {}
+};
+
+struct Beta {
+    int c;
+    int d;
+    Beta(int first = 0, int second = 0) : c(first), d(second) {}
+};
+
+TEST_F(CalloutHandleTest, ComplexTypes) {
+    CalloutHandle handle(getCalloutManager());
+
+    // Declare two variables of different (complex) types. (Note as to the
+    // variable names: aleph and beth are the first two letters of the Hebrew
+    // alphabet.)
+    Alpha aleph(1, 2);
+    EXPECT_EQ(1, aleph.a);
+    EXPECT_EQ(2, aleph.b);
+    handle.setArgument("aleph", aleph);
+
+    Beta beth(11, 22);
+    EXPECT_EQ(11, beth.c);
+    EXPECT_EQ(22, beth.d);
+    handle.setArgument("beth", beth);
+
+    // Ensure we can extract the data correctly.
+    Alpha aleph2;
+    EXPECT_EQ(0, aleph2.a);
+    EXPECT_EQ(0, aleph2.b);
+    handle.getArgument("aleph", aleph2);
+    EXPECT_EQ(1, aleph2.a);
+    EXPECT_EQ(2, aleph2.b);
+
+    Beta beth2;
+    EXPECT_EQ(0, beth2.c);
+    EXPECT_EQ(0, beth2.d);
+    handle.getArgument("beth", beth2);
+    EXPECT_EQ(11, beth2.c);
+    EXPECT_EQ(22, beth2.d);
+
+    // Ensure that complex types also thrown an exception if we attempt to
+    // get a context element of the wrong type.
+    EXPECT_THROW(handle.getArgument("aleph", beth), boost::bad_any_cast);
+}
+
+// Check that the context can store pointers. And also check that it respects
+// that a "pointer to X" is not the same as a "pointer to const X".
+
+TEST_F(CalloutHandleTest, PointerTypes) {
+    CalloutHandle handle(getCalloutManager());
+
+    // Declare a couple of variables, const and non-const.
+    Alpha aleph(5, 10);
+    const Beta beth(15, 20);
+
+    Alpha* pa = ℵ
+    const Beta* pcb = ℶ
+
+    // Check pointers can be set and retrieved OK.
+    handle.setArgument("non_const_pointer", pa);
+    handle.setArgument("const_pointer", pcb);
+
+    Alpha* pa2 = 0;
+    handle.getArgument("non_const_pointer", pa2);
+    EXPECT_TRUE(pa == pa2);
+
+    const Beta* pcb2 = 0;
+    handle.getArgument("const_pointer", pcb2);
+    EXPECT_TRUE(pcb == pcb2);
+
+    // Check that the "const" is protected in the context.
+    const Alpha* pca3;
+    EXPECT_THROW(handle.getArgument("non_const_pointer", pca3),
+                 boost::bad_any_cast);
+
+    Beta* pb3;
+    EXPECT_THROW(handle.getArgument("const_pointer", pb3),
+                 boost::bad_any_cast);
+}
+
+// Check that we can get the names of the arguments.
+
+TEST_F(CalloutHandleTest, ContextItemNames) {
+    CalloutHandle handle(getCalloutManager());
+
+    vector<string> expected_names;
+
+    expected_names.push_back("faith");
+    handle.setArgument("faith", 42);
+    expected_names.push_back("hope");
+    handle.setArgument("hope", 43);
+    expected_names.push_back("charity");
+    handle.setArgument("charity", 44);
+
+    // Get the names and check against the expected names.  We'll sort
+    // both arrays to simplify the checking.
+    vector<string> actual_names = handle.getArgumentNames();
+
+    sort(actual_names.begin(), actual_names.end());
+    sort(expected_names.begin(), expected_names.end());
+    EXPECT_TRUE(expected_names == actual_names);
+}
+
+// Test that we can delete an argument.
+
+TEST_F(CalloutHandleTest, DeleteArgument) {
+    CalloutHandle handle(getCalloutManager());
+
+    int one = 1;
+    int two = 2;
+    int three = 3;
+    int four = 4;
+    int value;      // Return value
+
+    handle.setArgument("one", one);
+    handle.setArgument("two", two);
+    handle.setArgument("three", three);
+    handle.setArgument("four", four);
+
+    // Delete "one".
+    handle.getArgument("one", value);
+    EXPECT_EQ(1, value);
+    handle.deleteArgument("one");
+
+    EXPECT_THROW(handle.getArgument("one", value), NoSuchArgument);
+    handle.getArgument("two", value);
+    EXPECT_EQ(2, value);
+    handle.getArgument("three", value);
+    EXPECT_EQ(3, value);
+    handle.getArgument("four", value);
+    EXPECT_EQ(4, value);
+
+    // Delete "three".
+    handle.getArgument("three", value);
+    EXPECT_EQ(3, value);
+    handle.deleteArgument("three");
+
+    EXPECT_THROW(handle.getArgument("one", value), NoSuchArgument);
+    handle.getArgument("two", value);
+    EXPECT_EQ(2, value);
+    EXPECT_THROW(handle.getArgument("three", value), NoSuchArgument);
+    handle.getArgument("four", value);
+    EXPECT_EQ(4, value);
+}
+
+// Test that we can delete all arguments.
+
+TEST_F(CalloutHandleTest, DeleteAllArguments) {
+    CalloutHandle handle(getCalloutManager());
+
+    int one = 1;
+    int two = 2;
+    int three = 3;
+    int four = 4;
+    int value;      // Return value
+
+    // Set the arguments.  The previous test verifies that this works.
+    handle.setArgument("one", one);
+    handle.setArgument("two", two);
+    handle.setArgument("three", three);
+    handle.setArgument("four", four);
+
+    // Delete all arguments...
+    handle.deleteAllArguments();
+
+    // ... and check that none are left.
+    EXPECT_THROW(handle.getArgument("one", value), NoSuchArgument);
+    EXPECT_THROW(handle.getArgument("two", value), NoSuchArgument);
+    EXPECT_THROW(handle.getArgument("three", value), NoSuchArgument);
+    EXPECT_THROW(handle.getArgument("four", value), NoSuchArgument);
+}
+
+// Test the "skip" flag.
+
+TEST_F(CalloutHandleTest, SkipFlag) {
+    CalloutHandle handle(getCalloutManager());
+
+    // Should be false on construction.
+    EXPECT_FALSE(handle.getSkip());
+
+    handle.setSkip(true);
+    EXPECT_TRUE(handle.getSkip());
+
+    handle.setSkip(false);
+    EXPECT_FALSE(handle.getSkip());
+}
+
+// Further tests of the "skip" flag and tests of getting the name of the
+// hook to which the current callout is attached is in the "handles_unittest"
+// module.
+
+} // Anonymous namespace
diff --git a/src/lib/hooks/tests/callout_manager_unittest.cc b/src/lib/hooks/tests/callout_manager_unittest.cc
new file mode 100644
index 0000000..22bb3d1
--- /dev/null
+++ b/src/lib/hooks/tests/callout_manager_unittest.cc
@@ -0,0 +1,759 @@
+// Copyright (C) 2013  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 <exceptions/exceptions.h>
+#include <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+#include <hooks/library_handle.h>
+#include <hooks/server_hooks.h>
+
+#include <boost/scoped_ptr.hpp>
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+/// @file
+/// @brief CalloutManager and LibraryHandle tests
+///
+/// These set of tests check the CalloutManager and LibraryHandle.  They are
+/// together in the same file because the LibraryHandle is little more than a
+/// restricted interface to the CalloutManager, and a lot of the support
+/// structure for the tests is common.
+
+using namespace isc;
+using namespace isc::hooks;
+using namespace std;
+
+namespace {
+
+class CalloutManagerTest : public ::testing::Test {
+public:
+    /// @brief Constructor
+    ///
+    /// Sets up a collection of three LibraryHandle objects to use in the test.
+    CalloutManagerTest() {
+
+        // Set up the server hooks.  There is sone singleton for all tests,
+        // so reset it and explicitly set up the hooks for the test.
+        ServerHooks& hooks = ServerHooks::getServerHooks();
+        hooks.reset();
+        alpha_index_ = hooks.registerHook("alpha");
+        beta_index_ = hooks.registerHook("beta");
+        gamma_index_ = hooks.registerHook("gamma");
+        delta_index_ = hooks.registerHook("delta");
+
+        // Set up the callout manager with these hooks.  Assume a maximum of
+        // four libraries.
+        callout_manager_.reset(new CalloutManager(10));
+
+        // Set up the callout handle.
+        callout_handle_.reset(new CalloutHandle(callout_manager_));
+
+        // Initialize the static variable.
+        callout_value_ = 0;
+    }
+
+    /// @brief Return the callout handle
+    CalloutHandle& getCalloutHandle() {
+        return (*callout_handle_);
+    }
+
+    /// @brief Return the callout manager
+    boost::shared_ptr<CalloutManager> getCalloutManager() {
+        return (callout_manager_);
+    }
+
+    /// Static variable used for accumulating information
+    static int callout_value_;
+
+    /// Hook indexes.  These are somewhat ubiquitous, so are made public for
+    /// ease of reference instead of being accessible by a function.
+    int alpha_index_;
+    int beta_index_;
+    int gamma_index_;
+    int delta_index_;
+
+private:
+    /// Callout handle used in calls
+    boost::shared_ptr<CalloutHandle> callout_handle_;
+
+    /// Callout manager used for the test
+    boost::shared_ptr<CalloutManager> callout_manager_;
+};
+
+// Definition of the static variable.
+int CalloutManagerTest::callout_value_ = 0;
+
+// Callout definitions
+//
+// The callouts defined here are structured in such a way that it is possible
+// to determine the order in which they are called and whether they are called
+// at all. The method used is simple - after a sequence of callouts, the digits
+// in the value, reading left to right, determines the order of the callouts
+// called.  For example, callout one followed by two followed by three followed
+// by two followed by one results in a value of 12321.
+//
+// Functions return a zero to indicate success.
+
+extern "C" {
+int callout_general(int number) {
+    CalloutManagerTest::callout_value_ =
+        10 * CalloutManagerTest::callout_value_ + number;
+    return (0);
+}
+
+int callout_one(CalloutHandle&) {
+    return (callout_general(1));
+}
+
+int callout_two(CalloutHandle&) {
+    return (callout_general(2));
+}
+
+int callout_three(CalloutHandle&) {
+    return (callout_general(3));
+}
+
+int callout_four(CalloutHandle&) {
+    return (callout_general(4));
+}
+
+int callout_five(CalloutHandle&) {
+    return (callout_general(5));
+}
+
+int callout_six(CalloutHandle&) {
+    return (callout_general(6));
+}
+
+int callout_seven(CalloutHandle&) {
+    return (callout_general(7));
+}
+
+// The next functions are duplicates of some of the above, but return an error.
+
+int callout_one_error(CalloutHandle& handle) {
+    (void) callout_one(handle);
+    return (1);
+}
+
+int callout_two_error(CalloutHandle& handle) {
+    (void) callout_two(handle);
+    return (1);
+}
+
+int callout_three_error(CalloutHandle& handle) {
+    (void) callout_three(handle);
+    return (1);
+}
+
+int callout_four_error(CalloutHandle& handle) {
+    (void) callout_four(handle);
+    return (1);
+}
+
+};  // extern "C"
+
+// *** Callout Tests ***
+//
+// The next set of tests check that callouts can be called.
+
+// Constructor - check that we trap bad parameters.
+
+TEST_F(CalloutManagerTest, BadConstructorParameters) {
+    boost::scoped_ptr<CalloutManager> cm;
+
+    // Invalid number of libraries
+    EXPECT_THROW(cm.reset(new CalloutManager(0)), BadValue);
+    EXPECT_THROW(cm.reset(new CalloutManager(-1)), BadValue);
+}
+
+// Check the number of libraries is reported successfully.
+
+TEST_F(CalloutManagerTest, GetNumLibraries) {
+    boost::scoped_ptr<CalloutManager> cm;
+
+    // Check two valid values of number of libraries to ensure that the
+    // GetNumLibraries() returns the value set.
+    EXPECT_NO_THROW(cm.reset(new CalloutManager(4)));
+    EXPECT_EQ(4, cm->getNumLibraries());
+
+    EXPECT_NO_THROW(cm.reset(new CalloutManager(42)));
+    EXPECT_EQ(42, cm->getNumLibraries());
+}
+
+// Check that we can only set the current library index to the correct values.
+
+TEST_F(CalloutManagerTest, CheckLibraryIndex) {
+    // Check valid indexes
+    for (int i = 0; i < 4; ++i) {
+        EXPECT_NO_THROW(getCalloutManager()->setLibraryIndex(i));
+    }
+
+    // Check invalid ones
+    EXPECT_THROW(getCalloutManager()->setLibraryIndex(-1), NoSuchLibrary);
+    EXPECT_THROW(getCalloutManager()->setLibraryIndex(15), NoSuchLibrary);
+}
+
+// Check that we can only register callouts on valid hook names.
+
+TEST_F(CalloutManagerTest, ValidHookNames) {
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_NO_THROW(getCalloutManager()->registerCallout("alpha", callout_one));
+    EXPECT_THROW(getCalloutManager()->registerCallout("unknown", callout_one),
+                                                      NoSuchHook);
+}
+
+
+// Check we can register callouts appropriately.
+
+TEST_F(CalloutManagerTest, RegisterCallout) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+
+    // Set up so that hooks "alpha" and "beta" have callouts attached from a
+    // different libraries.
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("beta", callout_two);
+
+    // Check all is as expected.
+    EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_TRUE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Check that calling the callouts returns as expected. (This is also a
+    // test of the callCallouts method.)
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1, callout_value_);
+
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(2, callout_value_);
+
+    // Register some more callouts from different libraries on hook "alpha".
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->setLibraryIndex(3);
+    getCalloutManager()->registerCallout("alpha", callout_five);
+
+    // Check it is as expected.
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1345, callout_value_);
+
+    // ... and check the additional callouts were not registered on the "beta"
+    // hook.
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(2, callout_value_);
+
+    // Add another callout to hook "alpha" from library index 2 - this should
+    // appear at the end of the callout list for that library.
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout_six);
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(13465, callout_value_);
+
+    // Add a callout from library index 1 - this should appear between the
+    // callouts from library index 0 and linrary index 2.
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_seven);
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(173465, callout_value_);
+}
+
+// Check the "calloutsPresent()" method.
+
+TEST_F(CalloutManagerTest, CalloutsPresent) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Set up so that hooks "alpha", "beta" and "delta" have callouts attached
+    // to them, and callout  "gamma" does not. (In the statements below, the
+    // exact callouts attached to a hook are not relevant - only the fact
+    // that some callouts are).  Chose the libraries for which the callouts
+    // are registered randomly.
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->registerCallout("beta", callout_two);
+
+    getCalloutManager()->setLibraryIndex(3);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("delta", callout_four);
+
+    // Check all is as expected.
+    EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_TRUE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_TRUE(getCalloutManager()->calloutsPresent(delta_index_));
+
+    // Check we fail on an invalid hook index.
+    EXPECT_THROW(getCalloutManager()->calloutsPresent(42), NoSuchHook);
+    EXPECT_THROW(getCalloutManager()->calloutsPresent(-1), NoSuchHook);
+}
+
+// Test that calling a hook with no callouts on it returns success.
+
+TEST_F(CalloutManagerTest, CallNoCallouts) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Call the callouts on an arbitrary hook and ensure that nothing happens.
+    callout_value_ = 475;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(475, callout_value_); // Unchanged
+}
+
+// Test that the callouts are called in the correct order (i.e. the callouts
+// from the first library in the order they were registered, then the callouts
+// from the second library in the order they were registered etc.)
+
+TEST_F(CalloutManagerTest, CallCalloutsSuccess) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Each library contributes one callout on hook "alpha".
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->setLibraryIndex(3);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1234, callout_value_);
+
+    // Do a random selection of callouts on hook "beta".
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("beta", callout_one);
+    getCalloutManager()->registerCallout("beta", callout_three);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("beta", callout_two);
+    getCalloutManager()->setLibraryIndex(3);
+    getCalloutManager()->registerCallout("beta", callout_four);
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(1324, callout_value_);
+
+    // Ensure that calling the callouts on a hook with no callouts works.
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(gamma_index_, getCalloutHandle());
+    EXPECT_EQ(0, callout_value_);
+}
+
+// Test that the callouts are called in order, but that callouts occurring
+// after a callout that returns an error are not called.
+//
+// (Note: in this test, the callouts that return an error set the value of
+// callout_value_ before they return the error code.)
+
+TEST_F(CalloutManagerTest, CallCalloutsError) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Each library contributing one callout on hook "alpha". The first callout
+    // returns an error (after adding its value to the result).
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one_error);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->setLibraryIndex(3);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1234, callout_value_);
+
+    // Each library contributing multiple callouts on hook "beta". The last
+    // callout on the first library returns an error.
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("beta", callout_one);
+    getCalloutManager()->registerCallout("beta", callout_one_error);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("beta", callout_two);
+    getCalloutManager()->registerCallout("beta", callout_two);
+    getCalloutManager()->registerCallout("beta", callout_three);
+    getCalloutManager()->registerCallout("beta", callout_three);
+    getCalloutManager()->setLibraryIndex(3);
+    getCalloutManager()->registerCallout("beta", callout_four);
+    getCalloutManager()->registerCallout("beta", callout_four);
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(11223344, callout_value_);
+
+    // A callout in a random position in the callout list returns an error.
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("gamma", callout_one);
+    getCalloutManager()->registerCallout("gamma", callout_one);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("gamma", callout_two);
+    getCalloutManager()->registerCallout("gamma", callout_two);
+    getCalloutManager()->setLibraryIndex(3);
+    getCalloutManager()->registerCallout("gamma", callout_four_error);
+    getCalloutManager()->registerCallout("gamma", callout_four);
+    getCalloutManager()->callCallouts(gamma_index_, getCalloutHandle());
+    EXPECT_EQ(112244, callout_value_);
+
+    // The last callout on a hook returns an error.
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("delta", callout_one);
+    getCalloutManager()->registerCallout("delta", callout_one);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("delta", callout_two);
+    getCalloutManager()->registerCallout("delta", callout_two);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("delta", callout_three);
+    getCalloutManager()->registerCallout("delta", callout_three);
+    getCalloutManager()->setLibraryIndex(3);
+    getCalloutManager()->registerCallout("delta", callout_four);
+    getCalloutManager()->registerCallout("delta", callout_four_error);
+    getCalloutManager()->callCallouts(delta_index_, getCalloutHandle());
+    EXPECT_EQ(11223344, callout_value_);
+}
+
+// Now test that we can deregister a single callout on a hook.
+
+TEST_F(CalloutManagerTest, DeregisterSingleCallout) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Add a callout to hook "alpha" and check it is added correctly.
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(2, callout_value_);
+
+    // Remove it and check that the no callouts are present.  We have to reset
+    // the current library index here as it was invalidated by the call
+    // to callCallouts().
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+}
+
+// Now test that we can deregister a single callout on a hook that has multiple
+// callouts from the same library.
+
+TEST_F(CalloutManagerTest, DeregisterSingleCalloutSameLibrary) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Add multiple callouts to hook "alpha".
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1234, callout_value_);
+
+    // Remove the callout_two callout.  We have to reset the current library
+    // index here as it was invalidated by the call to callCallouts().
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(134, callout_value_);
+
+    // Try removing it again.
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", callout_two));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(134, callout_value_);
+
+}
+
+// Check we can deregister multiple callouts from the same library.
+
+TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsSameLibrary) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Each library contributes one callout on hook "alpha".
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(12123434, callout_value_);
+
+    // Remove the callout_two callouts.  We have to reset the current library
+    // index here as it was invalidated by the call to callCallouts().
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(113434, callout_value_);
+
+    // Try removing multiple callouts that includes one at the end of the
+    // list of callouts.
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_four));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1133, callout_value_);
+
+    // ... and from the start.
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_one));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(33, callout_value_);
+
+    // ... and the remaining callouts.
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_three));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(0, callout_value_);
+
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+}
+
+// Check we can deregister multiple callouts from multiple libraries.
+
+TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsMultipleLibraries) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Each library contributes two callouts to hook "alpha".
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout_five);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(123452, callout_value_);
+
+    // Remove the callout_two callout from library 0.  It should not affect
+    // the second callout_two callout registered by library 2.
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(13452, callout_value_);
+}
+
+// Check we can deregister all callouts from a single library.
+
+TEST_F(CalloutManagerTest, DeregisterAllCallouts) {
+    // Ensure that no callouts are attached to hook one.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+                 
+    // Each library contributes two callouts to hook "alpha".
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout_five);
+    getCalloutManager()->registerCallout("alpha", callout_six);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(123456, callout_value_);
+
+    // Remove all callouts from library index 1.
+    getCalloutManager()->setLibraryIndex(1);
+    EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1256, callout_value_);
+
+    // Remove all callouts from library index 2.
+    getCalloutManager()->setLibraryIndex(2);
+    EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(12, callout_value_);
+}
+
+// Check that we can register/deregister callouts on different libraries
+// and different hooks, and that the callout instances are regarded as
+// unique and do not affect one another.
+
+TEST_F(CalloutManagerTest, MultipleCalloutsLibrariesHooks) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Register callouts on the alpha hook.
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_one);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout_three);
+    getCalloutManager()->registerCallout("alpha", callout_four);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout_five);
+    getCalloutManager()->registerCallout("alpha", callout_two);
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(123452, callout_value_);
+
+    // Register the same callouts on the beta hook, and check that those
+    // on the alpha hook are not affected.
+    callout_value_ = 0;
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("beta", callout_five);
+    getCalloutManager()->registerCallout("beta", callout_one);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("beta", callout_four);
+    getCalloutManager()->registerCallout("beta", callout_three);
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(5143, callout_value_);
+
+    // Check that the order of callouts on the alpha hook has not been affected.
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(123452, callout_value_);
+
+    // Remove callout four from beta and check that alpha is not affected.
+    getCalloutManager()->setLibraryIndex(2);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("beta", callout_four));
+
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
+    EXPECT_EQ(513, callout_value_);
+
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(123452, callout_value_);
+}
+
+// Library handle tests.  As by inspection the LibraryHandle can be seen to be
+// little more than shell around CalloutManager, only a basic set of tests
+// is done concerning registration and deregistration of functions.
+//
+// More extensive tests (i.e. checking that when a callout is called it can
+// only register and deregister callouts within its library) require that
+// the CalloutHandle object pass the appropriate LibraryHandle to the
+// callout.  These tests are done in the handles_unittest tests.
+
+TEST_F(CalloutManagerTest, LibraryHandleRegistration) {
+    // Ensure that no callouts are attached to any of the hooks.
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
+
+    // Set up so that hooks "alpha" and "beta" have callouts attached from a
+    // different libraries.
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->getLibraryHandle().registerCallout("alpha",
+                                                            callout_one);
+    getCalloutManager()->getLibraryHandle().registerCallout("alpha",
+                                                            callout_two);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->getLibraryHandle().registerCallout("alpha",
+                                                            callout_three);
+    getCalloutManager()->getLibraryHandle().registerCallout("alpha",
+                                                            callout_four);
+
+    // Check all is as expected.
+    EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
+    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
+                 
+    // Check that calling the callouts returns as expected. (This is also a
+    // test of the callCallouts method.)
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1234, callout_value_);
+
+    // Deregister a callout on library index 0 (after we check we can't
+    // deregister it through library index 1).
+    getCalloutManager()->setLibraryIndex(1);
+    EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", callout_two));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1234, callout_value_);
+
+    getCalloutManager()->setLibraryIndex(0);
+    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(134, callout_value_);
+
+    // Deregister all callouts on library index 1.
+    getCalloutManager()->setLibraryIndex(1);
+    EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
+    callout_value_ = 0;
+    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
+    EXPECT_EQ(1, callout_value_);
+}
+
+// The setting of the hook index is checked in the handles_unittest
+// set of tests, as access restrictions mean it is not easily tested
+// on its own.
+
+} // Anonymous namespace
diff --git a/src/lib/hooks/tests/handles_unittest.cc b/src/lib/hooks/tests/handles_unittest.cc
new file mode 100644
index 0000000..47a7999
--- /dev/null
+++ b/src/lib/hooks/tests/handles_unittest.cc
@@ -0,0 +1,961 @@
+// Copyright (C) 2013  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 <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+#include <hooks/library_handle.h>
+#include <hooks/server_hooks.h>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <string>
+
+/// @file
+/// CalloutHandle/LibraryHandle interaction tests
+///
+/// This file holds unit tests checking the interaction between the
+/// CalloutHandle/LibraryHandle and CalloutManager classes.  In particular,
+/// they check that:
+///
+/// - A CalloutHandle's context is shared between callouts from the same
+///   library, but there is a separate context for each library.
+///
+/// - The various methods manipulating the items in the CalloutHandle's context
+///   work correctly.
+///
+/// - An active callout can only modify the registration of callouts registered
+///   by its own library.
+
+using namespace isc::hooks;
+using namespace std;
+
+namespace {
+
+class HandlesTest : public ::testing::Test {
+public:
+    /// @brief Constructor
+    ///
+    /// Sets up the various elements used in each test.
+    HandlesTest() {
+        // Set up four hooks, although through gamma
+        ServerHooks& hooks = ServerHooks::getServerHooks();
+        hooks.reset();
+        alpha_index_ = hooks.registerHook("alpha");
+        beta_index_ = hooks.registerHook("beta");
+        gamma_index_ = hooks.registerHook("gamma");
+        delta_index_ = hooks.registerHook("delta");
+
+        // Set up for three libraries.
+        manager_.reset(new CalloutManager(3));
+
+        // Initialize remaining variables.
+        common_string_ = "";
+    }
+
+    /// @brief Return callout manager
+    boost::shared_ptr<CalloutManager> getCalloutManager() {
+        return (manager_);
+    }
+
+    /// Hook indexes - these are frequently accessed, so are accessed directly.
+    int alpha_index_;
+    int beta_index_;
+    int gamma_index_;
+    int delta_index_;
+
+    /// String accessible by all callouts whatever the library
+    static std::string common_string_;
+
+private:
+    /// Callout manager.  Declared static so that the callout functions can
+    /// access it.
+    boost::shared_ptr<CalloutManager> manager_;
+};
+
+/// Define the common string
+std::string HandlesTest::common_string_;
+
+
+// The next set of functions define the callouts used by the tests.  They
+// manipulate the data in such a way that callouts called - and the order in
+// which they were called - can be determined.  The functions also check that
+// the "callout context" data areas are separate.
+//
+// Three libraries are assumed, and each supplies four callouts.  All callouts
+// manipulate two context elements the CalloutHandle, the elements being called
+// "string" and "int" (which describe the type of data manipulated).
+//
+// For the string item, each callout shifts data to the left and inserts its own
+// data.  The data is a string of the form "nmc", where "n" is the number of
+// the library, "m" is the callout number and "y" is the indication of what
+// callout handle was passed as an argument ("1" or "2": "0" is used when no
+// identification has been set in the callout handle).
+//
+// For simplicity, and to cut down the number of functions actually written,
+// the callout indicator ("1" or "2") ) used in the in the CalloutHandle
+// functions is passed via a CalloutArgument.  The argument is named "string":
+// use of a name the same as that of one of the context elements serves as a
+// check that the argument name space and argument context space are separate.
+//
+// For integer data, the value starts at zero and an increment is added on each
+// call.  This increment is equal to:
+//
+// 100 * library number + 10 * callout number + callout handle
+//
+// Although this gives less information than the string value, the reasons for
+// using it are:
+//
+// - It is a separate item in the context, so checks that the context can
+//   handle multiple items.
+// - It provides an item that can be deleted by the context deletion
+//   methods.
+
+
+// Values set in the CalloutHandle context.  There are three libraries, so
+// there are three contexts for the callout, one for each library.
+
+std::string& resultCalloutString(int index) {
+    static std::string result_callout_string[3];
+    return (result_callout_string[index]);
+}
+
+int& resultCalloutInt(int index) {
+    static int result_callout_int[3];
+    return (result_callout_int[index]);
+}
+
+// A simple function to zero the results.
+
+static void zero_results() {
+    for (int i = 0; i < 3; ++i) {
+        resultCalloutString(i) = "";
+        resultCalloutInt(i) = 0;
+    }
+}
+
+
+// Library callouts.
+
+// Common code for setting the callout context values.
+
+int
+execute(CalloutHandle& callout_handle, int library_num, int callout_num) {
+
+    // Obtain the callout handle number
+    int handle_num = 0;
+    try  {
+        callout_handle.getArgument("handle_num", handle_num);
+    } catch (const NoSuchArgument&) {
+        // handle_num argument not set: this is the case in the tests where
+        // the context_create hook check is tested.
+        handle_num = 0;
+    }
+
+    // Create the basic data to be appended to the context value.
+    int idata = 100 * library_num + 10 * callout_num + handle_num;
+    string sdata = boost::lexical_cast<string>(idata);
+
+    // Get the context data. As before, this will not exist for the first
+    // callout called. (In real life, the library should create it when the
+    // "context_create" hook gets called before any packet processing takes
+    // place.)
+    int int_value = 0;
+    try {
+        callout_handle.getContext("int", int_value);
+    } catch (const NoSuchCalloutContext&) {
+        int_value = 0;
+    }
+
+    string string_value = "";
+    try {
+        callout_handle.getContext("string", string_value);
+    } catch (const NoSuchCalloutContext&) {
+        string_value = "";
+    }
+
+    // Update the values and set them back in the callout context.
+    int_value += idata;
+    callout_handle.setContext("int", int_value);
+
+    string_value += sdata;
+    callout_handle.setContext("string", string_value);
+
+    return (0);
+}
+
+// The following functions are the actual callouts - the name is of the
+// form "callout_<library number>_<callout number>"
+
+int
+callout11(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 1, 1));
+}
+
+int
+callout12(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 1, 2));
+}
+
+int
+callout13(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 1, 3));
+}
+
+int
+callout21(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 2, 1));
+}
+
+int
+callout22(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 2, 2));
+}
+
+int
+callout23(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 2, 3));
+}
+
+int
+callout31(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 3, 1));
+}
+
+int
+callout32(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 3, 2));
+}
+
+int
+callout33(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 3, 3));
+}
+
+// Common callout code for the fourth hook (which makes the data available for
+// checking).  It copies the library and callout context data to the global
+// variables.
+
+int printExecute(CalloutHandle& callout_handle, int library_num) {
+    callout_handle.getContext("string", resultCalloutString(library_num - 1));
+    callout_handle.getContext("int", resultCalloutInt(library_num - 1));
+
+    return (0);
+}
+
+// These are the actual callouts.
+
+int
+print1(CalloutHandle& callout_handle) {
+    return (printExecute(callout_handle, 1));
+}
+
+int
+print2(CalloutHandle& callout_handle) {
+    return (printExecute(callout_handle, 2));
+}
+
+int
+print3(CalloutHandle& callout_handle) {
+    return (printExecute(callout_handle, 3));
+}
+
+// This test checks the many-faced nature of the context for the CalloutContext.
+
+TEST_F(HandlesTest, ContextAccessCheck) {
+    // Register callouts for the different libraries.
+    CalloutHandle handle(getCalloutManager());
+
+    // Library 0.
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout11);
+    getCalloutManager()->registerCallout("beta", callout12);
+    getCalloutManager()->registerCallout("gamma", callout13);
+    getCalloutManager()->registerCallout("delta", print1);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout21);
+    getCalloutManager()->registerCallout("beta", callout22);
+    getCalloutManager()->registerCallout("gamma", callout23);
+    getCalloutManager()->registerCallout("delta", print2);
+
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout31);
+    getCalloutManager()->registerCallout("beta", callout32);
+    getCalloutManager()->registerCallout("gamma", callout33);
+    getCalloutManager()->registerCallout("delta", print3);
+
+    // Create the callout handles and distinguish them by setting the
+    // "handle_num" argument.
+    CalloutHandle callout_handle_1(getCalloutManager());
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+
+    CalloutHandle callout_handle_2(getCalloutManager());
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+
+    // Now call the callouts attached to the first three hooks.  Each hook is
+    // called twice (once for each callout handle) before the next hook is
+    // called.
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
+    getCalloutManager()->callCallouts(beta_index_, callout_handle_1);
+    getCalloutManager()->callCallouts(beta_index_, callout_handle_2);
+    getCalloutManager()->callCallouts(gamma_index_, callout_handle_1);
+    getCalloutManager()->callCallouts(gamma_index_, callout_handle_2);
+
+    // Get the results for each callout (the callout on hook "delta" copies
+    // the context values into a location the test can access).  Explicitly
+    // zero the variables before getting the results so we are certain that
+    // the values are the results of the callouts.
+
+    zero_results();
+
+    // To explain the expected callout context results.
+    //
+    // Each callout handle maintains a separate context for each library.  When
+    // the first call to callCallouts() is made, "111" gets appended to
+    // the context for library 1 maintained by the first callout handle, "211"
+    // gets appended to the context maintained for library 2, and "311" to
+    // the context maintained for library 3.  In each case, the first digit
+    // corresponds to the library number, the second to the callout number and
+    // the third to the "handle_num" of the callout handle. For the first call
+    // to callCallouts, handle 1 is used, so the last digit is always 1.
+    //
+    // The next call to callCallouts() calls the same callouts but for the
+    // second callout handle.  It also maintains three contexts (one for
+    // each library) and they will get "112", "212", "312" appended to
+    // them. The explanation for the digits is the same as before, except that
+    // in this case, the callout handle is number 2, so the third digit is
+    // always 2.  These additions don't affect the contexts maintained by
+    // callout handle 1.
+    //
+    // The process is then repeated for hooks "beta" and "gamma" which, for
+    // callout handle 1, append "121", "221" and "321" for hook "beta" and
+    // "311", "321" and "331" for hook "gamma".
+    //
+    // The expected integer values can be found by summing up the values
+    // corresponding to the elements of the strings.
+
+    // At this point, we have only called the "print" function for callout
+    // handle "1", so the following results are checking the context values
+    // maintained in that callout handle.
+
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
+    EXPECT_EQ("111121131", resultCalloutString(0));
+    EXPECT_EQ("211221231", resultCalloutString(1));
+    EXPECT_EQ("311321331", resultCalloutString(2));
+
+    EXPECT_EQ((111 + 121 + 131), resultCalloutInt(0));
+    EXPECT_EQ((211 + 221 + 231), resultCalloutInt(1));
+    EXPECT_EQ((311 + 321 + 331), resultCalloutInt(2));
+
+    // Repeat the checks for callout 2.
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
+
+    EXPECT_EQ((112 + 122 + 132), resultCalloutInt(0));
+    EXPECT_EQ((212 + 222 + 232), resultCalloutInt(1));
+    EXPECT_EQ((312 + 322 + 332), resultCalloutInt(2));
+
+    EXPECT_EQ("112122132", resultCalloutString(0));
+    EXPECT_EQ("212222232", resultCalloutString(1));
+    EXPECT_EQ("312322332", resultCalloutString(2));
+}
+
+// Now repeat the test, but add a deletion callout to the list.  The "beta"
+// hook of library 2 will have an additional callout to delete the "int"
+// element: the same hook for library 3 will delete both elements.  In
+// addition, the names of context elements for the libraries at this point
+// will be printed.
+
+// List of context item names.
+
+vector<string>&
+getItemNames(int index) {
+    static vector<string> context_items[3];
+    return (context_items[index]);
+}
+
+// Context item deletion functions.
+
+int
+deleteIntContextItem(CalloutHandle& handle) {
+    handle.deleteContext("int");
+    return (0);
+}
+
+int
+deleteAllContextItems(CalloutHandle& handle) {
+    handle.deleteAllContext();
+    return (0);
+}
+
+// Generic print function - copy names in sorted order.
+
+int
+printContextNamesExecute(CalloutHandle& handle, int library_num) {
+    const int index = library_num - 1;
+    getItemNames(index) = handle.getContextNames();
+    sort(getItemNames(index).begin(), getItemNames(index).end());
+    return (0);
+}
+
+int
+printContextNames1(CalloutHandle& handle) {
+    return (printContextNamesExecute(handle, 1));
+}
+
+int
+printContextNames2(CalloutHandle& handle) {
+    return (printContextNamesExecute(handle, 2));
+}
+
+int
+printContextNames3(CalloutHandle& handle) {
+    return (printContextNamesExecute(handle, 3));
+}
+
+// Perform the test including deletion of context items.
+
+TEST_F(HandlesTest, ContextDeletionCheck) {
+
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout11);
+    getCalloutManager()->registerCallout("beta", callout12);
+    getCalloutManager()->registerCallout("beta", printContextNames1);
+    getCalloutManager()->registerCallout("gamma", callout13);
+    getCalloutManager()->registerCallout("delta", print1);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout21);
+    getCalloutManager()->registerCallout("beta", callout22);
+    getCalloutManager()->registerCallout("beta", deleteIntContextItem);
+    getCalloutManager()->registerCallout("beta", printContextNames2);
+    getCalloutManager()->registerCallout("gamma", callout23);
+    getCalloutManager()->registerCallout("delta", print2);
+
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout31);
+    getCalloutManager()->registerCallout("beta", callout32);
+    getCalloutManager()->registerCallout("beta", deleteAllContextItems);
+    getCalloutManager()->registerCallout("beta", printContextNames3);
+    getCalloutManager()->registerCallout("gamma", callout33);
+    getCalloutManager()->registerCallout("delta", print3);
+
+    // Create the callout handles and distinguish them by setting the "long"
+    // argument.
+    CalloutHandle callout_handle_1(getCalloutManager());
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1));
+
+    CalloutHandle callout_handle_2(getCalloutManager());
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2));
+
+    // Now call the callouts attached to the first three hooks.  Each hook is
+    // called twice (once for each callout handle) before the next hook is
+    // called.
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
+    getCalloutManager()->callCallouts(beta_index_, callout_handle_1);
+    getCalloutManager()->callCallouts(beta_index_, callout_handle_2);
+    getCalloutManager()->callCallouts(gamma_index_, callout_handle_1);
+    getCalloutManager()->callCallouts(gamma_index_, callout_handle_2);
+
+    // Get the results for each callout.  Explicitly zero the variables before
+    // getting the results so we are certain that the values are the results
+    // of the callouts.
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
+
+    // The logic by which the expected results are arrived at is described
+    // in the ContextAccessCheck test.  The results here are different
+    // because context items have been modified along the way.
+
+    EXPECT_EQ((111 + 121 + 131), resultCalloutInt(0));
+    EXPECT_EQ((            231), resultCalloutInt(1));
+    EXPECT_EQ((            331), resultCalloutInt(2));
+
+    EXPECT_EQ("111121131", resultCalloutString(0));
+    EXPECT_EQ("211221231", resultCalloutString(1));
+    EXPECT_EQ(      "331", resultCalloutString(2));
+
+    // Repeat the checks for callout handle 2.
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
+
+    EXPECT_EQ((112 + 122 + 132), resultCalloutInt(0));
+    EXPECT_EQ((            232), resultCalloutInt(1));
+    EXPECT_EQ((            332), resultCalloutInt(2));
+
+    EXPECT_EQ("112122132", resultCalloutString(0));
+    EXPECT_EQ("212222232", resultCalloutString(1));
+    EXPECT_EQ(      "332", resultCalloutString(2));
+
+    // ... and check what the names of the context items are after the callouts
+    // for hook "beta".  We know they are in sorted order.
+
+    EXPECT_EQ(2, getItemNames(0).size());
+    EXPECT_EQ(string("int"),    getItemNames(0)[0]);
+    EXPECT_EQ(string("string"), getItemNames(0)[1]);
+
+    EXPECT_EQ(1, getItemNames(1).size());
+    EXPECT_EQ(string("string"), getItemNames(1)[0]);
+
+    EXPECT_EQ(0, getItemNames(2).size());
+}
+
+// Tests that the CalloutHandle's constructor and destructor call the
+// context_create and context_destroy callbacks (if registered).  For
+// simplicity, we'll use the same callout functions as used above, plus
+// the following that returns an error:
+
+int returnError(CalloutHandle&) {
+    return (1);
+}
+
+TEST_F(HandlesTest, ConstructionDestructionCallouts) {
+
+    // Register context callouts.
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("context_create", callout11);
+    getCalloutManager()->registerCallout("context_create", print1);
+    getCalloutManager()->registerCallout("context_destroy", callout12);
+    getCalloutManager()->registerCallout("context_destroy", print1);
+
+    // Create the CalloutHandle and check that the constructor callout
+    // has run.
+    zero_results();
+    boost::scoped_ptr<CalloutHandle>
+        callout_handle(new CalloutHandle(getCalloutManager()));
+    EXPECT_EQ("110", resultCalloutString(0));
+    EXPECT_EQ(110, resultCalloutInt(0));
+
+    // Check that the destructor callout runs.  Note that the "print1" callout
+    // didn't destroy the library context - it only copied it to where it
+    // could be examined.  As a result, the destructor callout appends its
+    // elements to the constructor's values and the result is printed.
+    zero_results();
+    callout_handle.reset();
+
+    EXPECT_EQ("110120", resultCalloutString(0));
+    EXPECT_EQ((110 + 120), resultCalloutInt(0));
+}
+
+// Dynamic callout registration and deregistration.
+// The following are the dynamic registration/deregistration callouts.
+
+
+// Add callout_78_alpha - adds a callout to hook alpha that appends "78x"
+// (where "x" is the callout handle) to the current output.
+
+int
+callout78(CalloutHandle& callout_handle) {
+    return (execute(callout_handle, 7, 8));
+}
+
+int
+add_callout78_alpha(CalloutHandle& callout_handle) {
+    callout_handle.getLibraryHandle().registerCallout("alpha", callout78);
+    return (0);
+}
+
+int
+delete_callout78_alpha(CalloutHandle& callout_handle) {
+    static_cast<void>(
+        callout_handle.getLibraryHandle().deregisterCallout("alpha",
+                                                            callout78));
+    return (0);
+}
+
+// Check that a callout can register another callout on a different hook.
+
+TEST_F(HandlesTest, DynamicRegistrationAnotherHook) {
+    // Register callouts for the different libraries.
+    CalloutHandle handle(getCalloutManager());
+
+    // Set up callouts on "alpha".
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout11);
+    getCalloutManager()->registerCallout("delta", print1);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout21);
+    getCalloutManager()->registerCallout("delta", print2);
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", callout31);
+    getCalloutManager()->registerCallout("delta", print3);
+
+    // ... and on "beta", set up the function to add a hook to alpha (but only
+    // for library 1).
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("beta", add_callout78_alpha);
+
+    // See what we get for calling the callouts on alpha first.
+    CalloutHandle callout_handle_1(getCalloutManager());
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
+    EXPECT_EQ("111", resultCalloutString(0));
+    EXPECT_EQ("211", resultCalloutString(1));
+    EXPECT_EQ("311", resultCalloutString(2));
+
+    // All as expected, now call the callouts on beta.  This should add a
+    // callout to the list of callouts for alpha, which we should see when
+    // we run the test again.
+    getCalloutManager()->callCallouts(beta_index_, callout_handle_1);
+
+    // Use a new callout handle so as to get fresh callout context.
+    CalloutHandle callout_handle_2(getCalloutManager());
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
+    EXPECT_EQ("112", resultCalloutString(0));
+    EXPECT_EQ("212782", resultCalloutString(1));
+    EXPECT_EQ("312", resultCalloutString(2));
+}
+
+// Check that a callout can register another callout on the same hook.
+// Note that the registration only applies to a subsequent invocation of
+// callCallouts, not to the current one. In other words, if
+//
+// * the callout list for a library is "A then B then C"
+// * when callCallouts is executed "B" adds "D" to that list,
+//
+// ... the current execution of callCallouts only executes A, B and C.  A
+// subsequent invocation will execute A, B, C then D.
+
+TEST_F(HandlesTest, DynamicRegistrationSameHook) {
+    // Register callouts for the different libraries.
+    CalloutHandle handle(getCalloutManager());
+
+    // Set up callouts on "alpha".
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout11);
+    getCalloutManager()->registerCallout("alpha", add_callout78_alpha);
+    getCalloutManager()->registerCallout("delta", print1);
+
+    // See what we get for calling the callouts on alpha first.
+    CalloutHandle callout_handle_1(getCalloutManager());
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
+    EXPECT_EQ("111", resultCalloutString(0));
+
+    // Run it again - we should have added something to this hook.
+    CalloutHandle callout_handle_2(getCalloutManager());
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
+    EXPECT_EQ("112782", resultCalloutString(0));
+
+    // And a third time...
+    CalloutHandle callout_handle_3(getCalloutManager());
+    callout_handle_3.setArgument("handle_num", static_cast<int>(3)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_3);
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_3);
+    EXPECT_EQ("113783783", resultCalloutString(0));
+}
+
+// Deregistration of a callout from a different hook
+
+TEST_F(HandlesTest, DynamicDeregistrationDifferentHook) {
+    // Register callouts for the different libraries.
+    CalloutHandle handle(getCalloutManager());
+
+    // Set up callouts on "alpha".
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout11);
+    getCalloutManager()->registerCallout("alpha", callout78);
+    getCalloutManager()->registerCallout("alpha", callout11);
+    getCalloutManager()->registerCallout("delta", print1);
+
+    getCalloutManager()->registerCallout("beta", delete_callout78_alpha);
+
+    // Call the callouts on alpha
+    CalloutHandle callout_handle_1(getCalloutManager());
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
+    EXPECT_EQ("111781111", resultCalloutString(0));
+
+    // Run the callouts on hook beta to remove the callout on alpha.
+    getCalloutManager()->callCallouts(beta_index_, callout_handle_1);
+
+    // The run of the callouts should have altered the callout list on the
+    // first library for hook alpha, so call again to make sure.
+    CalloutHandle callout_handle_2(getCalloutManager());
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
+    EXPECT_EQ("112112", resultCalloutString(0));
+}
+
+// Deregistration of a callout from the same hook
+
+TEST_F(HandlesTest, DynamicDeregistrationSameHook) {
+    // Register callouts for the different libraries.
+    CalloutHandle handle(getCalloutManager());
+
+    // Set up callouts on "alpha".
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout11);
+    getCalloutManager()->registerCallout("alpha", delete_callout78_alpha);
+    getCalloutManager()->registerCallout("alpha", callout78);
+    getCalloutManager()->registerCallout("delta", print1);
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", callout21);
+    getCalloutManager()->registerCallout("alpha", callout78);
+    getCalloutManager()->registerCallout("delta", print2);
+
+    // Call the callouts on alpha
+    CalloutHandle callout_handle_1(getCalloutManager());
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
+    EXPECT_EQ("111781", resultCalloutString(0));
+    EXPECT_EQ("211781", resultCalloutString(1));
+
+    // The run of the callouts should have altered the callout list on the
+    // first library for hook alpha, so call again to make sure.
+    CalloutHandle callout_handle_2(getCalloutManager());
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
+
+    zero_results();
+    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
+    EXPECT_EQ("112", resultCalloutString(0));
+    EXPECT_EQ("212782", resultCalloutString(1));
+}
+
+// Testing the operation of the "skip" flag.  Callouts print the value
+// they see in the flag and either leave it unchanged, set it or clear it.
+
+int
+calloutPrintSkip(CalloutHandle& handle) {
+    static const std::string YES("Y");
+    static const std::string NO("N");
+
+    HandlesTest::common_string_ = HandlesTest::common_string_ +
+        (handle.getSkip() ? YES : NO);
+    return (0);
+}
+
+int
+calloutSetSkip(CalloutHandle& handle) {
+    static_cast<void>(calloutPrintSkip(handle));
+    handle.setSkip(true);
+    return (0);
+}
+
+int
+calloutClearSkip(CalloutHandle& handle) {
+    static_cast<void>(calloutPrintSkip(handle));
+    handle.setSkip(false);
+    return (0);
+}
+
+// Do a series of tests, returning with the skip flag set "true".
+
+TEST_F(HandlesTest, ReturnSkipSet) {
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+
+    CalloutHandle callout_handle(getCalloutManager());
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
+
+    // Check result.  For each of visual checking, the expected string is
+    // divided into sections corresponding to the blocks of callouts above.
+    EXPECT_EQ(std::string("NNYY" "NNYYN" "NNYN"), common_string_);
+
+    // ... and check that the skip flag on exit from callCallouts is set.
+    EXPECT_TRUE(callout_handle.getSkip());
+}
+
+// Repeat the test, returning with the skip flag clear.
+TEST_F(HandlesTest, ReturnSkipClear) {
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
+    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
+    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
+
+    CalloutHandle callout_handle(getCalloutManager());
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
+
+    // Check result.  For each of visual checking, the expected string is
+    // divided into sections corresponding to the blocks of callouts above.
+    EXPECT_EQ(std::string("NYY" "NNYNYN" "NNNY"), common_string_);
+
+    // ... and check that the skip flag on exit from callCallouts is set.
+    EXPECT_FALSE(callout_handle.getSkip());
+}
+
+// The next set of callouts do a similar thing to the above "skip" tests,
+// but alter the value of a string argument.  This is for testing that the
+// a callout is able to change an argument and return it to the caller.
+
+const char* MODIFIED_ARG = "modified_arg";
+
+int
+calloutSetArgumentCommon(CalloutHandle& handle, const char* what) {
+    std::string modified_arg = "";
+
+    handle.getArgument(MODIFIED_ARG, modified_arg);
+    modified_arg = modified_arg + std::string(what);
+    handle.setArgument(MODIFIED_ARG, modified_arg);
+    return (0);
+}
+
+int
+calloutSetArgumentYes(CalloutHandle& handle) {
+    return (calloutSetArgumentCommon(handle, "Y"));
+}
+
+int
+calloutSetArgumentNo(CalloutHandle& handle) {
+    return (calloutSetArgumentCommon(handle, "N"));
+}
+
+// ... and a callout to just copy the argument to the "common_string_" variable
+// but otherwise not alter it.
+
+int
+calloutPrintArgument(CalloutHandle& handle) {
+    handle.getArgument(MODIFIED_ARG, HandlesTest::common_string_);
+    return (0);
+}
+
+TEST_F(HandlesTest, CheckModifiedArgument) {
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+    getCalloutManager()->registerCallout("alpha", calloutPrintArgument);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+
+    getCalloutManager()->setLibraryIndex(2);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
+    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
+
+    // Create the argument with an initial empty string value.  Then call the
+    // sequence of callouts above.
+    CalloutHandle callout_handle(getCalloutManager());
+    std::string modified_arg = "";
+    callout_handle.setArgument(MODIFIED_ARG, modified_arg);
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
+
+    // Check the intermediate and results.  For visual checking, the expected
+    // string is divided into sections corresponding to the blocks of callouts
+    // above.
+    EXPECT_EQ(std::string("YNN" "YY"), common_string_);
+
+    callout_handle.getArgument(MODIFIED_ARG, modified_arg);
+    EXPECT_EQ(std::string("YNN" "YYNN" "YNY"), modified_arg);
+}
+
+// Test that the CalloutHandle provides the name of the hook to which the
+// callout is attached.
+
+int
+callout_hook_name(CalloutHandle& callout_handle) {
+    HandlesTest::common_string_ = callout_handle.getHookName();
+    return (0);
+}
+
+int
+callout_hook_dummy(CalloutHandle&) {
+    return (0);
+}
+
+TEST_F(HandlesTest, HookName) {
+    getCalloutManager()->setLibraryIndex(0);
+    getCalloutManager()->registerCallout("alpha", callout_hook_name);
+    getCalloutManager()->registerCallout("beta", callout_hook_name);
+
+    // Call alpha abd beta callouts and check the hook to which they belong.
+    CalloutHandle callout_handle(getCalloutManager());
+
+    EXPECT_EQ(std::string(""), HandlesTest::common_string_);
+
+    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
+    EXPECT_EQ(std::string("alpha"), HandlesTest::common_string_);
+
+    getCalloutManager()->callCallouts(beta_index_, callout_handle);
+    EXPECT_EQ(std::string("beta"), HandlesTest::common_string_);
+
+    // Make sure that the callout accesses the name even if it is not the
+    // only callout in the list.
+    getCalloutManager()->setLibraryIndex(1);
+    getCalloutManager()->registerCallout("gamma", callout_hook_dummy);
+    getCalloutManager()->registerCallout("gamma", callout_hook_dummy);
+    getCalloutManager()->registerCallout("gamma", callout_hook_name);
+
+    EXPECT_EQ(std::string("beta"), HandlesTest::common_string_);
+    getCalloutManager()->callCallouts(gamma_index_, callout_handle);
+    EXPECT_EQ(std::string("gamma"), HandlesTest::common_string_);
+}
+
+} // Anonymous namespace
+
diff --git a/src/lib/hooks/tests/incorrect_version_library.cc b/src/lib/hooks/tests/incorrect_version_library.cc
new file mode 100644
index 0000000..30685f2
--- /dev/null
+++ b/src/lib/hooks/tests/incorrect_version_library.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2013  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.
+
+/// @file
+/// @brief Incorrect version function test
+/// This is a test file for the LibraryManager test.  It produces a library
+/// that contans a "version" function but which returns an incorrect version
+/// number.
+
+#include <hooks/hooks.h>
+
+extern "C" {
+
+int version() {
+    return (BIND10_HOOKS_VERSION + 1);
+}
+
+};
diff --git a/src/lib/hooks/tests/library_manager_unittest.cc.in b/src/lib/hooks/tests/library_manager_unittest.cc.in
new file mode 100644
index 0000000..8646b75
--- /dev/null
+++ b/src/lib/hooks/tests/library_manager_unittest.cc.in
@@ -0,0 +1,424 @@
+// Copyright (C) 2013  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 <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+#include <hooks/library_manager.h>
+#include <hooks/server_hooks.h>
+#include <hooks/tests/marker_file.h>
+
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <fstream>
+#include <string>
+
+#include <unistd.h>
+
+
+using namespace isc;
+using namespace isc::hooks;
+using namespace std;
+
+/// @brief Library manager test class
+
+class LibraryManagerTest : public ::testing::Test {
+public:
+    /// @brief Constructor
+    ///
+    /// Sets up a collection of three LibraryHandle objects to use in the test.
+    LibraryManagerTest() {
+
+        // Set up the server hooks.  There is sone singleton for all tests,
+        // so reset it and explicitly set up the hooks for the test.
+        ServerHooks& hooks = ServerHooks::getServerHooks();
+        hooks.reset();
+        lm_one_index_ = hooks.registerHook("lm_one");
+        lm_two_index_ = hooks.registerHook("lm_two");
+        lm_three_index_ = hooks.registerHook("lm_three");
+
+        // Set up the callout manager with these hooks.  Assume a maximum of
+        // four libraries.
+        callout_manager_.reset(new CalloutManager(1));
+
+        // Set up the callout handle.
+        callout_handle_.reset(new CalloutHandle(callout_manager_));
+
+        // Ensure the marker file is not present
+        static_cast<void>(unlink(MARKER_FILE));
+    }
+
+    /// @brief Destructor
+    ///
+    /// Ensures a marker file is removed after the test.
+    ~LibraryManagerTest() {
+        static_cast<void>(unlink(MARKER_FILE));
+    }
+
+    /// Hook indexes.  These are somewhat ubiquitous, so are made public for
+    /// ease of reference instead of being accessible by a function.
+    int lm_one_index_;
+    int lm_two_index_;
+    int lm_three_index_;
+
+    /// Callout handle used in calls
+    boost::shared_ptr<CalloutHandle> callout_handle_;
+
+    /// Callout manager used for the test
+    boost::shared_ptr<CalloutManager> callout_manager_;
+};
+
+
+/// @brief Library manager class
+///
+/// This is an instance of the LibraryManager class but with the protected
+/// methods made public for test purposes.
+
+class PublicLibraryManager : public isc::hooks::LibraryManager {
+public:
+    /// @brief Constructor
+    ///
+    /// Stores the library name.  The actual loading is done in loadLibrary().
+    ///
+    /// @param name Name of the library to load.  This should be an absolute
+    ///        path name.
+    /// @param index Index of this library.  For all these tests, it will be
+    ///        zero, as we are only using one library.
+    /// @param manager CalloutManager object
+    PublicLibraryManager(const std::string& name, int index,
+                         const boost::shared_ptr<CalloutManager>& manager)
+        : LibraryManager(name, index, manager)
+    {}
+
+    /// @brief Destructor
+    ///
+    /// Ensures that the library is closed after the test.
+    ~PublicLibraryManager() {
+        static_cast<void>(closeLibrary());
+    }
+
+    /// Public methods that call protected methods on the superclass.
+    using LibraryManager::openLibrary;
+    using LibraryManager::closeLibrary;
+    using LibraryManager::checkVersion;
+    using LibraryManager::registerStandardCallouts;
+    using LibraryManager::runLoad;
+    using LibraryManager::runUnload;
+};
+
+// Names of the libraries used in these tests.  These libraries are built using
+// libtool, so we need to look in the hidden ".libs" directory to locate the
+// .so file.  Note that we access the .so file - libtool creates this as a
+// like to the real shared library.
+static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libbcl.so";
+static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/.libs/libivl.so";
+static const char* LOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/liblcl.so";
+static const char* LOAD_ERROR_CALLOUT_LIBRARY =
+    "@abs_builddir@/.libs/liblecl.so";
+static const char* NOT_PRESENT_LIBRARY = "@abs_builddir@/.libs/libnothere.so";
+static const char* NO_VERSION_LIBRARY = "@abs_builddir@/.libs/libnvl.so";
+static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libucl.so";
+
+
+namespace {
+
+// Tests that OpenLibrary reports an error for an unknown library.
+
+TEST_F(LibraryManagerTest, NonExistentLibrary) {
+    PublicLibraryManager lib_manager(std::string(NOT_PRESENT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_FALSE(lib_manager.openLibrary());
+}
+
+// Tests that the openLibrary() and closeLibrary() methods work.
+
+TEST_F(LibraryManagerTest, OpenClose) {
+    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+
+    // Open and close the library
+    EXPECT_TRUE(lib_manager.openLibrary());
+    EXPECT_TRUE(lib_manager.closeLibrary());
+
+    // Check that a second close does not report an error.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Check that the code handles the case of a library with no version function.
+
+TEST_F(LibraryManagerTest, NoVersionFunction) {
+    PublicLibraryManager lib_manager(std::string(NO_VERSION_LIBRARY),
+                                     0, callout_manager_);
+    // Open should succeed.
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Version check should fail.
+    EXPECT_FALSE(lib_manager.checkVersion());
+
+    // Tidy up.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Check that the code handles the case of a library with a version function
+// that returns an incorrect version number.
+
+TEST_F(LibraryManagerTest, IncorrectVersionReturned) {
+    PublicLibraryManager lib_manager(std::string(INCORRECT_VERSION_LIBRARY),
+                                     0, callout_manager_);
+    // Open should succeed.
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Version check should fail.
+    EXPECT_FALSE(lib_manager.checkVersion());
+
+    // Tidy up.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Tests that checkVersion() function succeeds in the case of a library with a
+// version function that returns the correct version number.
+
+TEST_F(LibraryManagerTest, CorrectVersionReturned) {
+    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    // Open should succeed.
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Version check should succeed.
+    EXPECT_TRUE(lib_manager.checkVersion());
+
+    // Tidy up.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Checks the registration of standard callouts.
+
+TEST_F(LibraryManagerTest, RegisterStandardCallouts) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                               0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check the version of the library.
+    EXPECT_TRUE(lib_manager.checkVersion());
+
+    // Load the standard callouts
+    EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
+
+    int result = 0;
+
+    // Now execute the callouts in the order expected.  context_create
+    // always comes first.  This sets the context value to 10.
+    callout_manager_->callCallouts(ServerHooks::CONTEXT_CREATE,
+                                   *callout_handle_);
+
+    // First callout adds 5 to the context value.
+    callout_handle_->setArgument("data_1", static_cast<int>(5));
+    callout_manager_->callCallouts(lm_one_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
+    EXPECT_EQ(15, result);
+
+    // Second callout multiples the running total by 7
+    callout_handle_->setArgument("data_2", static_cast<int>(7));
+    callout_manager_->callCallouts(lm_two_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
+    EXPECT_EQ(105, result);
+
+    // Third callout subtracts 17 from the running total.
+    callout_handle_->setArgument("data_3", static_cast<int>(17));
+    callout_manager_->callCallouts(lm_three_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
+    EXPECT_EQ(88, result);
+
+    // Explicitly clear the callout_handle_ so that we can delete the library.
+    // This is the only object to contain memory allocated by it.
+    callout_handle_.reset();
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Test that the "load" function is called correctly.
+
+TEST_F(LibraryManagerTest, CheckLoadCalled) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(LOAD_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check the version of the library.
+    EXPECT_TRUE(lib_manager.checkVersion());
+
+    // Load the standard callouts
+    EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
+
+    int result = 0;
+
+    // Check that only context_create and lm_one have callouts registered.
+    EXPECT_TRUE(callout_manager_->calloutsPresent(
+                ServerHooks::CONTEXT_CREATE));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(
+                 ServerHooks::CONTEXT_DESTROY));
+
+    // Call the runLoad() method to run the load() function.
+    EXPECT_TRUE(lib_manager.runLoad());
+    EXPECT_TRUE(callout_manager_->calloutsPresent(
+                ServerHooks::CONTEXT_CREATE));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_two_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(
+                 ServerHooks::CONTEXT_DESTROY));
+
+    // Now execute the callouts in the order expected.
+    // only the first callout should be executed and the
+    // always comes first.  This sets the context value to 10.
+    callout_manager_->callCallouts(ServerHooks::CONTEXT_CREATE,
+                                   *callout_handle_);
+
+    // First callout multiplies the passed data by 5.
+    callout_handle_->setArgument("data_1", static_cast<int>(5));
+    callout_manager_->callCallouts(lm_one_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
+    EXPECT_EQ(25, result);
+
+    // Second callout adds 7 to the stored data.
+    callout_handle_->setArgument("data_2", static_cast<int>(7));
+    callout_manager_->callCallouts(lm_two_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
+    EXPECT_EQ(32, result);
+
+    // Third callout multiplies the running total by 10
+    callout_handle_->setArgument("data_3", static_cast<int>(10));
+    callout_manager_->callCallouts(lm_three_index_, *callout_handle_);
+    callout_handle_->getArgument("result", result);
+    EXPECT_EQ(320, result);
+
+    // Explicitly clear the callout_handle_ so that we can delete the library.
+    // This is the only object to contain memory allocated by it.
+    callout_handle_.reset();
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Check handling of a "load" function that returns an error.
+
+TEST_F(LibraryManagerTest, CheckLoadError) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(LOAD_ERROR_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check that we catch a load error
+    EXPECT_FALSE(lib_manager.runLoad());
+
+    // Explicitly clear the callout_handle_ so that we can delete the library.
+    // This is the only object to contain memory allocated by it.
+    callout_handle_.reset();
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// TODO Check that unload is called.  This causes problems with testing
+// in that it can't communicate anything back to the caller.  So we'll
+// test a successful call by checking whether a marker file is created.
+
+// No unload function
+
+TEST_F(LibraryManagerTest, CheckNoUnload) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(BASIC_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check that no unload function returns true.
+    EXPECT_TRUE(lib_manager.runUnload());
+
+    // Explicitly clear the callout_handle_ so that we can delete the library.
+    // This is the only object to contain memory allocated by it.
+    callout_handle_.reset();
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Unload function returns an error
+
+TEST_F(LibraryManagerTest, CheckUnloadError) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(LOAD_ERROR_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check that unload function returning an error returns false.
+    EXPECT_FALSE(lib_manager.runUnload());
+
+    // Explicitly clear the callout_handle_ so that we can delete the library.
+    // This is the only object to contain memory allocated by it.
+    callout_handle_.reset();
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+// Unload function works
+
+TEST_F(LibraryManagerTest, CheckUnload) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(UNLOAD_CALLOUT_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check that the marker file is not present (at least that the file
+    // open fails).
+    fstream marker;
+    marker.open(MARKER_FILE, fstream::in);
+    EXPECT_TRUE(marker.fail());
+
+    // Check that unload function runs and returns a success
+    EXPECT_TRUE(lib_manager.runUnload());
+
+    // Check that the open succeeded
+    marker.open(MARKER_FILE, fstream::in);
+    EXPECT_TRUE(marker.is_open());
+
+    // Tidy up
+    marker.close();
+
+    // Explicitly clear the callout_handle_ so that we can delete the library.
+    // This is the only object to contain memory allocated by it.
+    callout_handle_.reset();
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
+} // Anonymous namespace
diff --git a/src/lib/hooks/tests/load_callout_library.cc b/src/lib/hooks/tests/load_callout_library.cc
new file mode 100644
index 0000000..1294e76
--- /dev/null
+++ b/src/lib/hooks/tests/load_callout_library.cc
@@ -0,0 +1,121 @@
+// Copyright (C) 2013  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.
+
+/// @file
+/// @brief Basic Load Library
+///
+/// This is a test file for the LibraryManager test.  It produces a library
+/// that allows for tests of the basic library manager functions.
+///
+/// The characteristics of this library are:
+///
+/// - The "version" and "load" framework functions are supplied.  One "standard"
+///   callout is supplied ("lm_one") and two non-standard ones which are
+///   registered during the call to "load" on the hooks "lm_two" and
+///   "lm_three". 
+///
+///   All callouts do trivial calculations, the result of the calculation being
+///
+///   @f[ ((5 * data_1) + data_2) * data_3 @f]
+///
+///   ...where data_1, data_2 and data_3 are the values passed in arguments
+///   of the same name to the three callouts (data_1 passed to lm_one,
+///   data_2 to lm_two etc.) and the result is returned in the argument
+///   "result".
+
+#include <hooks/hooks.h>
+#include <iostream>
+
+using namespace isc::hooks;
+
+extern "C" {
+
+// Callouts
+
+int
+context_create(CalloutHandle& handle) {
+    handle.setContext("result", static_cast<int>(5));
+    handle.setArgument("result", static_cast<int>(5));
+    return (0);
+}
+
+// First callout multiples the passed "data_1" argument to the initialized
+// context value of 5.
+
+int
+lm_one(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_1", data);
+
+    int result;
+    handle.getContext("result", result);
+
+    result *= data;
+    handle.setContext("result", result);
+    handle.setArgument("result", result);
+
+    return (0);
+}
+
+// Second callout multiplies the current context value by the "data_2"
+// argument.
+
+static int
+lm_nonstandard_two(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_2", data);
+
+    int result;
+    handle.getContext("result", result);
+
+    result += data;
+    handle.setContext("result", result);
+    handle.setArgument("result", result);
+
+    return (0);
+}
+
+// Final callout adds the result in "data_3" and.
+
+static int
+lm_nonstandard_three(CalloutHandle& handle) {
+    int data;
+    handle.getArgument("data_3", data);
+
+    int result;
+    handle.getContext("result", result);
+
+    result *= data;
+    handle.setArgument("result", result);
+
+    return (0);
+}
+
+// Framework functions
+
+int
+version() {
+    return (BIND10_HOOKS_VERSION);
+}
+
+int load(LibraryHandle& handle) {
+    // Register the non-standard functions
+    handle.registerCallout("lm_two", lm_nonstandard_two);
+    handle.registerCallout("lm_three", lm_nonstandard_three);
+
+    return (0);
+}
+
+};
+
diff --git a/src/lib/hooks/tests/load_error_callout_library.cc b/src/lib/hooks/tests/load_error_callout_library.cc
new file mode 100644
index 0000000..5870f3a
--- /dev/null
+++ b/src/lib/hooks/tests/load_error_callout_library.cc
@@ -0,0 +1,51 @@
+// Copyright (C) 2013  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.
+
+/// @file
+/// @brief Error Load Library
+///
+/// This is a test file for the LibraryManager test.  It produces a library
+/// that allows for tests of the basic library manager functions.
+///
+/// The characteristics of this library are:
+///
+/// - All framework functions are supplied.  "version" returns the correct
+///   value, but "load" and unload return an error.
+
+#include <hooks/hooks.h>
+#include <iostream>
+
+using namespace isc::hooks;
+
+extern "C" {
+
+// Framework functions
+
+int
+version() {
+    return (BIND10_HOOKS_VERSION);
+}
+
+int
+load(LibraryHandle&) {
+    return (1);
+}
+
+int
+unload() {
+    return (1);
+}
+
+};
+
diff --git a/src/lib/hooks/tests/marker_file.h.in b/src/lib/hooks/tests/marker_file.h.in
new file mode 100644
index 0000000..e032cdd
--- /dev/null
+++ b/src/lib/hooks/tests/marker_file.h.in
@@ -0,0 +1,27 @@
+// Copyright (C) 2013  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 MARKER_FILE_H
+#define MARKER_FILE_H
+
+/// @file
+/// Define a marker file that is used in tests to prove that an "unload"
+/// function has been called.
+
+namespace {
+const char* MARKER_FILE = "@abs_builddir@/marker_file.dat";
+}
+
+#endif // MARKER_FILE_H
+
diff --git a/src/lib/hooks/tests/no_version_library.cc b/src/lib/hooks/tests/no_version_library.cc
new file mode 100644
index 0000000..448871c
--- /dev/null
+++ b/src/lib/hooks/tests/no_version_library.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2013  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.
+
+/// @file
+/// @brief No version function library
+///
+/// This is a test file for the LibraryManager test.  It produces a library
+/// that does not have a "version" function.
+
+extern "C" {
+
+int no_version() {
+    return (0);
+}
+
+};
diff --git a/src/lib/hooks/tests/run_unittests.cc b/src/lib/hooks/tests/run_unittests.cc
new file mode 100644
index 0000000..f68a58d
--- /dev/null
+++ b/src/lib/hooks/tests/run_unittests.cc
@@ -0,0 +1,25 @@
+// Copyright (C) 2009  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 <log/logger_support.h>
+#include <util/unittests/run_all.h>
+
+#include <gtest/gtest.h>
+
+int
+main(int argc, char* argv[]) {
+    ::testing::InitGoogleTest(&argc, argv);
+    isc::log::initLogger();
+    return (isc::util::unittests::run_all());
+}
diff --git a/src/lib/hooks/tests/server_hooks_unittest.cc b/src/lib/hooks/tests/server_hooks_unittest.cc
new file mode 100644
index 0000000..19ab700
--- /dev/null
+++ b/src/lib/hooks/tests/server_hooks_unittest.cc
@@ -0,0 +1,292 @@
+// Copyright (C) 2013  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 <hooks/server_hooks.h>
+
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+using namespace isc;
+using namespace isc::hooks;
+using namespace std;
+
+namespace {
+
+// Checks the registration of hooks and the interrogation methods.  As the
+// constructor registers two hooks, this is also a test of the constructor.
+
+TEST(ServerHooksTest, RegisterHooks) {
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+
+    // There should be two hooks already registered, with indexes 0 and 1.
+    EXPECT_EQ(2, hooks.getCount());
+    EXPECT_EQ(0, hooks.getIndex("context_create"));
+    EXPECT_EQ(1, hooks.getIndex("context_destroy"));
+
+    // Check that the constants are as expected. (The intermediate variables
+    // are used because of problems with g++ 4.6.1/Ubuntu 11.10 when resolving
+    // the value of the ServerHooks constants when they appeared within the
+    // gtest macro.)
+    const int create_value = ServerHooks::CONTEXT_CREATE;
+    const int destroy_value = ServerHooks::CONTEXT_DESTROY;
+    EXPECT_EQ(0, create_value);
+    EXPECT_EQ(1, destroy_value);
+
+    // Register another couple of hooks.  The test on returned index is based
+    // on knowledge that the hook indexes are assigned in ascending order.
+    int alpha = hooks.registerHook("alpha");
+    EXPECT_EQ(2, alpha);
+    EXPECT_EQ(2, hooks.getIndex("alpha"));
+
+    int beta = hooks.registerHook("beta");
+    EXPECT_EQ(3, beta);
+    EXPECT_EQ(3, hooks.getIndex("beta"));
+
+    // Should be four hooks now
+    EXPECT_EQ(4, hooks.getCount());
+}
+
+// Check that duplicate names cannot be registered.
+
+TEST(ServerHooksTest, DuplicateHooks) {
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+
+    // Ensure we can't duplicate one of the existing names.
+    EXPECT_THROW(hooks.registerHook("context_create"), DuplicateHook);
+
+    // Check we can't duplicate a newly registered hook.
+    int gamma = hooks.registerHook("gamma");
+    EXPECT_EQ(2, gamma);
+    EXPECT_THROW(hooks.registerHook("gamma"), DuplicateHook);
+}
+
+// Checks that we can get the name of the hooks.
+
+TEST(ServerHooksTest, GetHookNames) {
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+    vector<string> expected_names;
+
+    // Add names into the hooks object and to the set of expected names.
+    expected_names.push_back("alpha");
+    expected_names.push_back("beta");
+    expected_names.push_back("gamma");
+    expected_names.push_back("delta");
+    for (int i = 0; i < expected_names.size(); ++i) {
+        hooks.registerHook(expected_names[i].c_str());
+    };
+
+    // Update the expected names to include the pre-defined hook names.
+    expected_names.push_back("context_create");
+    expected_names.push_back("context_destroy");
+
+    // Get the actual hook names
+    vector<string> actual_names = hooks.getHookNames();
+
+    // For comparison, sort the names into alphabetical order and do a straight
+    // vector comparison.
+    sort(expected_names.begin(), expected_names.end());
+    sort(actual_names.begin(), actual_names.end());
+
+    EXPECT_TRUE(expected_names == actual_names);
+}
+
+// Test the inverse hooks functionality (i.e. given an index, get the name).
+
+TEST(ServerHooksTest, GetHookIndexes) {
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+
+    int alpha = hooks.registerHook("alpha");
+    int beta = hooks.registerHook("beta");
+    int gamma = hooks.registerHook("gamma");
+
+    EXPECT_EQ(std::string("context_create"),
+              hooks.getName(ServerHooks::CONTEXT_CREATE));
+    EXPECT_EQ(std::string("context_destroy"),
+              hooks.getName(ServerHooks::CONTEXT_DESTROY));
+    EXPECT_EQ(std::string("alpha"), hooks.getName(alpha));
+    EXPECT_EQ(std::string("beta"), hooks.getName(beta));
+    EXPECT_EQ(std::string("gamma"), hooks.getName(gamma));
+
+    // Check for an invalid index
+    EXPECT_THROW(hooks.getName(-1), NoSuchHook);
+    EXPECT_THROW(hooks.getName(42), NoSuchHook);
+}
+
+// Test the reset functionality.
+
+TEST(ServerHooksTest, Reset) {
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+
+    int alpha = hooks.registerHook("alpha");
+    int beta = hooks.registerHook("beta");
+    int gamma = hooks.registerHook("gamma");
+
+    // Check the counts before and after a reset.
+    EXPECT_EQ(5, hooks.getCount());
+    hooks.reset();
+    EXPECT_EQ(2, hooks.getCount());
+
+    // ... and check that the hooks are as expected.
+    EXPECT_EQ(0, hooks.getIndex("context_create"));
+    EXPECT_EQ(1, hooks.getIndex("context_destroy"));
+}
+
+// Check that getting an unknown name throws an exception.
+
+TEST(ServerHooksTest, UnknownHookName) {
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+
+    EXPECT_THROW(static_cast<void>(hooks.getIndex("unknown")), NoSuchHook);
+}
+
+// Check that the count of hooks is correct.
+
+TEST(ServerHooksTest, HookCount) {
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+
+    // Insert the names into the hooks object
+    hooks.registerHook("alpha");
+    hooks.registerHook("beta");
+    hooks.registerHook("gamma");
+    hooks.registerHook("delta");
+
+    // Should be two more hooks that the number we have registered.
+    EXPECT_EQ(6, hooks.getCount());
+}
+
+// HookRegistrationFunction tests
+
+// Declare some hook registration functions.
+
+int alpha = 0;
+int beta = 0;
+int gamma = 0;
+int delta = 0;
+
+void registerAlphaBeta(ServerHooks& hooks) {
+    alpha = hooks.registerHook("alpha");
+    beta = hooks.registerHook("beta");
+}
+
+void registerGammaDelta(ServerHooks& hooks) {
+    gamma = hooks.registerHook("gamma");
+    delta = hooks.registerHook("delta");
+}
+
+// Add them to the registration vector.  This addition should happen before
+// any tests are run, so we should start off with two functions in the
+// registration vector.
+
+HookRegistrationFunction f1(registerAlphaBeta);
+HookRegistrationFunction f2(registerGammaDelta);
+
+// This is not registered statically: it is used in the latter part of the
+// test.
+
+int epsilon = 0;
+void registerEpsilon(ServerHooks& hooks) {
+    epsilon = hooks.registerHook("epsilon");
+}
+
+// Test that the registration functions were defined and can be executed.
+
+TEST(HookRegistrationFunction, Registration) {
+
+    // The first part of the tests checks the static registration.  As there
+    // is only one list of registration functions, we have to do this first
+    // as the static registration is done outside our control, before the
+    // tests are loaded.
+
+    // Ensure that the hook numbers are initialized.
+    EXPECT_EQ(0, alpha);
+    EXPECT_EQ(0, beta);
+    EXPECT_EQ(0, gamma);
+    EXPECT_EQ(0, delta);
+
+    // Should have two hook registration functions registered.
+    EXPECT_EQ(2, HookRegistrationFunction::getFunctionVector().size());
+
+    // Execute the functions and check that four new hooks were defined (two
+    // from each function).
+    ServerHooks& hooks = ServerHooks::getServerHooks();
+    hooks.reset();
+
+    EXPECT_EQ(2, hooks.getCount());
+    HookRegistrationFunction::execute(hooks);
+    EXPECT_EQ(6, hooks.getCount());
+
+    // Check the hook names are as expected.
+    vector<string> names = hooks.getHookNames();
+    ASSERT_EQ(6, names.size());
+    sort(names.begin(), names.end());
+    EXPECT_EQ(string("alpha"), names[0]);
+    EXPECT_EQ(string("beta"), names[1]);
+    EXPECT_EQ(string("context_create"), names[2]);
+    EXPECT_EQ(string("context_destroy"), names[3]);
+    EXPECT_EQ(string("delta"), names[4]);
+    EXPECT_EQ(string("gamma"), names[5]);
+
+    // Check that numbers in the range 2-5 inclusive were assigned as the
+    // hook indexes (0 and 1 being reserved for context_create and
+    // context_destroy).
+    vector<int> indexes;
+    indexes.push_back(alpha);
+    indexes.push_back(beta);
+    indexes.push_back(gamma);
+    indexes.push_back(delta);
+    sort(indexes.begin(), indexes.end());
+    EXPECT_EQ(2, indexes[0]);
+    EXPECT_EQ(3, indexes[1]);
+    EXPECT_EQ(4, indexes[2]);
+    EXPECT_EQ(5, indexes[3]);
+
+    // One last check.  We'll test that the constructor of does indeed
+    // add a function to the function vector and that the static initialization
+    // was not somehow by chance.
+    HookRegistrationFunction::getFunctionVector().clear();
+    EXPECT_TRUE(HookRegistrationFunction::getFunctionVector().empty());
+    epsilon = 0;
+
+    // Register a single registration function.
+    HookRegistrationFunction f3(registerEpsilon);
+    EXPECT_EQ(1, HookRegistrationFunction::getFunctionVector().size());
+
+    // Execute it...
+    hooks.reset();
+    EXPECT_EQ(0, epsilon);
+    EXPECT_EQ(2, hooks.getCount());
+    HookRegistrationFunction::execute(hooks);
+
+    // There should be three hooks, with the new one assigned an index of 2.
+    names = hooks.getHookNames();
+    ASSERT_EQ(3, names.size());
+    sort(names.begin(), names.end());
+    EXPECT_EQ(string("context_create"), names[0]);
+    EXPECT_EQ(string("context_destroy"), names[1]);
+    EXPECT_EQ(string("epsilon"), names[2]);
+
+    EXPECT_EQ(2, epsilon);
+}
+
+} // Anonymous namespace
diff --git a/src/lib/hooks/tests/unload_callout_library.cc b/src/lib/hooks/tests/unload_callout_library.cc
new file mode 100644
index 0000000..7308d31
--- /dev/null
+++ b/src/lib/hooks/tests/unload_callout_library.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 2013  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.
+
+/// @file
+/// @brief Basic unload library
+///
+/// This is a test file for the LibraryManager test.  It produces a library
+/// that allows for tests of the basic library manager functions.
+///
+/// The characteristics of this library are:
+///
+/// - The "version" and "unload" framework functions are supplied. "version"
+///   returns a valid value and "unload" creates a marker file and returns
+///   success.
+
+#include <hooks/hooks.h>
+#include <hooks/tests/marker_file.h>
+
+#include <fstream>
+
+using namespace isc::hooks;
+
+extern "C" {
+
+// Framework functions
+
+int
+version() {
+    return (BIND10_HOOKS_VERSION);
+}
+
+int unload() {
+    // Create the marker file.
+    std::fstream marker;
+    marker.open(MARKER_FILE, std::fstream::out);
+    marker.close();
+
+    return (0);
+}
+
+};
+
diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am
index 6d07ac8..ff5ef40 100644
--- a/src/lib/util/Makefile.am
+++ b/src/lib/util/Makefile.am
@@ -37,10 +37,6 @@ libb10_util_la_SOURCES += encode/base32hex_from_binary.h
 libb10_util_la_SOURCES += encode/base_n.cc encode/hex.h
 libb10_util_la_SOURCES += encode/binary_from_base32hex.h
 libb10_util_la_SOURCES += encode/binary_from_base16.h
-libb10_util_la_SOURCES += hooks/callout_manager.h hooks/callout_manager.cc
-libb10_util_la_SOURCES += hooks/callout_handle.h hooks/callout_handle.cc
-libb10_util_la_SOURCES += hooks/library_handle.h hooks/library_handle.cc
-libb10_util_la_SOURCES += hooks/server_hooks.h hooks/server_hooks.cc
 libb10_util_la_SOURCES += random/qid_gen.h random/qid_gen.cc
 libb10_util_la_SOURCES += random/random_number_generator.h
 
diff --git a/src/lib/util/hooks/callout_handle.cc b/src/lib/util/hooks/callout_handle.cc
deleted file mode 100644
index 8052823..0000000
--- a/src/lib/util/hooks/callout_handle.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (C) 2013  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 <util/hooks/callout_handle.h>
-#include <util/hooks/callout_manager.h>
-#include <util/hooks/library_handle.h>
-#include <util/hooks/server_hooks.h>
-
-#include <string>
-#include <utility>
-#include <vector>
-
-using namespace std;
-using namespace isc::util;
-
-namespace isc {
-namespace util {
-
-// Constructor.
-CalloutHandle::CalloutHandle(const boost::shared_ptr<CalloutManager>& manager)
-    : arguments_(), context_collection_(), manager_(manager), skip_(false) {
-
-    // Call the "context_create" hook.  We should be OK doing this - although
-    // the constructor has not finished running, all the member variables
-    // have been created.
-    manager_->callCallouts(ServerHooks::CONTEXT_CREATE, *this);
-}
-
-// Destructor
-CalloutHandle::~CalloutHandle() {
-
-    // Call the "context_destroy" hook.  We should be OK doing this - although
-    // the destructor is being called, all the member variables are still in
-    // existence.
-    manager_->callCallouts(ServerHooks::CONTEXT_DESTROY, *this);
-}
-
-// Return the name of all argument items.
-
-vector<string>
-CalloutHandle::getArgumentNames() const {
-
-    vector<string> names;
-    for (ElementCollection::const_iterator i = arguments_.begin();
-         i != arguments_.end(); ++i) {
-        names.push_back(i->first);
-    }
-
-    return (names);
-}
-
-// Return the library handle allowing the callout to access the CalloutManager
-// registration/deregistration functions.
-
-LibraryHandle&
-CalloutHandle::getLibraryHandle() const {
-    return (manager_->getLibraryHandle());
-}
-
-// Return the context for the currently pointed-to library.  This version is
-// used by the "setContext()" method and creates a context for the current
-// library if it does not exist.
-
-CalloutHandle::ElementCollection&
-CalloutHandle::getContextForLibrary() {
-    int libindex = manager_->getLibraryIndex();
-
-    // Access a reference to the element collection for the given index,
-    // creating a new element collection if necessary, and return it.
-    return (context_collection_[libindex]);
-}
-
-// The "const" version of the above, used by the "getContext()" method.  If
-// the context for the current library doesn't exist, throw an exception.
-
-const CalloutHandle::ElementCollection&
-CalloutHandle::getContextForLibrary() const {
-    int libindex = manager_->getLibraryIndex();
-
-    ContextCollection::const_iterator libcontext =
-        context_collection_.find(libindex);
-    if (libcontext == context_collection_.end()) {
-        isc_throw(NoSuchCalloutContext, "unable to find callout context "
-                  "associated with the current library index (" << libindex <<
-                  ")");
-    }
-
-    // Return a reference to the context's element collection.
-    return (libcontext->second);
-}
-
-// Return the name of all items in the context associated with the current]
-// library.
-
-vector<string>
-CalloutHandle::getContextNames() const {
-
-    vector<string> names;
-
-    const ElementCollection& elements = getContextForLibrary();
-    for (ElementCollection::const_iterator i = elements.begin();
-         i != elements.end(); ++i) {
-        names.push_back(i->first);
-    }
-
-    return (names);
-}
-
-} // namespace util
-} // namespace isc
diff --git a/src/lib/util/hooks/callout_handle.h b/src/lib/util/hooks/callout_handle.h
deleted file mode 100644
index 0033505..0000000
--- a/src/lib/util/hooks/callout_handle.h
+++ /dev/null
@@ -1,353 +0,0 @@
-// Copyright (C) 2013  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 CALLOUT_HANDLE_H
-#define CALLOUT_HANDLE_H
-
-#include <exceptions/exceptions.h>
-#include <util/hooks/library_handle.h>
-
-#include <boost/any.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <map>
-#include <string>
-#include <vector>
-
-namespace isc {
-namespace util {
-
-/// @brief No such argument
-///
-/// Thrown if an attempt is made access an argument that does not exist.
-
-class NoSuchArgument : public Exception {
-public:
-    NoSuchArgument(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-/// @brief No such callout context item
-///
-/// Thrown if an attempt is made to get an item of data from this callout's
-/// context and either the context or an item in the context with that name
-/// does not exist.
-
-class NoSuchCalloutContext : public Exception {
-public:
-    NoSuchCalloutContext(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-// Forward declaration of the library handle and related collection classes.
-
-class CalloutManager;
-class LibraryHandle;
-
-/// @brief Per-packet callout handle
-///
-/// An object of this class is associated with every packet (or request)
-/// processed by the server.  It forms the principle means of passing data
-/// between the server and the user-library callouts.
-///
-/// The class allows access to the following information:
-///
-/// - Arguments.  When the callouts associated with a hook are called, they
-///   are passed information by the server (and can return information to it)
-///   through name/value pairs.  Each of these pairs is an argument and the
-///   information is accessed through the {get,set}Argument() methods.
-///
-/// - Per-packet context.  Each packet has a context associated with it, this
-///   context being  on a per-library basis.  In other words, As a packet passes
-///   through the callouts associated with a given library, the callouts can
-///   associate and retrieve information with the packet.  The per-library
-///   nature of the context means that the callouts within a given library can
-///   pass packet-specific information between one another, but they cannot pass
-///   information to callous within another library.  Typically such context
-///   is created in the "context_create" callout and destroyed in the
-///   "context_destroy" callout.  The information is accessed through the
-///   {get,set}Context() methods.
-///
-/// - Per-library handle.  Allows the callout to dynamically register and
-///   deregister callouts. (In the latter case, only functions registered by
-///   functions in the same library as the callout doing the deregistration
-///   can be removed: callouts registered by other libraries cannot be
-///   modified.)
-
-class CalloutHandle {
-public:
-
-    /// Typedef to allow abbreviation of iterator specification in methods.
-    /// The std::string is the argument name and the "boost::any" is the
-    /// corresponding value associated with it.
-    typedef std::map<std::string, boost::any> ElementCollection;
-
-    /// Typedef to allow abbreviations in specifications when accessing
-    /// context.  The ElementCollection is the name/value collection for
-    /// a particular context.  The "int" corresponds to the index of an
-    /// associated library - there is a 1:1 correspondence between libraries
-    /// and a name.value collection.
-    ///
-    /// The collection of contexts is stored in a map, as not every library
-    /// will require creation of a context associated with each packet.  In
-    /// addition, the structure is more flexible in that the size does not
-    /// need to be set when the CalloutHandle is constructed.
-    typedef std::map<int, ElementCollection> ContextCollection;
-
-
-    /// @brief Constructor
-    ///
-    /// Creates the object and calls the callouts on the "context_create"
-    /// hook.
-    ///
-    /// @param manager Pointer to the callout manager object.
-    CalloutHandle(const boost::shared_ptr<CalloutManager>& manager);
-
-    /// @brief Destructor
-    ///
-    /// Calls the context_destroy callback to release any per-packet context.
-    ~CalloutHandle();
-
-    /// @brief Set argument
-    ///
-    /// Sets the value of an argument.  The argument is created if it does not
-    /// already exist.
-    ///
-    /// @param name Name of the argument.
-    /// @param value Value to set.  That can be of any data type.
-    template <typename T>
-    void setArgument(const std::string& name, T value) {
-        arguments_[name] = value;
-    }
-
-    /// @brief Get argument
-    ///
-    /// Gets the value of an argument.
-    ///
-    /// @param name Name of the element in the argument list to get.
-    /// @param value [out] Value to set.  The type of "value" is important:
-    ///        it must match the type of the value set.
-    ///
-    /// @throw NoSuchArgument No argument with the given name is present.
-    /// @throw boost::bad_any_cast An argument with the given name is present,
-    ///        but the data type of the value is not the same as the type of
-    ///        the variable provided to receive the value.
-    template <typename T>
-    void getArgument(const std::string& name, T& value) const {
-        ElementCollection::const_iterator element_ptr = arguments_.find(name);
-        if (element_ptr == arguments_.end()) {
-            isc_throw(NoSuchArgument, "unable to find argument with name " <<
-                      name);
-        }
-
-        value = boost::any_cast<T>(element_ptr->second);
-    }
-    
-    /// @brief Get argument names
-    ///
-    /// Returns a vector holding the names of arguments in the argument
-    /// vector.
-    ///
-    /// @return Vector of strings reflecting argument names.
-    std::vector<std::string> getArgumentNames() const;
-
-    /// @brief Delete argument
-    ///
-    /// Deletes an argument of the given name.  If an argument of that name
-    /// does not exist, the method is a no-op.
-    ///
-    /// N.B. If the element is a raw pointer, the pointed-to data is NOT deleted
-    /// by this method.
-    ///
-    /// @param name Name of the element in the argument list to set.
-    void deleteArgument(const std::string& name) {
-        static_cast<void>(arguments_.erase(name));
-    }
-
-    /// @brief Delete all arguments
-    ///
-    /// Deletes all arguments associated with this context.
-    ///
-    /// N.B. If any elements are raw pointers, the pointed-to data is NOT
-    /// deleted by this method.
-    void deleteAllArguments() {
-        arguments_.clear();
-    }
-
-    /// @brief Set skip flag
-    ///
-    /// Sets the "skip" variable in the callout handle.  This variable is
-    /// interrogated by the server to see if the remaining callouts associated
-    /// with the current hook should be bypassed.
-    ///
-    /// @param skip New value of the "skip" flag.
-    void setSkip(bool skip) {
-        skip_ = skip;
-    }
-
-    /// @brief Get skip flag
-    ///
-    /// Gets the current value of the "skip" flag.
-    ///
-    /// @return Current value of the skip flag.
-    bool getSkip() const {
-        return (skip_);
-    }
-
-    /// @brief Access current library handle
-    ///
-    /// Returns a reference to the current library handle.  This function is
-    /// only available when called by a callout (which in turn is called
-    /// through the "callCallouts" method), as it is only then that the current
-    /// library index is valid.  A callout uses the library handle to
-    /// dynamically register or deregister callouts.
-    ///
-    /// @return Reference to the library handle.
-    ///
-    /// @throw InvalidIndex thrown if this method is called when the current
-    ///        library index is invalid (typically if it is called outside of
-    ///        the active callout).
-    LibraryHandle& getLibraryHandle() const;
-
-    /// @brief Set context
-    ///
-    /// Sets an element in the context associated with the current library.  If
-    /// an element of the name is already present, it is replaced.
-    ///
-    /// @param name Name of the element in the context to set.
-    /// @param value Value to set.
-    template <typename T>
-    void setContext(const std::string& name, T value) {
-        getContextForLibrary()[name] = value;
-    }
-
-    /// @brief Get context
-    ///
-    /// Gets an element from the context associated with the current library.
-    ///
-    /// @param name Name of the element in the context to get.
-    /// @param value [out] Value to set.  The type of "value" is important:
-    ///        it must match the type of the value set.
-    ///
-    /// @throw NoSuchCalloutContext Thrown if no context element with the name
-    ///        "name" is present.
-    /// @throw boost::bad_any_cast Thrown if the context element is present
-    ///        but the type of the data is not the same as the type of the
-    ///        variable provided to receive its value.
-    template <typename T>
-    void getContext(const std::string& name, T& value) const {
-        const ElementCollection& lib_context = getContextForLibrary();
-
-        ElementCollection::const_iterator element_ptr = lib_context.find(name);
-        if (element_ptr == lib_context.end()) {
-            isc_throw(NoSuchCalloutContext, "unable to find callout context "
-                      "item " << name << " in the context associated with "
-                      "current library");
-        }
-
-        value = boost::any_cast<T>(element_ptr->second);
-    }
-    
-    /// @brief Get context names
-    ///
-    /// Returns a vector holding the names of items in the context associated
-    /// with the current library.
-    ///
-    /// @return Vector of strings reflecting the names of items in the callout
-    ///         context associated with the current library.
-    std::vector<std::string> getContextNames() const;
-
-    /// @brief Delete context element
-    ///
-    /// Deletes an item of the given name from the context associated with the
-    /// current library.  If an item  of that name does not exist, the method is
-    /// a no-op.
-    ///
-    /// N.B. If the element is a raw pointer, the pointed-to data is NOT deleted
-    /// by this.
-    ///
-    /// @param name Name of the context item to delete.
-    void deleteContext(const std::string& name) {
-        static_cast<void>(getContextForLibrary().erase(name));
-    }
-
-    /// @brief Delete all context items
-    ///
-    /// Deletes all items from the context associated with the current library.
-    ///
-    /// N.B. If any elements are raw pointers, the pointed-to data is NOT
-    /// deleted by this.
-    void deleteAllContext() {
-        getContextForLibrary().clear();
-    }
-
-
-private:
-    /// @brief Check index
-    ///
-    /// Gets the current library index, throwing an exception if it is not set
-    /// or is invalid for the current library collection.
-    ///
-    /// @return Current library index, valid for this library collection.
-    ///
-    /// @throw InvalidIndex current library index is not valid for the library
-    ///        handle collection.
-    int getLibraryIndex() const;
-
-    /// @brief Return reference to context for current library
-    ///
-    /// Called by all context-setting functions, this returns a reference to
-    /// the callout context for the current library, creating a context if it
-    /// does not exist.
-    ///
-    /// @return Reference to the collection of name/value pairs associated
-    ///         with the current library.
-    ///
-    /// @throw InvalidIndex current library index is not valid for the library
-    ///        handle collection.
-    ElementCollection& getContextForLibrary();
-
-    /// @brief Return reference to context for current library (const version)
-    ///
-    /// Called by all context-accessing functions, this a reference to the
-    /// callout context for the current library.  An exception is thrown if
-    /// it does not exist.
-    ///
-    /// @return Reference to the collection of name/value pairs associated
-    ///         with the current library.
-    ///
-    /// @throw NoSuchCalloutContext Thrown if there is no ElementCollection
-    ///        associated with the current library.
-    const ElementCollection& getContextForLibrary() const;
-
-    // Member variables
-
-    /// Collection of arguments passed to the callouts
-    ElementCollection arguments_;
-
-    /// Context collection - there is one entry per library context.
-    ContextCollection context_collection_;
-
-    /// Callout manager.
-    boost::shared_ptr<CalloutManager> manager_;
-
-    /// "Skip" flag, indicating if the caller should bypass remaining callouts.
-    bool skip_;
-};
-
-} // namespace util
-} // namespace isc
-
-
-#endif // CALLOUT_HANDLE_H
diff --git a/src/lib/util/hooks/callout_manager.cc b/src/lib/util/hooks/callout_manager.cc
deleted file mode 100644
index af20619..0000000
--- a/src/lib/util/hooks/callout_manager.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (C) 2013  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 <util/hooks/callout_handle.h>
-#include <util/hooks/callout_manager.h>
-
-#include <boost/static_assert.hpp>
-
-#include <algorithm>
-#include <functional>
-#include <utility>
-
-using namespace std;
-using namespace isc::util;
-
-namespace isc {
-namespace util {
-
-// Register a callout for the current library.
-
-void
-CalloutManager::registerCallout(const std::string& name, CalloutPtr callout) {
-    // Sanity check that the current library index is set to a valid value.
-    checkLibraryIndex(current_library_);
-
-    // Get the index associated with this hook (validating the name in the
-    // process).
-    int hook_index = hooks_->getIndex(name);
-
-    // Iterate through the callout vector for the hook from start to end,
-    // looking for the first entry where the library index is greater than
-    // the present index.
-    for (CalloutVector::iterator i = hook_vector_[hook_index].begin();
-         i != hook_vector_[hook_index].end(); ++i) {
-        if (i->first > current_library_) {
-            // Found an element whose library index number is greater than the
-            // current index, so insert the new element ahead of this one.
-            hook_vector_[hook_index].insert(i, make_pair(current_library_,
-                                                         callout));
-            return;
-        }
-    }
-
-    // Reached the end of the vector, so there is no element in the (possibly
-    // empty) set of callouts with a library index greater than the current
-    // library index.  Inset the callout at the end of the list.
-    hook_vector_[hook_index].push_back(make_pair(current_library_, callout));
-}
-
-// Check if callouts are present for a given hook index.
-
-bool
-CalloutManager::calloutsPresent(int hook_index) const {
-    // Validate the hook index.
-    if ((hook_index < 0) || (hook_index >= hook_vector_.size())) {
-        isc_throw(NoSuchHook, "hook index " << hook_index <<
-                  " is not valid for the list of registered hooks");
-    }
-
-    // Valid, so are there any callouts associated with that hook?
-    return (!hook_vector_[hook_index].empty());
-}
-
-// Call all the callouts for a given hook.
-
-void
-CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
-
-    // Only initialize and iterate if there are callouts present.  This check
-    // also catches the case of an invalid index.
-    if (calloutsPresent(hook_index)) {
-
-        // Clear the "skip" flag so we don't carry state from a previous call.
-        callout_handle.setSkip(false);
-
-        // Duplicate the callout vector for this hook and work through that.
-        // This step is needed because we allow dynamic registration and
-        // deregistration of callouts.  If a callout attached to a hook modified
-        // the list of callouts on that hook, the underlying CalloutVector would
-        // change and potentially affect the iteration through that vector.
-        CalloutVector callouts(hook_vector_[hook_index]);
-
-        // Call all the callouts.
-        for (CalloutVector::const_iterator i = callouts.begin();
-             i != callouts.end(); ++i) {
-            // In case the callout tries to register or deregister a callout,
-            // set the current library index to the index associated with the
-            // library that registered the callout being called.
-            current_library_ = i->first;
-
-            // Call the callout
-            // @todo Log the return status if non-zero
-            static_cast<void>((*i->second)(callout_handle));
-        }
-
-        // Reset the current library index to an invalid value to catch any
-        // programming errors.
-        current_library_ = -1;
-    }
-}
-
-// Deregister a callout registered by the current library on a particular hook.
-
-bool
-CalloutManager::deregisterCallout(const std::string& name, CalloutPtr callout) {
-    // Sanity check that the current library index is set to a valid value.
-    checkLibraryIndex(current_library_);
-
-    // Get the index associated with this hook (validating the name in the
-    // process).
-    int hook_index = hooks_->getIndex(name);
-
-    /// Construct a CalloutEntry matching the current library and the callout
-    /// we want to remove.
-    CalloutEntry target(current_library_, callout);
-
-    /// To decide if any entries were removed, we'll record the initial size
-    /// of the callout vector for the hook, and compare it with the size after
-    /// the removal.
-    size_t initial_size = hook_vector_[hook_index].size();
-
-    // The next bit is standard STL (see "Item 33" in "Effective STL" by
-    // Scott Meyers).
-    //
-    // remove_if reorders the hook vector so that all items not matching
-    // the predicate are at the start of the vector and returns a pointer
-    // to the next element. (In this case, the predicate is that the item
-    // is equal to the value of the passed callout.)  The erase() call
-    // removes everything from that element to the end of the vector, i.e.
-    // all the matching elements.
-    hook_vector_[hook_index].erase(remove_if(hook_vector_[hook_index].begin(),
-                                             hook_vector_[hook_index].end(),
-                                             bind1st(equal_to<CalloutEntry>(),
-                                                     target)),
-                                   hook_vector_[hook_index].end());
-
-    // Return an indication of whether anything was removed.
-    return (initial_size != hook_vector_[hook_index].size());
-}
-
-// Deregister all callouts on a given hook.
-
-bool
-CalloutManager::deregisterAllCallouts(const std::string& name) {
-
-    // Get the index associated with this hook (validating the name in the
-    // process).
-    int hook_index = hooks_->getIndex(name);
-
-    /// Construct a CalloutEntry matching the current library (the callout
-    /// pointer is NULL as we are not checking that).
-    CalloutEntry target(current_library_, NULL);
-
-    /// To decide if any entries were removed, we'll record the initial size
-    /// of the callout vector for the hook, and compare it with the size after
-    /// the removal.
-    size_t initial_size = hook_vector_[hook_index].size();
-
-    // Remove all callouts matching this library.
-    hook_vector_[hook_index].erase(remove_if(hook_vector_[hook_index].begin(),
-                                             hook_vector_[hook_index].end(),
-                                             bind1st(CalloutLibraryEqual(),
-                                                     target)),
-                                   hook_vector_[hook_index].end());
-
-    // Return an indication of whether anything was removed.
-    return (initial_size != hook_vector_[hook_index].size());
-}
-
-} // namespace util
-} // namespace isc
diff --git a/src/lib/util/hooks/callout_manager.h b/src/lib/util/hooks/callout_manager.h
deleted file mode 100644
index 7a22433..0000000
--- a/src/lib/util/hooks/callout_manager.h
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright (C) 2013  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 CALLOUT_MANAGER_H
-#define CALLOUT_MANAGER_H
-
-#include <exceptions/exceptions.h>
-#include <util/hooks/library_handle.h>
-#include <util/hooks/server_hooks.h>
-
-#include <boost/shared_ptr.hpp>
-
-#include <map>
-#include <string>
-
-namespace isc {
-namespace util {
-
-/// @brief No such library
-///
-/// Thrown if an attempt is made to set the current library index to a value
-/// that is invalid for the number of loaded libraries.
-class NoSuchLibrary : public Exception {
-public:
-    NoSuchLibrary(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-
-/// @brief Callout Manager
-///
-/// This class manages the registration, deregistration and execution of the
-/// library callouts.
-///
-/// In operation, the class needs to know two items of data:
-///
-/// - The list of server hooks, which is used in two ways.  Firstly, when a
-///   callout registers or deregisters a hook, it does so by name: the
-///   @ref isc::util::ServerHooks object supplies the names of registered
-///   hooks.  Secondly, when the callouts associated with a hook are called by
-///   the server, the server supplies the index of the relevant hook: this is
-///   validated by reference to the list of hook.
-///
-/// - The number of loaded libraries.  Each callout registered by a user
-///   library is associated with that library, the callout manager storing both
-///   a pointer to the callout and the index of the library in the list of
-///   loaded libraries.  Callouts are allowed to dynamically register and
-///   deregister callouts in the same library (including themselves): they
-///   cannot affect callouts registered by another library.  When calling a
-///   callout, the callout manager maintains the idea of a "current library
-///   index": if the callout calls one of the callout registration functions 
-///   (indirectly via the @ref LibraryHandle object), the registration
-///   functions use the "current library index" in their processing.
-///
-/// These two items of data are supplied when an object of this class is
-/// constructed.
-///
-/// Note that the callout function do not access the library manager: instead,
-/// they use a LibraryHandle object.  This contains an internal pointer to
-/// the CalloutManager, but provides a restricted interface.  In that way,
-/// callouts are unable to affect callouts supplied by other libraries.
-
-class CalloutManager {
-private:
-
-    // Private typedefs
-
-    /// Element in the vector of callouts.  The elements in the pair are the
-    /// index of the library from which this callout was registered, and a#
-    /// pointer to the callout itself.
-    typedef std::pair<int, CalloutPtr> CalloutEntry;
-
-    /// An element in the hook vector. Each element is a vector of callouts
-    /// associated with a given hook.
-    typedef std::vector<CalloutEntry> CalloutVector;
-
-public:
-
-    /// @brief Constructor
-    ///
-    /// Initializes member variables, in particular sizing the hook vector
-    /// (the vector of callout vectors) to the appropriate size.
-    ///
-    /// @param hooks Collection of known hook names.
-    /// @param num_libraries Number of loaded libraries.
-    ///
-    /// @throw isc::BadValue if the number of libraries is less than or equal
-    ///        to 0, or if the pointer to the server hooks object is empty.
-    CalloutManager(const boost::shared_ptr<ServerHooks>& hooks,
-                   int num_libraries)
-        : current_library_(-1), hooks_(hooks), hook_vector_(),
-          library_handle_(this), num_libraries_(num_libraries)
-    {
-        if (!hooks) {
-            isc_throw(isc::BadValue, "must pass a pointer to a valid server "
-                      "hooks object to the CalloutManager");
-        } else if (num_libraries <= 0) {
-            isc_throw(isc::BadValue, "number of libraries passed to the "
-                      "CalloutManager must be >= 0");
-        }
-
-        // Parameters OK, do operations that depend on them.
-        hook_vector_.resize(hooks_->getCount());
-    }
-
-    /// @brief Register a callout on a hook for the current library
-    ///
-    /// Registers a callout function for the current library with a given hook
-    /// (the index of the "current library" being given by the current_library_
-    /// member).  The callout is added to the end of the callouts for this
-    /// library that are associated with that hook.
-    ///
-    /// @param name Name of the hook to which the callout is added.
-    /// @param callout Pointer to the callout function to be registered.
-    ///
-    /// @throw NoSuchHook The hook name is unrecognised.
-    /// @throw Unexpected The hook name is valid but an internal data structure
-    ///        is of the wrong size.
-    void registerCallout(const std::string& name, CalloutPtr callout);
-
-    /// @brief De-Register a callout on a hook for the current library
-    ///
-    /// Searches through the functions registered by the the current library
-    /// (the index of the "current library" being given by the current_library_
-    /// member) with the named hook and removes all entries matching the
-    /// callout.
-    ///
-    /// @param name Name of the hook from which the callout is removed.
-    /// @param callout Pointer to the callout function to be removed.
-    ///
-    /// @return true if a one or more callouts were deregistered.
-    ///
-    /// @throw NoSuchHook The hook name is unrecognised.
-    /// @throw Unexpected The hook name is valid but an internal data structure
-    ///        is of the wrong size.
-    bool deregisterCallout(const std::string& name, CalloutPtr callout);
-
-    /// @brief Removes all callouts on a hook for the current library
-    ///
-    /// Removes all callouts associated with a given hook that were registered
-    /// by the current library (the index of the "current library" being given
-    /// by the current_library_ member).
-    ///
-    /// @param name Name of the hook from which the callouts are removed.
-    ///
-    /// @return true if one or more callouts were deregistered.
-    ///
-    /// @throw NoSuchHook Thrown if the hook name is unrecognised.
-    bool deregisterAllCallouts(const std::string& name);
-
-    /// @brief Checks if callouts are present on a hook
-    ///
-    /// Checks all loaded libraries and returns true if at least one callout
-    /// has been registered by any of them for the given hook.
-    ///
-    /// @param hook_index Hook index for which callouts are checked.
-    ///
-    /// @return true if callouts are present, false if not.
-    ///
-    /// @throw NoSuchHook Given index does not correspond to a valid hook.
-    bool calloutsPresent(int hook_index) const;
-
-    /// @brief Calls the callouts for a given hook
-    ///
-    /// Iterates through the libray handles and calls the callouts associated
-    /// with the given hook index.
-    ///
-    /// @note This method invalidates the current library index set with
-    ///       setLibraryIndex().
-    ///
-    /// @param hook_index Index of the hook to call.
-    /// @param callout_handle Reference to the CalloutHandle object for the
-    ///        current object being processed.
-    void callCallouts(int hook_index, CalloutHandle& callout_handle);
-
-    /// @brief Get number of libraries
-    ///
-    /// Returns the number of libraries that this CalloutManager is expected
-    /// to serve.  This is the number passed to its constructor.
-    ///
-    /// @return Number of libraries server by this CalloutManager.
-    int getNumLibraries() const {
-        return (num_libraries_);
-    }
-
-    /// @brief Get current library index
-    ///
-    /// Returns the index of the "current" library.  This the index associated
-    /// with the currently executing callout when callCallouts is executing.
-    /// When callCallouts() is not executing (as is the case when the load()
-    /// function in a user-library is called during the library load process),
-    /// the index can be set by setLibraryIndex().
-    ///
-    /// @note The value set by this method is lost after a call to
-    ///       callCallouts.
-    ///
-    /// @return Current library index.
-    int getLibraryIndex() const {
-        return (current_library_);
-    }
-
-    /// @brief Set current library index
-    ///
-    /// Sets the current library index.  This must be in the range 0 to
-    /// (numlib - 1), where "numlib" is the number of libraries loaded in the
-    /// system, this figure being passed to this object at construction time.
-    ///
-    /// @param library_index New library index.
-    ///
-    /// @throw NoSuchLibrary if the index is not valid.
-    void setLibraryIndex(int library_index) {
-        checkLibraryIndex(library_index);
-        current_library_ = library_index;
-    }
-
-    /// @brief Return library handle
-    ///
-    /// The library handle is available to the user callout via the callout
-    /// handle object.  It provides a cut-down view of the CalloutManager,
-    /// allowing the callout to register and deregister callouts in the
-    /// library of which it is part, whilst denying access to anything that
-    /// may affect other libraries.
-    ///
-    /// @return Reference to callout handle for this manager
-    LibraryHandle& getLibraryHandle() {
-        return (library_handle_);
-    }
-
-private:
-    /// @brief Check library index
-    ///
-    /// Ensures that the current library index is valid.  This is called by
-    /// the hook registration functions.
-    ///
-    /// @param library_index Value to check for validity as a library index.
-    ///
-    /// @throw NoSuchLibrary Library index is not valid.
-    void checkLibraryIndex(int library_index) const {
-        if ((library_index < 0) || (library_index >= num_libraries_)) {
-            isc_throw(NoSuchLibrary, "library index " << library_index <<
-                      " is not valid for the number of loaded libraries (" <<
-                      num_libraries_ << ")");
-        }
-    }
-
-    /// @brief Compare two callout entries for library equality
-    ///
-    /// This is used in callout removal code when all callouts on a hook for a
-    /// given library are being removed.  It checks whether two callout entries
-    /// have the same library index.
-    ///
-    /// @param ent1 First callout entry to check
-    /// @param ent2 Second callout entry to check
-    ///
-    /// @return bool true if the library entries are the same
-    class CalloutLibraryEqual :
-        public std::binary_function<CalloutEntry, CalloutEntry, bool> {
-    public:
-        bool operator()(const CalloutEntry& ent1,
-                        const CalloutEntry& ent2) const {
-            return (ent1.first == ent2.first);
-        }
-    };
-
-    /// Current library index.  When a call is made to any of the callout
-    /// registration methods, this variable indicates the index of the user
-    /// library that should be associated with the call.
-    int current_library_;
-
-    /// List of server hooks.
-    boost::shared_ptr<ServerHooks>  hooks_;
-
-    /// Vector of callout vectors.  There is one entry in this outer vector for
-    /// each hook. Each element is itself a vector, with one entry for each
-    /// callout registered for that hook.
-    std::vector<CalloutVector>  hook_vector_;
-
-    /// LibraryHandle object user by the callout to access the callout
-    /// registration methods on this CalloutManager object.
-    LibraryHandle library_handle_;
-
-    /// Number of libraries.
-    int num_libraries_;
-
-};
-
-} // namespace util
-} // namespace isc
-
-#endif // CALLOUT_MANAGER_H
diff --git a/src/lib/util/hooks/library_handle.cc b/src/lib/util/hooks/library_handle.cc
deleted file mode 100644
index 0a65e54..0000000
--- a/src/lib/util/hooks/library_handle.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2013  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 <util/hooks/callout_manager.h>
-#include <util/hooks/library_handle.h>
-
-namespace isc {
-namespace util {
-
-// Callout manipulation - all deferred to the CalloutManager.
-
-void
-LibraryHandle::registerCallout(const std::string& name, CalloutPtr callout) {
-    callout_manager_->registerCallout(name, callout);
-}
-
-bool
-LibraryHandle::deregisterCallout(const std::string& name, CalloutPtr callout) {
-    return (callout_manager_->deregisterCallout(name, callout));
-}
-
-bool
-LibraryHandle::deregisterAllCallouts(const std::string& name) {
-    return (callout_manager_->deregisterAllCallouts(name));
-}
-
-} // namespace util
-} // namespace isc
diff --git a/src/lib/util/hooks/library_handle.h b/src/lib/util/hooks/library_handle.h
deleted file mode 100644
index 43a78a1..0000000
--- a/src/lib/util/hooks/library_handle.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (C) 2013  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 LIBRARY_HANDLE_H
-#define LIBRARY_HANDLE_H
-
-#include <string>
-
-namespace isc {
-namespace util {
-
-// Forward declarations
-class CalloutHandle;
-class CalloutManager;
-
-/// Typedef for a callout pointer.  (Callouts must have "C" linkage.)
-extern "C" {
-    typedef int (*CalloutPtr)(CalloutHandle&);
-};
-
-/// @brief Library handle
-///
-/// This class is accessed by the user library when registering callouts,
-/// either by the library's load() function, or by one of the callouts
-/// themselves.
-///
-/// It is really little more than a shell around the CalloutManager.  By
-/// presenting this object to the user-library callouts, callouts can manage
-/// the callout list for their own library, but cannot affect the callouts
-/// registered by other libraries.
-///
-/// (This restriction is achieved by the CalloutManager maintaining the concept
-/// of the "current library".  When a callout is registered - either by the
-/// library's load() function, or by a callout in the library - the registration
-/// information includes the library active at the time.  When that callout is
-/// called, the CalloutManager uses that information to set the "current
-/// library": the registration functions only operator on data whose
-/// associated library is equal to the "current library".)
-
-class LibraryHandle {
-public:
-
-    /// @brief Constructor
-    ///
-    /// @param manager Back pointer to the containing CalloutManager.
-    ///        This pointer is used to access appropriate methods in that
-    ///        object.  Note that the "raw" pointer is safe - the only
-    ///        instance of the LibraryHandle in the system is as a member of
-    ///        the CalloutManager to which it points.
-    LibraryHandle(CalloutManager* manager) : callout_manager_(manager)
-    {}
-
-    /// @brief Register a callout on a hook
-    ///
-    /// Registers a callout function with a given hook.  The callout is added
-    /// to the end of the callouts for the current library that are associated
-    /// with that hook.
-    ///
-    /// @param name Name of the hook to which the callout is added.
-    /// @param callout Pointer to the callout function to be registered.
-    ///
-    /// @throw NoSuchHook The hook name is unrecognised.
-    /// @throw Unexpected The hook name is valid but an internal data structure
-    ///        is of the wrong size.
-    void registerCallout(const std::string& name, CalloutPtr callout);
-
-    /// @brief De-Register a callout on a hook
-    ///
-    /// Searches through the functions registered by the current library with
-    /// the named hook and removes all entries matching the callout.  It does
-    /// not affect callouts registered by other libraries.
-    ///
-    /// @param name Name of the hook from which the callout is removed.
-    /// @param callout Pointer to the callout function to be removed.
-    ///
-    /// @return true if a one or more callouts were deregistered.
-    ///
-    /// @throw NoSuchHook The hook name is unrecognised.
-    /// @throw Unexpected The hook name is valid but an internal data structure
-    ///        is of the wrong size.
-    bool deregisterCallout(const std::string& name, CalloutPtr callout);
-
-    /// @brief Removes all callouts on a hook
-    ///
-    /// Removes all callouts associated with a given hook that were registered.
-    /// by the current library.  It does not affect callouts that were
-    /// registered by other libraries.
-    ///
-    /// @param name Name of the hook from which the callouts are removed.
-    ///
-    /// @return true if one or more callouts were deregistered.
-    ///
-    /// @throw NoSuchHook Thrown if the hook name is unrecognised.
-    bool deregisterAllCallouts(const std::string& name);
-
-private:
-    /// Back pointer to the collection object for the library
-    CalloutManager* callout_manager_;
-};
-
-} // namespace util
-} // namespace isc
-
-#endif // LIBRARY_HANDLE_H
diff --git a/src/lib/util/hooks/server_hooks.cc b/src/lib/util/hooks/server_hooks.cc
deleted file mode 100644
index 478d94c..0000000
--- a/src/lib/util/hooks/server_hooks.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (C) 2013  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 <exceptions/exceptions.h>
-#include <util/hooks/server_hooks.h>
-
-#include <utility>
-#include <vector>
-
-using namespace std;
-using namespace isc;
-
-namespace isc {
-namespace util {
-
-// Constructor - register the pre-defined hooks and check that the indexes
-// assigned to them are as expected.
-
-ServerHooks::ServerHooks() {
-    int create = registerHook("context_create");
-    int destroy = registerHook("context_destroy");
-
-    if ((create != CONTEXT_CREATE) || (destroy != CONTEXT_DESTROY)) {
-        isc_throw(Unexpected, "pre-defined hook indexes are not as expected. "
-                  "context_create: expected = " << CONTEXT_CREATE <<
-                  ", actual = " << create <<
-                  ". context_destroy: expected = " << CONTEXT_DESTROY <<
-                  ", actual = " << destroy);
-    }
-}
-
-// Register a hook.  The index assigned to the hook is the current number
-// of entries in the collection, so ensuring that hook indexes are unique
-// and non-negative.
-
-int
-ServerHooks::registerHook(const string& name) {
-
-    // Determine index for the new element and insert.
-    int index = hooks_.size();
-    pair<HookCollection::iterator, bool> result =
-        hooks_.insert(make_pair(name, index));
-
-    if (!result.second) {
-        // New element was not inserted because an element with the same name
-        // already existed.
-        isc_throw(DuplicateHook, "hook with name " << name <<
-                  " is already registered");
-    }
-
-    // New element inserted, return numeric index.
-    return (index);
-}
-
-// Find the index associated with a hook name.
-
-int
-ServerHooks::getIndex(const string& name) const {
-
-    // Get iterator to matching element.
-    HookCollection::const_iterator i = hooks_.find(name);
-    if (i == hooks_.end()) {
-        isc_throw(NoSuchHook, "hook name " << name << " is not recognised");
-    }
-
-    return (i->second);
-}
-
-// Return vector of hook names.  The names are not sorted - it is up to the
-// caller to perform sorting if required.
-
-vector<string>
-ServerHooks::getHookNames() const {
-
-    vector<string> names;
-    HookCollection::const_iterator i;
-    for (i = hooks_.begin(); i != hooks_.end(); ++i) {
-        names.push_back(i->first);
-    }
-
-    return (names);
-}
-
-// Hook registration function methods
-
-// Access the hook registration function vector itself
-
-std::vector<HookRegistrationFunction::RegistrationFunctionPtr>&
-HookRegistrationFunction::getFunctionVector() {
-    static std::vector<RegistrationFunctionPtr> reg_functions;
-    return (reg_functions);
-}
-
-// Constructor - add a registration function to the function vector
-
-HookRegistrationFunction::HookRegistrationFunction(
-    HookRegistrationFunction::RegistrationFunctionPtr reg_func) {
-    getFunctionVector().push_back(reg_func);
-}
-
-// Execute all registered registration functions
-
-void
-HookRegistrationFunction::execute(ServerHooks& hooks) {
-    std::vector<RegistrationFunctionPtr>& reg_functions = getFunctionVector();
-    for (int i = 0; i < reg_functions.size(); ++i) {
-        (*reg_functions[i])(hooks);
-    }
-}
-
-
-
-} // namespace util
-} // namespace isc
diff --git a/src/lib/util/hooks/server_hooks.h b/src/lib/util/hooks/server_hooks.h
deleted file mode 100644
index ce41fa0..0000000
--- a/src/lib/util/hooks/server_hooks.h
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (C) 2013  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 SERVER_HOOKS_H
-#define SERVER_HOOKS_H
-
-#include <exceptions/exceptions.h>
-
-#include <map>
-#include <string>
-#include <vector>
-
-namespace isc {
-namespace util {
-
-/// @brief Duplicate hook
-///
-/// Thrown if an attempt is made to register a hook with the same name as a
-/// previously-registered hook.
-class DuplicateHook : public Exception {
-public:
-    DuplicateHook(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-/// @brief Invalid hook
-///
-/// Thrown if an attempt is made to get the index for an invalid hook.
-class NoSuchHook : public Exception {
-public:
-    NoSuchHook(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-
-/// @brief Server hook collection
-///
-/// This class is used by the server-side code to register hooks - points in the
-/// server processing at which libraries can register functions (callouts) that
-/// the server will call.  These functions can modify data and so affect the
-/// processing of the server.
-///
-/// The ServerHooks class is little more than a wrapper around the std::map
-/// class.  It stores a hook, assigning to it a unique index number.  This
-/// number is then used by the server code to identify the hook being called.
-/// (Although it would be feasible to use a name as an index, using an integer
-/// will speed up the time taken to locate the callouts, which may make a
-/// difference in a frequently-executed piece of code.)
-
-class ServerHooks {
-public:
-
-    /// Index numbers for pre-defined hooks.
-    static const int CONTEXT_CREATE = 0;
-    static const int CONTEXT_DESTROY = 1;
-
-    /// @brief Constructor
-    ///
-    /// This pre-registers two hooks, context_create and context_destroy, which
-    /// are called by the server before processing a packet and after processing
-    /// for the packet has completed.  They allow the server code to allocate
-    /// and destroy per-packet context.
-    ///
-    /// @throws isc::Unexpected if the registration of the pre-defined hooks
-    ///         fails in some way.
-    ServerHooks();
-
-    /// @brief Register a hook
-    ///
-    /// Registers a hook and returns the hook index.
-    ///
-    /// @param name Name of the hook
-    ///
-    /// @return Index of the hook, to be used in subsequent hook-related calls.
-    ///         This will be greater than or equal to zero (so allowing a
-    ///         negative value to indicate an invalid index).
-    ///
-    /// @throws DuplicateHook A hook with the same name has already been
-    ///         registered.
-    int registerHook(const std::string& name);
-
-    /// @brief Get hook index
-    ///
-    /// Returns the index of a hook.
-    ///
-    /// @param name Name of the hook
-    ///
-    /// @return Index of the hook, to be used in subsequent calls.
-    ///
-    /// @throw NoSuchHook if the hook name is unknown to the caller.
-    int getIndex(const std::string& name) const;
-
-    /// @brief Return number of hooks
-    ///
-    /// Returns the total number of hooks registered.
-    ///
-    /// @return Number of hooks registered.
-    int getCount() const {
-        return (hooks_.size());
-    }
-
-    /// @brief Get hook names
-    ///
-    /// Return list of hooks registered in the object.
-    ///
-    /// @return Vector of strings holding hook names.
-    std::vector<std::string> getHookNames() const;
-
-private:
-    typedef std::map<std::string, int> HookCollection;
-
-    HookCollection  hooks_;     ///< Hook name/index collection
-};
-
-
-/// @brief Hooks Registration
-///
-/// All hooks must be registered before libraries are loaded and callouts
-/// assigned to them.  One way of doing this is to have a global list of hooks:
-/// the addition of any hook anywhere would require updating the list. This
-/// is possible and, if desired, the author of a server can do it.
-///
-/// An alternative is the option provided here, where each component of BIND 10
-/// registers the hooks they are using.  To do this, the component should
-/// create a hook registration function of the form:
-///
-/// @code
-/// static int hook1_num = -1;  // Initialize number for hook 1
-/// static int hook2_num = -1;  // Initialize number for hook 2
-///
-/// void myModuleRegisterHooks(ServerHooks& hooks) {
-///     hook1_num = hooks.registerHook("hook1");
-///     hook2_num = hooks.registerHook("hook2");
-/// }
-/// @endcode
-///
-/// ... which registers the hooks and stores the associated hook index. To
-/// avoid the need to add an explicit call to each of the hook registration
-/// functions to the server initialization code, the component should declare
-/// an object of this class in the same file as the registration function,
-/// but outside of any function.  The declaration should include the name
-/// of the registration function, i.e.
-///
-/// @code
-/// HookRegistrationFunction f(myModuleRegisterHooks);
-/// @code
-///
-/// The constructor of this object will run prior to main() getting called and
-/// will add the registration function to a list of such functions.  The server
-/// then calls the static class method "execute()" to run all the declared
-/// registration functions.
-
-class HookRegistrationFunction {
-public:
-    /// @brief Pointer to a hook registration function
-    typedef void (*RegistrationFunctionPtr)(ServerHooks&);
-
-    /// @brief Constructor
-    ///
-    /// For variables declared outside functions or methods, the constructors
-    /// are run after the program is loaded and before main() is called. This
-    /// constructor adds the passed pointer to a vector of such pointers.
-    HookRegistrationFunction(RegistrationFunctionPtr reg_func);
-
-    /// @brief Access registration function vector
-    ///
-    /// One of the problems with functions run prior to starting main() is the
-    /// "static initialization fiasco".  This occurs because the order in which
-    /// objects outside functions are constructed is not defined.  So if this
-    /// constructor were to depend on a vector declared externally, we would
-    /// not be able to guarantee that the vector had been initialised properly
-    /// before we used it.
-    ///
-    /// To get round this situation, the vector is declared statically within
-    /// a static function.  The first time the function is called, the vector
-    /// is initialized before it is used.
-    ///
-    /// This function returns a reference to the vector used to hold the
-    /// pointers.
-    ///
-    /// @return Reference to the (static) list of registration functions
-    static std::vector<RegistrationFunctionPtr>& getFunctionVector();
-
-    /// @brief Execute registration functions
-    ///
-    /// Called by the server initialization code, this function executes all
-    /// registered hook registration functions.
-    ///
-    /// @param hooks ServerHooks object to which hook information will be added.
-    static void execute(ServerHooks& hooks);
-};
-
-} // namespace util
-} // namespace isc
-
-#endif  // SERVER_HOOKS_H
diff --git a/src/lib/util/tests/Makefile.am b/src/lib/util/tests/Makefile.am
index ceb8b95..ab85fa2 100644
--- a/src/lib/util/tests/Makefile.am
+++ b/src/lib/util/tests/Makefile.am
@@ -25,13 +25,10 @@ run_unittests_SOURCES  = run_unittests.cc
 run_unittests_SOURCES += base32hex_unittest.cc
 run_unittests_SOURCES += base64_unittest.cc
 run_unittests_SOURCES += buffer_unittest.cc
-run_unittests_SOURCES += callout_handle_unittest.cc
-run_unittests_SOURCES += callout_manager_unittest.cc
 run_unittests_SOURCES += fd_share_tests.cc
 run_unittests_SOURCES += fd_tests.cc
 run_unittests_SOURCES += filename_unittest.cc
 run_unittests_SOURCES += hex_unittest.cc
-run_unittests_SOURCES += handles_unittest.cc
 run_unittests_SOURCES += io_utilities_unittest.cc
 run_unittests_SOURCES += lru_list_unittest.cc
 run_unittests_SOURCES += memory_segment_local_unittest.cc
@@ -42,7 +39,6 @@ run_unittests_SOURCES += memory_segment_common_unittest.h
 run_unittests_SOURCES += memory_segment_common_unittest.cc
 run_unittests_SOURCES += qid_gen_unittest.cc
 run_unittests_SOURCES += random_number_generator_unittest.cc
-run_unittests_SOURCES += server_hooks_unittest.cc
 run_unittests_SOURCES += sha1_unittest.cc
 run_unittests_SOURCES += socketsession_unittest.cc
 run_unittests_SOURCES += strutil_unittest.cc
diff --git a/src/lib/util/tests/callout_handle_unittest.cc b/src/lib/util/tests/callout_handle_unittest.cc
deleted file mode 100644
index 76e18d8..0000000
--- a/src/lib/util/tests/callout_handle_unittest.cc
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright (C) 2013  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 <util/hooks/callout_handle.h>
-#include <util/hooks/callout_manager.h>
-#include <util/hooks/library_handle.h>
-#include <util/hooks/server_hooks.h>
-
-#include <boost/shared_ptr.hpp>
-
-#include <gtest/gtest.h>
-
-using namespace isc::util;
-using namespace std;
-
-namespace {
-
-/// @file
-/// @brief Holds the CalloutHandle argument tests
-///
-/// Additional testing of the CalloutHandle - together with the interaction
-/// of the LibraryHandle - is done in the handles_unittests set of tests.
-
-class CalloutHandleTest : public ::testing::Test {
-public:
-
-    /// @brief Constructor
-    ///
-    /// Sets up a callout manager to be referenced by the CalloutHandle in
-    /// these tests. (The "4" for the number of libraries in the
-    /// CalloutManager is arbitrary - it is not used in these tests.)
-    CalloutHandleTest()
-        : hooks_(new ServerHooks()), manager_(new CalloutManager(hooks_, 4))
-    {}
-
-    /// Obtain hook manager
-    boost::shared_ptr<CalloutManager>& getCalloutManager() {
-        return (manager_);
-    }
-
-private:
-    /// List of server hooks
-    boost::shared_ptr<ServerHooks> hooks_;
-
-    /// Callout manager accessed by this CalloutHandle.
-    boost::shared_ptr<CalloutManager> manager_;
-};
-
-// *** Argument Tests ***
-//
-// The first set of tests check that the CalloutHandle can store and retrieve
-// arguments.  These are very similar to the LibraryHandle context tests.
-
-// Test that we can store multiple values of the same type and that they
-// are distinct.
-
-TEST_F(CalloutHandleTest, ArgumentDistinctSimpleType) {
-    CalloutHandle handle(getCalloutManager());
-
-    // Store and retrieve an int (random value).
-    int a = 42;
-    handle.setArgument("integer1", a);
-    EXPECT_EQ(42, a);
-
-    int b = 0;
-    handle.getArgument("integer1", b);
-    EXPECT_EQ(42, b);
-
-    // Add another integer (another random value).
-    int c = 142;
-    handle.setArgument("integer2", c);
-    EXPECT_EQ(142, c);
-
-    int d = 0;
-    handle.getArgument("integer2", d);
-    EXPECT_EQ(142, d);
-
-    // Add a short (random value).
-    short e = -81; 
-    handle.setArgument("short", e);
-    EXPECT_EQ(-81, e);
-
-    short f = 0;
-    handle.getArgument("short", f);
-    EXPECT_EQ(-81, f);
-}
-
-// Test that trying to get an unknown argument throws an exception.
-
-TEST_F(CalloutHandleTest, ArgumentUnknownName) {
-    CalloutHandle handle(getCalloutManager());
-
-    // Set an integer
-    int a = 42;
-    handle.setArgument("integer1", a);
-    EXPECT_EQ(42, a);
-
-    // Check we can retrieve it
-    int b = 0;
-    handle.getArgument("integer1", b);
-    EXPECT_EQ(42, b);
-
-    // Check that getting an unknown name throws an exception.
-    int c = 0;
-    EXPECT_THROW(handle.getArgument("unknown", c), NoSuchArgument);
-}
-
-// Test that trying to get an argument with an incorrect type throws an
-// exception.
-
-TEST_F(CalloutHandleTest, ArgumentIncorrectType) {
-    CalloutHandle handle(getCalloutManager());
-
-    // Set an integer
-    int a = 42;
-    handle.setArgument("integer1", a);
-    EXPECT_EQ(42, a);
-
-    // Check we can retrieve it
-    long b = 0;
-    EXPECT_THROW(handle.getArgument("integer1", b), boost::bad_any_cast);
-}
-
-// Now try with some very complex types.  The types cannot be defined within
-// the function and they should contain a copy constructor.  For this reason,
-// a simple "struct" is used.
-
-struct Alpha {
-    int a;
-    int b;
-    Alpha(int first = 0, int second = 0) : a(first), b(second) {}
-};
-
-struct Beta {
-    int c;
-    int d;
-    Beta(int first = 0, int second = 0) : c(first), d(second) {}
-};
-
-TEST_F(CalloutHandleTest, ComplexTypes) {
-    CalloutHandle handle(getCalloutManager());
-
-    // Declare two variables of different (complex) types. (Note as to the
-    // variable names: aleph and beth are the first two letters of the Hebrew
-    // alphabet.)
-    Alpha aleph(1, 2);
-    EXPECT_EQ(1, aleph.a);
-    EXPECT_EQ(2, aleph.b);
-    handle.setArgument("aleph", aleph);
-
-    Beta beth(11, 22);
-    EXPECT_EQ(11, beth.c);
-    EXPECT_EQ(22, beth.d);
-    handle.setArgument("beth", beth);
-
-    // Ensure we can extract the data correctly.
-    Alpha aleph2;
-    EXPECT_EQ(0, aleph2.a);
-    EXPECT_EQ(0, aleph2.b);
-    handle.getArgument("aleph", aleph2);
-    EXPECT_EQ(1, aleph2.a);
-    EXPECT_EQ(2, aleph2.b);
-
-    Beta beth2;
-    EXPECT_EQ(0, beth2.c);
-    EXPECT_EQ(0, beth2.d);
-    handle.getArgument("beth", beth2);
-    EXPECT_EQ(11, beth2.c);
-    EXPECT_EQ(22, beth2.d);
-
-    // Ensure that complex types also thrown an exception if we attempt to
-    // get a context element of the wrong type.
-    EXPECT_THROW(handle.getArgument("aleph", beth), boost::bad_any_cast);
-}
-
-// Check that the context can store pointers. And also check that it respects
-// that a "pointer to X" is not the same as a "pointer to const X".
-
-TEST_F(CalloutHandleTest, PointerTypes) {
-    CalloutHandle handle(getCalloutManager());
-
-    // Declare a couple of variables, const and non-const.
-    Alpha aleph(5, 10);
-    const Beta beth(15, 20);
-
-    Alpha* pa = ℵ
-    const Beta* pcb = ℶ
-
-    // Check pointers can be set and retrieved OK.
-    handle.setArgument("non_const_pointer", pa);
-    handle.setArgument("const_pointer", pcb);
-
-    Alpha* pa2 = 0;
-    handle.getArgument("non_const_pointer", pa2);
-    EXPECT_TRUE(pa == pa2);
-
-    const Beta* pcb2 = 0;
-    handle.getArgument("const_pointer", pcb2);
-    EXPECT_TRUE(pcb == pcb2);
-
-    // Check that the "const" is protected in the context.
-    const Alpha* pca3;
-    EXPECT_THROW(handle.getArgument("non_const_pointer", pca3),
-                 boost::bad_any_cast);
-
-    Beta* pb3;
-    EXPECT_THROW(handle.getArgument("const_pointer", pb3),
-                 boost::bad_any_cast);
-}
-
-// Check that we can get the names of the arguments.
-
-TEST_F(CalloutHandleTest, ContextItemNames) {
-    CalloutHandle handle(getCalloutManager());
-
-    vector<string> expected_names;
-
-    expected_names.push_back("faith");
-    handle.setArgument("faith", 42);
-    expected_names.push_back("hope");
-    handle.setArgument("hope", 43);
-    expected_names.push_back("charity");
-    handle.setArgument("charity", 44);
-
-    // Get the names and check against the expected names.  We'll sort
-    // both arrays to simplify the checking.
-    vector<string> actual_names = handle.getArgumentNames();
-
-    sort(actual_names.begin(), actual_names.end());
-    sort(expected_names.begin(), expected_names.end());
-    EXPECT_TRUE(expected_names == actual_names);
-}
-
-// Test that we can delete an argument.
-
-TEST_F(CalloutHandleTest, DeleteArgument) {
-    CalloutHandle handle(getCalloutManager());
-
-    int one = 1;
-    int two = 2;
-    int three = 3;
-    int four = 4;
-    int value;      // Return value
-
-    handle.setArgument("one", one);
-    handle.setArgument("two", two);
-    handle.setArgument("three", three);
-    handle.setArgument("four", four);
-
-    // Delete "one".
-    handle.getArgument("one", value);
-    EXPECT_EQ(1, value);
-    handle.deleteArgument("one");
-
-    EXPECT_THROW(handle.getArgument("one", value), NoSuchArgument);
-    handle.getArgument("two", value);
-    EXPECT_EQ(2, value);
-    handle.getArgument("three", value);
-    EXPECT_EQ(3, value);
-    handle.getArgument("four", value);
-    EXPECT_EQ(4, value);
-
-    // Delete "three".
-    handle.getArgument("three", value);
-    EXPECT_EQ(3, value);
-    handle.deleteArgument("three");
-
-    EXPECT_THROW(handle.getArgument("one", value), NoSuchArgument);
-    handle.getArgument("two", value);
-    EXPECT_EQ(2, value);
-    EXPECT_THROW(handle.getArgument("three", value), NoSuchArgument);
-    handle.getArgument("four", value);
-    EXPECT_EQ(4, value);
-}
-
-// Test that we can delete all arguments.
-
-TEST_F(CalloutHandleTest, DeleteAllArguments) {
-    CalloutHandle handle(getCalloutManager());
-
-    int one = 1;
-    int two = 2;
-    int three = 3;
-    int four = 4;
-    int value;      // Return value
-
-    // Set the arguments.  The previous test verifies that this works.
-    handle.setArgument("one", one);
-    handle.setArgument("two", two);
-    handle.setArgument("three", three);
-    handle.setArgument("four", four);
-
-    // Delete all arguments...
-    handle.deleteAllArguments();
-
-    // ... and check that none are left.
-    EXPECT_THROW(handle.getArgument("one", value), NoSuchArgument);
-    EXPECT_THROW(handle.getArgument("two", value), NoSuchArgument);
-    EXPECT_THROW(handle.getArgument("three", value), NoSuchArgument);
-    EXPECT_THROW(handle.getArgument("four", value), NoSuchArgument);
-}
-
-// Test the "skip" flag.
-
-TEST_F(CalloutHandleTest, SkipFlag) {
-    CalloutHandle handle(getCalloutManager());
-
-    // Should be false on construction.
-    EXPECT_FALSE(handle.getSkip());
-
-    handle.setSkip(true);
-    EXPECT_TRUE(handle.getSkip());
-
-    handle.setSkip(false);
-    EXPECT_FALSE(handle.getSkip());
-}
-
-} // Anonymous namespace
diff --git a/src/lib/util/tests/callout_manager_unittest.cc b/src/lib/util/tests/callout_manager_unittest.cc
deleted file mode 100644
index ca9b8ad..0000000
--- a/src/lib/util/tests/callout_manager_unittest.cc
+++ /dev/null
@@ -1,765 +0,0 @@
-// Copyright (C) 2013  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 <exceptions/exceptions.h>
-#include <util/hooks/callout_handle.h>
-#include <util/hooks/callout_manager.h>
-#include <util/hooks/library_handle.h>
-#include <util/hooks/server_hooks.h>
-
-#include <boost/scoped_ptr.hpp>
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-/// @file
-/// @brief CalloutManager and LibraryHandle tests
-///
-/// These set of tests check the CalloutManager and LibraryHandle.  They are
-/// together in the same file because the LibraryHandle is little more than a
-/// restricted interface to the CalloutManager, and a lot of the support
-/// structure for the tests is common.
-
-using namespace isc;
-using namespace isc::util;
-using namespace std;
-
-namespace {
-
-class CalloutManagerTest : public ::testing::Test {
-public:
-    /// @brief Constructor
-    ///
-    /// Sets up a collection of three LibraryHandle objects to use in the test.
-    CalloutManagerTest() : hooks_(new ServerHooks()) {
-
-        // Set up the server hooks
-        alpha_index_ = hooks_->registerHook("alpha");
-        beta_index_ = hooks_->registerHook("beta");
-        gamma_index_ = hooks_->registerHook("gamma");
-        delta_index_ = hooks_->registerHook("delta");
-
-        // Set up the callout manager with these hooks.  Assume a maximum of
-        // four libraries.
-        callout_manager_.reset(new CalloutManager(hooks_, 10));
-
-        // Set up the callout handle.
-        callout_handle_.reset(new CalloutHandle(callout_manager_));
-
-        // Initialize the static variable.
-        callout_value_ = 0;
-    }
-
-    /// @brief Return the callout handle
-    CalloutHandle& getCalloutHandle() {
-        return (*callout_handle_);
-    }
-
-    /// @brief Return the callout manager
-    boost::shared_ptr<CalloutManager> getCalloutManager() {
-        return (callout_manager_);
-    }
-
-    boost::shared_ptr<ServerHooks> getServerHooks() {
-        return (hooks_);
-    }
-
-    /// Static variable used for accumulating information
-    static int callout_value_;
-
-    /// Hook indexes.  These are somewhat ubiquitous, so are made public for
-    /// ease of reference instead of being accessible by a function.
-    int alpha_index_;
-    int beta_index_;
-    int gamma_index_;
-    int delta_index_;
-
-private:
-    /// Callout handle used in calls
-    boost::shared_ptr<CalloutHandle> callout_handle_;
-
-    /// Callout manager used for the test
-    boost::shared_ptr<CalloutManager> callout_manager_;
-
-    /// Server hooks
-    boost::shared_ptr<ServerHooks> hooks_;
-};
-
-// Definition of the static variable.
-int CalloutManagerTest::callout_value_ = 0;
-
-// Callout definitions
-//
-// The callouts defined here are structured in such a way that it is possible
-// to determine the order in which they are called and whether they are called
-// at all. The method used is simple - after a sequence of callouts, the digits
-// in the value, reading left to right, determines the order of the callouts
-// called.  For example, callout one followed by two followed by three followed
-// by two followed by one results in a value of 12321.
-//
-// Functions return a zero to indicate success.
-
-extern "C" {
-int callout_general(int number) {
-    CalloutManagerTest::callout_value_ =
-        10 * CalloutManagerTest::callout_value_ + number;
-    return (0);
-}
-
-int callout_one(CalloutHandle&) {
-    return (callout_general(1));
-}
-
-int callout_two(CalloutHandle&) {
-    return (callout_general(2));
-}
-
-int callout_three(CalloutHandle&) {
-    return (callout_general(3));
-}
-
-int callout_four(CalloutHandle&) {
-    return (callout_general(4));
-}
-
-int callout_five(CalloutHandle&) {
-    return (callout_general(5));
-}
-
-int callout_six(CalloutHandle&) {
-    return (callout_general(6));
-}
-
-int callout_seven(CalloutHandle&) {
-    return (callout_general(7));
-}
-
-// The next functions are duplicates of some of the above, but return an error.
-
-int callout_one_error(CalloutHandle& handle) {
-    (void) callout_one(handle);
-    return (1);
-}
-
-int callout_two_error(CalloutHandle& handle) {
-    (void) callout_two(handle);
-    return (1);
-}
-
-int callout_three_error(CalloutHandle& handle) {
-    (void) callout_three(handle);
-    return (1);
-}
-
-int callout_four_error(CalloutHandle& handle) {
-    (void) callout_four(handle);
-    return (1);
-}
-
-};  // extern "C"
-
-// *** Callout Tests ***
-//
-// The next set of tests check that callouts can be called.
-
-// Constructor - check that we trap bad parameters.
-
-TEST_F(CalloutManagerTest, BadConstructorParameters) {
-    boost::scoped_ptr<CalloutManager> cm;
-
-    // Invalid number of libraries
-    EXPECT_THROW(cm.reset(new CalloutManager(getServerHooks(), 0)), BadValue);
-    EXPECT_THROW(cm.reset(new CalloutManager(getServerHooks(), -1)), BadValue);
-
-    // Invalid server hooks pointer.
-    boost::shared_ptr<ServerHooks> sh;
-    EXPECT_THROW(cm.reset(new CalloutManager(sh, 4)), BadValue);
-}
-
-// Check the number of libraries is reported successfully.
-
-TEST_F(CalloutManagerTest, GetNumLibraries) {
-    boost::scoped_ptr<CalloutManager> cm;
-
-    // Check two valid values of number of libraries to ensure that the
-    // GetNumLibraries() returns the value set.
-    EXPECT_NO_THROW(cm.reset(new CalloutManager(getServerHooks(), 4)));
-    EXPECT_EQ(4, cm->getNumLibraries());
-
-    EXPECT_NO_THROW(cm.reset(new CalloutManager(getServerHooks(), 42)));
-    EXPECT_EQ(42, cm->getNumLibraries());
-}
-
-// Check that we can only set the current library index to the correct values.
-
-TEST_F(CalloutManagerTest, CheckLibraryIndex) {
-    // Check valid indexes
-    for (int i = 0; i < 4; ++i) {
-        EXPECT_NO_THROW(getCalloutManager()->setLibraryIndex(i));
-    }
-
-    // Check invalid ones
-    EXPECT_THROW(getCalloutManager()->setLibraryIndex(-1), NoSuchLibrary);
-    EXPECT_THROW(getCalloutManager()->setLibraryIndex(15), NoSuchLibrary);
-}
-
-// Check that we can only register callouts on valid hook names.
-
-TEST_F(CalloutManagerTest, ValidHookNames) {
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_NO_THROW(getCalloutManager()->registerCallout("alpha", callout_one));
-    EXPECT_THROW(getCalloutManager()->registerCallout("unknown", callout_one),
-                                                      NoSuchHook);
-}
-
-
-// Check we can register callouts appropriately.
-
-TEST_F(CalloutManagerTest, RegisterCallout) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-
-    // Set up so that hooks "alpha" and "beta" have callouts attached from a
-    // different libraries.
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("beta", callout_two);
-
-    // Check all is as expected.
-    EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_TRUE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Check that calling the callouts returns as expected. (This is also a
-    // test of the callCallouts method.)
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1, callout_value_);
-
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
-    EXPECT_EQ(2, callout_value_);
-
-    // Register some more callouts from different libraries on hook "alpha".
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("alpha", callout_five);
-
-    // Check it is as expected.
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1345, callout_value_);
-
-    // ... and check the additional callouts were not registered on the "beta"
-    // hook.
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
-    EXPECT_EQ(2, callout_value_);
-
-    // Add another callout to hook "alpha" from library index 2 - this should
-    // appear at the end of the callout list for that library.
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout_six);
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(13465, callout_value_);
-
-    // Add a callout from library index 1 - this should appear between the
-    // callouts from library index 0 and linrary index 2.
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout_seven);
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(173465, callout_value_);
-}
-
-// Check the "calloutsPresent()" method.
-
-TEST_F(CalloutManagerTest, CalloutsPresent) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Set up so that hooks "alpha", "beta" and "delta" have callouts attached
-    // to them, and callout  "gamma" does not. (In the statements below, the
-    // exact callouts attached to a hook are not relevant - only the fact
-    // that some callouts are).  Chose the libraries for which the callouts
-    // are registered randomly.
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->registerCallout("beta", callout_two);
-
-    getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->registerCallout("delta", callout_four);
-
-    // Check all is as expected.
-    EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_TRUE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_TRUE(getCalloutManager()->calloutsPresent(delta_index_));
-
-    // Check we fail on an invalid hook index.
-    EXPECT_THROW(getCalloutManager()->calloutsPresent(42), NoSuchHook);
-    EXPECT_THROW(getCalloutManager()->calloutsPresent(-1), NoSuchHook);
-}
-
-// Test that calling a hook with no callouts on it returns success.
-
-TEST_F(CalloutManagerTest, CallNoCallouts) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Call the callouts on an arbitrary hook and ensure that nothing happens.
-    callout_value_ = 475;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(475, callout_value_); // Unchanged
-}
-
-// Test that the callouts are called in the correct order (i.e. the callouts
-// from the first library in the order they were registered, then the callouts
-// from the second library in the order they were registered etc.)
-
-TEST_F(CalloutManagerTest, CallCalloutsSuccess) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Each library contributes one callout on hook "alpha".
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1234, callout_value_);
-
-    // Do a random selection of callouts on hook "beta".
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("beta", callout_one);
-    getCalloutManager()->registerCallout("beta", callout_three);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("beta", callout_two);
-    getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("beta", callout_four);
-    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
-    EXPECT_EQ(1324, callout_value_);
-
-    // Ensure that calling the callouts on a hook with no callouts works.
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(gamma_index_, getCalloutHandle());
-    EXPECT_EQ(0, callout_value_);
-}
-
-// Test that the callouts are called in order, but that callouts occurring
-// after a callout that returns an error are not called.
-//
-// (Note: in this test, the callouts that return an error set the value of
-// callout_value_ before they return the error code.)
-
-TEST_F(CalloutManagerTest, CallCalloutsError) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Each library contributing one callout on hook "alpha". The first callout
-    // returns an error (after adding its value to the result).
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_one_error);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1234, callout_value_);
-
-    // Each library contributing multiple callouts on hook "beta". The last
-    // callout on the first library returns an error.
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("beta", callout_one);
-    getCalloutManager()->registerCallout("beta", callout_one_error);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("beta", callout_two);
-    getCalloutManager()->registerCallout("beta", callout_two);
-    getCalloutManager()->registerCallout("beta", callout_three);
-    getCalloutManager()->registerCallout("beta", callout_three);
-    getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("beta", callout_four);
-    getCalloutManager()->registerCallout("beta", callout_four);
-    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
-    EXPECT_EQ(11223344, callout_value_);
-
-    // A callout in a random position in the callout list returns an error.
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("gamma", callout_one);
-    getCalloutManager()->registerCallout("gamma", callout_one);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("gamma", callout_two);
-    getCalloutManager()->registerCallout("gamma", callout_two);
-    getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("gamma", callout_four_error);
-    getCalloutManager()->registerCallout("gamma", callout_four);
-    getCalloutManager()->callCallouts(gamma_index_, getCalloutHandle());
-    EXPECT_EQ(112244, callout_value_);
-
-    // The last callout on a hook returns an error.
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("delta", callout_one);
-    getCalloutManager()->registerCallout("delta", callout_one);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("delta", callout_two);
-    getCalloutManager()->registerCallout("delta", callout_two);
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("delta", callout_three);
-    getCalloutManager()->registerCallout("delta", callout_three);
-    getCalloutManager()->setLibraryIndex(3);
-    getCalloutManager()->registerCallout("delta", callout_four);
-    getCalloutManager()->registerCallout("delta", callout_four_error);
-    getCalloutManager()->callCallouts(delta_index_, getCalloutHandle());
-    EXPECT_EQ(11223344, callout_value_);
-}
-
-// Now test that we can deregister a single callout on a hook.
-
-TEST_F(CalloutManagerTest, DeregisterSingleCallout) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Add a callout to hook "alpha" and check it is added correctly.
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(2, callout_value_);
-
-    // Remove it and check that the no callouts are present.  We have to reset
-    // the current library index here as it was invalidated by the call
-    // to callCallouts().
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-}
-
-// Now test that we can deregister a single callout on a hook that has multiple
-// callouts from the same library.
-
-TEST_F(CalloutManagerTest, DeregisterSingleCalloutSameLibrary) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Add multiple callouts to hook "alpha".
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1234, callout_value_);
-
-    // Remove the callout_two callout.  We have to reset the current library
-    // index here as it was invalidated by the call to callCallouts().
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(134, callout_value_);
-
-    // Try removing it again.
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", callout_two));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(134, callout_value_);
-
-}
-
-// Check we can deregister multiple callouts from the same library.
-
-TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsSameLibrary) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Each library contributes one callout on hook "alpha".
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(12123434, callout_value_);
-
-    // Remove the callout_two callouts.  We have to reset the current library
-    // index here as it was invalidated by the call to callCallouts().
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(113434, callout_value_);
-
-    // Try removing multiple callouts that includes one at the end of the
-    // list of callouts.
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_four));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1133, callout_value_);
-
-    // ... and from the start.
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_one));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(33, callout_value_);
-
-    // ... and the remaining callouts.
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_three));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(0, callout_value_);
-
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-}
-
-// Check we can deregister multiple callouts from multiple libraries.
-
-TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsMultipleLibraries) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Each library contributes two callouts to hook "alpha".
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout_five);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(123452, callout_value_);
-
-    // Remove the callout_two callout from library 0.  It should not affect
-    // the second callout_two callout registered by library 2.
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(13452, callout_value_);
-}
-
-// Check we can deregister all callouts from a single library.
-
-TEST_F(CalloutManagerTest, DeregisterAllCallouts) {
-    // Ensure that no callouts are attached to hook one.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-                 
-    // Each library contributes two callouts to hook "alpha".
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout_five);
-    getCalloutManager()->registerCallout("alpha", callout_six);
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(123456, callout_value_);
-
-    // Remove all callouts from library index 1.
-    getCalloutManager()->setLibraryIndex(1);
-    EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1256, callout_value_);
-
-    // Remove all callouts from library index 2.
-    getCalloutManager()->setLibraryIndex(2);
-    EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(12, callout_value_);
-}
-
-// Check that we can register/deregister callouts on different libraries
-// and different hooks, and that the callout instances are regarded as
-// unique and do not affect one another.
-
-TEST_F(CalloutManagerTest, MultipleCalloutsLibrariesHooks) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Register callouts on the alpha hook.
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout_one);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout_three);
-    getCalloutManager()->registerCallout("alpha", callout_four);
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout_five);
-    getCalloutManager()->registerCallout("alpha", callout_two);
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(123452, callout_value_);
-
-    // Register the same callouts on the beta hook, and check that those
-    // on the alpha hook are not affected.
-    callout_value_ = 0;
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("beta", callout_five);
-    getCalloutManager()->registerCallout("beta", callout_one);
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("beta", callout_four);
-    getCalloutManager()->registerCallout("beta", callout_three);
-    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
-    EXPECT_EQ(5143, callout_value_);
-
-    // Check that the order of callouts on the alpha hook has not been affected.
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(123452, callout_value_);
-
-    // Remove callout four from beta and check that alpha is not affected.
-    getCalloutManager()->setLibraryIndex(2);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("beta", callout_four));
-
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(beta_index_, getCalloutHandle());
-    EXPECT_EQ(513, callout_value_);
-
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(123452, callout_value_);
-}
-
-// Library handle tests.  As by inspection the LibraryHandle can be seen to be
-// little more than shell around CalloutManager, only a basic set of tests
-// is done concerning registration and deregistration of functions.
-//
-// More extensive tests (i.e. checking that when a callout is called it can
-// only register and deregister callouts within its library) require that
-// the CalloutHandle object pass the appropriate LibraryHandle to the
-// callout.  These tests are done in the handles_unittest tests.
-
-TEST_F(CalloutManagerTest, LibraryHandleRegistration) {
-    // Ensure that no callouts are attached to any of the hooks.
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-
-    // Set up so that hooks "alpha" and "beta" have callouts attached from a
-    // different libraries.
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->getLibraryHandle().registerCallout("alpha",
-                                                            callout_one);
-    getCalloutManager()->getLibraryHandle().registerCallout("alpha",
-                                                            callout_two);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->getLibraryHandle().registerCallout("alpha",
-                                                            callout_three);
-    getCalloutManager()->getLibraryHandle().registerCallout("alpha",
-                                                            callout_four);
-
-    // Check all is as expected.
-    EXPECT_TRUE(getCalloutManager()->calloutsPresent(alpha_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
-    EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
-    // Check that calling the callouts returns as expected. (This is also a
-    // test of the callCallouts method.)
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1234, callout_value_);
-
-    // Deregister a callout on library index 0 (after we check we can't
-    // deregister it through library index 1).
-    getCalloutManager()->setLibraryIndex(1);
-    EXPECT_FALSE(getCalloutManager()->deregisterCallout("alpha", callout_two));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1234, callout_value_);
-
-    getCalloutManager()->setLibraryIndex(0);
-    EXPECT_TRUE(getCalloutManager()->deregisterCallout("alpha", callout_two));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(134, callout_value_);
-
-    // Deregister all callouts on library index 1.
-    getCalloutManager()->setLibraryIndex(1);
-    EXPECT_TRUE(getCalloutManager()->deregisterAllCallouts("alpha"));
-    callout_value_ = 0;
-    getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
-    EXPECT_EQ(1, callout_value_);
-}
-
-
-
-} // Anonymous namespace
diff --git a/src/lib/util/tests/handles_unittest.cc b/src/lib/util/tests/handles_unittest.cc
deleted file mode 100644
index 22ac88d..0000000
--- a/src/lib/util/tests/handles_unittest.cc
+++ /dev/null
@@ -1,922 +0,0 @@
-// Copyright (C) 2013  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 <util/hooks/callout_handle.h>
-#include <util/hooks/callout_manager.h>
-#include <util/hooks/library_handle.h>
-#include <util/hooks/server_hooks.h>
-
-#include <boost/lexical_cast.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <string>
-
-/// @file
-/// CalloutHandle/LibraryHandle interaction tests
-///
-/// This file holds unit tests checking the interaction between the
-/// CalloutHandle/LibraryHandle and CalloutManager classes.  In particular,
-/// they check that:
-///
-/// - A CalloutHandle's context is shared between callouts from the same
-///   library, but there is a separate context for each library.
-///
-/// - The various methods manipulating the items in the CalloutHandle's context
-///   work correctly.
-///
-/// - An active callout can only modify the registration of callouts registered
-///   by its own library.
-
-using namespace isc::util;
-using namespace std;
-
-namespace {
-
-class HandlesTest : public ::testing::Test {
-public:
-    /// @brief Constructor
-    ///
-    /// Sets up the various elements used in each test.
-    HandlesTest() : hooks_(new ServerHooks()), manager_()
-    {
-        // Set up four hooks, although through gamma
-        alpha_index_ = hooks_->registerHook("alpha");
-        beta_index_ = hooks_->registerHook("beta");
-        gamma_index_ = hooks_->registerHook("gamma");
-        delta_index_ = hooks_->registerHook("delta");
-
-        // Set up for three libraries.
-        manager_.reset(new CalloutManager(hooks_, 3));
-
-        // Initialize remaining variables.
-        common_string_ = "";
-    }
-
-    /// @brief Return callout manager
-    boost::shared_ptr<CalloutManager> getCalloutManager() {
-        return (manager_);
-    }
-
-    /// Hook indexes - these are frequently accessed, so are accessed directly.
-    int alpha_index_;
-    int beta_index_;
-    int gamma_index_;
-    int delta_index_;
-
-    /// String accessible by all callouts whatever the library
-    static std::string common_string_;
-
-private:
-    /// Server hooks 
-    boost::shared_ptr<ServerHooks> hooks_;
-
-    /// Callout manager.  Declared static so that the callout functions can
-    /// access it.
-    boost::shared_ptr<CalloutManager> manager_;
-};
-
-/// Define the common string
-std::string HandlesTest::common_string_;
-
-
-// The next set of functions define the callouts used by the tests.  They
-// manipulate the data in such a way that callouts called - and the order in
-// which they were called - can be determined.  The functions also check that
-// the "callout context" data areas are separate.
-//
-// Three libraries are assumed, and each supplies four callouts.  All callouts
-// manipulate two context elements the CalloutHandle, the elements being called
-// "string" and "int" (which describe the type of data manipulated).
-//
-// For the string item, each callout shifts data to the left and inserts its own
-// data.  The data is a string of the form "nmc", where "n" is the number of
-// the library, "m" is the callout number and "y" is the indication of what
-// callout handle was passed as an argument ("1" or "2": "0" is used when no
-// identification has been set in the callout handle).
-//
-// For simplicity, and to cut down the number of functions actually written,
-// the callout indicator ("1" or "2") ) used in the in the CalloutHandle
-// functions is passed via a CalloutArgument.  The argument is named "string":
-// use of a name the same as that of one of the context elements serves as a
-// check that the argument name space and argument context space are separate.
-//
-// For integer data, the value starts at zero and an increment is added on each
-// call.  This increment is equal to:
-//
-// 100 * library number + 10 * callout number + callout handle
-//
-// Although this gives less information than the string value, the reasons for
-// using it are:
-//
-// - It is a separate item in the context, so checks that the context can
-//   handle multiple items.
-// - It provides an item that can be deleted by the context deletion
-//   methods.
-
-
-// Values set in the CalloutHandle context.  There are three libraries, so
-// there are three contexts for the callout, one for each library.
-
-std::string& resultCalloutString(int index) {
-    static std::string result_callout_string[3];
-    return (result_callout_string[index]);
-}
-
-int& resultCalloutInt(int index) {
-    static int result_callout_int[3];
-    return (result_callout_int[index]);
-}
-
-// A simple function to zero the results.
-
-static void zero_results() {
-    for (int i = 0; i < 3; ++i) {
-        resultCalloutString(i) = "";
-        resultCalloutInt(i) = 0;
-    }
-}
-
-
-// Library callouts.
-
-// Common code for setting the callout context values.
-
-int
-execute(CalloutHandle& callout_handle, int library_num, int callout_num) {
-
-    // Obtain the callout handle number
-    int handle_num = 0;
-    try  {
-        callout_handle.getArgument("handle_num", handle_num);
-    } catch (const NoSuchArgument&) {
-        // handle_num argument not set: this is the case in the tests where
-        // the context_create hook check is tested.
-        handle_num = 0;
-    }
-
-    // Create the basic data to be appended to the context value.
-    int idata = 100 * library_num + 10 * callout_num + handle_num;
-    string sdata = boost::lexical_cast<string>(idata);
-
-    // Get the context data. As before, this will not exist for the first
-    // callout called. (In real life, the library should create it when the
-    // "context_create" hook gets called before any packet processing takes
-    // place.)
-    int int_value = 0;
-    try {
-        callout_handle.getContext("int", int_value);
-    } catch (const NoSuchCalloutContext&) {
-        int_value = 0;
-    }
-
-    string string_value = "";
-    try {
-        callout_handle.getContext("string", string_value);
-    } catch (const NoSuchCalloutContext&) {
-        string_value = "";
-    }
-
-    // Update the values and set them back in the callout context.
-    int_value += idata;
-    callout_handle.setContext("int", int_value);
-
-    string_value += sdata;
-    callout_handle.setContext("string", string_value);
-
-    return (0);
-}
-
-// The following functions are the actual callouts - the name is of the
-// form "callout_<library number>_<callout number>"
-
-int
-callout11(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 1, 1));
-}
-
-int
-callout12(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 1, 2));
-}
-
-int
-callout13(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 1, 3));
-}
-
-int
-callout21(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 2, 1));
-}
-
-int
-callout22(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 2, 2));
-}
-
-int
-callout23(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 2, 3));
-}
-
-int
-callout31(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 3, 1));
-}
-
-int
-callout32(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 3, 2));
-}
-
-int
-callout33(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 3, 3));
-}
-
-// Common callout code for the fourth hook (which makes the data available for
-// checking).  It copies the library and callout context data to the global
-// variables.
-
-int printExecute(CalloutHandle& callout_handle, int library_num) {
-    callout_handle.getContext("string", resultCalloutString(library_num - 1));
-    callout_handle.getContext("int", resultCalloutInt(library_num - 1));
-
-    return (0);
-}
-
-// These are the actual callouts.
-
-int
-print1(CalloutHandle& callout_handle) {
-    return (printExecute(callout_handle, 1));
-}
-
-int
-print2(CalloutHandle& callout_handle) {
-    return (printExecute(callout_handle, 2));
-}
-
-int
-print3(CalloutHandle& callout_handle) {
-    return (printExecute(callout_handle, 3));
-}
-
-// This test checks the many-faced nature of the context for the CalloutContext.
-
-TEST_F(HandlesTest, ContextAccessCheck) {
-    // Register callouts for the different libraries.
-    CalloutHandle handle(getCalloutManager());
-
-    // Library 0.
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout11);
-    getCalloutManager()->registerCallout("beta", callout12);
-    getCalloutManager()->registerCallout("gamma", callout13);
-    getCalloutManager()->registerCallout("delta", print1);
-
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout21);
-    getCalloutManager()->registerCallout("beta", callout22);
-    getCalloutManager()->registerCallout("gamma", callout23);
-    getCalloutManager()->registerCallout("delta", print2);
-
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout31);
-    getCalloutManager()->registerCallout("beta", callout32);
-    getCalloutManager()->registerCallout("gamma", callout33);
-    getCalloutManager()->registerCallout("delta", print3);
-
-    // Create the callout handles and distinguish them by setting the
-    // "handle_num" argument.
-    CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
-
-    CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
-
-    // Now call the callouts attached to the first three hooks.  Each hook is
-    // called twice (once for each callout handle) before the next hook is
-    // called.
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
-    getCalloutManager()->callCallouts(beta_index_, callout_handle_1);
-    getCalloutManager()->callCallouts(beta_index_, callout_handle_2);
-    getCalloutManager()->callCallouts(gamma_index_, callout_handle_1);
-    getCalloutManager()->callCallouts(gamma_index_, callout_handle_2);
-
-    // Get the results for each callout (the callout on hook "delta" copies
-    // the context values into a location the test can access).  Explicitly
-    // zero the variables before getting the results so we are certain that
-    // the values are the results of the callouts.
-
-    zero_results();
-
-    // To explain the expected callout context results.
-    //
-    // Each callout handle maintains a separate context for each library.  When
-    // the first call to callCallouts() is made, "111" gets appended to
-    // the context for library 1 maintained by the first callout handle, "211"
-    // gets appended to the context maintained for library 2, and "311" to
-    // the context maintained for library 3.  In each case, the first digit
-    // corresponds to the library number, the second to the callout number and
-    // the third to the "handle_num" of the callout handle. For the first call
-    // to callCallouts, handle 1 is used, so the last digit is always 1.
-    //
-    // The next call to callCallouts() calls the same callouts but for the
-    // second callout handle.  It also maintains three contexts (one for
-    // each library) and they will get "112", "212", "312" appended to
-    // them. The explanation for the digits is the same as before, except that
-    // in this case, the callout handle is number 2, so the third digit is
-    // always 2.  These additions don't affect the contexts maintained by
-    // callout handle 1.
-    //
-    // The process is then repeated for hooks "beta" and "gamma" which, for
-    // callout handle 1, append "121", "221" and "321" for hook "beta" and
-    // "311", "321" and "331" for hook "gamma".
-    //
-    // The expected integer values can be found by summing up the values
-    // corresponding to the elements of the strings.
-
-    // At this point, we have only called the "print" function for callout
-    // handle "1", so the following results are checking the context values
-    // maintained in that callout handle.
-
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
-    EXPECT_EQ("111121131", resultCalloutString(0));
-    EXPECT_EQ("211221231", resultCalloutString(1));
-    EXPECT_EQ("311321331", resultCalloutString(2));
-
-    EXPECT_EQ((111 + 121 + 131), resultCalloutInt(0));
-    EXPECT_EQ((211 + 221 + 231), resultCalloutInt(1));
-    EXPECT_EQ((311 + 321 + 331), resultCalloutInt(2));
-
-    // Repeat the checks for callout 2.
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
-
-    EXPECT_EQ((112 + 122 + 132), resultCalloutInt(0));
-    EXPECT_EQ((212 + 222 + 232), resultCalloutInt(1));
-    EXPECT_EQ((312 + 322 + 332), resultCalloutInt(2));
-
-    EXPECT_EQ("112122132", resultCalloutString(0));
-    EXPECT_EQ("212222232", resultCalloutString(1));
-    EXPECT_EQ("312322332", resultCalloutString(2));
-}
-
-// Now repeat the test, but add a deletion callout to the list.  The "beta"
-// hook of library 2 will have an additional callout to delete the "int"
-// element: the same hook for library 3 will delete both elements.  In
-// addition, the names of context elements for the libraries at this point
-// will be printed.
-
-// List of context item names.
-
-vector<string>&
-getItemNames(int index) {
-    static vector<string> context_items[3];
-    return (context_items[index]);
-}
-
-// Context item deletion functions.
-
-int
-deleteIntContextItem(CalloutHandle& handle) {
-    handle.deleteContext("int");
-    return (0);
-}
-
-int
-deleteAllContextItems(CalloutHandle& handle) {
-    handle.deleteAllContext();
-    return (0);
-}
-
-// Generic print function - copy names in sorted order.
-
-int
-printContextNamesExecute(CalloutHandle& handle, int library_num) {
-    const int index = library_num - 1;
-    getItemNames(index) = handle.getContextNames();
-    sort(getItemNames(index).begin(), getItemNames(index).end());
-    return (0);
-}
-
-int
-printContextNames1(CalloutHandle& handle) {
-    return (printContextNamesExecute(handle, 1));
-}
-
-int
-printContextNames2(CalloutHandle& handle) {
-    return (printContextNamesExecute(handle, 2));
-}
-
-int
-printContextNames3(CalloutHandle& handle) {
-    return (printContextNamesExecute(handle, 3));
-}
-
-// Perform the test including deletion of context items.
-
-TEST_F(HandlesTest, ContextDeletionCheck) {
-
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout11);
-    getCalloutManager()->registerCallout("beta", callout12);
-    getCalloutManager()->registerCallout("beta", printContextNames1);
-    getCalloutManager()->registerCallout("gamma", callout13);
-    getCalloutManager()->registerCallout("delta", print1);
-
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout21);
-    getCalloutManager()->registerCallout("beta", callout22);
-    getCalloutManager()->registerCallout("beta", deleteIntContextItem);
-    getCalloutManager()->registerCallout("beta", printContextNames2);
-    getCalloutManager()->registerCallout("gamma", callout23);
-    getCalloutManager()->registerCallout("delta", print2);
-
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout31);
-    getCalloutManager()->registerCallout("beta", callout32);
-    getCalloutManager()->registerCallout("beta", deleteAllContextItems);
-    getCalloutManager()->registerCallout("beta", printContextNames3);
-    getCalloutManager()->registerCallout("gamma", callout33);
-    getCalloutManager()->registerCallout("delta", print3);
-
-    // Create the callout handles and distinguish them by setting the "long"
-    // argument.
-    CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1));
-
-    CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2));
-
-    // Now call the callouts attached to the first three hooks.  Each hook is
-    // called twice (once for each callout handle) before the next hook is
-    // called.
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
-    getCalloutManager()->callCallouts(beta_index_, callout_handle_1);
-    getCalloutManager()->callCallouts(beta_index_, callout_handle_2);
-    getCalloutManager()->callCallouts(gamma_index_, callout_handle_1);
-    getCalloutManager()->callCallouts(gamma_index_, callout_handle_2);
-
-    // Get the results for each callout.  Explicitly zero the variables before
-    // getting the results so we are certain that the values are the results
-    // of the callouts.
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
-
-    // The logic by which the expected results are arrived at is described
-    // in the ContextAccessCheck test.  The results here are different
-    // because context items have been modified along the way.
-
-    EXPECT_EQ((111 + 121 + 131), resultCalloutInt(0));
-    EXPECT_EQ((            231), resultCalloutInt(1));
-    EXPECT_EQ((            331), resultCalloutInt(2));
-
-    EXPECT_EQ("111121131", resultCalloutString(0));
-    EXPECT_EQ("211221231", resultCalloutString(1));
-    EXPECT_EQ(      "331", resultCalloutString(2));
-
-    // Repeat the checks for callout handle 2.
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
-
-    EXPECT_EQ((112 + 122 + 132), resultCalloutInt(0));
-    EXPECT_EQ((            232), resultCalloutInt(1));
-    EXPECT_EQ((            332), resultCalloutInt(2));
-
-    EXPECT_EQ("112122132", resultCalloutString(0));
-    EXPECT_EQ("212222232", resultCalloutString(1));
-    EXPECT_EQ(      "332", resultCalloutString(2));
-
-    // ... and check what the names of the context items are after the callouts
-    // for hook "beta".  We know they are in sorted order.
-
-    EXPECT_EQ(2, getItemNames(0).size());
-    EXPECT_EQ(string("int"),    getItemNames(0)[0]);
-    EXPECT_EQ(string("string"), getItemNames(0)[1]);
-
-    EXPECT_EQ(1, getItemNames(1).size());
-    EXPECT_EQ(string("string"), getItemNames(1)[0]);
-
-    EXPECT_EQ(0, getItemNames(2).size());
-}
-
-// Tests that the CalloutHandle's constructor and destructor call the
-// context_create and context_destroy callbacks (if registered).  For
-// simplicity, we'll use the same callout functions as used above, plus
-// the following that returns an error:
-
-int returnError(CalloutHandle&) {
-    return (1);
-}
-
-TEST_F(HandlesTest, ConstructionDestructionCallouts) {
-
-    // Register context callouts.
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("context_create", callout11);
-    getCalloutManager()->registerCallout("context_create", print1);
-    getCalloutManager()->registerCallout("context_destroy", callout12);
-    getCalloutManager()->registerCallout("context_destroy", print1);
-
-    // Create the CalloutHandle and check that the constructor callout
-    // has run.
-    zero_results();
-    boost::scoped_ptr<CalloutHandle>
-        callout_handle(new CalloutHandle(getCalloutManager()));
-    EXPECT_EQ("110", resultCalloutString(0));
-    EXPECT_EQ(110, resultCalloutInt(0));
-
-    // Check that the destructor callout runs.  Note that the "print1" callout
-    // didn't destroy the library context - it only copied it to where it
-    // could be examined.  As a result, the destructor callout appends its
-    // elements to the constructor's values and the result is printed.
-    zero_results();
-    callout_handle.reset();
-
-    EXPECT_EQ("110120", resultCalloutString(0));
-    EXPECT_EQ((110 + 120), resultCalloutInt(0));
-}
-
-// Dynamic callout registration and deregistration.
-// The following are the dynamic registration/deregistration callouts.
-
-
-// Add callout_78_alpha - adds a callout to hook alpha that appends "78x"
-// (where "x" is the callout handle) to the current output.
-
-int
-callout78(CalloutHandle& callout_handle) {
-    return (execute(callout_handle, 7, 8));
-}
-
-int
-add_callout78_alpha(CalloutHandle& callout_handle) {
-    callout_handle.getLibraryHandle().registerCallout("alpha", callout78);
-    return (0);
-}
-
-int
-delete_callout78_alpha(CalloutHandle& callout_handle) {
-    static_cast<void>(
-        callout_handle.getLibraryHandle().deregisterCallout("alpha",
-                                                            callout78));
-    return (0);
-}
-
-// Check that a callout can register another callout on a different hook.
-
-TEST_F(HandlesTest, DynamicRegistrationAnotherHook) {
-    // Register callouts for the different libraries.
-    CalloutHandle handle(getCalloutManager());
-
-    // Set up callouts on "alpha".
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout11);
-    getCalloutManager()->registerCallout("delta", print1);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout21);
-    getCalloutManager()->registerCallout("delta", print2);
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", callout31);
-    getCalloutManager()->registerCallout("delta", print3);
-
-    // ... and on "beta", set up the function to add a hook to alpha (but only
-    // for library 1).
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("beta", add_callout78_alpha);
-
-    // See what we get for calling the callouts on alpha first.
-    CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
-    EXPECT_EQ("111", resultCalloutString(0));
-    EXPECT_EQ("211", resultCalloutString(1));
-    EXPECT_EQ("311", resultCalloutString(2));
-
-    // All as expected, now call the callouts on beta.  This should add a
-    // callout to the list of callouts for alpha, which we should see when
-    // we run the test again.
-    getCalloutManager()->callCallouts(beta_index_, callout_handle_1);
-
-    // Use a new callout handle so as to get fresh callout context.
-    CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
-    EXPECT_EQ("112", resultCalloutString(0));
-    EXPECT_EQ("212782", resultCalloutString(1));
-    EXPECT_EQ("312", resultCalloutString(2));
-}
-
-// Check that a callout can register another callout on the same hook.
-// Note that the registration only applies to a subsequent invocation of
-// callCallouts, not to the current one. In other words, if
-//
-// * the callout list for a library is "A then B then C"
-// * when callCallouts is executed "B" adds "D" to that list,
-//
-// ... the current execution of callCallouts only executes A, B and C.  A
-// subsequent invocation will execute A, B, C then D.
-
-TEST_F(HandlesTest, DynamicRegistrationSameHook) {
-    // Register callouts for the different libraries.
-    CalloutHandle handle(getCalloutManager());
-
-    // Set up callouts on "alpha".
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout11);
-    getCalloutManager()->registerCallout("alpha", add_callout78_alpha);
-    getCalloutManager()->registerCallout("delta", print1);
-
-    // See what we get for calling the callouts on alpha first.
-    CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
-    EXPECT_EQ("111", resultCalloutString(0));
-
-    // Run it again - we should have added something to this hook.
-    CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
-    EXPECT_EQ("112782", resultCalloutString(0));
-
-    // And a third time...
-    CalloutHandle callout_handle_3(getCalloutManager());
-    callout_handle_3.setArgument("handle_num", static_cast<int>(3)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_3);
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_3);
-    EXPECT_EQ("113783783", resultCalloutString(0));
-}
-
-// Deregistration of a callout from a different hook
-
-TEST_F(HandlesTest, DynamicDeregistrationDifferentHook) {
-    // Register callouts for the different libraries.
-    CalloutHandle handle(getCalloutManager());
-
-    // Set up callouts on "alpha".
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout11);
-    getCalloutManager()->registerCallout("alpha", callout78);
-    getCalloutManager()->registerCallout("alpha", callout11);
-    getCalloutManager()->registerCallout("delta", print1);
-
-    getCalloutManager()->registerCallout("beta", delete_callout78_alpha);
-
-    // Call the callouts on alpha
-    CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
-    EXPECT_EQ("111781111", resultCalloutString(0));
-
-    // Run the callouts on hook beta to remove the callout on alpha.
-    getCalloutManager()->callCallouts(beta_index_, callout_handle_1);
-
-    // The run of the callouts should have altered the callout list on the
-    // first library for hook alpha, so call again to make sure.
-    CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
-    EXPECT_EQ("112112", resultCalloutString(0));
-}
-
-// Deregistration of a callout from the same hook
-
-TEST_F(HandlesTest, DynamicDeregistrationSameHook) {
-    // Register callouts for the different libraries.
-    CalloutHandle handle(getCalloutManager());
-
-    // Set up callouts on "alpha".
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", callout11);
-    getCalloutManager()->registerCallout("alpha", delete_callout78_alpha);
-    getCalloutManager()->registerCallout("alpha", callout78);
-    getCalloutManager()->registerCallout("delta", print1);
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", callout21);
-    getCalloutManager()->registerCallout("alpha", callout78);
-    getCalloutManager()->registerCallout("delta", print2);
-
-    // Call the callouts on alpha
-    CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
-    EXPECT_EQ("111781", resultCalloutString(0));
-    EXPECT_EQ("211781", resultCalloutString(1));
-
-    // The run of the callouts should have altered the callout list on the
-    // first library for hook alpha, so call again to make sure.
-    CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
-
-    zero_results();
-    getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
-    EXPECT_EQ("112", resultCalloutString(0));
-    EXPECT_EQ("212782", resultCalloutString(1));
-}
-
-// Testing the operation of the "skip" flag.  Callouts print the value
-// they see in the flag and either leave it unchanged, set it or clear it.
-
-int
-calloutPrintSkip(CalloutHandle& handle) {
-    static const std::string YES("Y");
-    static const std::string NO("N");
-
-    HandlesTest::common_string_ = HandlesTest::common_string_ +
-        (handle.getSkip() ? YES : NO);
-    return (0);
-}
-
-int
-calloutSetSkip(CalloutHandle& handle) {
-    static_cast<void>(calloutPrintSkip(handle));
-    handle.setSkip(true);
-    return (0);
-}
-
-int
-calloutClearSkip(CalloutHandle& handle) {
-    static_cast<void>(calloutPrintSkip(handle));
-    handle.setSkip(false);
-    return (0);
-}
-
-// Do a series of tests, returning with the skip flag set "true".
-
-TEST_F(HandlesTest, ReturnSkipSet) {
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-
-    CalloutHandle callout_handle(getCalloutManager());
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
-
-    // Check result.  For each of visual checking, the expected string is
-    // divided into sections corresponding to the blocks of callouts above.
-    EXPECT_EQ(std::string("NNYY" "NNYYN" "NNYN"), common_string_);
-
-    // ... and check that the skip flag on exit from callCallouts is set.
-    EXPECT_TRUE(callout_handle.getSkip());
-}
-
-// Repeat the test, returning with the skip flag clear.
-TEST_F(HandlesTest, ReturnSkipClear) {
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-    getCalloutManager()->registerCallout("alpha", calloutPrintSkip);
-    getCalloutManager()->registerCallout("alpha", calloutSetSkip);
-    getCalloutManager()->registerCallout("alpha", calloutClearSkip);
-
-    CalloutHandle callout_handle(getCalloutManager());
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
-
-    // Check result.  For each of visual checking, the expected string is
-    // divided into sections corresponding to the blocks of callouts above.
-    EXPECT_EQ(std::string("NYY" "NNYNYN" "NNNY"), common_string_);
-
-    // ... and check that the skip flag on exit from callCallouts is set.
-    EXPECT_FALSE(callout_handle.getSkip());
-}
-
-// The next set of callouts do a similar thing to the above "skip" tests,
-// but alter the value of a string argument.  This is for testing that the
-// a callout is able to change an argument and return it to the caller.
-
-const char* MODIFIED_ARG = "modified_arg";
-
-int
-calloutSetArgumentCommon(CalloutHandle& handle, const char* what) {
-    std::string modified_arg = "";
-
-    handle.getArgument(MODIFIED_ARG, modified_arg);
-    modified_arg = modified_arg + std::string(what);
-    handle.setArgument(MODIFIED_ARG, modified_arg);
-    return (0);
-}
-
-int
-calloutSetArgumentYes(CalloutHandle& handle) {
-    return (calloutSetArgumentCommon(handle, "Y"));
-}
-
-int
-calloutSetArgumentNo(CalloutHandle& handle) {
-    return (calloutSetArgumentCommon(handle, "N"));
-}
-
-// ... and a callout to just copy the argument to the "common_string_" variable
-// but otherwise not alter it.
-
-int
-calloutPrintArgument(CalloutHandle& handle) {
-    handle.getArgument(MODIFIED_ARG, HandlesTest::common_string_);
-    return (0);
-}
-
-TEST_F(HandlesTest, CheckModifiedArgument) {
-    getCalloutManager()->setLibraryIndex(0);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
-
-    getCalloutManager()->setLibraryIndex(1);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
-    getCalloutManager()->registerCallout("alpha", calloutPrintArgument);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
-
-    getCalloutManager()->setLibraryIndex(2);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentNo);
-    getCalloutManager()->registerCallout("alpha", calloutSetArgumentYes);
-
-    // Create the argument with an initial empty string value.  Then call the
-    // sequence of callouts above.
-    CalloutHandle callout_handle(getCalloutManager());
-    std::string modified_arg = "";
-    callout_handle.setArgument(MODIFIED_ARG, modified_arg);
-    getCalloutManager()->callCallouts(alpha_index_, callout_handle);
-
-    // Check the intermediate and results.  For visual checking, the expected
-    // string is divided into sections corresponding to the blocks of callouts
-    // above.
-    EXPECT_EQ(std::string("YNN" "YY"), common_string_);
-
-    callout_handle.getArgument(MODIFIED_ARG, modified_arg);
-    EXPECT_EQ(std::string("YNN" "YYNN" "YNY"), modified_arg);
-}
-
-
-} // Anonymous namespace
-
diff --git a/src/lib/util/tests/server_hooks_unittest.cc b/src/lib/util/tests/server_hooks_unittest.cc
deleted file mode 100644
index f029ad2..0000000
--- a/src/lib/util/tests/server_hooks_unittest.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright (C) 2013  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 <util/hooks/server_hooks.h>
-
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-using namespace isc;
-using namespace isc::util;
-using namespace std;
-
-namespace {
-
-// Checks the registration of hooks and the interrogation methods.  As the
-// constructor registers two hooks, this is also a test of the constructor.
-
-TEST(ServerHooksTest, RegisterHooks) {
-    ServerHooks hooks;
-
-    // There should be two hooks already registered, with indexes 0 and 1.
-    EXPECT_EQ(2, hooks.getCount());
-    EXPECT_EQ(0, hooks.getIndex("context_create"));
-    EXPECT_EQ(1, hooks.getIndex("context_destroy"));
-
-    // Check that the constants are as expected. (The intermediate variables
-    // are used because of problems with g++ 4.6.1/Ubuntu 11.10 when resolving
-    // the value of the ServerHooks constants when they appeared within the
-    // gtest macro.)
-    const int create_value = ServerHooks::CONTEXT_CREATE;
-    const int destroy_value = ServerHooks::CONTEXT_DESTROY;
-    EXPECT_EQ(0, create_value);
-    EXPECT_EQ(1, destroy_value);
-
-    // Register another couple of hooks.  The test on returned index is based
-    // on knowledge that the hook indexes are assigned in ascending order.
-    int alpha = hooks.registerHook("alpha");
-    EXPECT_EQ(2, alpha);
-    EXPECT_EQ(2, hooks.getIndex("alpha"));
-
-    int beta = hooks.registerHook("beta");
-    EXPECT_EQ(3, beta);
-    EXPECT_EQ(3, hooks.getIndex("beta"));
-
-    // Should be four hooks now
-    EXPECT_EQ(4, hooks.getCount());
-}
-
-// Check that duplicate names cannot be registered.
-
-TEST(ServerHooksTest, DuplicateHooks) {
-    ServerHooks hooks;
-
-    // Ensure we can't duplicate one of the existing names.
-    EXPECT_THROW(hooks.registerHook("context_create"), DuplicateHook);
-
-    // Check we can't duplicate a newly registered hook.
-    int gamma = hooks.registerHook("gamma");
-    EXPECT_EQ(2, gamma);
-    EXPECT_THROW(hooks.registerHook("gamma"), DuplicateHook);
-}
-
-// Checks that we can get the name of the hooks.
-
-TEST(ServerHooksTest, GetHookNames) {
-    vector<string> expected_names;
-    ServerHooks hooks;
-
-    // Add names into the hooks object and to the set of expected names.
-    expected_names.push_back("alpha");
-    expected_names.push_back("beta");
-    expected_names.push_back("gamma");
-    expected_names.push_back("delta");
-    for (int i = 0; i < expected_names.size(); ++i) {
-        hooks.registerHook(expected_names[i].c_str());
-    };
-
-    // Update the expected names to include the pre-defined hook names.
-    expected_names.push_back("context_create");
-    expected_names.push_back("context_destroy");
-
-    // Get the actual hook names
-    vector<string> actual_names = hooks.getHookNames();
-
-    // For comparison, sort the names into alphabetical order and do a straight
-    // vector comparison.
-    sort(expected_names.begin(), expected_names.end());
-    sort(actual_names.begin(), actual_names.end());
-
-    EXPECT_TRUE(expected_names == actual_names);
-}
-
-// Check that getting an unknown name throws an exception.
-
-TEST(ServerHooksTest, UnknownHookName) {
-    ServerHooks hooks;
-
-    EXPECT_THROW(static_cast<void>(hooks.getIndex("unknown")), NoSuchHook);
-}
-
-// Check that the count of hooks is correct.
-
-TEST(ServerHooksTest, HookCount) {
-    ServerHooks hooks;
-
-    // Insert the names into the hooks object
-    hooks.registerHook("alpha");
-    hooks.registerHook("beta");
-    hooks.registerHook("gamma");
-    hooks.registerHook("delta");
-
-    // Should be two more hooks that the number we have registered.
-    EXPECT_EQ(6, hooks.getCount());
-}
-
-// HookRegistrationFunction tests
-
-// Declare some hook registration functions.
-
-int alpha = 0;
-int beta = 0;
-int gamma = 0;
-int delta = 0;
-
-void registerAlphaBeta(ServerHooks& hooks) {
-    alpha = hooks.registerHook("alpha");
-    beta = hooks.registerHook("beta");
-}
-
-void registerGammaDelta(ServerHooks& hooks) {
-    gamma = hooks.registerHook("gamma");
-    delta = hooks.registerHook("delta");
-}
-
-// Add them to the registration vector.  This addition should happen before
-// any tests are run, so we should start off with two functions in the
-// registration vector.
-
-HookRegistrationFunction f1(registerAlphaBeta);
-HookRegistrationFunction f2(registerGammaDelta);
-
-// This is not registered statically: it is used in the latter part of the
-// test.
-
-int epsilon = 0;
-void registerEpsilon(ServerHooks& hooks) {
-    epsilon = hooks.registerHook("epsilon");
-}
-
-// Test that the registration functions were defined and can be executed.
-
-TEST(HookRegistrationFunction, Registration) {
-
-    // The first part of the tests checks the static registration.  As there
-    // is only one list of registration functions, we have to do this first
-    // as the static registration is done outside our control, before the
-    // tests are loaded.
-
-    // Ensure that the hook numbers are initialized.
-    EXPECT_EQ(0, alpha);
-    EXPECT_EQ(0, beta);
-    EXPECT_EQ(0, gamma);
-    EXPECT_EQ(0, delta);
-
-    // Should have two hook registration functions registered.
-    EXPECT_EQ(2, HookRegistrationFunction::getFunctionVector().size());
-
-    // Execute the functions and check that four new hooks were defined (two
-    // from each function).
-    ServerHooks hooks;
-    EXPECT_EQ(2, hooks.getCount());
-    HookRegistrationFunction::execute(hooks);
-    EXPECT_EQ(6, hooks.getCount());
-
-    // Check the hook names are as expected.
-    vector<string> names = hooks.getHookNames();
-    ASSERT_EQ(6, names.size());
-    sort(names.begin(), names.end());
-    EXPECT_EQ(string("alpha"), names[0]);
-    EXPECT_EQ(string("beta"), names[1]);
-    EXPECT_EQ(string("context_create"), names[2]);
-    EXPECT_EQ(string("context_destroy"), names[3]);
-    EXPECT_EQ(string("delta"), names[4]);
-    EXPECT_EQ(string("gamma"), names[5]);
-
-    // Check that numbers in the range 2-5 inclusive were assigned as the
-    // hook indexes (0 and 1 being reserved for context_create and
-    // context_destroy).
-    vector<int> indexes;
-    indexes.push_back(alpha);
-    indexes.push_back(beta);
-    indexes.push_back(gamma);
-    indexes.push_back(delta);
-    sort(indexes.begin(), indexes.end());
-    EXPECT_EQ(2, indexes[0]);
-    EXPECT_EQ(3, indexes[1]);
-    EXPECT_EQ(4, indexes[2]);
-    EXPECT_EQ(5, indexes[3]);
-
-    // One last check.  We'll test that the constructor of does indeed
-    // add a function to the function vector and that the static initialization
-    // was not somehow by chance.
-    HookRegistrationFunction::getFunctionVector().clear();
-    EXPECT_TRUE(HookRegistrationFunction::getFunctionVector().empty());
-    epsilon = 0;
-
-    // Register a single registration function.
-    HookRegistrationFunction f3(registerEpsilon);
-    EXPECT_EQ(1, HookRegistrationFunction::getFunctionVector().size());
-
-    // Execute it...
-    ServerHooks hooks2;
-    EXPECT_EQ(0, epsilon);
-    EXPECT_EQ(2, hooks2.getCount());
-    HookRegistrationFunction::execute(hooks2);
-
-    // There should be three hooks, with the new one assigned an index of 2.
-    names = hooks2.getHookNames();
-    ASSERT_EQ(3, names.size());
-    sort(names.begin(), names.end());
-    EXPECT_EQ(string("context_create"), names[0]);
-    EXPECT_EQ(string("context_destroy"), names[1]);
-    EXPECT_EQ(string("epsilon"), names[2]);
-
-    EXPECT_EQ(2, epsilon);
-}
-
-} // Anonymous namespace



More information about the bind10-changes mailing list