BIND 10 trac2355, updated. 53ceb71e36d310a2a4cd5fef7ae9fa5d410f078a [2355] Initial commit of refactoring bin/dchp4 and bin/dchp6 configuration parsing classes into a common set of classes in lib/dhcpsrv. Moved most of the parsers classes into new files dhcp_parsers.h/cc. Eliminated use of global variables within common parsers.

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Apr 10 21:05:36 UTC 2013


The branch, trac2355 has been updated
       via  53ceb71e36d310a2a4cd5fef7ae9fa5d410f078a (commit)
      from  06602f5a998ac727aadd8e094e633c569487ac8f (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 53ceb71e36d310a2a4cd5fef7ae9fa5d410f078a
Author: Thomas Markwalder <tmark at isc.org>
Date:   Wed Apr 10 17:02:10 2013 -0400

    [2355] Initial commit of refactoring bin/dchp4 and bin/dchp6
    configuration parsing classes into a common set of classes
    in lib/dhcpsrv.  Moved most of the parsers classes into
    new files dhcp_parsers.h/cc. Eliminated use of global
    variables within common parsers.

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

Summary of changes:
 src/bin/dhcp4/config_parser.cc  | 1250 ++++----------------------------------
 src/bin/dhcp4/config_parser.h   |   48 +-
 src/bin/dhcp6/config_parser.cc  | 1254 +++------------------------------------
 src/bin/dhcp6/config_parser.h   |   44 ++
 src/lib/dhcpsrv/Makefile.am     |    2 +
 src/lib/dhcpsrv/dhcp_parsers.cc |  633 ++++++++++++++++++++
 src/lib/dhcpsrv/dhcp_parsers.h  |  504 ++++++++++++++++
 7 files changed, 1422 insertions(+), 2313 deletions(-)
 create mode 100644 src/lib/dhcpsrv/dhcp_parsers.cc
 create mode 100644 src/lib/dhcpsrv/dhcp_parsers.h

-----------------------------------------------------------------------
diff --git a/src/bin/dhcp4/config_parser.cc b/src/bin/dhcp4/config_parser.cc
index 2391dff..e531745 100644
--- a/src/bin/dhcp4/config_parser.cc
+++ b/src/bin/dhcp4/config_parser.cc
@@ -13,19 +13,21 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <config/ccsession.h>
-#include <dhcp4/config_parser.h>
 #include <dhcp4/dhcp4_log.h>
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option_definition.h>
 #include <dhcpsrv/cfgmgr.h>
+#include <dhcp4/config_parser.h>
 #include <dhcpsrv/dbaccess_parser.h>
-#include <dhcpsrv/dhcp_config_parser.h>
+#include <dhcpsrv/dhcp_parsers.h>
 #include <dhcpsrv/option_space_container.h>
 #include <util/encode/hex.h>
 #include <util/strutil.h>
+
 #include <boost/foreach.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string.hpp>
+
 #include <limits>
 #include <iostream>
 #include <vector>
@@ -39,37 +41,17 @@ using namespace isc::asiolink;
 
 namespace {
 
-// Forward declarations of some of the parser classes.
-// They are used to define pointer types for these classes.
-class BooleanParser;
-class StringParser;
-class Uint32Parser;
-
 // Pointers to various parser objects.
 typedef boost::shared_ptr<BooleanParser> BooleanParserPtr;
 typedef boost::shared_ptr<StringParser> StringParserPtr;
 typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr;
 
-/// @brief a factory method that will create a parser for a given element name
-typedef isc::dhcp::DhcpConfigParser* ParserFactory(const std::string& config_id);
-
-/// @brief a collection of factories that creates parsers for specified element names
-typedef std::map<std::string, ParserFactory*> FactoryMap;
-
-/// @brief Storage for option definitions.
-typedef OptionSpaceContainer<OptionDefContainer,
-                             OptionDefinitionPtr> OptionDefStorage;
-
 /// @brief a collection of pools
 ///
 /// That type is used as intermediate storage, when pools are parsed, but there is
 /// no subnet object created yet to store them.
 typedef std::vector<Pool4Ptr> PoolStorage;
 
-/// Collection of containers holding option spaces. Each container within
-/// a particular option space holds so-called option descriptors.
-typedef OptionSpaceContainer<Subnet::OptionContainer,
-                             Subnet::OptionDescriptor> OptionStorage;
 
 /// @brief Global uint32 parameters that will be used as defaults.
 Uint32Storage uint32_defaults;
@@ -83,365 +65,6 @@ OptionStorage option_defaults;
 /// @brief Global storage for option definitions.
 OptionDefStorage option_def_intermediate;
 
-/// @brief a dummy configuration parser
-///
-/// It is a debugging parser. It does not configure anything,
-/// will accept any configuration and will just print it out
-/// on commit. Useful for debugging existing configurations and
-/// adding new ones.
-class DebugParser : public DhcpConfigParser {
-public:
-
-    /// @brief Constructor
-    ///
-    /// See @ref DhcpConfigParser class for details.
-    ///
-    /// @param param_name name of the parsed parameter
-    DebugParser(const std::string& param_name)
-        :param_name_(param_name) {
-    }
-
-    /// @brief builds parameter value
-    ///
-    /// See @ref DhcpConfigParser class for details.
-    ///
-    /// @param new_config pointer to the new configuration
-    virtual void build(ConstElementPtr new_config) {
-        std::cout << "Build for token: [" << param_name_ << "] = ["
-                  << value_->str() << "]" << std::endl;
-        value_ = new_config;
-    }
-
-    /// @brief pretends to apply the configuration
-    ///
-    /// This is a method required by base class. It pretends to apply the
-    /// configuration, but in fact it only prints the parameter out.
-    ///
-    /// See @ref DhcpConfigParser class for details.
-    virtual void commit() {
-        // Debug message. The whole DebugParser class is used only for parser
-        // debugging, and is not used in production code. It is very convenient
-        // to keep it around. Please do not turn this cout into logger calls.
-        std::cout << "Commit for token: [" << param_name_ << "] = ["
-                  << value_->str() << "]" << std::endl;
-    }
-
-    /// @brief factory that constructs DebugParser objects
-    ///
-    /// @param param_name name of the parameter to be parsed
-    static DhcpConfigParser* Factory(const std::string& param_name) {
-        return (new DebugParser(param_name));
-    }
-
-private:
-    /// name of the parsed parameter
-    std::string param_name_;
-
-    /// pointer to the actual value of the parameter
-    ConstElementPtr value_;
-};
-
-/// @brief A boolean value parser.
-///
-/// This parser handles configuration values of the boolean type.
-/// Parsed values are stored in a provided storage. If no storage
-/// is provided then the build function throws an exception.
-class BooleanParser : public DhcpConfigParser {
-public:
-    /// @brief Constructor.
-    ///
-    /// @param param_name name of the parameter.
-    BooleanParser(const std::string& param_name)
-        : storage_(NULL),
-          param_name_(param_name),
-          value_(false) {
-        // Empty parameter name is invalid.
-        if (param_name_.empty()) {
-            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-    }
-
-    /// @brief Parse a boolean value.
-    ///
-    /// @param value a value to be parsed.
-    ///
-    /// @throw isc::InvalidOperation if a storage has not been set
-    ///        prior to calling this function
-    /// @throw isc::dhcp::DhcpConfigError if a provided parameter's
-    ///        name is empty.
-    virtual void build(ConstElementPtr value) {
-        if (storage_ == NULL) {
-            isc_throw(isc::InvalidOperation, "parser logic error:"
-                      << " storage for the " << param_name_
-                      << " value has not been set");
-        } else if (param_name_.empty()) {
-            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-        // The Config Manager checks if user specified a
-        // valid value for a boolean parameter: True or False.
-        // It is then ok to assume that if str() does not return
-        // 'true' the value is 'false'.
-        value_ = (value->str() == "true") ? true : false;
-    }
-
-    /// @brief Put a parsed value to the storage.
-    virtual void commit() {
-        if (storage_ != NULL && !param_name_.empty()) {
-            storage_->setParam(param_name_, value_);
-        }
-    }
-
-    /// @brief Create an instance of the boolean parser.
-    ///
-    /// @param param_name name of the parameter for which the
-    ///        parser is created.
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new BooleanParser(param_name));
-    }
-
-    /// @brief Set the storage for parsed value.
-    ///
-    /// This function must be called prior to calling build.
-    ///
-    /// @param storage a pointer to the storage where parsed data
-    ///        is to be stored.
-    void setStorage(BooleanStorage* storage) {
-        storage_ = storage;
-    }
-
-private:
-    /// Pointer to the storage where parsed value is stored.
-    BooleanStorage* storage_;
-    /// Name of the parameter which value is parsed with this parser.
-    std::string param_name_;
-    /// Parsed value.
-    bool value_;
-};
-
-/// @brief Configuration parser for uint32 parameters
-///
-/// This class is a generic parser that is able to handle any uint32 integer
-/// type. By default it stores the value in external global container
-/// (uint32_defaults). If used in smaller scopes (e.g. to parse parameters
-/// in subnet config), it can be pointed to a different storage, using
-/// setStorage() method. This class follows the parser interface, laid out
-/// in its base class, @ref DhcpConfigParser.
-///
-/// For overview of usability of this generic purpose parser, see
-/// @ref dhcpv4ConfigInherit page.
-class Uint32Parser : public DhcpConfigParser {
-public:
-
-    /// @brief constructor for Uint32Parser
-    /// @param param_name name of the configuration parameter being parsed
-    Uint32Parser(const std::string& param_name)
-        : storage_(&uint32_defaults),
-          param_name_(param_name) {
-        // Empty parameter name is invalid.
-        if (param_name_.empty()) {
-            isc_throw(DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-    }
-
-    /// @brief Parses configuration configuration parameter as uint32_t.
-    ///
-    /// @param value pointer to the content of parsed values
-    /// @throw BadValue if supplied value could not be base to uint32_t
-    ///        or the parameter name is empty.
-    virtual void build(ConstElementPtr value) {
-        if (param_name_.empty()) {
-            isc_throw(DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-
-        int64_t check;
-        string x = value->str();
-        try {
-            check = boost::lexical_cast<int64_t>(x);
-        } catch (const boost::bad_lexical_cast &) {
-            isc_throw(BadValue, "Failed to parse value " << value->str()
-                      << " as unsigned 32-bit integer.");
-        }
-        if (check > std::numeric_limits<uint32_t>::max()) {
-            isc_throw(BadValue, "Value " << value->str() << "is too large"
-                      << " for unsigned 32-bit integer.");
-        }
-        if (check < 0) {
-            isc_throw(BadValue, "Value " << value->str() << "is negative."
-                      << " Only 0 or larger are allowed for unsigned 32-bit integer.");
-        }
-
-        // value is small enough to fit
-        value_ = static_cast<uint32_t>(check);
-    }
-
-    /// @brief Stores the parsed uint32_t value in a storage.
-    virtual void commit() {
-        if (storage_ != NULL && !param_name_.empty()) {
-            // If a given parameter already exists in the storage we override
-            // its value. If it doesn't we insert a new element.
-            storage_->setParam(param_name_, value_);
-        }
-    }
-
-    /// @brief factory that constructs Uint32Parser objects
-    ///
-    /// @param param_name name of the parameter to be parsed
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new Uint32Parser(param_name));
-    }
-
-    /// @brief sets storage for value of this parameter
-    ///
-    /// See @ref dhcpv4ConfigInherit for details.
-    ///
-    /// @param storage pointer to the storage container
-    void setStorage(Uint32Storage* storage) {
-        storage_ = storage;
-    }
-
-private:
-    /// pointer to the storage, where parsed value will be stored
-    Uint32Storage* storage_;
-
-    /// name of the parameter to be parsed
-    std::string param_name_;
-
-    /// the actual parsed value
-    uint32_t value_;
-};
-
-/// @brief Configuration parser for string parameters
-///
-/// This class is a generic parser that is able to handle any string
-/// parameter. By default it stores the value in external global container
-/// (string_defaults). If used in smaller scopes (e.g. to parse parameters
-/// in subnet config), it can be pointed to a different storage, using
-/// setStorage() method. This class follows the parser interface, laid out
-/// in its base class, @ref DhcpConfigParser.
-///
-/// For overview of usability of this generic purpose parser, see
-/// @ref dhcpv4ConfigInherit page.
-class StringParser : public DhcpConfigParser {
-public:
-
-    /// @brief constructor for StringParser
-    /// @param param_name name of the configuration parameter being parsed
-    StringParser(const std::string& param_name)
-        :storage_(&string_defaults), param_name_(param_name) {
-        // Empty parameter name is invalid.
-        if (param_name_.empty()) {
-            isc_throw(DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-    }
-
-    /// @brief parses parameter value
-    ///
-    /// Parses configuration entry and stores it in storage. See
-    /// @ref setStorage() for details.
-    ///
-    /// @param value pointer to the content of parsed values
-    virtual void build(ConstElementPtr value) {
-        value_ = value->str();
-        boost::erase_all(value_, "\"");
-    }
-
-    /// @brief Stores the parsed value in a storage.
-    virtual void commit() {
-        if (storage_ != NULL && !param_name_.empty()) {
-            // If a given parameter already exists in the storage we override
-            // its value. If it doesn't we insert a new element.
-            storage_->setParam(param_name_, value_);
-        }
-    }
-
-    /// @brief factory that constructs StringParser objects
-    ///
-    /// @param param_name name of the parameter to be parsed
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new StringParser(param_name));
-    }
-
-    /// @brief sets storage for value of this parameter
-    ///
-    /// See \ref dhcpv4ConfigInherit for details.
-    ///
-    /// @param storage pointer to the storage container
-    void setStorage(StringStorage* storage) {
-        storage_ = storage;
-    }
-
-private:
-    /// pointer to the storage, where parsed value will be stored
-    StringStorage* storage_;
-
-    /// name of the parameter to be parsed
-    std::string param_name_;
-
-    /// the actual parsed value
-    std::string value_;
-};
-
-
-/// @brief parser for interface list definition
-///
-/// This parser handles Dhcp4/interface entry.
-/// It contains a list of network interfaces that the server listens on.
-/// In particular, it can contain an entry called "all" or "any" that
-/// designates all interfaces.
-///
-/// It is useful for parsing Dhcp4/interface parameter.
-class InterfaceListConfigParser : public DhcpConfigParser {
-public:
-
-    /// @brief constructor
-    ///
-    /// As this is a dedicated parser, it must be used to parse
-    /// "interface" parameter only. All other types will throw exception.
-    ///
-    /// @param param_name name of the configuration parameter being parsed
-    /// @throw BadValue if supplied parameter name is not "interface"
-    InterfaceListConfigParser(const std::string& param_name) {
-        if (param_name != "interface") {
-            isc_throw(BadValue, "Internal error. Interface configuration "
-                      "parser called for the wrong parameter: " << param_name);
-        }
-    }
-
-    /// @brief parses parameters value
-    ///
-    /// Parses configuration entry (list of parameters) and adds each element
-    /// to the interfaces list.
-    ///
-    /// @param value pointer to the content of parsed values
-    virtual void build(ConstElementPtr value) {
-        BOOST_FOREACH(ConstElementPtr iface, value->listValue()) {
-            interfaces_.push_back(iface->str());
-        }
-    }
-
-    /// @brief commits interfaces list configuration
-    virtual void commit() {
-        /// @todo: Implement per interface listening. Currently always listening
-        /// on all interfaces.
-    }
-
-    /// @brief factory that constructs InterfaceListConfigParser objects
-    ///
-    /// @param param_name name of the parameter to be parsed
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new InterfaceListConfigParser(param_name));
-    }
-
-private:
-    /// contains list of network interfaces
-    vector<string> interfaces_;
-};
-
 /// @brief parser for pool definition
 ///
 /// This parser handles pool definitions, i.e. a list of entries of one
@@ -461,6 +84,12 @@ public:
         // ignore parameter name, it is always Dhcp4/subnet4[X]/pool
     }
 
+    /// @brief constructor.
+    PoolParser(const std::string& /*param_name*/,  PoolStorage* pools)
+        :pools_(pools) {
+        // ignore parameter name, it is always Dhcp4/subnet4[X]/pool
+    }
+
     /// @brief parses the actual list
     ///
     /// This method parses the actual list of interfaces.
@@ -575,675 +204,6 @@ private:
     PoolStorage local_pools_;
 };
 
