diff --git a/engine/gen/Storyboard/GenericAction/TrafficSinkAction.h b/engine/gen/Storyboard/GenericAction/TrafficSinkAction.h
index db18e47132e267c0bb1103ae9f62f1c1bd4345a1..58f3823aceaa839da229eab8f8364f9bea180dd2 100644
--- a/engine/gen/Storyboard/GenericAction/TrafficSinkAction.h
+++ b/engine/gen/Storyboard/GenericAction/TrafficSinkAction.h
@@ -54,7 +54,8 @@ private:
             [=]() { return ConvertScenarioPosition(environment, trafficSinkAction_->GetPosition()); },
             trafficSinkAction_->IsSetTrafficDefinition()
                 ? std::make_optional(ConvertScenarioTrafficDefinition(trafficSinkAction_->GetTrafficDefinition()))
-                : std::nullopt},
+                : std::nullopt
+            },
         OpenScenarioEngine::v1_2::TrafficSinkAction::Interfaces{
             environment});
   }
diff --git a/generator/open_scenario_tree.py b/generator/open_scenario_tree.py
index 7ad40fcc9f4774c11229dd5917deeb8c20c10e1d..6e90e654bb0182f41266372d6af66f032139a3c4 100644
--- a/generator/open_scenario_tree.py
+++ b/generator/open_scenario_tree.py
@@ -21,15 +21,15 @@ class Entity:
 
 @dataclass
 class PrimitiveType:
-     name: str
+    name: str
 
-@dataclass
+@dataclass(frozen=True)
 class OscProperty:
