diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000000000000000000000000000000000..4ebdbde593360115727d892d2379acdbc05e423f
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "NG_Commons"]
+	path = NG_Commons
+	url = ../../nerdgautica/python/commons
diff --git a/NG_Commons b/NG_Commons
new file mode 160000
index 0000000000000000000000000000000000000000..30e3744e1d2f4afb0fec23f9e82b4f5b9ca131a7
--- /dev/null
+++ b/NG_Commons
@@ -0,0 +1 @@
+Subproject commit 30e3744e1d2f4afb0fec23f9e82b4f5b9ca131a7
diff --git a/Recipe.py b/Recipe.py
index 70ee16ff8626c8bc229f8153a4e152053a5d5ece..efa072826e10209a06bb22a509f2de0ce14b7240 100644
--- a/Recipe.py
+++ b/Recipe.py
@@ -1,9 +1,11 @@
-from xml.etree.ElementTree import Element
+from xml.etree.ElementTree import Element, tostring
 
 class WareRecipe:
     class ProductionResourceDef:
         resources: dict
-        def __init__(self, resources={}):
+        def __init__(self, resources=None):
+            if resources is None:
+                resources = {}
             self.resources = resources
 
         def set_resource(self, wareid: str, amount: int):
@@ -12,7 +14,9 @@ class WareRecipe:
 
     class ProductionEffectDef:
         effects: dict
-        def __init__(self, effects={}):
+        def __init__(self, effects=None):
+            if effects is None:
+                effects = {}
             self.effects = effects
 
         def set_effect(self, effect_type: str, product: float):
@@ -21,7 +25,7 @@ class WareRecipe:
     wareid: str
     resources: ProductionResourceDef
     effects: ProductionEffectDef
-    worktime: int
+    worktime: float
     produced_amount: int
     method: str
     recipe_name: str
@@ -50,22 +54,23 @@ class WareRecipe:
         return ware_recipe
 
     @staticmethod
-    def from_xml(wareid: str, production_node: Element):
+    def from_xml(wareid: str, wareid_lookup: str, production_node: Element):
         ware_recipe = WareRecipe()
         ware_recipe.wareid = wareid
-        ware_recipe.worktime = int(production_node.get("time"))
+        ware_recipe.wareid_lookup = wareid_lookup
+        ware_recipe.worktime = float(production_node.get("time"))
         ware_recipe.produced_amount = int(production_node.get("amount"))
         ware_recipe.method = production_node.get("method")
         ware_recipe.recipe_name = production_node.get("name")
-        ware_recipe.effects = WareRecipe.ProductionEffectDef()
-        ware_recipe.resources = WareRecipe.ProductionResourceDef()
-        for subnode in production_node.getchildren():
+        ware_recipe.effects = WareRecipe.ProductionEffectDef({})
+        ware_recipe.resources = WareRecipe.ProductionResourceDef({})
+        for subnode in production_node.iter():
             if subnode.tag == "primary":  # Actual resources used
-                for resource in subnode.getchildren():
+                for resource in subnode.iter():
                     if resource.tag == "ware":
                         ware_recipe.resources.set_resource(resource.get("ware"), int(resource.get("amount")))
             elif subnode.tag == "effects":  # Possible effects on production
-                for effect in subnode.getchildren():
+                for effect in subnode.iter():
                     if effect.tag == "effect":
                         ware_recipe.effects.set_effect(effect.get("type"), float(effect.get("product")))
         return ware_recipe
@@ -103,16 +108,33 @@ class WareRecipe:
         root.append(production)
         return root
 
+    def to_xml_string(self, encoding="unicode"):
+        return tostring(self.generate_recipe_addition(), encoding)
+
+    def to_dict(self) -> dict:
+        return {
+            "wareid": self.wareid,
+            "wareid_lookup": self.wareid_lookup,
+            "method": self.method,
+            "recipe_name": self.recipe_name,
+            "worktime": self.worktime,
+            "produced_amount": self.produced_amount,
+            "effects": self.effects.effects,
+            "resources": self.resources.resources
+        }
+
+    def __str__(self) -> str:
+        return str(self.to_dict())
+
 if __name__ == "__main__":
     # Doing a simple generation test
-    from xml.etree.ElementTree import tostring
     recipe = WareRecipe.generate(
         wareid='bogus_debug_ware',
         method='terran',
         recipe_name='same_translation_string_as_original',
         worktime=100,
         produced_amount=42,
-        effects=WareRecipe.ProductionEffectDef(),  # defaults to empty
+        effects=WareRecipe.ProductionEffectDef({}),  # defaults to empty
         resources=WareRecipe.ProductionResourceDef(
             {
                 'first_resource': 7,
diff --git a/ProductionCalculation.py b/Wares.py
similarity index 62%
rename from ProductionCalculation.py
rename to Wares.py
index 9afd7952871e89cb96fbe58fe5a852720574b1f6..ea0f1ede35e29445750a5e1fd23d7bb61a64fa8c 100644
--- a/ProductionCalculation.py
+++ b/Wares.py
@@ -12,7 +12,7 @@ def get_ware_recipes(root: Element) -> 'list[WareRecipe]':
     recipes = []
 
     if is_delta:
-        for element in root.getchildren():
+        for element in root.iter():
             # Only supporting additions for now
             if element.tag != "add":
                 continue
@@ -25,20 +25,28 @@ def get_ware_recipes(root: Element) -> 'list[WareRecipe]':
             elif ware_selection.startswith("/wares/ware"):
                 # Get ware ID in question
                 wareid = ware_selection[17:-2]
-                for subelement in element.getchildren():
+                for subelement in element.iter():
                     if subelement.tag == "production":
                         # Is not altering production -> not a recipe
-                        recipes.append(WareRecipe.from_xml(wareid=wareid, production_node=subelement))
+                        recipes.append(WareRecipe.from_xml(
+                            wareid=wareid,
+                            wareid_lookup="/wares/ware",  # Enforced due to prior logic
+                            production_node=subelement
+                        ))
     else:
-        for element in root.getchildren():
+        for element in root.iter():
             # Ignore "production" and "defaults" for now, they aren't important to parse it
             # Functionality regarding those might be added later on?
             if element.tag != "ware":
                 continue
             wareid = element.get("id")
-            for production_node in element.getchildren():
+            for production_node in element.iter():
                 if production_node.tag == "production":
-                    recipes.append(WareRecipe.from_xml(wareid=wareid, production_node=production_node))
+                    recipes.append(WareRecipe.from_xml(
+                        wareid=wareid,
+                        wareid_lookup="/wares/ware",  # Enforced due to prior logic
+                        production_node=production_node
+                    ))
 
     return recipes
 
@@ -50,4 +58,12 @@ def get_ware_recipes_string(xml_string: str) -> 'list[WareRecipe]':
 def get_ware_recipes_file(filepath: str) -> 'list[WareRecipe]':
     from xml.etree.ElementTree import parse
     with open(filepath, "r") as xml_file:
-        return get_ware_recipes(parse(xml_file))
+        return get_ware_recipes(parse(xml_file).getroot())
+
+
+if __name__ == "__main__":
+    # Some debug code for testing
+    from NG_Commons.CLI import dictString, promptInput
+    for recipe in get_ware_recipes_file(promptInput("Please provide the path to the wares.xml to process", None, False)):
+        print("----------")
+        print(dictString(recipe.to_dict()))