-/// @brief Parser for option data value.
-///
-/// This parser parses configuration entries that specify value of
-/// a single option. These entries include option name, option code
-/// and data carried by the option. The option data can be specified
-/// in one of the two available formats: binary value represented as
-/// a string of hexadecimal digits or a list of comma separated values.
-/// The format being used is controlled by csv-format configuration
-/// parameter. When setting this value to True, the latter format is
-/// used. The subsequent values in the CSV format apply to relevant
-/// option data fields in the configured option. For example the
-/// configuration: "data" : "192.168.2.0, 56, hello world" can be
-/// used to set values for the option comprising IPv4 address,
-/// integer and string data field. Note that order matters. If the
-/// order of values does not match the order of data fields within
-/// an option the configuration will not be accepted. If parsing
-/// is successful then an instance of an option is created and
-/// added to the storage provided by the calling class.
-class OptionDataParser : public DhcpConfigParser {
-public:
-
-    /// @brief Constructor.
-    ///
-    /// Class constructor.
-    OptionDataParser(const std::string&)
-        : options_(NULL),
-          // initialize option to NULL ptr
-          option_descriptor_(false) { }
-
-    /// @brief Parses the single option data.
-    ///
-    /// This method parses the data of a single option from the configuration.
-    /// The option data includes option name, option code and data being
-    /// carried by this option. Eventually it creates the instance of the
-    /// option.
-    ///
-    /// @warning setStorage must be called with valid storage pointer prior
-    /// to calling this method.
-    ///
-    /// @param option_data_entries collection of entries that define value
-    /// for a particular option.
-    /// @throw DhcpConfigError if invalid parameter specified in
-    /// the configuration.
-    /// @throw isc::InvalidOperation if failed to set storage prior to
-    /// calling build.
-    virtual void build(ConstElementPtr option_data_entries) {
-        if (options_ == NULL) {
-            isc_throw(isc::InvalidOperation, "Parser logic error: storage must be set before "
-                      "parsing option data.");
-        }
-        BOOST_FOREACH(ConfigPair param, option_data_entries->mapValue()) {
-            ParserPtr parser;
-            if (param.first == "name" || param.first == "data" ||
-                param.first == "space") {
-                boost::shared_ptr<StringParser>
-                    name_parser(dynamic_cast<StringParser*>(StringParser::factory(param.first)));
-                if (name_parser) {
-                    name_parser->setStorage(&string_values_);
-                    parser = name_parser;
-                }
-            } else if (param.first == "code") {
-                boost::shared_ptr<Uint32Parser>
-                    code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::factory(param.first)));
-                if (code_parser) {
-                    code_parser->setStorage(&uint32_values_);
-                    parser = code_parser;
-                }
-            } else if (param.first == "csv-format") {
-                boost::shared_ptr<BooleanParser>
-                    value_parser(dynamic_cast<BooleanParser*>(BooleanParser::factory(param.first)));
-                if (value_parser) {
-                    value_parser->setStorage(&boolean_values_);
-                    parser = value_parser;
-                }
-            } else {
-                isc_throw(DhcpConfigError,
-                          "Parser error: option-data parameter not supported: "
-                          << param.first);
-            }
-            parser->build(param.second);
-            // Before we can create an option we need to get the data from
-            // the child parsers. The only way to do it is to invoke commit
-            // on them so as they store the values in appropriate storages
-            // that this class provided to them. Note that this will not
-            // modify values stored in the global storages so the configuration
-            // will remain consistent even parsing fails somewhere further on.
-            parser->commit();
-        }
-        // Try to create the option instance.
-        createOption();
-    }
-
-    /// @brief Commits option value.
-    ///
-    /// This function adds a new option to the storage or replaces an existing option
-    /// with the same code.
-    ///
-    /// @throw isc::InvalidOperation if failed to set pointer to storage or failed
-    /// to call build() prior to commit. If that happens data in the storage
-    /// remain un-modified.
-    virtual void commit() {
-        if (options_ == NULL) {
-            isc_throw(isc::InvalidOperation, "parser logic error: storage must be set before "
-                      "committing option data.");
-        } else  if (!option_descriptor_.option) {
-            // Before we can commit the new option should be configured. If it is not
-            // than somebody must have called commit() before build().
-            isc_throw(isc::InvalidOperation, "parser logic error: no option has been configured and"
-                      " thus there is nothing to commit. Has build() been called?");
-        }
-        uint16_t opt_type = option_descriptor_.option->getType();
-        Subnet::OptionContainerPtr options = options_->getItems(option_space_);
-        // The getItems() should never return NULL pointer. If there are no
-        // options configured for the particular option space a pointer
-        // to an empty container should be returned.
-        assert(options);
-        Subnet::OptionContainerTypeIndex& idx = options->get<1>();
-        // Try to find options with the particular option code in the main
-        // storage. If found, remove these options because they will be
-        // replaced with new one.
-        Subnet::OptionContainerTypeRange range =
-            idx.equal_range(opt_type);
-        if (std::distance(range.first, range.second) > 0) {
-            idx.erase(range.first, range.second);
-        }
-        // Append new option to the main storage.
-        options_->addItem(option_descriptor_, option_space_);
-    }
-
-    /// @brief Set storage for the parser.
-    ///
-    /// Sets storage for the parser. This storage points to the
-    /// vector of options and is used by multiple instances of
-    /// OptionDataParser. Each instance creates exactly one object
-    /// of dhcp::Option or derived type and appends it to this
-    /// storage.
-    ///
-    /// @param storage pointer to the options storage
-    void setStorage(OptionStorage* storage) {
-        options_ = storage;
-    }
-
-private:
-
-    /// @brief Create option instance.
-    ///
-    /// Creates an instance of an option and adds it to the provided
-    /// options storage. If the option data parsed by \ref build function
-    /// are invalid or insufficient this function emits an exception.
-    ///
-    /// @warning this function does not check if options_ storage pointer
-    /// is intitialized but this check is not needed here because it is done
-    /// in the \ref build function.
-    ///
-    /// @throw DhcpConfigError if parameters provided in the configuration
-    /// are invalid.
-    void createOption() {
-        // Option code is held in the uint32_t storage but is supposed to
-        // be uint16_t value. We need to check that value in the configuration
-        // does not exceed range of uint8_t and is not zero.
-        uint32_t option_code = uint32_values_.getParam("code");
-        if (option_code == 0) {
-            isc_throw(DhcpConfigError, "option code must not be zero."
-                      << " Option code '0' is reserved in DHCPv4.");
-        } else if (option_code > std::numeric_limits<uint8_t>::max()) {
-            isc_throw(DhcpConfigError, "invalid option code '" << option_code
-                      << "', it must not exceed '"
-                      << std::numeric_limits<uint8_t>::max() << "'");
-        }
-
-        // Check that the option name has been specified, is non-empty and does not
-        // contain spaces
-        std::string option_name = string_values_.getParam("name"); 
-        if (option_name.empty()) {
-            isc_throw(DhcpConfigError, "name of the option with code '"
-                      << option_code << "' is empty");
-        } else if (option_name.find(" ") != std::string::npos) {
-            isc_throw(DhcpConfigError, "invalid option name '" << option_name
-                      << "', space character is not allowed");
-        }
-
-        std::string option_space = string_values_.getParam("space"); 
-        if (!OptionSpace::validateName(option_space)) {
-            isc_throw(DhcpConfigError, "invalid option space name '"
-                      << option_space << "' specified for option '"
-                      << option_name << "' (code '" << option_code
-                      << "')");
-        }
-
-        OptionDefinitionPtr def;
-        if (option_space == "dhcp4" &&
-            LibDHCP::isStandardOption(Option::V4, option_code)) {
-            def = LibDHCP::getOptionDef(Option::V4, option_code);
-
-        } else if (option_space == "dhcp6") {
-            isc_throw(DhcpConfigError, "'dhcp6' option space name is reserved"
-                      << " for DHCPv6 server");
-        } else {
-            // If we are not dealing with a standard option then we
-            // need to search for its definition among user-configured
-            // options. They are expected to be in the global storage
-            // already.
-            OptionDefContainerPtr defs = option_def_intermediate.getItems(option_space);
-            // The getItems() should never return the NULL pointer. If there are
-            // no option definitions for the particular option space a pointer
-            // to an empty container should be returned.
-            assert(defs);
-            const OptionDefContainerTypeIndex& idx = defs->get<1>();
-            OptionDefContainerTypeRange range = idx.equal_range(option_code);
-            if (std::distance(range.first, range.second) > 0) {
-                def = *range.first;
-            }
-            if (!def) {
-                isc_throw(DhcpConfigError, "definition for the option '"
-                          << option_space << "." << option_name
-                          << "' having code '" <<  option_code
-                          << "' does not exist");
-            }
-
-        }
-
-        // Get option data from the configuration database ('data' field).
-        const std::string option_data = string_values_.getParam("data");
-        const bool csv_format = boolean_values_.getParam("csv-format");
-
-        // Transform string of hexadecimal digits into binary format.
-        std::vector<uint8_t> binary;
-        std::vector<std::string> data_tokens;
-
-        if (csv_format) {
-            // If the option data is specified as a string of comma
-            // separated values then we need to split this string into
-            // individual values - each value will be used to initialize
-            // one data field of an option.
-            data_tokens = isc::util::str::tokens(option_data, ",");
-        } else {
-            // Otherwise, the option data is specified as a string of
-            // hexadecimal digits that we have to turn into binary format.
-            try {
-                util::encode::decodeHex(option_data, binary);
-            } catch (...) {
-                isc_throw(DhcpConfigError, "option data is not a valid"
-                          << " string of hexadecimal digits: " << option_data);
-            }
-        }
-
-        OptionPtr option;
-        if (!def) {
-            if (csv_format) {
-                isc_throw(DhcpConfigError, "the CSV option data format can be"
-                          " used to specify values for an option that has a"
-                          " definition. The option with code " << option_code
-                          << " does not have a definition.");
-            }
-
-            // @todo We have a limited set of option definitions intiialized at the moment.
-            // In the future we want to initialize option definitions for all options.
-            // Consequently an error will be issued if an option definition does not exist
-            // for a particular option code. For now it is ok to create generic option
-            // if definition does not exist.
-            OptionPtr option(new Option(Option::V4, static_cast<uint16_t>(option_code),
-                                        binary));
-            // The created option is stored in option_descriptor_ class member until the
-            // commit stage when it is inserted into the main storage. If an option with the
-            // same code exists in main storage already the old option is replaced.
-            option_descriptor_.option = option;
-            option_descriptor_.persistent = false;
-        } else {
-
-            // Option name should match the definition. The option name
-            // may seem to be redundant but in the future we may want
-            // to reference options and definitions using their names
-            // and/or option codes so keeping the option name in the
-            // definition of option value makes sense.
-            if (def->getName() != option_name) {
-                isc_throw(DhcpConfigError, "specified option name '"
-                          << option_name << "' does not match the "
-                          << "option definition: '" << option_space
-                          << "." << def->getName() << "'");
-            }
-
-            // Option definition has been found so let's use it to create
-            // an instance of our option.
-            try {
-                OptionPtr option = csv_format ?
-                    def->optionFactory(Option::V4, option_code, data_tokens) :
-                    def->optionFactory(Option::V4, option_code, binary);
-                Subnet::OptionDescriptor desc(option, false);
-                option_descriptor_.option = option;
-                option_descriptor_.persistent = false;
-            } catch (const isc::Exception& ex) {
-                isc_throw(DhcpConfigError, "option data does not match"
-                          << " option definition (space: " << option_space
-                          << ", code: " << option_code << "): "
-                          << ex.what());
-            }
-
-        }
-        // All went good, so we can set the option space name.
-        option_space_ = option_space;
-    }
-
-    /// Storage for uint32 values (e.g. option code).
-    Uint32Storage uint32_values_;
-    /// Storage for string values (e.g. option name or data).
-    StringStorage string_values_;
-    /// Storage for boolean values.
-    BooleanStorage boolean_values_;
-    /// Pointer to options storage. This storage is provided by
-    /// the calling class and is shared by all OptionDataParser objects.
-    OptionStorage* options_;
-    /// Option descriptor holds newly configured option.
-    Subnet::OptionDescriptor option_descriptor_;
-    /// Option space name where the option belongs to.
-    std::string option_space_;
-};
-
-/// @brief Parser for option data values within a subnet.
-///
-/// This parser iterates over all entries that define options
-/// data for a particular subnet and creates a collection of options.
-/// If parsing is successful, all these options are added to the Subnet
-/// object.
-class OptionDataListParser : public DhcpConfigParser {
-public:
-
-    /// @brief Constructor.
-    ///
-    /// Unless otherwise specified, parsed options will be stored in
-    /// a global option container (option_default). That storage location
-    /// is overriden on a subnet basis.
-    OptionDataListParser(const std::string&)
-        : options_(&option_defaults), local_options_() { }
-
-    /// @brief Parses entries that define options' data for a subnet.
-    ///
-    /// This method iterates over all entries that define option data
-    /// for options within a single subnet and creates options' instances.
-    ///
-    /// @param option_data_list pointer to a list of options' data sets.
-    /// @throw DhcpConfigError if option parsing failed.
-    void build(ConstElementPtr option_data_list) {
-        BOOST_FOREACH(ConstElementPtr option_value, option_data_list->listValue()) {
-            boost::shared_ptr<OptionDataParser> parser(new OptionDataParser("option-data"));
-            // options_ member will hold instances of all options thus
-            // each OptionDataParser takes it as a storage.
-            parser->setStorage(&local_options_);
-            // Build the instance of a single option.
-            parser->build(option_value);
-            // Store a parser as it will be used to commit.
-            parsers_.push_back(parser);
-        }
-    }
-
-    /// @brief Set storage for option instances.
-    ///
-    /// @param storage pointer to options storage.
-    void setStorage(OptionStorage* storage) {
-        options_ = storage;
-    }
-
-
-    /// @brief Commit all option values.
-    ///
-    /// This function invokes commit for all option values.
-    void commit() {
-        BOOST_FOREACH(ParserPtr parser, parsers_) {
-            parser->commit();
-        }
-        // Parsing was successful and we have all configured
-        // options in local storage. We can now replace old values
-        // with new values.
-        std::swap(local_options_, *options_);
-    }
-
-    /// @brief Create DhcpDataListParser object
-    ///
-    /// @param param_name param name.
-    ///
-    /// @return DhcpConfigParser object.
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new OptionDataListParser(param_name));
-    }
-
-    /// Pointer to options instances storage.
-    OptionStorage* options_;
-    /// Intermediate option storage. This storage is used by
-    /// lower level parsers to add new options.  Values held
-    /// in this storage are assigned to main storage (options_)
-    /// if overall parsing was successful.
-    OptionStorage local_options_;
-    /// Collection of parsers;
-    ParserCollection parsers_;
-};
-
-/// @brief Parser for a single option definition.
-///
-/// This parser creates an instance of a single option definition.
-class OptionDefParser : public DhcpConfigParser {
-public:
-
-    /// @brief Constructor.
-    ///
-    /// This constructor sets the pointer to the option definitions
-    /// storage to NULL. It must be set to point to the actual storage
-    /// before \ref build is called.
-    OptionDefParser(const std::string&)
-        : storage_(NULL) {
-    }
-
-    /// @brief Parses an entry that describes single option definition.
-    ///
-    /// @param option_def a configuration entry to be parsed.
-    ///
-    /// @throw DhcpConfigError if parsing was unsuccessful.
-    void build(ConstElementPtr option_def) {
-        if (storage_ == NULL) {
-            isc_throw(DhcpConfigError, "parser logic error: storage must be set"
-                      " before parsing option definition data");
-        }
-        // Parse the elements that make up the option definition.
-        BOOST_FOREACH(ConfigPair param, option_def->mapValue()) {
-            std::string entry(param.first);
-            ParserPtr parser;
-            if (entry == "name" || entry == "type" ||
-                entry == "record-types" || entry == "space" ||
-                entry == "encapsulate") {
-                StringParserPtr
-                    str_parser(dynamic_cast<StringParser*>(StringParser::factory(entry)));
-                if (str_parser) {
-                    str_parser->setStorage(&string_values_);
-                    parser = str_parser;
-                }
-            } else if (entry == "code") {
-                Uint32ParserPtr
-                    code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::factory(entry)));
-                if (code_parser) {
-                    code_parser->setStorage(&uint32_values_);
-                    parser = code_parser;
-                }
-            } else if (entry == "array") {
-                BooleanParserPtr
-                    array_parser(dynamic_cast<BooleanParser*>(BooleanParser::factory(entry)));
-                if (array_parser) {
-                    array_parser->setStorage(&boolean_values_);
-                    parser = array_parser;
-                }
-            } else {
-                isc_throw(DhcpConfigError, "invalid parameter: " << entry);
-            }
-
-            parser->build(param.second);
-            parser->commit();
-        }
-
-        // Create an instance of option definition.
-        createOptionDef();
-
-        // Get all items we collected so far for the particular option space.
-        OptionDefContainerPtr defs = storage_->getItems(option_space_name_);
-        // Check if there are any items with option code the same as the
-        // one specified for the definition we are now creating.
-        const OptionDefContainerTypeIndex& idx = defs->get<1>();
-        const OptionDefContainerTypeRange& range =
-            idx.equal_range(option_definition_->getCode());
-        // If there are any items with this option code already we need
-        // to issue an error because we don't allow duplicates for
-        // option definitions within an option space.
-        if (std::distance(range.first, range.second) > 0) {
-            isc_throw(DhcpConfigError, "duplicated option definition for"
-                      << " code '" << option_definition_->getCode() << "'");
-        }
-    }
-
-    /// @brief Stores the parsed option definition in a storage.
-    void commit() {
-        if (storage_ && option_definition_ &&
-            OptionSpace::validateName(option_space_name_)) {
-            storage_->addItem(option_definition_, option_space_name_);
-        }
-    }
-
-    /// @brief Sets a pointer to the data store.
-    ///
-    /// The newly created instance of an option definition will be
-    /// added to the data store given by the argument.
-    ///
-    /// @param storage pointer to the data store where the option definition
-    /// will be added to.
-    void setStorage(OptionDefStorage* storage) {
-        storage_ = storage;
-    }
-
-private:
-
-    /// @brief Create option definition from the parsed parameters.
-    void createOptionDef() {
-
-        // Get the option space name and validate it.
-        std::string space = string_values_.getParam("space");
-        if (!OptionSpace::validateName(space)) {
-            isc_throw(DhcpConfigError, "invalid option space name '"
-                      << space << "'");
-        }
-
-        // Get other parameters that are needed to create the
-        // option definition.
-        std::string name = string_values_.getParam("name");
-        uint32_t code = uint32_values_.getParam("code");
-        std::string type = string_values_.getParam("type");
-        bool array_type = boolean_values_.getParam("array");
-        std::string encapsulates = string_values_.getParam("encapsulate");
-
-        // Create option definition.
-        OptionDefinitionPtr def;
-        // We need to check if user has set encapsulated option space
-        // name. If so, different constructor will be used.
-        if (!encapsulates.empty()) {
-            // Arrays can't be used together with sub-options.
-            if (array_type) {
-                isc_throw(DhcpConfigError, "option '" << space << "."
-                          << "name" << "', comprising an array of data"
-                          << " fields may not encapsulate any option space");
-
-            } else if (encapsulates == space) {
-                isc_throw(DhcpConfigError, "option must not encapsulate"
-                          << " an option space it belongs to: '"
-                          << space << "." << name << "' is set to"
-                          << " encapsulate '" << space << "'");
-
-            } else {
-                def.reset(new OptionDefinition(name, code, type,
-                                               encapsulates.c_str()));
-            }
-
-        } else {
-            def.reset(new OptionDefinition(name, code, type, array_type));
-
-        }
-        // The record-types field may carry a list of comma separated names
-        // of data types that form a record.
-        std::string record_types = string_values_.getParam("record-types");
-
-        // Split the list of record types into tokens.
-        std::vector<std::string> record_tokens =
-            isc::util::str::tokens(record_types, ",");
-        // Iterate over each token and add a record type into
-        // option definition.
-        BOOST_FOREACH(std::string record_type, record_tokens) {
-            try {
-                boost::trim(record_type);
-                if (!record_type.empty()) {
-                    def->addRecordField(record_type);
-                }
-            } catch (const Exception& ex) {
-                isc_throw(DhcpConfigError, "invalid record type values"
-                          << " specified for the option definition: "
-                          << ex.what());
-            }
-        }
-
-        // Check the option definition parameters are valid.
-        try {
-            def->validate();
-        } catch (const isc::Exception& ex) {
-            isc_throw(DhcpConfigError, "invalid option definition"
-                      << " parameters: " << ex.what());
-        }
-        // Option definition has been created successfully.
-        option_space_name_ = space;
-        option_definition_ = def;
-    }
-
-    /// Instance of option definition being created by this parser.
-    OptionDefinitionPtr option_definition_;
-    /// Name of the space the option definition belongs to.
-    std::string option_space_name_;
-
-    /// Pointer to a storage where the option definition will be
-    /// added when \ref commit is called.
-    OptionDefStorage* storage_;
-
-    /// Storage for boolean values.
-    BooleanStorage boolean_values_;
-    /// Storage for string values.
-    StringStorage string_values_;
-    /// Storage for uint32 values.
-    Uint32Storage uint32_values_;
-};
-
-/// @brief Parser for a list of option definitions.
-///
-/// This parser iterates over all configuration entries that define
-/// option definitions and creates instances of these definitions.
-/// If the parsing is successful, the collection of created definitions
-/// is put into the provided storage.
-class OptionDefListParser : DhcpConfigParser {
-public:
-
-    /// @brief Constructor.
-    ///
-    /// This constructor initializes the pointer to option definitions
-    /// storage to NULL value. This pointer has to be set to point to
-    /// the actual storage before the \ref build function is called.
-    OptionDefListParser(const std::string&) {
-    }
-
-    /// @brief Parse configuration entries.
-    ///
-    /// This function parses configuration entries and creates instances
-    /// of option definitions.
-    ///
-    /// @param option_def_list pointer to an element that holds entries
-    /// that define option definitions.
-    /// @throw DhcpConfigError if configuration parsing fails.
-    void build(ConstElementPtr option_def_list) {
-        // Clear existing items in the global storage.
-        // We are going to replace all of them.
-        option_def_intermediate.clearItems();
-
-        if (!option_def_list) {
-            isc_throw(DhcpConfigError, "parser error: a pointer to a list of"
-                      << " option definitions is NULL");
-        }
-
-        BOOST_FOREACH(ConstElementPtr option_def, option_def_list->listValue()) {
-            boost::shared_ptr<OptionDefParser>
-                parser(new OptionDefParser("single-option-def"));
-            parser->setStorage(&option_def_intermediate);
-            parser->build(option_def);
-            parser->commit();
-        }
-    }
-
-    /// @brief Stores option definitions in the CfgMgr.
-    void commit() {
-
-        CfgMgr& cfg_mgr = CfgMgr::instance();
-
-        cfg_mgr.deleteOptionDefs();
-
-        // We need to move option definitions from the temporary
-        // storage to the global storage.
-        std::list<std::string> space_names =
-            option_def_intermediate.getOptionSpaceNames();
-        BOOST_FOREACH(std::string space_name, space_names) {
-
-            BOOST_FOREACH(OptionDefinitionPtr def,
-                          *option_def_intermediate.getItems(space_name)) {
-                // All option definitions should be initialized to non-NULL
-                // values. The validation is expected to be made by the
-                // OptionDefParser when creating an option definition.
-                assert(def);
-                cfg_mgr.addOptionDef(def, space_name);
-            }
-        }
-    }
-
-    /// @brief Create an OptionDefListParser object.
-    ///
-    /// @param param_name configuration entry holding option definitions.
-    ///
-    /// @return OptionDefListParser object.
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new OptionDefListParser(param_name));
-    }
-
-};
-
 /// @brief this class parses a single subnet
 ///
 /// This class parses the whole subnet definition. It creates parsers