-     name: str
-     type: Union[str, PrimitiveType]
-     optional: bool
-     list: bool
-     choice: bool
+    name: str
+    type: Union[str, PrimitiveType]
+    optional: bool
+    list: bool
+    choice: bool
 
 class OscNode:
     PROPAGATED_PROPERTIES = {
diff --git a/generator/property_view.py b/generator/property_view.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae50f06b433060fa8ff5d2cbe5f192b34507b300
--- /dev/null
+++ b/generator/property_view.py
@@ -0,0 +1,42 @@
+from typing import List
+from open_scenario_tree import OscProperty
+from converter import Converter
+
+def feature_decorator(condition, prefix, suffix = ""):
+    def decorator(func):
+        def wrapper(self, *args, **kwargs):
+            prefix_, suffix_ = ("", "")
+            if condition(self):
+                prefix_ = prefix if isinstance(prefix, str) else prefix(self)
+                suffix_ = suffix if isinstance(suffix, str) else suffix(self)
+            return f'{prefix_}{func(self, *args, **kwargs)}{suffix_}'
+        return wrapper
+    return decorator
+
+class PropertyView:
+    CONVERTER_PREFIX = "ConvertScenario"
+
+    def __init__(self, node_name, converter: Converter, properties: List[OscProperty]):
+        self.node_name = node_name
+        self.converter = converter
+        self.properties = properties
+
+    @staticmethod
+    def capitalize_first(s):
+        return s[0].upper() + s[1:] if s else s
+
+    def get_property(self, prop):
+        prefix = f"{self.node_name}->IsSet{self.capitalize_first(prop.name)}() ? std::make_optional(" if prop.optional else ""
+        suffix = ") : std::nullopt" if prop.optional else ""
+        return f"{prefix}{self.node_name}->Get{self.capitalize_first(prop.name)}(){suffix}"
+
+    @feature_decorator(condition = lambda self: self.converter and self.converter.runtime,
+                        prefix="[=](){ return ",
+                        suffix="; }")
+    @feature_decorator(condition = lambda self: self.converter,
+                        prefix=lambda self: f"{self.CONVERTER_PREFIX}{self.capitalize_first(self.converter.name)}(",
+                        suffix=")")
+    @feature_decorator(condition = lambda self: self.converter and self.converter.dependencies,
+                       prefix=lambda self: f'{", ".join([d.name for d in self.converter.dependencies])}, ')
+    def __str__(self):
+        return ", ".join(self.get_property(prop) for prop in self.properties)
diff --git a/generator/tests/test_nodeview.py b/generator/tests/test_nodeview.py
index 3c7e81cb020819eccd9161f0faa46389ed699edc..589710a19bc31d47ec66f5083b6d7437a92fd570 100644
--- a/generator/tests/test_nodeview.py
+++ b/generator/tests/test_nodeview.py
@@ -3,11 +3,8 @@ from open_scenario_tree import OscNode, parse_properties
 from converter import Converter, Dependency
 from typing import List
 import pytest
-import dataclasses
 
-#from test_property_view import PropertyView
-class PropertyView:
-    pass
+from property_view import PropertyView
 
 def capitalize_first(s):
     return s[0].upper() + s[1:] if s else s
@@ -21,54 +18,28 @@ class NodeView:
 
     def __init__(self, node: OscNode, converter: List[Converter]):
         self.node = node
+        self.member_name = f'{lowercase_first(self.node.name)}{self.MEMBER_SUFFIX}'
         self.converter = converter
-        self.properties_view = self._generate_properties_view()
+        self._properties = self._generate_properties_view()
         self.dependencies = self._generate_dependencies()
         self.includes = self._generate_converter_includes()
 
-    @property
-    def name(self):
-        return f'{lowercase_first(self.node.name)}{self.MEMBER_SUFFIX}'
-    
     def _generate_properties_view(self):
-        properties_view = []
+        properties = []
+        unconverted_properties = set(self.node.properties)
         for converter in self.converter:
             if set(converter.properties).issubset({prop.name for prop in self.node.properties}):
-                property_view = PropertyView(converter, )
-                property_view.name=f"{self.CONVERTER_PREFIX}{capitalize_first(converter.name)}"
-                property_view.members=[f"{self.name}->Get{capitalize_first(prop)}()" for prop in converter.properties]
-                if converter.keep:
-                    properties_view.extend([
-                        PropertyView(
-                            name=f"{self.name}->Get{capitalize_first(prop)}") for prop in converter.keep 
-                                 if all(f"{self.name}->Get{capitalize_first(prop)}" != prop_view.name for prop_view in properties_view)])
-                if converter.dependencies:
-                    property_view.dependencies=[dep.name for dep in converter.dependencies]
-                if converter.runtime:
-                    property_view.opening="[=](){ return "
-                    property_view.closing="; }"
-                properties_view.extend(property_view)
-
-        
-        optional_props = [prop for prop in self.node.properties if prop.optional]
-        properties_view.extend([
-                PropertyView(
-                    name=f"{self.name}->Get{capitalize_first(prop.name)}",
-                    opening=f"{self.name}->IsSet{capitalize_first(prop.name)}() ? std::make_optional(",
-                    closing=") : std::nullopt") for prop in optional_props for prop_view in properties_view])
-                            
-        # Add remaining properties that are not consumed by the converters       
-        consumed_props = [prop for converter in self.converter for prop in converter.properties]
-        remaining_props = [prop for prop in self.node.properties if prop.name not in consumed_props and not prop.optional]
-        properties_view.extend([
-                PropertyView(
-                    name=f"{self.name}->Get{capitalize_first(prop.name)}") for prop in remaining_props])
-
-        return properties_view
+                consumed_properties = [prop for prop in self.node.properties if prop.name in converter.properties]
+                properties.append(PropertyView(self.member_name, converter, consumed_properties))
+                unconverted_properties.difference_update(consumed_properties)
+                unconverted_properties.update([prop for prop in self.node.properties if prop.name in converter.keep])
+        for prop in unconverted_properties:
+            properties.append(PropertyView(self.member_name, None, [prop]))
+        return properties
 
     @property
-    def new_properties(self):
-        return sorted([str(prop) for prop in self.properties_view])
+    def properties(self):
+        return sorted([str(prop) for prop in self._properties])
 
     def _generate_converter_includes(self):
         includes = []
@@ -97,12 +68,12 @@ def node_with_3_props():
 
 def test__given_node_and_no_converters__relays_name(node_with_3_props):
     node_view = NodeView(node_with_3_props, [])
-    assert node_view.name == "nodeUnderTest_"
+    assert node_view.member_name == "nodeUnderTest_"
 
 def test__given_node_and_no_converters__generates_property_views_without_converters(node_with_3_props):
     node_view = NodeView(node_with_3_props, [])
 
-    assert node_view.new_properties == [
+    assert node_view.properties == [
         "nodeUnderTest_->GetPropName1()",
         "nodeUnderTest_->GetPropName2()",
         "nodeUnderTest_->GetPropName3()" ]
@@ -114,7 +85,7 @@ def test__given_node_and_no_converters__generates_no_conversion_includes(node_wi
 def test__given_node_and_consuming_converter__combines_props_and_consumes_them(node_with_3_props):
     node_view = NodeView(node_with_3_props, [Converter([], "customPropName", {'Properties': ['propName1', 'propName3']})])
 
-    assert node_view.new_properties == [
+    assert node_view.properties == [
         "ConvertScenarioCustomPropName(nodeUnderTest_->GetPropName1(), nodeUnderTest_->GetPropName3())",
         "nodeUnderTest_->GetPropName2()"]
 
@@ -129,7 +100,7 @@ def test__given_node_and_keeping_converter__combines_props_and_keeps_prop(node_w
         'Keep': ['propName3']
     })])
 
-    assert node_view.new_properties == [
+    assert node_view.properties == [
         "ConvertScenarioCustomPropName(nodeUnderTest_->GetPropName1(), nodeUnderTest_->GetPropName3())",
         "nodeUnderTest_->GetPropName2()",
         "nodeUnderTest_->GetPropName3()"]
@@ -143,7 +114,7 @@ def test__given_node_and_two_keeping_converters__combines_props_and_keeps_prop_o
         'Keep': ['propName3']
     })])
 
