diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp
index 947a3eaa141035961bada73d95c649f803fb2a8a..93398f45340adfd1e2977d46f8b52c834ddd8621 100644
--- a/Applications/ApplicationsLib/ProjectData.cpp
+++ b/Applications/ApplicationsLib/ProjectData.cpp
@@ -28,6 +28,8 @@
 #include "FileIO/XmlIO/Boost/BoostXmlGmlInterface.h"
 #include "FileIO/readMeshFromFile.h"
 
+#include "BaseLib/ConfigTreeNew.h"
+
 namespace detail
 {
 static
@@ -61,7 +63,9 @@ ProjectData::ProjectData(BaseLib::ConfigTree const& project_config,
 	_mesh_vec.push_back(mesh);
 
 	// process variables
-	parseProcessVariables(project_config.get_child("process_variables"));
+
+	BaseLib::ConfigTreeNew var_conf(project_config.get_child("process_variables"));
+	parseProcessVariables(var_conf);
 
 	// parameters
 	parseParameters(project_config.get_child("parameters"));
@@ -174,7 +178,7 @@ bool ProjectData::isMeshNameUniqueAndProvideUniqueName(std::string &name) const
 }
 
 void ProjectData::parseProcessVariables(
-	BaseLib::ConfigTree const& process_variables_config)
+	BaseLib::ConfigTreeNew& process_variables_config)
 {
 	DBUG("Parse process variables:")
 	if (_geoObjects == nullptr) {
@@ -191,12 +195,12 @@ void ProjectData::parseProcessVariables(
 		return;
 	}
 
-	_process_variables.reserve(process_variables_config.size());
+	// _process_variables.reserve(process_variables_config.size());
 
-	for (auto it : process_variables_config) {
-		BaseLib::ConfigTree const& var_config = it.second;
+	for (auto var_config
+		 : process_variables_config.getConfSubtreeList("process_variable")) {
 		// TODO Extend to referenced meshes.
-		_process_variables.emplace_back(var_config,*_mesh_vec[0],*_geoObjects);
+		_process_variables.emplace_back(var_config, *_mesh_vec[0], *_geoObjects);
 	}
 }
 
diff --git a/Applications/ApplicationsLib/ProjectData.h b/Applications/ApplicationsLib/ProjectData.h
index d5fa7f0f8604874c80e1d1c1c609237665443b69..a537af688a88bc615a1e58a25abcdedce75bd3d9 100644
--- a/Applications/ApplicationsLib/ProjectData.h
+++ b/Applications/ApplicationsLib/ProjectData.h
@@ -167,7 +167,7 @@ private:
 	/// Parses the process variables configuration and creates new variables for
 	/// each variable entry passing the corresponding subtree to the process
 	/// variable constructor.
-	void parseProcessVariables(BaseLib::ConfigTree const& process_variables_config);
+	void parseProcessVariables(BaseLib::ConfigTreeNew& process_variables_config);
 
 	/// Parses the parameters configuration and saves them in a list.
 	/// Checks if a parameter has name tag.
diff --git a/BaseLib/ConfigTreeNew-impl.h b/BaseLib/ConfigTreeNew-impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f2ad6521cf27277c10c589f21593c45a1be94b4
--- /dev/null
+++ b/BaseLib/ConfigTreeNew-impl.h
@@ -0,0 +1,159 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "ConfigTreeNew.h"
+
+#include <logog/include/logog.hpp>
+
+namespace BaseLib
+{
+
+//! Wraps a pair of iterators for use as a range in range-based for-loops.
+template<typename Iterator>
+class Range
+{
+public:
+    explicit Range(Iterator begin, Iterator end)
+        : _begin(begin), _end(end)
+    {}
+
+    Iterator begin() const { return _begin; }
+    Iterator end()   const { return _end; }
+private:
+    Iterator _begin;
+    Iterator _end;
+};
+
+template<typename T>
+T
+ConfigTreeNew::
+getConfParam(std::string const& param)
+{
+    auto p = getConfParamOptional<T>(param);
+    if (p) return *p;
+
+    error("Key <" + param + "> has not been found");
+    return T();
+}
+
+template<typename T>
+T
+ConfigTreeNew::
+getConfParam(std::string const& param, T const& default_value)
+{
+    auto p = getConfParamOptional<T>(param);
+    if (p) return *p;
+    return default_value;
+}
+
+template<typename T>
+boost::optional<T>
+ConfigTreeNew::
+getConfParamOptional(std::string const& param)
+{
+    checkUnique(param);
+    auto p = _tree->get_child_optional(param);
+
+    bool peek_only = p == boost::none;
+    markVisited<T>(param, peek_only);
+
+    if (p) {
+        auto v = p->get_value_optional<T>();
+        if (v) {
+            return v;
+        } else {
+            error("Value for key <" + param + "> `" + shortString(p->data())
+                  + "' not convertible to the desired type.");
+        }
+    }
+
+    return boost::none;
+}
+
+template<typename T>
+Range<ConfigTreeNew::ValueIterator<T> >
+ConfigTreeNew::
+getConfParamList(std::string const& param)
+{
+    checkUnique(param);
+    markVisited<T>(param, true);
+
+    auto p = _tree->equal_range(param);
+    return Range<ValueIterator<T> >(
+                ValueIterator<T>(p.first,  param, *this),
+                ValueIterator<T>(p.second, param, *this));
+}
+
+template<typename T>
+T
+ConfigTreeNew::
+peekConfParam(std::string const& param)
+{
+    checkKeyname(param);
+
+    auto p =_tree->get_child_optional(param);
+
+    if (!p) {
+        error("Key <" + param + "> has not been found");
+    } else {
+        try {
+            return p->get_value<T>();
+        } catch (boost::property_tree::ptree_bad_data) {
+            error("Value for key <" + param + "> `" + shortString(p->data())
+                  + "' not convertible to the desired type.");
+        }
+    }
+
+    return T();
+}
+
+template<typename T>
+void
+ConfigTreeNew::
+checkConfParam(std::string const& param, T const& value)
+{
+    if (getConfParam<T>(param) != value) {
+        error("The value of key <" + param + "> is not the expected one.");
+    }
+}
+
+template<typename Ch>
+void
+ConfigTreeNew::
+checkConfParam(std::string const& param, Ch const* value)
+{
+    if (getConfParam<std::string>(param) != value) {
+        error("The value of key <" + param + "> is not the expected one.");
+    }
+}
+
+
+template<typename T>
+ConfigTreeNew::CountType&
+ConfigTreeNew::
+markVisited(std::string const& key, bool peek_only)
+{
+    auto const type = std::type_index(typeid(T));
+
+    auto p = _visited_params.emplace(key, CountType{peek_only ? 0 : 1, type});
+
+    if (!p.second) { // no insertion happened
+        auto& v = p.first->second;
+        if (v.type == type) {
+            if (!peek_only) ++v.count;
+        } else {
+            error("There already was an attempt to obtain key <" + key
+                  + "> with type \"" + v.type.name() + "\" (now: \"" + type.name() + "\").");
+        }
+    }
+
+    return p.first->second;
+}
+
+}
diff --git a/BaseLib/ConfigTreeNew.cpp b/BaseLib/ConfigTreeNew.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..24b807d883c34582a7c6fa84dfd270b0bdf08bfa
--- /dev/null
+++ b/BaseLib/ConfigTreeNew.cpp
@@ -0,0 +1,224 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "ConfigTreeNew.h"
+
+namespace BaseLib
+{
+
+const char ConfigTreeNew::pathseparator = '/';
+const std::string ConfigTreeNew::key_chars_start = "abcdefghijklmnopqrstuvwxyz";
+const std::string ConfigTreeNew::key_chars = key_chars_start + "_0123456789";
+
+ConfigTreeNew::
+ConfigTreeNew(PTree const& tree,
+              Callback const& error_cb,
+              Callback const& warning_cb)
+    : _tree(&tree), _onerror(error_cb), _onwarning(warning_cb)
+{
+    if (!_onerror) {
+        ERR("ConfigTree: No valid error handler provided.");
+        std::abort();
+    }
+    if (!_onwarning) {
+        ERR("ConfigTree: No valid warning handler provided.");
+        std::abort();
+    }
+}
+
+ConfigTreeNew::
+ConfigTreeNew(PTree const& tree, ConfigTreeNew const& parent,
+              std::string const& root)
+    : _tree(&tree), _path(joinPaths(parent._path, root)),
+      _onerror(parent._onerror), _onwarning(parent._onwarning)
+{
+    checkKeyname(root);
+}
+
+ConfigTreeNew::
+ConfigTreeNew(ConfigTreeNew && other)
+	: _tree(other._tree)
+	, _path(other._path)
+	, _visited_params(std::move(other._visited_params))
+	, _onerror(other._onerror)
+	, _onwarning(other._onwarning)
+{
+	other._tree = nullptr;
+}
+
+ConfigTreeNew::~ConfigTreeNew()
+{
+	if (!_tree) return;
+
+	for (auto const& p : *_tree)
+	{
+		markVisitedDecrement(p.first);
+	}
+
+	for (auto const& p : _visited_params)
+	{
+		if (p.second.count > 0) {
+			warning("Key <" + p.first + "> has been read " + std::to_string(p.second.count)
+					+ " time(s) more than it was present in the configuration tree.");
+		} else if (p.second.count < 0) {
+			warning("Key <" + p.first + "> has been read " + std::to_string(-p.second.count)
+					+ " time(s) less than it was present in the configuration tree.");
+		}
+	}
+}
+
+ConfigTreeNew
+ConfigTreeNew::
+getConfSubtree(std::string const& root)
+{
+    if (auto t = getConfSubtreeOptional(root)) {
+        return std::move(*t);
+    } else {
+        error("Key <" + root + "> has not been found.");
+        return ConfigTreeNew(PTree(), *this, ""); // TODO that will crash
+    }
+}
+
+boost::optional<ConfigTreeNew>
+ConfigTreeNew::
+getConfSubtreeOptional(std::string const& root)
+{
+    checkUnique(root);
+    auto subtree = _tree->get_child_optional(root);
+
+    if (subtree) {
+        markVisited(root);
+        return boost::optional<ConfigTreeNew>(std::move(
+                ConfigTreeNew(*subtree, *this, root)));
+    } else {
+        markVisited(root, true);
+        return boost::optional<ConfigTreeNew>();
+    }
+}
+
+Range<ConfigTreeNew::SubtreeIterator>
+ConfigTreeNew::
+getConfSubtreeList(std::string const& root)
+{
+    checkUnique(root);
+    markVisited(root, true);
+
+    auto p = _tree->equal_range(root);
+
+    return Range<SubtreeIterator>(
+                SubtreeIterator(p.first,  root, *this),
+                SubtreeIterator(p.second, root, *this));
+}
+
+void ConfigTreeNew::ignoreConfParam(const std::string &param)
+{
+    checkUnique(param);
+    // if not found, peek only
+    bool peek_only = _tree->find(param) == _tree->not_found();
+    markVisited(param, peek_only);
+}
+
+void ConfigTreeNew::ignoreConfParamAll(const std::string &param)
+{
+    checkUnique(param);
+    auto& ct = markVisited(param, true);
+
+    auto p = _tree->equal_range(param);
+    for (auto it = p.first; it != p.second; ++it) {
+        ++ct.count;
+    }
+}
+
+
+void ConfigTreeNew::error(const std::string& message)
+{
+	_onerror(_path, message);
+}
+
+void ConfigTreeNew::warning(const std::string& message)
+{
+	_onwarning(_path, message);
+}
+
+
+void ConfigTreeNew::onerror(const std::string& path, const std::string& message)
+{
+    ERR("ConfigTree: At path <%s>: %s", path.c_str(), message.c_str());
+    std::abort();
+}
+
+void ConfigTreeNew::onwarning(const std::string& path, const std::string& message)
+{
+    WARN("ConfigTree: At path <%s>: %s", path.c_str(), message.c_str());
+}
+
+std::string ConfigTreeNew::shortString(const std::string &s)
+{
+    const std::size_t maxlen = 100;
+
+    if (s.size() < maxlen) return s;
+
+    return s.substr(0, maxlen-3) + "...";
+}
+
+
+void ConfigTreeNew::checkKeyname(std::string const& key)
+{
+	if (key.empty()) {
+		error("Search for empty key.");
+	} else if (key_chars_start.find(key.front()) == std::string::npos) {
+		error("Key <" + key + "> starts with an illegal character.");
+	} else if (key.find_first_not_of(key_chars, 1) != std::string::npos) {
+		error("Key <" + key + "> contains illegal characters.");
+	}
+}
+
+std::string ConfigTreeNew::
+joinPaths( const std::string &p1, const std::string &p2)
+{
+	if (p2.empty()) {
+		error("Second path to be joined is empty.");
+	}
+
+	if (p1.empty()) return p2;
+
+	return p1 + pathseparator + p2;
+}
+
+void ConfigTreeNew::checkUnique(const std::string &key)
+{
+	checkKeyname(key);
+
+	if (_visited_params.find(key) != _visited_params.end()) {
+		error("Key <" + key + "> has already been processed.");
+	}
+}
+
+ConfigTreeNew::CountType&
+ConfigTreeNew::
+markVisited(std::string const& key, bool peek_only)
+{
+    return markVisited<ConfigTreeNew>(key, peek_only);
+}
+
+void
+ConfigTreeNew::
+markVisitedDecrement(std::string const& key)
+{
+    auto const type = std::type_index(typeid(nullptr));
+
+    auto p = _visited_params.emplace(key, CountType{-1, type});
+
+    if (!p.second) { // no insertion happened
+        auto& v = p.first->second;
+        --v.count;
+    }
+}
+
+}
diff --git a/BaseLib/ConfigTreeNew.h b/BaseLib/ConfigTreeNew.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea660c36d7b9291cee14d8ee21c62c113a3099e5
--- /dev/null
+++ b/BaseLib/ConfigTreeNew.h
@@ -0,0 +1,392 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include "ConfigTree.h"
+
+#include <typeindex>
+#include <map>
+
+#include <functional>
+
+namespace BaseLib
+{
+
+template<typename Iterator> class Range;
+
+/*!
+ * Wrapper around a Boost Property Tree with some basic error reporting features.
+ *
+ * Features. This class:
+ *  * makes sure that every configuration setting in a Property Tree is read
+ *    exactly once. If some settings is not read (e.g. due to a typo), a warning message
+ *    is generated. The message contains a hint where it occured.
+ *  * enforces a naming scheme of settings: letters a-z, numbers 0-9, underscore
+ *  * provides some functionality to read lists of values using range-based for loops.
+ *  * has rather long method names that are easily greppable from the source code. So a list
+ *    of supported configuration options can be easily obtained from the source code.
+ *
+ * The purpose of this class is to reduce or completely avoid the amount of error-handling
+ * code in routines that take configuration parameters.
+ *
+ * Most methods of this class check that they have not been called before for the same
+ * \c ConfigTree and the same parameter. This behaviour helps to enforce that every parameter
+ * is read exactly once during parsing of the configuration settings.
+ *
+ * The most notable restriction of this class when compared to plain tree traversal is, that
+ * one must know all the XML tags (i.e. configuration parameters) at compile time. It is not
+ * possible to read from this class, which configuration parameters are present in the tree.
+ * This restriction, however, is intended, because it provides the possibility to get all
+ * existing configuration parameters from the source code.
+ */
+class ConfigTreeNew final
+{
+public:
+    /*!
+     * A wrapper around a Boost Iterator for iterating over ranges of subtrees.
+     *
+     * The methods of this class tell the associated (parent) \c ConfigTree object when
+     * a setting has been parsed.
+     */
+    class SubtreeIterator
+            : public std::iterator<std::input_iterator_tag, ConfigTreeNew>
+    {
+    public:
+        using Iterator = boost::property_tree::ptree::const_assoc_iterator;
+
+        explicit SubtreeIterator(Iterator it, std::string const& root,
+                                 ConfigTreeNew& parent)
+            : _it(it), _root(root), _parent(parent)
+        {}
+
+        SubtreeIterator& operator++() {
+            ++_it;
+            _has_incremented = true;
+            return *this;
+        }
+
+        ConfigTreeNew operator*() {
+            // if this iterator has been incremented since the last dereference,
+            // tell the _parent instance that a subtree now has been parsed.
+            if (_has_incremented) {
+                _has_incremented = false;
+                _parent.markVisited(_root);
+            }
+            return ConfigTreeNew(_it->second, _parent, _root);
+        }
+
+        bool operator==(SubtreeIterator const& other) const {
+            return _it == other._it;
+        }
+
+        bool operator!=(SubtreeIterator const& other) const {
+            return _it != other._it;
+        }
+
+    private:
+        bool _has_incremented = true;
+        Iterator _it;
+        std::string const _root;
+        ConfigTreeNew& _parent;
+    };
+
+
+    /*!
+     * A wrapper around a Boost Iterator for iterating over ranges of values.
+     *
+     * The methods of this class tell the associated (parent) \c ConfigTree object when
+     * a setting has been parsed.
+     */
+    template<typename ValueType>
+    class ValueIterator
+            : public std::iterator<std::input_iterator_tag, ValueType>
+    {
+    public:
+        using Iterator = boost::property_tree::ptree::const_assoc_iterator;
+
+        explicit ValueIterator(Iterator it, std::string const& root,
+                               ConfigTreeNew& parent)
+            : _it(it), _root(root), _parent(parent)
+        {}
+
+        ValueIterator<ValueType>& operator++() {
+            ++_it;
+            _has_incremented = true;
+            return *this;
+        }
+
+        ValueType operator*() {
+            // if this iterator has been incremented since the last dereference,
+            // tell the _parent instance that a setting now has been parsed.
+            if (_has_incremented) {
+                _has_incremented = false;
+                _parent.markVisited<ValueType>(_root);
+            }
+
+            if (_it->second.begin() != _it->second.end()) {
+                _parent.error("Configuration at key " + _root + " has subitems.");
+                return ValueType();
+            }
+
+            auto v = _it->second.get_value_optional<ValueType>();
+
+            if (v) return *v;
+
+            // TODO: change error method
+            _parent.error("Could not get value out of key " + _root + ".");
+            return ValueType();
+        }
+
+        bool operator==(ValueIterator<ValueType> const& other) const {
+            return _it == other._it;
+        }
+
+        bool operator!=(ValueIterator<ValueType> const& other) const {
+            return _it != other._it;
+        }
+
+    private:
+        bool _has_incremented = true;
+        Iterator _it;
+        std::string const _root;
+        ConfigTreeNew& _parent;
+    };
+
+    using PTree = boost::property_tree::ptree;
+
+    //! Type of the function objects used as callbacks.
+    //! The first argument denotes the path in the tree at which an event (warning/error)
+    //! occured, the second argument is the associated message
+    using Callback = std::function<void(const std::string& path,
+                                        const std::string& message)>;
+
+    /*! Creates a new instance wrapping the given Boost Property Tree.
+     *
+     * \param tree the Boost Property Tree to be wrapped
+     * \param error_cb callback function to be called on error.
+     * \param warning_cb callback function to be called on warning.
+     *
+     * The callback functions must be valid callable functions, i.e. not nullptr's.
+     * They are configurable in order to make unit tests of this class easier.
+     * They should not be provided in production code!
+     *
+     * If a custom error callback is provided, this function should break out of
+     * the normal execution order, e.g., by throwing or by calling std::abort(),
+     * because otherwise this class will effectively treat errors as no-errors.
+     */
+    explicit ConfigTreeNew(PTree const& tree,
+                           Callback const& error_cb = onerror,
+                           Callback const& warning_cb = onwarning);
+
+    //! copying is not compatible with the semantics of this class
+    ConfigTreeNew(ConfigTreeNew const&) = delete;
+
+    //! After being moved from, \c other is in an undefined state and must not be
+    //! used anymore!
+    ConfigTreeNew(ConfigTreeNew && other);
+
+    ConfigTreeNew() = delete;
+
+    void operator=(ConfigTreeNew const&) = delete;
+    void operator=(ConfigTreeNew &&) = delete;
+
+    /*! Get parameter \c param of type \c T from the configuration tree.
+     *
+     * \return the value looked for or a default constructed value \c T() in the case of
+     *         an error. For the behaviour in case of an error, see also the documentation
+     *         of the method error().
+     *
+     * \pre \c param must not have been read before from this ConfigTree.
+     */
+    template<typename T> T
+    getConfParam(std::string const& param);
+
+    /*! Get parameter \c param of type \c T from the configuration tree or the \c default_value.
+     *
+     * This method has a similar behaviour as getConfParam(std::string const&) except in case
+     * of errors the \c default_value is returned.
+     *
+     * \pre \c param must not have been read before from this ConfigTree.
+     */
+    template<typename T> T
+    getConfParam(std::string const& param, T const& default_value);
+
+    /*! Get parameter \c param of type \c T from the configuration tree if present
+     *
+     * This method has a similar behaviour as getConfParam(std::string const&) except
+     * no errors are raised. Rather it can be told from the return value if the
+     * parameter could be read.
+     *
+     * \pre \c param must not have been read before from this ConfigTree.
+     */
+    template<typename T> boost::optional<T>
+    getConfParamOptional(std::string const& param);
+
+    /*! Returns all parameters with the name \c param from the current level of the tree.
+     *
+     * The return value is suitable to be used with range-base for-loops.
+     *
+     * \pre \c param must not have been read before from this ConfigTree.
+     */
+    template<typename T> Range<ValueIterator<T> >
+    getConfParamList(std::string const& param);
+
+    /*! Peek at a parameter \c param of type \c T from the configuration tree.
+     *
+     * This method is an exception to the single-read rule. It is meant to be used to
+     * tell from a ConfigTree instance where to pass that instance on for further processing.
+     *
+     * Return value and error behaviour are the same as for getConfParam(std::string const&).
+     */
+    template<typename T> T
+    peekConfParam(std::string const& param);
+
+    /*! Assert that \c param has the given \c value.
+     *
+     * Convenience method combining getConfParam(std::string const&) with a check.
+     */
+    template<typename T> void
+    checkConfParam(std::string const& param, T const& value);
+
+    //! Make checkConfParam() work for string literals.
+    template<typename Ch> void
+    checkConfParam(std::string const& param, Ch const* value);
+
+    /*! Get the subtree rooted at \c root
+     *
+     * If \c root is not found error() is called.
+     *
+     * \pre \c root must not have been read before from this ConfigTree.
+     */
+    ConfigTreeNew
+    getConfSubtree(std::string const& root);
+
+    /*! Get the subtree rooted at \c root if present
+     *
+     * \pre \c root must not have been read before from this ConfigTree.
+     */
+    boost::optional<ConfigTreeNew>
+    getConfSubtreeOptional(std::string const& root);
+
+    /*! Get all subtrees that have a root \c root from the current level of the tree.
+     *
+     * The return value is suitable to be used with range-base for-loops.
+     *
+     * \pre \c root must not have been read before from this ConfigTree.
+     */
+    Range<SubtreeIterator>
+    getConfSubtreeList(std::string const& root);
+
+    /*! Tell this instance to ignore parameter \c param.
+     *
+     * This method is used to avoid warning messages.
+     *
+     * \pre \c root must not have been read before from this ConfigTree.
+     */
+    void ignoreConfParam(std::string const& param);
+
+    /*! Tell this instance to ignore all parameters \c param on the current level of the tree.
+     *
+     * This method is used to avoid warning messages.
+     *
+     * \pre \c root must not have been read before from this ConfigTree.
+     */
+    void ignoreConfParamAll(std::string const& param);
+
+    //! The destructor performs the check if all nodes at the current level of the tree
+    //! have been read.
+    ~ConfigTreeNew();
+
+private:
+    struct CountType
+    {
+        int count;
+        std::type_index type;
+    };
+
+    //! Used for wrapping a subtree
+    explicit ConfigTreeNew(PTree const& tree, ConfigTreeNew const& parent, std::string const& root);
+
+    //! Called if an error occurs. Will call the error callback.
+    //! This method only acts as a helper method.
+    void error(std::string const& message);
+
+    //! Called for printing warning messages. Will call the warning callback.
+    //! This method only acts as a helper method.
+    void warning(std::string const& message);
+
+    //! Checks if \c key complies with the rules [a-z0-9_].
+    void checkKeyname(std::string const& key);
+
+    //! Used to generate the path of a subtree.
+    std::string joinPaths(std::string const& p1, std::string const& p2);
+
+    //! Asserts that the \c key has not been read yet.
+    void checkUnique(std::string const& key);
+
+    /*! Keeps track of the key \c key and its value type \c T.
+     *
+     * This method asserts that a key is read always with the same type.
+     *
+     * \c param peek_only if true, do not change the read-count of the given key.
+     */
+    template<typename T>
+    CountType& markVisited(std::string const& key, bool peek_only = false);
+
+    /*! Keeps track of the key \c key and its value type ConfigTree.
+     *
+     * This method asserts that a key is read always with the same type.
+     *
+     * \c param peek_only if true, do not change the read-count of the given key.
+     */
+    CountType& markVisited(std::string const& key, bool peek_only = false);
+
+    //! Used in the destructor to compute the difference between number of reads of a parameter
+    //! and the number of times it exists in the ConfigTree
+    void markVisitedDecrement(std::string const& key);
+
+    //! Default error callback function
+    //! Will print an error message and call std::abort()
+    static void onerror(std::string const& path, std::string const& message);
+
+    //! Default warning callback function
+    //! Will print a warning message
+    static void onwarning(std::string const& path, std::string const& message);
+
+    //! returns a short string at suitable for error/warning messages
+    static std::string shortString(std::string const& s);
+
+    //! The wrapped tree.
+    boost::property_tree::ptree const* _tree;
+
+    //! A path printed in error/warning messages.
+    std::string const _path;
+
+    //! A map key -> (count, type) keeping track which parameters have been read how often
+    //! and which datatype they have.
+    std::map<std::string, CountType> _visited_params;
+
+    const Callback _onerror;
+    const Callback _onwarning;
+
+    //! Character separating two path components.
+    static const char pathseparator;
+
+    //! Set of allowed characters as the first letter of a key name.
+    static const std::string key_chars_start;
+
+    //! Set of allowed characters in a key name.
+    static const std::string key_chars;
+};
+
+}
+
+#include "ConfigTreeNew-impl.h"
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7719a8be4f34f9e48de036d93fc154c366857ca8..45b38e1afa99ebe7b1161b3a5b61800371cae120 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,9 @@
  - Axis aligned bounding box:
    - Is now a from the right half-open interval.
    - Removed template from class declaration.
+ - New configuration tree parser
+   - Checks configuration parameters more strictly, automatically prints error/warning messages.
+   - Requires Boost >= 1.56 because of boost::optional with move semantics.
 
 ### Infrastructure
 
diff --git a/ProcessLib/InitialCondition.cpp b/ProcessLib/InitialCondition.cpp
index bad0bb68a43aae732c757e30104f5fe32a9d8401..ff0789664f198d420a759bc8897da15235e9c60e 100644
--- a/ProcessLib/InitialCondition.cpp
+++ b/ProcessLib/InitialCondition.cpp
@@ -16,46 +16,40 @@
 #include "MeshLib/Elements/Element.h"
 #include "MeshLib/Mesh.h"
 
+#include "BaseLib/ConfigTreeNew.h"
+
 namespace ProcessLib
 {
 std::unique_ptr<InitialCondition> createUniformInitialCondition(
-    BaseLib::ConfigTree const& config)
+    BaseLib::ConfigTreeNew& config)
 {
-	auto value = config.get_optional<double>("value");
-	if (!value)
-	{
-		ERR("Could not find required parameter value.");
-		std::abort();
-	}
-	DBUG("Using value %g", *value);
+	config.checkConfParam("type", "Uniform");
+
+	auto value = config.getConfParam<double>("value");
+	DBUG("Using value %g", value);
 
 	return std::unique_ptr<InitialCondition>(
-	    new UniformInitialCondition(*value));
+	    new UniformInitialCondition(value));
 }
 
 std::unique_ptr<InitialCondition> createMeshPropertyInitialCondition(
-    BaseLib::ConfigTree const& config, MeshLib::Mesh const& mesh)
+    BaseLib::ConfigTreeNew& config, MeshLib::Mesh const& mesh)
 {
-	auto field_name = config.get_optional<std::string>("field_name");
-	if (!field_name)
-	{
-		ERR("Could not find required parameter field_name.");
-		std::abort();
-	}
-	DBUG("Using field_name %s", field_name->c_str());
+	auto field_name = config.getConfParam<std::string>("field_name");
+	DBUG("Using field_name %s", field_name.c_str());
 
-	if (!mesh.getProperties().hasPropertyVector(*field_name))
+	if (!mesh.getProperties().hasPropertyVector(field_name))
 	{
 		ERR("The required property %s does not exists in the mesh.",
-		    field_name->c_str());
+		    field_name.c_str());
 		std::abort();
 	}
 	auto const& property =