@@ -1264,30 +224,10 @@ public:
 
         BOOST_FOREACH(ConfigPair param, subnet->mapValue()) {
             ParserPtr parser(createSubnet4ConfigParser(param.first));
-            // The actual type of the parser is unknown here. We have to discover
-            // the parser type here to invoke the corresponding setStorage function
-            // on it.  We discover parser type by trying to cast the parser to various
-            // parser types and checking which one was successful. For this one
-            // a setStorage and build methods are invoked.
-
-            // Try uint32 type parser.
-            if (!buildParser<Uint32Parser, Uint32Storage >(parser, uint32_values_,
-                                                          param.second) &&
-                // Try string type parser.
-                !buildParser<StringParser, StringStorage >(parser, string_values_,
-                                                           param.second) &&
-                // Try pool parser.
-                !buildParser<PoolParser, PoolStorage >(parser, pools_,
-                                                       param.second) &&
-                // Try option data parser.
-                !buildParser<OptionDataListParser, OptionStorage >(parser, options_,
-                                                                   param.second)) {
-                // Appropriate parsers are created in the createSubnet6ConfigParser
-                // and they should be limited to those that we check here for. Thus,
-                // if we fail to find a matching parser here it is a programming error.
-                isc_throw(DhcpConfigError, "failed to find suitable parser");
-            }
+            parser->build(param.second);
+            parsers_.push_back(parser);
         }
+
         // In order to create new subnet we need to get the data out
         // of the child parsers first. The only way to do it is to
         // invoke commit on them because it will make them write
@@ -1319,40 +259,6 @@ public:
 
 private:
 
-    /// @brief Set storage for a parser and invoke build.
-    ///
-    /// This helper method casts the provided parser pointer to the specified
-    /// type. If the cast is successful it sets the corresponding storage for
-    /// this parser, invokes build on it and saves the parser.
-    ///
-    /// @tparam T parser type to which parser argument should be cast.
-    /// @tparam Y storage type for the specified parser type.
-    /// @param parser parser on which build must be invoked.
-    /// @param storage reference to a storage that will be set for a parser.
-    /// @param subnet subnet element read from the configuration and being parsed.
-    /// @return true if parser pointer was successfully cast to specialized
-    /// parser type provided as Y.
-    template<typename T, typename Y>
-    bool buildParser(const ParserPtr& parser, Y& storage, const ConstElementPtr& subnet) {
-        // We need to cast to T in order to set storage for the parser.
-        boost::shared_ptr<T> cast_parser = boost::dynamic_pointer_cast<T>(parser);
-        // It is common that this cast is not successful because we try to cast to all
-        // supported parser types as we don't know the type of a parser in advance.
-        if (cast_parser) {
-            // Cast, successful so we go ahead with setting storage and actual parse.
-            cast_parser->setStorage(&storage);
-            parser->build(subnet);
-            parsers_.push_back(parser);
-            // We indicate that cast was successful so as the calling function
-            // may skip attempts to cast to other parser types and proceed to
-            // next element.
-            return (true);
-        }
-        // It was not successful. Indicate that another parser type
-        // should be tried.
-        return (false);
-    }
-
     /// @brief Append sub-options to an option.
     ///
     /// @param option_space a name of the encapsulated option space.
@@ -1418,7 +324,7 @@ private:
         try {
             subnet_txt = string_values_.getParam("subnet"); 
         } catch (DhcpConfigError) {
-            // Rethrow with precise error.
+            // rethrow with precise error
             isc_throw(DhcpConfigError,
                       "Mandatory subnet definition in subnet missing");
         }
@@ -1534,24 +440,27 @@ private:
     /// @return parser object for specified entry name
     /// @throw NotImplemented if trying to create a parser for unknown config element
     DhcpConfigParser* createSubnet4ConfigParser(const std::string& config_id) {
-        FactoryMap factories;
-        factories["valid-lifetime"] = Uint32Parser::factory;
-        factories["renew-timer"] = Uint32Parser::factory;
-        factories["rebind-timer"] = Uint32Parser::factory;
-        factories["subnet"] = StringParser::factory;
-        factories["pool"] = PoolParser::factory;
-        factories["option-data"] = OptionDataListParser::factory;
-
-        FactoryMap::iterator f = factories.find(config_id);
-        if (f == factories.end()) {
-            // Used for debugging only.
-            // return new DebugParser(config_id);
-
+        DhcpConfigParser *parser = NULL;
+        if ((config_id.compare("valid-lifetime") == 0)  ||
+            (config_id.compare("renew-timer") == 0)  ||
+            (config_id.compare("rebind-timer") == 0))  {
+            parser = new Uint32Parser(config_id, &uint32_values_);
+        }
+        else if (config_id.compare("subnet") == 0) {
+            parser = new StringParser(config_id, &string_values_);
+        }
+        else if (config_id.compare("pool") == 0) {
+            parser = new PoolParser(config_id, &pools_);
+        }
+        else if (config_id.compare("option-data") == 0) {
+           parser = new OptionDataListParser(config_id, &options_, &option_def_intermediate,
+                                            Dhcp4OptionDataParser::factory);
+        } else {
             isc_throw(NotImplemented,
-                      "parser error: Subnet4 parameter not supported: "
-                      << config_id);
+                "parser error: Subnet4 parameter not supported: " << config_id);
         }
-        return (f->second(config_id));
+
+        return (parser);
     }
 
     /// @brief Returns value for a given parameter (after using inheritance)
@@ -1622,16 +531,11 @@ public:
     ///
     /// @param subnets_list pointer to a list of IPv4 subnets
     void build(ConstElementPtr subnets_list) {
-
-        // No need to define FactoryMap here. There's only one type
-        // used: Subnet4ConfigParser
-
         BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) {
             ParserPtr parser(new Subnet4ConfigParser("subnet"));
             parser->build(subnet);
             subnets_.push_back(parser);
         }
-
     }
 
     /// @brief commits subnets definitions.