-    assert node_view.new_properties == [
+    assert node_view.properties == [
         "ConvertScenarioCustomPropName1(nodeUnderTest_->GetPropName1(), nodeUnderTest_->GetPropName3())",
         "ConvertScenarioCustomPropName2(nodeUnderTest_->GetPropName2(), nodeUnderTest_->GetPropName3())",
         "nodeUnderTest_->GetPropName3()"]
@@ -155,21 +126,21 @@ def test__given_node_and_converter_with_deps_and_props__integrates_deps_and_cons
         'Dependencies': ['Environment']})
     node_view = NodeView(node_with_3_props, [converter])
 
-    assert "ConvertScenarioCustomType(environment, nodeUnderTest_->GetPropName1())" in node_view.new_properties
+    assert "ConvertScenarioCustomType(environment, nodeUnderTest_->GetPropName1())" in node_view.properties
 
 def test__given_node_and_converter_with_deps_and_no_props__integrates_deps_and_consumes_default_prop(node_with_3_props):
     fake_deps = {"Environment": Dependency("environment", "std::shared_ptr<mantle_api::IEnvironment>", "<mantle_api/i_environment.h>")}
     converter = Converter(fake_deps, "propName1", {'Dependencies': ['Environment']})
     node_view = NodeView(node_with_3_props, [converter])
 
-    assert "ConvertScenarioPropName1(environment, nodeUnderTest_->GetPropName1())" in node_view.new_properties
+    assert "ConvertScenarioPropName1(environment, nodeUnderTest_->GetPropName1())" in node_view.properties
 
 def test__given_node_and_non_matching_converter__ignores_converter(node_with_3_props):
     fake_deps = {"Environment": Dependency("environment", "std::shared_ptr<mantle_api::IEnvironment>", "<mantle_api/i_environment.h>")}
     unused_converter = Converter(fake_deps, "someArbitraryProperty", {'Dependencies': ['Environment']})
     node_view = NodeView(node_with_3_props, [unused_converter])
 
