diff --git a/integration/.gitignore b/integration/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c585e19389d195ff2268d354ecf676d738a578de
--- /dev/null
+++ b/integration/.gitignore
@@ -0,0 +1 @@
+out
\ No newline at end of file
diff --git a/integration/CMakeDemo/.gitignore b/integration/CMakeDemo/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..facd9a12fc110d698803cb3e8b6a34b9f00f142c
--- /dev/null
+++ b/integration/CMakeDemo/.gitignore
@@ -0,0 +1 @@
+.cmake
\ No newline at end of file
diff --git a/integration/CMakeDemo/CMakeLists.txt b/integration/CMakeDemo/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b69ff9aec9fe93af6d5364edb80cff67a51a5ba0
--- /dev/null
+++ b/integration/CMakeDemo/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required( VERSION 3.24 )
+
+project( pssfg_cmake_integration_test )
+
+set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${pssfg_cmake_integration_test_SOURCE_DIR}/.cmake )
+
+#   Don't try this at home!
+file(MAKE_DIRECTORY .cmake)
+execute_process( COMMAND sfg-cli cmake make-find-module
+                 WORKING_DIRECTORY ${pssfg_cmake_integration_test_SOURCE_DIR}/.cmake )
+
+find_package( PystencilsSfg REQUIRED )
+
+set( PystencilsSfg_CONFIG_MODULE codegen_config.py )
+
+add_library( genlib )
+pystencilssfg_generate_target_sources( genlib SCRIPTS kernels.py FILE_EXTENSIONS .h .cpp )
+pystencilssfg_generate_target_sources( genlib SCRIPTS more_kernels.py )
diff --git a/integration/CMakeDemo/codegen_config.py b/integration/CMakeDemo/codegen_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..8162ae460328ab0229f422c3ec9d63522106a78b
--- /dev/null
+++ b/integration/CMakeDemo/codegen_config.py
@@ -0,0 +1,6 @@
+from pystencilssfg import SfgConfig
+
+
+def configure(cfg: SfgConfig):
+    cfg.extensions.header = "h++"
+    cfg.extensions.impl = "c++"
diff --git a/integration/CMakeDemo/kernels.py b/integration/CMakeDemo/kernels.py
new file mode 100644
index 0000000000000000000000000000000000000000..517c7e0f512761c2cd08842ca5d1a9cd1924edba
--- /dev/null
+++ b/integration/CMakeDemo/kernels.py
@@ -0,0 +1,23 @@
+# type: ignore
+
+import sympy as sp
+
+from pystencils import fields, kernel
+
+from pystencilssfg import SourceFileGenerator, SfgComposer
+
+
+with SourceFileGenerator() as ctx:
+    sfg = SfgComposer(ctx)
+
+    src, dst = fields("src, dst(1) : double[2D]")
+
+    @kernel
+    def poisson_jacobi():
+        dst[0, 0] @= (src[1, 0] + src[-1, 0] + src[0, 1] + src[0, -1]) / 4
+
+    poisson_kernel = sfg.kernels.create(poisson_jacobi)
+
+    sfg.function("jacobi_smooth")(
+        sfg.call(poisson_kernel)
+    )
diff --git a/integration/CMakeDemo/more_kernels.py b/integration/CMakeDemo/more_kernels.py
new file mode 100644
index 0000000000000000000000000000000000000000..5fbd6addccb66596c289ef9abc38b7baf772226b
--- /dev/null
+++ b/integration/CMakeDemo/more_kernels.py
@@ -0,0 +1,24 @@
+# type: ignore
+
+import sympy as sp
+
+from pystencils import fields, kernel, Field
+
+from pystencilssfg import SourceFileGenerator, SfgComposer
+
+with SourceFileGenerator() as ctx:
+    sfg = SfgComposer(ctx)
+
+    src: Field = fields("src: double[2D]")
+
+    h = sp.Symbol('h')
+
+    @kernel
+    def poisson_gs():
+        src[0, 0] @= (src[1, 0] + src[-1, 0] + src[0, 1] + src[0, -1]) / 4
+
+    poisson_kernel = sfg.kernels.create(poisson_gs)
+
+    sfg.function("gs_smooth")(
+        sfg.call(poisson_kernel)
+    )
diff --git a/integration/MakeDemo/Makefile b/integration/MakeDemo/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5a2fb0e99793bf2bcb0665ddc87a8051f48e36f9
--- /dev/null
+++ b/integration/MakeDemo/Makefile
@@ -0,0 +1,36 @@
+
+CXX := clang++
+CXX_FLAGS := -DDEBUG -g -std=c++2b -I/home/fhennig/lssgit/mdspan/include
+
+PYTHON := python
+
+MKDIR := mkdir -p
+dir_guard = $(MKDIR) $(@D)	
+
+OBJ := obj
+BIN := bin
+GEN_SRC := generated_src
+
+.PHONY: all clean
+
+all: $(BIN)/mdspan_test
+
+clean: 
+	rm -rf $(BIN) $(OBJ) $(GEN_SRC)
+
+$(GEN_SRC)/kernels.cpp $(GEN_SRC)/kernels.h &: kernels.py
+	@$(dir_guard)
+	$(PYTHON) $< --sfg-output-dir $(@D)
+
+$(OBJ)/kernels.o: $(GEN_SRC)/kernels.cpp $(GEN_SRC)/kernels.h
+	@$(dir_guard)
+	$(CXX) $(CXX_FLAGS) -c -o $@ $<
+
+$(OBJ)/main.o: main.cpp $(GEN_SRC)/kernels.h
+	@$(dir_guard)
+	$(CXX) $(CXX_FLAGS) -c -o $@ $<
+
+$(BIN)/mdspan_test: $(OBJ)/kernels.o $(OBJ)/main.o
+	@$(dir_guard)
+	$(CXX) $(CXX_FLAGS) -o $@ $^
+
diff --git a/integration/MakeDemo/kernels.py b/integration/MakeDemo/kernels.py
new file mode 100644
index 0000000000000000000000000000000000000000..87f2920b5c788a5031ddbe67a71e788a980183c7
--- /dev/null
+++ b/integration/MakeDemo/kernels.py
@@ -0,0 +1,39 @@
+# type: ignore
+
+import sympy as sp
+
+from pystencils import fields, kernel
+
+from pystencilssfg import SourceFileGenerator, SfgConfiguration, SfgComposer
+from pystencilssfg.lang.cpp import mdspan_ref
+
+sfg_config = SfgConfiguration(
+    outer_namespace="make_demo"
+)
+
+with SourceFileGenerator(sfg_config) as ctx:
+    sfg = SfgComposer(ctx)
+    
+    sfg.prelude("""Generated by the pystencils Source File Generator.
+
+Author: Frederik Hennig <frederik.hennig@fau.de>""")
+    
+    sfg.define("using namespace std;")
+    
+    sfg.namespace("jacobi")
+
+    u_src, u_dst, f = fields("u_src, u_dst, f : double[2D]", layout="fzyx")
+    h = sp.Symbol("h")
+
+    @kernel
+    def poisson_jacobi():
+        u_dst[0,0] @= (h**2 * f[0, 0] * u_src[1, 0] + u_src[-1, 0] + u_src[0, 1] + u_src[0, -1]) / 4
+
+    poisson_kernel = sfg.kernels.create(poisson_jacobi)
+
+    sfg.function("jacobi_smooth")(
+        sfg.map_field(u_src, mdspan_ref(u_src)),
+        sfg.map_field(u_dst, mdspan_ref(u_dst)),
+        sfg.map_field(f, mdspan_ref(f)),
+        sfg.call(poisson_kernel)
+    )
diff --git a/integration/MakeDemo/main.cpp b/integration/MakeDemo/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..033261f0f090d0e6ed1bfeec2d999e29a7ac8e90
--- /dev/null
+++ b/integration/MakeDemo/main.cpp
@@ -0,0 +1,62 @@
+#include <iostream>
+#include <fstream>
+
+#include <cstdint>
+#include <vector>
+
+#include <experimental/mdspan>
+
+#include "generated_src/kernels.h"
+
+using field_t = std::mdspan< double, std::extents< uint32_t, std::dynamic_extent, std::dynamic_extent > >;
+
+double boundary(double x, double y){
+    return 1.0;
+}
+
+int main(int argc, char ** argv){
+    uint32_t N = 8; /* number of grid nodes */
+    double h = 1.0 / (double(N) - 1);
+    uint32_t n_iters = 100;
+
+    std::vector< double > data_src(N*N);
+    field_t src(data_src.data(), N, N);
+
+    std::vector< double > data_dst(N*N);
+    field_t dst(data_dst.data(), N, N);
+
+    std::vector< double > data_f(N*N);
+    field_t f(data_f.data(), N, N);
+
+    for(uint32_t i = 0; i < N; ++i){
+        for(uint32_t j = 0; j < N; ++j){
+            if(i == 0 || j == 0 || i == N-1 || j == N-1){
+                src[i, j] = boundary(double(i) * h, double(j) * h);
+                dst[i, j] = boundary(double(i) * h, double(j) * h);
+                f[i, j] = 0.0;
+            }
+        }
+    }
+    
+    for(uint32_t i = 0; i < n_iters; ++i){
+        make_demo::jacobi::jacobi_smooth(f, h, dst, src);
+        std::swap(src, dst);
+    }
+
+    std::ofstream file("data.out", std::ios::trunc | std::ios::out);
+
+    if(!file.is_open()){
+        std::cerr << "Could not open output file.\n";
+    } else {
+        for(uint32_t i = 0; i < N; ++i){
+            for(uint32_t j = 0; j < N; ++j){
+                file << src[i, j] << " ";
+            }
+            file << '\n';
+        }
+    }
+
+    file.close();
+
+    return 0;
+}
diff --git a/integration/TestSequencing.py b/integration/TestSequencing.py
new file mode 100644
index 0000000000000000000000000000000000000000..b25593a114082ab419de632b48478b0770f079b6
--- /dev/null
+++ b/integration/TestSequencing.py
@@ -0,0 +1,24 @@
+from pystencilssfg import SourceFileGenerator, SfgComposer
+
+from lbmpy.advanced_streaming import Timestep
+from lbmpy import LBMConfig, create_lb_ast
+
+with SourceFileGenerator() as ctx:
+    sfg = SfgComposer(ctx)
+
+    lb_config = LBMConfig(streaming_pattern='esotwist')
+
+    lb_ast_even = create_lb_ast(lbm_config=lb_config, timestep=Timestep.EVEN)
+
+    lb_ast_odd = create_lb_ast(lbm_config=lb_config, timestep=Timestep.ODD)
+
+    kernel_even = sfg.kernels.add(lb_ast_even, "lb_even")
+    kernel_odd = sfg.kernels.add(lb_ast_odd, "lb_odd")
+
+    sfg.function("myFunction")(
+        sfg.branch("(timestep & 1) ^ 1")(
+            sfg.call(kernel_even)
+        )(
+            sfg.call(kernel_odd)
+        )
+    )
diff --git a/integration/__init__.py b/integration/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/integration/test_class_composer.py b/integration/test_class_composer.py
new file mode 100644
index 0000000000000000000000000000000000000000..2a028b0e48175dc950798006fdf02ace1f408a9a
--- /dev/null
+++ b/integration/test_class_composer.py
@@ -0,0 +1,53 @@
+# type: ignore
+from pystencilssfg import SourceFileGenerator, SfgConfiguration, SfgComposer
+from pystencilssfg.configuration import SfgCodeStyle
+from pystencilssfg.composer import SfgClassComposer
+
+from pystencils import fields, kernel
+
+sfg_config = SfgConfiguration(
+    output_directory="out/test_class_composer",
+    outer_namespace="gen_code",
+    codestyle=SfgCodeStyle(
+        code_style="Mozilla",
+        force_clang_format=True
+    )
+)
+
+f, g = fields("f, g(1): double[2D]")
+
+with SourceFileGenerator(sfg_config) as ctx:
+    sfg = SfgComposer(ctx)
+
+    @kernel
+    def assignments():
+        f[0, 0] @= 3 * g[0, 0]
+
+    khandle = sfg.kernels.create(assignments)
+
+    sfg.struct("DataStruct")(
+        sfg.var("coord", "uint32_t"),
+        sfg.var("value", "float")
+    ),
+
+    sfg.klass("MyClass", bases=("MyBaseClass",))(
+        # class body sequencer
+
+        sfg.constructor(sfg.var("a", "int"))
+        .init("a_(a)")
+        .body(
+            'cout << "Hi!" << endl;'
+        ),
+
+        sfg.private(
+            sfg.var("a_", "int"),
+
+            sfg.method("getX", returns="int")(
+                "return 2.0;"
+            )
+        ),
+
+        sfg.public(
+            "using xtype = uint8_t;"
+        )
+    )
diff --git a/integration/test_classes.py b/integration/test_classes.py
new file mode 100644
index 0000000000000000000000000000000000000000..4be345197965ae8b15353f3ce0471e265d28b35d
--- /dev/null
+++ b/integration/test_classes.py
@@ -0,0 +1,68 @@
+# type: ignore
+from pystencilssfg import SourceFileGenerator, SfgConfiguration, SfgComposer
+from pystencilssfg.configuration import SfgCodeStyle
+from pystencils.types import PsCustomType
+from pystencilssfg.ir.source_components import SfgClass, SfgMemberVariable, SfgConstructor, SfgMethod
+
+from pystencils import fields, kernel
+
+sfg_config = SfgConfiguration(
+    output_directory="out/test_classes",
+    outer_namespace="gen_code",
+    codestyle=SfgCodeStyle(
+        code_style="Mozilla",
+        force_clang_format=True
+    )
+)
+
+f, g = fields("f, g(1): double[2D]")
+
+with SourceFileGenerator(sfg_config) as ctx:
+    sfg = SfgComposer(ctx)
+
+    @kernel
+    def assignments():
+        f[0,0] @= 3 * g[0,0]
+
+    khandle = sfg.kernels.create(assignments)
+
+    cls = SfgClass("MyClass")
+    cls.default.append_member(SfgMethod(
+        "callKernel",
+        sfg.call(khandle)
+    ))
+
+    cls.default.append_member(SfgMethod(
+        "inlineConst",
+        sfg.seq(
+            "return -1.0;"
+        ),
+        return_type="double",
+        inline=True,
+        const=True
+    ))
+
+    cls.default.append_member(SfgMethod(
+        "awesomeMethod",
+        sfg.seq(
+            "return 2.0f;"
+        ),
+        return_type="float",
+        inline=False,
+        const=True
+    ))
+
+    cls.default.append_member(
+        SfgMemberVariable(
+            "stuff", PsCustomType("std::vector< int > &")
+        )
+    )
+
+    cls.default.append_member(
+        SfgConstructor(
+            [sfg.var("stuff", PsCustomType("std::vector< int > &"))],
+            ["stuff_(stuff)"]
+        )
+    )
+
+    sfg.context.add_class(cls)
diff --git a/integration/test_cuda.py b/integration/test_cuda.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b1f1f439c6dc3adbbca73f8a56f676ac9951ef2
--- /dev/null
+++ b/integration/test_cuda.py
@@ -0,0 +1,16 @@
+from pystencils import Target, CreateKernelConfig, no_jit
+from lbmpy import create_lb_update_rule, LBMOptimisation
+from pystencilssfg import SourceFileGenerator, SfgConfig
+
+sfg_config = SfgConfig()
+sfg_config.extensions.impl = "cu"
+sfg_config.output_directory = "out/test_cuda"
+sfg_config.outer_namespace = "gen_code"
+
+with SourceFileGenerator(sfg_config) as sfg:
+    gen_config = CreateKernelConfig(target=Target.CUDA, jit=no_jit)
+    opt = LBMOptimisation(field_layout="fzyx")
+    update = create_lb_update_rule()
+    kernel = sfg.kernels.create(update, "lbm_update", gen_config)
+
+    sfg.function("lb_update")(sfg.call(kernel))
diff --git a/integration/test_sycl.py b/integration/test_sycl.py
new file mode 100644
index 0000000000000000000000000000000000000000..d49edc71bbf8c10afa57bb7abbe9240043f00c5b
--- /dev/null
+++ b/integration/test_sycl.py
@@ -0,0 +1,21 @@
+from pystencils import Target, CreateKernelConfig, create_kernel, no_jit
+from lbmpy import create_lb_update_rule, LBMOptimisation
+from pystencilssfg import SourceFileGenerator, SfgConfiguration, SfgOutputMode
+from pystencilssfg.lang.cpp import mdspan_ref
+
+sfg_config = SfgConfiguration(
+    output_directory="out/test_sycl",
+    outer_namespace="gen_code",
+    impl_extension="ipp",
+    output_mode=SfgOutputMode.INLINE
+)
+
+with SourceFileGenerator(sfg_config) as sfg:
+    gen_config = CreateKernelConfig(target=Target.SYCL, jit=no_jit)
+    opt = LBMOptimisation(field_layout="fzyx")
+    update = create_lb_update_rule()
+    kernel = sfg.kernels.create(update, "lbm_update", gen_config)
+
+    sfg.function("lb_update")(
+        sfg.call(kernel)
+    )
diff --git a/integration/test_sycl_buffer.py b/integration/test_sycl_buffer.py
new file mode 100644
index 0000000000000000000000000000000000000000..a1e52eb85af599814a2192b726afd4aae2fd084d
--- /dev/null
+++ b/integration/test_sycl_buffer.py
@@ -0,0 +1,33 @@
+from pystencils import Target, CreateKernelConfig, no_jit
+from lbmpy import create_lb_update_rule, LBMOptimisation
+from pystencilssfg import SourceFileGenerator, SfgConfig, OutputMode
+from pystencilssfg.lang.cpp.sycl_accessor import sycl_accessor_ref
+import pystencilssfg.extensions.sycl as sycl
+from itertools import chain
+
+sfg_config = SfgConfig(
+    output_directory="out/test_sycl_buffer",
+    outer_namespace="gen_code",
+    output_mode=OutputMode.INLINE,
+)
+
+with SourceFileGenerator(sfg_config) as sfg:
+    sfg = sycl.SyclComposer(sfg)
+    gen_config = CreateKernelConfig(target=Target.SYCL, jit=no_jit)
+    opt = LBMOptimisation(field_layout="fzyx")
+    update = create_lb_update_rule(lbm_optimisation=opt)
+    kernel = sfg.kernels.create(update, "lbm_update", gen_config)
+
+    cgh = sfg.sycl_handler("handler")
+    rang = sfg.sycl_range(update.method.dim, "range")
+    mappings = [
+        sfg.map_field(field, sycl_accessor_ref(field))
+        for field in chain(update.free_fields, update.bound_fields)
+    ]
+
+    sfg.function("lb_update")(
+        cgh.parallel_for(rang)(
+            *mappings,
+            sfg.call(kernel),
+        ),
+    )