@@ -1668,6 +572,34 @@ public:
 namespace isc {
 namespace dhcp {
 
+//************** Dhcp4OptionDataParser methods *******************************
+
+Dhcp4OptionDataParser::Dhcp4OptionDataParser(const std::string& param_name, 
+    OptionStorage *options, OptionDefStorage *option_defs)
+    :OptionDataParser(param_name, options, option_defs, Option::V4) {
+}
+
+OptionDataParser* Dhcp4OptionDataParser::factory(const std::string& param_name,
+    OptionStorage *options, OptionDefStorage *option_defs) {
+    return new Dhcp4OptionDataParser(param_name, options, option_defs);
+}
+
+OptionDefinitionPtr Dhcp4OptionDataParser::findServerSpaceOptionDefinition (
+    std::string& option_space, uint32_t option_code) {
+    OptionDefinitionPtr def;
+
+    if (option_space == "dhcp4" &&
+        LibDHCP::isStandardOption(Option::V4, option_code)) {
+        def = LibDHCP::getOptionDef(Option::V4, option_code);
+
+    } else if (option_space == "dhcp6") {
+        isc_throw(DhcpConfigError, "'dhcp6' option space name is reserved"
+                << " for DHCPv6 server");
+    }
+
+    return def;
+}
+
 /// @brief creates global parsers
 ///
 /// This method creates global parsers that parse global parameters, i.e.
@@ -1677,28 +609,39 @@ namespace dhcp {
 /// @return parser for specified global DHCPv4 parameter
 /// @throw NotImplemented if trying to create a parser for unknown config element
 DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) {
-    FactoryMap factories;
-
-    factories["valid-lifetime"] = Uint32Parser::factory;
-    factories["renew-timer"] = Uint32Parser::factory;
-    factories["rebind-timer"] = Uint32Parser::factory;
-    factories["interface"] = InterfaceListConfigParser::factory;
-    factories["subnet4"] = Subnets4ListConfigParser::factory;
-    factories["option-data"] = OptionDataListParser::factory;
-    factories["option-def"] = OptionDefListParser::factory;
-    factories["version"] = StringParser::factory;
-    factories["lease-database"] = DbAccessParser::factory;
-
-    FactoryMap::iterator f = factories.find(config_id);
-    if (f == factories.end()) {
-        // Used for debugging only.
-        // return new DebugParser(config_id);
-
+    DhcpConfigParser *parser = NULL;
+    if ((config_id.compare("valid-lifetime") == 0)  ||
+        (config_id.compare("renew-timer") == 0)  ||
+        (config_id.compare("rebind-timer") == 0))  {
+        parser = new Uint32Parser(config_id, &uint32_defaults);
+    }
+    else if (config_id.compare("interface") == 0) {
+        parser = new InterfaceListConfigParser(config_id);
+    }
+    else if (config_id.compare("subnet4") == 0) {
+        parser = new Subnets4ListConfigParser(config_id);
+    }
+    else if (config_id.compare("option-data") == 0) {
+        parser = new OptionDataListParser(config_id, &option_defaults, 
+                                          &option_def_intermediate,
+                                          Dhcp4OptionDataParser::factory);
+    }
+    else if (config_id.compare("option-def") == 0) {
+        parser  = new OptionDefListParser(config_id, &option_def_intermediate);
+    }
+    else if (config_id.compare("version") == 0) {
+        parser  = new StringParser(config_id, &string_defaults);
+    }
+    else if (config_id.compare("lease-database") == 0) {
+        parser = new DbAccessParser(config_id); 
+    }
+    else {
         isc_throw(NotImplemented,
-                  "Parser error: Global configuration parameter not supported: "
-                  << config_id);
+                "Parser error: Global configuration parameter not supported: "
+                << config_id);
     }
-    return (f->second(config_id));
+
+    return (parser);
 }
 
 isc::data::ConstElementPtr
@@ -1790,6 +733,7 @@ configureDhcp4Server(Dhcpv4Srv&, ConstElementPtr config_set) {
     } catch (const isc::Exception& ex) {
         LOG_ERROR(dhcp4_logger, DHCP4_PARSER_FAIL)
                   .arg(config_pair.first).arg(ex.what());
+        std::cout << "parse failed on:" << config_pair.first << std::endl;
         answer = isc::config::createAnswer(1,
                      string("Configuration parsing failed: ") + ex.what());
 
@@ -1834,6 +778,13 @@ configureDhcp4Server(Dhcpv4Srv&, ConstElementPtr config_set) {
 
     // Rollback changes as the configuration parsing failed.
     if (rollback) {
+
+    // TKM - take this out, its just here for diagnostics
+    std::cout << "***************" <<  std::endl;
+    std::cout << "answer is:" <<  std::endl;
+    answer->toJSON(std::cout);
+    std::cout << std::endl << "***************" <<  std::endl;
+
         std::swap(uint32_defaults, uint32_local);
         std::swap(string_defaults, string_local);
         std::swap(option_defaults, option_local);
@@ -1854,3 +805,4 @@ const Uint32Storage& getUint32Defaults() {
 
 }; // end of isc::dhcp namespace
 }; // end of isc namespace
+
diff --git a/src/bin/dhcp4/config_parser.h b/src/bin/dhcp4/config_parser.h
index 51a7556..578b637 100644
--- a/src/bin/dhcp4/config_parser.h
+++ b/src/bin/dhcp4/config_parser.h
@@ -12,9 +12,10 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <exceptions/exceptions.h>
-#include <dhcpsrv/dhcp_config_parser.h>
 #include <cc/data.h>
+#include <exceptions/exceptions.h>
+#include <dhcpsrv/dhcp_parsers.h>
+
 #include <stdint.h>
 #include <string>
 
@@ -69,6 +70,49 @@ configureDhcp4Server(Dhcpv4Srv&,
 /// @return a reference to a global uint32 values storage.
 const Uint32Storage& getUint32Defaults();
 
+
+/// @brief Parser for DHCP4 option data value.
+///
+/// This parser parses configuration entries that specify value of
+/// a single option specific to DHCP4.  It provides the DHCP4-specific
+/// implementation of the abstract class OptionDataParser.
+class Dhcp4OptionDataParser : public OptionDataParser {
+public:
+    /// @brief Constructor.
+    ///
+    /// Class constructor.
+    Dhcp4OptionDataParser(const std::string&, OptionStorage *options,
+        OptionDefStorage *option_defs);
+
+    /// @brief static factory method for instantiating Dhcp4OptionDataParsers
+    ///
+    /// @param param_name name fo the parameter to be parsed.
+    /// @param options storage where the parameter value is to be stored.
+    /// @param global_option_defs global option definitions storage 
+    static OptionDataParser* factory(const std::string& param_name, OptionStorage *options,
+        OptionDefStorage *global_option_defs);
+
+protected:
+    /// @brief Finds an option definition within the server's option space
+    /// 
+    /// Given an option space and an option code, find the correpsonding 
+    /// option defintion within the server's option defintion storage.
+    ///
+    /// @param option_space name of the parameter option space 
+    /// @param option_code numeric value of the parameter to find 
+    /// @return OptionDefintionPtr of the option defintion or an 
+    /// empty OptionDefinitionPtr if not found.
+    /// @throw DhcpConfigError if the option space requested is not valid 
+    /// for this server. 
+    virtual OptionDefinitionPtr findServerSpaceOptionDefinition (
+        std::string& option_space, uint32_t option_code);
+
+private:
+    // Private default Constructor declared for safety.
+    Dhcp4OptionDataParser() :OptionDataParser("",NULL,NULL,Option::V4) {}
+};
+
+
 }; // end of isc::dhcp namespace
 }; // end of isc namespace
 
diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc
index e99deeb..8e74607 100644
--- a/src/bin/dhcp6/config_parser.cc
+++ b/src/bin/dhcp6/config_parser.cc
@@ -22,6 +22,7 @@
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/dbaccess_parser.h>
 #include <dhcpsrv/dhcp_config_parser.h>
+#include <dhcpsrv/dhcp_parsers.h>
 #include <dhcpsrv/pool.h>
 #include <dhcpsrv/subnet.h>
 #include <dhcpsrv/triplet.h>
@@ -49,38 +50,17 @@ using namespace isc::asiolink;
 
 namespace {
 
-// Forward declarations of some of the parser classes.
-// They are used to define pointer types for these classes.
-class BooleanParser;
-class StringParser;
-class Uint32Parser;
-
 // Pointers to various parser objects.
 typedef boost::shared_ptr<BooleanParser> BooleanParserPtr;
 typedef boost::shared_ptr<StringParser> StringParserPtr;
 typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr;
 
-/// @brief Factory method that will create a parser for a given element name
-typedef isc::dhcp::DhcpConfigParser* ParserFactory(const std::string& config_id);
-
-/// @brief Collection of factories that create parsers for specified element names
-typedef std::map<std::string, ParserFactory*> FactoryMap;
-
-/// @brief Storage for option definitions.
-typedef OptionSpaceContainer<OptionDefContainer,
-                             OptionDefinitionPtr> OptionDefStorage;
-
 /// @brief Collection of address pools.
 ///
 /// This type is used as intermediate storage, when pools are parsed, but there is
 /// no subnet object created yet to store them.
 typedef std::vector<isc::dhcp::Pool6Ptr> PoolStorage;
 
-/// Collection of containers holding option spaces. Each container within
-/// a particular option space holds so-called option descriptors.
-typedef OptionSpaceContainer<Subnet::OptionContainer,
-                             Subnet::OptionDescriptor> OptionStorage;
-
 /// @brief Global uint32 parameters that will be used as defaults.
 Uint32Storage uint32_defaults;
 
@@ -93,381 +73,6 @@ OptionStorage option_defaults;
 /// @brief Global storage for option definitions.
 OptionDefStorage option_def_intermediate;
 
-/// @brief a dummy configuration parser
-///
-/// This is a debugging parser. It does not configure anything,
-/// will accept any configuration and will just print it out
-/// on commit.  Useful for debugging existing configurations and
-/// adding new ones.
-class DebugParser : public DhcpConfigParser {
-public:
-
-    /// @brief Constructor
-    ///
-    /// See @ref DhcpConfigParser class for details.
-    ///
-    /// @param param_name name of the parsed parameter
-    DebugParser(const std::string& param_name)
-        :param_name_(param_name) {
-    }
-
-    /// @brief builds parameter value
-    ///
-    /// See @ref DhcpConfigParser class for details.
-    ///
-    /// @param new_config pointer to the new configuration
-    virtual void build(ConstElementPtr new_config) {
-        std::cout << "Build for token: [" << param_name_ << "] = ["
-                  << value_->str() << "]" << std::endl;
-        value_ = new_config;
-    }
-
-    /// @brief Pretends to apply the configuration.
-    ///
-    /// This is a method required by the base class. It pretends to apply the
-    /// configuration, but in fact it only prints the parameter out.
-    ///
-    /// See @ref DhcpConfigParser class for details.
-    virtual void commit() {
-        // Debug message. The whole DebugParser class is used only for parser
-        // debugging, and is not used in production code. It is very convenient
-        // to keep it around. Please do not turn this cout into logger calls.
-        std::cout << "Commit for token: [" << param_name_ << "] = ["
-                  << value_->str() << "]" << std::endl;
-    }
-
-    /// @brief factory that constructs DebugParser objects
-    ///
-    /// @param param_name name of the parameter to be parsed
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new DebugParser(param_name));
-    }
-
-private:
-    /// name of the parsed parameter
-    std::string param_name_;
-
-    /// pointer to the actual value of the parameter
-    ConstElementPtr value_;
-};
-
-
-/// @brief A boolean value parser.
-///
-/// This parser handles configuration values of the boolean type.
-/// Parsed values are stored in a provided storage. If no storage
-/// is provided then the build function throws an exception.
-class BooleanParser : public DhcpConfigParser {
-public:
-    /// @brief Constructor.
-    ///
-    /// @param param_name name of the parameter.
-    BooleanParser(const std::string& param_name)
-        : storage_(NULL),
-          param_name_(param_name),
-          value_(false) {
-        // Empty parameter name is invalid.
-        if (param_name_.empty()) {
-            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-    }
-
-    /// @brief Parse a boolean value.
-    ///
-    /// @param value a value to be parsed.
-    ///
-    /// @throw isc::InvalidOperation if a storage has not been set
-    ///        prior to calling this function
-    /// @throw isc::dhcp::DhcpConfigError if a provided parameter's
-    ///        name is empty.
-    virtual void build(ConstElementPtr value) {
-        if (storage_ == NULL) {
-            isc_throw(isc::InvalidOperation, "parser logic error:"
-                      << " storage for the " << param_name_
-                      << " value has not been set");
-        } else if (param_name_.empty()) {
-            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-        // The Config Manager checks if user specified a
-        // valid value for a boolean parameter: True or False.
-        // It is then ok to assume that if str() does not return
-        // 'true' the value is 'false'.
-        value_ = (value->str() == "true") ? true : false;
-    }
-
-    /// @brief Put a parsed value to the storage.
-    virtual void commit() {
-        if (storage_ != NULL && !param_name_.empty()) {
-            storage_->setParam(param_name_, value_);
-        }
-    }
-
-    /// @brief Create an instance of the boolean parser.
-    ///
-    /// @param param_name name of the parameter for which the
-    ///        parser is created.
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new BooleanParser(param_name));
-    }
-
-    /// @brief Set the storage for parsed value.
-    ///
-    /// This function must be called prior to calling build.
-    ///
-    /// @param storage a pointer to the storage where parsed data
-    ///        is to be stored.
-    void setStorage(BooleanStorage* storage) {
-        storage_ = storage;
-    }
-
-private:
-    /// Pointer to the storage where parsed value is stored.
-    BooleanStorage* storage_;
-    /// Name of the parameter which value is parsed with this parser.
-    std::string param_name_;
-    /// Parsed value.
-    bool value_;
-};
-
-/// @brief Configuration parser for uint32 parameters
-///
-/// This class is a generic parser that is able to handle any uint32 integer
-/// type. By default it stores the value in external global container
-/// (uint32_defaults). If used in smaller scopes (e.g. to parse parameters
-/// in subnet config), it can be pointed to a different storage, using
-/// setStorage() method. This class follows the parser interface, laid out
-/// in its base class, @ref DhcpConfigParser.
-///
-/// For overview of usability of this generic purpose parser, see
-/// @ref dhcpv6ConfigInherit page.
-///
-/// @todo this class should be turned into the template class which
-/// will handle all uintX_types of data (see ticket #2415).
-class Uint32Parser : public DhcpConfigParser {
-public:
-
-    /// @brief constructor for Uint32Parser
-    ///
-    /// @param param_name name of the configuration parameter being parsed
-    Uint32Parser(const std::string& param_name)
-        : storage_(&uint32_defaults),
-          param_name_(param_name) {
-        // Empty parameter name is invalid.
-        if (param_name_.empty()) {
-            isc_throw(DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-    }
-
-    /// @brief Parses configuration configuration parameter as uint32_t.
-    ///
-    /// @param value pointer to the content of parsed values
-    /// @throw isc::dhcp::DhcpConfigError if failed to parse
-    ///        the configuration parameter as uint32_t value.
-    virtual void build(ConstElementPtr value) {
-        if (param_name_.empty()) {
-            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-
-        bool parse_error = false;
-        // Cast the provided value to int64 value to check.
-        int64_t int64value = 0;
-        try {
-            // Parsing the value as a int64 value allows to
-            // check if the provided value is within the range
-            // of uint32_t (is not negative or greater than
-            // maximal uint32_t value).
-            int64value = boost::lexical_cast<int64_t>(value->str());
-        } catch (const boost::bad_lexical_cast&) {
-            parse_error = true;
-        }
-        if (!parse_error) {
-            // Check that the value is not out of bounds.
-            if ((int64value < 0) ||
-                (int64value > std::numeric_limits<uint32_t>::max())) {
-                parse_error = true;
-            } else {
-                // A value is not out of bounds so let's cast it to
-                // the uint32_t type.
-                value_ = static_cast<uint32_t>(int64value);
-            }
-
-        }
-        // Invalid value provided.
-        if (parse_error) {
-            isc_throw(isc::dhcp::DhcpConfigError, "Failed to parse value " << value->str()
-                      << " as unsigned 32-bit integer.");
-        }
-    }
-
-    /// @brief Stores the parsed uint32_t value in a storage.
-    virtual void commit() {
-        if (storage_ != NULL) {
-            // If a given parameter already exists in the storage we override
-            // its value. If it doesn't we insert a new element.
-            storage_->setParam(param_name_, value_);
-        }
-    }
-
-    /// @brief Factory that constructs Uint32Parser objects.
-    ///
-    /// @param param_name name of the parameter to be parsed.
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new Uint32Parser(param_name));
-    }
-
-    /// @brief Sets storage for value of this parameter.
-    ///
-    /// See @ref dhcpv6ConfigInherit for details.
-    ///
-    /// @param storage pointer to the storage container.
-    void setStorage(Uint32Storage* storage) {
-        storage_ = storage;
-    }
-
-private:
-    /// pointer to the storage, where parsed value will be stored
-    Uint32Storage* storage_;
-    /// name of the parameter to be parsed
-    std::string param_name_;
-    /// the actual parsed value
-    uint32_t value_;
-};
-
-/// @brief Configuration parser for string parameters
-///
-/// This class is a generic parser that is able to handle any string
-/// parameter. By default it stores the value in an external global container
-/// (string_defaults). If used in smaller scopes (e.g. to parse parameters
-/// in subnet config), it can be pointed to a different storage, using the
-/// setStorage() method. This class follows the parser interface, laid out
-/// in its base class, @ref DhcpConfigParser.
-///
-/// For overview of usability of this generic purpose parser, see
-/// @ref dhcpv6ConfigInherit page.
-class StringParser : public DhcpConfigParser {
-public:
-
-    /// @brief constructor for StringParser
-    ///
-    /// @param param_name name of the configuration parameter being parsed
-    StringParser(const std::string& param_name)
-        : storage_(&string_defaults),
-          param_name_(param_name) {
-        // Empty parameter name is invalid.
-        if (param_name_.empty()) {
-            isc_throw(DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-    }
-
-    /// @brief parses parameter value
-    ///
-    /// Parses configuration parameter's value as string.
-    ///
-    /// @param value pointer to the content of parsed values
-    /// @throws DhcpConfigError if the parsed parameter's name is empty.
-    virtual void build(ConstElementPtr value) {
-        if (param_name_.empty()) {
-            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
-                      << "empty parameter name provided");
-        }
-        value_ = value->str();
-        boost::erase_all(value_, "\"");
-    }
-
-    /// @brief Stores the parsed value in a storage.
-    virtual void commit() {
-        if (storage_ != NULL && !param_name_.empty()) {
-            // If a given parameter already exists in the storage we override
-            // its value. If it doesn't we insert a new element.
-            storage_->setParam(param_name_, value_);
-        }
-    }
-
-    /// @brief Factory that constructs StringParser objects
-    ///
-    /// @param param_name name of the parameter to be parsed
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new StringParser(param_name));
-    }
-
-    /// @brief Sets storage for value of this parameter.
-    ///
-    /// See @ref dhcpv6ConfigInherit for details.
-    ///
-    /// @param storage pointer to the storage container
-    void setStorage(StringStorage* storage) {
-        storage_ = storage;
-    }
-
-private:
-    /// Pointer to the storage, where parsed value will be stored
-    StringStorage* storage_;
-    /// Name of the parameter to be parsed
-    std::string param_name_;
-    /// The actual parsed value
-    std::string value_;
-};
-
-/// @brief parser for interface list definition
-///
-/// This parser handles Dhcp6/interface entry.
-/// It contains a list of network interfaces that the server listens on.
-/// In particular, it can contain an entry called "all" or "any" that
-/// designates all interfaces.
-///
-/// It is useful for parsing Dhcp6/interface parameter.
-class InterfaceListConfigParser : public DhcpConfigParser {
-public:
-
-    /// @brief constructor
-    ///
-    /// As this is a dedicated parser, it must be used to parse
-    /// "interface" parameter only. All other types will throw exception.
-    ///
-    /// @param param_name name of the configuration parameter being parsed
-    /// @throw BadValue if supplied parameter name is not "interface"
-    InterfaceListConfigParser(const std::string& param_name) {
-        if (param_name != "interface") {
-            isc_throw(isc::BadValue, "Internal error. Interface configuration "
-                      "parser called for the wrong parameter: " << param_name);
-        }
-    }
-
-    /// @brief parses parameters value
-    ///
-    /// Parses configuration entry (list of parameters) and stores it in
-    /// storage.
-    ///
-    /// @param value pointer to the content of parsed values
-    virtual void build(ConstElementPtr value) {
-        BOOST_FOREACH(ConstElementPtr iface, value->listValue()) {
-            interfaces_.push_back(iface->str());
-        }
-    }
-
-    /// @brief commits interfaces list configuration
-    virtual void commit() {
-        /// @todo: Implement per interface listening. Currently always listening
-        /// on all interfaces.
-    }
-
-    /// @brief factory that constructs InterfaceListConfigParser objects
-    ///
-    /// @param param_name name of the parameter to be parsed
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new InterfaceListConfigParser(param_name));
-    }
-
-private:
-    /// contains list of network interfaces
-    vector<string> interfaces_;
-};
-
 /// @brief parser for pool definition
 ///
 /// This parser handles pool definitions, i.e. a list of entries of one
@@ -487,6 +92,12 @@ public:
         // ignore parameter name, it is always Dhcp6/subnet6[X]/pool
     }
 
+    /// @brief constructor.
+    PoolParser(const std::string& /*param_name*/,  PoolStorage* pools)
+        :pools_(pools) {
+        // ignore parameter name, it is always Dhcp6/subnet6[X]/pool
+    }
+
     /// @brief parses the actual list
     ///
     /// This method parses the actual list of interfaces.
@@ -602,674 +213,6 @@ private:
     PoolStorage local_pools_;
 };
 