-    assert node_view.new_properties == [
+    assert node_view.properties == [
         "nodeUnderTest_->GetPropName1()",
         "nodeUnderTest_->GetPropName2()",
         "nodeUnderTest_->GetPropName3()"]
@@ -198,7 +169,7 @@ def test__given_node_and_runtime_converter__creates_lambda_wrapper_for_converter
         'Type': 'runtime'
     })])
 
-    assert "[=](){ return ConvertScenarioPropName1(nodeUnderTest_->GetPropName1()); }" in node_view.new_properties
+    assert "[=](){ return ConvertScenarioPropName1(nodeUnderTest_->GetPropName1()); }" in node_view.properties
 
 def test__given_node_and_runtime_converter_with_deps__creates_lambda_wrapper_for_converter_stage(node_with_3_props):
     fake_deps = {"Environment": Dependency("environment", "std::shared_ptr<mantle_api::IEnvironment>", "<mantle_api/i_environment.h>")}
@@ -206,7 +177,7 @@ def test__given_node_and_runtime_converter_with_deps__creates_lambda_wrapper_for
         'Type': 'runtime'
     })])
 
-    assert "[=](){ return ConvertScenarioPropName1(environment, nodeUnderTest_->GetPropName1()); }" in node_view.new_properties
+    assert "[=](){ return ConvertScenarioPropName1(environment, nodeUnderTest_->GetPropName1()); }" in node_view.properties
 
     # assert str(PropertyView(
     #     opening="[=](){ return ",
@@ -225,7 +196,7 @@ def test__given_node_with_optional_property__generates_ternary_operator():
          }))
     node_view = NodeView(node_under_test, [])
 
-    assert node_view.new_properties == [
+    assert node_view.properties == [
         "nodeUnderTest_->IsSetPropName1() ? std::make_optional(nodeUnderTest_->GetPropName1()) : std::nullopt"]
 
 def test__given_node_with_optional_property_and_converter__generates_ternary_operator():
@@ -234,8 +205,8 @@ def test__given_node_with_optional_property_and_converter__generates_ternary_ope
          }))
     node_view = NodeView(node_under_test, [Converter([], "customPropName", {'Properties': ['propName1']})])
 
-    assert node_view.new_properties == [
-        "nodeUnderTest_->IsSetPropName1() ? std::make_optional(ConvertScenarioCustomPropName(nodeUnderTest_->GetPropName1())) : std::nullopt"]
+    assert node_view.properties == [
+        "ConvertScenarioCustomPropName(nodeUnderTest_->IsSetPropName1() ? std::make_optional(nodeUnderTest_->GetPropName1()) : std::nullopt)"]
 
 def test__given_node_with_optional_property_and_runtime__generates_ternary_operator():
     node_under_test = OscNode("NodeUnderTest", parse_properties({
@@ -243,5 +214,5 @@ def test__given_node_with_optional_property_and_runtime__generates_ternary_opera
          }))
     node_view = NodeView(node_under_test, [Converter([], "customPropName", {'Properties': ['propName1'], 'Type': 'runtime'})])
 
-    assert node_view.new_properties == [
-        "[=](){ return nodeUnderTest_->IsSetPropName1() ? std::make_optional(ConvertScenarioCustomPropName(nodeUnderTest_->GetPropName1())) : std::nullopt }"]
+    assert node_view.properties == [
+        "[=](){ return ConvertScenarioCustomPropName(nodeUnderTest_->IsSetPropName1() ? std::make_optional(nodeUnderTest_->GetPropName1()) : std::nullopt); }"]
diff --git a/generator/tests/test_property_view.py b/generator/tests/test_property_view.py
index 6b1be24a192b09383d4bf88756c08e216342e15f..4b2dc223f7332baca58ed2ff0140d0eda709e382 100644
--- a/generator/tests/test_property_view.py
+++ b/generator/tests/test_property_view.py
@@ -1,91 +1,32 @@
-from typing import List
-
 import pytest
