diff --git a/src/pystencilssfg/ir/source_components.py b/src/pystencilssfg/ir/source_components.py
index 07ee848efccf3afd64a62a26db5c5d00eafa4218..d98e2d8796c3f09b579017c4bf38017d6aa7e35c 100644
--- a/src/pystencilssfg/ir/source_components.py
+++ b/src/pystencilssfg/ir/source_components.py
@@ -39,9 +39,9 @@ class SfgCodeEntity:
     Each code entity has a name and an optional enclosing namespace.
     """
 
-    def __init__(self, name: str, namespace: SfgNamespace | None) -> None:
+    def __init__(self, name: str, parent_namespace: SfgNamespace | None) -> None:
         self._name = name
-        self._namespace: SfgNamespace | None = namespace
+        self._namespace: SfgNamespace | None = parent_namespace
 
     @property
     def name(self) -> str:
@@ -57,11 +57,23 @@ class SfgCodeEntity:
             return self._name
 
     @property
-    def namespace(self) -> SfgNamespace | None:
+    def parent_namespace(self) -> SfgNamespace | None:
         """Parent namespace of this entity"""
         return self._namespace
 
 
+class SfgNamespace(SfgCodeEntity):
+    """A C++ namespace.
+
+    Each namespace has a `name` and a `parent`; its fully qualified name is given as
+    ``<parent.name>::<name>``.
+
+    Args:
+        name: Local name of this namespace
+        parent: Parent namespace enclosing this namespace
+    """
+
+
 class SfgKernelHandle(SfgCodeEntity):
     """Handle to a pystencils kernel."""
 
@@ -100,7 +112,76 @@ class SfgKernelHandle(SfgCodeEntity):
         return self._kernel
 
 
+class SfgKernelNamespace(SfgNamespace):
+    """A namespace grouping together a number of kernels."""
+
+    def __init__(self, name: str, parent: SfgNamespace | None):
+        super().__init__(name, parent)
+        self._kernels: dict[str, SfgKernelHandle] = []
+
+    @property
+    def name(self):
+        return self._name
+
+    @property
+    def kernels(self) -> tuple[SfgKernelHandle, ...]:
+        return tuple(self._kernels.values())
+
+    def add(self, kernel: Kernel, name: str | None = None):
+        """Adds an existing pystencils AST to this namespace.
+        If a name is specified, the AST's function name is changed."""
+        if name is None:
+            kernel_name = kernel.name
+        else:
+            kernel_name = name
+
+        if kernel_name in self._kernels:
+            raise ValueError(
+                f"Duplicate kernels: A kernel called {kernel_name} already exists in namespace {self.fqname}"
+            )
+
+        if name is not None:
+            kernel.name = kernel_name
+
+        khandle = SfgKernelHandle(kernel_name, self, kernel)
+        self._kernels[kernel_name] = khandle
+
+        #   TODO: collect includes later
+        # for header in kernel.required_headers:
+        #     self._ctx.add_include(
+        #         SfgHeaderInclude(HeaderFile.parse(header), private=True)
+        #     )
+
+        return khandle
+
+    def create(
+        self,
+        assignments,
+        name: str | None = None,
+        config: CreateKernelConfig | None = None,
+    ):
+        """Creates a new pystencils kernel from a list of assignments and a configuration.
+        This is a wrapper around `pystencils.create_kernel`
+        with a subsequent call to `add`.
+        """
+        if config is None:
+            config = CreateKernelConfig()
+
+        if name is not None:
+            if name in self._kernels:
+                raise ValueError(
+                    f"Duplicate kernels: A kernel with name {name} already exists in namespace {self.fqname}"
+                )
+            config = replace(config, function_name=name)
+
+        # type: ignore
+        kernel = create_kernel(assignments, config=config)
+        return self.add(kernel)
+
+
 class SfgFunction(SfgCodeEntity):