-
-/// @brief Parser for option data value.
-///
-/// This parser parses configuration entries that specify value of
-/// a single option. These entries include option name, option code
-/// and data carried by the option. The option data can be specified
-/// in one of the two available formats: binary value represented as
-/// a string of hexadecimal digits or a list of comma separated values.
-/// The format being used is controlled by csv-format configuration
-/// parameter. When setting this value to True, the latter format is
-/// used. The subsequent values in the CSV format apply to relevant
-/// option data fields in the configured option. For example the
-/// configuration: "data" : "192.168.2.0, 56, hello world" can be
-/// used to set values for the option comprising IPv4 address,
-/// integer and string data field. Note that order matters. If the
-/// order of values does not match the order of data fields within
-/// an option the configuration will not be accepted. If parsing
-/// is successful then an instance of an option is created and
-/// added to the storage provided by the calling class.
-class OptionDataParser : public DhcpConfigParser {
-public:
-
-    /// @brief Constructor.
-    ///
-    /// Class constructor.
-    OptionDataParser(const std::string&)
-        : options_(NULL),
-          // initialize option to NULL ptr
-          option_descriptor_(false) { }
-
-    /// @brief Parses the single option data.
-    ///
-    /// This method parses the data of a single option from the configuration.
-    /// The option data includes option name, option code and data being
-    /// carried by this option. Eventually it creates the instance of the
-    /// option.
-    ///
-    /// @warning setStorage must be called with valid storage pointer prior
-    /// to calling this method.
-    ///
-    /// @param option_data_entries collection of entries that define value
-    /// for a particular option.
-    /// @throw DhcpConfigError if invalid parameter specified in
-    /// the configuration.
-    /// @throw isc::InvalidOperation if failed to set storage prior to
-    /// calling build.
-    virtual void build(ConstElementPtr option_data_entries) {
-
-        if (options_ == NULL) {
-            isc_throw(isc::InvalidOperation, "Parser logic error: storage must be set before "
-                      "parsing option data.");
-        }
-        BOOST_FOREACH(ConfigPair param, option_data_entries->mapValue()) {
-            ParserPtr parser;
-            if (param.first == "name" || param.first == "data" ||
-                param.first == "space") {
-                boost::shared_ptr<StringParser>
-                    name_parser(dynamic_cast<StringParser*>(StringParser::factory(param.first)));
-                if (name_parser) {
-                    name_parser->setStorage(&string_values_);
-                    parser = name_parser;
-                }
-            } else if (param.first == "code") {
-                boost::shared_ptr<Uint32Parser>
-                    code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::factory(param.first)));
-                if (code_parser) {
-                    code_parser->setStorage(&uint32_values_);
-                    parser = code_parser;
-                }
-            } else if (param.first == "csv-format") {
-                boost::shared_ptr<BooleanParser>
-                    value_parser(dynamic_cast<BooleanParser*>(BooleanParser::factory(param.first)));
-                if (value_parser) {
-                    value_parser->setStorage(&boolean_values_);
-                    parser = value_parser;
-                }
-            } else {
-                isc_throw(DhcpConfigError,
-                          "parser error: option-data parameter not supported: "
-                          << param.first);
-            }
-            parser->build(param.second);
-            // Before we can create an option we need to get the data from
-            // the child parsers. The only way to do it is to invoke commit
-            // on them so as they store the values in appropriate storages
-            // that this class provided to them. Note that this will not
-            // modify values stored in the global storages so the configuration
-            // will remain consistent even parsing fails somewhere further on.
-            parser->commit();
-        }
-        // Try to create the option instance.
-        createOption();
-    }
-
-    /// @brief Commits option value.
-    ///
-    /// This function adds a new option to the storage or replaces an existing option
-    /// with the same code.
-    ///
-    /// @throw isc::InvalidOperation if failed to set pointer to storage or failed
-    /// to call build() prior to commit. If that happens data in the storage
-    /// remain un-modified.
-    virtual void commit() {
-        if (options_ == NULL) {
-            isc_throw(isc::InvalidOperation, "parser logic error: storage must be set before "
-                      "committing option data.");
-        } else  if (!option_descriptor_.option) {
-            // Before we can commit the new option should be configured. If it is not
-            // than somebody must have called commit() before build().
-            isc_throw(isc::InvalidOperation, "parser logic error: no option has been configured and"
-                      " thus there is nothing to commit. Has build() been called?");
-        }
-        uint16_t opt_type = option_descriptor_.option->getType();
-        Subnet::OptionContainerPtr options = options_->getItems(option_space_);
-        // The getItems() should never return NULL pointer. If there are no
-        // options configured for the particular option space a pointer
-        // to an empty container should be returned.
-        assert(options);
-        Subnet::OptionContainerTypeIndex& idx = options->get<1>();
-        // Try to find options with the particular option code in the main
-        // storage. If found, remove these options because they will be
-        // replaced with new one.
-        Subnet::OptionContainerTypeRange range =
-            idx.equal_range(opt_type);
-        if (std::distance(range.first, range.second) > 0) {
-            idx.erase(range.first, range.second);
-        }
-        // Append new option to the main storage.
-        options_->addItem(option_descriptor_, option_space_);
-    }
-
-    /// @brief Set storage for the parser.
-    ///
-    /// Sets storage for the parser. This storage points to the
-    /// vector of options and is used by multiple instances of
-    /// OptionDataParser. Each instance creates exactly one object
-    /// of dhcp::Option or derived type and appends it to this
-    /// storage.
-    ///
-    /// @param storage pointer to the options storage
-    void setStorage(OptionStorage* storage) {
-        options_ = storage;
-    }
-
-private:
-
-    /// @brief Create option instance.
-    ///
-    /// Creates an instance of an option and adds it to the provided
-    /// options storage. If the option data parsed by \ref build function
-    /// are invalid or insufficient this function emits an exception.
-    ///
-    /// @warning this function does not check if options_ storage pointer
-    /// is intitialized but this check is not needed here because it is done
-    /// in the \ref build function.
-    ///
-    /// @throw DhcpConfigError if parameters provided in the configuration
-    /// are invalid.
-    void createOption() {
-
-        // Option code is held in the uint32_t storage but is supposed to
-        // be uint16_t value. We need to check that value in the configuration
-        // does not exceed range of uint16_t and is not zero.
-        uint32_t option_code = uint32_values_.getParam("code");
-        if (option_code == 0) {
-            isc_throw(DhcpConfigError, "option code must not be zero."
-                      << " Option code '0' is reserved in DHCPv6.");
-        } else if (option_code > std::numeric_limits<uint16_t>::max()) {
-            isc_throw(DhcpConfigError, "invalid option code '" << option_code
-                      << "', it must not exceed '"
-                      << std::numeric_limits<uint16_t>::max() << "'");
-        }
-        // Check that the option name has been specified, is non-empty and does not
-        // contain spaces.
-        std::string option_name = string_values_.getParam("name");
-        if (option_name.empty()) {
-            isc_throw(DhcpConfigError, "name of the option with code '"
-                      << option_code << "' is empty");
-        } else if (option_name.find(" ") != std::string::npos) {
-            isc_throw(DhcpConfigError, "invalid option name '" << option_name
-                      << "', space character is not allowed");
-        }
-
-        std::string option_space = string_values_.getParam("space");
-        if (!OptionSpace::validateName(option_space)) {
-            isc_throw(DhcpConfigError, "invalid option space name '"
-                      << option_space << "' specified for option '"
-                      << option_name << "' (code '" << option_code
-                      << "')");
-        }
-
-        OptionDefinitionPtr def;
-        if (option_space == "dhcp6" &&
-            LibDHCP::isStandardOption(Option::V6, option_code)) {
-            def = LibDHCP::getOptionDef(Option::V6, option_code);
-
-        } else if (option_space == "dhcp4") {
-            isc_throw(DhcpConfigError, "'dhcp4' option space name is reserved"
-                      << " for DHCPv4 server");
-        } else {
-            // If we are not dealing with a standard option then we
-            // need to search for its definition among user-configured
-            // options. They are expected to be in the global storage
-            // already.
-            OptionDefContainerPtr defs = option_def_intermediate.getItems(option_space);
-            // The getItems() should never return the NULL pointer. If there are
-            // no option definitions for the particular option space a pointer
-            // to an empty container should be returned.
-            assert(defs);
-            const OptionDefContainerTypeIndex& idx = defs->get<1>();
-            OptionDefContainerTypeRange range = idx.equal_range(option_code);
-            if (std::distance(range.first, range.second) > 0) {
-                def = *range.first;
-            }
-            if (!def) {
-                isc_throw(DhcpConfigError, "definition for the option '"
-                          << option_space << "." << option_name
-                          << "' having code '" <<  option_code
-                          << "' does not exist");
-            }
-
-        }
-
-        // Get option data from the configuration database ('data' field).
-        const std::string option_data = string_values_.getParam("data");
-        const bool csv_format = boolean_values_.getParam("csv-format");
-
-        // Transform string of hexadecimal digits into binary format.
-        std::vector<uint8_t> binary;
-        std::vector<std::string> data_tokens;
-
-        if (csv_format) {
-            // If the option data is specified as a string of comma
-            // separated values then we need to split this string into
-            // individual values - each value will be used to initialize
-            // one data field of an option.
-            data_tokens = isc::util::str::tokens(option_data, ",");
-        } else {
-            // Otherwise, the option data is specified as a string of
-            // hexadecimal digits that we have to turn into binary format.
-            try {
-                util::encode::decodeHex(option_data, binary);
-            } catch (...) {
-                isc_throw(DhcpConfigError, "Parser error: option data is not a valid"
-                          << " string of hexadecimal digits: " << option_data);
-            }
-        }
-
-        OptionPtr option;
-        if (!def) {
-            if (csv_format) {
-                isc_throw(DhcpConfigError, "the CSV option data format can be"
-                          " used to specify values for an option that has a"
-                          " definition. The option with code " << option_code
-                          << " does not have a definition.");
-            }
-
-            // @todo We have a limited set of option definitions intiialized at the moment.
-            // In the future we want to initialize option definitions for all options.
-            // Consequently an error will be issued if an option definition does not exist
-            // for a particular option code. For now it is ok to create generic option
-            // if definition does not exist.
-            OptionPtr option(new Option(Option::V6, static_cast<uint16_t>(option_code),
-                                        binary));
-            // The created option is stored in option_descriptor_ class member until the
-            // commit stage when it is inserted into the main storage. If an option with the
-            // same code exists in main storage already the old option is replaced.
-            option_descriptor_.option = option;
-            option_descriptor_.persistent = false;
-        } else {
-
-            // Option name should match the definition. The option name
-            // may seem to be redundant but in the future we may want
-            // to reference options and definitions using their names
-            // and/or option codes so keeping the option name in the
-            // definition of option value makes sense.
-            if (def->getName() != option_name) {
-                isc_throw(DhcpConfigError, "specified option name '"
-                          << option_name << "' does not match the "
-                          << "option definition: '" << option_space
-                          << "." << def->getName() << "'");
-            }
-
-            // Option definition has been found so let's use it to create
-            // an instance of our option.
-            try {
-                OptionPtr option = csv_format ?
-                    def->optionFactory(Option::V6, option_code, data_tokens) :
-                    def->optionFactory(Option::V6, option_code, binary);
-                Subnet::OptionDescriptor desc(option, false);
-                option_descriptor_.option = option;
-                option_descriptor_.persistent = false;
-            } catch (const isc::Exception& ex) {
-                isc_throw(DhcpConfigError, "option data does not match"
-                          << " option definition (space: " << option_space
-                          << ", code: " << option_code << "): "
-                          << ex.what());
-            }
-        }
-        // All went good, so we can set the option space name.
-        option_space_ = option_space;
-    }
-
-    /// Storage for uint32 values (e.g. option code).
-    Uint32Storage uint32_values_;
-    /// Storage for string values (e.g. option name or data).
-    StringStorage string_values_;
-    /// Storage for boolean values.
-    BooleanStorage boolean_values_;
-    /// Pointer to options storage. This storage is provided by
-    /// the calling class and is shared by all OptionDataParser objects.
-    OptionStorage* options_;
-    /// Option descriptor holds newly configured option.
-    isc::dhcp::Subnet::OptionDescriptor option_descriptor_;
-    /// Option space name where the option belongs to.
-    std::string option_space_;
-};
-
-/// @brief Parser for option data values within a subnet.
-///
-/// This parser iterates over all entries that define options
-/// data for a particular subnet and creates a collection of options.
-/// If parsing is successful, all these options are added to the Subnet
-/// object.
-class OptionDataListParser : public DhcpConfigParser {
-public:
-
-    /// @brief Constructor.
-    ///
-    /// Unless otherwise specified, parsed options will be stored in
-    /// a global option container (option_default). That storage location
-    /// is overriden on a subnet basis.
-    OptionDataListParser(const std::string&)
-        : options_(&option_defaults), local_options_() { }
-
-    /// @brief Parses entries that define options' data for a subnet.
-    ///
-    /// This method iterates over all entries that define option data
-    /// for options within a single subnet and creates options' instances.
-    ///
-    /// @param option_data_list pointer to a list of options' data sets.
-    /// @throw DhcpConfigError if option parsing failed.
-    void build(ConstElementPtr option_data_list) {
-        BOOST_FOREACH(ConstElementPtr option_value, option_data_list->listValue()) {
-            boost::shared_ptr<OptionDataParser> parser(new OptionDataParser("option-data"));
-            // options_ member will hold instances of all options thus
-            // each OptionDataParser takes it as a storage.
-            parser->setStorage(&local_options_);
-            // Build the instance of a single option.
-            parser->build(option_value);
-            // Store a parser as it will be used to commit.
-            parsers_.push_back(parser);
-        }
-    }
-
-    /// @brief Set storage for option instances.
-    ///
-    /// @param storage pointer to options storage.
-    void setStorage(OptionStorage* storage) {
-        options_ = storage;
-    }
-
-
-    /// @brief Commit all option values.
-    ///
-    /// This function invokes commit for all option values.
-    void commit() {
-        BOOST_FOREACH(ParserPtr parser, parsers_) {
-            parser->commit();
-        }
-        // Parsing was successful and we have all configured
-        // options in local storage. We can now replace old values
-        // with new values.
-        std::swap(local_options_, *options_);
-    }
-
-    /// @brief Create DhcpDataListParser object
-    ///
-    /// @param param_name param name.
-    ///
-    /// @return DhcpConfigParser object.
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new OptionDataListParser(param_name));
-    }
-
-    /// Pointer to options instances storage.
-    OptionStorage* options_;
-    /// Intermediate option storage. This storage is used by
-    /// lower level parsers to add new options.  Values held
-    /// in this storage are assigned to main storage (options_)
-    /// if overall parsing was successful.
-    OptionStorage local_options_;
-    /// Collection of parsers;
-    ParserCollection parsers_;
-};
-
-/// @brief Parser for a single option definition.
-///
-/// This parser creates an instance of a single option definition.
-class OptionDefParser: DhcpConfigParser {
-public:
-
-    /// @brief Constructor.
-    ///
-    /// This constructor sets the pointer to the option definitions
-    /// storage to NULL. It must be set to point to the actual storage
-    /// before \ref build is called.
-    OptionDefParser(const std::string&)
-        : storage_(NULL) {
-    }
-
-    /// @brief Parses an entry that describes single option definition.
-    ///
-    /// @param option_def a configuration entry to be parsed.
-    ///
-    /// @throw DhcpConfigError if parsing was unsuccessful.
-    void build(ConstElementPtr option_def) {
-        if (storage_ == NULL) {
-            isc_throw(DhcpConfigError, "parser logic error: storage must be set"
-                      " before parsing option definition data");
-        }
-        // Parse the elements that make up the option definition.
-        BOOST_FOREACH(ConfigPair param, option_def->mapValue()) {
-            std::string entry(param.first);
-            ParserPtr parser;
-            if (entry == "name" || entry == "type" || entry == "record-types" ||
-                entry == "space" || entry == "encapsulate") {
-                StringParserPtr
-                    str_parser(dynamic_cast<StringParser*>(StringParser::factory(entry)));
-                if (str_parser) {
-                    str_parser->setStorage(&string_values_);
-                    parser = str_parser;
-                }
-            } else if (entry == "code") {
-                Uint32ParserPtr
-                    code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::factory(entry)));
-                if (code_parser) {
-                    code_parser->setStorage(&uint32_values_);
-                    parser = code_parser;
-                }
-            } else if (entry == "array") {
-                BooleanParserPtr
-                    array_parser(dynamic_cast<BooleanParser*>(BooleanParser::factory(entry)));
-                if (array_parser) {
-                    array_parser->setStorage(&boolean_values_);
-                    parser = array_parser;
-                }
-            } else {
-                isc_throw(DhcpConfigError, "invalid parameter: " << entry);
-            }
-
-            parser->build(param.second);
-            parser->commit();
-        }
-
-        // Create an instance of option definition.
-        createOptionDef();
-
-        // Get all items we collected so far for the particular option space.
-        OptionDefContainerPtr defs = storage_->getItems(option_space_name_);
-        // Check if there are any items with option code the same as the
-        // one specified for the definition we are now creating.
-        const OptionDefContainerTypeIndex& idx = defs->get<1>();
-        const OptionDefContainerTypeRange& range =
-            idx.equal_range(option_definition_->getCode());
-        // If there are any items with this option code already we need
-        // to issue an error because we don't allow duplicates for
-        // option definitions within an option space.
-        if (std::distance(range.first, range.second) > 0) {
-            isc_throw(DhcpConfigError, "duplicated option definition for"
-                      << " code '" << option_definition_->getCode() << "'");
-        }
-    }
-
-    /// @brief Stores the parsed option definition in the data store.
-    void commit() {
-        if (storage_ && option_definition_ &&
-            OptionSpace::validateName(option_space_name_)) {
-            storage_->addItem(option_definition_, option_space_name_);
-        }
-    }
-
-    /// @brief Sets a pointer to the data store.
-    ///
-    /// The newly created instance of an option definition will be
-    /// added to the data store given by the argument.
-    ///
-    /// @param storage pointer to the data store where the option definition
-    /// will be added to.
-    void setStorage(OptionDefStorage* storage) {
-        storage_ = storage;
-    }
-
-private:
-
-    /// @brief Create option definition from the parsed parameters.
-    void createOptionDef() {
-        // Get the option space name and validate it.
-        std::string space = string_values_.getParam("space");
-        if (!OptionSpace::validateName(space)) {
-            isc_throw(DhcpConfigError, "invalid option space name '"
-                      << space << "'");
-        }
-
-        // Get other parameters that are needed to create the
-        // option definition.
-        std::string name = string_values_.getParam("name");
-        uint32_t code = uint32_values_.getParam("code");
-        std::string type = string_values_.getParam("type");
-        bool array_type = boolean_values_.getParam("array");
-        std::string encapsulates = string_values_.getParam("encapsulate");
-
-        // Create option definition.
-        OptionDefinitionPtr def;
-        // We need to check if user has set encapsulated option space
-        // name. If so, different constructor will be used.
-        if (!encapsulates.empty()) {
-            // Arrays can't be used together with sub-options.
-            if (array_type) {
-                isc_throw(DhcpConfigError, "option '" << space << "."
-                          << "name" << "', comprising an array of data"
-                          << " fields may not encapsulate any option space");
-
-            } else if (encapsulates == space) {
-                isc_throw(DhcpConfigError, "option must not encapsulate"
-                          << " an option space it belongs to: '"
-                          << space << "." << name << "' is set to"
-                          << " encapsulate '" << space << "'");
-
-            } else {
-                def.reset(new OptionDefinition(name, code, type,
-                                               encapsulates.c_str()));
-            }
-
-        } else {
-            def.reset(new OptionDefinition(name, code, type, array_type));
-
-        }
-
-        // The record-types field may carry a list of comma separated names
-        // of data types that form a record.
-        std::string record_types = string_values_.getParam("record-types");
-        // Split the list of record types into tokens.
-        std::vector<std::string> record_tokens =
-            isc::util::str::tokens(record_types, ",");
-        // Iterate over each token and add a record type into
-        // option definition.
-        BOOST_FOREACH(std::string record_type, record_tokens) {
-            try {
-                boost::trim(record_type);
-                if (!record_type.empty()) {
-                    def->addRecordField(record_type);
-                }
-            } catch (const Exception& ex) {
-                isc_throw(DhcpConfigError, "invalid record type values"
-                          << " specified for the option definition: "
-                          << ex.what());
-            }
-        }
-
-        // Check the option definition parameters are valid.
-        try {
-            def->validate();
-        } catch (const isc::Exception& ex) {
-            isc_throw(DhcpConfigError, "invalid option definition"
-                      << " parameters: " << ex.what());
-        }
-        // Option definition has been created successfully.
-        option_space_name_ = space;
-        option_definition_ = def;
-    }
-
-    /// Instance of option definition being created by this parser.
-    OptionDefinitionPtr option_definition_;
-    /// Name of the space the option definition belongs to.
-    std::string option_space_name_;
-
-    /// Pointer to a storage where the option definition will be
-    /// added when \ref commit is called.
-    OptionDefStorage* storage_;
-
-    /// Storage for boolean values.
-    BooleanStorage boolean_values_;
-    /// Storage for string values.
-    StringStorage string_values_;
-    /// Storage for uint32 values.
-    Uint32Storage uint32_values_;
-};
-
-/// @brief Parser for a list of option definitions.
-///
-/// This parser iterates over all configuration entries that define
-/// option definitions and creates instances of these definitions.
-/// If the parsing is successful, the collection of created definitions
-/// is put into the provided storage.
-class OptionDefListParser : DhcpConfigParser {
-public:
-
-    /// @brief Constructor.
-    ///
-    /// This constructor initializes the pointer to option definitions
-    /// storage to NULL value. This pointer has to be set to point to
-    /// the actual storage before the \ref build function is called.
-    OptionDefListParser(const std::string&) {
-    }
-
-    /// @brief Parse configuration entries.
-    ///
-    /// This function parses configuration entries and creates instances
-    /// of option definitions.
-    ///
-    /// @param option_def_list pointer to an element that holds entries
-    /// that define option definitions.
-    /// @throw DhcpConfigError if configuration parsing fails.
-    void build(ConstElementPtr option_def_list) {
-        // Clear existing items in the global storage.
-        // We are going to replace all of them.
-        option_def_intermediate.clearItems();
-
-        if (!option_def_list) {
-            isc_throw(DhcpConfigError, "parser error: a pointer to a list of"
-                      << " option definitions is NULL");
-        }
-
-        BOOST_FOREACH(ConstElementPtr option_def, option_def_list->listValue()) {
-            boost::shared_ptr<OptionDefParser>
-                parser(new OptionDefParser("single-option-def"));
-            parser->setStorage(&option_def_intermediate);
-            parser->build(option_def);
-            parser->commit();
-        }
-    }
-
-    /// @brief Stores option definitions in the CfgMgr.
-    void commit() {
-
-        CfgMgr& cfg_mgr = CfgMgr::instance();
-
-        cfg_mgr.deleteOptionDefs();
-
-        // We need to move option definitions from the temporary
-        // storage to the global storage.
-        std::list<std::string> space_names =
-            option_def_intermediate.getOptionSpaceNames();
-        BOOST_FOREACH(std::string space_name, space_names) {
-
-            BOOST_FOREACH(OptionDefinitionPtr def,
-                          *option_def_intermediate.getItems(space_name)) {
-                // All option definitions should be initialized to non-NULL
-                // values. The validation is expected to be made by the
-                // OptionDefParser when creating an option definition.
-                assert(def);
-                cfg_mgr.addOptionDef(def, space_name);
-            }
-        }
-    }
-
-    /// @brief Create an OptionDefListParser object.
-    ///
-    /// @param param_name configuration entry holding option definitions.
-    ///
-    /// @return OptionDefListParser object.
-    static DhcpConfigParser* factory(const std::string& param_name) {
-        return (new OptionDefListParser(param_name));
-    }
-
-};
-
 /// @brief this class parses a single subnet
 ///
 /// This class parses the whole subnet definition. It creates parsers
