diff --git a/BaseLib/ConfigTreeNew.cpp b/BaseLib/ConfigTreeNew.cpp
index eed2bfb36cbc5a245404b78893d8222a5a817a0c..8373a7facfcd5350ebc456cc4f1bf3b2b389c77c 100644
--- a/BaseLib/ConfigTreeNew.cpp
+++ b/BaseLib/ConfigTreeNew.cpp
@@ -54,37 +54,21 @@ ConfigTreeNew(ConfigTreeNew && other)
 
 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.");
-        }
-    }
+    checkFullyRead();
 }
 
 ConfigTreeNew&
 ConfigTreeNew::
 operator=(ConfigTreeNew&& other)
 {
-    _tree = other._tree;
-    other._tree = nullptr;
-    _path = other._path;
-    _visited_params = std::move(other._visited_params);
+    checkFullyRead();
 
-    // TODO Caution: That might be a very nontrivial operation (copying a std::function).
-    _onerror = other._onerror;
-    _onwarning = other._onwarning;
+    _tree           = other._tree;
+    other._tree     = nullptr;
+    _path           = std::move(other._path);
+    _visited_params = std::move(other._visited_params);
+    _onerror        = std::move(other._onerror);
+    _onwarning      = std::move(other._onwarning);
 
     return *this;
 }
@@ -236,4 +220,26 @@ markVisitedDecrement(std::string const& key) const
     }
 }
 
+void
+ConfigTreeNew::checkFullyRead() const
+{
+    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.");
+        }
+    }
+}
+
 }
diff --git a/BaseLib/ConfigTreeNew.h b/BaseLib/ConfigTreeNew.h
index a14748733b21bf773bd6935cd61b5791f4f52bb3..50f55b8ea91e9b0abfbbd9a09cd54a9b96bc931b 100644
--- a/BaseLib/ConfigTreeNew.h
+++ b/BaseLib/ConfigTreeNew.h
@@ -192,8 +192,6 @@ public:
     //! used anymore!
     ConfigTreeNew(ConfigTreeNew && other);
 
-    ConfigTreeNew() = delete;
-
     //! copying is not compatible with the semantics of this class
     ConfigTreeNew& operator=(ConfigTreeNew const&) = delete;
 
@@ -364,6 +362,10 @@ private:
     //! and the number of times it exists in the ConfigTree
     void markVisitedDecrement(std::string const& key) const;
 
+    //! Helper method that checks if the top level of this tree has
+    //! been red entirely (and not too often).
+    void checkFullyRead() const;
+
     //! returns a short string at suitable for error/warning messages
     static std::string shortString(std::string const& s);
 
@@ -375,6 +377,11 @@ private:
 
     //! A map key -> (count, type) keeping track which parameters have been read how often
     //! and which datatype they have.
+    //!
+    //! This member will be written to when reading from the config tree.
+    //! Therefore it has to be mutable in order to be able to read from
+    //! constant instances, e.g., those passed as constant references to
+    //! temporaries.
     mutable std::map<std::string, CountType> _visited_params;
 
     Callback _onerror;
diff --git a/Tests/BaseLib/TestConfigTree.cpp b/Tests/BaseLib/TestConfigTree.cpp
index 250ac3e15dc5367aa04bfb30e86c720236653711..7b5bb62362e05c8be7ce8cea9c27468ce2b5a2d9 100644
--- a/Tests/BaseLib/TestConfigTree.cpp
+++ b/Tests/BaseLib/TestConfigTree.cpp
@@ -400,7 +400,7 @@ TEST(BaseLibConfigTree, ConfigTreeStringLiterals)
 }
 
 // String literals are somewhat special for template classes
-TEST(BaseLibConfigTree, ConfigTreeMove)
+TEST(BaseLibConfigTree, ConfigTreeMoveConstruct)
 {
     const char xml[] =
             "<s>test</s>"
@@ -428,3 +428,36 @@ TEST(BaseLibConfigTree, ConfigTreeMove)
     DO_EXPECT(cbs, false, false);
 }
 
+// String literals are somewhat special for template classes
+TEST(BaseLibConfigTree, ConfigTreeMoveAssign)
+{
+    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(ptree, cbs.get_error_cb(), cbs.get_warning_cb());
+        conf2 = std::move(conf);
+        // Expect warning because config tree has not been traversed
+        // entirely before.
+        DO_EXPECT(cbs, false, true);
+
+        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);
+}
+