From d054d010b24915889aeb447c5a3a6e0be5253a23 Mon Sep 17 00:00:00 2001
From: iht <IhateTrains@users.noreply.github.com>
Date: Tue, 1 Oct 2024 19:04:46 +0200
Subject: [PATCH] Convert many cpp files to WIP csharp files

---
 .../Characters/Character.cpp                  |   0
 .../{CK3World => CK3}/Characters/Character.h  |   0
 .../Characters/CharacterDomain.cpp            |   0
 .../Characters/CharacterDomain.h              |   0
 .../Characters/Characters.cpp                 |   6 +-
 .../{CK3World => CK3}/Characters/Characters.h |   0
 .../Source/CK3/CoatsOfArms/CoatsOfArms.cs     |  59 ++
 .../Source/CK3/CoatsOfArms/EmblemInstance.cs  |  16 +-
 CK3ToEU4/Source/CK3/Cultures/Culture.cs       | 160 ++++++
 CK3ToEU4/Source/CK3/Cultures/Cultures.cs      |  43 ++
 .../{CK3World => CK3}/Dynasties/Dynasties.cpp |   2 +-
 .../{CK3World => CK3}/Dynasties/Dynasties.h   |   0
 .../{CK3World => CK3}/Dynasties/Dynasty.cpp   |   0
 .../{CK3World => CK3}/Dynasties/Dynasty.h     |   0
 .../{CK3World => CK3}/Dynasties/House.cpp     |   0
 .../{CK3World => CK3}/Dynasties/House.h       |   0
 .../Dynasties/HouseNameScraper.cpp            |   0
 .../Dynasties/HouseNameScraper.h              |   0
 .../Dynasties/HouseNameScraping.cpp           |   0
 .../Dynasties/HouseNameScraping.h             |   0
 .../{CK3World => CK3}/Dynasties/Houses.cpp    |   0
 .../{CK3World => CK3}/Dynasties/Houses.h      |   0
 CK3ToEU4/Source/CK3/Flags/Flags.cs            |  58 ++
 CK3ToEU4/Source/CK3/Geography/CountyDetail.cs |  46 ++
 .../Geography/CountyDetails.cpp               |   6 +-
 .../Geography/CountyDetails.h                 |   0
 .../Geography/ProvinceHolding.cpp             |   0
 .../Geography/ProvinceHolding.h               |   0
 .../Geography/ProvinceHoldings.cpp            |   0
 .../Geography/ProvinceHoldings.h              |   0
 CK3ToEU4/Source/CK3/Religions/Faith.cs        |  88 +++
 CK3ToEU4/Source/CK3/Religions/Faiths.cs       |  66 +++
 CK3ToEU4/Source/CK3/Religions/Religion.cs     |  50 ++
 CK3ToEU4/Source/CK3/Religions/Religions.cs    |  70 +++
 CK3ToEU4/Source/CK3/Titles/DynamicTemplate.cs |  28 +
 CK3ToEU4/Source/CK3/Titles/LandedTitles.cs    | 148 +++++
 CK3ToEU4/Source/CK3/Titles/Title.cs           |  24 +-
 .../Titles.cpp => CK3/Titles/Titles.cs}       | 274 +++++----
 CK3ToEU4/Source/CK3/World.cs                  |  27 +-
 .../CK3World/CoatsOfArms/CoatOfArms.cpp       |  70 ---
 .../Source/CK3World/CoatsOfArms/CoatOfArms.h  |  45 --
 .../CK3World/CoatsOfArms/CoatsOfArms.cpp      |  53 --
 .../Source/CK3World/CoatsOfArms/CoatsOfArms.h |  25 -
 .../Source/CK3World/CoatsOfArms/Emblem.cpp    |  61 ---
 CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.h |  35 --
 .../CK3World/CoatsOfArms/EmblemInstance.cpp   |  31 --
 .../CK3World/CoatsOfArms/EmblemInstance.h     |  32 --
 CK3ToEU4/Source/CK3World/Cultures/Culture.cpp | 127 -----
 CK3ToEU4/Source/CK3World/Cultures/Culture.h   |  54 --
 .../Source/CK3World/Cultures/Cultures.cpp     |  34 --
 CK3ToEU4/Source/CK3World/Cultures/Cultures.h  |  27 -
 CK3ToEU4/Source/CK3World/Flags/Flags.cpp      |  51 --
 CK3ToEU4/Source/CK3World/Flags/Flags.h        |  26 -
 .../CK3World/Geography/CountyDetail.cpp       |  29 -
 .../Source/CK3World/Geography/CountyDetail.h  |  34 --
 CK3ToEU4/Source/CK3World/Religions/Faith.cpp  |  50 --
 CK3ToEU4/Source/CK3World/Religions/Faith.h    |  53 --
 CK3ToEU4/Source/CK3World/Religions/Faiths.cpp |  49 --
 CK3ToEU4/Source/CK3World/Religions/Faiths.h   |  29 -
 .../Source/CK3World/Religions/Religion.cpp    |  26 -
 CK3ToEU4/Source/CK3World/Religions/Religion.h |  31 --
 .../Source/CK3World/Religions/Religions.cpp   |  54 --
 .../Source/CK3World/Religions/Religions.h     |  28 -
 .../CK3World/Titles/DynamicTemplate.cpp       |  21 -
 .../Source/CK3World/Titles/DynamicTemplate.h  |  23 -
 .../Source/CK3World/Titles/LandedTitles.cpp   | 136 -----
 .../Source/CK3World/Titles/LandedTitles.h     |  60 --
 CK3ToEU4/Source/CK3World/Titles/Title.cpp     | 518 ------------------
 CK3ToEU4/Source/CK3World/Titles/Title.h       | 184 -------
 CK3ToEU4/Source/CK3World/Titles/Titles.h      |  36 --
 .../Source/Configuration/Configuration.cpp    | 218 --------
 CK3ToEU4/Source/Configuration/Configuration.h | 145 -----
 72 files changed, 993 insertions(+), 2573 deletions(-)
 rename CK3ToEU4/Source/{CK3World => CK3}/Characters/Character.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Characters/Character.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Characters/CharacterDomain.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Characters/CharacterDomain.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Characters/Characters.cpp (98%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Characters/Characters.h (100%)
 create mode 100644 CK3ToEU4/Source/CK3/CoatsOfArms/CoatsOfArms.cs
 create mode 100644 CK3ToEU4/Source/CK3/Cultures/Culture.cs
 create mode 100644 CK3ToEU4/Source/CK3/Cultures/Cultures.cs
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/Dynasties.cpp (97%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/Dynasties.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/Dynasty.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/Dynasty.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/House.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/House.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/HouseNameScraper.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/HouseNameScraper.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/HouseNameScraping.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/HouseNameScraping.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/Houses.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Dynasties/Houses.h (100%)
 create mode 100644 CK3ToEU4/Source/CK3/Flags/Flags.cs
 create mode 100644 CK3ToEU4/Source/CK3/Geography/CountyDetail.cs
 rename CK3ToEU4/Source/{CK3World => CK3}/Geography/CountyDetails.cpp (95%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Geography/CountyDetails.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Geography/ProvinceHolding.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Geography/ProvinceHolding.h (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Geography/ProvinceHoldings.cpp (100%)
 rename CK3ToEU4/Source/{CK3World => CK3}/Geography/ProvinceHoldings.h (100%)
 create mode 100644 CK3ToEU4/Source/CK3/Religions/Faith.cs
 create mode 100644 CK3ToEU4/Source/CK3/Religions/Faiths.cs
 create mode 100644 CK3ToEU4/Source/CK3/Religions/Religion.cs
 create mode 100644 CK3ToEU4/Source/CK3/Religions/Religions.cs
 create mode 100644 CK3ToEU4/Source/CK3/Titles/DynamicTemplate.cs
 create mode 100644 CK3ToEU4/Source/CK3/Titles/LandedTitles.cs
 rename CK3ToEU4/Source/{CK3World/Titles/Titles.cpp => CK3/Titles/Titles.cs} (78%)
 delete mode 100644 CK3ToEU4/Source/CK3World/CoatsOfArms/CoatOfArms.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/CoatsOfArms/CoatOfArms.h
 delete mode 100644 CK3ToEU4/Source/CK3World/CoatsOfArms/CoatsOfArms.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/CoatsOfArms/CoatsOfArms.h
 delete mode 100644 CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.h
 delete mode 100644 CK3ToEU4/Source/CK3World/CoatsOfArms/EmblemInstance.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/CoatsOfArms/EmblemInstance.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Cultures/Culture.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Cultures/Culture.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Cultures/Cultures.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Cultures/Cultures.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Flags/Flags.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Flags/Flags.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Geography/CountyDetail.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Geography/CountyDetail.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Religions/Faith.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Religions/Faith.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Religions/Faiths.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Religions/Faiths.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Religions/Religion.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Religions/Religion.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Religions/Religions.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Religions/Religions.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Titles/DynamicTemplate.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Titles/DynamicTemplate.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Titles/LandedTitles.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Titles/LandedTitles.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Titles/Title.cpp
 delete mode 100644 CK3ToEU4/Source/CK3World/Titles/Title.h
 delete mode 100644 CK3ToEU4/Source/CK3World/Titles/Titles.h
 delete mode 100644 CK3ToEU4/Source/Configuration/Configuration.cpp
 delete mode 100644 CK3ToEU4/Source/Configuration/Configuration.h

diff --git a/CK3ToEU4/Source/CK3World/Characters/Character.cpp b/CK3ToEU4/Source/CK3/Characters/Character.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Characters/Character.cpp
rename to CK3ToEU4/Source/CK3/Characters/Character.cpp
diff --git a/CK3ToEU4/Source/CK3World/Characters/Character.h b/CK3ToEU4/Source/CK3/Characters/Character.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Characters/Character.h
rename to CK3ToEU4/Source/CK3/Characters/Character.h
diff --git a/CK3ToEU4/Source/CK3World/Characters/CharacterDomain.cpp b/CK3ToEU4/Source/CK3/Characters/CharacterDomain.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Characters/CharacterDomain.cpp
rename to CK3ToEU4/Source/CK3/Characters/CharacterDomain.cpp
diff --git a/CK3ToEU4/Source/CK3World/Characters/CharacterDomain.h b/CK3ToEU4/Source/CK3/Characters/CharacterDomain.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Characters/CharacterDomain.h
rename to CK3ToEU4/Source/CK3/Characters/CharacterDomain.h
diff --git a/CK3ToEU4/Source/CK3World/Characters/Characters.cpp b/CK3ToEU4/Source/CK3/Characters/Characters.cpp
similarity index 98%
rename from CK3ToEU4/Source/CK3World/Characters/Characters.cpp
rename to CK3ToEU4/Source/CK3/Characters/Characters.cpp
index d1ef9c3e..75986910 100644
--- a/CK3ToEU4/Source/CK3World/Characters/Characters.cpp
+++ b/CK3ToEU4/Source/CK3/Characters/Characters.cpp
@@ -1,11 +1,11 @@
 #include "Characters.h"
 #include "../../Mappers/TraitScraper/TraitScraper.h"
-#include "../Cultures/Cultures.h"
+#include "../Cultures/Cultures.cs"
 #include "../Dynasties/House.h"
 #include "../Dynasties/Houses.h"
-#include "../Religions/Faiths.h"
+#include "../Religions/Faiths.cs"
 #include "../Titles/Title.h"
-#include "../Titles/Titles.h"
+#include "../Titles/Titles.cs"
 #include "Character.h"
 #include "CharacterDomain.h"
 #include "CommonRegexes.h"
diff --git a/CK3ToEU4/Source/CK3World/Characters/Characters.h b/CK3ToEU4/Source/CK3/Characters/Characters.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Characters/Characters.h
rename to CK3ToEU4/Source/CK3/Characters/Characters.h
diff --git a/CK3ToEU4/Source/CK3/CoatsOfArms/CoatsOfArms.cs b/CK3ToEU4/Source/CK3/CoatsOfArms/CoatsOfArms.cs
new file mode 100644
index 00000000..ba68fb84
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/CoatsOfArms/CoatsOfArms.cs
@@ -0,0 +1,59 @@
+
+namespace CK3ToEU4.CK3.CoatsOfArms;
+
+class CoatsOfArms
+{
+	public CoatsOfArms()
+	{
+	}
+
+	public CoatsOfArms(std::istream& theStream)
+	{
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
+	}
+	public auto getCoats() const { return coats; }
+
+	public void linkParents(const Titles& titles)
+	{
+		auto counter = 0;
+		const auto& titleData = titles.getTitles();
+		for (const auto& coat: coats)
+		{
+			if (!coat.second->getParent())
+				continue;
+			const auto& titleDataItr = titleData.find(coat.second->getParent()->first);
+			if (titleDataItr != titleData.end())
+			{
+				if (!titleDataItr->second->getCoA())
+					throw std::runtime_error("CoA " + std::to_string(coat.first) + " has parent " + coat.second->getParent()->first + " which has no coat defined!");
+				if (!coats.count(titleDataItr->second->getCoA()->first))
+					throw std::runtime_error(
+						"CoA " + std::to_string(coat.first) + " has parent " + coat.second->getParent()->first + " which has invalid coat defined!");
+				coat.second->loadParent(std::make_pair(coat.second->getParent()->first, coats[titleDataItr->second->getCoA()->first]));
+				++counter;
+			}
+			else
+			{
+				throw std::runtime_error("CoA " + std::to_string(coat.first) + " has parent " + coat.second->getParent()->first + " which is undefined!");
+			}
+		}
+		Log(LogLevel::Info) << "<> " << counter << " coats updated.";
+	}
+
+	:
+	private void registerKeys()
+	{
+		registerRegex(R"(\d+)", [this](const std::string& coaID, std::istream& theStream) {
+			auto newCoA = std::make_shared<CoatOfArms>(theStream, std::stoll(coaID));
+			coats.insert(std::pair(newCoA->getID(), newCoA));
+		});
+		registerKeyword("coat_of_arms_manager_database", [this](const std::string& unused, std::istream& theStream) {
+			coats = CoatsOfArms(theStream).getCoats();
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+	private std::map<long long, std::shared_ptr<CoatOfArms>> coats;
+};
\ No newline at end of file
diff --git a/CK3ToEU4/Source/CK3/CoatsOfArms/EmblemInstance.cs b/CK3ToEU4/Source/CK3/CoatsOfArms/EmblemInstance.cs
index 050681eb..562e6845 100644
--- a/CK3ToEU4/Source/CK3/CoatsOfArms/EmblemInstance.cs
+++ b/CK3ToEU4/Source/CK3/CoatsOfArms/EmblemInstance.cs
@@ -14,22 +14,22 @@ public EmblemInstance(BufferedReader reader)
     
     private void RegisterKeys(Parser parser)
     {
-        registerKeyword("rotation", [this](const std::string& unused, std::istream& theStream) {
-            rotation = commonItems::singleDouble(theStream).getDouble();
+        parser.RegisterKeyword("rotation", reader => {
+            rotation = reader.GetDouble();
         });
-        registerKeyword("depth", [this](const std::string& unused, std::istream& theStream) {
-            depth = commonItems::singleDouble(theStream).getDouble();
+        parser.RegisterKeyword("depth", reader => {
+            depth = reader.GetDouble();
         });
-        registerKeyword("position", [this](const std::string& unused, std::istream& theStream) {
+        parser.RegisterKeyword("position", reader => {
             position = commonItems::doubleList(theStream).getDoubles();
         });
-        registerKeyword("scale", [this](const std::string& unused, std::istream& theStream) {
+        parser.RegisterKeyword("scale", reader => {
             scale = commonItems::doubleList(theStream).getDoubles();
         });
-        registerKeyword("offset", [this](const std::string& unused, std::istream& theStream) {
+        parser.RegisterKeyword("offset", reader => {
             offset = commonItems::doubleList(theStream).getDoubles();
         });
-        registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+        parser.RegisterRegex(CommonRegexes.Catchall, ParserHelpers.IgnoreItem);
     }
 
     public void DefaultPosition()
diff --git a/CK3ToEU4/Source/CK3/Cultures/Culture.cs b/CK3ToEU4/Source/CK3/Cultures/Culture.cs
new file mode 100644
index 00000000..c14c0c45
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Cultures/Culture.cs
@@ -0,0 +1,160 @@
+using System.Collections.Generic;
+using commonItems;
+
+namespace CK3ToEU4.CK3.Cultures
+{
+class Culture
+{
+	public Culture() {}
+	public Culture(BufferedReader reader, long theID)
+	{
+		ID = theID;
+		
+		var parser = new Parser();
+		registerKeys(parser);
+		parser.ParseStream(reader);
+	}
+
+	public  auto getID() const { return ID; }
+	public  auto isEU4Ready() const { return eu4Ready; }
+	public  auto isDynamic() const { return dynamic; }
+	public  const auto& getLocalizedName() const { return localizedName; }
+	public  const auto& getName() const { return name; }
+	public  const auto& getNameLists() const { return nameLists; }
+	public  const auto& getHeritage() const { return heritage; }
+	public  const auto& getTemplate() const { return culture_template; }
+	public  const auto& getEthos() const { return ethos; }
+	public  const auto& getTraditions() const { return traditions; }
+
+	public void setDynamic() { dynamic = true; }
+	public void concoctCultureName(LocalizationMapper localizationMapper,
+	 CultureMapper cultureMapper,
+	 Dictionary<string, int> cultureNamingCounter)
+{
+	/* This function is responsible for determining what a culture is and where it's going. Base/vanilla cultures are known to us but
+	 * hybrids and divergences most certainly are not. We can try to normalize some of them like Swiss (hybrid) or Austrian (divergence) into
+	 * eu4 cultures (sidestepping cultural mapping altogether), and if that fails we can generate dynamic cultures and file them in culture
+	 * groups according to their heritages. In this function we do the first half.
+	 */
+
+	// Is this a base ck3 culture?
+	if (culture_template)
+	{
+		name = *culture_template;
+		return;
+	}
+
+	// Does this culture have a name? If not that means the player was very funny. We'll do the same.
+	if (!localizedName)
+	{
+		name = "noname";
+		return;
+	}
+
+	/* We have a divergent culture. Hybrids and divergents are by definition eu4-ready cultures but:
+	 * 1. we allow for overrides using "ck3 = culture" mappings
+	 * 2. not all of them have eu4 definitions which we'll have to generate.
+	 * If a culture is not in "eu4 = " target block then 2) applies and we need to know this.
+	 */
+
+	// Can we reverse map it via localization into some common base like "austrian"?
+	const auto& match = localizationMapper.reverseLookupCultureName(*localizedName);
+	if (match)
+	{
+		auto strippedName = *match;
+		strippedName = strippedName.substr(0, strippedName.size() - 5);
+		if (cultureMapper.getTargetCultures().contains(strippedName))
+		{
+			// this is a full-flegded eu4 culture with predefined definitions.
+			name = strippedName;
+			eu4Ready = true;
+			return;
+		}
+
+		if (cultureMapper.getSourceCultures().contains(strippedName))
+		{
+			// this is a culture we've mapped to something else. Proceed normally as if it were vanilla ck3 culture.
+			name = strippedName;
+			return;
+		}
+	}
+
+	// Now everything else, we need to Concoct the culture name, finally.
+	name = "dynamic-";
+	for (const auto& entry: nameLists)
+	{
+		// Enery name component must be mapped to some base eu4 culture, so that eu4tovic2 can decompose it.
+		const auto& cultureMatch = cultureMapper.cultureNonRegionalNonReligiousMatch(entry, "", 0, "");
+		if (cultureMatch)
+		{
+			name += *cultureMatch + "-";
+		}
+		else
+		{
+			Log(LogLevel::Warning) << "Mapping " << entry << " to an EU4 culture failed! Check mappings!";
+			name += entry + "-";
+		}
+	}
+	name += "culture";
+
+	// did we see this culture before, elsewhere?
+
+	if (cultureNamingCounter.contains(name))
+	{
+
+		++cultureNamingCounter.at(name);
+		name += "-num" + std::to_string(cultureNamingCounter.at(name));
+	}
+	else
+	{
+		cultureNamingCounter.emplace(name, 1);
+		name += "-num1";
+	}
+
+	dynamic = true;
+}
+
+
+  
+	private void registerKeys()
+	{
+		registerKeyword("culture_template", [this](std::istream& theStream) {
+			culture_template = commonItems::getString(theStream);
+		});
+		registerKeyword("name", [this](std::istream& theStream) {
+			localizedName = commonItems::getString(theStream);
+		});
+		registerKeyword("heritage", [this](std::istream& theStream) {
+			heritage = commonItems::getString(theStream);
+		});
+		registerKeyword("ethos", [this](std::istream& theStream) {
+			ethos = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("traditions", [this](std::istream& theStream) {
+			traditions = commonItems::getStrings(theStream);
+		});
+		registerKeyword("name_list", [this](std::istream& theStream) {
+			auto temp = commonItems::getString(theStream);
+			if (temp.size() > 10)
+			{
+				temp = temp.substr(10, temp.size()); // drop "name_list_", leave "polish"
+				nameLists.insert(temp);
+			}
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+	private long long ID = 0;
+	private bool eu4Ready = false; // this culture has eu4 match and needs zero processing
+	private bool dynamic = false;  // this culture is dynamic and will need generation of cultural data
+
+	private std::optional<std::string> culture_template; // this has data only for base ck3 cultures, like czech or german
+	private std::optional<std::string> localizedName;		// this can be anything - user input or localized name in a particular language game is running.
+	private std::string heritage;								// all cultures should have this.
+	private std::set<std::string> nameLists;					// We use these to generate dynamic culture code names, in lack of a better solution.
+	private std::string ethos;									// used to generate custom ideas for custom tags with a custom culture
+	private std::vector<std::string> traditions;			// used to generate custom ideas for custom tags with a custom culture
+
+	private std::string name; // calculated value from all of the above - can be either *eu4* culture, ck3 vanilla, or anything in between.
+};
+}
\ No newline at end of file
diff --git a/CK3ToEU4/Source/CK3/Cultures/Cultures.cs b/CK3ToEU4/Source/CK3/Cultures/Cultures.cs
new file mode 100644
index 00000000..4e468af4
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Cultures/Cultures.cs
@@ -0,0 +1,43 @@
+using CK3;
+
+namespace CK3ToEU4.CK3.Cultures;
+
+class Cultures: commonItems::parser
+{
+	public Cultures() {}
+	public Cultures(std::istream& theStream)
+	{
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
+	}
+
+	public const auto& getCultures() const { return cultures; }
+	public void concoctCultures(const mappers::LocalizationMapper& localizationMapper, const mappers::CultureMapper& cultureMapper)
+	{
+		for (const auto& culture: cultures | std::views::values)
+		{
+			culture->concoctCultureName(localizationMapper, cultureMapper, cultureNamingCounter);
+		}
+	}
+
+
+  
+	private void registerKeys()
+	{
+		registerRegex(R"(\d+)", [this](const std::string& cultureID, std::istream& theStream) {
+			auto newCulture = std::make_shared<Culture>(theStream, std::stoll(cultureID));
+			cultures.insert(std::pair(newCulture->getID(), newCulture));
+		});
+		registerKeyword("cultures", [this](std::istream& theStream) {
+			const auto scraper = Cultures(theStream);
+			cultures = scraper.getCultures();
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+
+
+	private std::map<long long, std::shared_ptr<Culture>> cultures;
+	private std::map<std::string, int> cultureNamingCounter;
+};
\ No newline at end of file
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/Dynasties.cpp b/CK3ToEU4/Source/CK3/Dynasties/Dynasties.cpp
similarity index 97%
rename from CK3ToEU4/Source/CK3World/Dynasties/Dynasties.cpp
rename to CK3ToEU4/Source/CK3/Dynasties/Dynasties.cpp
index 0a0f8e9b..9a574874 100644
--- a/CK3ToEU4/Source/CK3World/Dynasties/Dynasties.cpp
+++ b/CK3ToEU4/Source/CK3/Dynasties/Dynasties.cpp
@@ -1,5 +1,5 @@
 #include "Dynasties.h"
-#include "../CoatsOfArms/CoatsOfArms.h"
+#include "../CoatsOfArms/CoatsOfArms.cs"
 #include "CommonRegexes.h"
 #include "Dynasty.h"
 #include "Log.h"
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/Dynasties.h b/CK3ToEU4/Source/CK3/Dynasties/Dynasties.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/Dynasties.h
rename to CK3ToEU4/Source/CK3/Dynasties/Dynasties.h
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/Dynasty.cpp b/CK3ToEU4/Source/CK3/Dynasties/Dynasty.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/Dynasty.cpp
rename to CK3ToEU4/Source/CK3/Dynasties/Dynasty.cpp
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/Dynasty.h b/CK3ToEU4/Source/CK3/Dynasties/Dynasty.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/Dynasty.h
rename to CK3ToEU4/Source/CK3/Dynasties/Dynasty.h
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/House.cpp b/CK3ToEU4/Source/CK3/Dynasties/House.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/House.cpp
rename to CK3ToEU4/Source/CK3/Dynasties/House.cpp
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/House.h b/CK3ToEU4/Source/CK3/Dynasties/House.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/House.h
rename to CK3ToEU4/Source/CK3/Dynasties/House.h
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/HouseNameScraper.cpp b/CK3ToEU4/Source/CK3/Dynasties/HouseNameScraper.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/HouseNameScraper.cpp
rename to CK3ToEU4/Source/CK3/Dynasties/HouseNameScraper.cpp
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/HouseNameScraper.h b/CK3ToEU4/Source/CK3/Dynasties/HouseNameScraper.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/HouseNameScraper.h
rename to CK3ToEU4/Source/CK3/Dynasties/HouseNameScraper.h
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/HouseNameScraping.cpp b/CK3ToEU4/Source/CK3/Dynasties/HouseNameScraping.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/HouseNameScraping.cpp
rename to CK3ToEU4/Source/CK3/Dynasties/HouseNameScraping.cpp
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/HouseNameScraping.h b/CK3ToEU4/Source/CK3/Dynasties/HouseNameScraping.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/HouseNameScraping.h
rename to CK3ToEU4/Source/CK3/Dynasties/HouseNameScraping.h
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/Houses.cpp b/CK3ToEU4/Source/CK3/Dynasties/Houses.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/Houses.cpp
rename to CK3ToEU4/Source/CK3/Dynasties/Houses.cpp
diff --git a/CK3ToEU4/Source/CK3World/Dynasties/Houses.h b/CK3ToEU4/Source/CK3/Dynasties/Houses.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Dynasties/Houses.h
rename to CK3ToEU4/Source/CK3/Dynasties/Houses.h
diff --git a/CK3ToEU4/Source/CK3/Flags/Flags.cs b/CK3ToEU4/Source/CK3/Flags/Flags.cs
new file mode 100644
index 00000000..27ebdb47
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Flags/Flags.cs
@@ -0,0 +1,58 @@
+#ifndef CK3_FLAGS_H
+#define CK3_FLAGS_H
+#include <set>
+
+#include "Parser.h"
+
+namespace CK3
+{
+class Flags: commonItems::parser
+{
+  public:
+	Flags() = default;
+	explicit Flags(std::istream& theStream)
+	{
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
+
+		if (itemType == "flag" && !incomingFlag.empty())
+			flags.insert(incomingFlag);
+	}
+
+	[[nodiscard]] const auto& getFlags() const { return flags; }
+
+  private:
+	void registerKeys()
+	{
+		registerKeyword("list", [this](const std::string& unused, std::istream& theStream) {
+			for (const auto& blob: commonItems::blobList(theStream).getBlobs())
+			{
+				auto blobStream = std::stringstream(blob);
+				const auto scraper = Flags(blobStream);
+				const auto& foundFlags = scraper.getFlags();
+				flags.insert(foundFlags.begin(), foundFlags.end());
+			}
+		});
+		registerKeyword("item", [this](const std::string& unused, std::istream& theStream) {
+			const auto scraper = Flags(theStream);
+			const auto& foundFlags = scraper.getFlags();
+			flags.insert(foundFlags.begin(), foundFlags.end());
+		});
+		registerKeyword("flag", [this](const std::string& unused, std::istream& theStream) {
+			incomingFlag = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("type", [this](const std::string& unused, std::istream& theStream) {
+			itemType = commonItems::singleString(theStream).getString();
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+
+	std::string itemType;
+	std::string incomingFlag;
+	std::set<std::string> flags;
+};
+} // namespace CK3
+
+#endif // CK3_FLAGS_H
diff --git a/CK3ToEU4/Source/CK3/Geography/CountyDetail.cs b/CK3ToEU4/Source/CK3/Geography/CountyDetail.cs
new file mode 100644
index 00000000..9dd2a7be
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Geography/CountyDetail.cs
@@ -0,0 +1,46 @@
+
+namespace CK3ToEU4.CK3.Geography;
+
+class CountyDetail
+{
+	public CountyDetail() {};
+	public CountyDetail(std::istream& theStream)
+	{
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
+	}
+
+	public auto getDevelopment() const { return development; }
+	public const auto& getCulture() const { return culture; }
+	public const auto& getFaith() const { return faith; }
+	public const auto& isDeJureHRE() const { return deJureHRE; }
+
+	public void loadCulture(const std::pair<long long, std::shared_ptr<Culture>>& theCulture) { culture = theCulture; }
+	public void loadFaith(const std::pair<long long, std::shared_ptr<Faith>>& theFaith) { faith = theFaith; }
+	public void setDeJureHRE() { deJureHRE = true; }
+
+	private void registerKeys()
+	{
+		registerKeyword("development", [this](const std::string& unused, std::istream& theStream) {
+			development = commonItems::singleInt(theStream).getInt();
+		});
+		registerKeyword("culture", [this](const std::string& unused, std::istream& theStream) {
+			culture = std::make_pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
+			if (culture.first == 4294967295)
+				culture.first = 0;
+		});
+		registerKeyword("faith", [this](const std::string& unused, std::istream& theStream) {
+			faith = std::make_pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
+			if (faith.first == 4294967295)
+				faith.first = 0;
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+
+	private int development = 0;
+	private std::pair<long long, std::shared_ptr<Culture>> culture;
+	private std::pair<long long, std::shared_ptr<Faith>> faith;
+	private bool deJureHRE = false;
+}
\ No newline at end of file
diff --git a/CK3ToEU4/Source/CK3World/Geography/CountyDetails.cpp b/CK3ToEU4/Source/CK3/Geography/CountyDetails.cpp
similarity index 95%
rename from CK3ToEU4/Source/CK3World/Geography/CountyDetails.cpp
rename to CK3ToEU4/Source/CK3/Geography/CountyDetails.cpp
index 57a476f6..0a3ff3c0 100644
--- a/CK3ToEU4/Source/CK3World/Geography/CountyDetails.cpp
+++ b/CK3ToEU4/Source/CK3/Geography/CountyDetails.cpp
@@ -1,8 +1,8 @@
 #include "CountyDetails.h"
-#include "../Cultures/Cultures.h"
-#include "../Religions/Faiths.h"
+#include "../Cultures/Cultures.cs"
+#include "../Religions/Faiths.cs"
 #include "CommonRegexes.h"
-#include "CountyDetail.h"
+#include "CountyDetail.cs"
 #include "Log.h"
 #include "ParserHelpers.h"
 
diff --git a/CK3ToEU4/Source/CK3World/Geography/CountyDetails.h b/CK3ToEU4/Source/CK3/Geography/CountyDetails.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Geography/CountyDetails.h
rename to CK3ToEU4/Source/CK3/Geography/CountyDetails.h
diff --git a/CK3ToEU4/Source/CK3World/Geography/ProvinceHolding.cpp b/CK3ToEU4/Source/CK3/Geography/ProvinceHolding.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Geography/ProvinceHolding.cpp
rename to CK3ToEU4/Source/CK3/Geography/ProvinceHolding.cpp
diff --git a/CK3ToEU4/Source/CK3World/Geography/ProvinceHolding.h b/CK3ToEU4/Source/CK3/Geography/ProvinceHolding.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Geography/ProvinceHolding.h
rename to CK3ToEU4/Source/CK3/Geography/ProvinceHolding.h
diff --git a/CK3ToEU4/Source/CK3World/Geography/ProvinceHoldings.cpp b/CK3ToEU4/Source/CK3/Geography/ProvinceHoldings.cpp
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Geography/ProvinceHoldings.cpp
rename to CK3ToEU4/Source/CK3/Geography/ProvinceHoldings.cpp
diff --git a/CK3ToEU4/Source/CK3World/Geography/ProvinceHoldings.h b/CK3ToEU4/Source/CK3/Geography/ProvinceHoldings.h
similarity index 100%
rename from CK3ToEU4/Source/CK3World/Geography/ProvinceHoldings.h
rename to CK3ToEU4/Source/CK3/Geography/ProvinceHoldings.h
diff --git a/CK3ToEU4/Source/CK3/Religions/Faith.cs b/CK3ToEU4/Source/CK3/Religions/Faith.cs
new file mode 100644
index 00000000..d4e12efa
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Religions/Faith.cs
@@ -0,0 +1,88 @@
+
+
+namespace CK3
+{
+class Religion;
+class Faith: commonItems::parser
+{
+  public:
+	Faith() = default;
+	Faith(std::istream& theStream, long long theID): ID(theID)
+	{
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
+	}
+
+	[[nodiscard]] const auto& getName() const { return tag; }
+	[[nodiscard]] const auto& getColor() const { return color; }
+	[[nodiscard]] const auto& getDoctrines() const { return doctrines; }
+	[[nodiscard]] const auto& getReligion() const { return religion; }
+	[[nodiscard]] const auto& getReligiousHead() const { return religiousHead; }
+	[[nodiscard]] auto getID() const { return ID; }
+	[[nodiscard]] const auto& getCustomName() const { return customName; }
+	[[nodiscard]] const auto& getCustomAdj() const { return customAdjective; }
+	[[nodiscard]] const auto& getDescription() const { return description; }
+	[[nodiscard]] const auto& getTemplate() const { return religionTemplate; }
+	[[nodiscard]] const auto& getIconPath() const { return iconPath; }
+	[[nodiscard]] const auto& getReformedFlag() const { return reformedFlag; }
+
+	void setReligiousHead(const auto& newHead) { religiousHead = newHead; }
+	void loadReligion(const std::pair<long long, std::shared_ptr<Religion>>& theReligion) { religion = theReligion; }
+
+  private:
+	void registerKeys()
+	{
+		registerKeyword("tag", [this](const std::string& unused, std::istream& theStream) {
+			tag = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("doctrine", [this](const std::string& unused, std::istream& theStream) {
+			doctrines.emplace_back(commonItems::singleString(theStream).getString());
+		});
+		registerKeyword("religion", [this](const std::string& unused, std::istream& theStream) {
+			religion = std::make_pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
+		});
+		registerKeyword("color", [this](const std::string& unused, std::istream& theStream) {
+			color = laFabricaDeColor.getColor(theStream);
+		});
+		registerKeyword("template", [this](const std::string& unused, std::istream& theStream) {
+			religionTemplate = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("name", [this](const std::string& unused, std::istream& theStream) {
+			customName = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("adjective", [this](const std::string& unused, std::istream& theStream) {
+			customAdjective = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("religious_head", [this](const std::string& unused, std::istream& theStream) {
+			religiousHead = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("desc", [this](const std::string& unused, std::istream& theStream) {
+			description = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("icon", [this](const std::string& unused, std::istream& theStream) {
+			iconPath = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("variables", [this](const std::string& unused, std::istream& theStream) {
+			if (commonItems::stringOfItem(theStream).getString().find("has_been_reformed") != std::string::npos)
+				reformedFlag = true;
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+
+	bool reformedFlag = false;
+	long long ID = 0;
+	std::string tag;
+	std::string religionTemplate;
+	std::string iconPath;
+	std::string customName;
+	std::string customAdjective;
+	std::string description;
+	std::string religiousHead;
+	std::optional<commonItems::Color> color;
+	std::vector<std::string>
+		 doctrines; // This is a vector in order to keep order consistent. We want the first things read (tenets) to be the first things output, ALWAYS
+	std::pair<long long, std::shared_ptr<Religion>> religion;
+};
+}
\ No newline at end of file
diff --git a/CK3ToEU4/Source/CK3/Religions/Faiths.cs b/CK3ToEU4/Source/CK3/Religions/Faiths.cs
new file mode 100644
index 00000000..77e58ed8
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Religions/Faiths.cs
@@ -0,0 +1,66 @@
+#ifndef CK3_FAITHS_H
+#define CK3_FAITHS_H
+#include "../Titles/LandedTitles.cs"
+#include "../Titles/Title.h"
+#include "../Titles/Titles.cs"
+#include "Parser.h"
+
+namespace CK3
+{
+class Faith;
+class Religions;
+class Faiths: commonItems::parser
+{
+  public:
+	Faiths() = default;
+	public Faiths(std::istream& theStream)
+	{
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
+	}
+
+	[[nodiscard]] const auto& getFaiths() const { return faiths; }
+
+	void linkReligions(const Religions& religions, const Titles& titles)
+	{
+		auto counter = 0;
+		const auto& religionData = religions.getReligions();
+		std::map<std::string, std::string> religiousHeadList; // ID, Title
+		for (const auto& title: titles.getTitles())
+			if (title.second)
+				religiousHeadList.emplace(std::to_string(title.second->getID()), title.first);
+		for (const auto& faith: faiths)
+		{
+			const auto& religionDataItr = religionData.find(faith.second->getReligion().first);
+			if (religionDataItr != religionData.end())
+			{
+				faith.second->loadReligion(*religionDataItr);
+				if (religiousHeadList.contains(faith.second->getReligiousHead()))
+					faith.second->setReligiousHead(religiousHeadList.at(faith.second->getReligiousHead()));
+				++counter;
+			}
+			else
+			{
+				throw std::runtime_error(
+					 "Faith " + faith.second->getName() + " has religion " + std::to_string(faith.second->getReligion().first) + " which has no definition!");
+			}
+		}
+		Log(LogLevel::Info) << "<> " << counter << " faiths updated.";
+	}
+
+  private:
+	void registerKeys()
+	{
+		registerRegex(R"(\d+)", [this](const std::string& faithID, std::istream& theStream) {
+			auto newFaith = std::make_shared<Faith>(theStream, std::stoll(faithID));
+			faiths.insert(std::pair(newFaith->getID(), newFaith));
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+	std::map<long long, std::shared_ptr<Faith>> faiths;
+};
+} // namespace CK3
+
+#endif // CK3_FAITHS_H
diff --git a/CK3ToEU4/Source/CK3/Religions/Religion.cs b/CK3ToEU4/Source/CK3/Religions/Religion.cs
new file mode 100644
index 00000000..1e20f003
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Religions/Religion.cs
@@ -0,0 +1,50 @@
+#ifndef CK3_RELIGION_H
+#define CK3_RELIGION_H
+#include "Parser.h"
+
+namespace CK3
+{
+class Faith;
+class Religion: commonItems::parser
+{
+  public:
+	Religion() = default;
+	Religion(std::istream& theStream, long long theID): ID(theID)
+	{
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
+	}
+
+	[[nodiscard]] auto getID() const { return ID; }
+	[[nodiscard]] const auto& getName() const { return tag; }
+	[[nodiscard]] const auto& getFamily() const { return family; }
+	[[nodiscard]] const auto& getFaiths() const { return faiths; }
+
+	void loadFaiths(const std::map<long long, std::shared_ptr<Faith>>& theFaiths) { faiths = theFaiths; }
+
+  private:
+	void registerKeys()
+	{
+		registerKeyword("tag", [this](const std::string& unused, std::istream& theStream) {
+			tag = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("family", [this](const std::string& unused, std::istream& theStream) {
+			family = commonItems::singleString(theStream).getString();
+		});
+		registerKeyword("faiths", [this](const std::string& unused, std::istream& theStream) {
+			for (auto faith: commonItems::llongList(theStream).getLlongs())
+				faiths.insert(std::pair(faith, nullptr));
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+
+	long long ID = 0;
+	std::string tag;
+	std::string family;
+	std::map<long long, std::shared_ptr<Faith>> faiths;
+};
+} // namespace CK3
+
+#endif // CK3_RELIGION_H
diff --git a/CK3ToEU4/Source/CK3/Religions/Religions.cs b/CK3ToEU4/Source/CK3/Religions/Religions.cs
new file mode 100644
index 00000000..d51a7779
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Religions/Religions.cs
@@ -0,0 +1,70 @@
+#ifndef CK3_RELIGIONS_H
+#define CK3_RELIGIONS_H
+#include "Faiths.cs"
+#include "Parser.h"
+
+namespace CK3
+{
+class Religion;
+class Religions: commonItems::parser
+{
+  public:
+	explicit Religions(std::istream& theStream)
+	{
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
+	}
+
+	[[nodiscard]] const auto& getReligions() const { return religions; }
+	[[nodiscard]] auto getFaiths() { return std::move(faiths); } // Use this only once in World.cpp
+
+	void linkFaiths(const Faiths& theFaiths)
+	{
+		auto counter = 0;
+		const auto& faithData = theFaiths.getFaiths();
+		for (const auto& religion: religions)
+		{
+			const auto& religionFaiths = religion.second->getFaiths();
+			std::map<long long, std::shared_ptr<Faith>> replacementMap;
+
+			for (const auto& faith: religionFaiths)
+			{
+				const auto& faithDataItr = faithData.find(faith.first);
+				if (faithDataItr != faithData.end())
+				{
+					replacementMap.insert(*faithDataItr);
+				}
+				else
+				{
+					throw std::runtime_error("Religion " + religion.second->getName() + " has faith " + std::to_string(faith.first) + " which has no definition!");
+				}
+			}
+			religion.second->loadFaiths(replacementMap);
+			++counter;
+		}
+		Log(LogLevel::Info) << "<> " << counter << " religions updated.";
+	}
+
+  private:
+	void registerKeys()
+	{
+		registerRegex(R"(\d+)", [this](const std::string& faithID, std::istream& theStream) {
+			auto newReligion = std::make_shared<Religion>(theStream, std::stoll(faithID));
+			religions.insert(std::pair(newReligion->getID(), newReligion));
+		});
+		registerKeyword("religions", [this](const std::string& unused, std::istream& theStream) {
+			religions = Religions(theStream).getReligions();
+		});
+		registerKeyword("faiths", [this](const std::string& unused, std::istream& theStream) {
+			faiths = Faiths(theStream);
+		});
+		registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
+	}
+
+	std::map<long long, std::shared_ptr<Religion>> religions;
+	Faiths faiths;
+};
+} // namespace CK3
+
+#endif // CK3_RELIGIONS_H
diff --git a/CK3ToEU4/Source/CK3/Titles/DynamicTemplate.cs b/CK3ToEU4/Source/CK3/Titles/DynamicTemplate.cs
new file mode 100644
index 00000000..137ff82e
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Titles/DynamicTemplate.cs
@@ -0,0 +1,28 @@
+using commonItems;
+
+namespace CK3ToEU4.CK3.Titles;
+
+class DynamicTemplate
+{
+	public DynamicTemplate(BufferedReader reader)
+	{
+		var parser = new Parser();
+		RegisterKeys(parser);
+		parser.ParseStream(reader);
+	}
+
+	public string DynamicTitleKey { get; private set; } = string.Empty;
+	public string DynamicTitleRank { get; private set; } = string.Empty;
+		
+	private void RegisterKeys(Parser parser)
+	{
+		parser.RegisterKeyword("key", reader => {
+			DynamicTitleKey = reader.GetString();
+		});
+		parser.RegisterKeyword("tier", reader => {
+			DynamicTitleRank = reader.GetString();
+		});
+		parser.RegisterRegex(CommonRegexes.Catchall, ParserHelpers.IgnoreItem);
+	}
+}
+
diff --git a/CK3ToEU4/Source/CK3/Titles/LandedTitles.cs b/CK3ToEU4/Source/CK3/Titles/LandedTitles.cs
new file mode 100644
index 00000000..2b13bac2
--- /dev/null
+++ b/CK3ToEU4/Source/CK3/Titles/LandedTitles.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using commonItems;
+using commonItems.Colors;
+
+namespace CK3ToEU4.CK3.Titles;
+
+class LandedTitles
+{
+	// This is a recursive class that scrapes 00_landed_titles.txt (and related files) looking for title colors, landlessness,
+	// and most importantly relation between baronies and barony provinces so we can link titles to actual clay.
+	// Since titles are nested according to hierarchy we do this recursively.
+
+	// Keep in mind that we use this class as middleware between titles and hard geographical data. Baronies and Counties have said data,
+	// but newfangled custom empires and such found in Titles will not be present here. They should have colors defined in their Title block
+	// anyway, and whatever relates to Title over there takes precedence over data in this class.
+
+	public void loadTitles(BufferedReader reader)
+	{
+		var parser = new Parser();
+		registerKeys(parser);
+		parser.ParseStream(reader);
+	}
+	public void loadTitles(string fileName)
+	{
+		var parser = new Parser();
+		registerKeys(parser);
+		parser.ParseFile(fileName);
+	}
+
+	public bool DefiniteForm { get;private set; } = false;
+	public bool Landless { get; private set; } = false;
+	public bool CanBeNamedAfterDynasty { get; private set; } = true;
+	public Color? Color { get; private set; }
+	
+	// This is of questionable use as savegame already defines defacto capitals. Not always present, and if present then a COUNTY.
+	public KeyValuePair<string, Title?>? Capital { get; private set; }
+	
+	// only b_baronies have these - holdings are related to individual provinces on map.
+	public KeyValuePair<int, ProvinceHolding?>? Province { get; private set; }
+	
+	// only c_counties have these - these define common data for group of baronies under county.
+	public KeyValuePair<string, CountyDetail?>? County { get; private set; }
+
+	// We're using title name, not savegame ID for key value.
+	public IReadOnlyDictionary<string, LandedTitles?> FoundTitles => foundTitles;
+	private readonly Dictionary<string, LandedTitles?> foundTitles;
+
+	public void loadProvinceHolding(const KeyValuePair<int, ProvinceHolding?>& provinceHolding) { province = provinceHolding; }
+	public void loadCountyDetails(const KeyValuePair<string, std::shared_ptr<CountyDetail>>& countyDetail) { county = countyDetail; }
+	public void loadCapital(const KeyValuePair<string, Title?>& theCapital) { capital = theCapital; }
+
+	public void linkProvinceHoldings(ProvinceHoldings provinceHoldings) {
+		// We're linking provinces into BARONY titles only, as other titles have no holding data.
+		int counter = 0;
+		var provinceData = provinceHoldings.getProvinceHoldings();
+		foreach (var landedTitle in foundTitles)
+		{
+			if (landedTitle.first.find("b_") != 0)
+				continue;
+			if (!landedTitle.second->getProvince())
+				throw std::runtime_error("Landed title " + landedTitle.first + " has not province holding defined!");
+
+			const auto& provinceDataItr = provinceData.find(landedTitle.second->getProvince()->first);
+			if (provinceDataItr != provinceData.end())
+			{
+				landedTitle.second->loadProvinceHolding(*provinceDataItr);
+				++counter;
+			}
+			else
+			{
+				throw new Exception("Landed title " + landedTitle.first + " has province holding " + std::to_string(landedTitle.second->getProvince()->first) +
+				                    " which has no definition!");
+			}
+		}
+		Logger.Info("<> " + counter + " landed titles updated.");
+	}
+	public void linkCountyDetails(CountyDetails countyDetails) {
+		// We're linking county details into COUNTY titles only, as other titles have no such details.
+		int counter = 0;
+		var countyData = countyDetails.getCountyDetails();
+		foreach (var landedTitle in foundTitles)
+		{
+			if (!landedTitle.Key.StartsWith("c_"))
+				continue;
+			const auto& countyDataItr = countyData.find(landedTitle.first);
+			if (countyDataItr != countyData.end())
+			{
+				landedTitle.second->loadCountyDetails(*countyDataItr);
+				++counter;
+			}
+			else
+			{
+				// Nothing. People with missing titles from mods and whatnot can have holes on their map.
+				Logger.Warn("Landed title " + landedTitle.first + " has no definition in counties={} section of the save game!");
+			}
+		}
+		Logger.Info("<> " + counter + " landed titles updated.");
+	}
+	public void linkTitles(Titles titles) {
+		int counter = 0;
+		var titleData = titles.getTitles();
+		foreach (var landedTitle in foundTitles)
+		{
+			const auto& theCapital = landedTitle.second->getCapital();
+			if (!theCapital)
+				continue;
+			if (const auto& titleDataItr = titleData.find(theCapital->first); titleDataItr != titleData.end())
+			{
+				landedTitle.second->loadCapital(*titleDataItr);
+				++counter;
+			}
+			else
+			{
+				Log(LogLevel::Error) << "Landed title " + landedTitle.first + " has a capital " + theCapital->first + " which has no definition!";
+			}
+		}
+		Logger.Info("<> " + counter + " landed title capitals updated.");
+	}
+
+	
+	private void registerKeys(Parser parser, ColorFactory colorFactory) 
+	{
+		parser.RegisterRegex(R"((e|k|d|c|b)_[A-Za-z0-9_\-\']+)", (reader, titleName) => {
+			// Pull the titles beneath this one and add them to the lot, overwriting existing ones.
+			var newTitle = new LandedTitles();
+			newTitle.loadTitles(theStream);
+			foreach (var locatedTitle: newTitle->getFoundTitles())
+			foundTitles[locatedTitle.first] = locatedTitle.second;
+
+			// And then add this one as well, overwriting existing.
+			foundTitles[titleName] = newTitle;
+		});
+		parser.RegisterKeyword("definite_form", reader => DefiniteForm = reader.GetString() == "yes");
+		parser.RegisterKeyword("landless", reader => Landless = reader.GetString() == "yes");
+		parser.RegisterKeyword("color", reader => Color = colorFactory.GetColor(reader));
+		parser.RegisterKeyword("capital", reader => {
+			Capital = new(reader.GetString(), null);
+		});
+		parser.RegisterKeyword("province", reader => {
+			Province = new (reader.GetInt(), null);
+		});
+		parser.RegisterKeyword("can_be_named_after_dynasty", reader => {
+			CanBeNamedAfterDynasty = reader.GetString() == "yes";
+		});
+		parser.RegisterRegex(CommonRegexes.Catchall, ParserHelpers.IgnoreItem);
+	}
+};
\ No newline at end of file
diff --git a/CK3ToEU4/Source/CK3/Titles/Title.cs b/CK3ToEU4/Source/CK3/Titles/Title.cs
index f4cca0d1..fbfdb30c 100644
--- a/CK3ToEU4/Source/CK3/Titles/Title.cs
+++ b/CK3ToEU4/Source/CK3/Titles/Title.cs
@@ -113,13 +113,13 @@ public Title(BufferedReader reader, long theID)
 	public void setThePope() { thePope = true; }
 	public void setCustomTitle() { customTitle = true; }
 	public void setManualNameClaim() { nameClaimed = true; }
-	public void pickDisplayName(const Dictionary<string, std::shared_ptr<Title>>& possibleTitles); // Grants one county's name to another during N:1/N:M mappings
+	public void pickDisplayName(const Dictionary<string, Title?>& possibleTitles); // Grants one county's name to another during N:1/N:M mappings
 	public Title findDuchyCapital();																 // Only for c_, for now
 	public void congregateDFCounties();
 	public void congregateDJCounties();
-	public void loadGeneratedLiege(const std::pair<string, std::shared_ptr<Title>>& liege) { generatedLiege = liege; }
-	public void addGeneratedVassal(const std::pair<string, std::shared_ptr<Title>>& theVassal) { generatedVassals.insert(theVassal); }
-	public void loadHoldingTitle(const std::pair<string, std::shared_ptr<Title>>& theTitle) { holdingTitle = theTitle; }
+	public void loadGeneratedLiege(const KeyValuePair<string, Title?>& liege) { generatedLiege = liege; }
+	public void addGeneratedVassal(const KeyValuePair<string, Title?>& theVassal) { generatedVassals.insert(theVassal); }
+	public void loadHoldingTitle(const KeyValuePair<string, Title?>& theTitle) { holdingTitle = theTitle; }
 	public void setElectorate() { electorate = true; }
 	public void relinkDeFactoVassals();
 	#endregion
@@ -135,14 +135,14 @@ public Title(BufferedReader reader, long theID)
 	Dictionary<string, Title> coalesceDJCounties() const;
 	#endregion
 
-	private void RegisterKeys(Parser parser)
+	private void RegisterKeys(Parser parser, ColorFactory colorFactory)
 	{
 			parser.RegisterKeyword("key", reader => {
 		name = reader.GetString();
 	});
 	parser.RegisterKeyword("name", reader => {
 		displayName = reader.GetString();
-		if (displayName.find("\x15") != std::string::npos)
+		if (displayName.find("\x15") != string::npos)
 		{
 			cleanUpDisplayName();
 		}
@@ -170,13 +170,13 @@ private void RegisterKeys(Parser parser)
 		dCapitalBarony = reader.GetString() == "yes";
 	});
 	parser.RegisterKeyword("capital", reader => {
-		capital = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
+		capital = new(reader.GetLong(), null);
 	});
 	parser.RegisterKeyword("de_facto_liege", reader => {
-		dfLiege = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
+		dfLiege = KeyValuePair(commonItems::singleLlong(theStream).getLlong(), nullptr);
 	});
 	parser.RegisterKeyword("de_jure_liege", reader => {
-		djLiege = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
+		djLiege = KeyValuePair(commonItems::singleLlong(theStream).getLlong(), nullptr);
 	});
 	parser.RegisterKeyword("de_jure_vassals", reader => {
 		for (auto vassalID: commonItems::llongList(theStream).getLlongs())
@@ -191,7 +191,7 @@ private void RegisterKeys(Parser parser)
 		laws = std::set(theLaws.begin(), theLaws.end());
 	});
 	parser.RegisterKeyword("holder", reader => {
-		holder = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
+		holder = KeyValuePair(commonItems::singleLlong(theStream).getLlong(), nullptr);
 	});
 	parser.RegisterKeyword("renamed", [this](std::istream& theStream) {
 		renamed = commonItems::getString(theStream) == "yes";
@@ -211,7 +211,7 @@ private void RegisterKeys(Parser parser)
 		landless = reader.GetString() == "yes";
 	});
 	parser.RegisterKeyword("color", reader => {
-		color = laFabricaDeColor.getColor(theStream);
+		color = colorFactory.GetColor(reader);
 	});
 	parser.RegisterKeyword("history", reader => {
 		previousHolders = new Title(reader, 0).getPreviousHolders();
@@ -237,7 +237,7 @@ private void RegisterKeys(Parser parser)
 
 
     																			
-    private KeyValuePair<long, Title> capital;							// capital title is a COUNTY, even for county itself and baronies beneath it!
+    private KeyValuePair<long, Title?> capital;							// capital title is a COUNTY, even for county itself and baronies beneath it!
     private string name;																			// c_ashmaka
     private string displayName;																// Ashmaka
     private string adjective;																	// Ashmakan
diff --git a/CK3ToEU4/Source/CK3World/Titles/Titles.cpp b/CK3ToEU4/Source/CK3/Titles/Titles.cs
similarity index 78%
rename from CK3ToEU4/Source/CK3World/Titles/Titles.cpp
rename to CK3ToEU4/Source/CK3/Titles/Titles.cs
index 27ab7252..e0332703 100644
--- a/CK3ToEU4/Source/CK3World/Titles/Titles.cpp
+++ b/CK3ToEU4/Source/CK3/Titles/Titles.cs
@@ -1,132 +1,49 @@
-#include "Titles.h"
-#include "../Characters/Character.h"
-#include "../Characters/Characters.h"
-#include "../CoatsOfArms/CoatOfArms.h"
-#include "../CoatsOfArms/CoatsOfArms.h"
-#include "CommonRegexes.h"
-#include "DynamicTemplate.h"
-#include "LandedTitles.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-#include "Title.h"
 
-CK3::Titles::Titles(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-
-	// This bit assigns CK3::Level to dynamic titles that have a rank definition in the save. It should be all of them, but it's CK3, so who knows.
-	if (!dynamicTitleRanks.empty())
-		transcribeDynamicRanks();
-}
 
-void CK3::Titles::registerKeys()
-{
-	registerKeyword("dynamic_templates", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::blobList dynamicRanks(theStream);
-		for (const auto& dynamicTitle: dynamicRanks.getBlobs())
-		{
-			std::stringstream blobStream(dynamicTitle);
-			const DynamicTemplate dynamicTitleTemplate(blobStream);
-			if (!dynamicTitleTemplate.getDynamicTitleKey().empty() && !dynamicTitleTemplate.getDynamicTitleRank().empty())
-				dynamicTitleRanks.insert(std::pair(dynamicTitleTemplate.getDynamicTitleKey(), dynamicTitleTemplate.getDynamicTitleRank()));
-		}
-	});
-	registerKeyword("landed_titles", [this](const std::string& unused, std::istream& theStream) {
-		// A bit of recursion is good for the soul.
-		const auto& tempTitles = Titles(theStream);
-		titles = tempTitles.getTitles();
-		titleCounter = tempTitles.getCounter();
-	});
-	registerRegex(R"(\d+)", [this](const std::string& ID, std::istream& theStream) {
-		// Incoming titles may not be actual titles but half-deleted junk.
-		const auto& titleBlob = commonItems::stringOfItem(theStream).getString();
-		if (titleBlob.find('{') != std::string::npos)
-		{
-			std::stringstream tempStream(titleBlob);
-			try
-			{
-				auto newTitle = std::make_shared<Title>(tempStream, std::stoll(ID));
-				if (!newTitle->getName().empty())
-					titles.insert(std::pair(newTitle->getName(), newTitle));
-				if (newTitle->getName().find("b_") == 0)
-					++titleCounter[0];
-				else if (newTitle->getName().find("c_") == 0)
-					++titleCounter[1];
-				else if (newTitle->getName().find("d_") == 0)
-					++titleCounter[2];
-				else if (newTitle->getName().find("k_") == 0)
-					++titleCounter[3];
-				else if (newTitle->getName().find("e_") == 0)
-					++titleCounter[4];
-				else
-					++titleCounter[5]; // x_x_, x_mc_ and the rest.
-			}
-			catch (std::exception& e)
-			{
-				throw std::runtime_error("Cannot import title ID: " + ID + " (" + e.what() + ")");
-			}
-		}
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
+namespace CK3ToEU4.CK3.Titles;
 
-void CK3::Titles::transcribeDynamicRanks()
+class Titles
 {
-	Log(LogLevel::Info) << "-> Transcribing dynamic ranks.";
-	auto counter = 0;
-	for (const auto& [key, rank]: dynamicTitleRanks)
+	public Titles(std::istream& theStream)
 	{
-		if (!titles.contains(key))
-			continue; // Yay?
-		if (!titles.at(key))
-			continue; // Huh?
+		registerKeys();
+		parseStream(theStream);
+		clearRegisteredKeywords();
 
-		// There will not be a dynamic county or barony.
-		if (rank == "duchy")
-			titles.at(key)->setDynamicLevel(LEVEL::DUCHY);
-		else if (rank == "kingdom")
-		{
-			titles.at(key)->setDynamicLevel(LEVEL::KINGDOM);
-			titles.at(key)->setCustomTitle();
-		}
-		else if (rank == "empire")
-		{
-			titles.at(key)->setDynamicLevel(LEVEL::EMPIRE);
-			titles.at(key)->setCustomTitle();
-		}
-		counter++;
+		// This bit assigns CK3::Level to dynamic titles that have a rank definition in the save. It should be all of them, but it's CK3, so who knows.
+		if (!dynamicTitleRanks.empty())
+			transcribeDynamicRanks();
 	}
-	Log(LogLevel::Info) << "<> Transcribed " << counter << " dynamics.";
-}
 
-void CK3::Titles::linkCoats(const CoatsOfArms& coats)
-{
-	auto counter = 0;
-	const auto& coatData = coats.getCoats();
-	for (const auto& title: titles)
+	public const auto& getTitles() const { return titles; }
+	public const auto& getCounter() const { return titleCounter; }
+
+	public void linkCoats(const CoatsOfArms& coats)
 	{
-		if (!title.second->getCoA())
-			continue;
-		const auto& coatDataItr = coatData.find(title.second->getCoA()->first);
-		if (coatDataItr != coatData.end())
-		{
-			title.second->loadCoat(*coatDataItr);
-			++counter;
-		}
-		else
+		auto counter = 0;
+		const auto& coatData = coats.getCoats();
+		for (const auto& title: titles)
 		{
-			Log(LogLevel::Warning) << "Title " + title.first + " has CoA " + std::to_string(title.second->getCoA()->first) +
-													" which has no definition. Using Default.";
-			auto defaultCoat = std::make_pair(title.second->getCoA()->first, std::make_shared<CoatOfArms>());
-			title.second->loadCoat(defaultCoat);
+			if (!title.second->getCoA())
+				continue;
+			const auto& coatDataItr = coatData.find(title.second->getCoA()->first);
+			if (coatDataItr != coatData.end())
+			{
+				title.second->loadCoat(*coatDataItr);
+				++counter;
+			}
+			else
+			{
+				Log(LogLevel::Warning) << "Title " + title.first + " has CoA " + std::to_string(title.second->getCoA()->first) +
+					" which has no definition. Using Default.";
+				auto defaultCoat = std::make_pair(title.second->getCoA()->first, std::make_shared<CoatOfArms>());
+				title.second->loadCoat(defaultCoat);
+			}
 		}
+		Log(LogLevel::Info) << "<> " << counter << " titles updated.";
 	}
-	Log(LogLevel::Info) << "<> " << counter << " titles updated.";
-}
 
-void CK3::Titles::linkTitles()
+	public void linkTitles()
 {
 	auto DFLcounter = 0;
 	auto DJLcounter = 0;
@@ -275,14 +192,7 @@ void CK3::Titles::linkTitles()
 	Log(LogLevel::Info) << "<> " << DFLcounter << " defacto lieges, " << DJLcounter << " dejure lieges, " << DFVcounter << " defacto vassals, " << DJVcounter
 							  << " dejure vassals updated.";
 }
-
-void CK3::Titles::relinkDeFactoVassals()
-{
-	for (const auto& title: titles)
-		title.second->relinkDeFactoVassals();
-}
-
-void CK3::Titles::linkCharacters(const Characters& characters)
+	public void linkCharacters(Characters characters)
 {
 	auto holderCounter = 0;
 	auto claimantCounter = 0;
@@ -405,24 +315,112 @@ void CK3::Titles::linkCharacters(const Characters& characters)
 	Log(LogLevel::Info) << "<> " << holderCounter << " holders, " << claimantCounter << " claimants, " << heirCounter << " heirs, " << exCounter
 							  << " previous holders, " << electorCounter << " electors updated.";
 }
+	public void linkLandedTitles(LandedTitles landedTitles)
+	{
+		// We're injecting clay towards titles instead the other way around.
+		auto counter = 0;
+		for (const auto& clay: landedTitles.getFoundTitles())
+		{
+			const auto& titleItr = titles.find(clay.first);
+			if (titleItr != titles.end())
+			{
+				titleItr->second->loadClay(clay.second);
+				++counter;
+			}
+			else
+			{
+				Log(LogLevel::Error) << "Clay for " << clay.first
+					<< " has no title definition! THIS IS BAD! Are you converting an old save against a new CK3 version?";
+			}
+		}
+		Log(LogLevel::Info) << "<> " << counter << " titles updated.";
+	}
+	public void relinkDeFactoVassals()
+	{
+		for (const auto& title: titles)
+		title.second->relinkDeFactoVassals();
+	}
 
-void CK3::Titles::linkLandedTitles(const LandedTitles& landedTitles)
+	private void registerKeys()
 {
-	// We're injecting clay towards titles instead the other way around.
-	auto counter = 0;
-	for (const auto& clay: landedTitles.getFoundTitles())
-	{
-		const auto& titleItr = titles.find(clay.first);
-		if (titleItr != titles.end())
+	registerKeyword("dynamic_templates", [this](const std::string& unused, std::istream& theStream) {
+		const commonItems::blobList dynamicRanks(theStream);
+		for (const auto& dynamicTitle: dynamicRanks.getBlobs())
 		{
-			titleItr->second->loadClay(clay.second);
-			++counter;
+			std::stringstream blobStream(dynamicTitle);
+			const DynamicTemplate dynamicTitleTemplate(blobStream);
+			if (!dynamicTitleTemplate.getDynamicTitleKey().empty() && !dynamicTitleTemplate.getDynamicTitleRank().empty())
+				dynamicTitleRanks.insert(std::pair(dynamicTitleTemplate.getDynamicTitleKey(), dynamicTitleTemplate.getDynamicTitleRank()));
 		}
-		else
+	});
+	registerKeyword("landed_titles", [this](const std::string& unused, std::istream& theStream) {
+		// A bit of recursion is good for the soul.
+		const auto& tempTitles = Titles(theStream);
+		titles = tempTitles.getTitles();
+		titleCounter = tempTitles.getCounter();
+	});
+	registerRegex(R"(\d+)", [this](const std::string& ID, std::istream& theStream) {
+		// Incoming titles may not be actual titles but half-deleted junk.
+		const auto& titleBlob = commonItems::stringOfItem(theStream).getString();
+		if (titleBlob.find('{') != std::string::npos)
 		{
-			Log(LogLevel::Error) << "Clay for " << clay.first
-										<< " has no title definition! THIS IS BAD! Are you converting an old save against a new CK3 version?";
+			std::stringstream tempStream(titleBlob);
+			try
+			{
+				auto newTitle = std::make_shared<Title>(tempStream, std::stoll(ID));
+				if (!newTitle->getName().empty())
+					titles.insert(std::pair(newTitle->getName(), newTitle));
+				if (newTitle->getName().find("b_") == 0)
+					++titleCounter[0];
+				else if (newTitle->getName().find("c_") == 0)
+					++titleCounter[1];
+				else if (newTitle->getName().find("d_") == 0)
+					++titleCounter[2];
+				else if (newTitle->getName().find("k_") == 0)
+					++titleCounter[3];
+				else if (newTitle->getName().find("e_") == 0)
+					++titleCounter[4];
+				else
+					++titleCounter[5]; // x_x_, x_mc_ and the rest.
+			}
+			catch (std::exception& e)
+			{
+				throw std::runtime_error("Cannot import title ID: " + ID + " (" + e.what() + ")");
+			}
 		}
-	}
-	Log(LogLevel::Info) << "<> " << counter << " titles updated.";
+	});
+	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
 }
+	private void transcribeDynamicRanks()
+	{
+		Log(LogLevel::Info) << "-> Transcribing dynamic ranks.";
+		auto counter = 0;
+		for (const auto& [key, rank]: dynamicTitleRanks)
+		{
+			if (!titles.contains(key))
+				continue; // Yay?
+			if (!titles.at(key))
+				continue; // Huh?
+
+			// There will not be a dynamic county or barony.
+			if (rank == "duchy")
+				titles.at(key)->setDynamicLevel(LEVEL::DUCHY);
+			else if (rank == "kingdom")
+			{
+				titles.at(key)->setDynamicLevel(LEVEL::KINGDOM);
+				titles.at(key)->setCustomTitle();
+			}
+			else if (rank == "empire")
+			{
+				titles.at(key)->setDynamicLevel(LEVEL::EMPIRE);
+				titles.at(key)->setCustomTitle();
+			}
+			counter++;
+		}
+		Log(LogLevel::Info) << "<> Transcribed " << counter << " dynamics.";
+	}
+
+	private std::vector<int> titleCounter = {0, 0, 0, 0, 0, 0};
+	private std::map<std::string, std::shared_ptr<Title>> titles; // We're using NAME, not ID for key value!
+	private std::map<std::string, std::string> dynamicTitleRanks;
+};
diff --git a/CK3ToEU4/Source/CK3/World.cs b/CK3ToEU4/Source/CK3/World.cs
index e77299cd..376d8c02 100644
--- a/CK3ToEU4/Source/CK3/World.cs
+++ b/CK3ToEU4/Source/CK3/World.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using CK3ToEU4.CK3.Titles;
 using CK3ToEU4.Configuration;
 using commonItems;
 using commonItems.Mods;
@@ -257,9 +258,9 @@ private void locatePlayerTitle(Config theConfiguration)
     {
 	    foreach (var (titleId, title) in IndependentTitles)
 	    {
-		    if (title.getHolder() && title->getHolder()->first == playerId)
+		    if (title.getHolder() && title.getHolder().first == playerId)
 		    {
-			    Logger.Info("Player title: " << title->getName();
+			    Logger.Info("Player title: " << title.getName();
 			    PlayerTitleId = title.first;
 			    break;
 		    }
@@ -626,7 +627,7 @@ private void shatterHRE(Config theConfiguration) const
 	foreach (var afflictedPerson: brickedPeople)
 	{
 		const auto& holderDomain = afflictedPerson.second->getCharacterDomain()->getDomain();
-		const auto holderTitles = std::map(holderDomain.begin(), holderDomain.end());
+		const auto holderTitles = Dictionary(holderDomain.begin(), holderDomain.end());
 
 		foreach (var holderTitle: holderDomain)
 		{
@@ -636,7 +637,7 @@ private void shatterHRE(Config theConfiguration) const
 			{
 				// fix this title.
 				const auto& djLiege = holderTitle.second->getDJLiege();
-				djLiege->second->addDFVassals(std::map{holderTitle});
+				djLiege->second->addDFVassals(Dictionary{holderTitle});
 				holderTitle.second->loadDFLiege(*djLiege);
 			}
 		}
@@ -760,7 +761,7 @@ private void shatterEmpires(Config theConfiguration) const
 			}
 
 			const auto& holderDomain = afflictedPerson.second->getCharacterDomain()->getDomain();
-			const auto holderTitles = std::map(holderDomain.begin(), holderDomain.end());
+			const auto holderTitles = Dictionary(holderDomain.begin(), holderDomain.end());
 
 			foreach (var holderTitle: holderDomain)
 			{
@@ -770,7 +771,7 @@ private void shatterEmpires(Config theConfiguration) const
 				{
 					// fix this title.
 					const auto& djLiege = holderTitle.second->getDJLiege();
-					djLiege->second->addDFVassals(std::map{holderTitle});
+					djLiege->second->addDFVassals(Dictionary{holderTitle});
 					holderTitle.second->loadDFLiege(*djLiege);
 				}
 			}
@@ -899,7 +900,7 @@ private void splitVassals(Config theConfiguration)
 			double threshold = static_cast<double>(countiesClaimed.size()) / relevantVassals + 0.1 * static_cast<double>(countiesClaimed.size());
 			threshold *= vassalSplitoffMapper.getFactor();
 			if (static_cast<double>(vassalProvincesClaimed.size()) > threshold)
-				newIndeps.insert(std::pair(vassal.second->getName(), vassal.second));
+				newIndeps.insert(KeyValuePair(vassal.second->getName(), vassal.second));
 		}
 	}
 
@@ -908,7 +909,7 @@ private void splitVassals(Config theConfiguration)
 	{
 		const auto& liege = newIndep.second->getDFLiege();
 		liege->second->addGeneratedVassal(newIndep);
-		newIndep.second->loadGeneratedLiege(std::pair(liege->second->getName(), liege->second));
+		newIndep.second->loadGeneratedLiege(KeyValuePair(liege->second->getName(), liege->second));
 		newIndep.second->grantIndependence();
 		independentTitles.insert(newIndep);
 	}
@@ -940,7 +941,7 @@ private void gatherCourtierNames()
 			if (character.second->getEmployer() && character.second->getEmployer()->second)
 			{
 				// easiest case.
-				holderCourtiers[character.second->getEmployer()->first].insert(std::pair(character.second->getName(), !character.second->isFemale()));
+				holderCourtiers[character.second->getEmployer()->first].insert(KeyValuePair(character.second->getName(), !character.second->isFemale()));
 				holderCouncilors[character.second->getEmployer()->first].insert(character);
 			}
 			else if (character.second->getCharacterDomain() && !character.second->getCharacterDomain()->getDomain().empty())
@@ -955,7 +956,7 @@ private void gatherCourtierNames()
 				const auto& liege = liegeTitle->second->getHolder();
 				if (!liege || !liege->second)
 					continue; // Or maybe we should fire his liege.
-				holderCourtiers[liege->first].insert(std::pair(character.second->getName(), character.second->isFemale()));
+				holderCourtiers[liege->first].insert(KeyValuePair(character.second->getName(), character.second->isFemale()));
 				holderCouncilors[liege->first].insert(character);
 			}
 			else
@@ -967,7 +968,7 @@ private void gatherCourtierNames()
 		else if (character.second->getEmployer())
 		{
 			// Being employed but without a council task means a knight or physician or similar. Works for us.
-			holderCourtiers[character.second->getEmployer()->first].insert(std::pair(character.second->getName(), !character.second->isFemale()));
+			holderCourtiers[character.second->getEmployer()->first].insert(KeyValuePair(character.second->getName(), !character.second->isFemale()));
 		}
 	}
 
@@ -1000,7 +1001,7 @@ private void congregateDFCounties()
 		title.second->congregateDFCounties();
 		foreach (var province: title.second->getOwnedDFCounties())
 		{
-			province.second->loadHoldingTitle(std::pair(title.first, title.second));
+			province.second->loadHoldingTitle(KeyValuePair(title.first, title.second));
 		}
 		counter += static_cast<int>(title.second->getOwnedDFCounties().size());
 	}
@@ -1065,7 +1066,7 @@ private void setElectors()
 	// Preambule done, we start here.
 	// Make a registry of indep titles and their holders.
 	Dictionary<long, Dictionary<string, Title?>> holderTitles; // holder/titles
-	std::pair<long, Character?> hreHolder;
+	KeyValuePair<long, Character?> hreHolder;
 
 	foreach (var title: independentTitles)
 	{
diff --git a/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatOfArms.cpp b/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatOfArms.cpp
deleted file mode 100644
index 4419d5fd..00000000
--- a/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatOfArms.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "CoatOfArms.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::CoatOfArms::CoatOfArms(std::istream& theStream, long long theID): ID(theID)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::CoatOfArms::registerKeys()
-{
-	registerKeyword("pattern", [this](const std::string& unused, std::istream& theStream) {
-		pattern = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("color1", [this](const std::string& unused, std::istream& theStream) {
-		try
-		{
-			color1 = laFabricaDeColor.getColor(theStream);
-		}
-		catch (std::exception& e)
-		{
-			Log(LogLevel::Warning) << e.what() << " - sidestepping with black.";
-			color1 = commonItems::Color(std::array<int, 3>{0, 0, 0});
-		}
-	});
-	registerKeyword("color2", [this](const std::string& unused, std::istream& theStream) {
-		try
-		{
-			color2 = laFabricaDeColor.getColor(theStream);
-		}
-		catch (std::exception& e)
-		{
-			Log(LogLevel::Warning) << e.what() << " - sidestepping with black.";
-			color2 = commonItems::Color(std::array<int, 3>{0, 0, 0});
-		}
-	});
-	registerKeyword("color3", [this](const std::string& unused, std::istream& theStream) {
-		try
-		{
-			color3 = laFabricaDeColor.getColor(theStream);
-		}
-		catch (std::exception& e)
-		{
-			Log(LogLevel::Warning) << e.what() << " - sidestepping with black.";
-			color3 = commonItems::Color(std::array<int, 3>{0, 0, 0});
-		}
-	});
-	registerKeyword("textured_emblem", [this](const std::string& unused, std::istream& theStream) {
-		texturedEmblems.emplace_back(Emblem(theStream));
-	});
-	registerKeyword("colored_emblem", [this](const std::string& unused, std::istream& theStream) {
-		coloredEmblems.emplace_back(Emblem(theStream));
-	});
-	registerKeyword("sub", [this](const std::string& unused, std::istream& theStream) {
-		subs.emplace_back(std::make_shared<CoatOfArms>(theStream, 0));
-	});
-	registerKeyword("instance", [this](const std::string& unused, std::istream& theStream) {
-		auto instance = EmblemInstance(theStream);
-		if (instance.getOffset().empty())
-			instance.defaultOffset();
-		instances.emplace_back(instance);
-	});
-	registerKeyword("parent", [this](const std::string& unused, std::istream& theStream) {
-		parent = std::make_pair(commonItems::singleString(theStream).getString(), nullptr);
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
diff --git a/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatOfArms.h b/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatOfArms.h
deleted file mode 100644
index 453a5d2c..00000000
--- a/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatOfArms.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef CK3_COATOFARMS_H
-#define CK3_COATOFARMS_H
-#include "Color.h"
-#include "Emblem.h"
-#include "Parser.h"
-extern commonItems::Color::Factory laFabricaDeColor;
-
-namespace CK3
-{
-class CoatOfArms: commonItems::parser
-{
-  public:
-	CoatOfArms() = default;
-	CoatOfArms(std::istream& theStream, long long theID);
-
-	[[nodiscard]] auto getID() const { return ID; }
-	[[nodiscard]] const auto& getPattern() const { return pattern; }
-	[[nodiscard]] const auto& getColor1() const { return color1; }
-	[[nodiscard]] const auto& getColor2() const { return color2; }
-	[[nodiscard]] const auto& getColor3() const { return color3; }
-	[[nodiscard]] const auto& getTexturedEmblems() const { return texturedEmblems; }
-	[[nodiscard]] const auto& getColoredEmblems() const { return coloredEmblems; }
-	[[nodiscard]] const auto& getSubs() const { return subs; }
-	[[nodiscard]] const auto& getInstances() const { return instances; }
-	[[nodiscard]] const auto& getParent() const { return parent; }
-
-	void loadParent(const std::pair<std::string, std::shared_ptr<CoatOfArms>>& theParent) { parent = theParent; }
-
-  private:
-	void registerKeys();
-
-	long long ID = 0;
-	std::optional<std::string> pattern;
-	std::optional<commonItems::Color> color1; // mask: 255, 0, 0 - red
-	std::optional<commonItems::Color> color2; // mask: 255, 255, 0 - yellow
-	std::optional<commonItems::Color> color3; // mask: 255, 255, 255 - white
-	std::vector<Emblem> texturedEmblems;
-	std::vector<Emblem> coloredEmblems;
-	std::vector<std::shared_ptr<CoatOfArms>> subs;										// These are sub-coatsofarms. They are recursive!
-	std::vector<EmblemInstance> instances;													// Used to position sub-coats.
-	std::optional<std::pair<std::string, std::shared_ptr<CoatOfArms>>> parent; // Used for recursive external flags.
-};
-} // namespace CK3
-
-#endif // CK3_COATOFARMS_H
diff --git a/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatsOfArms.cpp b/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatsOfArms.cpp
deleted file mode 100644
index 50d6cb3c..00000000
--- a/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatsOfArms.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "CoatsOfArms.h"
-#include "../Titles/Title.h"
-#include "../Titles/Titles.h"
-#include "CoatOfArms.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::CoatsOfArms::CoatsOfArms(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::CoatsOfArms::registerKeys()
-{
-	registerRegex(R"(\d+)", [this](const std::string& coaID, std::istream& theStream) {
-		auto newCoA = std::make_shared<CoatOfArms>(theStream, std::stoll(coaID));
-		coats.insert(std::pair(newCoA->getID(), newCoA));
-	});
-	registerKeyword("coat_of_arms_manager_database", [this](const std::string& unused, std::istream& theStream) {
-		coats = CoatsOfArms(theStream).getCoats();
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
-
-void CK3::CoatsOfArms::linkParents(const Titles& titles)
-{
-	auto counter = 0;
-	const auto& titleData = titles.getTitles();
-	for (const auto& coat: coats)
-	{
-		if (!coat.second->getParent())
-			continue;
-		const auto& titleDataItr = titleData.find(coat.second->getParent()->first);
-		if (titleDataItr != titleData.end())
-		{
-			if (!titleDataItr->second->getCoA())
-				throw std::runtime_error("CoA " + std::to_string(coat.first) + " has parent " + coat.second->getParent()->first + " which has no coat defined!");
-			if (!coats.count(titleDataItr->second->getCoA()->first))
-				throw std::runtime_error(
-					 "CoA " + std::to_string(coat.first) + " has parent " + coat.second->getParent()->first + " which has invalid coat defined!");
-			coat.second->loadParent(std::make_pair(coat.second->getParent()->first, coats[titleDataItr->second->getCoA()->first]));
-			++counter;
-		}
-		else
-		{
-			throw std::runtime_error("CoA " + std::to_string(coat.first) + " has parent " + coat.second->getParent()->first + " which is undefined!");
-		}
-	}
-	Log(LogLevel::Info) << "<> " << counter << " coats updated.";
-}
\ No newline at end of file
diff --git a/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatsOfArms.h b/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatsOfArms.h
deleted file mode 100644
index 39732733..00000000
--- a/CK3ToEU4/Source/CK3World/CoatsOfArms/CoatsOfArms.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef CK3_COATSOFARMS_H
-#define CK3_COATSOFARMS_H
-#include "Parser.h"
-
-namespace CK3
-{
-class CoatOfArms;
-class Titles;
-class CoatsOfArms: commonItems::parser
-{
-  public:
-	CoatsOfArms() = default;
-	explicit CoatsOfArms(std::istream& theStream);
-	[[nodiscard]] auto getCoats() const { return coats; }
-
-	void linkParents(const Titles& titles);
-
-  private:
-	void registerKeys();
-
-	std::map<long long, std::shared_ptr<CoatOfArms>> coats;
-};
-} // namespace CK3
-
-#endif // CK3_COATSOFARMS_H
diff --git a/CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.cpp b/CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.cpp
deleted file mode 100644
index e72a1b29..00000000
--- a/CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "Emblem.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::Emblem::Emblem(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::Emblem::registerKeys()
-{
-	registerKeyword("texture", [this](const std::string& unused, std::istream& theStream) {
-		texture = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("color1", [this](const std::string& unused, std::istream& theStream) {
-		try
-		{
-			color1 = laFabricaDeColor.getColor(theStream);
-		}
-		catch (std::exception& e)
-		{
-			Log(LogLevel::Warning) << e.what() << " - sidestepping with black.";
-			color1 = commonItems::Color(std::array<int, 3>{0, 0, 0});
-		}
-	});
-	registerKeyword("color2", [this](const std::string& unused, std::istream& theStream) {
-		try
-		{
-			color2 = laFabricaDeColor.getColor(theStream);
-		}
-		catch (std::exception& e)
-		{
-			Log(LogLevel::Warning) << e.what() << " - sidestepping with black.";
-			color2 = commonItems::Color(std::array<int, 3>{0, 0, 0});
-		}
-	});
-	registerKeyword("color3", [this](const std::string& unused, std::istream& theStream) {
-		try
-		{
-			color3 = laFabricaDeColor.getColor(theStream);
-		}
-		catch (std::exception& e)
-		{
-			Log(LogLevel::Warning) << e.what() << " - sidestepping with black.";
-			color3 = commonItems::Color(std::array<int, 3>{0, 0, 0});
-		}
-	});
-	registerKeyword("mask", [this](const std::string& unused, std::istream& theStream) {
-		mask = commonItems::intList(theStream).getInts();
-	});
-	registerKeyword("instance", [this](const std::string& unused, std::istream& theStream) {
-		auto instance = EmblemInstance(theStream);
-		if (instance.getPosition().empty())
-			instance.defaultPosition();
-		instances.emplace_back(instance);
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
diff --git a/CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.h b/CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.h
deleted file mode 100644
index f3d0aa60..00000000
--- a/CK3ToEU4/Source/CK3World/CoatsOfArms/Emblem.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef CK3_EMBLEM_H
-#define CK3_EMBLEM_H
-#include "Color.h"
-#include "EmblemInstance.h"
-#include "Parser.h"
-extern commonItems::Color::Factory laFabricaDeColor;
-
-namespace CK3
-{
-class Emblem: commonItems::parser
-{
-  public:
-	Emblem() = default;
-	Emblem(std::istream& theStream);
-
-	[[nodiscard]] const auto& getTexture() const { return texture; }
-	[[nodiscard]] const auto& getColor1() const { return color1; }
-	[[nodiscard]] const auto& getColor2() const { return color2; }
-	[[nodiscard]] const auto& getColor3() const { return color3; }
-	[[nodiscard]] const auto& getMask() const { return mask; }
-	[[nodiscard]] const auto& getInstances() const { return instances; }
-
-  private:
-	void registerKeys();
-
-	std::optional<std::string> texture;
-	std::optional<commonItems::Color> color1; // mask: 0, 0, 128 - blueish
-	std::optional<commonItems::Color> color2; // mask: 0, 255, 128 - greenish
-	std::optional<commonItems::Color> color3; // mask: 255, 0, 128 - unsupported by PDX, must render to white!
-	std::vector<int> mask;
-	std::vector<EmblemInstance> instances;
-};
-} // namespace CK3
-
-#endif // CK3_EMBLEM_H
diff --git a/CK3ToEU4/Source/CK3World/CoatsOfArms/EmblemInstance.cpp b/CK3ToEU4/Source/CK3World/CoatsOfArms/EmblemInstance.cpp
deleted file mode 100644
index c4939fc5..00000000
--- a/CK3ToEU4/Source/CK3World/CoatsOfArms/EmblemInstance.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "EmblemInstance.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::EmblemInstance::EmblemInstance(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::EmblemInstance::registerKeys()
-{
-	registerKeyword("rotation", [this](const std::string& unused, std::istream& theStream) {
-		rotation = commonItems::singleDouble(theStream).getDouble();
-	});
-	registerKeyword("depth", [this](const std::string& unused, std::istream& theStream) {
-		depth = commonItems::singleDouble(theStream).getDouble();
-	});
-	registerKeyword("position", [this](const std::string& unused, std::istream& theStream) {
-		position = commonItems::doubleList(theStream).getDoubles();
-	});
-	registerKeyword("scale", [this](const std::string& unused, std::istream& theStream) {
-		scale = commonItems::doubleList(theStream).getDoubles();
-	});
-	registerKeyword("offset", [this](const std::string& unused, std::istream& theStream) {
-		offset = commonItems::doubleList(theStream).getDoubles();
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
diff --git a/CK3ToEU4/Source/CK3World/CoatsOfArms/EmblemInstance.h b/CK3ToEU4/Source/CK3World/CoatsOfArms/EmblemInstance.h
deleted file mode 100644
index 5409cfd2..00000000
--- a/CK3ToEU4/Source/CK3World/CoatsOfArms/EmblemInstance.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef CK3_EMBLEMINSTANCE_H
-#define CK3_EMBLEMINSTANCE_H
-#include "Parser.h"
-
-namespace CK3
-{
-class EmblemInstance: commonItems::parser
-{
-  public:
-	EmblemInstance() = default;
-	EmblemInstance(std::istream& theStream);
-
-	[[nodiscard]] auto getRotation() const { return rotation; }
-	[[nodiscard]] auto getDepth() const { return depth; }
-	[[nodiscard]] const auto& getPosition() const { return position; }
-	[[nodiscard]] const auto& getScale() const { return scale; }
-	[[nodiscard]] const auto& getOffset() const { return offset; }
-	void defaultPosition() { position = {0.5, 0.5}; }
-	void defaultOffset() { offset = {0.0, 0.0}; }
-
-  private:
-	void registerKeys();
-
-	double rotation = 0.0;						 // Degrees, clockwise.
-	double depth = 0.0;							 // Do. Not. Ask. Go to wiki and complain there.
-	std::vector<double> position;				 // Default position is UPPER LEFT corner. Targets CENTER of emblem.
-	std::vector<double> scale = {1.0, 1.0}; // Relative to image size. Defaults to "across entire image".
-	std::vector<double> offset;				 // Used in sub-coat instances. Also UPPER LEFT corner. Targets UPPER LEFT corner of subcoat.
-};
-} // namespace CK3
-
-#endif // CK3_EMBLEMINSTANCE_H
diff --git a/CK3ToEU4/Source/CK3World/Cultures/Culture.cpp b/CK3ToEU4/Source/CK3World/Cultures/Culture.cpp
deleted file mode 100644
index 026b9c38..00000000
--- a/CK3ToEU4/Source/CK3World/Cultures/Culture.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include "Culture.h"
-#include "../../Mappers/CultureMapper/CultureMapper.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::Culture::Culture(std::istream& theStream, long long theID): ID(theID)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::Culture::registerKeys()
-{
-	registerKeyword("culture_template", [this](std::istream& theStream) {
-		culture_template = commonItems::getString(theStream);
-	});
-	registerKeyword("name", [this](std::istream& theStream) {
-		localizedName = commonItems::getString(theStream);
-	});
-	registerKeyword("heritage", [this](std::istream& theStream) {
-		heritage = commonItems::getString(theStream);
-	});
-	registerKeyword("ethos", [this](std::istream& theStream) {
-		ethos = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("traditions", [this](std::istream& theStream) {
-		traditions = commonItems::getStrings(theStream);
-	});
-	registerKeyword("name_list", [this](std::istream& theStream) {
-		auto temp = commonItems::getString(theStream);
-		if (temp.size() > 10)
-		{
-			temp = temp.substr(10, temp.size()); // drop "name_list_", leave "polish"
-			nameLists.insert(temp);
-		}
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
-
-void CK3::Culture::concoctCultureName(const mappers::LocalizationMapper& localizationMapper,
-	 const mappers::CultureMapper& cultureMapper,
-	 std::map<std::string, int>& cultureNamingCounter)
-{
-	/* This function is responsible for determining what a culture is and where it's going. Base/vanilla cultures are known to us but
-	 * hybrids and divergences most certainly are not. We can try to normalize some of them like Swiss (hybrid) or Austrian (divergence) into
-	 * eu4 cultures (sidestepping cultural mapping altogether), and if that fails we can generate dynamic cultures and file them in culture
-	 * groups according to their heritages. In this function we do the first half.
-	 */
-
-	// Is this a base ck3 culture?
-	if (culture_template)
-	{
-		name = *culture_template;
-		return;
-	}
-
-	// Does this culture have a name? If not that means the player was very funny. We'll do the same.
-	if (!localizedName)
-	{
-		name = "noname";
-		return;
-	}
-
-	/* We have a divergent culture. Hybrids and divergents are by definition eu4-ready cultures but:
-	 * 1. we allow for overrides using "ck3 = culture" mappings
-	 * 2. not all of them have eu4 definitions which we'll have to generate.
-	 * If a culture is not in "eu4 = " target block then 2) applies and we need to know this.
-	 */
-
-	// Can we reverse map it via localization into some common base like "austrian"?
-	const auto& match = localizationMapper.reverseLookupCultureName(*localizedName);
-	if (match)
-	{
-		auto strippedName = *match;
-		strippedName = strippedName.substr(0, strippedName.size() - 5);
-		if (cultureMapper.getTargetCultures().contains(strippedName))
-		{
-			// this is a full-flegded eu4 culture with predefined definitions.
-			name = strippedName;
-			eu4Ready = true;
-			return;
-		}
-
-		if (cultureMapper.getSourceCultures().contains(strippedName))
-		{
-			// this is a culture we've mapped to something else. Proceed normally as if it were vanilla ck3 culture.
-			name = strippedName;
-			return;
-		}
-	}
-
-	// Now everything else, we need to Concoct the culture name, finally.
-	name = "dynamic-";
-	for (const auto& entry: nameLists)
-	{
-		// Enery name component must be mapped to some base eu4 culture, so that eu4tovic2 can decompose it.
-		const auto& cultureMatch = cultureMapper.cultureNonRegionalNonReligiousMatch(entry, "", 0, "");
-		if (cultureMatch)
-		{
-			name += *cultureMatch + "-";
-		}
-		else
-		{
-			Log(LogLevel::Warning) << "Mapping " << entry << " to an EU4 culture failed! Check mappings!";
-			name += entry + "-";
-		}
-	}
-	name += "culture";
-
-	// did we see this culture before, elsewhere?
-
-	if (cultureNamingCounter.contains(name))
-	{
-
-		++cultureNamingCounter.at(name);
-		name += "-num" + std::to_string(cultureNamingCounter.at(name));
-	}
-	else
-	{
-		cultureNamingCounter.emplace(name, 1);
-		name += "-num1";
-	}
-
-	dynamic = true;
-}
diff --git a/CK3ToEU4/Source/CK3World/Cultures/Culture.h b/CK3ToEU4/Source/CK3World/Cultures/Culture.h
deleted file mode 100644
index bccf188b..00000000
--- a/CK3ToEU4/Source/CK3World/Cultures/Culture.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef CK3_CULTURE_H
-#define CK3_CULTURE_H
-#include "../../Mappers/LocalizationMapper/LocalizationMapper.h"
-#include "Parser.h"
-#include <set>
-
-namespace mappers
-{
-class CultureMapper;
-}
-
-namespace CK3
-{
-class Culture: commonItems::parser
-{
-  public:
-	Culture() = default;
-	Culture(std::istream& theStream, long long theID);
-
-	[[nodiscard]] auto getID() const { return ID; }
-	[[nodiscard]] auto isEU4Ready() const { return eu4Ready; }
-	[[nodiscard]] auto isDynamic() const { return dynamic; }
-	[[nodiscard]] const auto& getLocalizedName() const { return localizedName; }
-	[[nodiscard]] const auto& getName() const { return name; }
-	[[nodiscard]] const auto& getNameLists() const { return nameLists; }
-	[[nodiscard]] const auto& getHeritage() const { return heritage; }
-	[[nodiscard]] const auto& getTemplate() const { return culture_template; }
-	[[nodiscard]] const auto& getEthos() const { return ethos; }
-	[[nodiscard]] const auto& getTraditions() const { return traditions; }
-
-	void setDynamic() { dynamic = true; }
-	void concoctCultureName(const mappers::LocalizationMapper& localizationMapper,
-		 const mappers::CultureMapper& cultureMapper,
-		 std::map<std::string, int>& cultureNamingCounter);
-
-  private:
-	void registerKeys();
-
-	long long ID = 0;
-	bool eu4Ready = false; // this culture has eu4 match and needs zero processing
-	bool dynamic = false;  // this culture is dynamic and will need generation of cultural data
-
-	std::optional<std::string> culture_template; // this has data only for base ck3 cultures, like czech or german
-	std::optional<std::string> localizedName;		// this can be anything - user input or localized name in a particular language game is running.
-	std::string heritage;								// all cultures should have this.
-	std::set<std::string> nameLists;					// We use these to generate dynamic culture code names, in lack of a better solution.
-	std::string ethos;									// used to generate custom ideas for custom tags with a custom culture
-	std::vector<std::string> traditions;			// used to generate custom ideas for custom tags with a custom culture
-
-	std::string name; // calculated value from all of the above - can be either *eu4* culture, ck3 vanilla, or anything in between.
-};
-} // namespace CK3
-
-#endif // CK3_CULTURE_H
diff --git a/CK3ToEU4/Source/CK3World/Cultures/Cultures.cpp b/CK3ToEU4/Source/CK3World/Cultures/Cultures.cpp
deleted file mode 100644
index 2022fab7..00000000
--- a/CK3ToEU4/Source/CK3World/Cultures/Cultures.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "Cultures.h"
-#include "CommonRegexes.h"
-#include "Culture.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-#include <ranges>
-
-CK3::Cultures::Cultures(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::Cultures::registerKeys()
-{
-	registerRegex(R"(\d+)", [this](const std::string& cultureID, std::istream& theStream) {
-		auto newCulture = std::make_shared<Culture>(theStream, std::stoll(cultureID));
-		cultures.insert(std::pair(newCulture->getID(), newCulture));
-	});
-	registerKeyword("cultures", [this](std::istream& theStream) {
-		const auto scraper = Cultures(theStream);
-		cultures = scraper.getCultures();
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
-
-void CK3::Cultures::concoctCultures(const mappers::LocalizationMapper& localizationMapper, const mappers::CultureMapper& cultureMapper)
-{
-	for (const auto& culture: cultures | std::views::values)
-	{
-		culture->concoctCultureName(localizationMapper, cultureMapper, cultureNamingCounter);
-	}
-}
diff --git a/CK3ToEU4/Source/CK3World/Cultures/Cultures.h b/CK3ToEU4/Source/CK3World/Cultures/Cultures.h
deleted file mode 100644
index 62b7a951..00000000
--- a/CK3ToEU4/Source/CK3World/Cultures/Cultures.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef CK3_CULTURES_H
-#define CK3_CULTURES_H
-#include "../../Mappers/CultureMapper/CultureMapper.h"
-#include "../../Mappers/LocalizationMapper/LocalizationMapper.h"
-#include "Parser.h"
-
-namespace CK3
-{
-class Culture;
-class Cultures: commonItems::parser
-{
-  public:
-	Cultures() = default;
-	explicit Cultures(std::istream& theStream);
-
-	[[nodiscard]] const auto& getCultures() const { return cultures; }
-	void concoctCultures(const mappers::LocalizationMapper& localizationMapper, const mappers::CultureMapper& cultureMapper);
-
-  private:
-	void registerKeys();
-
-	std::map<long long, std::shared_ptr<Culture>> cultures;
-	std::map<std::string, int> cultureNamingCounter;
-};
-} // namespace CK3
-
-#endif // CK3_CULTURES_H
diff --git a/CK3ToEU4/Source/CK3World/Flags/Flags.cpp b/CK3ToEU4/Source/CK3World/Flags/Flags.cpp
deleted file mode 100644
index a00e0c18..00000000
--- a/CK3ToEU4/Source/CK3World/Flags/Flags.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "Flags.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-// This file loads data flags ("flag_re_restored_antioch"), not graphical flags.
-// Since game uses this type of syntax:
-//		type=flag
-//		flag="flag_formed_kingdom_of_aragon"
-// we'll be loading only those flags that have type = flag set. Unsure if any other flag type exists.
-// Flags in "data" section of save are ignored - those appear to be gameplay-session related and not really global.
-//
-// Flags are further complicated by being bundled in data groups. As of yet we do not know if
-// name="unavailable_unique_decisions" { flag="flag_formed_kingdom_of_aragon" }
-// means aragon is already formed, thus decision is unavailable (giving proper semantics to the flag we scrape) or
-// aragon forming decision is simply unavailable, in which case the flag means the opposite of what we assume it to be.
-
-CK3::Flags::Flags(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-
-	if (itemType == "flag" && !incomingFlag.empty())
-		flags.insert(incomingFlag);
-}
-
-void CK3::Flags::registerKeys()
-{
-	registerKeyword("list", [this](const std::string& unused, std::istream& theStream) {
-		for (const auto& blob: commonItems::blobList(theStream).getBlobs())
-		{
-			auto blobStream = std::stringstream(blob);
-			const auto scraper = Flags(blobStream);
-			const auto& foundFlags = scraper.getFlags();
-			flags.insert(foundFlags.begin(), foundFlags.end());
-		}
-	});
-	registerKeyword("item", [this](const std::string& unused, std::istream& theStream) {
-		const auto scraper = Flags(theStream);
-		const auto& foundFlags = scraper.getFlags();
-		flags.insert(foundFlags.begin(), foundFlags.end());
-	});
-	registerKeyword("flag", [this](const std::string& unused, std::istream& theStream) {
-		incomingFlag = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("type", [this](const std::string& unused, std::istream& theStream) {
-		itemType = commonItems::singleString(theStream).getString();
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
diff --git a/CK3ToEU4/Source/CK3World/Flags/Flags.h b/CK3ToEU4/Source/CK3World/Flags/Flags.h
deleted file mode 100644
index b61ea9fd..00000000
--- a/CK3ToEU4/Source/CK3World/Flags/Flags.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef CK3_FLAGS_H
-#define CK3_FLAGS_H
-#include <set>
-
-#include "Parser.h"
-
-namespace CK3
-{
-class Flags: commonItems::parser
-{
-  public:
-	Flags() = default;
-	explicit Flags(std::istream& theStream);
-
-	[[nodiscard]] const auto& getFlags() const { return flags; }
-
-  private:
-	void registerKeys();
-
-	std::string itemType;
-	std::string incomingFlag;
-	std::set<std::string> flags;
-};
-} // namespace CK3
-
-#endif // CK3_FLAGS_H
diff --git a/CK3ToEU4/Source/CK3World/Geography/CountyDetail.cpp b/CK3ToEU4/Source/CK3World/Geography/CountyDetail.cpp
deleted file mode 100644
index b2eee219..00000000
--- a/CK3ToEU4/Source/CK3World/Geography/CountyDetail.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "CountyDetail.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::CountyDetail::CountyDetail(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::CountyDetail::registerKeys()
-{
-	registerKeyword("development", [this](const std::string& unused, std::istream& theStream) {
-		development = commonItems::singleInt(theStream).getInt();
-	});
-	registerKeyword("culture", [this](const std::string& unused, std::istream& theStream) {
-		culture = std::make_pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
-		if (culture.first == 4294967295)
-			culture.first = 0;
-	});
-	registerKeyword("faith", [this](const std::string& unused, std::istream& theStream) {
-		faith = std::make_pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
-		if (faith.first == 4294967295)
-			faith.first = 0;
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
diff --git a/CK3ToEU4/Source/CK3World/Geography/CountyDetail.h b/CK3ToEU4/Source/CK3World/Geography/CountyDetail.h
deleted file mode 100644
index 5f276542..00000000
--- a/CK3ToEU4/Source/CK3World/Geography/CountyDetail.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef CK3_COUNTYDETAIL_H
-#define CK3_COUNTYDETAIL_H
-#include "Parser.h"
-
-namespace CK3
-{
-class Faith;
-class Culture;
-class CountyDetail: commonItems::parser
-{
-  public:
-	CountyDetail() = default;
-	CountyDetail(std::istream& theStream);
-
-	[[nodiscard]] auto getDevelopment() const { return development; }
-	[[nodiscard]] const auto& getCulture() const { return culture; }
-	[[nodiscard]] const auto& getFaith() const { return faith; }
-	[[nodiscard]] const auto& isDeJureHRE() const { return deJureHRE; }
-
-	void loadCulture(const std::pair<long long, std::shared_ptr<Culture>>& theCulture) { culture = theCulture; }
-	void loadFaith(const std::pair<long long, std::shared_ptr<Faith>>& theFaith) { faith = theFaith; }
-	void setDeJureHRE() { deJureHRE = true; }
-
-  private:
-	void registerKeys();
-
-	int development = 0;
-	std::pair<long long, std::shared_ptr<Culture>> culture;
-	std::pair<long long, std::shared_ptr<Faith>> faith;
-	bool deJureHRE = false;
-};
-} // namespace CK3
-
-#endif // CK3_COUNTYDETAIL_H
diff --git a/CK3ToEU4/Source/CK3World/Religions/Faith.cpp b/CK3ToEU4/Source/CK3World/Religions/Faith.cpp
deleted file mode 100644
index 7a5a68df..00000000
--- a/CK3ToEU4/Source/CK3World/Religions/Faith.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "Faith.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::Faith::Faith(std::istream& theStream, long long theID): ID(theID)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::Faith::registerKeys()
-{
-	registerKeyword("tag", [this](const std::string& unused, std::istream& theStream) {
-		tag = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("doctrine", [this](const std::string& unused, std::istream& theStream) {
-		doctrines.emplace_back(commonItems::singleString(theStream).getString());
-	});
-	registerKeyword("religion", [this](const std::string& unused, std::istream& theStream) {
-		religion = std::make_pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
-	});
-	registerKeyword("color", [this](const std::string& unused, std::istream& theStream) {
-		color = laFabricaDeColor.getColor(theStream);
-	});
-	registerKeyword("template", [this](const std::string& unused, std::istream& theStream) {
-		religionTemplate = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("name", [this](const std::string& unused, std::istream& theStream) {
-		customName = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("adjective", [this](const std::string& unused, std::istream& theStream) {
-		customAdjective = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("religious_head", [this](const std::string& unused, std::istream& theStream) {
-		religiousHead = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("desc", [this](const std::string& unused, std::istream& theStream) {
-		description = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("icon", [this](const std::string& unused, std::istream& theStream) {
-		iconPath = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("variables", [this](const std::string& unused, std::istream& theStream) {
-		if (commonItems::stringOfItem(theStream).getString().find("has_been_reformed") != std::string::npos)
-			reformedFlag = true;
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
diff --git a/CK3ToEU4/Source/CK3World/Religions/Faith.h b/CK3ToEU4/Source/CK3World/Religions/Faith.h
deleted file mode 100644
index e3634e6b..00000000
--- a/CK3ToEU4/Source/CK3World/Religions/Faith.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef CK3_FAITH_H
-#define CK3_FAITH_H
-#include "Color.h"
-#include "Parser.h"
-#include <set>
-
-extern commonItems::Color::Factory laFabricaDeColor;
-
-namespace CK3
-{
-class Religion;
-class Faith: commonItems::parser
-{
-  public:
-	Faith() = default;
-	Faith(std::istream& theStream, long long theID);
-
-	[[nodiscard]] const auto& getName() const { return tag; }
-	[[nodiscard]] const auto& getColor() const { return color; }
-	[[nodiscard]] const auto& getDoctrines() const { return doctrines; }
-	[[nodiscard]] const auto& getReligion() const { return religion; }
-	[[nodiscard]] const auto& getReligiousHead() const { return religiousHead; }
-	[[nodiscard]] auto getID() const { return ID; }
-	[[nodiscard]] const auto& getCustomName() const { return customName; }
-	[[nodiscard]] const auto& getCustomAdj() const { return customAdjective; }
-	[[nodiscard]] const auto& getDescription() const { return description; }
-	[[nodiscard]] const auto& getTemplate() const { return religionTemplate; }
-	[[nodiscard]] const auto& getIconPath() const { return iconPath; }
-	[[nodiscard]] const auto& getReformedFlag() const { return reformedFlag; }
-
-	void setReligiousHead(const auto& newHead) { religiousHead = newHead; }
-	void loadReligion(const std::pair<long long, std::shared_ptr<Religion>>& theReligion) { religion = theReligion; }
-
-  private:
-	void registerKeys();
-
-	bool reformedFlag = false;
-	long long ID = 0;
-	std::string tag;
-	std::string religionTemplate;
-	std::string iconPath;
-	std::string customName;
-	std::string customAdjective;
-	std::string description;
-	std::string religiousHead;
-	std::optional<commonItems::Color> color;
-	std::vector<std::string>
-		 doctrines; // This is a vector in order to keep order consistent. We want the first things read (tenets) to be the first things output, ALWAYS
-	std::pair<long long, std::shared_ptr<Religion>> religion;
-};
-} // namespace CK3
-
-#endif // CK3_FAITH_H
diff --git a/CK3ToEU4/Source/CK3World/Religions/Faiths.cpp b/CK3ToEU4/Source/CK3World/Religions/Faiths.cpp
deleted file mode 100644
index ff0b71e9..00000000
--- a/CK3ToEU4/Source/CK3World/Religions/Faiths.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "Faiths.h"
-#include "CommonRegexes.h"
-#include "Faith.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-#include "Religions.h"
-
-CK3::Faiths::Faiths(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::Faiths::registerKeys()
-{
-	registerRegex(R"(\d+)", [this](const std::string& faithID, std::istream& theStream) {
-		auto newFaith = std::make_shared<Faith>(theStream, std::stoll(faithID));
-		faiths.insert(std::pair(newFaith->getID(), newFaith));
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
-
-void CK3::Faiths::linkReligions(const Religions& religions, const Titles& titles)
-{
-	auto counter = 0;
-	const auto& religionData = religions.getReligions();
-	std::map<std::string, std::string> religiousHeadList; // ID, Title
-	for (const auto& title: titles.getTitles())
-		if (title.second)
-			religiousHeadList.emplace(std::to_string(title.second->getID()), title.first);
-	for (const auto& faith: faiths)
-	{
-		const auto& religionDataItr = religionData.find(faith.second->getReligion().first);
-		if (religionDataItr != religionData.end())
-		{
-			faith.second->loadReligion(*religionDataItr);
-			if (religiousHeadList.contains(faith.second->getReligiousHead()))
-				faith.second->setReligiousHead(religiousHeadList.at(faith.second->getReligiousHead()));
-			++counter;
-		}
-		else
-		{
-			throw std::runtime_error(
-				 "Faith " + faith.second->getName() + " has religion " + std::to_string(faith.second->getReligion().first) + " which has no definition!");
-		}
-	}
-	Log(LogLevel::Info) << "<> " << counter << " faiths updated.";
-}
\ No newline at end of file
diff --git a/CK3ToEU4/Source/CK3World/Religions/Faiths.h b/CK3ToEU4/Source/CK3World/Religions/Faiths.h
deleted file mode 100644
index 6d5daee1..00000000
--- a/CK3ToEU4/Source/CK3World/Religions/Faiths.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef CK3_FAITHS_H
-#define CK3_FAITHS_H
-#include "../Titles/LandedTitles.h"
-#include "../Titles/Title.h"
-#include "../Titles/Titles.h"
-#include "Parser.h"
-
-namespace CK3
-{
-class Faith;
-class Religions;
-class Faiths: commonItems::parser
-{
-  public:
-	Faiths() = default;
-	explicit Faiths(std::istream& theStream);
-
-	[[nodiscard]] const auto& getFaiths() const { return faiths; }
-
-	void linkReligions(const Religions& religions, const Titles& titles);
-
-  private:
-	void registerKeys();
-
-	std::map<long long, std::shared_ptr<Faith>> faiths;
-};
-} // namespace CK3
-
-#endif // CK3_FAITHS_H
diff --git a/CK3ToEU4/Source/CK3World/Religions/Religion.cpp b/CK3ToEU4/Source/CK3World/Religions/Religion.cpp
deleted file mode 100644
index 114fe290..00000000
--- a/CK3ToEU4/Source/CK3World/Religions/Religion.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "Religion.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::Religion::Religion(std::istream& theStream, long long theID): ID(theID)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::Religion::registerKeys()
-{
-	registerKeyword("tag", [this](const std::string& unused, std::istream& theStream) {
-		tag = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("family", [this](const std::string& unused, std::istream& theStream) {
-		family = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("faiths", [this](const std::string& unused, std::istream& theStream) {
-		for (auto faith: commonItems::llongList(theStream).getLlongs())
-			faiths.insert(std::pair(faith, nullptr));
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
diff --git a/CK3ToEU4/Source/CK3World/Religions/Religion.h b/CK3ToEU4/Source/CK3World/Religions/Religion.h
deleted file mode 100644
index 8cf74710..00000000
--- a/CK3ToEU4/Source/CK3World/Religions/Religion.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef CK3_RELIGION_H
-#define CK3_RELIGION_H
-#include "Parser.h"
-
-namespace CK3
-{
-class Faith;
-class Religion: commonItems::parser
-{
-  public:
-	Religion() = default;
-	Religion(std::istream& theStream, long long theID);
-
-	[[nodiscard]] auto getID() const { return ID; }
-	[[nodiscard]] const auto& getName() const { return tag; }
-	[[nodiscard]] const auto& getFamily() const { return family; }
-	[[nodiscard]] const auto& getFaiths() const { return faiths; }
-
-	void loadFaiths(const std::map<long long, std::shared_ptr<Faith>>& theFaiths) { faiths = theFaiths; }
-
-  private:
-	void registerKeys();
-
-	long long ID = 0;
-	std::string tag;
-	std::string family;
-	std::map<long long, std::shared_ptr<Faith>> faiths;
-};
-} // namespace CK3
-
-#endif // CK3_RELIGION_H
diff --git a/CK3ToEU4/Source/CK3World/Religions/Religions.cpp b/CK3ToEU4/Source/CK3World/Religions/Religions.cpp
deleted file mode 100644
index 371797c2..00000000
--- a/CK3ToEU4/Source/CK3World/Religions/Religions.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "Religions.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-#include "Religion.h"
-
-CK3::Religions::Religions(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::Religions::registerKeys()
-{
-	registerRegex(R"(\d+)", [this](const std::string& faithID, std::istream& theStream) {
-		auto newReligion = std::make_shared<Religion>(theStream, std::stoll(faithID));
-		religions.insert(std::pair(newReligion->getID(), newReligion));
-	});
-	registerKeyword("religions", [this](const std::string& unused, std::istream& theStream) {
-		religions = Religions(theStream).getReligions();
-	});
-	registerKeyword("faiths", [this](const std::string& unused, std::istream& theStream) {
-		faiths = Faiths(theStream);
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
-
-void CK3::Religions::linkFaiths(const Faiths& theFaiths)
-{
-	auto counter = 0;
-	const auto& faithData = theFaiths.getFaiths();
-	for (const auto& religion: religions)
-	{
-		const auto& religionFaiths = religion.second->getFaiths();
-		std::map<long long, std::shared_ptr<Faith>> replacementMap;
-
-		for (const auto& faith: religionFaiths)
-		{
-			const auto& faithDataItr = faithData.find(faith.first);
-			if (faithDataItr != faithData.end())
-			{
-				replacementMap.insert(*faithDataItr);
-			}
-			else
-			{
-				throw std::runtime_error("Religion " + religion.second->getName() + " has faith " + std::to_string(faith.first) + " which has no definition!");
-			}
-		}
-		religion.second->loadFaiths(replacementMap);
-		++counter;
-	}
-	Log(LogLevel::Info) << "<> " << counter << " religions updated.";
-}
diff --git a/CK3ToEU4/Source/CK3World/Religions/Religions.h b/CK3ToEU4/Source/CK3World/Religions/Religions.h
deleted file mode 100644
index 2c3158d6..00000000
--- a/CK3ToEU4/Source/CK3World/Religions/Religions.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef CK3_RELIGIONS_H
-#define CK3_RELIGIONS_H
-#include "Faiths.h"
-#include "Parser.h"
-
-namespace CK3
-{
-class Religion;
-class Religions: commonItems::parser
-{
-  public:
-	Religions() = default;
-	explicit Religions(std::istream& theStream);
-
-	[[nodiscard]] const auto& getReligions() const { return religions; }
-	[[nodiscard]] auto getFaiths() { return std::move(faiths); } // Use this only once in World.cpp
-
-	void linkFaiths(const Faiths& theFaiths);
-
-  private:
-	void registerKeys();
-
-	std::map<long long, std::shared_ptr<Religion>> religions;
-	Faiths faiths;
-};
-} // namespace CK3
-
-#endif // CK3_RELIGIONS_H
diff --git a/CK3ToEU4/Source/CK3World/Titles/DynamicTemplate.cpp b/CK3ToEU4/Source/CK3World/Titles/DynamicTemplate.cpp
deleted file mode 100644
index 62edba0e..00000000
--- a/CK3ToEU4/Source/CK3World/Titles/DynamicTemplate.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "DynamicTemplate.h"
-#include "CommonRegexes.h"
-#include "ParserHelpers.h"
-
-CK3::DynamicTemplate::DynamicTemplate(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::DynamicTemplate::registerKeys()
-{
-	registerKeyword("key", [this](const std::string& unused, std::istream& theStream) {
-		dynamicKey = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("tier", [this](const std::string& unused, std::istream& theStream) {
-		dynamicRank = commonItems::singleString(theStream).getString();
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
diff --git a/CK3ToEU4/Source/CK3World/Titles/DynamicTemplate.h b/CK3ToEU4/Source/CK3World/Titles/DynamicTemplate.h
deleted file mode 100644
index 02c2c2cb..00000000
--- a/CK3ToEU4/Source/CK3World/Titles/DynamicTemplate.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef CK3_DYNAMICTEMPLATE_H
-#define CK3_DYNAMICTEMPLATE_H
-#include "Parser.h"
-
-namespace CK3
-{
-class DynamicTemplate: commonItems::parser
-{
-  public:
-	explicit DynamicTemplate(std::istream& theStream);
-
-	[[nodiscard]] const auto& getDynamicTitleKey() const { return dynamicKey; }
-	[[nodiscard]] const auto& getDynamicTitleRank() const { return dynamicRank; }
-
-  private:
-	void registerKeys();
-
-	std::string dynamicKey;
-	std::string dynamicRank;
-};
-} // namespace CK3
-
-#endif // CK3_DYNAMICTEMPLATE_H
diff --git a/CK3ToEU4/Source/CK3World/Titles/LandedTitles.cpp b/CK3ToEU4/Source/CK3World/Titles/LandedTitles.cpp
deleted file mode 100644
index a2a90bac..00000000
--- a/CK3ToEU4/Source/CK3World/Titles/LandedTitles.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "LandedTitles.h"
-#include "../Geography/CountyDetails.h"
-#include "../Geography/ProvinceHoldings.h"
-#include "CommonRegexes.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-#include "Title.h"
-#include "Titles.h"
-
-// This is a recursive class that scrapes 00_landed_titles.txt (and related files) looking for title colors, landlessness,
-// and most importantly relation between baronies and barony provinces so we can link titles to actual clay.
-// Since titles are nested according to hierarchy we do this recursively.
-
-// Keep in mind that we use this class as middleware between titles and hard geographical data. Baronies and Counties have said data,
-// but newfangled custom empires and such found in Titles will not be present here. They should have colors defined in their Title block
-// anyway, and whatever relates to Title over there takes precedence over data in this class.
-
-void CK3::LandedTitles::loadTitles(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-}
-
-void CK3::LandedTitles::loadTitles(const std::string& fileName)
-{
-	registerKeys();
-	parseFile(fileName);
-	clearRegisteredKeywords();
-}
-
-void CK3::LandedTitles::registerKeys()
-{
-	registerRegex(R"((e|k|d|c|b)_[A-Za-z0-9_\-\']+)", [this](const std::string& titleName, std::istream& theStream) {
-		// Pull the titles beneath this one and add them to the lot, overwriting existing ones.
-		auto newTitle = std::make_shared<LandedTitles>();
-		newTitle->loadTitles(theStream);
-		for (const auto& locatedTitle: newTitle->getFoundTitles())
-			foundTitles[locatedTitle.first] = locatedTitle.second;
-
-		// And then add this one as well, overwriting existing.
-		foundTitles[titleName] = newTitle;
-	});
-	registerKeyword("definite_form", [this](const std::string& unused, std::istream& theStream) {
-		definiteForm = commonItems::singleString(theStream).getString() == "yes";
-	});
-	registerKeyword("landless", [this](const std::string& unused, std::istream& theStream) {
-		landless = commonItems::singleString(theStream).getString() == "yes";
-	});
-	registerKeyword("color", [this](const std::string& unused, std::istream& theStream) {
-		color = laFabricaDeColor.getColor(theStream);
-	});
-	registerKeyword("capital", [this](const std::string& unused, std::istream& theStream) {
-		capital = std::make_pair(commonItems::singleString(theStream).getString(), nullptr);
-	});
-	registerKeyword("province", [this](const std::string& unused, std::istream& theStream) {
-		province = std::make_pair(commonItems::singleInt(theStream).getInt(), nullptr);
-	});
-	registerKeyword("can_be_named_after_dynasty", [this](const std::string& unused, std::istream& theStream) {
-		mayBeNamedAfterDynasty = commonItems::singleString(theStream).getString() == "yes";
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
-
-void CK3::LandedTitles::linkProvinceHoldings(const ProvinceHoldings& provinceHoldings)
-{
-	// We're linking provinces into BARONY titles only, as other titles have no holding data.
-	auto counter = 0;
-	const auto& provinceData = provinceHoldings.getProvinceHoldings();
-	for (const auto& landedTitle: foundTitles)
-	{
-		if (landedTitle.first.find("b_") != 0)
-			continue;
-		if (!landedTitle.second->getProvince())
-			throw std::runtime_error("Landed title " + landedTitle.first + " has not province holding defined!");
-
-		const auto& provinceDataItr = provinceData.find(landedTitle.second->getProvince()->first);
-		if (provinceDataItr != provinceData.end())
-		{
-			landedTitle.second->loadProvinceHolding(*provinceDataItr);
-			++counter;
-		}
-		else
-		{
-			throw std::runtime_error("Landed title " + landedTitle.first + " has province holding " + std::to_string(landedTitle.second->getProvince()->first) +
-											 " which has no definition!");
-		}
-	}
-	Log(LogLevel::Info) << "<> " << counter << " landed titles updated.";
-}
-
-void CK3::LandedTitles::linkCountyDetails(const CountyDetails& countyDetails)
-{
-	// We're linking county details into COUNTY titles only, as other titles have no such details.
-	auto counter = 0;
-	const auto& countyData = countyDetails.getCountyDetails();
-	for (const auto& landedTitle: foundTitles)
-	{
-		if (landedTitle.first.find("c_") != 0)
-			continue;
-		const auto& countyDataItr = countyData.find(landedTitle.first);
-		if (countyDataItr != countyData.end())
-		{
-			landedTitle.second->loadCountyDetails(*countyDataItr);
-			++counter;
-		}
-		else
-		{
-			// Nothing. People with missing titles from mods and whatnot can have holes on their map.
-			Log(LogLevel::Warning) << "Landed title " << landedTitle.first << " has no definition in counties={} section of the save game!";
-		}
-	}
-	Log(LogLevel::Info) << "<> " << counter << " landed titles updated.";
-}
-
-void CK3::LandedTitles::linkTitles(const Titles& titles)
-{
-	auto counter = 0;
-	const auto& titleData = titles.getTitles();
-	for (const auto& landedTitle: foundTitles)
-	{
-		const auto& theCapital = landedTitle.second->getCapital();
-		if (!theCapital)
-			continue;
-		if (const auto& titleDataItr = titleData.find(theCapital->first); titleDataItr != titleData.end())
-		{
-			landedTitle.second->loadCapital(*titleDataItr);
-			++counter;
-		}
-		else
-		{
-			Log(LogLevel::Error) << "Landed title " + landedTitle.first + " has a capital " + theCapital->first + " which has no definition!";
-		}
-	}
-	Log(LogLevel::Info) << "<> " << counter << " landed title capitals updated.";
-}
diff --git a/CK3ToEU4/Source/CK3World/Titles/LandedTitles.h b/CK3ToEU4/Source/CK3World/Titles/LandedTitles.h
deleted file mode 100644
index 206baaf8..00000000
--- a/CK3ToEU4/Source/CK3World/Titles/LandedTitles.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef CK3_LANDEDTITLES_H
-#define CK3_LANDEDTITLES_H
-#include "Color.h"
-#include "Parser.h"
-extern commonItems::Color::Factory laFabricaDeColor;
-
-namespace CK3
-{
-class Title;
-class Titles;
-class ProvinceHolding;
-class ProvinceHoldings;
-class CountyDetails;
-class CountyDetail;
-class LandedTitles: commonItems::parser
-{
-  public:
-	void loadTitles(std::istream& theStream);
-	void loadTitles(const std::string& fileName);
-
-	[[nodiscard]] auto isDefiniteForm() const { return definiteForm; }
-	[[nodiscard]] auto isLandless() const { return landless; }
-	[[nodiscard]] auto canBeNamedAfterDynasty() const { return mayBeNamedAfterDynasty; }
-	[[nodiscard]] const auto& getColor() const { return color; }
-	[[nodiscard]] const auto& getCapital() const { return capital; }
-	[[nodiscard]] const auto& getProvince() const { return province; }
-	[[nodiscard]] const auto& getCounty() const { return county; }
-	[[nodiscard]] const auto& getFoundTitles() const { return foundTitles; }
-
-	void loadProvinceHolding(const std::pair<int, std::shared_ptr<ProvinceHolding>>& provinceHolding) { province = provinceHolding; }
-	void loadCountyDetails(const std::pair<std::string, std::shared_ptr<CountyDetail>>& countyDetail) { county = countyDetail; }
-	void loadCapital(const std::pair<std::string, std::shared_ptr<Title>>& theCapital) { capital = theCapital; }
-
-	void linkProvinceHoldings(const ProvinceHoldings& provinceHoldings);
-	void linkCountyDetails(const CountyDetails& countyDetails);
-	void linkTitles(const Titles& titles);
-
-  private:
-	void registerKeys();
-
-	bool definiteForm = false;
-	bool landless = false;
-	bool mayBeNamedAfterDynasty = true;
-	std::optional<commonItems::Color> color;
-
-	// This is of questionable use as savegame already defines defacto capitals. Not always present, and if present then a COUNTY.
-	std::optional<std::pair<std::string, std::shared_ptr<Title>>> capital;
-
-	// only b_baronies have these - holdings are related to individual provinces on map.
-	std::optional<std::pair<int, std::shared_ptr<ProvinceHolding>>> province;
-
-	// only c_counties have these - these define common data for group of baronies under county.
-	std::optional<std::pair<std::string, std::shared_ptr<CountyDetail>>> county;
-
-	// We're using title name, not savegame ID for key value.
-	std::map<std::string, std::shared_ptr<LandedTitles>> foundTitles;
-};
-} // namespace CK3
-
-#endif // CK3_TITLES_H
diff --git a/CK3ToEU4/Source/CK3World/Titles/Title.cpp b/CK3ToEU4/Source/CK3World/Titles/Title.cpp
deleted file mode 100644
index fd600aa7..00000000
--- a/CK3ToEU4/Source/CK3World/Titles/Title.cpp
+++ /dev/null
@@ -1,518 +0,0 @@
-#include "Title.h"
-#include "../../Mappers/DevWeightsMapper/DevWeightsMapper.h"
-#include "../Characters/Character.h"
-#include "../Geography/CountyDetail.h"
-#include "../Geography/ProvinceHolding.h"
-#include "CommonRegexes.h"
-#include "LandedTitles.h"
-#include "Log.h"
-#include "ParserHelpers.h"
-
-CK3::Title::Title(std::istream& theStream, long long theID): ID(theID)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-
-	// Obligatory sanity check.
-	if (!holder)
-	{
-		// This title does NOT in fact exist.
-		dfLiege.reset();
-	}
-}
-
-void CK3::Title::registerKeys()
-{
-	registerKeyword("key", [this](const std::string& unused, std::istream& theStream) {
-		name = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("name", [this](const std::string& unused, std::istream& theStream) {
-		displayName = commonItems::singleString(theStream).getString();
-		if (displayName.find("\x15") != std::string::npos)
-		{
-			cleanUpDisplayName();
-		}
-	});
-	registerKeyword("adj", [this](const std::string& unused, std::istream& theStream) {
-		adjective = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("date", [this](const std::string& unused, std::istream& theStream) {
-		creationDate = date(commonItems::singleString(theStream).getString());
-	});
-	registerKeyword("claim", [this](const std::string& unused, std::istream& theStream) {
-		for (auto claimantID: commonItems::llongList(theStream).getLlongs())
-			claimants.insert(std::make_pair(claimantID, nullptr));
-	});
-	registerKeyword("history_government", [this](const std::string& unused, std::istream& theStream) {
-		historyGovernment = commonItems::singleString(theStream).getString();
-	});
-	registerKeyword("theocratic_lease", [this](const std::string& unused, std::istream& theStream) {
-		theocraticLease = commonItems::singleString(theStream).getString() == "yes";
-	});
-	registerKeyword("capital_barony", [this](const std::string& unused, std::istream& theStream) {
-		cCapitalBarony = commonItems::singleString(theStream).getString() == "yes";
-	});
-	registerKeyword("duchy_capital_barony", [this](const std::string& unused, std::istream& theStream) {
-		dCapitalBarony = commonItems::singleString(theStream).getString() == "yes";
-	});
-	registerKeyword("capital", [this](const std::string& unused, std::istream& theStream) {
-		capital = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
-	});
-	registerKeyword("de_facto_liege", [this](const std::string& unused, std::istream& theStream) {
-		dfLiege = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
-	});
-	registerKeyword("de_jure_liege", [this](const std::string& unused, std::istream& theStream) {
-		djLiege = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
-	});
-	registerKeyword("de_jure_vassals", [this](const std::string& unused, std::istream& theStream) {
-		for (auto vassalID: commonItems::llongList(theStream).getLlongs())
-			djVassals.insert(std::make_pair(vassalID, nullptr));
-	});
-	registerKeyword("heir", [this](const std::string& unused, std::istream& theStream) {
-		for (auto heirID: commonItems::llongList(theStream).getLlongs())
-			heirs.emplace_back(std::make_pair(heirID, nullptr));
-	});
-	registerKeyword("laws", [this](const std::string& unused, std::istream& theStream) {
-		const auto& theLaws = commonItems::stringList(theStream).getStrings();
-		laws = std::set(theLaws.begin(), theLaws.end());
-	});
-	registerKeyword("holder", [this](const std::string& unused, std::istream& theStream) {
-		holder = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
-	});
-	registerKeyword("renamed", [this](std::istream& theStream) {
-		renamed = commonItems::getString(theStream) == "yes";
-	});
-	registerKeyword("coat_of_arms_id", [this](const std::string& unused, std::istream& theStream) {
-		coa = std::pair(commonItems::singleLlong(theStream).getLlong(), nullptr);
-	});
-	registerKeyword("succession_election", [this](const std::string& unused, std::istream& theStream) {
-		const auto newTitle = Title(theStream, 0);
-		electors = newTitle.getElectors();
-	});
-	registerKeyword("electors", [this](const std::string& unused, std::istream& theStream) {
-		for (auto electorID: commonItems::intList(theStream).getInts())
-			electors.insert(std::pair(electorID, nullptr));
-	});
-	registerKeyword("landless", [this](const std::string& unused, std::istream& theStream) {
-		landless = commonItems::singleString(theStream).getString() == "yes";
-	});
-	registerKeyword("color", [this](const std::string& unused, std::istream& theStream) {
-		color = laFabricaDeColor.getColor(theStream);
-	});
-	registerKeyword("history", [this](const std::string& unused, std::istream& theStream) {
-		previousHolders = Title(theStream, 0).getPreviousHolders();
-	});
-	registerRegex(R"(\d+.\d+.\d+)", [this](const std::string& unused, std::istream& theStream) {
-		const auto questionableItem = commonItems::stringOfItem(theStream).getString();
-		auto tempStream = std::stringstream(questionableItem);
-		if (questionableItem.find('{') == std::string::npos)
-		{
-			try
-			{
-				previousHolders.emplace_back(std::pair(commonItems::singleLlong(tempStream).getLlong(), nullptr));
-			}
-			catch (std::exception&)
-			{
-				Log(LogLevel::Warning) << "Invalid previous holder ID: " << questionableItem;
-			}
-		}
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
-
-void CK3::Title::cleanUpDisplayName()
-{
-	auto start = displayName.find('\x15');
-	auto silence = false;
-	auto silenceOverRide = false;
-	auto braceDepth = 0;
-	std::string newName;
-	while (start != std::string::npos)
-	{
-		if ((!silence || silenceOverRide) && start != 0)
-		{
-			newName += displayName.substr(0, start);
-			displayName = displayName.substr(start, displayName.length());
-			silence = true;
-			silenceOverRide = false;
-			start = displayName.find('\x15');
-		}
-		else if (displayName.at(start + 1) == 'L')
-		{
-			if (displayName.length() >= start + 3)
-				displayName = displayName.substr(start + 3, displayName.length());
-			else
-				break;
-			silence = true;
-			silenceOverRide = true;
-			braceDepth++;
-			start = displayName.find('\x15');
-		}
-		else if (displayName.at(start + 1) == '!')
-		{
-			if (displayName.length() >= start + 2)
-				displayName = displayName.substr(start + 2, displayName.length());
-			else
-				break;
-			braceDepth--;
-			if (braceDepth <= 0)
-			{
-				silence = false;
-				braceDepth = 0;
-			}
-			silenceOverRide = false;
-			start = displayName.find('\x15');
-		}
-		else
-		{
-			silence = true;
-			silenceOverRide = false;
-			if (displayName.length() >= start + 1)
-				displayName = displayName.substr(start + 1, displayName.length());
-			else
-				break;
-			braceDepth++;
-			start = displayName.find('\x15');
-		}
-	}
-	displayName = newName;
-}
-
-int CK3::Title::flagDeJureHREProvinces()
-{
-	auto counter = 0;
-	// For CK3 flagging dejure alone is not enough as we'll be losing a ton of land when duchies break away in full independence.
-	// Flag our dejure AND defacto counties, or our dejure/defacto vassals' counties, wherever those may be.
-	// Actual flagging will happen on county level as higher titles have no dejure provinces linked to them at this stage.
-	// We're leaving baronies out of this, counties are sufficient.
-	for (const auto& deJureVassal: djVassals)
-	{
-		counter += deJureVassal.second->flagDeJureHREProvinces();
-	}
-	for (const auto& deFactoVassal: dfVassals)
-	{
-		counter += deFactoVassal.second->flagDeJureHREProvinces();
-	}
-	if (!clay) // We really need the county clay to confirm we're a landful proper county.
-		return counter;
-	if (!clay->getCounty() || getLevel() != LEVEL::COUNTY)
-		return counter;
-
-	clay->getCounty()->second->setDeJureHRE();
-	++counter;
-
-	return counter;
-}
-
-void CK3::Title::brickTitle()
-{
-	grantIndependence();
-
-	// Drop from own holder's domain.
-	if (holder && holder->second)
-		holder->second->dropTitleFromDomain(ID);
-	else
-		Log(LogLevel::Warning) << "Bricking " << name << " without holder!";
-
-	// Drop holder
-	holder.reset();
-
-	// release all vassals
-	std::vector<std::shared_ptr<Title>> independentList;
-	for (const auto& vassal: dfVassals)
-		if (vassal.second)
-			independentList.emplace_back(vassal.second);
-		else
-			Log(LogLevel::Warning) << "Granting independence to " << vassal.first << " that's not linked!";
-
-	for (const auto& independentVassal: independentList)
-		independentVassal->grantIndependence();
-
-	dfVassals.clear(); // just in case?
-}
-
-void CK3::Title::dropTitleFromDFVassals(long long titleID)
-{
-	const auto& dfvItr = dfVassals.find(titleID);
-	if (dfvItr != dfVassals.end())
-		dfVassals.erase(dfvItr);
-	else
-		Log(LogLevel::Warning) << "dropping vassal " << titleID << " that doesn't exist!";
-}
-
-void CK3::Title::grantIndependence()
-{
-	// Drop this title from liege holder's vassals
-	if (dfLiege && dfLiege->second)
-		dfLiege->second->dropTitleFromDFVassals(ID);
-
-	// Drop liege
-	dfLiege.reset();
-}
-
-std::map<std::string, std::shared_ptr<CK3::Title>> CK3::Title::coalesceDFCounties() const
-{
-	// We're gathering vassal's counties + self (if c_), and passing them on, adding nothing to ourselves.
-	std::map<std::string, std::shared_ptr<Title>> toReturn;
-	for (const auto& vassal: dfVassals)
-	{
-		const auto& vassalCounties = vassal.second->coalesceDFCounties();
-		toReturn.insert(vassalCounties.begin(), vassalCounties.end());
-	}
-	toReturn.insert(ownedDFCounties.begin(), ownedDFCounties.end());
-	return toReturn;
-}
-
-std::map<std::string, std::shared_ptr<CK3::Title>> CK3::Title::coalesceDJCounties() const
-{
-	// We're gathering vassal dejure provinces + our own, and passing them on, adding nothing to ourselves.
-	std::map<std::string, std::shared_ptr<Title>> toReturn;
-	for (const auto& deJureVassal: djVassals)
-	{
-		const auto& vassalDJCounties = deJureVassal.second->coalesceDJCounties();
-		toReturn.insert(vassalDJCounties.begin(), vassalDJCounties.end());
-	}
-	toReturn.insert(ownedDJCounties.begin(), ownedDJCounties.end());
-	return toReturn;
-}
-
-void CK3::Title::pickDisplayName(const std::map<std::string, std::shared_ptr<Title>>& possibleTitles)
-{
-	// Guard clause all used pointers
-	if (!isRenamed())
-		return;
-
-	// Duchy capital ptrs are all null_ptr, outsource fixing and validation
-	const auto myDuchyCapital = findDuchyCapital();
-
-	if (!myDuchyCapital || myDuchyCapital->getID() == getID() || !myDuchyCapital->getDFLiege() || !getDFLiege())
-		return;
-
-	// If the title's name is transfering to EU4, make sure it makes sense. Thrace should use Constantinople's name...
-	// ... if they belong to the same owner, Constantinople also has a custom name and they are in the same mapping
-	if (myDuchyCapital->isRenamed() && possibleTitles.contains(myDuchyCapital->getName()) && myDuchyCapital->getDFLiege()->first == getDFLiege()->first)
-	{
-		displayName = myDuchyCapital->getDisplayName();
-	}
-}
-
-std::shared_ptr<CK3::Title> CK3::Title::findDuchyCapital()
-{
-	if (name[0] != 'c' || !getDJLiege() || !getDJLiege()->second)
-		return nullptr;
-
-	const auto myDuchy = getDJLiege()->second;
-	const auto& capID = myDuchy->getCapital().first;
-
-	if (myDuchy->getDJVassals().empty() || !myDuchy->getDJVassals().contains(capID) || !myDuchy->getDJVassals().at(capID))
-		return nullptr;
-
-	return myDuchy->getDJVassals().at(capID);
-}
-
-void CK3::Title::congregateDFCounties()
-{
-	// We're gathering vassal counties and adding to our own.
-	for (const auto& vassal: dfVassals)
-	{
-		const auto& vassalDFCounties = vassal.second->coalesceDFCounties();
-		ownedDFCounties.insert(vassalDFCounties.begin(), vassalDFCounties.end());
-	}
-}
-
-void CK3::Title::congregateDJCounties()
-{
-	// We're gathering de jure vassal de jure counties and adding to our own.
-	for (const auto& deJureVassal: djVassals)
-	{
-		const auto& deJureVassalDJCounties = deJureVassal.second->coalesceDJCounties();
-		ownedDJCounties.insert(deJureVassalDJCounties.begin(), deJureVassalDJCounties.end());
-	}
-}
-
-CK3::LEVEL CK3::Title::getLevel() const
-{
-	// It's easy, until it's not.
-	if (name.find("b_") == 0)
-		return LEVEL::BARONY;
-	if (name.find("c_") == 0)
-		return LEVEL::COUNTY;
-	if (name.find("d_") == 0)
-		return LEVEL::DUCHY;
-	if (name.find("k_") == 0)
-		return LEVEL::KINGDOM;
-	if (name.find("e_") == 0)
-		return LEVEL::EMPIRE;
-
-	// for dynamic tiles we may have a level set already.
-	if (dynamicLevel)
-		return *dynamicLevel;
-
-	// If not...
-	// This is the questionable part. It should work for customs as they are treated identically as any other - with dejure parents and all.
-	// exceptions are dynamic mercs, landless religious orders and similar - but those don't hold land, at least initially.
-
-	// see if they hold any vassals and if so, assign a level one step higher.
-	auto level = -1;
-	const std::set<char> allowedPrefixes = {'b', 'c', 'd', 'k'};
-	for (const auto& vassal: djVassals) // run through all as they can vary in levels.
-	{
-		if (!allowedPrefixes.count(vassal.second->getName().at(0)))
-			continue; // Those dynamic vassals can't help us. Or heaven's forbid, it's an empire.
-		if (LevelToInt[vassal.second->getLevel()] > level)
-			level = LevelToInt[vassal.second->getLevel()] + 1;
-	}
-	if (level > -1)
-		return IntToLevel[std::max(level, 4)];
-
-	// Without vassals we must poke at our hierarchy, if any.
-	if (djLiege)
-		return IntToLevel[LevelToInt[djLiege->second->getLevel()] - 1];
-	else
-		return LEVEL::EMPIRE; // If this is wrong for landless mercs, it won't affect anything as they are landless anyway.
-}
-
-std::optional<commonItems::Color> CK3::Title::getColor() const
-{
-	if (color)
-		return color;
-	if (clay && clay->getColor())
-		return clay->getColor();
-	return std::nullopt;
-}
-
-bool CK3::Title::isLandless() const
-{
-	if (landless)
-		return true;
-	if (clay && clay->isLandless())
-		return true;
-	return false;
-}
-
-double CK3::Title::getBuildingWeight(const mappers::DevWeightsMapper& devWeightsMapper) const
-{
-	if (getLevel() != LEVEL::COUNTY) // This applies to nothing but counties.
-		return 0;
-
-	// buildingWeight is a mixture of all holdings, their potential buildings, and general county development.
-	if (!clay)
-		throw std::runtime_error("County " + name + " has no clay?");
-	if (!clay->getCounty() || !clay->getCounty()->second)
-		throw std::runtime_error("County " + name + " has no county in its clay?");
-	const auto development = clay->getCounty()->second->getDevelopment();
-	auto buildingCount = 0;
-	auto holdingCount = 0;
-
-	for (const auto& barony: djVassals)
-	{
-		if (!barony.second)
-		{
-			Log(LogLevel::Error) << "Running unlinked vassals, are we? " << std::to_string(barony.first) << " has no link.";
-			continue;
-		}
-		if (!barony.second->getClay())
-		{
-			Log(LogLevel::Error) << "Supposed barony " << barony.second->getName() << " of " << name << " has no clay?";
-			continue;
-		}
-		if (!barony.second->getClay()->getProvince() || !barony.second->getClay()->getProvince()->second)
-		{
-			Log(LogLevel::Error) << "Barony " << barony.second->getName() << " of " << name << " has no clay province?";
-			continue;
-		}
-		const auto& baronyProvince = barony.second->getClay()->getProvince();
-		buildingCount += baronyProvince->second->countBuildings();
-		if (!baronyProvince->second->getHoldingType().empty())
-			++holdingCount;
-	}
-
-	const auto totalDev = devWeightsMapper.getDevFromHolding() * holdingCount + devWeightsMapper.getDevFromBuilding() * buildingCount +
-								 std::max(0.0, development - devWeightsMapper.getDevTreshold()) * devWeightsMapper.getDevFromDev();
-	return totalDev;
-}
-
-void CK3::Title::relinkDeFactoVassals()
-{
-	// We're reconstructing defacto hierarchy; we're redirecting our DFvassals from our DFtitle into our DJtitle - if holder of this title holds hold both.
-	// This is important - otherwise secondary titles wouldn't have their own vassals under them but under primary title, breaking PU splitoffs,
-	// and resulting with those secondary duchies/kingdoms being discarded as landless.
-
-	if (name.starts_with("c_") || name.starts_with("b_"))
-		return; // don't bother with counties and below.
-
-	std::set<long long> dropList;
-
-	for (const auto& [dfVassalID, dfVassal]: dfVassals)
-	{
-		if (!dfVassal)
-			continue;
-
-		if (dfVassal->areDFLiegeAndDJLiegeSet() && !dfVassal->areDFLiegeAndDJLiegeSame()) // We have different df and dj lieges there.
-		{
-			// Do we own both titles?
-			if (doesHolderHaveCharacterDomain())
-			{
-				const auto holderTitles = holder->second->getCharacterDomain()->getDomain();
-
-				// Make a small cache of the holder's owned title names.
-				const auto titleNameCache = getTitleNamesFromHolderDomain();
-
-				if (titleNameCache.contains(dfVassal->getDFLiege()->second->getName()) && titleNameCache.contains(dfVassal->getDJLiege()->second->getName()))
-				{
-					// We do own both. Tell the vassal to relink its defacto owner to dejure title.
-					dfVassal->loadDFLiege(*dfVassal->getDJLiege());
-					// Tell dejure title it's now owner of a brand new vassal.
-					dfVassal->getDJLiege()->second->addDFVassals(std::map{std::pair(dfVassalID, dfVassal)});
-					// And finally...
-					dropList.insert(dfVassalID);
-				}
-			}
-			else
-			{
-				if (!isHolderSet())
-					Log(LogLevel::Warning) << name << " has no holder but has vassals?";
-				else if (!isHolderLinked())
-					Log(LogLevel::Warning) << name << "'s holder is not linked up!";
-				else
-					Log(LogLevel::Warning) << name << "' holder has no domain but has vassals?";
-			}
-		}
-	}
-
-	for (auto dropVassalID: dropList)
-		dropTitleFromDFVassals(dropVassalID);
-}
-
-bool CK3::Title::areDFLiegeAndDJLiegeSet() const
-{
-	return dfLiege && djLiege;
-}
-
-bool CK3::Title::areDFLiegeAndDJLiegeSame() const
-{
-	if (!areDFLiegeAndDJLiegeSet())
-		return false; // Can't check if they're not set.
-	return dfLiege->first == djLiege->first;
-}
-
-bool CK3::Title::doesHolderHaveCharacterDomain() const
-{
-	return isHolderSet() && isHolderLinked() && holder->second->getCharacterDomain();
-}
-
-std::set<std::string> CK3::Title::getTitleNamesFromHolderDomain() const
-{
-	std::set<std::string> toReturn;
-	if (!doesHolderHaveCharacterDomain())
-		return toReturn;
-
-	const auto holderTitles = holder->second->getCharacterDomain()->getDomain();
-
-	for (const auto& [domainTitleID, domainTitle]: holderTitles)
-		if (domainTitle)
-			toReturn.insert(domainTitle->getName());
-
-	return toReturn;
-}
diff --git a/CK3ToEU4/Source/CK3World/Titles/Title.h b/CK3ToEU4/Source/CK3World/Titles/Title.h
deleted file mode 100644
index 51e0ed8c..00000000
--- a/CK3ToEU4/Source/CK3World/Titles/Title.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef CK3_TITLE_H
-#define CK3_TITLE_H
-#include "Color.h"
-#include "Date.h"
-#include "Parser.h"
-#include <set>
-
-namespace mappers
-{
-class DevWeightsMapper;
-}
-namespace EU4
-{
-class Country;
-}
-
-namespace CK3
-{
-class Character;
-class CoatOfArms;
-class LandedTitles;
-
-enum class LEVEL
-{
-	BARONY,
-	COUNTY,
-	DUCHY,
-	KINGDOM,
-	EMPIRE
-};
-
-static std::map<int, LEVEL> IntToLevel{{0, LEVEL::BARONY}, {1, LEVEL::COUNTY}, {2, LEVEL::DUCHY}, {3, LEVEL::KINGDOM}, {4, LEVEL::EMPIRE}};
-static std::map<LEVEL, int> LevelToInt{{LEVEL::BARONY, 0}, {LEVEL::COUNTY, 1}, {LEVEL::DUCHY, 2}, {LEVEL::KINGDOM, 3}, {LEVEL::EMPIRE, 4}};
-
-class Title: commonItems::parser
-{
-  public:
-	Title(std::istream& theStream, long long theID);
-	[[nodiscard]] auto getID() const { return ID; }
-	[[nodiscard]] auto isTheocraticLease() const { return theocraticLease; }
-	[[nodiscard]] auto isCountyCapitalBarony() const { return cCapitalBarony; }
-	[[nodiscard]] auto isDuchyCapitalBarony() const { return dCapitalBarony; }
-	[[nodiscard]] auto isHREEmperor() const { return HREEmperor; }
-	[[nodiscard]] auto isInHRE() const { return inHRE; }
-	[[nodiscard]] auto isThePope() const { return thePope; }
-	[[nodiscard]] auto isElectorate() const { return electorate; }
-	[[nodiscard]] auto isHolderCapital() const { return holderCapital; }
-	[[nodiscard]] auto isHRECapital() const { return HRECapital; }
-	[[nodiscard]] auto isCustomTitle() const { return customTitle; }
-	[[nodiscard]] auto isRenamed() const { return renamed; }
-	[[nodiscard]] auto isManualNameClaimed() const { return nameClaimed; }
-	[[nodiscard]] const auto& getName() const { return name; }
-	[[nodiscard]] const auto& getDisplayName() const { return displayName; }
-	[[nodiscard]] const auto& getAdjective() const { return adjective; }
-	[[nodiscard]] const auto& getCreationDate() const { return creationDate; }
-	[[nodiscard]] const auto& getHistoryGovernment() const { return historyGovernment; }
-	[[nodiscard]] const auto& getCapital() const { return capital; }
-	[[nodiscard]] const auto& getDFLiege() const { return dfLiege; }
-	[[nodiscard]] const auto& getDJLiege() const { return djLiege; }
-	[[nodiscard]] const auto& getDFVassals() const { return dfVassals; }
-	[[nodiscard]] const auto& getDJVassals() const { return djVassals; }
-	[[nodiscard]] const auto& getHeirs() const { return heirs; }
-	[[nodiscard]] const auto& getClaimants() const { return claimants; }
-	[[nodiscard]] const auto& getElectors() const { return electors; }
-	[[nodiscard]] const auto& getLaws() const { return laws; }
-	[[nodiscard]] const auto& getHolder() const { return holder; }
-	[[nodiscard]] const auto& getCoA() const { return coa; }
-	[[nodiscard]] const auto& getClay() const { return clay; }
-	[[nodiscard]] const auto& getOwnedDFCounties() const { return ownedDFCounties; }
-	[[nodiscard]] const auto& getOwnedDJCounties() const { return ownedDJCounties; }
-	[[nodiscard]] const auto& getHoldingTitle() const { return holdingTitle; }
-	[[nodiscard]] const auto& getGeneratedLiege() const { return generatedLiege; }
-	[[nodiscard]] const auto& getGeneratedVassals() const { return generatedVassals; }
-	[[nodiscard]] const auto& getEU4Tag() const { return tagCountry; }
-	[[nodiscard]] const auto& getPreviousHolders() const { return previousHolders; }
-
-	[[nodiscard]] std::optional<commonItems::Color> getColor() const;
-	[[nodiscard]] bool isLandless() const;
-	[[nodiscard]] bool areDFLiegeAndDJLiegeSet() const;
-	[[nodiscard]] bool areDFLiegeAndDJLiegeSame() const;
-	[[nodiscard]] bool isHolderSet() const { return holder != std::nullopt; }
-	[[nodiscard]] bool isHolderLinked() const { return holder && holder->second; }
-	[[nodiscard]] bool doesHolderHaveCharacterDomain() const;
-	[[nodiscard]] std::set<std::string> getTitleNamesFromHolderDomain() const;
-	[[nodiscard]] LEVEL getLevel() const;
-
-	// linkage
-	void loadCoat(const std::pair<long long, std::shared_ptr<CoatOfArms>>& coat) { coa = coat; }
-	void loadDFLiege(const std::pair<long long, std::shared_ptr<Title>>& DFLiege) { dfLiege = DFLiege; }
-	void loadDJLiege(const std::pair<long long, std::shared_ptr<Title>>& DJLiege) { djLiege = DJLiege; }
-	void loadDFVassals(const std::map<long long, std::shared_ptr<Title>>& DFVassals) { dfVassals = DFVassals; }
-	void addDFVassals(const std::map<long long, std::shared_ptr<Title>>& DFVassals) { dfVassals.insert(DFVassals.begin(), DFVassals.end()); }
-	void loadDJVassals(const std::map<long long, std::shared_ptr<Title>>& DJVassals) { djVassals = DJVassals; }
-	void loadHolder(const std::pair<long long, std::shared_ptr<Character>>& theHolder) { holder = theHolder; }
-	void loadHeirs(const std::vector<std::pair<long long, std::shared_ptr<Character>>>& theHeirs) { heirs = theHeirs; }
-	void loadPreviousHolders(const std::vector<std::pair<long long, std::shared_ptr<Character>>>& theHolders) { previousHolders = theHolders; }
-	void loadClaimants(const std::map<long long, std::shared_ptr<Character>>& theClaimants) { claimants = theClaimants; }
-	void loadElectors(const std::map<long long, std::shared_ptr<Character>>& theElectors) { electors = theElectors; }
-	void loadClay(const std::shared_ptr<LandedTitles>& theClay) { clay = theClay; }
-	void loadOwnedDFCounties(const std::map<std::string, std::shared_ptr<Title>>& theOwnedCounties) { ownedDFCounties = theOwnedCounties; }
-	void loadOwnedDJCounties(const std::map<std::string, std::shared_ptr<Title>>& theOwnedCounties) { ownedDJCounties = theOwnedCounties; }
-
-	// processing
-	void setDynamicLevel(LEVEL theLevel) { dynamicLevel = theLevel; }
-	void cleanUpDisplayName();
-	[[nodiscard]] int flagDeJureHREProvinces();
-	void brickTitle();
-	void grantIndependence();
-	void resetDFLiege() { dfLiege.reset(); }
-	void resetDJLiege() { djLiege.reset(); }
-	void setHREEmperor() { HREEmperor = true; }
-	void setInHRE() { inHRE = true; }
-	void dropTitleFromDFVassals(long long titleID);
-	void setThePope() { thePope = true; }
-	void setCustomTitle() { customTitle = true; }
-	void setManualNameClaim() { nameClaimed = true; }
-	void pickDisplayName(const std::map<std::string, std::shared_ptr<Title>>& possibleTitles); // Grants one county's name to another during N:1/N:M mappings
-	std::shared_ptr<Title> findDuchyCapital();																 // Only for c_, for now
-	void congregateDFCounties();
-	void congregateDJCounties();
-	void loadGeneratedLiege(const std::pair<std::string, std::shared_ptr<Title>>& liege) { generatedLiege = liege; }
-	void addGeneratedVassal(const std::pair<std::string, std::shared_ptr<Title>>& theVassal) { generatedVassals.insert(theVassal); }
-	void loadHoldingTitle(const std::pair<std::string, std::shared_ptr<Title>>& theTitle) { holdingTitle = theTitle; }
-	void setElectorate() { electorate = true; }
-	void relinkDeFactoVassals();
-
-	// conversion
-	void loadEU4Tag(const std::pair<std::string, std::shared_ptr<EU4::Country>>& theCountry) { tagCountry = theCountry; }
-	[[nodiscard]] double getBuildingWeight(const mappers::DevWeightsMapper& devWeightsMapper) const;
-	void setHolderCapital() { holderCapital = true; }
-	void setHRECapital() { HRECapital = true; }
-	void clearGeneratedVassals() { generatedVassals.clear(); }
-
-	[[nodiscard]] std::map<std::string, std::shared_ptr<Title>> coalesceDFCounties() const;
-	[[nodiscard]] std::map<std::string, std::shared_ptr<Title>> coalesceDJCounties() const;
-
-  private:
-	void registerKeys();
-
-	long long ID = 0;																			// 11038
-	std::pair<long long, std::shared_ptr<Title>> capital;							// capital title is a COUNTY, even for county itself and baronies beneath it!
-	std::string name;																			// c_ashmaka
-	std::string displayName;																// Ashmaka
-	std::string adjective;																	// Ashmakan
-	std::string article;																		// "the ". Not always present.
-	std::string historyGovernment;														// Unclear why this is history. Maybe further governments override it.
-	date creationDate;																		// Unclear. Ranges to 9999.1.1, probably is PDX alternative for "bool isCreated";
-	std::optional<std::pair<long long, std::shared_ptr<CoatOfArms>>> coa;	// This is dejure flag but not defacto.
-	std::optional<std::pair<long long, std::shared_ptr<Title>>> dfLiege;		// defacto liege title (d_kalyani)
-	std::optional<std::pair<long long, std::shared_ptr<Title>>> djLiege;		// dejure liege title (d_rattapadi)
-	std::optional<std::pair<long long, std::shared_ptr<Character>>> holder; // Holding character
-	std::map<long long, std::shared_ptr<Title>> dfVassals;						// defacto vassals, not in save, manually linked post-loading
-	std::map<long long, std::shared_ptr<Title>> djVassals;						// dejure vassals (for all except baronies and titulars)
-	std::vector<std::pair<long long, std::shared_ptr<Character>>> heirs;		// Order of heirs is unclear so we're keeping them ordered and using first if able.
-	std::map<long long, std::shared_ptr<Character>> claimants;					// People holding a claim to this title. Incredibly useful.
-	std::map<long long, std::shared_ptr<Character>> electors;					// People involved in elections regardless of election type law.
-	bool theocraticLease = false;															// Does this apply to non-baronies? Maybe? Who owns it then, dejure liege?
-	std::set<std::string> laws;
-	bool cCapitalBarony = false;
-	bool dCapitalBarony = false;
-	std::shared_ptr<LandedTitles> clay; // Middleware towards geographical data, essential for b_&c_, potentially obsolete for others.
-	bool HREEmperor = false;
-	bool inHRE = false;
-	bool thePope = false;
-	bool customTitle = false;													// True if title was fromed via "Found a New Kingdom/Empire" decision. Vestigal
-	bool renamed = false;														// True if title was manually named
-	bool nameClaimed = false;													// Flag for 1:M (or N:M) province mappings to decide who gets the manual name
-	std::map<std::string, std::shared_ptr<Title>> ownedDFCounties; // used to map higher-lvl titles directly to clay. Includes self! Every c_+ title has this.
-	std::map<std::string, std::shared_ptr<Title>> ownedDJCounties; // ditto
-	std::optional<std::pair<std::string, std::shared_ptr<Title>>> generatedLiege; // Liege we set manually while splitting vassals.
-	std::map<std::string, std::shared_ptr<Title>> generatedVassals;					// Vassals we split off deliberately.
-	std::pair<std::string, std::shared_ptr<Title>> holdingTitle;						// topmost owner title (e_francia or similar), only c_s have this.
-	bool electorate = false;
-	std::optional<std::pair<std::string, std::shared_ptr<EU4::Country>>> tagCountry;
-	bool landless = false;
-	std::optional<commonItems::Color> color;
-	std::vector<std::pair<long long, std::shared_ptr<Character>>> previousHolders;
-	bool holderCapital = false;
-	bool HRECapital = false;
-	std::optional<LEVEL> dynamicLevel; // Maybe assigned through dynamic ranks, otherwise getLevel will try to guesstimate.
-};
-} // namespace CK3
-
-#endif // CK3_TITLE_H
diff --git a/CK3ToEU4/Source/CK3World/Titles/Titles.h b/CK3ToEU4/Source/CK3World/Titles/Titles.h
deleted file mode 100644
index 95132b95..00000000
--- a/CK3ToEU4/Source/CK3World/Titles/Titles.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef CK3_TITLES_H
-#define CK3_TITLES_H
-#include "Parser.h"
-
-namespace CK3
-{
-class Title;
-class CoatsOfArms;
-class Characters;
-class LandedTitles;
-class Titles: commonItems::parser
-{
-  public:
-	Titles() = default;
-	explicit Titles(std::istream& theStream);
-
-	[[nodiscard]] const auto& getTitles() const { return titles; }
-	[[nodiscard]] const auto& getCounter() const { return titleCounter; }
-
-	void linkCoats(const CoatsOfArms& coats);
-	void linkTitles();
-	void linkCharacters(const Characters& characters);
-	void linkLandedTitles(const LandedTitles& landedTitles);
-	void relinkDeFactoVassals();
-
-  private:
-	void registerKeys();
-	void transcribeDynamicRanks();
-
-	std::vector<int> titleCounter = {0, 0, 0, 0, 0, 0};
-	std::map<std::string, std::shared_ptr<Title>> titles; // We're using NAME, not ID for key value!
-	std::map<std::string, std::string> dynamicTitleRanks;
-};
-} // namespace CK3
-
-#endif // CK3_TITLES_H
diff --git a/CK3ToEU4/Source/Configuration/Configuration.cpp b/CK3ToEU4/Source/Configuration/Configuration.cpp
deleted file mode 100644
index 3bf61e2a..00000000
--- a/CK3ToEU4/Source/Configuration/Configuration.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-#include "Configuration.h"
-#include "Color.h"
-#include "CommonFunctions.h"
-#include "CommonRegexes.h"
-#include "GameVersion.h"
-#include "Log.h"
-#include "OSCompatibilityLayer.h"
-#include "ParserHelpers.h"
-#include <fstream>
-auto laFabricaDeColor = commonItems::Color::Factory();
-
-Configuration::Configuration(const commonItems::ConverterVersion& converterVersion)
-{
-	Log(LogLevel::Info) << "Reading configuration file";
-	registerKeys();
-	parseFile("configuration.txt");
-	clearRegisteredKeywords();
-	setOutputName();
-	verifyCK3Path();
-	verifyCK3Version(converterVersion);
-	verifyEU4Path();
-	verifyEU4Version(converterVersion);
-	Log(LogLevel::Progress) << "3 %";
-}
-
-Configuration::Configuration(std::istream& theStream)
-{
-	registerKeys();
-	parseStream(theStream);
-	clearRegisteredKeywords();
-	setOutputName();
-}
-
-void Configuration::registerKeys()
-{
-	registerKeyword("SaveGame", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString path(theStream);
-		SaveGamePath = path.getString();
-		Log(LogLevel::Info) << "Save Game set to: " << SaveGamePath;
-	});
-	registerKeyword("CK3directory", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString path(theStream);
-		CK3Path = path.getString();
-	});
-	registerKeyword("EU4directory", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString path(theStream);
-		EU4Path = path.getString();
-	});
-	registerKeyword("CK3DocDirectory", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString path(theStream);
-		CK3DocPath = path.getString();
-	});
-	registerKeyword("output_name", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString nameStr(theStream);
-		outputName = nameStr.getString();
-		Log(LogLevel::Info) << "Output name set to: " << outputName;
-	});
-	registerKeyword("start_date", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString startDateString(theStream);
-		startDate = STARTDATE(std::stoi(startDateString.getString()));
-		Log(LogLevel::Info) << "Start date set to: " << startDateString.getString();
-	});
-	registerKeyword("i_am_hre", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString hreString(theStream);
-		iAmHre = I_AM_HRE(std::stoi(hreString.getString()));
-		Log(LogLevel::Info) << "HRE set to: " << hreString.getString();
-	});
-	registerKeyword("dejure", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString dejureString(theStream);
-		dejure = DEJURE(std::stoi(dejureString.getString()));
-		Log(LogLevel::Info) << "DeJure set to: " << dejureString.getString();
-	});
-	registerKeyword("split_vassals", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString splitVassalsString(theStream);
-		splitVassals = SPLITVASSALS(std::stoi(splitVassalsString.getString()));
-		Log(LogLevel::Info) << "Split Vassals set to: " << splitVassalsString.getString();
-	});
-	registerKeyword("shatter_empires", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString shatterEmpiresString(theStream);
-		shatterEmpires = SHATTER_EMPIRES(std::stoi(shatterEmpiresString.getString()));
-		Log(LogLevel::Info) << "Shatter Empires set to: " << shatterEmpiresString.getString();
-	});
-	registerKeyword("shatter_level", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString shatterLevelString(theStream);
-		shatterLevel = SHATTER_LEVEL(std::stoi(shatterLevelString.getString()));
-		Log(LogLevel::Info) << "Shatter Level set to: " << shatterLevelString.getString();
-	});
-	registerKeyword("shatter_hre_level", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString shatterHRELevelString(theStream);
-		shatterHRELevel = SHATTER_HRE_LEVEL(std::stoi(shatterHRELevelString.getString()));
-		Log(LogLevel::Info) << "Shatter HRE Level set to: " << shatterHRELevelString.getString();
-	});
-	registerKeyword("siberia", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString siberiaString(theStream);
-		siberia = SIBERIA(std::stoi(siberiaString.getString()));
-		Log(LogLevel::Info) << "Siberia set to: " << siberiaString.getString();
-	});
-	registerKeyword("sunset", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString sunsetString(theStream);
-		sunset = SUNSET(std::stoi(sunsetString.getString()));
-		Log(LogLevel::Info) << "Sunset set to: " << sunsetString.getString();
-	});
-	registerKeyword("dynamicInstitutions", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString dynamicInstitutionsString(theStream);
-		dynamicInstitutions = INSTITUTIONS(std::stoi(dynamicInstitutionsString.getString()));
-		Log(LogLevel::Info) << "Dynamic Institutions set to: " << dynamicInstitutionsString.getString();
-	});
-	registerKeyword("development", [this](const std::string& unused, std::istream& theStream) {
-		const commonItems::singleString developmentString(theStream);
-		development = DEVELOPMENT(std::stoi(developmentString.getString()));
-		Log(LogLevel::Info) << "Development set to: " << developmentString.getString();
-	});
-	registerKeyword("multiprovdevtransfer", [this](std::istream& theStream) {
-		const commonItems::singleString multiprovdevtransferString(theStream);
-		multiProvinceDevelopmentTransfer = MULTIPROVDEVTRANSFER(std::stoi(multiprovdevtransferString.getString()));
-		Log(LogLevel::Info) << "Multiple Province Dev Transfer set to: " << multiprovdevtransferString.getString();
-	});
-	registerKeyword("dynasticNames", [this](std::istream& theStream) {
-		const commonItems::singleString dynasticNamesString(theStream);
-		dynasticNames = DYNASTICNAMES(std::stoi(dynasticNamesString.getString()));
-		Log(LogLevel::Info) << "Dynastic Names set to: " << dynasticNamesString.getString();
-	});
-	registerKeyword("discoveredBy", [this](std::istream& theStream) {
-		const commonItems::singleString discoveredByString(theStream);
-		discoveredBy = DISCOVEREDBY(std::stoi(discoveredByString.getString()));
-		Log(LogLevel::Info) << "Discovered By set to: " << discoveredByString.getString();
-	});
-	registerRegex(commonItems::catchallRegex, commonItems::ignoreItem);
-}
-
-void Configuration::verifyCK3Path()
-{
-	if (!commonItems::DoesFolderExist(CK3Path))
-		throw std::runtime_error(CK3Path + " does not exist!");
-	// TODO: OSX and Linux paths are speculative
-	if (!commonItems::DoesFileExist(CK3Path + "/binaries/ck3.exe") && !commonItems::DoesFileExist(CK3Path + "/CK3game") &&
-		 !commonItems::DoesFileExist(CK3Path + "/binaries/ck3"))
-		throw std::runtime_error(CK3Path + " does not contain Crusader Kings 3!");
-	if (!commonItems::DoesFileExist(CK3Path + "/game/map_data/positions.txt"))
-		throw std::runtime_error(CK3Path + " does not appear to be a valid CK3 install!");
-	Log(LogLevel::Info) << "\tCK3 install path is " << CK3Path;
-	CK3Path += "/game/"; // We're adding "/game/" since all we ever need from now on is in that subdirectory.
-}
-
-void Configuration::verifyEU4Path() const
-{
-	if (!commonItems::DoesFolderExist(EU4Path))
-		throw std::runtime_error(EU4Path + " does not exist!");
-	if (!commonItems::DoesFileExist(EU4Path + "/eu4.exe") && !commonItems::DoesFileExist(EU4Path + "/eu4"))
-		throw std::runtime_error(EU4Path + " does not contain Europa Universalis 4!");
-	if (!commonItems::DoesFileExist(EU4Path + "/map/positions.txt"))
-		throw std::runtime_error(EU4Path + " does not appear to be a valid EU4 install!");
-	Log(LogLevel::Info) << "\tEU4 install path is " << EU4Path;
-}
-
-void Configuration::setOutputName()
-{
-	if (outputName.empty())
-	{
-		outputName = trimPath(SaveGamePath);
-	}
-	outputName = trimExtension(outputName);
-	outputName = replaceCharacter(outputName, '-');
-	outputName = replaceCharacter(outputName, ' ');
-
-	outputName = commonItems::normalizeUTF8Path(outputName);
-	Log(LogLevel::Info) << "Using output name " << outputName;
-}
-
-void Configuration::verifyCK3Version(const commonItems::ConverterVersion& converterVersion) const
-{
-	const auto CK3Version = GameVersion::extractVersionFromLauncher(CK3Path + "../launcher/launcher-settings.json");
-	if (!CK3Version)
-	{
-		Log(LogLevel::Error) << "CK3 version could not be determined, proceeding blind!";
-		return;
-	}
-
-	Log(LogLevel::Info) << "CK3 version: " << CK3Version->toShortString();
-
-	if (converterVersion.getMinSource() > *CK3Version)
-	{
-		Log(LogLevel::Error) << "CK3 version is v" << CK3Version->toShortString() << ", converter requires minimum v"
-									<< converterVersion.getMinSource().toShortString() << "!";
-		throw std::runtime_error("Converter vs CK3 installation mismatch!");
-	}
-	if (!converterVersion.getMaxSource().isLargerishThan(*CK3Version))
-	{
-		Log(LogLevel::Error) << "CK3 version is v" << CK3Version->toShortString() << ", converter requires maximum v"
-									<< converterVersion.getMaxSource().toShortString() << "!";
-		throw std::runtime_error("Converter vs CK3 installation mismatch!");
-	}
-}
-
-void Configuration::verifyEU4Version(const commonItems::ConverterVersion& converterVersion) const
-{
-	const auto EU4Version = GameVersion::extractVersionFromLauncher(EU4Path + "/launcher-settings.json");
-	if (!EU4Version)
-	{
-		Log(LogLevel::Error) << "EU4 version could not be determined, proceeding blind!";
-		return;
-	}
-
-	Log(LogLevel::Info) << "EU4 version: " << EU4Version->toShortString();
-
-	if (converterVersion.getMinTarget() > *EU4Version)
-	{
-		Log(LogLevel::Error) << "EU4 version is v" << EU4Version->toShortString() << ", converter requires minimum v"
-									<< converterVersion.getMinTarget().toShortString() << "!";
-		throw std::runtime_error("Converter vs EU4 installation mismatch!");
-	}
-	if (!converterVersion.getMaxTarget().isLargerishThan(*EU4Version))
-	{
-		Log(LogLevel::Error) << "EU4 version is v" << EU4Version->toShortString() << ", converter requires maximum v"
-									<< converterVersion.getMaxTarget().toShortString() << "!";
-		throw std::runtime_error("Converter vs EU4 installation mismatch!");
-	}
-}
diff --git a/CK3ToEU4/Source/Configuration/Configuration.h b/CK3ToEU4/Source/Configuration/Configuration.h
deleted file mode 100644
index 5281bba3..00000000
--- a/CK3ToEU4/Source/Configuration/Configuration.h
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef CONFIGURATION_H
-#define CONFIGURATION_H
-#include "ConverterVersion.h"
-#include "Parser.h"
-
-class Configuration: commonItems::parser
-{
-  public:
-	Configuration() = default;
-	explicit Configuration(const commonItems::ConverterVersion& converterVersion);
-	explicit Configuration(std::istream& theStream);
-
-	enum class STARTDATE
-	{
-		EU = 1,
-		CK = 2,
-		MANUAL = 3
-	};
-	enum class SPLITVASSALS
-	{
-		YES = 1,
-		NO = 2
-	};
-	enum class DEJURE
-	{
-		ENABLED = 1,
-		DISABLED = 2
-	};
-	enum class DEVELOPMENT
-	{
-		IMPORT = 1,
-		VANILLA = 2
-	};
-	enum class MULTIPROVDEVTRANSFER
-	{
-		DEFAULT = 1,
-		MP = 2
-	};
-	enum class SUNSET
-	{
-		DISABLED = 1,
-		ACTIVE = 2
-	};
-	enum class I_AM_HRE
-	{
-		HRE = 1,
-		BYZANTIUM = 2,
-		ROME = 3,
-		CUSTOM = 4,
-		NONE = 5
-	};
-	enum class SHATTER_EMPIRES
-	{
-		NONE = 1,
-		ALL = 2,
-		CUSTOM = 3
-	};
-	enum class SHATTER_LEVEL
-	{
-		DUTCHY = 1,
-		KINGDOM = 2
-	};
-	enum class SHATTER_HRE_LEVEL
-	{
-		DUTCHY = 1,
-		KINGDOM = 2
-	};
-	enum class SIBERIA
-	{
-		SMALL_SIBERIA = 1,
-		CLEAR_SIBERIA = 2,
-		LEAVE_SIBERIA = 3
-	};
-	enum class INSTITUTIONS
-	{
-		HISTORIC = 1,
-		DYNAMIC = 2
-	};
-	enum class DYNASTICNAMES
-	{
-		ENABLED = 1,
-		DISABLED = 2
-	};
-	enum class DISCOVEREDBY
-	{
-		VANILLA = 1,
-		DYNAMIC = 2
-	};
-
-	[[nodiscard]] const auto& getSaveGamePath() const { return SaveGamePath; }
-	[[nodiscard]] const auto& getCK3Path() const { return CK3Path; }
-	[[nodiscard]] const auto& getCK3DocPath() const { return CK3DocPath; }
-	[[nodiscard]] const auto& getEU4Path() const { return EU4Path; }
-	[[nodiscard]] const auto& getOutputName() const { return outputName; }
-	[[nodiscard]] const auto& getStartDateOption() const { return startDate; }
-	[[nodiscard]] const auto& getHRE() const { return iAmHre; }
-	[[nodiscard]] const auto& getShatterEmpires() const { return shatterEmpires; }
-	[[nodiscard]] const auto& getShatterLevel() const { return shatterLevel; }
-	[[nodiscard]] const auto& getDejure() const { return dejure; }
-	[[nodiscard]] const auto& getShatterHRELevel() const { return shatterHRELevel; }
-	[[nodiscard]] const auto& getSiberia() const { return siberia; }
-	[[nodiscard]] const auto& getSunset() const { return sunset; }
-	[[nodiscard]] const auto& getDynamicInstitutions() const { return dynamicInstitutions; }
-	[[nodiscard]] const auto& getDevelopment() const { return development; }
-	[[nodiscard]] const auto& getMultiProvDevTransfer() const { return multiProvinceDevelopmentTransfer; }
-	[[nodiscard]] const auto& getSplitVassals() const { return splitVassals; }
-	[[nodiscard]] const auto& getPlayerTitle() const { return playerTitle; }
-	[[nodiscard]] const auto& getDynasticNames() const { return dynasticNames; }
-	[[nodiscard]] const auto& getDiscoveredBy() const { return discoveredBy; }
-
-	void setCraftFlagForPlayerTitle(const std::string& title) { playerTitle = title; }
-
-  private:
-	void registerKeys();
-	void setOutputName();
-	void verifyCK3Path();
-	void verifyEU4Path() const;
-	void verifyCK3Version(const commonItems::ConverterVersion& converterVersion) const;
-	void verifyEU4Version(const commonItems::ConverterVersion& converterVersion) const;
-
-	std::string SaveGamePath;
-	std::string CK3Path;
-	std::string CK3DocPath;
-	std::string EU4Path;
-	std::string outputName;
-
-	STARTDATE startDate = STARTDATE::EU;
-	I_AM_HRE iAmHre = I_AM_HRE::HRE;
-	SHATTER_EMPIRES shatterEmpires = SHATTER_EMPIRES::NONE;
-	SHATTER_HRE_LEVEL shatterHRELevel = SHATTER_HRE_LEVEL::DUTCHY;
-	SHATTER_LEVEL shatterLevel = SHATTER_LEVEL::DUTCHY;
-	SIBERIA siberia = SIBERIA::CLEAR_SIBERIA;
-	SUNSET sunset = SUNSET::DISABLED;
-	INSTITUTIONS dynamicInstitutions = INSTITUTIONS::HISTORIC;
-	DEVELOPMENT development = DEVELOPMENT::IMPORT;
-	MULTIPROVDEVTRANSFER multiProvinceDevelopmentTransfer = MULTIPROVDEVTRANSFER::DEFAULT;
-	DEJURE dejure = DEJURE::ENABLED;
-	SPLITVASSALS splitVassals = SPLITVASSALS::YES;
-	DYNASTICNAMES dynasticNames = DYNASTICNAMES::ENABLED;
-	DISCOVEREDBY discoveredBy = DISCOVEREDBY::VANILLA;
-
-	std::optional<std::string> playerTitle;
-};
-
-#endif // CONFIGURATION_H