@@ -1292,29 +235,8 @@ public:
 
         BOOST_FOREACH(ConfigPair param, subnet->mapValue()) {
             ParserPtr parser(createSubnet6ConfigParser(param.first));
-            // The actual type of the parser is unknown here. We have to discover
-            // the parser type here to invoke the corresponding setStorage function
-            // on it.  We discover parser type by trying to cast the parser to various
-            // parser types and checking which one was successful. For this one
-            // a setStorage and build methods are invoked.
-
-            // Try uint32 type parser.
-            if (!buildParser<Uint32Parser, Uint32Storage >(parser, uint32_values_,
-                                                           param.second) &&
-                // Try string type parser.
-                !buildParser<StringParser, StringStorage >(parser, string_values_,
-                                                           param.second) &&
-                // Try pool parser.
-                !buildParser<PoolParser, PoolStorage >(parser, pools_,
-                                                       param.second) &&
-                // Try option data parser.
-                !buildParser<OptionDataListParser, OptionStorage >(parser, options_,
-                                                                   param.second)) {
-                // Appropriate parsers are created in the createSubnet6ConfigParser
-                // and they should be limited to those that we check here for. Thus,
-                // if we fail to find a matching parser here it is a programming error.
-                isc_throw(DhcpConfigError, "failed to find suitable parser");
-            }
+            parser->build(param.second);
+            parsers_.push_back(parser);
         }
 
         // In order to create new subnet we need to get the data out
@@ -1342,40 +264,6 @@ public:
 
 private:
 
-    /// @brief Set storage for a parser and invoke build.
-    ///
-    /// This helper method casts the provided parser pointer to the specified
-    /// type. If the cast is successful it sets the corresponding storage for
-    /// this parser, invokes build on it and saves the parser.
-    ///
-    /// @tparam T parser type to which parser argument should be cast.
-    /// @tparam Y storage type for the specified parser type.
-    /// @param parser parser on which build must be invoked.
-    /// @param storage reference to a storage that will be set for a parser.
-    /// @param subnet subnet element read from the configuration and being parsed.
-    /// @return true if parser pointer was successfully cast to specialized
-    /// parser type provided as Y.
-    template<typename T, typename Y>
-    bool buildParser(const ParserPtr& parser, Y& storage, const ConstElementPtr& subnet) {
-        // We need to cast to T in order to set storage for the parser.
-        boost::shared_ptr<T> cast_parser = boost::dynamic_pointer_cast<T>(parser);
-        // It is common that this cast is not successful because we try to cast to all
-        // supported parser types as we don't know the type of a parser in advance.
-        if (cast_parser) {
-            // Cast, successful so we go ahead with setting storage and actual parse.
-            cast_parser->setStorage(&storage);
-            parser->build(subnet);
-            parsers_.push_back(parser);
-            // We indicate that cast was successful so as the calling function
-            // may skip attempts to cast to other parser types and proceed to
-            // next element.
-            return (true);
-        }
-        // It was not successful. Indicate that another parser type
-        // should be tried.
-        return (false);
-    }
-
     /// @brief Append sub-options to an option.
     ///
     /// @param option_space a name of the encapsulated option space.
