diff --git a/pystencils/astnodes.py b/pystencils/astnodes.py
index 2f020d4e3e139b4e7525eabd2920c0fbc8a44e09..d21aeec6c0601428e321d9019a8474548f5c16b9 100644
--- a/pystencils/astnodes.py
+++ b/pystencils/astnodes.py
@@ -55,7 +55,8 @@ class Node:
         for arg in self.args:
             if isinstance(arg, arg_type):
                 result.add(arg)
-            result.update(arg.atoms(arg_type))
+            arg_atoms = arg.atoms(arg_type) if (isinstance(arg, sp.Basic) or isinstance(arg, Node) or isinstance(arg, sp.Expr)) else {}
+            result.update(arg_atoms)
         return result
 
 
@@ -232,7 +233,8 @@ class KernelFunction(Node):
     @property
     def fields_accessed(self) -> Set[Field]:
         """Set of Field instances: fields which are accessed inside this kernel function"""
-        return set(o.field for o in itertools.chain(self.atoms(ResolvedFieldAccess)))
+        fields = self.atoms(ResolvedFieldAccess)
+        return set(o.field for o in itertools.chain(fields))
 
     @property
     def fields_written(self) -> Set[Field]:
@@ -265,7 +267,9 @@ class KernelFunction(Node):
                 return tuple(field_map[fn] for fn in symbol.field_names)
             return ()
 
-        argument_symbols = self._body.undefined_symbols - self.global_variables
+        symbols_defined = self.body.symbols_defined
+        undefined_symbols =  self._body.undefined_symbols
+        argument_symbols = undefined_symbols - self.global_variables - symbols_defined
         argument_symbols.update(sizes)
         parameters = [self.Parameter(symbol, get_fields(symbol)) for symbol in argument_symbols]
         if hasattr(self, 'indexing'):
@@ -303,7 +307,7 @@ class SkipIteration(Node):
 
 
 class Block(Node):
-    def __init__(self, nodes: Union[Node, List[Node]]):
+    def __init__(self, nodes: List[Node]):
         super(Block, self).__init__()
         if not isinstance(nodes, list):
             nodes = [nodes]
@@ -345,6 +349,14 @@ class Block(Node):
         assert self._nodes.count(insert_before) == 1
         idx = self._nodes.index(insert_before)
 
+        # move all assignment (definitions to the top)
+        if isinstance(new_node, SympyAssignment) and new_node.is_declaration:
+            while idx > 0:
+                pn = self._nodes[idx - 1]
+                if isinstance(pn, LoopOverCoordinate) or isinstance(pn, Conditional):
+                    idx -= 1
+                else:
+                    break
         if not if_not_exists or self._nodes[idx] != new_node:
             self._nodes.insert(idx, new_node)
 
@@ -353,6 +365,14 @@ class Block(Node):
         assert self._nodes.count(insert_after) == 1
         idx = self._nodes.index(insert_after) + 1
 
+        # move all assignment (definitions to the top)
+        if isinstance(new_node, SympyAssignment) and new_node.is_declaration:
+            while idx > 0:
+                pn = self._nodes[idx - 1]
+                if isinstance(pn, LoopOverCoordinate) or isinstance(pn, Conditional):
+                    idx -= 1
+                else:
+                    break
         if not if_not_exists or not (self._nodes[idx - 1] == new_node
                                      or (idx < len(self._nodes) and self._nodes[idx] == new_node)):
             self._nodes.insert(idx, new_node)
@@ -404,7 +424,8 @@ class Block(Node):
             else:
                 result.update(a.undefined_symbols)
                 defined_symbols.update(a.symbols_defined)
-        return result - defined_symbols
+        ret = result - defined_symbols
+        return ret
 
     def __str__(self):
         return "Block " + ''.join('{!s}\n'.format(node) for node in self._nodes)
@@ -561,10 +582,10 @@ class SympyAssignment(Node):
     def __init__(self, lhs_symbol, rhs_expr, is_const=True, use_auto=False):
         super(SympyAssignment, self).__init__(parent=None)
         self._lhs_symbol = sp.sympify(lhs_symbol)