-	    mesh.getProperties().template getPropertyVector<double>(*field_name);
+	    mesh.getProperties().template getPropertyVector<double>(field_name);
 	if (!property)
 	{
 		ERR("The required property %s is not of the requested type.",
-		    field_name->c_str());
+		    field_name.c_str());
 		std::abort();
 	}
 
diff --git a/ProcessLib/InitialCondition.h b/ProcessLib/InitialCondition.h
index b3093bc39308d8524d004b38cfa215e56e2d8ae7..b8a6831cdf80f6ff40ae5fdf01cf58300ad4348e 100644
--- a/ProcessLib/InitialCondition.h
+++ b/ProcessLib/InitialCondition.h
@@ -15,6 +15,11 @@
 #include "MeshLib/Node.h"
 #include "MeshLib/PropertyVector.h"
 
+namespace BaseLib
+{
+class ConfigTreeNew;
+}
+
 namespace MeshLib
 {
 template <typename>
@@ -52,7 +57,7 @@ private:
 
 /// Construct a UniformInitialCondition from configuration.
 std::unique_ptr<InitialCondition> createUniformInitialCondition(
-    BaseLib::ConfigTree const& config);
+    BaseLib::ConfigTreeNew& config);
 
 /// Distribution of values given by a mesh property defined on nodes.
 class MeshPropertyInitialCondition : public InitialCondition
