diff --git a/README.md b/README.md
index eb1804cb69bc4b56b0152ed097b0b61033f8931c..b396dbad7a2d1b892b0aa64d6a7f257ee5b23379 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,2 @@
 # pc-setup-scripts
-
-## todos
+This tool installs and updates applications and packages using various package managers.
diff --git a/ansible_inventory.ini b/ansible_inventory.ini
new file mode 100644
index 0000000000000000000000000000000000000000..7053747879ef874fdca7d0596433da98adfc616d
--- /dev/null
+++ b/ansible_inventory.ini
@@ -0,0 +1,2 @@
+[local]
+localhost ansible_connection=local ansible_python_interpreter=/usr/bin/python3
diff --git a/defaults.sh b/defaults.sh
deleted file mode 100644
index 6a0c4b14f9438b06781e25ff3b96375cecf6bedc..0000000000000000000000000000000000000000
--- a/defaults.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-set -e
-source installer_vars.sh
-source install_functions.sh
-source setup_functions.sh
-source source_if_options_not_sourced.sh
-source_if_options_not_sourced
-
-
-# make dirs
-setup_paths
-
-
-# install programs
-vs_code_enabled=$checkbox_checked
-spotify_enabled=$checkbox_checked
-gimp_enabled=$checkbox_checked
-curl_enabled=$checkbox_checked
-kdiff3_enabled=$checkbox_checked
-git_enabled=$checkbox_checked
-mono_complete_enabled=$checkbox_checked
-virtualbox_enabled=$checkbox_checked
-vlc_enabled=$checkbox_checked
-docker_io_enabled=$checkbox_checked
-kubectl_enabled=$checkbox_checked
-net_tools_enabled=$checkbox_checked
-k3d_enabled=$checkbox_checked
-# git_extensions_enabled=$checkbox_checked
-set_dark_theme_enabled=$checkbox_checked
-set_idle_delay_enabled=$checkbox_checked
-pip_enabled=$checkbox_checked
-virtualenv_enabled=$checkbox_checked
-nano_enabled=$checkbox_checked
-
-source install.sh
diff --git a/dotnet_apt_preferences/aspnet b/dotnet_apt_preferences/aspnet
deleted file mode 100644
index 86c0810ac82b842c7d07c1331e235b2ec27a14a2..0000000000000000000000000000000000000000
--- a/dotnet_apt_preferences/aspnet
+++ /dev/null
@@ -1,3 +0,0 @@
-Package: aspnet*
-Pin: origin packages.microsoft.com
-Pin-Priority: 1001
diff --git a/dotnet_apt_preferences/dotnet b/dotnet_apt_preferences/dotnet
deleted file mode 100644
index dabf23ed2a4b67da21ee32132bdbd11000b455c7..0000000000000000000000000000000000000000
--- a/dotnet_apt_preferences/dotnet
+++ /dev/null
@@ -1,3 +0,0 @@
-Package: dotnet*
-Pin: origin packages.microsoft.com
-Pin-Priority: 1001
diff --git a/empty.sh b/empty.sh
deleted file mode 100644
index 78d1c98c1240b37da1f584b66cf1312acb2de62e..0000000000000000000000000000000000000000
--- a/empty.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-set -e
-source installer_vars.sh
-source source_if_options_not_sourced.sh
-source install_functions.sh
-source_if_options_not_sourced
-
-check_if_root
-source install.sh
diff --git a/helper_scripts/install_ansible.sh b/helper_scripts/install_ansible.sh
new file mode 100644
index 0000000000000000000000000000000000000000..20089589efdeba04305f19d613744b77e5c24243
--- /dev/null
+++ b/helper_scripts/install_ansible.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+if ! command -v ansible &> /dev/null; then
+    echo "Installing ansible"
+    sudo apt-add-repository --yes --update ppa:ansible/ansible
+    sudo apt update
+    sudo apt install -y ansible
+    echo "Ansible successfully installed"
+fi
diff --git a/helper_scripts/package_manager_identifiers.sh b/helper_scripts/package_manager_identifiers.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f5cfa055666ef76161e2565df0dab0bd04ab3887
--- /dev/null
+++ b/helper_scripts/package_manager_identifiers.sh
@@ -0,0 +1,5 @@
+APT_IDENTIFIER="apt"
+SNAP_IDENTIFIER="snap"
+FLATPAK_IDENTIFIER="flatpak"
+RAW_IDENTIFIER="raw"
+MAINLINE_KERNEL_IDENTIFIER="mainline-kernel"
diff --git a/install.sh b/install.sh
index 353ace08fe43688fbc056cc1edded49f1642c138..ee2047b28895635177c8cf2172a365f313d76fdb 100644
--- a/install.sh
+++ b/install.sh
@@ -1,198 +1,321 @@
-source source_if_options_not_sourced.sh
-source install_functions.sh
-source setup_functions.sh
-source_if_options_not_sourced
-
-check_if_root
-
-items=29
-selected_tags=$(whiptail "Select options" --checklist --notags $(($items + 10)) 100 $items \
-$firefox_key "$firefox_label" $firefox_enabled \
-$vs_code_key "$vs_code_label" $vs_code_enabled \
-$spotify_key "$spotify_label" $spotify_enabled \
-$gimp_key "$gimp_label" $gimp_enabled \
-$curl_key "$curl_label" $curl_enabled \
-$kdiff3_key "$kdiff3_label" $kdiff3_enabled \
-$git_key "$git_label" $git_enabled \
-$mono_complete_key "$mono_complete_label" $mono_complete_enabled \
-$virtualbox_key "$virtualbox_label" $virtualbox_enabled \
-$vlc_key "$vlc_label" $vlc_enabled \
-$docker_io_key "$docker_io_label" $docker_io_enabled \
-$kubectl_key "$kubectl_label" $kubectl_enabled \
-$net_tools_key "$net_tools_label" $net_tools_enabled \
-$k3d_key "$k3d_label" $k3d_enabled \
-$git_extensions_key "$git_extensions_label" $git_extensions_enabled \
-$set_dark_theme_key "$set_dark_theme_label" $set_dark_theme_enabled \
-$set_idle_delay_key "$set_idle_delay_label" $set_idle_delay_enabled \
-$flameshot_key "$flameshot_label" $flameshot_enabled \
-$intellij_idea_key "$intellij_idea_label" $intellij_idea_enabled \
-$linssid_key "$linssid_label" $linssid_enabled \
-$docker_ce_key "$docker_ce_label" $docker_ce_enabled \
-$dl_driver_key "$dl_driver_label" $dl_driver_enabled \
-$obsidian_key "$obsidian_label" $obsidian_enabled \
-$staruml_key "$staruml_label" $staruml_enabled \
-$node_key "$node_label" $node_enabled \
-$webstorm_key "$webstorm_label" $webstorm_enabled \
-$dotnet_key "$dotnet_label" $dotnet_enabled \
-$ilspy_key "$ilspy_label" $ilspy_enabled \
-$android_studio_key "$android_studio_label" $android_studio_enabled \
-$pip_key "$pip_label" $pip_enabled \
-$virtualenv_key "$virtualenv_label" $virtualenv_enabled \
-$rider_key "$rider_label" $rider_enabled \
-$nextcloud_client_key "$nextcloud_client_label" $nextcloud_client_enabled \
-$nano_key "$nano_label" $nano_enabled \
-$element_desktop_key "$element_desktop_label" $element_desktop_enabled \
-$dconf_editor_key "$dconf_editor_label" $dconf_editor_enabled \
-$openssh_server_key "$openssh_server_label" $openssh_server_enabled \
-$openconnect_key "$openconnect_label" $openconnect_enabled \
-$protonvpn_key "$protonvpn_label" $protonvpn_enabled \
-$flatseal_key "$flatseal_label" $flatseal_enabled \
-$wireguard_key "$wireguard_label" $wireguard_enabled \
-$remmina_key "$remmina_label" $remmina_enabled \
-$mainline_key "$mainline_label" $mainline_enabled \
-$swap_key "$swap_label" $swap_enabled \
-3>&1 1>&2 2>&3)
-IFS=' ' read -a selected_options <<< $selected_tags
-
-update_upgrade
-setup_paths
-
-for selected_option in "${selected_options[@]}"
-do
-    option="${selected_option%\"}"
-    option="${option#\"}"
-
-    if [ $option = $firefox_key ]
-    then
-        install_firefox
-    elif [ $option = $vs_code_key ]
-    then
-        install_vs_code
-    elif [ $option = $spotify_key ]
-    then
-        install_spotify
-    elif [ $option = $gimp_key ]
-    then
-        install_gimp
-    elif [ $option = $curl_key ]
-    then
-        install_curl
-    elif [ $option = $kdiff3_key ]
-    then
-        install_kdiff3
-    elif [ $option = $git_key ]
-    then
-        install_git
-    elif [ $option = $mono_complete_key ]
-    then
-        install_mono_complete
-    elif [ $option = $virtualbox_key ]
-    then
-        install_virtualbox
-    elif [ $option = $vlc_key ]
-    then
-        install_vlc
-    elif [ $option = $docker_io_key ]
-    then
-        install_docker
-    elif [ $option = $kubectl_key ]
-    then
-        install_kubectl
-    elif [ $option = $net_tools_key ]
-    then
-        install_net_tools
-    elif [ $option = $k3d_key ]
-    then
-        install_k3d
-    elif [ $option = $git_extensions_key ]
-    then
-        install_git_extensions
-    elif [ $option = $set_dark_theme_key ]
-    then
-        setup_dark_mode
-    elif [ $option = $set_idle_delay_key ]
-    then
-        setup_idle_delay
-    elif [ $option = $flameshot_key ]
-    then
-        install_flameshot
-    elif [ $option = $intellij_idea_key ]
-    then
-        install_intellij_idea
-    elif [ $option = $linssid_key ]
-    then
-        install_linssid
-    elif [ $option = $docker_ce_key ]
-    then
-        install_docker_ce
-    elif [ $option = $dl_driver_key ]
-    then
-        install_dl_driver
-    elif [ $option = $obsidian_key ]
-    then
-        install_obsidian
-    elif [ $option = $staruml_key ]
-    then
-        install_staruml
-    elif [ $option = $node_key ]
-    then
-        install_node
-    elif [ $option = $webstorm_key ]
-    then
-        install_webstorm
-    elif [ $option = $dotnet_key ]
-    then
-        install_dotnet
-    elif [ $option = $ilspy_key ]
-    then
-        install_ilspy
-    elif [ $option = $android_studio_key ]
-    then
-        install_android_studio
-    elif [ $option = $pip_key ]
-    then
-        install_pip
-    elif [ $option = $virtualenv_key ]
-    then
-        install_virtualenv
-    elif [ $option = $rider_key ]
-    then
-        install_rider
-    elif [ $option = $nextcloud_client_key ]
-    then
-        install_nextcloud_client
-    elif [ $option = $nano_key ]
-    then
-        install_nano
-    elif [ $option = $element_desktop_key ]
-    then
-        install_element_desktop
-    elif [ $option = $dconf_editor_key ]
-    then
-        install_dconf_editor
-    elif [ $option = $openssh_server_key ]
-    then
-        install_dconf_editor
-    elif [ $option = $openconnect_key ]
-    then
-        install_openconnect
-    elif [ $option = $protonvpn_key ]
-    then
-        install_protonvpn
-    elif [ $option = $flatseal_key ]
-    then
-        install_flatseal
-    elif [ $option = $wireguard_key ]
-    then
-        install_wireguard
-    elif [ $option = $remmina_key ]
-    then
-        install_remmina
-    elif [ $option = $mainline_key ]
-    then
-        install_mainline_kernel
-    elif [ $option = $swap_key ]
-    then
-        setup_swap
+#!/bin/bash
+set -e
+INSTALLER_DIR=$(dirname "${BASH_SOURCE[0]}")
+HELPER_SCRIPTS_DIR="$INSTALLER_DIR/helper_scripts"
+
+source "$HELPER_SCRIPTS_DIR/package_manager_identifiers.sh"
+
+# APT packages
+APT_GIT_PACKAGE="$APT_IDENTIFIER:git"
+APT_DOCKER_CE_PACKAGE="$APT_IDENTIFIER:docker-ce"
+APT_VIRTUALBOX_PACKAGE="$APT_IDENTIFIER:virtualbox"
+APT_VLC_PACKAGE="$APT_IDENTIFIER:vlc"
+APT_NET_TOOLS_PACKAGE="$APT_IDENTIFIER:net-tools"
+APT_DL_DRIVER_PACKAGE="$APT_IDENTIFIER:dl-driver"
+APT_PROTONVPN_PACKAGE="$APT_IDENTIFIER:proton-vpn"
+APT_WIREGUARDVPN_PACKAGE="$APT_IDENTIFIER:wireguard"
+APT_DCONF_EDITOR="$APT_IDENTIFIER:dconf-editor"
+
+# Snap packages
+SNAP_VSCODE_PACKAGE="$SNAP_IDENTIFIER:vscode"
+SNAP_RIDER_PACKAGE="$SNAP_IDENTIFIER:rider"
+SNAP_KUBECTL_PACKAGE="$SNAP_IDENTIFIER:kubectl"
+SNAP_FIREFOX_PACKAGE="$SNAP_IDENTIFIER:firefox"
+
+# Flatpak packages
+FLATPAK_IDEA_COMMUNITY_PACKAGE="$FLATPAK_IDENTIFIER:intellij-idea-community"
+FLATPAK_WEBSTORM_PACKAGE="$FLATPAK_IDENTIFIER:webstorm"
+FLATPAK_ANDROID_STUDIO_PACKAGE="$FLATPAK_IDENTIFIER:android-studio"
+FLATPAK_OBSIDIAN_PACKAGE="$FLATPAK_IDENTIFIER:obsidian"
+FLATPAK_SPOTIFY_PACKAGE="$FLATPAK_IDENTIFIER:spotify"
+FLATPAK_GIMP_PACKAGE="$FLATPAK_IDENTIFIER:gimp"
+FLATPAK_FLAMESHOT_PACKAGE="$FLATPAK_IDENTIFIER:flameshot"
+FLATPAK_NEXTCLOUD_CLIENT_PACKAGE="$FLATPAK_IDENTIFIER:nextcloud-client"
+FLATPAK_FLATSEAL_PACKAGE="$FLATPAK_IDENTIFIER:flatseal"
+FLATPAK_REMMINA_PACKAGE="$FLATPAK_IDENTIFIER:remmina"
+
+# Raw packages
+RAW_GITEXTENSIONS_PACKAGE="$RAW_IDENTIFIER:gitextensions"
+RAW_K3D_PACKAGE="$RAW_IDENTIFIER:k3d"
+
+# Mainline kernel
+MAINLINE_KERNEL_PACKAGE="$MAINLINE_KERNEL_IDENTIFIER"
+
+declare -A PACKAGES
+PACKAGES=(
+    ["$SNAP_VSCODE_PACKAGE"]="VS Code"
+    ["$FLATPAK_IDEA_COMMUNITY_PACKAGE"]="JetBrains IntelliJ IDEA Community"
+    ["$SNAP_RIDER_PACKAGE"]="JetBrains Rider"
+    ["$FLATPAK_WEBSTORM_PACKAGE"]="JetBrains WebStorm"
+    ["$FLATPAK_ANDROID_STUDIO_PACKAGE"]="Android Studio"
+    ["$APT_GIT_PACKAGE"]="Git"
+    ["$RAW_GITEXTENSIONS_PACKAGE"]="GitExtensions"
+    ["$APT_DOCKER_CE_PACKAGE"]="Docker Community Edition"
+    ["$RAW_K3D_PACKAGE"]="k3d"
+    ["$SNAP_KUBECTL_PACKAGE"]="kubectl"
+    ["$FLATPAK_OBSIDIAN_PACKAGE"]="Obsidian"
+    ["$FLATPAK_SPOTIFY_PACKAGE"]="Spotify"
+    ["$FLATPAK_GIMP_PACKAGE"]="GIMP"
+    ["$APT_VIRTUALBOX_PACKAGE"]="VirtualBox"
+    ["$APT_VLC_PACKAGE"]="VLC Media Player"
+    ["$APT_NET_TOOLS_PACKAGE"]="net-tools"
+    ["$FLATPAK_FLAMESHOT_PACKAGE"]="Flameshot"
+    ["$APT_DL_DRIVER_PACKAGE"]="DisplayLink Driver"
+    ["$FLATPAK_NEXTCLOUD_CLIENT_PACKAGE"]="Nextcloud Client"
+    ["$APT_PROTONVPN_PACKAGE"]="ProtonVPN"
+    ["$APT_WIREGUARDVPN_PACKAGE"]="WireGuard VPN"
+    ["$FLATPAK_FLATSEAL_PACKAGE"]="Flatseal"
+    ["$FLATPAK_REMMINA_PACKAGE"]="Remmina"
+    ["$SNAP_FIREFOX_PACKAGE"]="Firefox"
+    ["$MAINLINE_KERNEL_PACKAGE"]="Mainline Kernel"
+    ["$APT_DCONF_EDITOR"]="DConf Editor"
+)
+
+ORDERED_PACKAGES=( # Needed when order matters
+    "$SNAP_VSCODE_PACKAGE"
+    "$FLATPAK_IDEA_COMMUNITY_PACKAGE"
+    "$SNAP_RIDER_PACKAGE"
+    "$FLATPAK_WEBSTORM_PACKAGE"
+    "$FLATPAK_ANDROID_STUDIO_PACKAGE"
+    "$APT_GIT_PACKAGE"
+    "$RAW_GITEXTENSIONS_PACKAGE"
+    "$APT_DOCKER_CE_PACKAGE"
+    "$RAW_K3D_PACKAGE"
+    "$SNAP_KUBECTL_PACKAGE"
+    "$SNAP_FIREFOX_PACKAGE"
+    "$FLATPAK_OBSIDIAN_PACKAGE"
+    "$FLATPAK_SPOTIFY_PACKAGE"
+    "$FLATPAK_GIMP_PACKAGE"
+    "$APT_VIRTUALBOX_PACKAGE"
+    "$APT_VLC_PACKAGE"
+    "$APT_NET_TOOLS_PACKAGE"
+    "$FLATPAK_FLAMESHOT_PACKAGE"
+    "$APT_DL_DRIVER_PACKAGE"
+    "$FLATPAK_NEXTCLOUD_CLIENT_PACKAGE"
+    "$APT_PROTONVPN_PACKAGE"
+    "$APT_WIREGUARDVPN_PACKAGE"
+    "$FLATPAK_FLATSEAL_PACKAGE"
+    "$FLATPAK_REMMINA_PACKAGE"
+    "$APT_DCONF_EDITOR"
+    "$MAINLINE_KERNEL_PACKAGE"
+)
+
+declare -A NEEDS_VERSION
+NEEDS_VERSION=(
+    ["$APT_VIRTUALBOX_PACKAGE"]="https://www.virtualbox.org/wiki/Linux_Downloads|${PACKAGES["$APT_VIRTUALBOX_PACKAGE"]} version (e.g. 7.1)"
+    ["$RAW_GITEXTENSIONS_PACKAGE"]="https://github.com/gitextensions/gitextensions/releases|${PACKAGES["$RAW_GITEXTENSIONS_PACKAGE"]} version (e.g. 2.51.05)"
+    ["$APT_PROTONVPN_PACKAGE"]="https://protonvpn.com/support/official-linux-vpn-ubuntu|${PACKAGES["$APT_PROTONVPN_PACKAGE"]} Repository version (e.g. 1.0.6)"
+    ["$MAINLINE_KERNEL_PACKAGE"]="https://kernel.org/|Comma separated Kernel versions (e.g. 6.11.10)"
+)
+
+PACKAGES_WITH_GROUP=(
+    "$APT_DOCKER_CE_PACKAGE"
+    "$APT_VIRTUALBOX_PACKAGE"
+)
+
+declare -A BUGS
+BUGS=(
+    ["$FLATPAK_FLAMESHOT_PACKAGE"]="Can't take screenshot|open flameshot launcher, take screenshot from tray icon, allow permissions"
+    ["$APT_VIRTUALBOX_PACKAGE"]="VirtualBox Guest Additions can't be downloaded automatically in version 7.0|Download the VirtualBox Guest Additions for your VirtualBox version from https://download.virtualbox.org/virtualbox and mount them manually into the Virtual Machine"
+    ["$FLATPAK_NEXTCLOUD_CLIENT_PACKAGE"]="Nextcloud Client stops syncing|To debug the error, run \`flatpak run com.nextcloud.desktopclient.nextcloud\` in a terminal"
+)
+
+CAN_AUTOSTART=(
+    "$SNAP_VSCODE_PACKAGE"
+    "$FLATPAK_IDEA_COMMUNITY_PACKAGE"
+    "$SNAP_RIDER_PACKAGE"
+    "$FLATPAK_WEBSTORM_PACKAGE"
+    "$FLATPAK_ANDROID_STUDIO_PACKAGE"
+    "$RAW_GITEXTENSIONS_PACKAGE"
+    "$FLATPAK_OBSIDIAN_PACKAGE"
+    "$FLATPAK_SPOTIFY_PACKAGE"
+    "$FLATPAK_GIMP_PACKAGE"
+    "$APT_VIRTUALBOX_PACKAGE"
+    "$APT_VLC_PACKAGE"
+    "$FLATPAK_FLAMESHOT_PACKAGE"
+    "$FLATPAK_NEXTCLOUD_CLIENT_PACKAGE"
+    "$APT_PROTONVPN_PACKAGE"
+    "$FLATPAK_FLATSEAL_PACKAGE"
+    "$SNAP_FIREFOX_PACKAGE"
+    # "$FLATPAK_REMMINA_PACKAGE" # Adds itself to autostart
+)
+
+get_packages_from_identifier() {
+    package_identifier=$1
+    shift
+    packages=("$@")
+
+    for package in "${packages[@]}"; do
+        echo $package | tr ' ' '\n' | grep "^$package_identifier:"
+    done
+}
+
+remove_package_identifier() {
+    packages=("$@")
+
+    for package in "${packages[@]}"; do
+        echo $package | sed 's/^[^:]*://'
+    done
+}
+
+format_args_for_ansible() {
+    args=("$@")
+
+    for arg in "${args[@]}"; do
+        echo $arg | tr '\n' ' '
+    done
+}
+
+format_packages_for_ansible_from_real_package_manager() {
+    package_identifier=$1
+    shift
+    packages=$@
+
+    packages=$(get_packages_from_identifier "$package_identifier" "${packages[@]}")
+    IFS=$'\n' read -r -d '' -a packages <<< "$packages"
+
+    packages=$(remove_package_identifier "${packages[@]}")
+    IFS=$'\n' read -r -d '' -a packages <<< "$packages"
+
+    format_args_for_ansible "${packages[@]}"
+}
+
+main() {
+    # Select packages
+    selected_packages=$(for package in "${ORDERED_PACKAGES[@]}"; do
+        echo "false"
+        echo "${PACKAGES["$package"]}"
+        echo "$package"
+    done | zenity --list \
+        --title="Package Selection" \
+        --text="Select packages to install:" \
+        --checklist \
+        --column="Install" --column="Name" --column="Package" \
+        --print-column "3" \
+        --width=1200 --height=800 \
+        2>/dev/null # suppress file descriptor error
+    )
+
+    if [[ -z "$selected_packages" ]]; then
+    echo "No packages selected. Exiting."
+        exit 0
     fi
-done
+
+    IFS="|" read -ra selected_packages <<< "$selected_packages"
+    
+    # Select package versions if needed
+    declare -A selected_packages_need_version
+    selected_packages_need_version=()
+    for selected_package in "${selected_packages[@]}"; do
+        if [[ -v NEEDS_VERSION["$selected_package"] ]]; then
+            selected_packages_need_version+=(["$selected_package"]=true)
+        else
+            selected_packages_need_version+=(["$selected_package"]=false)
+        fi
+    done
+
+    selected_packages_with_versions=()
+    for selected_package in "${selected_packages[@]}"; do # keeps order, iterating over selected_packages_need_version has different order
+        if ${selected_packages_need_version["$selected_package"]}; then
+            IFS='|' read -r -a get_version_info <<< "${NEEDS_VERSION["$selected_package"]}"
+            xdg-open "${get_version_info[0]}" >/dev/null 2>&1 &
+            read -p "${get_version_info[1]}: " version
+            selected_packages_with_versions+=("$selected_package:$version")
+        else
+            selected_packages_with_versions+=("$selected_package")
+        fi
+    done
+
+    # Select groups from packages
+    possible_user_groups_packages=()
+    for selected_package in "${selected_packages[@]}"; do
+        for package_with_group in "${PACKAGES_WITH_GROUP[@]}"; do
+            if [[ "$selected_package" == "$package_with_group" ]]; then
+                possible_user_groups_packages+=("$selected_package")
+            fi
+        done
+    done
+
+    user_groups=""
+    if [ ${#possible_user_groups_packages[@]} -ne 0 ]; then
+        user_groups=$(for possible_user_group_package in "${possible_user_groups_packages[@]}"; do
+            echo "true"
+            echo "${PACKAGES["$possible_user_group_package"]}"
+            echo "$possible_user_group_package"
+        done | zenity --list \
+            --title="Group Selection" \
+            --text="Select groups from packages to add the current user to:" \
+            --checklist \
+            --column="Add to Group" --column="Name" --column="Package" \
+            --print-column "3" \
+            --width=1200 --height=800 \
+            2>/dev/null # suppress file descriptor error
+        )
+
+        IFS="|" read -ra user_groups <<< "$user_groups"
+        user_groups=$(format_packages_for_ansible_from_real_package_manager ".*" "${user_groups[@]}")
+    fi
+
+    # Select autostart applications
+    possible_autostart_applications=()
+    for selected_package in "${selected_packages[@]}"; do
+        for autostart_application in "${CAN_AUTOSTART[@]}"; do
+            if [[ "$selected_package" == "$autostart_application" ]]; then
+                possible_autostart_applications+=("$selected_package")
+            fi
+        done
+    done
+
+    autostart_applications=""
+    if [ ${#possible_autostart_applications[@]} -ne 0 ]; then
+        autostart_applications=$(for selected_package in "${possible_autostart_applications[@]}"; do
+            echo "false"
+            echo "${PACKAGES["$selected_package"]}"
+            echo "$selected_package"
+        done | zenity --list \
+            --title="Autostart Selection" \
+            --text="Select applications to autostart at login:" \
+            --checklist \
+            --column="Autostart" --column="Name" --column="Package" \
+            --print-column "3" \
+            --width=1200 --height=800 \
+            2>/dev/null # suppress file descriptor error
+        )
+
+        IFS="|" read -ra autostart_applications <<< "$autostart_applications"
+        autostart_applications=$(format_packages_for_ansible_from_real_package_manager ".*" "${autostart_applications[@]}")
+    fi
+
+    # Separate packages by source
+    # apt_packages=$(extract_package_infos "$APT_IDENTIFIER" "${selected_packages_with_versions[@]}")
+    apt_packages=$(format_packages_for_ansible_from_real_package_manager "$APT_IDENTIFIER" "${selected_packages_with_versions[@]}")
+    snap_packages=$(format_packages_for_ansible_from_real_package_manager "$SNAP_IDENTIFIER" "${selected_packages_with_versions[@]}")
+    flatpak_packages=$(format_packages_for_ansible_from_real_package_manager "$FLATPAK_IDENTIFIER" "${selected_packages_with_versions[@]}")
+    raw_packages=$(format_packages_for_ansible_from_real_package_manager "$RAW_IDENTIFIER" "${selected_packages_with_versions[@]}")
+
+    # Read mainline kernel versions
+    mainline_kernels=$(format_packages_for_ansible_from_real_package_manager "$MAINLINE_KERNEL_IDENTIFIER" "${selected_packages_with_versions[@]}")
+    mainline_kernels="${mainline_kernels//','/' '}"
+    
+    # Install packages using ansible
+    $HELPER_SCRIPTS_DIR/install_ansible.sh
+    ansible-playbook "${INSTALLER_DIR}/playbooks/install_packages.yaml" \
+        --extra-vars "apt_packages='$apt_packages' snap_packages='$snap_packages' flatpak_packages='$flatpak_packages' raw_packages='$raw_packages' mainline_kernels='$mainline_kernels' user_groups='$user_groups' autostart_applications='$autostart_applications'" \
+        --inventory "${INSTALLER_DIR}/ansible_inventory.ini" \
+        --ask-become-pass
+
+    # Print bugs and possible resolutions
+    for selected_package in "${selected_packages[@]}"; do
+        if [[ -v BUGS[$selected_package] ]]; then
+            IFS='&' read -r -a bugs <<< $(echo "${BUGS[$selected_package]}" | tr -d '\n')
+            for bug in "${bugs[@]}"; do
+                read -r bug <<< "$bug"
+                IFS='|' read -r -a bug_infos <<< "$bug"
+                echo "Bug in package ${PACKAGES[$selected_package]} ($selected_package): ${bug_infos[0]}. Suggested solution: ${bug_infos[1]}."
+            done
+            echo ''
+        fi
+    done
+}
+
+main
diff --git a/install_functions.sh b/install_functions.sh
deleted file mode 100644
index b6d04f8b57eca0dbaeb4342a1f76eefd53c74e72..0000000000000000000000000000000000000000
--- a/install_functions.sh
+++ /dev/null
@@ -1,401 +0,0 @@
-source installer_vars.sh
-
-apt_update_cmd="sudo apt update"
-apt_install_cmd="sudo apt install -y"
-snap_install_cmd="sudo snap install"
-snap_classic_arg="--classic"
-snap_channel_arg="--channel"
-snap_dangerous_arg="--dangerous"
-snap_alias_cmd="sudo snap alias"
-flatpak_install_cmd="flatpak install --user -y"
-flathub_repo="flathub"
-mkdir_cmd="mkdir -p"
-gtk_launch_cmd="gtk-launch"
-flatpak_run_cmd="flatpak run"
-add_user_to_group_cmd="sudo usermod -aG"
-
-command_exists() {
-    cmd=$1
-
-    if command -v $cmd &> /dev/null
-    then
-        true
-    else
-        false
-    fi
-}
-
-update_upgrade() {
-    $apt_update_cmd && sudo apt upgrade -y
-    sudo snap refresh
-
-    if command_exists flatpak
-    then
-        sudo flatpak update -y
-    else
-        echo "flatpak does not exist; skipping update"
-    fi
-
-    if command_exists mainline
-    then
-        sudo mainline install-minor || true
-        echo "kernel was updated to latest minor version, upgrading to a major version must be done manually"
-    else
-        echo "mainline does not exist; skipping update"
-    fi
-}
-
-flatpak_add_repo() {
-    repo_name=$1
-    repo_url=$2
-
-    flatpak remote-add --user --if-not-exists $repo_name $repo_url
-}
-
-install_flatpak() {
-    $apt_install_cmd flatpak
-
-    flatpak_add_repo $flathub_repo https://dl.flathub.org/repo/flathub.flatpakrepo
-}
-
-install_flatpak_app() {
-    app_name=$1
-    flatpak_repo="flathub"
-
-    install_flatpak
-    $flatpak_install_cmd $flatpak_repo $app_name
-}
-
-make_application_entry() {
-    file="$applications_path/$1.desktop"
-    app_name=$2
-    app_exec=$3
-    app_icon=$4
-
-    ensure_dir $applications_path
-    printf "[Desktop Entry]\nName=$2\nExec=$3\nIcon=$4\nType=Application" > $file
-}
-
-make_autostart_entry() {
-    file="$autostart_path/$1.desktop"
-    app_name=$2
-    app_exec=$3
-
-    read -p "Create autostart entry? (y/n): " creation_answer
-    if [ $creation_answer = "y" ]
-    then
-        ensure_dir $autostart_path
-        printf "[Desktop Entry]\nName=$2\nExec=$3\nType=Application" > $file
-    fi
-}
-
-install_firefox() {
-    $snap_install_cmd firefox
-
-    make_autostart_entry firefox Firefox firefox
-}
-
-install_vs_code() {
-    $snap_install_cmd code $snap_classic_arg
-    make_autostart_entry vscode "Visual Studio Code" "code" # flatpak not possible due to sandboxing, docker forwarding not really working, tries to mount /run/... path, results in error
-}
-
-install_spotify() {
-    flatpak_id="com.spotify.Client"
-
-    install_flatpak_app $flatpak_id
-    make_autostart_entry spotify Spotify "$flatpak_run_cmd $flatpak_id"
-}
-
-install_gimp() {
-    install_flatpak_app org.gimp.GIMP
-}
-
-install_curl() {
-    $apt_install_cmd curl
-}
-
-install_kdiff3() {
-    $apt_install_cmd kdiff3
-}
-
-install_git() {
-    $apt_install_cmd git
-}
-
-install_mono_complete() {
-    $apt_install_cmd mono-complete
-}
-
-install_virtualbox() {
-    # extension pack downloads: https://www.virtualbox.org/wiki/Downloads, probably under older releases
-    # guest additions downloads: https://download.virtualbox.org/virtualbox, in case vbox auto download does not work
-
-    virtualbox_source_list="/etc/apt/sources.list.d/virtualbox.list"
-    virtualbox_keyring_file="/usr/share/keyrings/virtualbox.gpg"
-    os=$(lsb_release -cs)
-
-    $apt_install_cmd apt-transport-https ca-certificates curl software-properties-common
-    curl -fsSL https://www.virtualbox.org/download/oracle_vbox_2016.asc | sudo gpg --dearmor --yes -o $virtualbox_keyring_file
-    echo "deb [arch=amd64 signed-by=$virtualbox_keyring_file] https://download.virtualbox.org/virtualbox/debian $os contrib" | sudo tee $virtualbox_source_list > /dev/null
-    $apt_update_cmd
-
-    firefox --new-window https://www.virtualbox.org/wiki/Linux_Downloads
-    read -p "virtualbox version (e.g. 7.1): " virtualbox_version
-
-    $apt_install_cmd virtualbox-$virtualbox_version
-    $add_user_to_group_cmd vboxusers $username
-}
-
-install_vlc() {
-    $apt_install_cmd vlc
-}
-
-install_docker() {
-    $apt_install_cmd docker.io
-    $add_user_to_group_cmd docker $username
-
-}
-
-install_kubectl() {
-    $snap_install_cmd kubectl $snap_classic_arg
-}
-
-install_net_tools() {
-    $apt_install_cmd net-tools
-}
-
-install_k3d() {
-    install_curl
-
-    curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
-}
-
-install_git_extensions() { #git extensions crashes # maybe newer versions work (.net 6)
-    install_mono_complete
-    install_curl
-
-    gitext_path="$portable_programs_path/GitExtensions"
-    gitext_zip_path="$downloads_path/gitextensions.zip"
-    gitext_exe_path="$gitext_path/GitExtensions.exe"
-    gitext_logo_path="$gitext_path/git-extensions-logo-final-256.ico"
-    mkdir -p $gitext_path
-
-    firefox --new-window https://github.com/gitextensions/gitextensions/releases
-    read -p "latest mono release (e.g. 2.51.05): " git_extensions_release
-
-    curl -L https://github.com/gitextensions/gitextensions/releases/download/v$git_extensions_release/GitExtensions-$git_extensions_release-Mono.zip -o $gitext_zip_path 
-    unzip -o $gitext_zip_path -d $portable_programs_path
-    rm "$gitext_path/Plugins/Bitbucket.dll"
-    rm $gitext_zip_path
-    # echo "alias gitext='mono $gitext_path/GitExtensions.exe'" >> $aliases_path
-
-    make_application_entry gitextensions GitExtensions "mono $gitext_exe_path" $gitext_logo_path
-    make_autostart_entry gitextensions GitExtensions "$gtk_launch_cmd gitextensions"
-}
-
-install_gridsite-clients() {
-    $apt_install_cmd gridsite-clients
-}
-
-install_flameshot() {
-    # Due to a bug in flameshot, follow those steps: open flameshot launcher, take screenshot from tray icon, allow permissions
-    flatpak_id="org.flameshot.Flameshot"
-
-    install_flatpak_app $flatpak_id
-    make_autostart_entry flameshot Flameshot "$flatpak_run_cmd $flatpak_id"
-}
-
-install_intellij_idea() {
-    install_flatpak_app com.jetbrains.IntelliJ-IDEA-Community
-}
-
-install_linssid() {
-    $apt_install_cmd linssid
-}
-
-install_docker_ce() {
-    install_curl
-
-    docker_source_list="/etc/apt/sources.list.d/docker.list"
-    docker_keyring_file="/usr/share/keyrings/docker.gpg"
-    docker_apt_repo="https://download.docker.com/linux/ubuntu"
-    os=$(lsb_release -cs)
-    sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
-    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o $docker_keyring_file
-    # curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo tee $docker_keyring_file > /dev/null # if already in gpg format
-    echo "deb [arch=amd64 signed-by=$docker_keyring_file] $docker_apt_repo $os stable" | sudo tee $docker_source_list > /dev/null
-
-    sudo apt update
-    ! sudo apt install -y docker-ce # needed because sometimes docker restarts to fast and docker daemon will be up and running after restart of pc
-    sudo dpkg --configure -a
-}
-
-install_dl_driver() {
-    install_curl
-    display_link_keyring="$downloads_path/synaptics-repository-keyring.deb"
-    curl https://www.synaptics.com/sites/default/files/Ubuntu/pool/stable/main/all/synaptics-repository-keyring.deb -o $display_link_keyring
-    $apt_install_cmd $display_link_keyring
-    sudo rm $display_link_keyring
-    sudo apt update
-
-    $apt_install_cmd gcc-14 # newer kernels require gcc 14
-    $apt_install_cmd displaylink-driver
-}
-
-install_obsidian() {
-    flatpak_id="md.obsidian.Obsidian"
-
-    install_flatpak_app $flatpak_id
-    make_autostart_entry obsidian Obsidian "$flatpak_run_cmd $flatpak_id"
-}
-
-install_staruml() {
-    install_curl
-
-    staruml_file="$downloads_path/staruml.deb"
-
-    firefox --new-window https://staruml.io/download
-    read -p "staruml major release (e.g. 5): " staruml_major_release
-    read -p "staruml minor release (e.g. 0.2): " staruml_minor_release
-
-    curl https://staruml.io/download/releases-v$staruml_major_release/StarUML_${staruml_major_release}.${staruml_minor_release}_amd64.deb -o $staruml_file
-
-    $apt_install_cmd $staruml_file
-
-    rm $staruml_file
-}
-
-install_node() {
-    install_curl
-    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
-
-    export NVM_DIR="$HOME/.nvm"
-    \. "$NVM_DIR/nvm.sh"
-    nvm install 20
-}
-
-install_webstorm() {
-    install_flatpak_app com.jetbrains.WebStorm
-}
-
-install_dotnet() {
-    # install repo
-    packages_installer="$downloads_path/packages-microsoft-prod.deb"
-    wget https://packages.microsoft.com/config/ubuntu/$ubuntu_release/packages-microsoft-prod.deb -O $packages_installer
-    sudo dpkg -i $packages_installer
-    rm $packages_installer
-
-    sudo cp dotnet_apt_preferences/dotnet /etc/apt/preferences.d/dotnet
-    sudo cp dotnet_apt_preferences/aspnet /etc/apt/preferences.d/aspnet
-
-    sudo apt update
-
-    read -p "dotnet release (e.g. 6.0): " dotnet_release
-
-    sudo apt-get install -y dotnet-sdk-$dotnet_release
-}
-
-install_ilspy() {
-    install_curl
-
-    ilspy_zip="$downloads_path/ilspy.zip"
-    ilspy_dir="$portable_programs_path/ILSpy"
-    mkdir -p $ilspy_dir
-
-    curl -L https://github.com/icsharpcode/AvaloniaILSpy/releases/latest/download/Linux.x64.Release.zip -o $ilspy_zip
-
-    unzip $ilspy_zip -d $ilspy_dir
-    rm $ilspy_zip
-    echo "alias ilspy='$ilspy_dir/ILSpy'" >> $aliases_path
-}
-
-install_android_studio() {
-    install_flatpak_app com.google.AndroidStudio
-}
-
-install_pip() {
-    $apt_install_cmd python3-pip
-}
-
-install_virtualenv() {
-    $apt_install_cmd virtualenv
-}
-
-install_rider() {
-    $snap_install_cmd rider $snap_classic_arg
-}
-
-install_nextcloud_client() {
-    flatpak_id="com.nextcloud.desktopclient.nextcloud"
-
-    install_flatpak_app $flatpak_id
-    make_autostart_entry nextcloudclient "Nextcloud Client" "$flatpak_run_cmd $flatpak_id" 
-}
-
-install_nano() {
-    $apt_install_cmd nano
-}
-
-install_element_desktop() {
-    element_keyring_file="/usr/share/keyrings/element-io-archive-keyring.gpg"
-
-    $apt_install_cmd wget apt-transport-https
-    sudo wget -O $element_keyring_file https://packages.element.io/debian/element-io-archive-keyring.gpg
-    echo "deb [signed-by=$element_keyring_file] https://packages.element.io/debian/ default main" | sudo tee /etc/apt/sources.list.d/element-io.list
-    
-    sudo apt update
-    $apt_install_cmd element-desktop
-}
-
-install_dconf_editor() {
-    $apt_install_cmd dconf-editor
-}
-
-install_openssh_server() {
-    $apt_install_cmd openssh-server
-}
-
-install_openconnect() {
-    $apt_install_cmd openconnect network-manager-openconnect network-manager-openconnect-gnome
-}
-
-install_protonvpn() {
-    firefox --new-window https://protonvpn.com/support/official-linux-vpn-ubuntu
-    read -p "latest repo version (e.g. 1.0.4) " proton_repo_version
-    repo_installer_file="$downloads_path/proton_repo.deb"
-    wget https://repo.protonvpn.com/debian/dists/stable/main/binary-all/protonvpn-stable-release_${proton_repo_version}_all.deb -O $repo_installer_file
-    sudo dpkg -i $repo_installer_file
-    rm $repo_installer_file
-
-    $apt_update_cmd
-    $apt_install_cmd proton-vpn-gnome-desktop
-
-    make_autostart_entry proton-vpn "proton vpn" "protonvpn-app"
-}
-
-install_flatseal() {
-    flatpak_id="com.github.tchx84.Flatseal"
-
-    install_flatpak_app $flatpak_id
-}
-
-install_wireguard() {
-    $apt_install_cmd wireguard
-}
-
-install_remmina() {
-    install_flatpak_app org.remmina.Remmina
-}
-
-install_mainline_kernel() {
-    sudo add-apt-repository ppa:cappelikan/ppa
-    $apt_update_cmd
-    $apt_install_cmd mainline
-
-    mainline list
-    echo "if displaylink driver is installed, make sure that displaylink evdi supports the kernel: https://github.com/DisplayLink/evdi/releases"
-    read -p "Kernel version (e.g. 6.11.10): " mainline_kernel_version
-
-    sudo mainline install $mainline_kernel_version || true
-}
diff --git a/installer_vars.sh b/installer_vars.sh
deleted file mode 100644
index c86b8aac0f5e57c2c2c9bbcd9e67009b46664619..0000000000000000000000000000000000000000
--- a/installer_vars.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-ubuntu_release=$(lsb_release -sr)
-username=$(whoami)
-homepath="/home/$username"
-portable_programs_path="$homepath/Programs"
-projects_path="$homepath/Projects"
-tmp_path="$homepath/tmp"
-applications_path="$homepath/.local/share/applications"
-autostart_path="$homepath/.config/autostart"
-aliases_path="$homepath/.bash_aliases"
-downloads_path="$homepath/Downloads"
-snap_path="$homepath/snap"
-
-check_if_root() {
-    if [ "$username" = "root" ]
-    then
-        echo "try executing from user account, no sudo required";
-        exit 1;
-    fi
-}
-
-ensure_dir() {
-    dir=$1
-
-    $mkdir_cmd $dir
-}
diff --git a/options.sh b/options.sh
deleted file mode 100644
index 09e22d30199712d92d1873cf4786b5c28950fe56..0000000000000000000000000000000000000000
--- a/options.sh
+++ /dev/null
@@ -1,144 +0,0 @@
-checkbox_checked="on"
-checkbox_unchecked="off"
-options_set="true"
-
-# enabled defaults
-firefox_enabled=$checkbox_unchecked
-vs_code_enabled=$checkbox_unchecked
-spotify_enabled=$checkbox_unchecked
-gimp_enabled=$checkbox_unchecked
-curl_enabled=$checkbox_unchecked
-kdiff3_enabled=$checkbox_unchecked
-git_enabled=$checkbox_unchecked
-mono_complete_enabled=$checkbox_unchecked
-virtualbox_enabled=$checkbox_unchecked
-vlc_enabled=$checkbox_unchecked
-docker_io_enabled=$checkbox_unchecked
-kubectl_enabled=$checkbox_unchecked
-net_tools_enabled=$checkbox_unchecked
-k3d_enabled=$checkbox_unchecked
-git_extensions_enabled=$checkbox_unchecked
-set_dark_theme_enabled=$checkbox_unchecked
-set_idle_delay_enabled=$checkbox_unchecked
-flameshot_enabled=$checkbox_unchecked
-intellij_idea_enabled=$checkbox_unchecked
-teams_enabled=$checkbox_unchecked
-linssid_enabled=$checkbox_unchecked
-docker_ce_enabled=$checkbox_unchecked
-dl_driver_enabled=$checkbox_unchecked
-obsidian_enabled=$checkbox_unchecked
-staruml_enabled=$checkbox_unchecked
-node_enabled=$checkbox_unchecked
-webstorm_enabled=$checkbox_unchecked
-dotnet_enabled=$checkbox_unchecked
-ilspy_enabled=$checkbox_unchecked
-android_studio_enabled=$checkbox_unchecked
-pip_enabled=$checkbox_unchecked
-virtualenv_enabled=$checkbox_unchecked
-rider_enabled=$checkbox_unchecked
-nextcloud_client_enabled=$checkbox_unchecked
-nano_enabled=$checkbox_unchecked
-element_desktop_enabled=$checkbox_unchecked
-dconf_editor_enabled=$checkbox_unchecked
-openssh_server_enabled=$checkbox_unchecked
-openconnect_enabled=$checkbox_unchecked
-protonvpn_enabled=$checkbox_unchecked
-flatseal_enabled=$checkbox_unchecked
-wireguard_enabled=$checkbox_unchecked
-remmina_enabled=$checkbox_unchecked
-mainline_enabled=$checkbox_unchecked
-swap_enabled=$checkbox_unchecked
-
-# labels
-firefox_key="firefox"
-vs_code_key="vs_code"
-spotify_key="spotify"
-gimp_key="gimp"
-curl_key="curl"
-kdiff3_key="kdiff3"
-git_key="git"
-mono_complete_key="mono_complete"
-virtualbox_key="virtualbox"
-vlc_key="vlc"
-docker_io_key="docker"
-kubectl_key="kubectl"
-net_tools_key="net_tools"
-k3d_key="k3d"
-git_extensions_key="git_extensions"
-set_dark_theme_key="dark_theme"
-set_idle_delay_key="idle_delay"
-flameshot_key="flameshot"
-intellij_idea_key="intellij_idea_community"
-teams_key="teams"
-linssid_key="linssid"
-docker_ce_key="docker_ce"
-dl_driver_key="dl_driver"
-obsidian_key="obsidian"
-staruml_key="staruml"
-node_key="node"
-webstorm_key="webstorm"
-dotnet_key="dotnet"
-ilspy_key="ilspy"
-android_studio_key="android_studio"
-pip_key="pip"
-virtualenv_key="virtualenv"
-rider_key="rider"
-nextcloud_client_key="nextcloud_client"
-nano_key="nano"
-element_desktop_key="element_desktop"
-dconf_editor_key="dconf_editor"
-openssh_server_key="openssh_server"
-openconnect_key="openconnect"
-protonvpn_key="proton_vpn"
-flatseal_key="flatseal"
-wireguard_key="wireguard"
-remmina_key="remmina"
-mainline_key="mainline"
-swap_key="swap"
-
-# show text
-firefox_label="firefox"
-vs_code_label="vs code"
-spotify_label="spotify"
-gimp_label="gimp"
-curl_label="curl"
-kdiff3_label="kdiff3"
-git_label="git"
-mono_complete_label="mono-complete"
-virtualbox_label="virtualbox"
-vlc_label="vlc"
-docker_io_label="docker"
-kubectl_label="kubectl"
-net_tools_label="net tools (ifconfig)"
-k3d_label="k3d"
-git_extensions_label="git extensions"
-set_dark_theme_label="dark theme"
-set_idle_delay_label="idle delay"
-flameshot_label="flameshot"
-intellij_idea_label="intellij idea community"
-teams_label="teams"
-linssid_label="linssid"
-docker_ce_label="docker ce"
-dl_driver_label="displaylink driver"
-obsidian_label="obsidian"
-staruml_label="staruml"
-node_label="node"
-webstorm_label="webstorm"
-dotnet_label="dotnet sdk"
-ilspy_label="ilspy (disassembler)"
-android_studio_label="android studio"
-pip_label="pip"
-virtualenv_label="virtualenv"
-rider_label="rider"
-nextcloud_client_label="nextcloud client"
-nano_label="nano"
-element_desktop_label="element desktop"
-dconf_editor_label="dconf-editor"
-openssh_server_label="openssh-server"
-openconnect_label="openconnect"
-protonvpn_label="proton-vpn"
-flatseal_label="flatseal"
-wireguard_label="wireguard"
-remmina_label="remmina"
-mainline_label="mainline kernel"
-swap_label="swap"
diff --git a/playbooks/install_packages.yaml b/playbooks/install_packages.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..47e8bfa4312a8c0669d9cd67dddd961e478941e3
--- /dev/null
+++ b/playbooks/install_packages.yaml
@@ -0,0 +1,56 @@
+- hosts: localhost
+  vars:
+    apt_packages: ""
+    snap_packages: ""
+    flatpak_packages: ""
+    raw_packages: ""
+    mainline_kernels: ""
+
+    autostart_applications: ""
+    autostart_directory: "{{ ansible_env.HOME }}/.config/autostart"
+
+    applications_directory: "{{ ansible_env.HOME }}/.local/share/applications"
+
+    latest_gcc_version: "14"
+
+  vars_files:
+    - ../variables/editable_variables.yaml
+    - ../variables/package_groups.yaml
+
+    - ../variables/repositories/flatpak.yaml
+    - ../variables/repositories/apt.yaml
+
+  tasks:
+    - name: Update APT cache
+      include_tasks: ../tasks/apt_templates/apt_update.yaml
+      when: apt_packages != "" or flatpak_packages != ""
+
+    - name: Include APT Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/apt_packages.yaml
+
+    - name: Include Flatpak Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/flatpak_packages.yaml
+
+    - name: Include Snap Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/snap_packages.yaml
+
+    - name: Include Raw Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/raw_packages.yaml
+
+    - name: Include Mainline Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/mainline/install_mainline_kernel.yaml
+
+    - name: Cleanup
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/apt_templates/cleanup_apt.yaml
diff --git a/playbooks/setup.yaml b/playbooks/setup.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8ff63d9a2641a1f95e8f9c54866a6ea56d47d078
--- /dev/null
+++ b/playbooks/setup.yaml
@@ -0,0 +1,23 @@
+- hosts: localhost
+  vars:
+    dconf_config_path: ""
+    vscode_config_path: ""
+    vscode_extensions_path: ""
+    swap_sizes: ""
+
+  tasks:
+    - name: Include DConf Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/setup/dconf.yaml
+    
+    - name: Include Visual Studio Code Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/setup/vscode_settings.yaml
+        - ../tasks/setup/vscode_extensions.yaml
+    
+    - name: Include Swap Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/setup/swap.yaml
diff --git a/playbooks/update_packages.yaml b/playbooks/update_packages.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9edcc463f127ebcd5360f4acb8c5ee504703f636
--- /dev/null
+++ b/playbooks/update_packages.yaml
@@ -0,0 +1,24 @@
+- hosts: localhost
+  vars:
+    package_managers: ""
+  tasks:
+    - name: Include APT Tasks
+      include_tasks: ../tasks/apt_templates/apt_upgrade.yaml
+      when: "'apt' in package_managers"
+
+    - name: Include Flatpak Tasks
+      include_tasks: ../tasks/flatpak_templates/upgrade_flatpak_packages.yaml
+      when: "'flatpak' in package_managers"      
+
+    - name: Include Snap Tasks
+      include_tasks: ../tasks/snap_templates/upgrade_snap_packages.yaml
+      when: "'snap' in package_managers"
+
+    - name: Include Mainline Kernel Tasks
+      include_tasks: ../tasks/mainline/upgrade_mainline_kernel.yaml
+      when: "'mainline' in package_managers"
+
+    - name: Cleanup
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/apt_templates/cleanup_apt.yaml
diff --git a/school_pc.sh b/school_pc.sh
deleted file mode 100644
index 4232cd3bca869edd03b6892f532114b0f1bedbd1..0000000000000000000000000000000000000000
--- a/school_pc.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-set -e
-source installer_vars.sh
-source source_if_options_not_sourced.sh
-source_if_options_not_sourced
-
-check_if_root
-
-# set defaults
-source defaults.sh
-
-flameshot_enabled=$checkbox_checked
-intellij_idea_enabled=$checkbox_checked
-teams_enabled=$checkbox_checked
-linssid_enabled=$checkbox_checked
-docker_ce_enabled=$checkbox_checked
-dl_driver_enabled=$checkbox_checked
-obsidian_enabled=$checkbox_checked
-git_extensions_enabled=$checkbox_checked
-
-source install.sh
diff --git a/setup.sh b/setup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5597e063555da1923a082c730c3a66dcfbd21461
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+set -e
+INSTALLER_DIR=$(dirname "${BASH_SOURCE[0]}")
+HELPER_SCRIPTS_DIR="$INSTALLER_DIR/helper_scripts"
+
+SWAP_DEFAULT_UNIT="G"
+
+main() {
+    read -e -p "DConf config path (empty to skip): " dconf_config_path
+    read -e -p "Visual Studio Code User Settings (empty to skip): " vscode_config_path
+    read -e -p "Visual Studio Code Extensions File (empty to skip): " vscode_extensions_path
+    read -e -p "Comma separated swap sizes in Gigabytes (empty to skip): " swap_sizes
+    swap_sizes="${swap_sizes//','/"$SWAP_DEFAULT_UNIT "}"
+
+    additional_ansible_args=()
+
+    if [[ -n "$swap_sizes" ]]; then
+        additional_ansible_args+=('--ask-become-pass')
+        swap_sizes+="$SWAP_DEFAULT_UNIT"
+    fi
+
+    $HELPER_SCRIPTS_DIR/install_ansible.sh
+    ansible-playbook "${INSTALLER_DIR}/playbooks/setup.yaml" \
+        --extra-vars "dconf_config_path='$dconf_config' vscode_config_path='$vscode_config_path' vscode_extensions_path='$vscode_extensions_path' swap_sizes='$swap_sizes'" \
+        --inventory "${INSTALLER_DIR}/ansible_inventory.ini" \
+        $(IFS=' ' echo "${additional_ansible_args[*]}")
+}
+
+main
diff --git a/setup_functions.sh b/setup_functions.sh
deleted file mode 100644
index 114e7522f3fb8877be48e0488043186a35e51b37..0000000000000000000000000000000000000000
--- a/setup_functions.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-source installer_vars.sh
-
-gsettings_set_cmd="gsettings set"
-control_center_cmd="gnome-terminal -- bash -c \"gnome-control-center $tab && exit\""
-mkdir_cmd="mkdir -p"
-
-gsettings_set_option() {
-    scheme=$1
-    key=$2
-    value=$3
-
-    $gsettings_set_cmd $scheme $key $value
-}
-
-control_center_set_option() {
-    tab=$1
-
-    gnome-terminal -- bash -c "gnome-control-center $tab && exit"
-}
-
-setup_dark_mode() { # todo, settings -> appereance must be opened to apply
-    gsettings_set_option org.gnome.desktop.interface color-scheme 'prefer-dark'
-
-    control_center_set_option 'ubuntu' #appereance tab
-}
-
-setup_idle_delay() { # todo, settings -> power must be opened to apply
-    gsettings_set_option org.gnome.desktop.session idle-delay 0
-
-    control_center_set_option 'power'
-}
-
-setup_paths() {
-    $mkdir_cmd $projects_path
-    $mkdir_cmd $portable_programs_path
-    $mkdir_cmd $tmp_path
-}
-
-setup_swap() {
-    swap_path="/swap"
-    swap_file="$swap_path/swapfile0"
-
-    sudo $mkdir_cmd $swap_path
-    read -p "swap size (e.g. 50G): " swap_size
-    sudo fallocate -l $swap_size $swap_file
-    sudo chmod 600 $swap_file
-    sudo mkswap $swap_file
-    echo "$swap_file none swap sw 0 0" | sudo tee -a /etc/fstab
-    sudo swapon $swap_file
-}
diff --git a/source_if_options_not_sourced.sh b/source_if_options_not_sourced.sh
deleted file mode 100644
index 022679a0d5d7a6769093815ce2b039e5335f97db..0000000000000000000000000000000000000000
--- a/source_if_options_not_sourced.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-# source options if not already sourced
-source_if_options_not_sourced() { 
-    if [ -z $options_set ]
-    then
-        source options.sh
-    fi
-}
\ No newline at end of file
diff --git a/tasks/apt_packages.yaml b/tasks/apt_packages.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4db7a678ae72e8cd4e0a15dc1c166fdf00bdd455
--- /dev/null
+++ b/tasks/apt_packages.yaml
@@ -0,0 +1,154 @@
+- name: Install Flatpak (APT)
+  include_tasks: apt_templates/install_apt_package.yaml
+  vars:
+    app: flatpak
+  when: flatpak_packages != ""
+
+- name: Install Git (APT)
+  include_tasks: apt_templates/install_apt_package.yaml
+  vars:
+    app: git
+  when: "'git' in apt_packages"
+
+- name: Install Docker Community Edition (APT)
+  when: "'docker' in apt_packages"
+  block:
+  - name: Add Docker APT Repository
+    include_tasks: apt_templates/add_apt_repository.yaml
+    vars:
+      gpg_url: "{{ apt_repositories.docker.gpg_url }}"
+      repository_url: "{{ apt_repositories.docker.repository_url }}"
+      repository_branch: "{{ apt_repositories.docker.repository_branch }}"
+      repository_name: "{{ apt_repositories.docker.repository_name }}"
+
+  - name: Install Docker Community Edition (APT)
+    include_tasks: apt_templates/install_apt_package.yaml
+    vars:
+      app: docker-ce
+
+  - name: Add current User to Docker Group
+    include_tasks: general_templates/add_user_to_group.yaml
+    vars:
+      groupname: "{{ package_groups.docker }}"
+    when: "'docker-ce' in user_groups"
+
+- name: Install VirtualBox (APT)
+  when: apt_packages is search('virtualbox:')
+  block:
+  - name: Add VirtualBox APT Repository
+    include_tasks: apt_templates/add_apt_repository.yaml
+    vars:
+      gpg_url: "{{ apt_repositories.virtualbox.gpg_url }}"
+      repository_url: "{{ apt_repositories.virtualbox.repository_url }}"
+      repository_branch: "{{ apt_repositories.virtualbox.repository_branch }}"
+      repository_name: "{{ apt_repositories.virtualbox.repository_name }}"
+
+  - name: Install VirtualBox (APT)
+    include_tasks: apt_templates/install_apt_package.yaml
+    vars:
+      version: "{{ apt_packages | regex_search('virtualbox:([^\\s]+)', '\\1') | first | trim }}"
+      app: virtualbox-{{ version }}
+
+  - name: Add current User to VirtualBox Group
+    include_tasks: general_templates/add_user_to_group.yaml
+    vars:
+      groupname: "{{ package_groups.virtualbox }}"
+    when: "'virtualbox' in user_groups"
+
+  - name: Create Autostart Entry
+    include_tasks: general_templates/create_desktop_file.yaml
+    vars:
+      filename: apt_virtualbox
+      app_name: VirtualBox
+      executable: virtualbox
+      description: Virtual Machine Manager
+    when: "'virtualbox' in autostart_applications"
+
+- name: Install VLC Media Player (APT)
+  when: "'vlc' in apt_packages"
+  block:
+  - name: Install VLC Media Player (APT)
+    include_tasks: apt_templates/install_apt_package.yaml
+    vars:
+      app: vlc
+
+  - name: Create Autostart Entry
+    include_tasks: general_templates/create_desktop_file.yaml
+    vars:
+      filename: apt_vlc
+      app_name: VLC Media Player
+      executable: vlc
+      description: Media Player
+    when: "'vlc' in autostart_applications"
+
+- name: Install net-tools (APT)
+  include_tasks: apt_templates/install_apt_package.yaml
+  vars:
+    app: net-tools
+  when: "'net-tools' in apt_packages"
+
+- name: Install DisplayLink Driver (APT)
+  when: "'dl-driver' in apt_packages"
+  block:
+    - name: Add Synaptics APT Repository
+      include_tasks: general_templates/wget_install.yaml
+      vars:
+        wget_output_file: synaptics_apt_repository.deb
+        url: "{{ apt_repositories.synaptics.deb_url }}"
+        installation_task: install_deb.yaml
+
+    - name: Update APT cache
+      include_tasks: apt_templates/apt_update.yaml
+
+    - name: Install Kernel Dependencies
+      include_tasks: apt_templates/install_apt_package.yaml
+      vars:
+        app: "gcc-{{ latest_gcc_version }}"
+
+    - name: Install DisplayLink Driver (APT)
+      include_tasks: apt_templates/install_apt_package.yaml
+      vars:
+        app: displaylink-driver
+
+- name: Install ProtonVPN (APT)
+  when: apt_packages is search('proton-vpn:')
+  block:
+  - name: Evaluate Variables
+    vars:
+      repository_version: "{{ apt_packages | regex_search('proton-vpn:([^\\s]+)', '\\1') | first | trim }}"
+    set_fact:
+      proton_repository_url: "{{ apt_repositories.proton.deb_url }}"
+
+  - name: Add Synaptics APT Repository
+    include_tasks: general_templates/wget_install.yaml
+    vars:
+      wget_output_file: protonvpn_repository.deb
+      installation_task: install_deb.yaml
+      url: "{{ proton_repository_url }}"
+
+  - name: Update APT cache
+    include_tasks: apt_templates/apt_update.yaml
+
+  - name: Install ProtonVPN (APT)
+    include_tasks: apt_templates/install_apt_package.yaml
+    vars:
+      app: proton-vpn-gnome-desktop
+
+  - name: Create Autostart Entry
+    include_tasks: general_templates/create_desktop_file.yaml
+    vars:
+      filename: apt_protonvpn
+      app_name: ProtonVPN
+      executable: protonvpn-app
+      description: VPN client
+    when: "'proton-vpn' in autostart_applications"
+
+- name: Install WireGuard VPN (APT)
+  include_tasks: apt_templates/install_apt_package.yaml
+  vars:
+    app: wireguard
+  when: "'wireguard' in apt_packages"
+
+- name: Install DConf Editor (APT)
+  include_tasks: apt_templates/packages/dconf.yaml
+  when: "'dconf-editor' in apt_packages"
diff --git a/tasks/apt_templates/add_apt_repository.yaml b/tasks/apt_templates/add_apt_repository.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0aadf0b8dd3c4a1c2e576a505aea83bcd089cd3f
--- /dev/null
+++ b/tasks/apt_templates/add_apt_repository.yaml
@@ -0,0 +1,20 @@
+- name: Install required dependencies to add APT Repository
+  apt:
+    name: apt-transport-https
+    state: present
+  become: true
+
+- name: Add Repository GPG Key
+  apt_key:
+    url: "{{ gpg_url }}"
+    keyring: /usr/share/keyrings/{{ repository_name }}.gpg
+    state: present
+  become: true
+
+- name: Add APT Repository
+  apt_repository:
+    repo: "deb [arch=amd64 signed-by=/usr/share/keyrings/{{ repository_name }}.gpg] {{ repository_url }} {{ ansible_distribution_release }} {{ repository_branch }}"
+    state: present
+    filename: "{{ repository_name }}"
+    update_cache: yes
+  become: true
diff --git a/tasks/apt_templates/apt_update.yaml b/tasks/apt_templates/apt_update.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe866af4c69e65376663ae992d9fda98bcbdeb95
--- /dev/null
+++ b/tasks/apt_templates/apt_update.yaml
@@ -0,0 +1,4 @@
+- name: Update APT cache
+  apt:
+    update_cache: yes
+  become: true
diff --git a/tasks/apt_templates/apt_upgrade.yaml b/tasks/apt_templates/apt_upgrade.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e6fd664742345205501e4227958950b99633da13
--- /dev/null
+++ b/tasks/apt_templates/apt_upgrade.yaml
@@ -0,0 +1,9 @@
+- name: Upgrade APT packages
+  block:
+    - name: Update APT Cache
+      include_tasks: apt_update.yaml
+
+    - name: Upgrade APT packages
+      apt:
+        upgrade: dist
+      become: true
diff --git a/tasks/apt_templates/cleanup_apt.yaml b/tasks/apt_templates/cleanup_apt.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a405cdd07c6e48688ebb0081529623810a4dbb8a
--- /dev/null
+++ b/tasks/apt_templates/cleanup_apt.yaml
@@ -0,0 +1,4 @@
+- name: Cleanup APT
+  apt:
+    autoremove: true
+  become: true
diff --git a/tasks/apt_templates/install_apt_package.yaml b/tasks/apt_templates/install_apt_package.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e9ad48356f4be8605cddd304685412718746c95b
--- /dev/null
+++ b/tasks/apt_templates/install_apt_package.yaml
@@ -0,0 +1,5 @@
+- name: Install APT Package
+  apt:
+    name: "{{ app }}"
+    state: present
+  become: true  
diff --git a/tasks/apt_templates/packages/dconf.yaml b/tasks/apt_templates/packages/dconf.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..dbf7523948fafb3ebb376c6c7f078aaa72cbdc5f
--- /dev/null
+++ b/tasks/apt_templates/packages/dconf.yaml
@@ -0,0 +1,4 @@
+- name: Install DConf Editor (APT)
+  include_tasks: ../install_apt_package.yaml
+  vars:
+    app: dconf-editor
diff --git a/tasks/flatpak_packages.yaml b/tasks/flatpak_packages.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..97ae57062a9dfe84d181c80f68869a674b1d501f
--- /dev/null
+++ b/tasks/flatpak_packages.yaml
@@ -0,0 +1,159 @@
+- name: Install JetBrains IntelliJ IDEA Community (Flatpak)
+  vars:
+    app:
+      id: com.jetbrains.IntelliJ-IDEA-Community
+  when: "'intellij-idea-community' in flatpak_packages"
+  block:
+    - name: Install JetBrains IntelliJ IDEA Community (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_intellij_idea_community
+        app_name: JetBrains IntelliJ IDEA Community
+        description: IntelliJ IDEA Community IDE
+      when: "'intellij-idea-community' in autostart_applications"
+
+- name: Install JetBrains WebStorm (Flatpak)
+  vars:
+    app:
+      id: com.jetbrains.WebStorm
+  when: "'webstorm' in flatpak_packages"
+  block:
+    - name: Install JetBrains WebStorm (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_jetbrains_webstorm
+        app_name: JetBrains WebStorm
+        description: JetBrains WebStorm IDE
+      when: "'webstorm' in autostart_applications"
+
+- name: Install Android Studio (Flatpak)
+  vars:
+    app:
+      id: com.google.AndroidStudio
+  when: "'android-studio' in flatpak_packages"
+  block:
+    - name: Install Android Studio (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_android_studio
+        app_name: Android Studio
+        description: Android Studio IDE
+      when: "'android-studio' in autostart_applications"
+
+- name: Install Obsidian (Flatpak)
+  vars:
+    app:
+      id: md.obsidian.Obsidian
+  when: "'obsidian' in flatpak_packages"
+  block:
+    - name: Install Obsidian (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_obsidian
+        app_name: Obsidian
+        description: Obsidian Note App
+      when: "'obsidian' in autostart_applications"
+
+- name: Install Spotify (Flatpak)
+  vars:
+    app:
+      id: com.spotify.Client
+  when: "'spotify' in flatpak_packages"
+  block:
+    - name: Install Spotify (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_spotify
+        app_name: Spotify
+        description: Spotify
+      when: "'spotify' in autostart_applications"
+
+- name: Install GIMP (Flatpak)
+  vars:
+    app:
+      id: org.gimp.GIMP
+  when: "'gimp' in flatpak_packages"
+  block:
+    - name: Install GIMP (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_gimp
+        app_name: GIMP
+        description: GNU Image Manipulation Program
+      when: "'gimp' in autostart_applications"
+
+- name: Install Flameshot (Flatpak)
+  vars:
+    app:
+      id: org.flameshot.Flameshot
+  when: "'flameshot' in flatpak_packages"
+  block:
+    - name: Install Flameshot (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_flameshot
+        app_name: Flameshot
+        description: Screenshot Tool
+      when: "'flameshot' in autostart_applications"
+
+- name: Install Nexcloud Client (Flatpak)
+  vars:
+    app:
+      id: com.nextcloud.desktopclient.nextcloud
+  when: "'nextcloud-client' in flatpak_packages"
+  block:
+    - name: Install Nexcloud Client (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_nexctloud_client
+        app_name: Nextcloud Client
+        description: Nextcloud synchronization client
+      when: "'nextcloud-client' in autostart_applications"
+
+- name: Install Flatseal (Flatpak)
+  vars:
+    app:
+      id: com.github.tchx84.Flatseal
+  when: "'flatseal' in flatpak_packages"
+  block:
+    - name: Install Flatseal (Flatpak)
+      include_tasks: flatpak_templates/install_flatpak_package.yaml
+
+    - name: Create Autostart Entry
+      include_tasks: flatpak_templates/create_flatpak_autostart_entry.yaml
+      vars:
+        filename: flatpak_flatseal
+        app_name: Flatseal
+        description: Flatpak Permission Manager
+      when: "'flatseal' in autostart_applications"
+
+- name: Install Remmina (Flatpak)
+  include_tasks: flatpak_templates/install_flatpak_package.yaml
+  vars:
+    app:
+      id: org.remmina.Remmina
+  when: "'remmina' in flatpak_packages"
diff --git a/tasks/flatpak_templates/create_flatpak_autostart_entry.yaml b/tasks/flatpak_templates/create_flatpak_autostart_entry.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9a4628959fc46dc88f9fbf31800c16bad980dcd5
--- /dev/null
+++ b/tasks/flatpak_templates/create_flatpak_autostart_entry.yaml
@@ -0,0 +1,4 @@
+- name: Create Flatpak Autostart Entry
+  include_tasks: ../general_templates/create_desktop_file.yaml
+  vars:
+    executable: flatpak run {{ app.id }}
diff --git a/tasks/flatpak_templates/install_flatpak_package.yaml b/tasks/flatpak_templates/install_flatpak_package.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..eabcc24198f0a113cb1bb8dbb5c89a2d6d5c2b9e
--- /dev/null
+++ b/tasks/flatpak_templates/install_flatpak_package.yaml
@@ -0,0 +1,9 @@
+- name: Install Flatpak package
+  block:
+    - name: Add Flatpak Repository
+      command: 
+        cmd: flatpak remote-add --user --if-not-exists {{ repo.name | default(flatpak_repositories.flathub.name) }} {{ repo.url | default(flatpak_repositories.flathub.url) }}
+
+    - name: Install Flatpak Package
+      command:
+        cmd: flatpak install --user -y {{ repo.name | default(flatpak_repositories.flathub.name) }} {{ app.id }}
diff --git a/tasks/flatpak_templates/upgrade_flatpak_packages.yaml b/tasks/flatpak_templates/upgrade_flatpak_packages.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..28c05e147e40236131604dabcdaf2286ef1fbd43
--- /dev/null
+++ b/tasks/flatpak_templates/upgrade_flatpak_packages.yaml
@@ -0,0 +1,3 @@
+- name: Upgrade Flatpak packages
+  command:
+    cmd: flatpak update --user -y
diff --git a/tasks/general_templates/add_user_to_group.yaml b/tasks/general_templates/add_user_to_group.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6583cbf63989cf54d955c148a47f0f47e2e2b9e4
--- /dev/null
+++ b/tasks/general_templates/add_user_to_group.yaml
@@ -0,0 +1,8 @@
+- name: Add current user to group
+  vars:
+    username: "{{ lookup('env', 'USER') }}" # current user
+  user:
+    name: "{{ username }}"
+    groups: "{{ groupname }}"
+    append: yes
+  become: true
diff --git a/tasks/general_templates/bash_installation.yaml b/tasks/general_templates/bash_installation.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e582be705117fddf8e302691acc137c33bb4dad5
--- /dev/null
+++ b/tasks/general_templates/bash_installation.yaml
@@ -0,0 +1,2 @@
+- name: Install bash File
+  shell: bash "{{ installation_file }}"
diff --git a/tasks/general_templates/create_desktop_file.yaml b/tasks/general_templates/create_desktop_file.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..337dafd84f87307d14379259cdf53f97693dafb7
--- /dev/null
+++ b/tasks/general_templates/create_desktop_file.yaml
@@ -0,0 +1,16 @@
+- name: Ensure Directory
+  include_tasks: make_dir.yaml
+  vars:
+    path: "{{ dir | default(autostart_directory) }}"
+
+- name: Create Desktop Entry
+  copy:
+    dest: "{{ dir | default(autostart_directory) }}/{{ filename }}.desktop"
+    content: |
+      [Desktop Entry]
+      Name={{ app_name }}
+      Comment={{ description }}
+      Exec={{ executable }}
+      Icon={{ icon_path | default('') }}
+      Type=Application
+    mode: '0644'
diff --git a/tasks/general_templates/install_deb.yaml b/tasks/general_templates/install_deb.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..551857c3693f0baa3bb97b01194afa0f77fd8d7e
--- /dev/null
+++ b/tasks/general_templates/install_deb.yaml
@@ -0,0 +1,6 @@
+- name: Install deb
+  apt:
+    deb: "{{ installation_file }}"
+    state: present
+  become: true
+
diff --git a/tasks/general_templates/make_dir.yaml b/tasks/general_templates/make_dir.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6084868bc4ca4f4327e7cf8b378f2d3899ea282f
--- /dev/null
+++ b/tasks/general_templates/make_dir.yaml
@@ -0,0 +1,6 @@
+- name: Ensure directory
+  file:
+    path: "{{ path }}"
+    state: directory
+    mode: '0755'
+  become: "{{ become | default(false) }}"
diff --git a/tasks/general_templates/print_warning.yaml b/tasks/general_templates/print_warning.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6d6975993a23b664aeda8c9e3b6e3a5f6902f1eb
--- /dev/null
+++ b/tasks/general_templates/print_warning.yaml
@@ -0,0 +1,4 @@
+- name: Print Warning
+  shell:
+    cmd: echo "\033[1;33m[WARNING] {{ warning }}\033[0m" > /dev/tty
+  changed_when: false
diff --git a/tasks/general_templates/unzip.yaml b/tasks/general_templates/unzip.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6e2452da24d048ed4f057f8e62fb296e45d047dd
--- /dev/null
+++ b/tasks/general_templates/unzip.yaml
@@ -0,0 +1,2 @@
+- name: Install File
+  shell: unzip -d "{{ unzipped_path }}" "{{ installation_file }}"
diff --git a/tasks/general_templates/wget_install.yaml b/tasks/general_templates/wget_install.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..852e37a0212249c6b4c048564bc0fffc9294bfe0
--- /dev/null
+++ b/tasks/general_templates/wget_install.yaml
@@ -0,0 +1,21 @@
+- name: wget File
+  vars:
+    output_path: "{{ temporary_downloads_path }}/{{ wget_output_file }}"
+  block:
+    - name: Install wget
+      include_tasks: ../apt_templates/install_apt_package.yaml
+      vars:
+        app: wget
+
+    - name: Download File
+      shell: wget -q "{{ url }}" -O "{{ output_path }}"
+
+    - name: Install File
+      include_tasks: "{{ installation_task }}"
+      vars:
+        installation_file: "{{ output_path }}"
+
+    - name: wget Cleanup
+      file:
+        path: "{{ temporary_downloads_path }}/{{ wget_output_file }}"
+        state: absent
diff --git a/tasks/mainline/install_mainline_kernel.yaml b/tasks/mainline/install_mainline_kernel.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0ab0eec42d319ed9db19c39610cd458b473fa327
--- /dev/null
+++ b/tasks/mainline/install_mainline_kernel.yaml
@@ -0,0 +1,44 @@
+- name: Install Mainline Kernels
+  when: mainline_kernels
+  block:
+  - name: Add Mainline Kernel APT Repository
+    include_tasks: ../apt_templates/add_apt_repository.yaml
+    vars:
+      gpg_url: "{{ apt_repositories.mainline.gpg_url }}"
+      repository_url: "{{ apt_repositories.mainline.repository_url }}"
+      repository_branch: "{{ apt_repositories.mainline.repository_branch }}"
+      repository_name: "{{ apt_repositories.mainline.repository_name }}"
+
+  - name: Install Mainline (APT)
+    include_tasks: ../apt_templates/install_apt_package.yaml
+    vars:
+      app: mainline
+
+  - name: Resolve Kernel versions
+    set_fact:
+      kernel_versions: "{{ mainline_kernels.split() }}"
+  
+  - name: Install Mainline Kernels
+    shell: mainline install "{{ lookup('vars', ansible_loop_var) }}"
+    register: mainline_result
+    failed_when: > # mainline install returns 0 when the error occurs during installation
+      (mainline_result.rc != 0)
+      or ('error' in mainline_result.stdout.lower())
+      or ('failed' in mainline_result.stdout.lower())
+      or ('error' in mainline_result.stderr.lower())
+      or ('failed' in mainline_result.stderr.lower())
+    # failed_when: "'error' in mainline_result.stdout.lower()"
+    loop_control:
+      loop_var: kernel_version
+    loop: "{{ kernel_versions }}"
+    become: true
+    # ignore_errors: true
+
+  # - name: Debug stdout and stderr for mainline install
+  #   debug:
+  #     msg:
+  #       "{{ mainline_result.results }}"
+  #     # - "Condition 1: 'error' in stdout: {{ 'error' in mainline_result.results[0].stdout.lower() }}"
+  #     # - "Condition 2: 'failed' in stdout: {{ 'failed' in mainline_result.results[0].stdout.lower() }}"
+  #     # - "Condition 3: 'error' in stderr: {{ 'error' in mainline_result.results[0].stderr.lower() }}"
+  #     # - "Condition 4: 'failed' in stderr: {{ 'failed' in mainline_result.results[0].stderr.lower() }}"
diff --git a/tasks/mainline/upgrade_mainline_kernel.yaml b/tasks/mainline/upgrade_mainline_kernel.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e984dcfdfc5d83787bb15997a03c00c9fe1b32b5
--- /dev/null
+++ b/tasks/mainline/upgrade_mainline_kernel.yaml
@@ -0,0 +1,21 @@
+- name: Upgrade Mainline Kernel
+  block:
+    - name: Upgrade Mainline Kernel to latest minor version
+      command:
+        cmd: mainline install-minor
+      become: true
+      register: mainline_result
+      failed_when: > # mainline install returns 0 when the error occurs during installation, return code 1 means no updates
+        ((mainline_result.rc != 0) and (mainline_result.rc != 1))
+        or ('error' in mainline_result.stdout.lower())
+        or ('failed' in mainline_result.stdout.lower())
+        or ('error' in mainline_result.stderr.lower())
+        or ('failed' in mainline_result.stderr.lower())
+      changed_when: mainline_result.rc != 1
+
+    - name: Print Upgrade Restriction
+      include_tasks: ../general_templates/print_warning.yaml
+      loop_control:
+        loop_var: warning
+      loop:
+        - Kernel was updated to latest minor version, upgrading to a major version must be done manually
diff --git a/tasks/raw_packages.yaml b/tasks/raw_packages.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..049d9030d823468f43c2e4effd6f946909168ebf
--- /dev/null
+++ b/tasks/raw_packages.yaml
@@ -0,0 +1,70 @@
+- name: Install GitExtensions (Raw)
+  vars:
+    gitextensions_path: "{{ portable_programs_path }}/GitExtensions"
+    desktop_filename: gitextensions
+    desktop_app_name: GitExtensions
+    desktop_description: GitExtensions Git GUI
+  when: raw_packages is search('gitextensions:')
+  block:
+    - name: Ensure Programs directory
+      include_tasks: general_templates/make_dir.yaml
+      vars:
+        path: "{{ portable_programs_path }}"
+
+    - name: Remove old GitExtensions Installation
+      file:
+        path: "{{ gitextensions_path }}"
+        state: absent
+
+    - name: Install Mono (APT)
+      include_tasks: apt_templates/install_apt_package.yaml
+      vars:
+        app: mono-complete
+
+    - name: Install GitExtensions (Raw)
+      include_tasks: general_templates/wget_install.yaml
+      vars:
+        version: "{{ raw_packages | regex_search('gitextensions:([^\\s]+)', '\\1') | first | trim }}"
+        url: https://github.com/gitextensions/gitextensions/releases/download/v{{ version }}/GitExtensions-{{ version }}-Mono.zip
+        wget_output_file: gitextensions.zip
+        unzipped_path: "{{  portable_programs_path }}"
+        installation_task: unzip.yaml
+
+    - name: Create Application Entry
+      include_tasks: general_templates/create_desktop_file.yaml
+      vars:
+        dir: "{{ applications_directory }}"
+        filename: "{{ desktop_filename }}"
+        app_name: "{{ desktop_app_name }}"
+        description: "{{ desktop_description }}"
+        executable: "mono {{ gitextensions_path }}/GitExtensions.exe"
+        icon_path: "{{ gitextensions_path }}/git-extensions-logo-final-256.ico"
+
+    - name: Remove unsupported Plugins
+      vars:
+        plugins_dir: "{{ gitextensions_path }}/Plugins"
+      file:
+        path: "{{ lookup('vars', ansible_loop_var) }}"
+        state: absent
+      loop_control:
+        loop_var: raw_gitextensions_unsupported_plugin
+      loop:
+        - "{{ plugins_dir }}/Bitbucket.dll"
+
+    - name: Create Autostart Entry
+      include_tasks: general_templates/create_desktop_file.yaml
+      vars:
+        filename: "{{ desktop_filename }}"
+        app_name: "{{ desktop_app_name }}"
+        description: "{{ desktop_description }}"
+        executable: gtk-launch gitextensions
+      when: "'gitextensions' in autostart_applications"
+      
+
+- name: Install k3d (Raw)
+  include_tasks: general_templates/wget_install.yaml
+  vars:
+    url: https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh
+    wget_output_file: k3d.sh
+    installation_task: bash_installation.yaml
+  when: "'k3d' in raw_packages"
diff --git a/tasks/setup/dconf.yaml b/tasks/setup/dconf.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b920944641a17f972e08b8e97ccb64922cd91ace
--- /dev/null
+++ b/tasks/setup/dconf.yaml
@@ -0,0 +1,9 @@
+- name: Import DConf config
+  when: dconf_config_path
+  block:
+    - name: Install DConf Editor (APT)
+      include_tasks: ../apt_templates/packages/dconf.yaml
+
+    - name: Import DConf config
+      shell:
+        cmd: "dconf load / < {{ dconf_config_path | realpath }}"
diff --git a/tasks/setup/swap.yaml b/tasks/setup/swap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..78424ddc2d1905771068c18cd7465878638cdea3
--- /dev/null
+++ b/tasks/setup/swap.yaml
@@ -0,0 +1,97 @@
+- name: Create swaps
+  when: swap_sizes
+  vars:
+    swap_dir: "/swap"
+    swapfile_prefix: "swapfile"
+    swapfiles: {}
+  block:
+    - name: Ensure swap directory
+      include_tasks: ../general_templates/make_dir.yaml
+      vars:
+        path: "{{ swap_dir }}"
+        become: true
+
+    - name: Extract swap sizes
+      set_fact:
+        swapsizes: "{{ swap_sizes.split() }}"
+
+    - name: Get existing swapfiles
+      find:
+        paths: "{{ swap_dir }}"
+        patterns: "{{ swapfile_prefix }}*"
+        file_type: file
+      register: existing_swapfiles
+
+    - name: Extract the highest existing swapfile number
+      set_fact:
+        highest_number: >-
+          {{
+            existing_swapfiles.files | map(attribute='path')
+            | map('basename')
+            | map('regex_replace', '^' ~ swapfile_prefix ~ '(\d+)', '\g<1>')
+            | select('!=', None)
+            | map('int')
+            | max | default(-1)
+          }}
+
+    - name: Generate swapfile filenames
+      set_fact:
+        swapfile_number_suffix: "{{ '%04d' | format((highest_number | int) + 1 + swapfile_index) }}"
+        swapfiles: "{{ swapfiles | combine({swapfile_prefix + '%04d' | format((highest_number | int) + 1 + swapfile_index): swapsizes[swapfile_index]}) }}"
+      loop_control:
+        loop_var: swapfile_index
+      with_items: "{{ range(swapsizes | length) }}"
+
+    - name: Create swapfiles
+      include_tasks: swap/create_swapfile.yaml
+      vars:
+        # swapfile_prefix: "{{ swapfile_prefix }}"
+        swapfile_filename: "{{ swapfile_infos.key }}"
+        # swap_dir: "{{ swap_dir }}"
+        swapfile_size: "{{ swapfile_infos.value }}"
+      # debug:
+      #   msg: "{{ swapfile_infos.key }}: {{  swapfile_infos.value }}"
+      loop_control:
+        loop_var: swapfile_infos
+      with_items: "{{ swapfiles | dict2items }}"
+
+    # - name: Create swapfiles
+    #   loop_control:
+    #     loop_var: swapfile_index
+    #   with_items: "{{ range(swapsizes | length) }}"
+    #   block:
+    #     - name: Evaluate swapfile filename
+    #       set_fact:
+    #         swapfile_filename: "swapfile{{ '%04d' | format(highest_number + item) }}"
+    #         swapfile_path: "{{ swap_dir }}/{{ swapfile_filename }}"
+
+      #   - name: "Allocate file size for swapfile {{ swapfile_filename }}"
+      #     shell:
+      #       cmd: "fallocate -l {{ swap_sizes[item] }} {{ swapfile_path }}"
+      #     become: true
+
+      #   - name: "Setting permissions for swapfile {{ swapfile_filename }}"
+      #     file:
+      #       path: "{{ swapfile_path }}"
+      #       owner: root
+      #       group: root
+      #       mode: '0600'
+      #     become: true
+
+      #   - name: "Make swapfile from {{ swapfile_filename }}"
+      #     shell:
+      #       cmd: "mkswap {{ swapfile_filename }}"
+      #     become: true
+
+      #   - name: "Add swapfile {{ swapfile_filename }} to /etc/fstab"
+      #     blockinfile:
+      #       path: /etc/fstab
+      #       block: |
+      #         {{ swapfile_path }} none swap sw 0 0
+      #       state: present
+      #     become: true
+
+      #   - name: "Enable swapfile {{ swapfile_filename }}"
+      #     shell:
+      #       cmd: "swapon {{ swapfile_path }}"
+      #     become: true
diff --git a/tasks/setup/swap/create_swapfile.yaml b/tasks/setup/swap/create_swapfile.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2b6e30b9ac757cdfbb98fe279ff6aec20f12a350
--- /dev/null
+++ b/tasks/setup/swap/create_swapfile.yaml
@@ -0,0 +1,33 @@
+- name: Evaluate swapfile filename
+  set_fact:
+    swapfile_path: "{{ swap_dir }}/{{ swapfile_filename }}"
+
+- name: "Allocate {{ swapfile_size }} for swapfile {{ swapfile_filename }}"
+  shell:
+    cmd: "fallocate -l {{ swapfile_size }} {{ swapfile_path }}"
+  become: true
+
+- name: "Setting permissions for swapfile {{ swapfile_filename }}"
+  file:
+    path: "{{ swapfile_path }}"
+    owner: root
+    group: root
+    mode: '0600'
+  become: true
+
+- name: "Make swapfile from {{ swapfile_filename }}"
+  shell:
+    cmd: "mkswap {{ swapfile_path }}"
+  become: true
+
+- name: "Add swapfile {{ swapfile_filename }} to /etc/fstab"
+  lineinfile:
+    path: /etc/fstab
+    line: "{{ swapfile_path }} none swap sw 0 0"
+    state: present
+  become: true
+
+- name: "Enable swapfile {{ swapfile_filename }}"
+  shell:
+    cmd: "swapon {{ swapfile_path }}"
+  become: true
diff --git a/tasks/setup/vscode_extensions.yaml b/tasks/setup/vscode_extensions.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b2d5d1cf98b1849cc5db31dc3697e1abe362421c
--- /dev/null
+++ b/tasks/setup/vscode_extensions.yaml
@@ -0,0 +1,18 @@
+- name: Install Visual Studio Code Extensions
+  when: vscode_extensions_path
+  block:
+    - name: Read Visual Studio Code Extensions from File
+      slurp:
+        src: "{{ vscode_extensions_path | realpath }}"
+      register: vscode_extensions_file_content
+
+    - name: Decode Visual Studio Code Extensions File Content
+      set_fact:
+        vscode_extensions: "{{ vscode_extensions_file_content['content'] | b64decode | split('\n') }}"
+
+    - name: Install Visual Studio Code Extensions
+      shell:
+        cmd: "code --install-extension {{ vscode_extension }}"
+      loop_control:
+        loop_var: vscode_extension
+      with_items: "{{ vscode_extensions }}"
diff --git a/tasks/setup/vscode_settings.yaml b/tasks/setup/vscode_settings.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e271016dd66d0ba4fe119fd4e703c84343c916c1
--- /dev/null
+++ b/tasks/setup/vscode_settings.yaml
@@ -0,0 +1,26 @@
+- name: Import Visual Studio Code User Settings
+  when: vscode_config_path
+  vars:
+    vscode_user_settings_path: "{{ ansible_env.HOME }}/.config/Code/User"
+    vscode_user_settings_file: "{{ vscode_user_settings_path }}/settings.json"
+  block:
+    - name: Ensure Visual Studio Code Config Directory
+      include_tasks: ../general_templates/make_dir.yaml
+      vars:
+        path: "{{ vscode_user_settings_path }}"
+
+    - name: Remove current Visual Studio Code User Settings
+      file:
+        path: "{{ vscode_user_settings_file }}"
+        state: absent
+
+    - name: Link Visual Studio Code User Settings
+      shell:
+        cmd: "ln -s {{ vscode_config_path | realpath }} {{ vscode_user_settings_file }}"
+
+    - name: Print Visual Studio Code User Settings Warnings
+      include_tasks: ../general_templates/print_warning.yaml
+      loop_control:
+        loop_var: warning
+      loop:
+        - The Visual Studio Code User Settings were dynamically linked. Please don't remove the source.
diff --git a/tasks/snap_packages.yaml b/tasks/snap_packages.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b7b7a2ae081043cae6b470524b962dc66bcf765d
--- /dev/null
+++ b/tasks/snap_packages.yaml
@@ -0,0 +1,64 @@
+- name: Install VS Code (Snap)
+  block:
+    - name: Install Visual Studio Code (Snap)
+      include_tasks: snap_templates/install_snap_package.yaml
+      vars:
+        app:
+          id: code
+          classic: true
+
+    - name: Create Autostart Entry
+      include_tasks: general_templates/create_desktop_file.yaml
+      vars:
+        filename: snap_vscode
+        app_name: Visual Studio Code
+        executable: code
+        description: Visual Studio Code IDE
+      when: "'vscode' in autostart_applications"
+  when: "'vscode' in snap_packages"
+
+- name: Install JetBrains Rider (Snap)
+  block:
+    - name: Install JetBrains Rider (Snap)
+      include_tasks: snap_templates/install_snap_package.yaml
+      vars:
+        app:
+          id: rider
+          classic: true
+
+    - name: Create Autostart Entry
+      include_tasks: general_templates/create_desktop_file.yaml
+      vars:
+        filename: snap_rider
+        app_name: JetBrains Rider
+        executable: rider
+        description: JetBrains Rider IDE
+      when: "'rider' in autostart_applications"
+  when: "'rider' in snap_packages"
+
+- name: Install kubectl (Snap)
+  include_tasks: snap_templates/install_snap_package.yaml
+  vars:
+    app:
+      id: rider
+      classic: true
+  when: "'kubectl' in snap_packages"
+
+- name: Install Firefox (Snap)
+  block:
+    - name: Install Firefox (Snap)
+      include_tasks: snap_templates/install_snap_package.yaml
+      vars:
+        app:
+          id: firefox
+
+    - name: Create Autostart Entry
+      include_tasks: general_templates/create_desktop_file.yaml
+      vars:
+        filename: snap_firefox
+        app_name: Firefox
+        executable: firefox
+        description: Firefox Web Browser
+      when: "'firefox' in autostart_applications"
+  when: "'firefox' in snap_packages"
+
diff --git a/tasks/snap_templates/install_snap_package.yaml b/tasks/snap_templates/install_snap_package.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9ecdd41cc61dc85d65ff58e329b7b931c689776c
--- /dev/null
+++ b/tasks/snap_templates/install_snap_package.yaml
@@ -0,0 +1,4 @@
+- name: Install Snap package
+  command: 
+    cmd: snap install {{ app.id }} {% if app.classic | default(false) %}--classic{% endif %}
+  become: true
diff --git a/tasks/snap_templates/upgrade_snap_packages.yaml b/tasks/snap_templates/upgrade_snap_packages.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3982a29995d06f968ca11ed2b78c7bc528f08931
--- /dev/null
+++ b/tasks/snap_templates/upgrade_snap_packages.yaml
@@ -0,0 +1,4 @@
+- name: Upgrade Snap packages
+  command: 
+    cmd: snap refresh
+  become: true
diff --git a/update.sh b/update.sh
index d116e9255a74ff499dcd5c2038d72b49b7dad9b2..c346a42d67aef358d51f25f7551a6f7e6331d51a 100644
--- a/update.sh
+++ b/update.sh
@@ -1,9 +1,90 @@
 #!/bin/bash
 set -e
-source installer_vars.sh
-source source_if_options_not_sourced.sh
-source install_functions.sh
-source_if_options_not_sourced
+INSTALLER_DIR=$(dirname "${BASH_SOURCE[0]}")
+HELPER_SCRIPTS_DIR="$INSTALLER_DIR/helper_scripts"
 
-check_if_root
-update_upgrade
+source "$HELPER_SCRIPTS_DIR/package_manager_identifiers.sh"
+
+declare -A PACKAGE_MANAGERS
+PACKAGE_MANAGERS=(
+    ["$APT_IDENTIFIER"]="APT"
+    ["$SNAP_IDENTIFIER"]="Snap"
+    ["$FLATPAK_IDENTIFIER"]="Flatpak"
+    ["$MAINLINE_KERNEL_IDENTIFIER"]="Mainline Kernel"
+)
+
+DEFAULT_PACKAGE_MANAGERS=(
+    "$APT_IDENTIFIER"
+)
+
+ORDERED_PACKAGE_MANAGERS=(
+    "$APT_IDENTIFIER"
+    "$FLATPAK_IDENTIFIER"
+    "$SNAP_IDENTIFIER"
+    "$MAINLINE_KERNEL_IDENTIFIER"
+)
+
+command_exists() {
+    cmd=$1
+
+    if command -v $cmd &> /dev/null
+    then
+        true
+    else
+        false
+    fi
+}
+
+main() {
+    possible_package_managers=("${DEFAULT_PACKAGE_MANAGERS[@]}")
+
+    if command_exists flatpak; then
+        possible_package_managers+=("$FLATPAK_IDENTIFIER")
+    fi
+
+    if command_exists snap; then
+        possible_package_managers+=("$SNAP_IDENTIFIER")
+    fi
+
+    if command_exists mainline; then
+        possible_package_managers+=("$MAINLINE_KERNEL_IDENTIFIER")
+    fi
+
+    update_package_managers=$(for package_manager in "${ORDERED_PACKAGE_MANAGERS[@]}"; do
+        for possible_package_manager in "${possible_package_managers[@]}"; do
+            if [[ "$package_manager" == "$possible_package_manager" ]]; then
+                echo "true"
+                echo "${PACKAGE_MANAGERS["$package_manager"]}"
+                echo "$package_manager"
+            fi
+        done
+    done | zenity --list \
+        --title="Update Selection" \
+        --text="Select package managers to update:" \
+        --checklist \
+        --column="Update" --column="Package Manager" --column="Identifier" \
+        --print-column "3" \
+        --width=600 --height=400 \
+        2>/dev/null # suppress file descriptor error
+    )
+
+    update_package_managers="${update_package_managers//|/' '}"
+
+    # Update packages using ansible
+    $HELPER_SCRIPTS_DIR/install_ansible.sh
+    ansible-playbook "${INSTALLER_DIR}/playbooks/update_packages.yaml" \
+        --extra-vars "package_managers='$update_package_managers'" \
+        --inventory "${INSTALLER_DIR}/ansible_inventory.ini" \
+        --ask-become-pass
+}
+
+main
+
+# set -e
+# source installer_vars.sh
+# source source_if_options_not_sourced.sh
+# source install_functions.sh
+# source_if_options_not_sourced
+
+# check_if_root
+# update_upgrade
diff --git a/variables/editable_variables.yaml b/variables/editable_variables.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9211f2b5894a38b68de935ce5dfbab58bd5ab24c
--- /dev/null
+++ b/variables/editable_variables.yaml
@@ -0,0 +1,2 @@
+portable_programs_path: "{{ ansible_env.HOME }}/Programs"
+temporary_downloads_path: "."
diff --git a/variables/package_groups.yaml b/variables/package_groups.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..68a6d93cde4b0c72c0f5bbb4b9729116f0b73a32
--- /dev/null
+++ b/variables/package_groups.yaml
@@ -0,0 +1,3 @@
+package_groups:
+  docker: docker
+  virtualbox: vboxusers
diff --git a/variables/repositories/apt.yaml b/variables/repositories/apt.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fd35a759fa5985ab662186c8d138207b1cec67ff
--- /dev/null
+++ b/variables/repositories/apt.yaml
@@ -0,0 +1,24 @@
+apt_repositories:
+  docker:
+    gpg_url: https://download.docker.com/linux/ubuntu/gpg
+    repository_url: https://download.docker.com/linux/ubuntu
+    repository_branch: stable
+    repository_name: docker
+
+  virtualbox:
+    gpg_url: https://www.virtualbox.org/download/oracle_vbox_2016.asc
+    repository_url: https://download.virtualbox.org/virtualbox/debian
+    repository_branch: contrib
+    repository_name: virtualbox
+
+  synaptics:
+    deb_url: https://www.synaptics.com/sites/default/files/Ubuntu/pool/stable/main/all/synaptics-repository-keyring.deb
+
+  proton:
+    deb_url: https://repo.protonvpn.com/debian/dists/stable/main/binary-all/protonvpn-stable-release_{{ repository_version | default('undefined') }}_all.deb
+
+  mainline:
+    gpg_url: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3ae27527713d2479dcaffd58a89d7c1b2f76304d
+    repository_url: https://ppa.launchpadcontent.net/cappelikan/ppa/ubuntu
+    repository_branch: main
+    repository_name: mainline
diff --git a/variables/repositories/flatpak.yaml b/variables/repositories/flatpak.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..edc448f8494d3addf25d93c9c0151e4cebc452b1
--- /dev/null
+++ b/variables/repositories/flatpak.yaml
@@ -0,0 +1,4 @@
+flatpak_repositories:
+  flathub:
+    name: flathub
+    url: https://dl.flathub.org/repo/flathub.flatpakrepo