+    """A free function."""
+
     __match_args__ = ("name", "tree", "parameters")
 
     def __init__(
@@ -142,6 +223,8 @@ class SfgFunction(SfgCodeEntity):
 
 
 class SfgVisibility(Enum):
+    """Visibility qualifiers of C++"""
+
     DEFAULT = auto()
     PRIVATE = auto()
     PROTECTED = auto()
@@ -160,6 +243,8 @@ class SfgVisibility(Enum):
 
 
 class SfgClassKeyword(Enum):
+    """Class keywords of C++"""
+
     STRUCT = auto()
     CLASS = auto()
 
@@ -172,6 +257,8 @@ class SfgClassKeyword(Enum):
 
 
 class SfgClassMember(ABC):
+    """Base class for class member entities"""
+
     def __init__(self) -> None:
         self._cls: SfgClass | None = None
         self._visibility: SfgVisibility | None = None
@@ -205,25 +292,56 @@ class SfgClassMember(ABC):
 
 
 class SfgMemberVariable(SfgVar, SfgClassMember):
+    """Variable that is a field of a class"""
+
     def __init__(self, name: str, dtype: PsType):
         SfgVar.__init__(self, name, dtype)
         SfgClassMember.__init__(self)
 
 
-class SfgMethod(SfgFunction, SfgClassMember):
+class SfgMethod(SfgClassMember):
+    """Instance method of a class"""
+
+    __match_args__ = ("name", "tree", "parameters")
+
     def __init__(
         self,
         name: str,
         tree: SfgCallTreeNode,
-        return_type: PsType = PsCustomType("void"),
+        return_type: PsType = void,
         inline: bool = False,
         const: bool = False,
     ):
-        SfgFunction.__init__(self, name, tree, return_type=return_type, inline=inline)
-        SfgClassMember.__init__(self)
+        super().__init__()
 
+        self._name = name
+        self._tree = tree
+        self._return_type = return_type
+        self._inline = inline
         self._const = const
-        self._parameters: set[SfgVar] = set()
+
+        self._parameters: set[SfgVar]
+
+        from .postprocessing import CallTreePostProcessing
+
+        param_collector = CallTreePostProcessing()
+        self._parameters = param_collector(self._tree).function_params
+
+    @property
+    def parameters(self) -> set[SfgVar]:
+        return self._parameters
+
+    @property
+    def tree(self) -> SfgCallTreeNode:
+        return self._tree
+
+    @property
+    def return_type(self) -> PsType:
+        return self._return_type
+
+    @property
+    def inline(self) -> bool:
+        return self._inline
 
     @property
     def const(self) -> bool:
@@ -231,6 +349,8 @@ class SfgMethod(SfgFunction, SfgClassMember):
 
 
 class SfgConstructor(SfgClassMember):
+    """Constructor of a class"""
+
     __match_args__ = ("parameters", "initializers", "body")
 
     def __init__(
@@ -503,7 +623,7 @@ class SfgVisibilityBlock:
         self._cls = cls
 
 
-class SfgNamespace:
+class SfgNamespaceDef:
     """A C++ namespace.
 
     Each namespace has a `name` and a `parent`; its fully qualified name is given as
@@ -514,24 +634,10 @@ class SfgNamespace:
         parent: Parent namespace enclosing this namespace
     """
 
-    def __init__(self, name: str, parent: SfgNamespace | None) -> None:
-        self._name: str = name
-        self._parent: SfgNamespace | None = parent
+    def __init__(self, namespace: SfgNamespace) -> None:
+        self._namespace = namespace
         self._elements: list[SfgNamespaceElement] = []
 
-    @property
-    def name(self) -> str:
-        """The name of this namespace"""
-        return self._name
-
-    @property
-    def fqname(self) -> str:
-        """The fully qualified name of this namespace"""
-        if self._parent is not None:
-            return self._parent.fqname + "::" + self._name
-        else:
-            return self._name
-
     @property
     def elements(self) -> list[SfgNamespaceElement]:
         """Sequence of source elements that make up the body of this namespace"""
@@ -542,74 +648,7 @@ class SfgNamespace:
         self._elements = list(elems)
 
 
-class SfgKernelNamespace(SfgNamespace):
-    """A namespace grouping together a number of kernels."""
-
-    def __init__(self, name: str, parent: SfgNamespace | None):
-        super().__init__(name, parent)
-        self._kernels: dict[str, SfgKernelHandle] = []
-
-    @property
-    def name(self):
-        return self._name
-
-    @property
-    def kernels(self) -> tuple[SfgKernelHandle, ...]:
-        return tuple(self._kernels.values())
-
-    def add(self, kernel: Kernel, name: str | None = None):
-        """Adds an existing pystencils AST to this namespace.
-        If a name is specified, the AST's function name is changed."""
-        if name is None:
-            kernel_name = kernel.name
-        else:
-            kernel_name = name
-
-        if kernel_name in self._kernels:
-            raise ValueError(
-                f"Duplicate kernels: A kernel called {kernel_name} already exists in namespace {self.fqname}"
-            )
-
-        if name is not None:
-            kernel.name = kernel_name
-
-        khandle = SfgKernelHandle(kernel_name, self, kernel)
-        self._kernels[kernel_name] = khandle
-
-        #   TODO: collect includes later
-        # for header in kernel.required_headers:
-        #     self._ctx.add_include(
-        #         SfgHeaderInclude(HeaderFile.parse(header), private=True)
-        #     )
-
-        return khandle
-
-    def create(
-        self,
-        assignments,
-        name: str | None = None,
-        config: CreateKernelConfig | None = None,
-    ):
-        """Creates a new pystencils kernel from a list of assignments and a configuration.
-        This is a wrapper around `pystencils.create_kernel`
-        with a subsequent call to `add`.
-        """
-        if config is None:
-            config = CreateKernelConfig()
-
-        if name is not None:
-            if name in self._kernels:
-                raise ValueError(
-                    f"Duplicate kernels: A kernel with name {name} already exists in namespace {self.fqname}"
-                )
-            config = replace(config, function_name=name)
-
-        # type: ignore
-        kernel = create_kernel(assignments, config=config)
-        return self.add(kernel)
-
-
-SfgNamespaceElement = str | SfgNamespace | SfgEntityDecl | SfgEntityDef
+SfgNamespaceElement = str | SfgNamespaceDef | SfgEntityDecl | SfgEntityDef
 """Elements that may be placed inside a namespace, including the global namespace."""