diff --git a/pystencils/astnodes.py b/pystencils/astnodes.py
index ed03bf7627040093167a175ec0229a17a484fe44..d2826fa850a6dbf06db192bf45509147633bfc93 100644
--- a/pystencils/astnodes.py
+++ b/pystencils/astnodes.py
@@ -294,6 +294,8 @@ class SkipIteration(Node):
 class Block(Node):
     def __init__(self, nodes: List[Node]):
         super(Block, self).__init__()
+        if not isinstance(nodes, list):
+            nodes = [nodes]
         self._nodes = nodes
         self.parent = None
         for n in self._nodes:
diff --git a/pystencils/backends/cbackend.py b/pystencils/backends/cbackend.py
index 8437bdb6801ecc5adc717dec2983e5d6eda0baf0..a8a3dbc8d467585ba71570d6c0df7d31a8738dcf 100644
--- a/pystencils/backends/cbackend.py
+++ b/pystencils/backends/cbackend.py
@@ -125,7 +125,7 @@ def get_headers(ast_node: Node) -> Set[str]:
 
 # --------------------------------------- Backend Specific Nodes -------------------------------------------------------
 
-
+# TODO CustomCodeNode should not be backend specific
 class CustomCodeNode(Node):
     def __init__(self, code, symbols_read, symbols_defined, parent=None):
         super(CustomCodeNode, self).__init__(parent=parent)
diff --git a/pystencils/kernelcreation.py b/pystencils/kernelcreation.py
index c63946bf0b05dd321a5c1da1672369932c80fe1e..50eaedf4f51eea2b969673d8011bd4c6a2dfa062 100644
--- a/pystencils/kernelcreation.py
+++ b/pystencils/kernelcreation.py
@@ -19,7 +19,7 @@ from pystencils.transformations import (
     loop_blocking, move_constants_before_loop, remove_conditionals_in_staggered_kernel)
 
 