-from open_scenario_tree import OscProperty
-from converter import Converter, Dependency
-
-
-# def test_my_decorator_used():
-#     obj = PropertyView("node", "Method", True, False)
-#     assert str(obj) == "node_->IsSetMethod ? std::make_optional(node_->GetMethod()) : std::nullopt"
-
-
-# def test_my_decorator_unused():
-#     obj = PropertyView("node", "Method", False, False)
-#     assert str(obj) == "node_->GetMethod()"
-
-# def test_my_decorator_used_2():
-#     obj = PropertyView("node", "Method", False, True)
-#     assert str(obj) == "[=](){ return node_->GetMethod(); }"
-
-# def test_my_decorator_used_3():
-#     obj = PropertyView("node", "Method", True, True)
-#     assert str(obj) == "[=](){ return node_->IsSetMethod ? std::make_optional(node_->GetMethod()) : std::nullopt; }"
 
-
-def feature_decorator(condition, prefix, suffix = ""):
-    def decorator(func):
-        def wrapper(self, *args, **kwargs):
-            prefix_, suffix_ = ("", "")
-            if condition(self):
-                prefix_ = prefix if isinstance(prefix, str) else prefix(self)
-                suffix_ = suffix if isinstance(suffix, str) else suffix(self)
-            return f'{prefix_}{func(self, *args, **kwargs)}{suffix_}'
-        return wrapper
-    return decorator
-
-class PropertyView:
-    CONVERTER_PREFIX = "ConvertScenario"
-    MEMBER_SUFFIX = "_"
-
-    def __init__(self, node, converter: Converter, properties: List[OscProperty]):
-        self.node = f'{node}{self.MEMBER_SUFFIX}'
-        self.converter = converter
-        self.properties = properties
-
-    @staticmethod
-    def capitalize_first(s):
-        return s[0].upper() + s[1:] if s else s
-
-    def get_property(self, prop):
-        prefix = f"{self.node}->IsSet{self.capitalize_first(prop.name)} ? std::make_optional(" if prop.optional else ""
-        suffix = ") : std::nullopt" if prop.optional else ""
-        return f"{prefix}{self.node}->Get{self.capitalize_first(prop.name)}(){suffix}"
-
-    @feature_decorator(condition = lambda self: self.converter and self.converter.runtime,
-                        prefix="[=](){ return ",
-                        suffix="; }")
-    @feature_decorator(condition = lambda self: self.converter,
-                        prefix=lambda self: f"{self.CONVERTER_PREFIX}{self.capitalize_first(self.converter.name)}(",
-                        suffix=")")
-    @feature_decorator(condition = lambda self: self.converter and self.converter.dependencies,
-                       prefix=lambda self: f'{", ".join([d.name for d in self.converter.dependencies])}, ')
-    def __str__(self):
-        return ", ".join(self.get_property(prop) for prop in self.properties)
+from property_view import PropertyView
+from converter import Converter, Dependency
+from open_scenario_tree import OscProperty
 
 @pytest.mark.parametrize("node, converter, oscProperty, expected_result", [
-    ("node", Converter([], "propName", {}), [OscProperty("propName", "type", False, False, False)], "ConvertScenarioPropName(node_->GetPropName())"),
-    ("node", Converter([], "propName", {}), [OscProperty("propName", "type", True, False, False)], "ConvertScenarioPropName(node_->IsSetPropName ? std::make_optional(node_->GetPropName()) : std::nullopt)"),
-    ("node", Converter([], "propName", {}), [OscProperty("propName", "type", False, True, False)], "ConvertScenarioPropName(node_->GetPropName())"),
-    ("node", Converter([], "propName", {}), [OscProperty("propName", "type", False, False, True)], "ConvertScenarioPropName(node_->GetPropName())"),
-    ("node", Converter([], "propName", {}), [OscProperty("propName", "type", True, True, False)], "ConvertScenarioPropName(node_->IsSetPropName ? std::make_optional(node_->GetPropName()) : std::nullopt)"),
-    ("node", Converter([], "propName", {}), [OscProperty("propName", "type", True, False, True)], "ConvertScenarioPropName(node_->IsSetPropName ? std::make_optional(node_->GetPropName()) : std::nullopt)"),
-    ("node", Converter([], "propName", {}), [OscProperty("propName", "type", False, True, True)], "ConvertScenarioPropName(node_->GetPropName())"),
-    ("node", Converter([], "propName", {}), [OscProperty("propName", "type", True, True, True)], "ConvertScenarioPropName(node_->IsSetPropName ? std::make_optional(node_->GetPropName()) : std::nullopt)")
+    ("node_", Converter([], "propName", {}), [OscProperty("propName", "type", False, False, False)], "ConvertScenarioPropName(node_->GetPropName())"),
+    ("node_", Converter([], "propName", {}), [OscProperty("propName", "type", True, False, False)], "ConvertScenarioPropName(node_->IsSetPropName() ? std::make_optional(node_->GetPropName()) : std::nullopt)"),
+    ("node_", Converter([], "propName", {}), [OscProperty("propName", "type", False, True, False)], "ConvertScenarioPropName(node_->GetPropName())"),
+    ("node_", Converter([], "propName", {}), [OscProperty("propName", "type", False, False, True)], "ConvertScenarioPropName(node_->GetPropName())"),
+    ("node_", Converter([], "propName", {}), [OscProperty("propName", "type", True, True, False)], "ConvertScenarioPropName(node_->IsSetPropName() ? std::make_optional(node_->GetPropName()) : std::nullopt)"),
+    ("node_", Converter([], "propName", {}), [OscProperty("propName", "type", True, False, True)], "ConvertScenarioPropName(node_->IsSetPropName() ? std::make_optional(node_->GetPropName()) : std::nullopt)"),
+    ("node_", Converter([], "propName", {}), [OscProperty("propName", "type", False, True, True)], "ConvertScenarioPropName(node_->GetPropName())"),
+    ("node_", Converter([], "propName", {}), [OscProperty("propName", "type", True, True, True)], "ConvertScenarioPropName(node_->IsSetPropName() ? std::make_optional(node_->GetPropName()) : std::nullopt)")
 ])
 def test__given_property_with_converter__generates_property_views_with_converters(node, converter, oscProperty, expected_result):
     obj = PropertyView(node, converter, oscProperty)
     assert str(obj) == expected_result
 
 def test__given_property_and_optional_property_with_converter__generates_property_views_with_ternary_operator():
