[continued from previous message]
++ source << fmt::format("const ::Opm::ParserKeyword Builtin::get_{0}() {{ return {0}(); }};\n",kw.className());
++ }
+ }
+
+- newSource << R"(
+- const ::Opm::ParserKeyword& operator[](const std::string& keyword) const {
+- if (this->keywords.empty()) {
++ newHeader << R"(
++ const ::Opm::ParserKeyword& operator[](const std::string& keyword) const {
++ if (this->keywords.empty()) {
+ )";
++ std::stringstream declareEmplace;
+
+ for(const auto& kw_pair : loader) {
+ const auto& keywords = kw_pair.second;
++ auto& source = newSources[kw_pair.first];
++ newHeader << fmt::format(" emplace{}(this->keywords);\n", kw_pair.first);
++ source << fmt::format(R"(
++void Builtin::emplace{}([[maybe_unused]] std::unordered_map<std::string, ::Opm::ParserKeyword>& keywords) const {{
++)",
++ kw_pair.first);
++ declareEmplace << fmt::format(R"(
++ void emplace{}(std::unordered_map<std::string, ::Opm::ParserKeyword>& keywords) const;
++)",
++ kw_pair.first);
++
+ for (const auto& kw: keywords)
+- newSource << fmt::format(" this->keywords.emplace(\"{0}\", this->{0});\n", kw.className());
++ source << fmt::format(" keywords.emplace(\"{0}\", {0}());\n", kw.className());
++ source <<"}\n";
++ source <<"} }\n";
+ }
+
+- newSource << R"( }
+- const auto kw_iter = this->keywords.find(keyword);
+- if (kw_iter == this->keywords.end())
+- throw std::invalid_argument(fmt::format("No builtin keyword: {}", keyword));
+- return kw_iter->second;
+-}
++ newHeader << R"( }
++ const auto kw_iter = this->keywords.find(keyword);
++ if (kw_iter == this->keywords.end())
++ throw std::invalid_argument(fmt::format("No builtin keyword: {}", keyword));
++ return kw_iter->second;
++ }
+
+- const ::Opm::ParserKeyword& getKeyword(const std::string& keyword) const { return this->operator[](keyword); }
++ const ::Opm::ParserKeyword& getKeyword(const std::string& keyword) const { return this->operator[](keyword); }
+ )";
+
+- newSource << R"(
+-private:
+- mutable std::unordered_map<std::string, ::Opm::ParserKeyword> keywords; ++ newHeader << "private:\n";
++ newHeader << declareEmplace.str();
++ newHeader << R"(
++ mutable std::unordered_map<std::string, ::Opm::ParserKeyword> keywords;
+ };
+ }
+ }
+@@ -154,7 +173,13 @@ private:
+ )";
+
+ const auto final_path = headerBuildPath + headerPath+ "/Builtin.hpp"; +- write_file( newSource, final_path, m_verbose, "header" );
++ write_file( newHeader, final_path, m_verbose, "header" );
++ for(auto&& [first_char, source]: newSources)
++ {
++ auto sourceFile = std::filesystem::path(sourcePath) / fmt::format("Builtin{}.cpp",
++ first_char);
++ write_file(source, sourceFile, m_verbose, fmt::format("builtin source for {}", first_char));
++ }
+ }
+
+ void KeywordGenerator::updateInitSource(const KeywordLoader& loader , const std::string& sourceFile,
+@@ -190,21 +215,18 @@ void addDefaultKeywords{0}(Parser& p);
+ std::stringstream sourceStr;
+ sourceStr << fmt::format(R"(
+ #include <opm/input/eclipse/Parser/Parser.hpp>
+-#include <opm/input/eclipse/Parser/ParserKeywords/Builtin.hpp>
+ #include<opm/input/eclipse/Parser/ParserKeywords/ParserInit{0}.hpp>
+ #include <opm/input/eclipse/Parser/ParserKeywords/{0}.hpp>
+
+ namespace Opm {{
+ namespace ParserKeywords {{
+-void addDefaultKeywords{0}(Parser& p){{
+- Builtin keywords;
++void addDefaultKeywords{0}([[maybe_unused]] Parser& p){{
++ //Builtin keywords;
+ )",
+ first_char);
+- for (const auto& kw_pair : loader) {
+ const auto& keywords = kw_pair.second;
+ for (const auto& kw : keywords)
+- sourceStr << fmt::format(" p.addParserKeyword( keywords.{} );", kw.className()) << std::endl;
+- }
++ sourceStr << fmt::format(" p.addParserKeyword( {}() );", kw.className()) << std::endl;
+ sourceStr << R"(
+
+ }
+diff --git a/src/opm/input/eclipse/Parser/createDefaultKeywordList.cpp b/src/opm/input/eclipse/Parser/createDefaultKeywordList.cpp
+index 88c8cf1..ec8d73d 100644
+--- a/src/opm/input/eclipse/Parser/createDefaultKeywordList.cpp
++++ b/src/opm/input/eclipse/Parser/createDefaultKeywordList.cpp
+@@ -60,7 +60,8 @@ int main(int argc, char ** argv) {
+ generator.updateKeywordSource(loader , source_file_path );
+ generator.updateInitSource(loader , init_file_name , source_file_path ); + generator.updateHeader(loader, header_file_base_path, header_file_path ); +- generator.updateBuiltInHeader(loader, header_file_base_path, header_file_path );
++ generator.updateBuiltInHeader(loader, header_file_base_path, header_file_path,
++ source_file_path );
+ generator.updateTest( loader , test_file_name );
+ if (argc >= 8)
+ generator.updatePybindSource(loader , argv[7]);
diff --git a/debian/patches/0016-Added-missing-include-to-ParserTests.cpp.patch b/debian/patches/0016-Added-missing-include-to-ParserTests.cpp.patch
new file mode 100644
index 000000000..f663a4aef
--- /dev/null
+++ b/debian/patches/0016-Added-missing-include-to-ParserTests.cpp.patch
@@ -0,0 +1,29 @@
+From: Markus Blatt <
markus@dr-blatt.de>
+Date: Wed, 8 Mar 2023 19:48:38 +0100
+Subject: Added missing include to ParserTests.cpp
+
+---
+ tests/parser/ParserTests.cpp | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tests/parser/ParserTests.cpp b/tests/parser/ParserTests.cpp +index 4ab0ecf..85b3086 100644
+--- a/tests/parser/ParserTests.cpp
++++ b/tests/parser/ParserTests.cpp
+@@ -35,6 +35,7 @@
+ #include <opm/input/eclipse/Parser/ParserKeyword.hpp>
+ #include <opm/input/eclipse/Parser/ParserKeywords/A.hpp>
+ #include <opm/input/eclipse/Parser/ParserKeywords/S.hpp>
++#include <opm/input/eclipse/Parser/ParserKeywords/T.hpp>
+ #include <opm/input/eclipse/Parser/ParserKeywords/Builtin.hpp>
+ #include <opm/input/eclipse/Parser/ParserRecord.hpp>
+
+@@ -2355,7 +2356,7 @@ GUIDERAT
+ )";
+
+ BOOST_CHECK_EQUAL( parser.size(), 0 );
+- parser.addParserKeyword(