-def create_kernel(assignments: Union[Assignment, List[Assignment], AssignmentCollection, List[Node]], *,
+def create_kernel(assignments: Union[Assignment, List[Assignment], AssignmentCollection, List[Node], NodeCollection], *,
                   config: CreateKernelConfig = None, **kwargs):
     """
     Creates abstract syntax tree (AST) of kernel, using a list of update equations.
diff --git a/pystencils/node_collection.py b/pystencils/node_collection.py
index 68f53f36c578fcb470cb18122b08300a89f1fe8b..0287b6fc8dbec76f03283b032d47f77eacb45516 100644
--- a/pystencils/node_collection.py
+++ b/pystencils/node_collection.py
@@ -1,12 +1,13 @@
 import logging
 from typing import List, Union
 
+import sympy
 import sympy as sp
 from sympy.codegen import Assignment
 from sympy.codegen.rewriting import ReplaceOptim, optimize
 
-from pystencils.astnodes import Node
-
+from pystencils.astnodes import Block, Node
+from pystencils.backends.cbackend import CustomCodeNode
 from pystencils.functions import DivFunc
 
 
@@ -28,11 +29,6 @@ class NodeCollection:
         self.simplification_hints = ()
 
     def evaluate_terms(self):
-
-        # There is no visitor implemented now so working with nodes does not work
-        if self.is_Nodes:
-            return
-
         evaluate_constant_terms = ReplaceOptim(
             lambda e: hasattr(e, 'is_constant') and e.is_constant and not e.is_integer,
             lambda p: p.evalf())
@@ -43,8 +39,22 @@ class NodeCollection:
                 sp.UnevaluatedExpr(sp.Mul(*([p.base] * +p.exp), evaluate=False)) if p.exp > 0 else
                 DivFunc(sp.Integer(1), sp.Mul(*([p.base] * -p.exp), evaluate=False))
             ))
-
         sympy_optimisations = [evaluate_constant_terms, evaluate_pow]
-        self.all_assignments = [Assignment(a.lhs, optimize(a.rhs, sympy_optimisations))
-                                if hasattr(a, 'lhs')
-                                else a for a in self.all_assignments]
+
+        if self.is_Nodes:
+            def visitor(node):
+                if isinstance(node, CustomCodeNode):
+                    return node
+                elif isinstance(node, Block):
+                    return node.func([visitor(child) for child in node.args])
+                elif isinstance(node, Node):
+                    return node.func(*[visitor(child) for child in node.args])
+                elif isinstance(node, sympy.Basic):
+                    return optimize(node, sympy_optimisations)
+                else:
+                    raise NotImplementedError(f'{node} {type(node)} has no valid visitor')
+            self.all_assignments = [visitor(assignment) for assignment in self.all_assignments]
+        else:
+            self.all_assignments = [Assignment(a.lhs, optimize(a.rhs, sympy_optimisations))
+                                    if hasattr(a, 'lhs')
+                                    else a for a in self.all_assignments]
diff --git a/pystencils_tests/test_fvm.py b/pystencils_tests/test_fvm.py
index 55ce1f7db2e859978a4afb5bb3a763ca5e7d2d56..c0e22f8bd497620863b185a460780eb6af95bb27 100644
--- a/pystencils_tests/test_fvm.py
+++ b/pystencils_tests/test_fvm.py
@@ -4,6 +4,8 @@ import numpy as np
 import pytest
 from itertools import product
 from pystencils.rng import random_symbol
+from pystencils.astnodes import SympyAssignment
+from pystencils.node_collection import NodeCollection
 
 
 def advection_diffusion(dim: int):
@@ -240,12 +242,10 @@ def advection_diffusion_fluctuations(dim: int):
 advection_diffusion_fluctuations.runners = {}
 
 
-# @pytest.mark.parametrize("velocity", list(product([0, 0.00041], [0, -0.00031])))
-# @pytest.mark.parametrize("density", [27.0, 56.5])
-# @pytest.mark.longrun
-def test_advection_diffusion_fluctuation_2d():
-    density = 27.0
-    velocity = [0, 0.00041]
+@pytest.mark.parametrize("velocity", list(product([0, 0.00041], [0, -0.00031])))
+@pytest.mark.parametrize("density", [27.0, 56.5])
+@pytest.mark.longrun
+def test_advection_diffusion_fluctuation_2d(density, velocity):
     if 2 not in advection_diffusion_fluctuations.runners:
         advection_diffusion_fluctuations.runners[2] = advection_diffusion_fluctuations(2)
     advection_diffusion_fluctuations.runners[2](density, velocity)
@@ -318,33 +318,38 @@ def diffusion_reaction(fluctuations: bool):
             # add fluctuations
             fluct *= 2 * (next(rng_symbol_gen) - 0.5) * sp.sqrt(3)
             
-            flux.main_assignments[i] = ps.Assignment(flux.main_assignments[i].lhs, flux.main_assignments[i].rhs + fluct)
+            flux.main_assignments[i] = ps.Assignment(flux.main_assignments[i].lhs,
+                                                       flux.main_assignments[i].rhs + fluct)
         
         # Add the folding to the flux, so that the random numbers persist through the ghostlayers.
         fold = {ps.astnodes.LoopOverCoordinate.get_loop_counter_symbol(i):
                 ps.astnodes.LoopOverCoordinate.get_loop_counter_symbol(i) % L[i] for i in range(len(L))}
         flux.subs(fold)
 
-    r_flux = ps.AssignmentCollection([ps.Assignment(j_fields[i].center, 0) for i in range(species)])
+    r_flux = NodeCollection([SympyAssignment(j_fields[i].center, 0) for i in range(species)])
     reaction = r_rate_const
     for i in range(species):
         reaction *= sp.Pow(n_fields[i].center, r_order[i])
-    if(fluctuations):
-        rng_symbol_gen = random_symbol(r_flux.subexpressions, dim=dh.dim)
+    new_assignments = []
+    if fluctuations:
+        rng_symbol_gen = random_symbol(new_assignments, dim=dh.dim)
         reaction_fluctuations = sp.sqrt(sp.Abs(reaction)) * 2 * (next(rng_symbol_gen) - 0.5) * sp.sqrt(3)
         reaction_fluctuations *= sp.Min(1, sp.Abs(reaction**2))
     else:
         reaction_fluctuations = 0.0
     for i in range(species):
-        r_flux.main_assignments[i] = ps.Assignment(
+        r_flux.all_assignments[i] = SympyAssignment(
             r_flux_fields[i].center, (reaction + reaction_fluctuations) * r_coefs[i])
+    [r_flux.all_assignments.insert(0, new) for new in new_assignments]
 
-    continuity_assignments.append(ps.Assignment(n_fields[0].center, n_fields[0].center + r_flux_fields[0].center))
+    continuity_assignments = [SympyAssignment(*assignment.args) for assignment in continuity_assignments]
+    continuity_assignments.append(SympyAssignment(n_fields[0].center, n_fields[0].center + r_flux_fields[0].center))
 
     flux_kernel = ps.create_staggered_kernel(flux).compile()
     reaction_kernel = ps.create_kernel(r_flux).compile()
 
-    pde_kernel = ps.create_kernel(continuity_assignments).compile()
+    config = ps.CreateKernelConfig(allow_double_writes=True)
+    pde_kernel = ps.create_kernel(continuity_assignments, config=config).compile()
 
     sync_conc = dh.synchronization_function([n_fields[0].name, n_fields[1].name])
 
@@ -414,7 +419,7 @@ advection_diffusion_fluctuations.runners = {}
 @pytest.mark.parametrize("density", [27.0, 56.5])
 @pytest.mark.parametrize("fluctuations", [False, True])
 @pytest.mark.longrun
-def test_diffusion_reaction(density, velocity, fluctuations):
+def test_diffusion_reaction(velocity, density, fluctuations):
     diffusion_reaction.runner = diffusion_reaction(fluctuations)
     diffusion_reaction.runner(density, velocity)