@@ -76,7 +81,7 @@ private:
 
 /// Construct a MeshPropertyInitialCondition from configuration.
 std::unique_ptr<InitialCondition> createMeshPropertyInitialCondition(
-    BaseLib::ConfigTree const& config, MeshLib::Mesh const& mesh);
+    BaseLib::ConfigTreeNew& config, MeshLib::Mesh const& mesh);
 
 }  // namespace ProcessLib
 
diff --git a/ProcessLib/NeumannBcConfig.h b/ProcessLib/NeumannBcConfig.h
index 5cccdadb7ff782735bd562bf93a81ea1d7ce0300..e65d2d972258aa1d3fc310ac5f2cec3209750fe8 100644
--- a/ProcessLib/NeumannBcConfig.h
+++ b/ProcessLib/NeumannBcConfig.h
@@ -12,7 +12,7 @@
 
 #include "logog/include/logog.hpp"
 
-#include "BaseLib/ConfigTree.h"
+#include "BaseLib/ConfigTreeNew.h"
 #include "MathLib/ConstantFunction.h"
 #include "MeshGeoToolsLib/BoundaryElementsSearcher.h"
 #include "MeshLib/Elements/Element.h"
@@ -44,12 +44,13 @@ class NeumannBcConfig : public BoundaryConditionConfig
 {
 public:
     NeumannBcConfig(GeoLib::GeoObject const* const geometry,
-            BaseLib::ConfigTree const& config)
+            BaseLib::ConfigTreeNew& config)
         : BoundaryConditionConfig(geometry)
     {
         DBUG("Constructing NeumannBcConfig from config.");
+        config.checkConfParam("type", "UniformNeumann");
 
-        double const value = config.get<double>("value", 0);
+        double const value = config.getConfParam<double>("value");
         DBUG("Using value %g", value);
 
         _function = new MathLib::ConstantFunction<double>(value);
diff --git a/ProcessLib/ProcessVariable.cpp b/ProcessLib/ProcessVariable.cpp
index 8ccf66315e9928ff02aacd47d88e577d85db6daa..58b3a083f5e27f72b22c46cbafca69a74c81ffff 100644
--- a/ProcessLib/ProcessVariable.cpp
+++ b/ProcessLib/ProcessVariable.cpp
@@ -14,54 +14,52 @@
 #include "GeoLib/GEOObjects.h"
 #include "MeshLib/Mesh.h"
 
+#include "BaseLib/ConfigTreeNew.h"
+
 namespace ProcessLib
 {
-ProcessVariable::ProcessVariable(BaseLib::ConfigTree const& config,
+ProcessVariable::ProcessVariable(BaseLib::ConfigTreeNew& config,
                                  MeshLib::Mesh const& mesh,
                                  GeoLib::GEOObjects const& geometries)
-    : _name(config.get<std::string>("name")), _mesh(mesh)
+    : _name(config.getConfParam<std::string>("name"))
+    , _mesh(mesh)
 {
 	DBUG("Constructing process variable %s", this->_name.c_str());
 
 	// Initial condition
+	if (auto ic_config = config.getConfSubtreeOptional("initial_condition"))
 	{
-		auto const& ic_config = config.find("initial_condition");
-		if (ic_config == config.not_found())
-			INFO("No initial condition found.");
-
-		std::string const type =
-		    config.get<std::string>("initial_condition.type");
+		auto const type = ic_config->peekConfParam<std::string>("type");
 		if (type == "Uniform")
 		{
 			_initial_condition =
-			    createUniformInitialCondition(ic_config->second);
+			    createUniformInitialCondition(*ic_config);
 		}
 		else if (type == "MeshProperty")
 		{
 			_initial_condition =
-			    createMeshPropertyInitialCondition(ic_config->second, _mesh);
+			    createMeshPropertyInitialCondition(*ic_config, _mesh);
 		}
 		else
 		{
 			ERR("Unknown type of the initial condition.");
 		}
 	}
+	else
+	{
+		INFO("No initial condition found.");
+	}
 
 	// Boundary conditions
+	if (auto bcs_config = config.getConfSubtreeOptional("boundary_conditions"))
 	{
-		auto const& bcs_config = config.find("boundary_conditions");
-		if (bcs_config == config.not_found())
-			INFO("No boundary conditions found.");
-
-		for (auto const& bc_iterator : bcs_config->second)
+		for (auto bc_config
+			 : bcs_config->getConfSubtreeList("boundary_condition"))
 		{
-			BaseLib::ConfigTree const& bc_config = bc_iterator.second;
-
-			// Find corresponding GeoObject
-			std::string const geometrical_set_name =
-			    bc_config.get<std::string>("geometrical_set");
-			std::string const geometry_name =
-			    bc_config.get<std::string>("geometry");
+			auto const geometrical_set_name =
+					bc_config.getConfParam<std::string>("geometrical_set");
+			auto const geometry_name =
+					bc_config.getConfParam<std::string>("geometry");
 
 			GeoLib::GeoObject const* const geometry =
 			    geometries.getGeoObject(geometrical_set_name, geometry_name);
@@ -70,7 +68,7 @@ ProcessVariable::ProcessVariable(BaseLib::ConfigTree const& config,
 			    GeoLib::convertGeoTypeToString(geometry->getGeoType()).c_str());
 
 			// Construct type dependent boundary condition
-			std::string const type = bc_config.get<std::string>("type");
+			auto const type = bc_config.peekConfParam<std::string>("type");
 
 			if (type == "UniformDirichlet")
 			{
@@ -88,7 +86,12 @@ ProcessVariable::ProcessVariable(BaseLib::ConfigTree const& config,
 				    type.c_str());
 			}
 		}
+	} else {
+		INFO("No boundary conditions found.");
 	}
+
+	// Source Terms
+	config.ignoreConfParam("source_terms");
 }
 
 ProcessVariable::ProcessVariable(ProcessVariable&& other)
diff --git a/ProcessLib/ProcessVariable.h b/ProcessLib/ProcessVariable.h
index f83b61e760166b91181508fa4b193697aca26c3b..957cdc45f6d771aef0fe41da70145bd8677affba 100644
--- a/ProcessLib/ProcessVariable.h
+++ b/ProcessLib/ProcessVariable.h
@@ -46,7 +46,7 @@ namespace ProcessLib
 class ProcessVariable
 {
 public:
-	ProcessVariable(BaseLib::ConfigTree const& config, MeshLib::Mesh const& mesh,
+	ProcessVariable(BaseLib::ConfigTreeNew& config, MeshLib::Mesh const& mesh,
 	                GeoLib::GEOObjects const& geometries);
 
 	ProcessVariable(ProcessVariable&&);
diff --git a/ProcessLib/UniformDirichletBoundaryCondition.h b/ProcessLib/UniformDirichletBoundaryCondition.h
index 5eed826238821c2572b273205357b8e969600005..2275e49d4f97162f54546bb6aa50cd6e578031de 100644
--- a/ProcessLib/UniformDirichletBoundaryCondition.h
+++ b/ProcessLib/UniformDirichletBoundaryCondition.h
@@ -17,7 +17,7 @@
 
 #include "NumericsConfig.h" // for GlobalIndexType
 
-#include "BaseLib/ConfigTree.h"
+#include "BaseLib/ConfigTreeNew.h"
 #include "AssemblerLib/LocalToGlobalIndexMap.h"
 #include "MeshGeoToolsLib/MeshNodeSearcher.h"
 
@@ -37,12 +37,13 @@ class UniformDirichletBoundaryCondition
 {
 public:
     UniformDirichletBoundaryCondition(GeoLib::GeoObject const* const geometry,
-                                      BaseLib::ConfigTree const& config)
+                                      BaseLib::ConfigTreeNew& config)
         : _geometry(geometry)
     {
         DBUG("Constructing UniformDirichletBoundaryCondition from config.");
+        config.checkConfParam("type", "UniformDirichlet");
 
-        _value = config.get<double>("value", 0);
+        _value = config.getConfParam<double>("value");
         DBUG("Using value %g", _value);
     }
 
diff --git a/Tests/BaseLib/TestConfigTree.cpp b/Tests/BaseLib/TestConfigTree.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ffdf50ddf555b4b4be435a04641aa2ed0cb3f33a
--- /dev/null
+++ b/Tests/BaseLib/TestConfigTree.cpp
@@ -0,0 +1,430 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <logog/include/logog.hpp>
+
+#include <boost/property_tree/xml_parser.hpp>
+#include <sstream>
+
+#include "BaseLib/ConfigTreeNew.h"
+
+#define DO_EXPECT(cbs, error, warning) do  { \
+        if (error)   EXPECT_TRUE((cbs).get_error());   else EXPECT_FALSE((cbs).get_error()); \
+        if (warning) EXPECT_TRUE((cbs).get_warning()); else EXPECT_FALSE((cbs).get_warning()); \
+        (cbs).reset(); \
+    } while(false)
+
+#define RUN_SAFE(expr) do { \
+        try { expr; } catch(Exc) {} \
+    } while (false)
+
+// Exception thrown by the error callback of the class below
+class Exc {};
+
+// class that provides callback functions used with ConfigTreeNew
+class Callbacks
+{
+public:
+    BaseLib::ConfigTreeNew::Callback
+    get_error_cb() {
+        return [this](std::string const& path, std::string const& message)
+        {
+            (void) path; (void) message;
+            DBUG("error <%s> : %s", path.c_str(), message.c_str());
+            _error = true;
+            throw Exc(); // throw in order to stop normal execution
+        };
+    }
+
+    BaseLib::ConfigTreeNew::Callback
+    get_warning_cb() {
+        return [this](std::string const& path, std::string const& message)
+        {
+            (void) path; (void) message;
+            DBUG("warning <%s> : %s", path.c_str(), message.c_str());
+            _warning = true;
+        };
+    }
+
+    bool get_error()   const { return _error; }
+    bool get_warning() const { return _warning; }
+    void reset() { _error = false; _warning = false; }
+
+private:
+    bool _error = false;
+    bool _warning = false;
+};
+
+
+TEST(BaseLibConfigTree, ConfigTreeEmpty)
+{
+    boost::property_tree::ptree ptree;
+    Callbacks cbs;
+
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+        (void) conf;
+    } // ConfigTree destroyed here
+
+    DO_EXPECT(cbs, false, false);
+}
+
+
+TEST(BaseLibConfigTree, ConfigTreeGet)
+{
+    const char xml[] =
+            "<double>5.6e-4</double>"
+            "<bool>true</bool>"
+            "<int>5</int>"
+            "<sub>"
+            "  <float>6.1</float>"
+            "  <float2>0.1</float2>"
+            "  <ignored/>"
+            "  <ignored2/>"
+            "  <ignored2/>"
+            "</sub>"
+            "<x>Y</x>";
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        EXPECT_EQ(5.6e-4, conf.getConfParam<double>("double")); // read certain types
+        DO_EXPECT(cbs, false, false);
+        EXPECT_TRUE(conf.getConfParam<bool>("bool"));
+        DO_EXPECT(cbs, false, false);
+        EXPECT_EQ(5, conf.getConfParam<int>("int"));
+        DO_EXPECT(cbs, false, false);
+
+        EXPECT_EQ(8, conf.getConfParam<int>("intx", 8)); // reading with default value
+        DO_EXPECT(cbs, false, false);
+
+        {
+            auto sub = conf.getConfSubtree("sub");
+            DO_EXPECT(cbs, false, false);
+
+            EXPECT_EQ(6.1f, sub.getConfParam<float>("float"));
+            DO_EXPECT(cbs, false, false);
+
+            if (auto f2 = sub.getConfParamOptional<float>("float2")) { // read optional value
+                EXPECT_EQ(0.1f, *f2);
+                DO_EXPECT(cbs, false, false);
+            }
+
+            auto f3 = sub.getConfParamOptional<float>("float3"); // optional value not existent
+            ASSERT_FALSE(f3);
+            DO_EXPECT(cbs, false, false);
+
+            sub.ignoreConfParam("ignored");
+            DO_EXPECT(cbs, false, false);
+            sub.ignoreConfParamAll("ignored2");
+            DO_EXPECT(cbs, false, false);
+            sub.ignoreConfParamAll("ignored4"); // I can ignore nonexistent stuff
+            DO_EXPECT(cbs, false, false);
+
+            // I can not ignore stuff that I already read
+            // this also makes sure that the subtree inherits the callbacks properly
+            RUN_SAFE(sub.ignoreConfParam("float"));
+            DO_EXPECT(cbs, true, false);
+        }
+        for (int i : {0, 1, 2}) {
+            (void) i;
+            EXPECT_EQ("Y", conf.peekConfParam<std::string>("x"));
+            DO_EXPECT(cbs, false, false);
+        }
+        conf.checkConfParam<std::string>("x", "Y");
+        DO_EXPECT(cbs, false, false);
+    } // ConfigTree destroyed here
+    DO_EXPECT(cbs, false, false);
+}
+
+
+TEST(BaseLibConfigTree, ConfigTreeIncompleteParse)
+{
+    const char xml[] =
+            "<double>5.6</double>"
+            "<bool>true</bool>"
+            ;
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        EXPECT_EQ(5.6, conf.getConfParam<double>("double")); // read certain types
+        DO_EXPECT(cbs, false, false);
+    } // ConfigTree destroyed here
+    DO_EXPECT(cbs, false, true); // expect warning because I didn't read everything
+}
+
+
+TEST(BaseLibConfigTree, ConfigTreeCheckRange)
+{
+    const char xml[] =
+            "<val><int>0</int></val>"
+            "<val><int>1</int></val>"
+            "<val><int>2</int></val>"
+            "<int>0</int>"
+            "<int>1</int>"
+            "<int>2</int>";
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        {
+            auto list = conf.getConfSubtreeList("val");
+            DO_EXPECT(cbs, false, false);
+            EXPECT_EQ(3, std::distance(list.begin(), list.end()));
+            DO_EXPECT(cbs, false, false);
+            EXPECT_EQ(3, std::distance(list.begin(), list.end()));
+            DO_EXPECT(cbs, false, false);
+        }
+
+        {
+            auto list = conf.getConfParamList<int>("int");
+            DO_EXPECT(cbs, false, false);
+            EXPECT_EQ(3, std::distance(list.begin(), list.end()));
+            DO_EXPECT(cbs, false, false);
+            EXPECT_EQ(3, std::distance(list.begin(), list.end()));
+            DO_EXPECT(cbs, false, false);
+        }
+
+    } // ConfigTree destroyed here
+
+    // there will be warnings because I don't process the list entries
+    DO_EXPECT(cbs, false, true);
+}
+
+
+TEST(BaseLibConfigTree, ConfigTreeGetSubtreeList)
+{
+    const char xml[] =
+            "<val><int>0</int></val>"
+            "<val><int>1</int></val>"
+            "<val><int>2</int></val>";
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        int i = 0;
+        for (auto ct : conf.getConfSubtreeList("val"))
+        {
+            EXPECT_EQ(i, ct.getConfParam<int>("int"));
+            DO_EXPECT(cbs, false, false);
+            ++i;
+        }
+    } // ConfigTree destroyed here
+    DO_EXPECT(cbs, false, false);
+}
+
+
+TEST(BaseLibConfigTree, ConfigTreeGetValueList)
+{
+    const char xml[] =
+            "<int>0</int>"
+            "<int>1</int>"
+            "<int>2</int>";
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        int n = 0;
+        for (auto i : conf.getConfParamList<int>("int"))
+        {
+            EXPECT_EQ(n, i);
+            DO_EXPECT(cbs, false, false);
+            ++n;
+        }
+    } // ConfigTree destroyed here
+    DO_EXPECT(cbs, false, false);
+}
+
+
+TEST(BaseLibConfigTree, ConfigTreeNoConversion)
+{
+    const char xml[] =
+            "<int>5.6</int>"         // not convertible to int
+            "<double>5.6tz</double>" // not convertible to double
+            "<non_double>0.1x</non_double>" // not either convertible to double
+            "<bool>true</bool>"
+            "<ign/>"
+            "<ign2/><ign2/><ign2/>"
+            ;
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        RUN_SAFE(conf.getConfParam<int>("int"));
+        DO_EXPECT(cbs, true, false);
+        RUN_SAFE(conf.ignoreConfParam("int")); // after failure I also cannot ignore something
+        DO_EXPECT(cbs, true, false);
+
+        RUN_SAFE(conf.getConfParam<double>("double"));
+        DO_EXPECT(cbs, true, false);
+
+        // peek value existent but not convertible
+        RUN_SAFE(conf.peekConfParam<double>("non_double"));
+        DO_EXPECT(cbs, true, false);
+
+        // optional value existent but not convertible
+        RUN_SAFE(
+            auto d = conf.getConfParamOptional<double>("non_double");
+            ASSERT_FALSE(d);
+        );
+        DO_EXPECT(cbs, true, false);
+
+        // assert that I can only ignore something once
+        RUN_SAFE(conf.ignoreConfParam("ign"));
+        DO_EXPECT(cbs, false, false);
+        RUN_SAFE(conf.ignoreConfParam("ign"));
+        DO_EXPECT(cbs, true, false);
+        RUN_SAFE(conf.ignoreConfParamAll("ign2"));
+        DO_EXPECT(cbs, false, false);
+        RUN_SAFE(conf.ignoreConfParamAll("ign2"));
+        DO_EXPECT(cbs, true, false);
+
+        // assert that I cannot read a parameter twice
+        RUN_SAFE(conf.getConfParam<bool>("bool"));
+        DO_EXPECT(cbs, false, false);
+        RUN_SAFE(conf.getConfParam<bool>("bool"));
+        DO_EXPECT(cbs, true, false);
+
+    } // ConfigTree destroyed here
+
+    // There will bewarnings because I don't succeed in reading every setting,
+    // and furthermore I read some setting too often.
+    DO_EXPECT(cbs, false, false);
+}
+
+
+TEST(BaseLibConfigTree, BadKeynames)
+{
+    const char xml[] = "";
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        for (std::string tag : { "<", "Z", ".", "$", "0", "", "/" })
+        {
+            RUN_SAFE(conf.getConfParam<int>(tag));
+            DO_EXPECT(cbs, true, false);
+            RUN_SAFE(conf.getConfParam<int>(tag, 500));
+            DO_EXPECT(cbs, true, false);
+            RUN_SAFE(conf.getConfParamOptional<int>(tag));
+            DO_EXPECT(cbs, true, false);
+            RUN_SAFE(conf.getConfParamList<int>(tag));
+
+            DO_EXPECT(cbs, true, false);
+            RUN_SAFE(conf.peekConfParam<int>(tag));
+            DO_EXPECT(cbs, true, false);
+            RUN_SAFE(conf.checkConfParam<int>(tag, 500));
+
+            DO_EXPECT(cbs, true, false);
+            RUN_SAFE(conf.getConfSubtree(tag));
+            DO_EXPECT(cbs, true, false);
+            RUN_SAFE(conf.getConfSubtreeOptional(tag));
+            DO_EXPECT(cbs, true, false);
+            RUN_SAFE(conf.getConfSubtreeList(tag));
+            DO_EXPECT(cbs, true, false);
+        }
+
+    } // ConfigTree destroyed here
+
+    DO_EXPECT(cbs, false, false);
+}
+
+// String literals are somewhat special for template classes
+TEST(BaseLibConfigTree, ConfigTreeStringLiterals)
+{
+    const char xml[] =
+            "<s>test</s>"
+            "<t>Test</t>";
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        EXPECT_EQ("test", conf.getConfParam<std::string>("s", "XX"));
+        DO_EXPECT(cbs, false, false);
+
+        EXPECT_EQ("XX",   conf.getConfParam<std::string>("n", "XX"));
+        DO_EXPECT(cbs, false, false);
+
+        conf.checkConfParam("t", "Test");
+        DO_EXPECT(cbs, false, false);
+    } // ConfigTree destroyed here
+    DO_EXPECT(cbs, false, false);
+}
+
+// String literals are somewhat special for template classes
+TEST(BaseLibConfigTree, ConfigTreeMove)
+{
+    const char xml[] =
+            "<s>test</s>"
+            "<t>Test</t>";
+
+    boost::property_tree::ptree ptree;
+    std::istringstream xml_str(xml);
+    read_xml(xml_str, ptree);
+
+    Callbacks cbs;
+    {
+        BaseLib::ConfigTreeNew conf(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+
+        EXPECT_EQ("test", conf.getConfParam<std::string>("s", "XX"));
+        DO_EXPECT(cbs, false, false);
+
+        BaseLib::ConfigTreeNew conf2(std::move(conf));
+
+        EXPECT_EQ("XX",   conf2.getConfParam<std::string>("n", "XX"));
+        DO_EXPECT(cbs, false, false);
+
+        conf2.checkConfParam("t", "Test");
+        DO_EXPECT(cbs, false, false);
+    } // ConfigTree destroyed here
+    DO_EXPECT(cbs, false, false);
+}
+