-        self._rhs = sp.sympify(rhs_expr)
+        self.rhs = sp.sympify(rhs_expr)
         self._is_const = is_const
         self._is_declaration = self.__is_declaration()
-        self._use_auto = use_auto
+        self.use_auto = use_auto
 
     def __is_declaration(self):
         from pystencils.typing import CastFunc
@@ -580,28 +601,15 @@ class SympyAssignment(Node):
     def lhs(self):
         return self._lhs_symbol
 
-    @property
-    def rhs(self):
-        return self._rhs
-
     @lhs.setter
     def lhs(self, new_value):
         self._lhs_symbol = new_value
         self._is_declaration = self.__is_declaration()
 
-    @rhs.setter
-    def rhs(self, new_rhs_expr):
-        self._rhs = new_rhs_expr
-
     def subs(self, subs_dict):
         self.lhs = fast_subs(self.lhs, subs_dict)
         self.rhs = fast_subs(self.rhs, subs_dict)
 
-    def fast_subs(self, subs_dict, skip=None):
-        self.lhs = fast_subs(self.lhs, subs_dict, skip)
-        self.rhs = fast_subs(self.rhs, subs_dict, skip)
-        return self
-
     def optimize(self, optimizations):
         try:
             from sympy.codegen.rewriting import optimize
@@ -611,7 +619,7 @@ class SympyAssignment(Node):
 
     @property
     def args(self):
-        return [self._lhs_symbol, self.rhs]
+        return [self._lhs_symbol, self.rhs, sp.sympify(self._is_const)]
 
     @property
     def symbols_defined(self):
@@ -642,10 +650,6 @@ class SympyAssignment(Node):
     def is_const(self):
         return self._is_const
 
-    @property
-    def use_auto(self):
-        return self._use_auto
-
     def replace(self, child, replacement):
         if child == self.lhs:
             replacement.parent = self
@@ -928,15 +932,15 @@ class ForLoop(Node):
 
 
     def __str__(self):