-    obj = PropertyView("node", Converter([], "MyConv", {}), [OscProperty("propName1", "type", False, False, False), OscProperty("propName2", "type", True, False, False)])
-    assert str(obj) == "ConvertScenarioMyConv(node_->GetPropName1(), node_->IsSetPropName2 ? std::make_optional(node_->GetPropName2()) : std::nullopt)"
+    obj = PropertyView("node_", Converter([], "MyConv", {}), [OscProperty("propName1", "type", False, False, False), OscProperty("propName2", "type", True, False, False)])
+    assert str(obj) == "ConvertScenarioMyConv(node_->GetPropName1(), node_->IsSetPropName2() ? std::make_optional(node_->GetPropName2()) : std::nullopt)"
 
 def test__given_property_with_no_converters__generates_property_views_without_converters():
-    obj = PropertyView("node", None, [OscProperty("propName1", "type", False, False, False)])
+    obj = PropertyView("node_", None, [OscProperty("propName1", "type", False, False, False)])
     assert str(obj) == "node_->GetPropName1()"
 
 def test__given_property_and_optional_property_with_converter__generates_property_views_with_ternary_operator213():
     dep = {"Environment": Dependency("environment", "", "")}
-    obj = PropertyView("node", Converter(dep, "MyConv", {'Dependencies': ['Environment']}), [OscProperty("propName1", "type", False, False, False)])
+    obj = PropertyView("node_", Converter(dep, "MyConv", {'Dependencies': ['Environment']}), [OscProperty("propName1", "type", False, False, False)])
     assert str(obj) == "ConvertScenarioMyConv(environment, node_->GetPropName1())"
\ No newline at end of file