@@ -1581,27 +469,30 @@ private:
     /// @throw isc::dhcp::DhcpConfigError if trying to create a parser
     ///        for unknown config element
     DhcpConfigParser* createSubnet6ConfigParser(const std::string& config_id) {
-        FactoryMap factories;
-
-        factories["preferred-lifetime"] = Uint32Parser::factory;
-        factories["valid-lifetime"] = Uint32Parser::factory;
-        factories["renew-timer"] = Uint32Parser::factory;
-        factories["rebind-timer"] = Uint32Parser::factory;
-        factories["subnet"] = StringParser::factory;
-        factories["pool"] = PoolParser::factory;
-        factories["option-data"] = OptionDataListParser::factory;
-        factories["interface"] = StringParser::factory;
-
-        FactoryMap::iterator f = factories.find(config_id);
-        if (f == factories.end()) {
-            // Used for debugging only.
-            // return new DebugParser(config_id);
-
-            isc_throw(isc::dhcp::DhcpConfigError,
-                      "parser error: subnet6 parameter not supported: "
-                      << config_id);
+        DhcpConfigParser *parser = NULL;
+        if ((config_id.compare("preferred-lifetime") == 0)  ||
+            (config_id.compare("valid-lifetime") == 0)  ||
+            (config_id.compare("renew-timer") == 0)  ||
+            (config_id.compare("rebind-timer") == 0))  {
+            parser = new Uint32Parser(config_id, &uint32_values_);
+        }
+        else if ((config_id.compare("subnet") == 0) ||
+                 (config_id.compare("interface") == 0)) {
+            parser = new StringParser(config_id, &string_values_);
+        }
+        else if (config_id.compare("pool") == 0) {
+            parser = new PoolParser(config_id, &pools_);
+        }
+        else if (config_id.compare("option-data") == 0) {
+           parser = new OptionDataListParser(config_id, &options_, 
+                                             &option_def_intermediate,
+                                             Dhcp6OptionDataParser::factory);
+        } else {
+            isc_throw(NotImplemented,
+                "parser error: Subnet6 parameter not supported: " << config_id);
         }
-        return (f->second(config_id));
+
+        return (parser);
     }
 
     /// @brief Returns value for a given parameter (after using inheritance)
@@ -1718,6 +609,34 @@ public:
 namespace isc {
 namespace dhcp {
 
+//************** Dhcp6OptionDataParser methods ****************************
+
+Dhcp6OptionDataParser::Dhcp6OptionDataParser(const std::string& param_name, 
+    OptionStorage *options, OptionDefStorage *option_defs)
+    :OptionDataParser(param_name, options, option_defs, Option::V6) {
+}
+
+OptionDataParser* Dhcp6OptionDataParser::factory(const std::string& param_name,
+    OptionStorage *options, OptionDefStorage *option_defs) {
+    return new Dhcp6OptionDataParser(param_name, options, option_defs);
+}
+
+OptionDefinitionPtr Dhcp6OptionDataParser::findServerSpaceOptionDefinition (
+    std::string& option_space, uint32_t option_code) {
+    OptionDefinitionPtr def;
+
+    if (option_space == "dhcp6" &&
+        LibDHCP::isStandardOption(Option::V6, option_code)) {
+        def = LibDHCP::getOptionDef(Option::V6, option_code);
+
+    } else if (option_space == "dhcp4") {
+        isc_throw(DhcpConfigError, "'dhcp4' option space name is reserved"
+                << " for DHCPv4 server");
+    }
+
+    return def;
+}
+
 /// @brief creates global parsers
 ///
 /// This method creates global parsers that parse global parameters, i.e.
@@ -1727,29 +646,40 @@ namespace dhcp {
 /// @return parser for specified global DHCPv6 parameter
 /// @throw NotImplemented if trying to create a parser for unknown config element
 DhcpConfigParser* createGlobalDhcpConfigParser(const std::string& config_id) {
-    FactoryMap factories;
-
-    factories["preferred-lifetime"] = Uint32Parser::factory;
-    factories["valid-lifetime"] = Uint32Parser::factory;
-    factories["renew-timer"] = Uint32Parser::factory;
-    factories["rebind-timer"] = Uint32Parser::factory;
-    factories["interface"] = InterfaceListConfigParser::factory;
-    factories["subnet6"] = Subnets6ListConfigParser::factory;
-    factories["option-data"] = OptionDataListParser::factory;
-    factories["option-def"] = OptionDefListParser::factory;
-    factories["version"] = StringParser::factory;
-    factories["lease-database"] = DbAccessParser::factory;
-
-    FactoryMap::iterator f = factories.find(config_id);
-    if (f == factories.end()) {
-        // Used for debugging only.
-        // return new DebugParser(config_id);
-
+    DhcpConfigParser *parser = NULL;
+    if ((config_id.compare("preferred-lifetime") == 0)  ||
+        (config_id.compare("valid-lifetime") == 0)  ||
+        (config_id.compare("renew-timer") == 0)  ||
+        (config_id.compare("rebind-timer") == 0))  {
+        parser = new Uint32Parser(config_id, &uint32_defaults);
+    }
+    else if (config_id.compare("interface") == 0) {
+        parser = new InterfaceListConfigParser(config_id);
+    }
+    else if (config_id.compare("subnet6") == 0) {
+        parser = new Subnets6ListConfigParser(config_id);
+    }
+    else if (config_id.compare("option-data") == 0) {
+        parser = new OptionDataListParser(config_id, &option_defaults, 
+                                          &option_def_intermediate,
+                                          Dhcp6OptionDataParser::factory);
+    }
+    else if (config_id.compare("option-def") == 0) {
+        parser  = new OptionDefListParser(config_id, &option_def_intermediate);
+    }
+    else if (config_id.compare("version") == 0) {
+        parser  = new StringParser(config_id, &string_defaults);
+    }
+    else if (config_id.compare("lease-database") == 0) {
+        parser = new DbAccessParser(config_id);
+    }
+    else {
         isc_throw(NotImplemented,
-                  "Parser error: Global configuration parameter not supported: "
-                  << config_id);
+                "Parser error: Global configuration parameter not supported: "
+                << config_id);
     }
-    return (f->second(config_id));
+
+    return (parser);
 }
 
 ConstElementPtr
diff --git a/src/bin/dhcp6/config_parser.h b/src/bin/dhcp6/config_parser.h
index 6d7a807..6840ecc 100644
--- a/src/bin/dhcp6/config_parser.h
+++ b/src/bin/dhcp6/config_parser.h
@@ -20,6 +20,8 @@
 
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
+#include <dhcpsrv/dhcp_parsers.h>
+
 #include <string>
 
 namespace isc {
@@ -47,6 +49,48 @@ class Dhcpv6Srv;
 isc::data::ConstElementPtr
 configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set);
 
+/// @brief Parser for DHCP6 option data value.
+///
+/// This parser parses configuration entries that specify value of
+/// a single option specific to DHCP6.  It provides the DHCP6-specific
+/// implementation of the abstract class OptionDataParser.
+class Dhcp6OptionDataParser : public OptionDataParser {
+public:
+    /// @brief Constructor.
+    ///
+    /// Class constructor.
+    Dhcp6OptionDataParser(const std::string&, OptionStorage *options,
+        OptionDefStorage *option_defs);
+
+    /// @brief static factory method for instantiating Dhcp4OptionDataParsers
+    ///
+    /// @param param_name name fo the parameter to be parsed.
+    /// @param options storage where the parameter value is to be stored.
+    /// @param global_option_defs global option definitions storage 
+    static OptionDataParser* factory(const std::string& param_name, OptionStorage *options,
+        OptionDefStorage *global_option_defs);
+
+protected:
+    /// @brief Finds an option definition within the server's option space
+    /// 
+    /// Given an option space and an option code, find the correpsonding 
+    /// option defintion within the server's option defintion storage.
+    ///
+    /// @param option_space name of the parameter option space 
+    /// @param option_code numeric value of the parameter to find 
+    /// @return OptionDefintionPtr of the option defintion or an 
+    /// empty OptionDefinitionPtr if not found.
+    /// @throw DhcpConfigError if the option space requested is not valid 
+    /// for this server. 
+    virtual OptionDefinitionPtr findServerSpaceOptionDefinition (
+        std::string& option_space, uint32_t option_code);
+
+private:
+    // Private default Constructor declared for safety.
+    Dhcp6OptionDataParser() :OptionDataParser("",NULL,NULL,Option::V6) {}
+};
+
+
 }; // end of isc::dhcp namespace
 }; // end of isc namespace
 
diff --git a/src/lib/dhcpsrv/Makefile.am b/src/lib/dhcpsrv/Makefile.am
index db82513..77a3a12 100644
--- a/src/lib/dhcpsrv/Makefile.am
+++ b/src/lib/dhcpsrv/Makefile.am
@@ -37,6 +37,7 @@ libb10_dhcpsrv_la_SOURCES += dbaccess_parser.cc dbaccess_parser.h
 libb10_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h
 libb10_dhcpsrv_la_SOURCES += cfgmgr.cc cfgmgr.h
 libb10_dhcpsrv_la_SOURCES += dhcp_config_parser.h
+libb10_dhcpsrv_la_SOURCES += dhcp_parsers.cc dhcp_parsers.h 
 libb10_dhcpsrv_la_SOURCES += key_from_key.h
 libb10_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h
 libb10_dhcpsrv_la_SOURCES += lease_mgr_factory.cc lease_mgr_factory.h
@@ -57,6 +58,7 @@ libb10_dhcpsrv_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
 libb10_dhcpsrv_la_LIBADD   = $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
 libb10_dhcpsrv_la_LIBADD  += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
 libb10_dhcpsrv_la_LIBADD  += $(top_builddir)/src/lib/util/libb10-util.la
+libb10_dhcpsrv_la_LIBADD  += $(top_builddir)/src/lib/cc/libb10-cc.la
 libb10_dhcpsrv_la_LDFLAGS  = -no-undefined -version-info 3:0:0
 if HAVE_MYSQL
 libb10_dhcpsrv_la_LDFLAGS += $(MYSQL_LIBS)
diff --git a/src/lib/dhcpsrv/dhcp_parsers.cc b/src/lib/dhcpsrv/dhcp_parsers.cc
new file mode 100644
index 0000000..940cf06
--- /dev/null
+++ b/src/lib/dhcpsrv/dhcp_parsers.cc
@@ -0,0 +1,633 @@
+// 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 <dhcpsrv/dhcp_parsers.h>
+#include <dhcp/libdhcp++.h>
+#include <dhcpsrv/cfgmgr.h>
+#include <util/encode/hex.h>
+#include <util/strutil.h>
+
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <string>
+#include <map>
+
+using namespace std;
+using namespace isc::data;
+
+namespace isc {
+namespace dhcp {
+
+// Pointers to various parser objects.
+typedef boost::shared_ptr<BooleanParser> BooleanParserPtr;
+typedef boost::shared_ptr<StringParser> StringParserPtr;
+typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr;
+
+// **************************** DebugParser *************************
+
+DebugParser::DebugParser(const std::string& param_name)
+    :param_name_(param_name) {
+}
+
+void DebugParser::build(ConstElementPtr new_config) {
+    std::cout << "Build for token: [" << param_name_ << "] = ["
+        << value_->str() << "]" << std::endl; 
+    value_ = new_config;
+}
+
+void DebugParser::commit() {
+    // Debug message. The whole DebugParser class is used only for parser
+    // debugging, and is not used in production code. It is very convenient
+    // to keep it around. Please do not turn this cout into logger calls.
+    std::cout << "Commit for token: [" << param_name_ << "] = ["
+                  << value_->str() << "]" << std::endl;
+}
+
+// **************************** BooleanParser  *************************
+BooleanParser::BooleanParser(const std::string& param_name, BooleanStorage *storage)
+    : storage_(storage), param_name_(param_name), value_(false) {
+    // Empty parameter name is invalid.
+    if (param_name_.empty()) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+        << "empty parameter name provided");
+    }
+
+    // NUll storage is invalid.
+    if (!storage_) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+            << "storage may not be NULL");
+    }
+}
+
+void BooleanParser::build(ConstElementPtr value) {
+    // The Config Manager checks if user specified a
+    // valid value for a boolean parameter: True or False.
+    // It is then ok to assume that if str() does not return
+    // 'true' the value is 'false'.
+    value_ = (value->str() == "true") ? true : false;
+}
+
+void BooleanParser::commit() {
+    // If a given parameter already exists in the storage we override
+    // its value. If it doesn't we insert a new element.
+    storage_->setParam(param_name_, value_);
+}
+
+// **************************** Uin32Parser  *************************
+
+Uint32Parser::Uint32Parser(const std::string& param_name, Uint32Storage *storage)
+    : storage_(storage), param_name_(param_name) {
+    // Empty parameter name is invalid.
+    if (param_name_.empty()) {
+        isc_throw(DhcpConfigError, "parser logic error:"
+            << "empty parameter name provided");
+    }
+
+    // NULL storage is invalid.
+    if (!storage_) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+            << "storage may not be NULL");
+    }
+}
+
+void Uint32Parser::build(ConstElementPtr value) {
+    int64_t check;
+    string x = value->str();
+    try {
+        check = boost::lexical_cast<int64_t>(x);
+    } catch (const boost::bad_lexical_cast &) {
+        isc_throw(BadValue, "Failed to parse value " << value->str()
+                  << " as unsigned 32-bit integer.");
+    }
+    if (check > std::numeric_limits<uint32_t>::max()) {
+        isc_throw(BadValue, "Value " << value->str() << "is too large"
+                  << " for unsigned 32-bit integer.");
+    }
+    if (check < 0) {
+        isc_throw(BadValue, "Value " << value->str() << "is negative."
+                  << " Only 0 or larger are allowed for unsigned 32-bit integer.");
+    }
+
+    // value is small enough to fit
+    value_ = static_cast<uint32_t>(check);
+}
+
+void Uint32Parser::commit() {
+    // If a given parameter already exists in the storage we override
+    // its value. If it doesn't we insert a new element.
+    storage_->setParam(param_name_, value_);
+}
+
+// **************************** StringParser  *************************
+
+StringParser::StringParser(const std::string& param_name, StringStorage *storage)
+    :storage_(storage), param_name_(param_name) {
+    // Empty parameter name is invalid.
+    if (param_name_.empty()) {
+        isc_throw(DhcpConfigError, "parser logic error:"
+                  << "empty parameter name provided");
+    }
+
+    // NULL storage is invalid.
+    if (!storage_) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+            << "storage may not be NULL");
+    }
+}
+
+void StringParser::build(ConstElementPtr value) {
+    value_ = value->str();
+    boost::erase_all(value_, "\"");
+}
+
+void StringParser::commit() {
+    // If a given parameter already exists in the storage we override
+    // its value. If it doesn't we insert a new element.
+    storage_->setParam(param_name_, value_);
+}
+
+// **************************** InterfaceListConfigParser *************************
+
+InterfaceListConfigParser::InterfaceListConfigParser(const std::string& param_name) {
+    if (param_name != "interface") {
+        isc_throw(BadValue, "Internal error. Interface configuration "
+            "parser called for the wrong parameter: " << param_name);
+    }
+}
+
+void InterfaceListConfigParser::build(ConstElementPtr value) {
+    BOOST_FOREACH(ConstElementPtr iface, value->listValue()) {
+        interfaces_.push_back(iface->str());
+    }
+}
+
+void InterfaceListConfigParser::commit() {
+    /// @todo: Implement per interface listening. Currently always listening
+    /// on all interfaces.
+}
+
+// **************************** OptionDataParser *************************
+
+OptionDataParser::OptionDataParser(const std::string&, OptionStorage *options,
+    OptionDefStorage *option_defs, Option::Universe universe)
+        : options_(options),
+          // initialize option to NULL ptr
+          option_descriptor_(false), global_option_defs_(option_defs),
+          universe_(universe) {
+    if (!options_) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+             << "options storage may not be NULL");
+    }
+}
+
+void OptionDataParser::build(ConstElementPtr option_data_entries) {
+    BOOST_FOREACH(ConfigPair param, option_data_entries->mapValue()) {
+        ParserPtr parser;
+        if (param.first == "name" || param.first == "data" ||
+            param.first == "space") {
+            StringParserPtr name_parser(new StringParser(param.first, &string_values_)); 
+            parser = name_parser;
+        } else if (param.first == "code") {
+            Uint32ParserPtr code_parser(new Uint32Parser(param.first, &uint32_values_)); 
+            parser = code_parser;
+        } else if (param.first == "csv-format") {
+            BooleanParserPtr value_parser(new BooleanParser(param.first, &boolean_values_)); 
+            parser = value_parser;
+        } else {
+            isc_throw(DhcpConfigError,
+                      "Parser error: option-data parameter not supported: "
+                      << param.first);
+        }
+
+        parser->build(param.second);
+        // Before we can create an option we need to get the data from
+        // the child parsers. The only way to do it is to invoke commit
+        // on them so as they store the values in appropriate storages
+        // that this class provided to them. Note that this will not
+        // modify values stored in the global storages so the configuration
+        // will remain consistent even parsing fails somewhere further on.
+        parser->commit();
+    }
+
+    // Try to create the option instance.
+    createOption();
+}
+
+void OptionDataParser::commit() {
+    if (!option_descriptor_.option) {
+        // Before we can commit the new option should be configured. If it is not
+        // than somebody must have called commit() before build().
+        isc_throw(isc::InvalidOperation, 
+            "parser logic error: no option has been configured and"
+            " thus there is nothing to commit. Has build() been called?");
+    }
+
+    uint16_t opt_type = option_descriptor_.option->getType();
+    Subnet::OptionContainerPtr options = options_->getItems(option_space_);
+    // The getItems() should never return NULL pointer. If there are no
+    // options configured for the particular option space a pointer
+    // to an empty container should be returned.
+    assert(options);
+    Subnet::OptionContainerTypeIndex& idx = options->get<1>();
+    // Try to find options with the particular option code in the main
+    // storage. If found, remove these options because they will be
+    // replaced with new one.
+    Subnet::OptionContainerTypeRange range = idx.equal_range(opt_type);
+    if (std::distance(range.first, range.second) > 0) {
+        idx.erase(range.first, range.second);
+    }
+
+    // Append new option to the main storage.
+    options_->addItem(option_descriptor_, option_space_);
+}
+
+void OptionDataParser::createOption() {
+    // Option code is held in the uint32_t storage but is supposed to
+    // be uint16_t value. We need to check that value in the configuration
+    // does not exceed range of uint8_t and is not zero.
+    uint32_t option_code = uint32_values_.getParam("code");
+    if (option_code == 0) {
+        isc_throw(DhcpConfigError, "option code must not be zero."
+                << " Option code '0' is reserved in DHCPv4.");
+    } else if (option_code > std::numeric_limits<uint8_t>::max()) {
+        isc_throw(DhcpConfigError, "invalid option code '" << option_code
+                << "', it must not exceed '"
+                << std::numeric_limits<uint8_t>::max() << "'");
+    }
+
+    // Check that the option name has been specified, is non-empty and does not
+    // contain spaces
+    std::string option_name = string_values_.getParam("name"); 
+    if (option_name.empty()) {
+        isc_throw(DhcpConfigError, "name of the option with code '"
+                << option_code << "' is empty");
+    } else if (option_name.find(" ") != std::string::npos) {
+        isc_throw(DhcpConfigError, "invalid option name '" << option_name
+                << "', space character is not allowed");
+    }
+
+    std::string option_space = string_values_.getParam("space"); 
+    if (!OptionSpace::validateName(option_space)) {
+        isc_throw(DhcpConfigError, "invalid option space name '"
+                << option_space << "' specified for option '"
+                << option_name << "' (code '" << option_code
+                << "')");
+    }
+
+    // Find the Option Definition for the option by its option code.
+    // findOptionDefinition will throw if not found, no need to test.
+    OptionDefinitionPtr def;
+    if (!(def = findServerSpaceOptionDefinition(option_space, option_code))) {
+        // If we are not dealing with a standard option then we
+        // need to search for its definition among user-configured
+        // options. They are expected to be in the global storage
+        // already.
+        OptionDefContainerPtr defs = global_option_defs_->getItems(option_space);
+
+        // The getItems() should never return the NULL pointer. If there are
+        // no option definitions for the particular option space a pointer
+        // to an empty container should be returned.
+        assert(defs);
+        const OptionDefContainerTypeIndex& idx = defs->get<1>();
+        OptionDefContainerTypeRange range = idx.equal_range(option_code);
+        if (std::distance(range.first, range.second) > 0) {
+            def = *range.first;
+        }
+        if (!def) {
+            isc_throw(DhcpConfigError, "definition for the option '"
+                      << option_space << "." << option_name
+                      << "' having code '" <<  option_code
+                      << "' does not exist");
+        }
+    }
+
+    // Get option data from the configuration database ('data' field).
+    const std::string option_data = string_values_.getParam("data");
+    const bool csv_format = boolean_values_.getParam("csv-format");
+
+    // Transform string of hexadecimal digits into binary format.
+    std::vector<uint8_t> binary;
+    std::vector<std::string> data_tokens;
+
+    if (csv_format) {
+        // If the option data is specified as a string of comma
+        // separated values then we need to split this string into
+        // individual values - each value will be used to initialize
+        // one data field of an option.
+        data_tokens = isc::util::str::tokens(option_data, ",");
+    } else {
+        // Otherwise, the option data is specified as a string of
+        // hexadecimal digits that we have to turn into binary format.
+        try {
+            util::encode::decodeHex(option_data, binary);
+        } catch (...) {
+            isc_throw(DhcpConfigError, "option data is not a valid"
+                      << " string of hexadecimal digits: " << option_data);
+        }
+    }
+
+    OptionPtr option;
+    if (!def) {
+        if (csv_format) {
+            isc_throw(DhcpConfigError, "the CSV option data format can be"
+                      " used to specify values for an option that has a"
+                      " definition. The option with code " << option_code
+                      << " does not have a definition.");
+        }
+
+        // @todo We have a limited set of option definitions intiialized at the moment.
+        // In the future we want to initialize option definitions for all options.
+        // Consequently an error will be issued if an option definition does not exist
+        // for a particular option code. For now it is ok to create generic option
+        // if definition does not exist.
+        OptionPtr option(new Option(universe_, static_cast<uint16_t>(option_code),
+                                        binary));
+        // The created option is stored in option_descriptor_ class member until the
+        // commit stage when it is inserted into the main storage. If an option with the
+        // same code exists in main storage already the old option is replaced.
+        option_descriptor_.option = option;
+        option_descriptor_.persistent = false;
+    } else {
+
+        // Option name should match the definition. The option name
+        // may seem to be redundant but in the future we may want
+        // to reference options and definitions using their names
+        // and/or option codes so keeping the option name in the
+        // definition of option value makes sense.
+        if (def->getName() != option_name) {
+            isc_throw(DhcpConfigError, "specified option name '"
+                      << option_name << "' does not match the "
+                      << "option definition: '" << option_space
+                      << "." << def->getName() << "'");
+        }
+
+        // Option definition has been found so let's use it to create
+        // an instance of our option.
+        try {
+            OptionPtr option = csv_format ?
+                def->optionFactory(universe_, option_code, data_tokens) :
+                def->optionFactory(universe_, option_code, binary);
+            Subnet::OptionDescriptor desc(option, false);
+            option_descriptor_.option = option;
+            option_descriptor_.persistent = false;
+        } catch (const isc::Exception& ex) {
+            isc_throw(DhcpConfigError, "option data does not match"
+                      << " option definition (space: " << option_space
+                      << ", code: " << option_code << "): "
+                      << ex.what());
+        }
+    }
+
+    // All went good, so we can set the option space name.
+    option_space_ = option_space;
+}
+
+// **************************** OptionDataListParser *************************
+
+OptionDataListParser::OptionDataListParser(const std::string&, 
+    OptionStorage *storage, OptionDefStorage *global_option_defs,
+    OptionDataParserFactory *optionDataParserFactory)
+    : options_(storage), local_options_(), 
+    global_option_defs_(global_option_defs),
+    optionDataParserFactory_(optionDataParserFactory) {
+    if (!options_) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+             << "options storage may not be NULL");
+    }
+
+    if (!optionDataParserFactory_) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+             << "option data parser factory may not be NULL");
+    }
+}
+
+
+void OptionDataListParser::build(ConstElementPtr option_data_list) {
+    BOOST_FOREACH(ConstElementPtr option_value, option_data_list->listValue()) {
+        boost::shared_ptr<OptionDataParser> 
+            parser((*optionDataParserFactory_)("option-data", &local_options_, global_option_defs_));
+
+        // options_ member will hold instances of all options thus
+        // each OptionDataParser takes it as a storage.
+        // Build the instance of a single option.
+        parser->build(option_value);
+        // Store a parser as it will be used to commit.
+        parsers_.push_back(parser);
+    }
+}
+
+void OptionDataListParser::commit() {
+    BOOST_FOREACH(ParserPtr parser, parsers_) {
+        parser->commit();
+    }
+
+    // Parsing was successful and we have all configured
+    // options in local storage. We can now replace old values
+    // with new values.
+    std::swap(local_options_, *options_);
+}
+
+// ******************************** OptionDefParser ****************************
+
+OptionDefParser::OptionDefParser(const std::string&, OptionDefStorage *storage)
+    : storage_(storage) {
+    if (!storage_) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+             << "options storage may not be NULL");
+    }
+}
+
+void OptionDefParser::build(ConstElementPtr option_def) {
+    // Parse the elements that make up the option definition.
+     BOOST_FOREACH(ConfigPair param, option_def->mapValue()) {
+        std::string entry(param.first);
+        ParserPtr parser;
+        if (entry == "name" || entry == "type" || entry == "record-types" 
+            || entry == "space" || entry == "encapsulate") {
+            StringParserPtr str_parser(new StringParser(entry, &string_values_));
+            parser = str_parser;
+        } else if (entry == "code") {
+            Uint32ParserPtr code_parser(new Uint32Parser(entry, &uint32_values_));
+            parser = code_parser;
+        } else if (entry == "array") {
+            BooleanParserPtr array_parser(new BooleanParser(entry, &boolean_values_));
+            parser = array_parser;
+        } else {
+            isc_throw(DhcpConfigError, "invalid parameter: " << entry);
+        }
+
+        parser->build(param.second);
+        parser->commit();
+    }
+
+    // Create an instance of option definition.
+    createOptionDef();
+
+    // Get all items we collected so far for the particular option space.
+    OptionDefContainerPtr defs = storage_->getItems(option_space_name_);
+
+    // Check if there are any items with option code the same as the
+    // one specified for the definition we are now creating.
+    const OptionDefContainerTypeIndex& idx = defs->get<1>();
+    const OptionDefContainerTypeRange& range =
+            idx.equal_range(option_definition_->getCode());
+
+    // If there are any items with this option code already we need
+    // to issue an error because we don't allow duplicates for
+    // option definitions within an option space.
+    if (std::distance(range.first, range.second) > 0) {
+        isc_throw(DhcpConfigError, "duplicated option definition for"
+                << " code '" << option_definition_->getCode() << "'");
+    }
+}
+
+void OptionDefParser::commit() {
+    if (storage_ && option_definition_ &&
+        OptionSpace::validateName(option_space_name_)) {
+            storage_->addItem(option_definition_, option_space_name_);
+    }
+}
+
+void OptionDefParser::createOptionDef() {
+    // Get the option space name and validate it.
+    std::string space = string_values_.getParam("space");
+    if (!OptionSpace::validateName(space)) {
+        isc_throw(DhcpConfigError, "invalid option space name '"
+                  << space << "'");
+    }
+
+    // Get other parameters that are needed to create the
+    // option definition.
+    std::string name = string_values_.getParam("name");
+    uint32_t code = uint32_values_.getParam("code");
+    std::string type = string_values_.getParam("type");
+    bool array_type = boolean_values_.getParam("array");
+    std::string encapsulates = string_values_.getParam("encapsulate");
+
+    // Create option definition.
+    OptionDefinitionPtr def;
+    // We need to check if user has set encapsulated option space
+    // name. If so, different constructor will be used.
+    if (!encapsulates.empty()) {
+        // Arrays can't be used together with sub-options.
+        if (array_type) {
+            isc_throw(DhcpConfigError, "option '" << space << "."
+                      << "name" << "', comprising an array of data"
+                      << " fields may not encapsulate any option space");
+
+        } else if (encapsulates == space) {
+            isc_throw(DhcpConfigError, "option must not encapsulate"
+                      << " an option space it belongs to: '"
+                      << space << "." << name << "' is set to"
+                      << " encapsulate '" << space << "'");
+
+        } else {
+            def.reset(new OptionDefinition(name, code, type,
+                        encapsulates.c_str()));
+        }
+
+    } else {
+        def.reset(new OptionDefinition(name, code, type, array_type));
+
+    }
+
+    // The record-types field may carry a list of comma separated names
+    // of data types that form a record.
+    std::string record_types = string_values_.getParam("record-types");
+
+    // Split the list of record types into tokens.
+    std::vector<std::string> record_tokens =
+    isc::util::str::tokens(record_types, ",");
+    // Iterate over each token and add a record type into
+    // option definition.
+    BOOST_FOREACH(std::string record_type, record_tokens) {
+        try {
+            boost::trim(record_type);
+            if (!record_type.empty()) {
+                    def->addRecordField(record_type);
+            }
+        } catch (const Exception& ex) {
+            isc_throw(DhcpConfigError, "invalid record type values"
+                      << " specified for the option definition: "
+                      << ex.what());
+        }
+    }
+
+    // Check the option definition parameters are valid.
+    try {
+        def->validate();
+    } catch (const isc::Exception& ex) {
+        isc_throw(DhcpConfigError, "invalid option definition"
+                  << " parameters: " << ex.what());
+    }
+
+    // Option definition has been created successfully.
+    option_space_name_ = space;
+    option_definition_ = def;
+}
+
+// ******************************** OptionDefListParser ************************
+
+OptionDefListParser::OptionDefListParser(const std::string&, 
+    OptionDefStorage *storage) :storage_(storage) {
+    if (!storage_) {
+        isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+             << "storage may not be NULL");
+    }
+}
+
+void OptionDefListParser::build(ConstElementPtr option_def_list) {
+    // Clear existing items in the global storage.
+    // We are going to replace all of them.
+    storage_->clearItems();
+
+    if (!option_def_list) {
+        isc_throw(DhcpConfigError, "parser error: a pointer to a list of"
+                  << " option definitions is NULL");
+    }
+
+    BOOST_FOREACH(ConstElementPtr option_def, option_def_list->listValue()) {
+        boost::shared_ptr<OptionDefParser>
+                parser(new OptionDefParser("single-option-def", storage_));
+        parser->build(option_def);
+        parser->commit();
+    }
+}
+
+void OptionDefListParser::commit() {
+    CfgMgr& cfg_mgr = CfgMgr::instance();
+    cfg_mgr.deleteOptionDefs();
+
+    // We need to move option definitions from the temporary
+    // storage to the global storage.
+    std::list<std::string> space_names =
+    storage_->getOptionSpaceNames();
+
+    BOOST_FOREACH(std::string space_name, space_names) {
+        BOOST_FOREACH(OptionDefinitionPtr def,
+                    *(storage_->getItems(space_name))) {
+            // All option definitions should be initialized to non-NULL
+            // values. The validation is expected to be made by the
+            // OptionDefParser when creating an option definition.
+            assert(def);
+            cfg_mgr.addOptionDef(def, space_name);
+        }
+    }
+}
+
+};  // namespace dhcp
+};  // namespace isc
diff --git a/src/lib/dhcpsrv/dhcp_parsers.h b/src/lib/dhcpsrv/dhcp_parsers.h
new file mode 100644
index 0000000..76c6719
--- /dev/null
+++ b/src/lib/dhcpsrv/dhcp_parsers.h
@@ -0,0 +1,504 @@
+// 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 DHCP_PARSERS_H
+#define DHCP_PARSERS_H
+
+#include <cc/data.h>
+#include <dhcp/option_definition.h>
+#include <dhcpsrv/dhcp_config_parser.h>
+#include <dhcpsrv/option_space_container.h>
+#include <dhcpsrv/subnet.h>
+#include <exceptions/exceptions.h>
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace isc {
+namespace dhcp {
+
+/// @brief Storage for option definitions.
+typedef OptionSpaceContainer<OptionDefContainer,
+                             OptionDefinitionPtr> OptionDefStorage;
+
+/// Collection of containers holding option spaces. Each container within
+/// a particular option space holds so-called option descriptors.
+typedef OptionSpaceContainer<Subnet::OptionContainer,
+                             Subnet::OptionDescriptor> OptionStorage;
+
+/// @brief a dummy configuration parser
+///
+/// It is a debugging parser. It does not configure anything,
+/// will accept any configuration and will just print it out
+/// on commit. Useful for debugging existing configurations and
+/// adding new ones.
+class DebugParser : public DhcpConfigParser {
+public:
+
+    /// @brief Constructor
+    ///
+    /// See @ref DhcpConfigParser class for details.
+    ///
+    /// @param param_name name of the parsed parameter
+    DebugParser(const std::string& param_name);
+
+    /// @brief builds parameter value
+    ///
+    /// See @ref DhcpConfigParser class for details.
+    ///
+    /// @param new_config pointer to the new configuration
+    virtual void build(isc::data::ConstElementPtr new_config);
+
+    /// @brief pretends to apply the configuration
+    ///
+    /// This is a method required by base class. It pretends to apply the
+    /// configuration, but in fact it only prints the parameter out.
+    ///
+    /// See @ref DhcpConfigParser class for details.
+    virtual void commit();
+
+private:
+    /// name of the parsed parameter
+    std::string param_name_;
+
+    /// pointer to the actual value of the parameter
+    isc::data::ConstElementPtr value_;
+
+};
+
+/// @brief A boolean value parser.
+///
+/// This parser handles configuration values of the boolean type.
+/// Parsed values are stored in a provided storage. If no storage
+/// is provided then the build function throws an exception.
+class BooleanParser : public DhcpConfigParser {
+public:
+
+    /// @brief Constructor.
+    ///
+    /// @param param_name name of the parameter.
+    BooleanParser(const std::string& param_name, BooleanStorage *storage);
+
+    /// @brief Parse a boolean value.
+    ///
+    /// @param value a value to be parsed.
+    ///
+    /// @throw isc::InvalidOperation if a storage has not been set
+    ///        prior to calling this function
+    /// @throw isc::dhcp::DhcpConfigError if a provided parameter's
+    ///        name is empty.
+    virtual void build(isc::data::ConstElementPtr value);
+
+    /// @brief Put a parsed value to the storage.
+    virtual void commit();
+
+private:
+    /// Pointer to the storage where parsed value is stored.
+    BooleanStorage* storage_;
+    /// Name of the parameter which value is parsed with this parser.
+    std::string param_name_;
+    /// Parsed value.
+    bool value_;
+
+    /// Default constructor is private for safety.
+    BooleanParser(){};
+};
+
+/// @brief Configuration parser for uint32 parameters
+///
+/// This class is a generic parser that is able to handle any uint32 integer
+/// type. By default it stores the value in external global container
+/// (uint32_defaults). If used in smaller scopes (e.g. to parse parameters
+/// in subnet config), it can be pointed to a different storage, using
+/// setStorage() method. This class follows the parser interface, laid out
+/// in its base class, @ref DhcpConfigParser.
+///
+/// For overview of usability of this generic purpose parser, see
+/// @ref dhcpv4ConfigInherit page.
+class Uint32Parser : public DhcpConfigParser {
+public:
+
+    /// @brief constructor for Uint32Parser
+    /// @param param_name name of the configuration parameter being parsed
+    Uint32Parser(const std::string& param_name, Uint32Storage *storage);
+
+    /// @brief Parses configuration configuration parameter as uint32_t.
+    ///
+    /// @param value pointer to the content of parsed values
+    /// @throw BadValue if supplied value could not be base to uint32_t
+    ///        or the parameter name is empty.
+    virtual void build(isc::data::ConstElementPtr value);
+
+    /// @brief Stores the parsed uint32_t value in a storage.
+    virtual void commit();
+
+private:
+    /// pointer to the storage, where parsed value will be stored
+    Uint32Storage* storage_;
+
+    /// name of the parameter to be parsed
+    std::string param_name_;
+
+    /// the actual parsed value
+    uint32_t value_;
+
+    /// Default constructor is private for safety.
+    Uint32Parser(){};
+};
+
+/// @brief Configuration parser for string parameters
+///
+/// This class is a generic parser that is able to handle any string
+/// parameter. By default it stores the value in external global container
+/// (string_defaults). If used in smaller scopes (e.g. to parse parameters
+/// in subnet config), it can be pointed to a different storage, using
+/// setStorage() method. This class follows the parser interface, laid out
+/// in its base class, @ref DhcpConfigParser.
+///
+/// For overview of usability of this generic purpose parser, see
+/// @ref dhcpv4ConfigInherit page.
+class StringParser : public DhcpConfigParser {
+public:
+    /// @brief constructor for StringParser
+    /// @param param_name name of the configuration parameter being parsed
+    StringParser(const std::string& param_name, StringStorage *storage);
+
+    /// @brief parses parameter value
+    ///
+    /// Parses configuration entry and stores it in storage. See
+    /// @ref setStorage() for details.
+    ///
+    /// @param value pointer to the content of parsed values
+    virtual void build(isc::data::ConstElementPtr value);
+
+    /// @brief Stores the parsed value in a storage.
+    virtual void commit();
+
+private:
+    /// pointer to the storage, where parsed value will be stored
+    StringStorage* storage_;
+
+    /// name of the parameter to be parsed
+    std::string param_name_;
+
+    /// the actual parsed value
+    std::string value_;
+
+    /// Default constructor is private for safety.
+    StringParser(){};
+};
+
+/// @brief parser for interface list definition
+///
+/// This parser handles Dhcp4/interface entry.
+/// It contains a list of network interfaces that the server listens on.
+/// In particular, it can contain an entry called "all" or "any" that
+/// designates all interfaces.
+///
+/// It is useful for parsing Dhcp4/interface parameter.
+class InterfaceListConfigParser : public DhcpConfigParser {
+public:
+
+    /// @brief constructor
+    ///
+    /// As this is a dedicated parser, it must be used to parse
+    /// "interface" parameter only. All other types will throw exception.
+    ///
+    /// @param param_name name of the configuration parameter being parsed
+    /// @throw BadValue if supplied parameter name is not "interface"
+    InterfaceListConfigParser(const std::string& param_name);
+
+    /// @brief parses parameters value
+    ///
+    /// Parses configuration entry (list of parameters) and adds each element
+    /// to the interfaces list.
+    ///
+    /// @param value pointer to the content of parsed values
+    virtual void build(isc::data::ConstElementPtr value);
+
+    /// @brief commits interfaces list configuration
+    virtual void commit();
+
+private:
+    /// contains list of network interfaces
+    std::vector<std::string> interfaces_;
+
+    /// Default constructor is private for safety.
+    InterfaceListConfigParser(){};
+};
+
+
+/// @brief Parser for option data value.
+///
+/// This parser parses configuration entries that specify value of
+/// a single option. These entries include option name, option code
+/// and data carried by the option. The option data can be specified
+/// in one of the two available formats: binary value represented as
+/// a string of hexadecimal digits or a list of comma separated values.
+/// The format being used is controlled by csv-format configuration
+/// parameter. When setting this value to True, the latter format is
+/// used. The subsequent values in the CSV format apply to relevant
+/// option data fields in the configured option. For example the
+/// configuration: "data" : "192.168.2.0, 56, hello world" can be
+/// used to set values for the option comprising IPv4 address,
+/// integer and string data field. Note that order matters. If the
+/// order of values does not match the order of data fields within
+/// an option the configuration will not be accepted. If parsing
+/// is successful then an instance of an option is created and
+/// added to the storage provided by the calling class.
+class OptionDataParser : public DhcpConfigParser {
+public:
+    /// @brief Constructor.
+    ///
+    /// Class constructor.
+    OptionDataParser(const std::string&, OptionStorage *options, 
+        OptionDefStorage *option_defs, Option::Universe universe);
+
+    /// @brief Parses the single option data.
+    ///
+    /// This method parses the data of a single option from the configuration.
+    /// The option data includes option name, option code and data being
+    /// carried by this option. Eventually it creates the instance of the
+    /// option.
+    ///
+    /// @warning setStorage must be called with valid storage pointer prior
+    /// to calling this method.
+    ///
+    /// @param option_data_entries collection of entries that define value
+    /// for a particular option.
+    /// @throw DhcpConfigError if invalid parameter specified in
+    /// the configuration.
+    /// @throw isc::InvalidOperation if failed to set storage prior to
+    /// calling build.
+    virtual void build(isc::data::ConstElementPtr option_data_entries);
+
+    /// @brief Commits option value.
+    ///
+    /// This function adds a new option to the storage or replaces an existing option
+    /// with the same code.
+    ///
+    /// @throw isc::InvalidOperation if failed to set pointer to storage or failed
+    /// to call build() prior to commit. If that happens data in the storage
+    /// remain un-modified.
+    virtual void commit();
+
+    /// @brief virtual destructor to ensure orderly destruction of derivations. 
+    virtual ~OptionDataParser(){};
+
+protected:
+    /// @brief Finds an option definition within the server's option space
+    /// 
+    /// Given an option space and an option code, find the correpsonding 
+    /// option defintion within the server's option defintion storage. This
+    /// method is pure virtual requiring derivations to manage which option
+    /// space(s) is valid for search.
+    ///
+    /// @param option_space name of the parameter option space 
+    /// @param option_code numeric value of the parameter to find 
+    /// @return OptionDefintionPtr of the option defintion or an 
+    /// empty OptionDefinitionPtr if not found.
+    /// @throw DhcpConfigError if the option space requested is not valid 
+    /// for this server.
+    virtual OptionDefinitionPtr findServerSpaceOptionDefinition (
+            std::string& option_space, uint32_t option_code) = 0;
+
+private:
+
+    /// @brief Create option instance.
+    ///
+    /// Creates an instance of an option and adds it to the provided
+    /// options storage. If the option data parsed by \ref build function
+    /// are invalid or insufficient this function emits an exception.
+    ///
+    /// @warning this function does not check if options_ storage pointer
+    /// is intitialized but this check is not needed here because it is done
+    /// in the \ref build function.
+    ///
+    /// @throw DhcpConfigError if parameters provided in the configuration
+    /// are invalid.
+    void createOption();
+
+    /// Storage for uint32 values (e.g. option code).
+    Uint32Storage uint32_values_;
+    /// Storage for string values (e.g. option name or data).
+    StringStorage string_values_;
+    /// Storage for boolean values.
+    BooleanStorage boolean_values_;
+    /// Pointer to options storage. This storage is provided by
+    /// the calling class and is shared by all OptionDataParser objects.
+    OptionStorage* options_;
+    /// Option descriptor holds newly configured option.
+    Subnet::OptionDescriptor option_descriptor_;
+    /// Option space name where the option belongs to.
+    std::string option_space_;
+
+    /// Option definition storage
+    OptionDefStorage *global_option_defs_;
+
+    /// Option::Universe for this parser's option
+    Option::Universe universe_;
+
+    /// Default constructor is private for safety.
+    OptionDataParser():option_descriptor_(false){};
+};
+
+///@brief Function pointer for OptionDataParser factory methods
+typedef OptionDataParser *OptionDataParserFactory(const std::string&, OptionStorage *options, 
+        OptionDefStorage *option_defs);
+
+/// @brief Parser for option data values within a subnet.
+///
+/// This parser iterates over all entries that define options
+/// data for a particular subnet and creates a collection of options.
+/// If parsing is successful, all these options are added to the Subnet
+/// object.
+class OptionDataListParser : public DhcpConfigParser {
+public:
+    /// @brief Constructor.
+    ///
+    /// @param string& nominally would be param name, this is always ignored.
+    /// @param storage parsed option storage for options in this list
+    /// @param global_option_defs global set of option definitions to reference
+    /// @param optionDataParserFactory factory method for creating individual option
+    /// parsers 
+    OptionDataListParser(const std::string&, OptionStorage *storage, 
+        OptionDefStorage *global_option_defs,
+        OptionDataParserFactory *optionDataParserFactory);
+
+    /// @brief Parses entries that define options' data for a subnet.
+    ///
+    /// This method iterates over all entries that define option data
+    /// for options within a single subnet and creates options' instances.
+    ///
+    /// @param option_data_list pointer to a list of options' data sets.
+    /// @throw DhcpConfigError if option parsing failed.
+    void build(isc::data::ConstElementPtr option_data_list);
+
+    /// @brief Commit all option values.
+    ///
+    /// This function invokes commit for all option values.
+    void commit();
+
+private:
+    /// Pointer to options instances storage.
+    OptionStorage* options_;
+    /// Intermediate option storage. This storage is used by
+    /// lower level parsers to add new options.  Values held
+    /// in this storage are assigned to main storage (options_)
+    /// if overall parsing was successful.
+    OptionStorage local_options_;
+    /// Collection of parsers;
+    ParserCollection parsers_;
+
+    /// Global option definitions
+    OptionDefStorage *global_option_defs_;
+
+    /// Factory to create server-specific option data parsers
+    OptionDataParserFactory *optionDataParserFactory_;
+
+    /// Default constructor is private for safety.
+    OptionDataListParser(){};
+};
+
+
+/// @brief Parser for a single option definition.
+///
+/// This parser creates an instance of a single option definition.
+class OptionDefParser : public DhcpConfigParser {
+public:
+    /// @brief Constructor.
+    ///
+    /// This constructor sets the pointer to the option definitions
+    /// storage to NULL. It must be set to point to the actual storage
+    /// before \ref build is called.
+    OptionDefParser(const std::string&, OptionDefStorage *storage);
+
+    /// @brief Parses an entry that describes single option definition.
+    ///
+    /// @param option_def a configuration entry to be parsed.
+    ///
+    /// @throw DhcpConfigError if parsing was unsuccessful.
+    void build(isc::data::ConstElementPtr option_def);
+
+    /// @brief Stores the parsed option definition in a storage.
+    void commit();
+
+private:
+
+    /// @brief Create option definition from the parsed parameters.
+    void createOptionDef();
+
+    /// Instance of option definition being created by this parser.
+    OptionDefinitionPtr option_definition_;
+    /// Name of the space the option definition belongs to.
+    std::string option_space_name_;
+
+    /// Pointer to a storage where the option definition will be
+    /// added when \ref commit is called.
+    OptionDefStorage* storage_;
+
+    /// Storage for boolean values.
+    BooleanStorage boolean_values_;
+    /// Storage for string values.
+    StringStorage string_values_;
+    /// Storage for uint32 values.
+    Uint32Storage uint32_values_;
+
+    // Default constructor is private for safety.
+    OptionDefParser(){};
+};
+
+/// @brief Parser for a list of option definitions.
+///
+/// This parser iterates over all configuration entries that define
+/// option definitions and creates instances of these definitions.
+/// If the parsing is successful, the collection of created definitions
+/// is put into the provided storage.
+class OptionDefListParser : public DhcpConfigParser {
+public:
+    /// @brief Constructor.
+    ///
+    /// This constructor initializes the pointer to option definitions
+    /// storage to NULL value. This pointer has to be set to point to
+    /// the actual storage before the \ref build function is called.
+    OptionDefListParser(const std::string&, OptionDefStorage *storage);
+
+    /// @brief Parse configuration entries.
+    ///
+    /// This function parses configuration entries and creates instances
+    /// of option definitions.
+    ///
+    /// @param option_def_list pointer to an element that holds entries
+    /// that define option definitions.
+    /// @throw DhcpConfigError if configuration parsing fails.
+    void build(isc::data::ConstElementPtr option_def_list);
+
+    /// @brief Stores option definitions in the CfgMgr.
+    void commit();
+
+private:
+    /// @brief storage for option definitions.
+    OptionDefStorage *storage_; 
+
+    // Default constructor is private for safety.
+    OptionDefListParser(){};
+
+};
+
+}; // end of isc::dhcp namespace
+}; // end of isc namespace
+
+#endif // DHCP_PARSERS_H
+



More information about the bind10-changes mailing list