-        return 'for({!s}={!s}; {!s}<{!s}; {!s}+={!s})\n{!s}'.format(self.ctr_to_loop_over.name, self.start,
-                                                                    self.ctr_to_loop_over.name, self.stop,
-                                                                    self.ctr_to_loop_over.name, self.step,
+        return 'for({!s}={!s}; {!s}<{!s}; {!s}+={!s})\n{!s}'.format(self.loop_counter_name, self.start,
+                                                                    self.loop_counter_name, self.stop,
+                                                                    self.loop_counter_name, self.step,
                                                                     ("\t" + "\t".join(str(self.body).splitlines(True))))
 
     def __repr__(self):
-        return 'for({!s}={!s}; {!s}<{!s}; {!s}+={!s})'.format(self.ctr_to_loop_over.name, self.start,
-                                                              self.ctr_to_loop_over.name, self.stop,
-                                                              self.ctr_to_loop_over.name, self.step)
+        return 'for({!s}={!s}; {!s}<{!s}; {!s}+={!s})'.format(self.loop_counter_name, self.start,
+                                                              self.loop_counter_name, self.stop,
+                                                              self.loop_counter_name, self.step)
 
 
 class ArrayDeclaration(Node):
@@ -962,7 +966,18 @@ class ArrayDeclaration(Node):
 
     @property
     def undefined_symbols(self):
-        return self._entries.atoms(TypedSymbol)
+        undefined_symbols = set()
+        for e in self._entries:
+            if isinstance(e, Node):
+                undefined_symbols = undefined_symbols | e.undefined_symbols
+            elif isinstance(e, sp.Basic) or isinstance(e, sp.Expr):
+                undefined_symbols = undefined_symbols | e.free_symbols
+
+        return undefined_symbols
+
+    def subs(self, substitutions, skip=None):
+        self._lhs = self.lhs.subs(substitutions)
+        self._entries = [e.subs(substitutions) for e in self._entries]
 
     def __str__(self):
         entry_str =  ", ".join( [str(e) for e in self._entries])
diff --git a/pystencils/backends/cbackend.py b/pystencils/backends/cbackend.py
index 874307628c08514b47b8b9d9c5f09160c670bda3..adfaa232de7d245d8445b8cca22456e2d9f579ee 100644
--- a/pystencils/backends/cbackend.py
+++ b/pystencils/backends/cbackend.py
@@ -224,13 +224,6 @@ class CBackend:
     def _print_AbstractType(self, node):
         return str(node)
 
-    def _print_ArrayDeclaration(self, node):
-        return str(node)
-
-    def _print_ForLoop(self, node):
-        return f"{node.__repr__()}\n{self._print(node.body)}"
-
-
     def _print_KernelFunction(self, node):
         function_arguments = [f"{self._print(s.symbol.dtype)} {s.symbol.name}" for s in node.get_parameters()
                               if not type(s.symbol) is CFunction]
@@ -248,7 +241,7 @@ class CBackend:
         return func_declaration + "\n" + body
 
     def _print_Block(self, node):
-        if node is None:
+        if node == None:
             return "\n"
 
         block_contents = "\n".join([self._print(child) for child in node.args])
@@ -272,14 +265,10 @@ class CBackend:
         return f"{prefix}{loop_str}\n{self._print(node.body)}"
 
     def _print_SympyAssignment(self, node):
-        printed_lhs = self.sympy_printer.doprint(node.lhs)
-        printed_rhs = self.sympy_printer.doprint(node.rhs)
-
         if node.is_declaration:
             if node.use_auto:
-                data_type = 'auto'
+                data_type = 'auto '
             else:
-                data_type = self._print(node.lhs.dtype).replace(' const', '')
                 if node.is_const:
                     prefix = 'const '
                 else:
@@ -364,10 +353,12 @@ class CBackend:
                     code += f"\nif ({flushcond}) {{\n\t{code2}\n}} else {{\n\t{code1}\n}}"
                 return pre_code + code
             else:
-                return f"{printed_lhs} = {printed_rhs};"
+                return f"{self.sympy_printer.doprint(node.lhs)} = {self.sympy_printer.doprint(node.rhs)};"
 
     def _print_ArrayDeclaration(self, node):
-        return node.__str__()
+        entry_str = ", ".join([self.sympy_printer.doprint(e) for e in node._entries])
+        return f"const {node._lhs.dtype.base_type} {node._lhs.name} [] = {{{entry_str}}};\n"
+
 
     def _print_ForLoop(self, node):
         counter_symbol = node.ctr_to_loop_over
@@ -685,7 +676,8 @@ class VectorizedCustomSympyPrinter(CustomSympyPrinter):
                 return self.instruction_set[instruction].format(*printed_args, **self._kwargs)
             else:
                 if arg.is_Number and not isinstance(arg, (sp.core.numbers.Infinity, sp.core.numbers.NegativeInfinity)):
-                    return self._typed_vectorized_number(arg, data_type)
+                    tmp = self._typed_vectorized_number(arg, data_type)
+                    return tmp
                 elif isinstance(arg, TypedSymbol):
                     return self._typed_vectorized_symbol(arg, data_type)
                 elif isinstance(arg, (InverseTrigonometricFunction, TrigonometricFunction, HyperbolicFunction)) \
@@ -779,6 +771,8 @@ class VectorizedCustomSympyPrinter(CustomSympyPrinter):
             return result
         args = expr.args
 
+
+
         # special treatment for all-integer args, for loop index arithmetic until we have proper int vectorization
         suffix = ""
         if all([(type(e) is CastFunc and str(e.dtype) == self.instruction_set['int']) or isinstance(e, sp.Integer)
@@ -798,6 +792,7 @@ class VectorizedCustomSympyPrinter(CustomSympyPrinter):
                 t = self._print(term)
                 sign = 1
             summands.append(self.SummandInfo(sign, t))
+
         # Use positive terms first
         summands.sort(key=lambda e: e.sign, reverse=True)
         # if no positive term exists, prepend a zero
@@ -836,7 +831,10 @@ class VectorizedCustomSympyPrinter(CustomSympyPrinter):
         if exp.is_integer and exp.is_number and 0 < exp < 8:
             return self._print(sp.Mul(*[expr.base] * exp, evaluate=False))
         elif exp.is_integer and exp.is_number and -8 < exp < 0:
-            return self._print(sp.Mul(*[DivFunc(CastFunc(1.0, expr.base.dtype), expr.base)] * (-exp), evaluate=False))
+            arg_types = [get_type_of_expression(a, default_float_type='float') for a in expr.args]
+
+            target_type = collate_types(arg_types)
+            return self._print(sp.Mul(*[DivFunc(CastFunc(1.0,target_type),expr.base)] * (-exp), evaluate=False))
         elif exp == 0.5:
             return root
         elif exp == -0.5:
@@ -902,6 +900,7 @@ class VectorizedCustomSympyPrinter(CustomSympyPrinter):
         result = self._scalarFallback('_print_Relational', expr)
         if result:
             return result
+        tmp = self.instruction_set[expr.rel_op].format(self._print(expr.lhs), self._print(expr.rhs), **self._kwargs)
         return self.instruction_set[expr.rel_op].format(self._print(expr.lhs), self._print(expr.rhs), **self._kwargs)
 
     def _print_Equality(self, expr):
@@ -915,6 +914,7 @@ class VectorizedCustomSympyPrinter(CustomSympyPrinter):
         if result:
             return result
 
+
         if expr.args[-1].cond is not sp.sympify(True):
             # We need the last conditional to be a True, otherwise the resulting
             # function may not return a result.
@@ -931,6 +931,9 @@ class VectorizedCustomSympyPrinter(CustomSympyPrinter):
                                                        result, **self._kwargs)
             else:
                 # noinspection SpellCheckingInspection
+                cond = self._print(condition)
+                true = self._print(true_expr)
+
                 result = self.instruction_set['blendv'].format(result, self._print(true_expr), self._print(condition),
                                                                **self._kwargs)
         return result
diff --git a/pystencils/cpu/vectorization.py b/pystencils/cpu/vectorization.py
index 7e0b15aa649b30a4f831ed30521a419c50506968..71e82740b7c517bb08db7a8430a89d0d4d50557f 100644
--- a/pystencils/cpu/vectorization.py
+++ b/pystencils/cpu/vectorization.py
@@ -50,7 +50,7 @@ class CachelineSize(ast.Node):
     symbol = sp.Symbol("_clsize")
     mask_symbol = sp.Symbol("_clsize_mask")
     last_symbol = sp.Symbol("_cl_lastvec")
-    
+
     def __init__(self):
         super(CachelineSize, self).__init__(parent=None)
 
@@ -142,7 +142,7 @@ def vectorize_inner_loops_and_adapt_load_stores(ast_node, assume_aligned, nontem
     """Goes over all innermost loops, changes increment to vector width and replaces field accesses by vector type."""
     vector_width = ast_node.instruction_set['width']
 
-    all_loops = filtered_tree_iteration(ast_node, ast.LoopOverCoordinate, stop_type=ast.SympyAssignment)
+    all_loops = filtered_tree_iteration(ast_node, ast.LoopOverCoordinate, stop_types=[ast.SympyAssignment, ast.ArrayDeclaration])
     inner_loops = [loop for loop in all_loops if loop.is_innermost_loop]
     zero_loop_counters = {loop.loop_counter_symbol: 0 for loop in all_loops}
 
@@ -283,7 +283,7 @@ def insert_vector_casts(ast_node, instruction_set, loop_counter_symbol, default_
     # TODO Vectorization Revamp: get rid of default_type
     def visit_expr(expr, default_type='double', force_vectorize=False):
         if isinstance(expr, ast.ResolvedFieldAccess):
-            assert (expr.args[1] != loop_counter_symbol) and (expr.args[1].name != loop_counter_symbol.name), f"ResolvedFieldAccess {expr} is indexed by the coordinate that is vectorized over, not handled."
+            #assert (expr.args[1] != loop_counter_symbol) and (expr.args[1].name != loop_counter_symbol.name), f"ResolvedFieldAccess {expr} is indexed by the coordinate that is vectorized over, not handled."
             if force_vectorize:
                     return CastFunc(expr, VectorType(expr.field.dtype, instruction_set['width']))
             else:
diff --git a/pystencils/transformations.py b/pystencils/transformations.py
index 4a50a4dc4fe7b1838d76e3d29bef5f7aa3c9c299..398148508c1070fbdc34a6f49230a4f771a39bb3 100644
--- a/pystencils/transformations.py
+++ b/pystencils/transformations.py
@@ -4,11 +4,9 @@ import warnings
 from collections import OrderedDict
 from copy import deepcopy
 from types import MappingProxyType
-from typing import Set
 
 import sympy as sp
 
-import pystencils as ps
 import pystencils.astnodes as ast
 from pystencils.astnodes import Conditional
 
@@ -78,14 +76,16 @@ class NestedScopes:
         return len(self._defined)
 
 
-def filtered_tree_iteration(node, node_type, stop_type=None):
+def filtered_tree_iteration(node, node_type, stop_types=None):
+    if not hasattr(node, 'args'):
+        raise Exception(node)
     for arg in node.args:
         if isinstance(arg, node_type):
             yield arg
-        elif stop_type and isinstance(node, stop_type):
+        elif stop_types and any([isinstance(node, stop_type) for stop_type in stop_types]):
             continue
 
-        yield from filtered_tree_iteration(arg, node_type)
+        yield from filtered_tree_iteration(arg, node_type, stop_types)
 
 
 def generic_visit(term, visitor):
@@ -523,7 +523,7 @@ def resolve_field_accesses(ast_node, read_only_field_names=None,
                 coord_dict = create_coordinate_dict(group)
                 new_ptr, offset = create_intermediate_base_pointer(field_access, coord_dict, last_pointer)
                 if new_ptr not in enclosing_block.symbols_defined:
-                    new_assignment = ast.SympyAssignment(new_ptr, last_pointer + offset, is_const=False, use_auto=False)
+                    new_assignment = ast.SympyAssignment(new_ptr, last_pointer + offset, is_const=False)
                     enclosing_block.insert_before(new_assignment, sympy_assignment)
                 last_pointer = new_ptr
 
@@ -587,70 +587,21 @@ def move_constants_before_loop(ast_node, rename_moved_consts = False, lhs_symbol
         """
         assert isinstance(node.parent, ast.Block)
 
-        def modifies_or_declares(node: ast.Node, symbol_names: Set[str]) -> bool:
-            if isinstance(node, (ps.Assignment, ast.SympyAssignment)):
-                if isinstance(node.lhs, ast.ResolvedFieldAccess):
-                    return node.lhs.typed_symbol.name in symbol_names
-                else:
-                    return node.lhs.name in symbol_names
-            elif isinstance(node, ast.Block):
-                for arg in node.args:
-                    if isinstance(arg, ast.SympyAssignment) and arg.is_declaration:
-                        continue
-                    if modifies_or_declares(arg, symbol_names):
-                        return True
-                return False
-            elif isinstance(node, ast.LoopOverCoordinate):
-                return modifies_or_declares(node.body, symbol_names)
-            elif isinstance(node, ast.Conditional):
-                return (
-                    modifies_or_declares(node.true_block, symbol_names)
-                    or (node.false_block and modifies_or_declares(node.false_block, symbol_names))
-                )
-            elif isinstance(node, ast.KernelFunction):
-                return False
-            else:
-                defs = {s.name for s in node.symbols_defined}
-                return bool(symbol_names.intersection(defs))
-
-        dependencies = {s.name for s in node.undefined_symbols}
-
         last_block = node.parent
         last_block_child = node
         element = node.parent
         prev_element = node
-
         while element:
-            if isinstance(element, (ast.Conditional, ast.KernelFunction)):
-                # Never move out of Conditionals or KernelFunctions.
-                break
-
-            elif isinstance(element, ast.Block):
+            if isinstance(element, ast.Block):
                 last_block = element
                 last_block_child = prev_element
 
-                if any(modifies_or_declares(sibling, dependencies) for sibling in element.args):
-                    # The node depends on one of the statements in this block.
-                    # Do not move further out.
-                    break
-
-            elif isinstance(element, ast.LoopOverCoordinate) :
-                if element.loop_counter_symbol.name in dependencies:
-                    # The node depends on the loop counter.
-                    # Do not move out of this loop.
-                    break
-            elif isinstance(element, ast.ForLoop) :
-                if element.ctr_to_loop_over.name in dependencies:
-                    # The node depends on the loop counter.
-                    # Do not move out of this loop.
-                    break
-
+            if isinstance(element, ast.Conditional):
+                break
             else:
-                raise NotImplementedError(f'Due to defensive programming we handle only specific expressions.\n'
-                                          f'The expression {element} of type {type(element)} is not known yet.')
-
-            # No dependencies to symbols defined/modified within the current element.
-            # We can move the node up one level and in front of the current element.
+                critical_symbols = set([s.name for s in element.symbols_defined])
+            if set([s.name for s in node.undefined_symbols]).intersection(critical_symbols):
+                break
             prev_element = element
             element = element.parent
         return last_block, last_block_child
@@ -679,13 +630,16 @@ def move_constants_before_loop(ast_node, rename_moved_consts = False, lhs_symbol
         consts_moved_subs = {}
 
         for child in children:
-            child.subs(consts_moved_subs)
 
             if not isinstance(child, ast.SympyAssignment):  # only move SympyAssignments
                 block.append(child)
                 continue
 
-            if isinstance(child, ast.SympyAssignment) and (lhs_symbol_ignore_predicate(child.lhs) or isinstance(child.lhs, ResolvedFieldAccess)):
+            if isinstance(child, ast.SympyAssignment) and lhs_symbol_ignore_predicate(child.lhs):
+                block.append(child)
+                continue
+
+            if isinstance(child, ast.SympyAssignment) and isinstance(child.lhs, ResolvedFieldAccess):  # dont move field accesses
                 block.append(child)
                 continue
 
@@ -702,10 +656,10 @@ def move_constants_before_loop(ast_node, rename_moved_consts = False, lhs_symbol
                 old_symbol = deepcopy(child.lhs)
                 if rename_moved_consts:
                     moved_symbol = TypedSymbol(old_symbol.name + "_mov" + str(moves_ctr), old_symbol.dtype)
-                    moved_nodes.add(moved_symbol)
-                    consts_moved_subs.update({old_symbol: moved_symbol})
+                    moved_nodes.add(moved_symbol.name)
+                    consts_moved_subs.update({old_symbol : moved_symbol})
                 else:
-                    moved_nodes.add(child.lhs)
+                    moved_nodes.add(child.lhs.name)
 
                 if not exists_already:
                     target.insert_before(child, child_to_insert_before)
@@ -720,13 +674,18 @@ def move_constants_before_loop(ast_node, rename_moved_consts = False, lhs_symbol
                     # -> symbol has to be renamed
                     assert isinstance(child.lhs, TypedSymbol)
                     new_symbol = TypedSymbol(sp.Dummy().name, child.lhs.dtype)
+                    moved_nodes.add(new_symbol.name)
                     target.insert_before(ast.SympyAssignment(new_symbol, child.rhs, is_const=child.is_const),
                                          child_to_insert_before)
-                    consts_moved_subs.update({old_symbol: new_symbol})
+                    #block.append(ast.SympyAssignment(child.lhs, new_symbol, is_const=child.is_const))
+                    consts_moved_subs.update({old_symbol : new_symbol})
 
+        if bool(consts_moved_subs):
+            for child in children:
+                child.subs(consts_moved_subs)
+            moves_ctr += 1
     return moved_nodes
 
-
 def split_inner_loop(ast_node: ast.Node, symbol_groups):
     """
     Splits inner loop into multiple loops to minimize the amount of simultaneous load/store streams
@@ -801,7 +760,7 @@ def split_inner_loop(ast_node: ast.Node, symbol_groups):
         outer_loop.parent.append(free_node)
 
 
-def cut_loop(loop_node, cutting_points, with_conditional: bool = False):
+def cut_loop(loop_node, cutting_points, with_conditional : bool = False):
     """Cuts loop at given cutting points.
 
     One loop is transformed into len(cuttingPoints)+1 new loops that range from
@@ -824,7 +783,7 @@ def cut_loop(loop_node, cutting_points, with_conditional: bool = False):
             new_body.subs({loop_node.loop_counter_symbol: new_start})
             if with_conditional:
                 conditional_expr = sp.And(sp.Ge(new_start, loop_node.start), sp.Le(new_start, loop_node.stop))
-                new_loops.append(ast.Conditional(conditional_expr, new_body))
+                new_loops.append(Conditional(conditional_expr, new_body))
             else:
                 new_loops.append(new_body)
         elif new_end - new_start == 0:
diff --git a/pystencils/typing/leaf_typing.py b/pystencils/typing/leaf_typing.py
index ff1ebe6309e71161f91b70b305c9db44aa168e33..7d05723b69d4d8c2f4651d42e224bc5612533624 100644
--- a/pystencils/typing/leaf_typing.py
+++ b/pystencils/typing/leaf_typing.py
@@ -10,6 +10,7 @@ from sympy.core.relational import Relational
 from sympy.functions.elementary.piecewise import ExprCondPair
 from sympy.functions.elementary.trigonometric import TrigonometricFunction, InverseTrigonometricFunction
 from sympy.functions.elementary.hyperbolic import HyperbolicFunction
+from sympy.codegen import Assignment
 from sympy.logic.boolalg import BooleanFunction
 from sympy.logic.boolalg import BooleanAtom
 
@@ -50,7 +51,7 @@ class TypeAdder:
     def visit(self, obj):
         if isinstance(obj, (list, tuple)):
             return [self.visit(e) for e in obj]
-        if isinstance(obj, ast.SympyAssignment):
+        if isinstance(obj, (sp.Eq, ast.SympyAssignment, Assignment)):
             return self.process_assignment(obj)
         elif isinstance(obj, ast.Conditional):
             condition, condition_type = self.figure_out_type(obj.condition_expr)
@@ -61,6 +62,8 @@ class TypeAdder:
             return ast.Conditional(condition, true_block=true_block, false_block=false_block)
         elif isinstance(obj, ast.Block):
             return ast.Block([self.visit(e) for e in obj.args])
+        elif isinstance(obj, ast.ArrayDeclaration):
+             return ast.ArrayDeclaration(obj.lhs, [self.figure_out_type(e)[0] for e in obj._entries])
         elif isinstance(obj, ast.LoopOverCoordinate):
             return ast.LoopOverCoordinate(ast.Block([self.visit(e) for e in obj.body.args]), obj.coordinate_to_loop_over, obj.start,
                                obj.stop)
@@ -71,7 +74,7 @@ class TypeAdder:
         else:
             raise ValueError("Invalid object " + str(obj) + " in kernel " + str(type(obj)))
 
-    def process_assignment(self, assignment: ast.SympyAssignment) -> ast.SympyAssignment:
+    def process_assignment(self, assignment: Union[sp.Eq, ast.SympyAssignment, Assignment]) -> ast.SympyAssignment:
         # for checks it is crucial to process rhs before lhs to catch e.g. a = a + 1
         new_rhs, rhs_type = self.figure_out_type(assignment.rhs)
 
@@ -84,12 +87,16 @@ class TypeAdder:
         new_lhs, lhs_type = self.figure_out_type(lhs)
         assert isinstance(new_lhs, (Field.Access, TypedSymbol))
 
+        # take over assignments qualifiers if they have, use std-initializers else
+        const_qualifier = assignment.is_const if isinstance(assignment, ast.SympyAssignment) else True
+        auto_qualifier = assignment.use_auto if isinstance(assignment, ast.SympyAssignment) else False
+
         if lhs_type != rhs_type:
-            logging.debug(f'Lhs"{new_lhs} of type "{lhs_type}" is assigned with a different datatype '
-                          f'rhs: "{new_rhs}" of type "{rhs_type}".')
-            return ast.SympyAssignment(new_lhs, CastFunc(new_rhs, lhs_type), assignment.is_const, assignment.use_auto)
+            logging.warning(f'Lhs"{new_lhs} of type "{lhs_type}" is assigned with a different datatype '
+                            f'rhs: "{new_rhs}" of type "{rhs_type}".')
+            return ast.SympyAssignment(new_lhs, CastFunc(new_rhs, lhs_type), const_qualifier, auto_qualifier)
         else:
-            return ast.SympyAssignment(new_lhs, new_rhs, assignment.is_const, assignment.use_auto)
+            return ast.SympyAssignment(new_lhs, new_rhs, const_qualifier, auto_qualifier)
 
     # Type System Specification
     # - Defined Types: TypedSymbol, Field, Field.Access, ...?