diff --git a/.gitignore b/.gitignore
index ffdfc5a1b258344c3c77b156362efcd922f899cd..c6fa6bf9ac17771e48f714bec9f8b03930023f76 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,5 @@
 SkywardHub.pro.user
 SkywardHub.pro.user.*
-.build
 build/**
 **/.DS_Store
 Deploy/*
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 8b8f9068e0501fd9b122b1df720c3f68a9560e09..fee18e3da98f25290ed429e4df20d4cb10f71a81 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -110,7 +110,7 @@
         "qcloseevent": "cpp",
         "qthread": "cpp"
     },
-    "editor.defaultFormatter": "chiehyu.vscode-astyle",
+    "editor.defaultFormatter": "ms-vscode.cpptools",
     "[xml]": {
         "editor.defaultFormatter": "redhat.vscode-xml"
     },
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 13c7a13416a72d597d0c9824476839fd270ab7f5..c39ce72eaa5e2c9ecdc1fd2962846c334fd0c47a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,7 +13,7 @@ find_package(Qt5 COMPONENTS Widgets REQUIRED)
 find_package(Qt5 COMPONENTS SerialPort REQUIRED)
 find_package(Qt5 COMPONENTS PrintSupport REQUIRED)
 
-add_executable(skywardhub
+add_executable(groundstation
     Components/ContextMenuSeparator/contextmenuseparator.cpp
     Components/ModulesPicker/modulespicker.cpp
     Components/SaveConfigurationDialog/saveconfigurationdialog.cpp
@@ -70,7 +70,7 @@ add_executable(skywardhub
     main.cpp
     application.qrc
 )
-target_include_directories(skywardhub PRIVATE ./)
-target_link_libraries(skywardhub Qt5::Widgets)
-target_link_libraries(skywardhub Qt5::SerialPort)
-target_link_libraries(skywardhub Qt5::PrintSupport)
+target_include_directories(groundstation PRIVATE ./)
+target_link_libraries(groundstation Qt5::Widgets)
+target_link_libraries(groundstation Qt5::SerialPort)
+target_link_libraries(groundstation Qt5::PrintSupport)
diff --git a/sbs b/sbs
new file mode 100755
index 0000000000000000000000000000000000000000..6a45fcda52663e9a3797e5626111d63b292d562e
--- /dev/null
+++ b/sbs
@@ -0,0 +1,391 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021 Skyward Experimental Rocketry
+# Author: Damiano Amatruda, Alberto Nidasio
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+print_banner() {
+    cat <<EOF
++------------------------------------------------------------------------------------------+
+|  ____  _                                _                                                |
+| / ___|| | ___   ___      ____ _ _ __ __| |                                               |
+| \\___ \\| |/ / | | \\ \\ /\\ / / _\` | '__/ _\` |                                               |
+|  ___) |   <| |_| |\\ V  V / (_| | | | (_| |                                               |
+| |____/|_|\\_\\\\__, | \\_/\\_/ \\__,_|_|  \\__,_|                                               |
+|  ____       |___/    _   ____            _                    __               ___  _    |
+| | __ ) _   _(_) | __| | / ___| _   _ ___| |_ ___ _ __ ___    / _| ___  _ __   / _ \\| |_  |
+| |  _ \\| | | | | |/ _\` | \\___ \\| | | / __| __/ _ \\ '_ \` _ \\  | |_ / _ \\| '__| | | | | __| |
+| | |_) | |_| | | | (_| |  ___) | |_| \\__ \\ ||  __/ | | | | | |  _| (_) | |    | |_| | |_  |
+| |____/ \\__,_|_|_|\\__,_| |____/ \\__, |___/\\__\\___|_| |_| |_| |_|  \\___/|_|     \\__\\_\\\\__| |
++---------------------------------|___/-----------------------------------------------v1.0-+
+
+EOF
+}
+
+ohai() {
+    printf "\n${TTY_BLUE}==>${TTY_RESET}${TTY_BOLD} %s${TTY_RESET}\n" "$@"
+}
+
+init_dirs() {
+    sbs_base="$(cd -- "$(dirname "$0")" > /dev/null 2>&1 && pwd -P)"
+    source_dir="$PWD"
+    build_dir="$source_dir/$BUILD_DIRNAME"
+}
+
+find_deps() {
+    ohai "Find dependencies"
+    
+    command -v cmake               > /dev/null 2>&1 && found_cmake=true
+    command -v ccache              > /dev/null 2>&1 && found_ccache=true
+    command -v ninja               > /dev/null 2>&1 && found_ninja=true
+    command -v python              > /dev/null 2>&1 && found_python=true
+    command -v cppcheck            > /dev/null 2>&1 && found_cppcheck=true
+    command -v clang-tidy          > /dev/null 2>&1 && found_clangtidy=true
+    command -v clang-format        > /dev/null 2>&1 && found_clangformat=true
+    
+    printf "Found CMake: ";               [ "$found_cmake" = true ]       && echo "yes" || echo "no"
+    printf "Found Ccache: ";              [ "$found_ccache" = true ]      && echo "yes" || echo "no"
+    printf "Found Ninja: ";               [ "$found_ninja" = true ]       && echo "yes" || echo "no"
+    printf "Found Python: ";              [ "$found_python" = true ]      && echo "yes" || echo "no"
+    printf "Found Cppcheck: ";            [ "$found_cppcheck" = true ]    && echo "yes" || echo "no"
+    printf "Found clang-tidy: ";          [ "$found_clangtidy" = true ]   && echo "yes" || echo "no"
+    printf "Found clang-format: ";        [ "$found_clangformat" = true ] && echo "yes" || echo "no"
+    
+    [ "$found_cmake" = true ]     || { echo "Error: CMake must be installed"; return 1; }
+}
+
+# Workaround: Disable tests in excluded subdirectories
+# See: https://gitlab.kitware.com/cmake/cmake/-/issues/20212
+cmake_disable_excluded_tests() {
+    declare build_dir="$1"
+    
+    [ ! -f "$build_dir/$CTEST_FILENAME" ] || sed -i.bak 's/^subdirs/# subdirs/' "$build_dir/$CTEST_FILENAME"
+}
+
+configure() {
+    declare build_dir="$1"
+    
+    ohai "Configure"
+    
+    declare -a defs=(-DCMAKE_EXPORT_COMPILE_COMMANDS=ON)
+    defs+=(-DCMAKE_CXX_FLAGS=-fdiagnostics-color=always)
+    [ "$found_ccache" = true ]   && defs+=(-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache)
+    [ "$config_debug" = true ]   && defs+=(-DCMAKE_BUILD_TYPE=Debug) || defs+=(-DCMAKE_BUILD_TYPE=Release)
+    [ "$config_verbose" = true ] && defs+=(-DCMAKE_VERBOSE_MAKEFILE=ON)
+    
+    declare gen
+    [ "$found_ninja" = true ] && gen=-GNinja || gen=-G"Unix Makefiles"
+    
+    cmake -B"$build_dir" "${defs[@]}" "$gen" "$source_dir" || return
+    
+    { [ "$config_debug" = true ]   && touch "$build_dir/$DEBUG_FILENAME";   } || rm -f "$build_dir/$DEBUG_FILENAME"
+    { [ "$config_verbose" = true ] && touch "$build_dir/$VERBOSE_FILENAME"; } || rm -f "$build_dir/$VERBOSE_FILENAME"
+}
+
+check_configured() {
+    declare build_dir="$1"
+    
+    declare to_reconfigure=false
+    if [ ! -d "$build_dir" ]; then
+        to_reconfigure=true
+        elif [ ! -f "$build_dir/$CMAKE_FILENAME" ]; then
+        rm -rf "$build_dir"
+        to_reconfigure=true
+    else
+        [ -f "$build_dir/$DEBUG_FILENAME" ]   && found_debug=true   || found_debug=false
+        [ -f "$build_dir/$VERBOSE_FILENAME" ] && found_verbose=true || found_verbose=false
+        if [ "$config_debug" != "$found_debug" ] \
+        || [ "$config_verbose" != "$found_verbose" ]; then
+            to_reconfigure=true
+        fi
+    fi
+    
+    if [ "$to_reconfigure" = true ]; then
+        configure "$build_dir"
+    fi
+}
+
+build() {
+    declare build_dir="$1"
+    declare target="$2"
+    
+    check_configured "$build_dir" || return
+    
+    ohai "Build"
+    
+    declare -a opts
+    get_build_opts opts
+    
+    cmake --build "$build_dir" "${opts[@]}" --target "$target"
+}
+
+build_all() {
+    declare build_dir="$build_dir"
+    
+    build "$build_dir" all
+}
+
+clean() {
+    declare build_desc="$1"
+    declare build_dir="$2"
+    
+    ohai "Clean ($build_desc)"
+    
+    if [ -f "$build_dir/$CMAKE_FILENAME" ]; then
+        declare -a opts
+        get_build_opts opts
+        
+        cmake --build "$build_dir" "${opts[@]}" --target clean
+    fi
+    
+    echo "Removing build folder..."
+    rm -rf "$build_dir"
+}
+
+clean_all() {
+    clean "Default" "$build_dir"
+    clean "Host" "$build_host_dir"
+}
+
+run() {
+    declare build_dir="$1"
+    declare target="$2"
+    
+    ohai "Run"
+    
+    $build_dir/$target
+}
+
+list() {
+    declare build_dir="$build_dir"
+    
+    check_configured "$build_dir" || return
+    
+    ohai "List targets"
+    
+    declare -a opts
+    get_build_opts opts
+    
+    echo "[1/1] All SBS targets available:"
+    cmake --build "$build_dir" "${opts[@]}" --target help \
+    | grep -Po '^.*/\K\w*(?=_autogen)' | uniq
+}
+
+lint_copyright() {
+    ohai "Lint (Copyright)"
+    
+    "$sbs_base/scripts/linter.py" --copyright "$source_dir/src"
+}
+
+lint_find() {
+    ohai "Lint (Find)"
+    
+    "$sbs_base/scripts/linter.py" --find "$source_dir/src"
+}
+
+lint_clangtidy() {
+    declare build_dir="$1"
+    
+    check_configured "$build_dir" || return
+    
+    ohai "Lint (clang-tidy)"
+    
+    defs=(--extra-arg=-D_MIOSIX=1 --extra-arg=-D_MIOSIX_GCC_PATCH_MINOR=1 \
+    --extra-arg=-D_MIOSIX_GCC_PATCH_MAJOR=3 --extra-arg=-D__LINT__)
+    IFS=$'\n' read -rd '' -a incs < \
+    <(arm-miosix-eabi-g++ -E -Wp,-v -xc++ /dev/null 2>&1 \
+    | sed -n "s/^ /--extra-arg=-isystem/p")
+    
+    declare opts=()
+    [ "$to_edit" = true ] && opts+=(--fix-notes --fix-errors)
+    
+    find "$source_dir/src" \
+    -type f \( -iname "*.cpp" -o -iname "*.h" -o -iname "*.c" \) \
+    -exec clang-tidy --header-filter=".*" -p="$build_dir" "${defs[@]}" \
+    "${incs[@]}" "${opts[@]}" {} \;
+}
+
+lint_cppcheck() {
+    ohai "Lint (Cppcheck)"
+    
+    declare -a opts=()
+    [ -n "$jobs" ] && opts+=("-j $jobs")
+    
+    cppcheck --language=c++ --std=c++11 --enable=all --inline-suppr \
+    --suppress=unmatchedSuppression --suppress=unusedFunction \
+    --suppress=missingInclude --error-exitcode=1 "${opts[@]}" \
+    "$source_dir/src"
+}
+
+lint_clangformat() {
+    declare to_edit="$1"
+    
+    ohai "Lint (clang-format)"
+    
+    declare -a opts=(--style=file --Werror)
+    [ "$to_edit" = true ] && opts+=(-i) || opts+=(--dry-run)
+    
+    find "$source_dir/src" \
+    -type f \( -iname "*.cpp" -o -iname "*.h" -o -iname "*.c" \) \
+    -exec clang-format "${opts[@]}" {} \;
+}
+
+lint() {
+    declare to_edit="$1"
+    
+    if [ "$found_python" = true ]; then
+        lint_copyright
+        lint_find
+    fi
+    
+    if [ "$found_clangtidy" = true ] && [ "$lint_clangtidy" = true ]; then
+        lint_clangtidy "$build_dir"
+    fi
+    
+    if [ "$found_cppcheck" = true ]; then
+        lint_cppcheck
+    fi
+    
+    if [ "$found_clangformat" = true ]; then
+        lint_clangformat "$to_edit"
+    fi
+}
+
+set_debug() {
+    config_debug=true
+}
+
+set_verbose() {
+    config_verbose=true
+}
+
+set_jobs() {
+    jobs="$1"
+}
+
+get_build_opts() {
+    declare -n build_opts=$1
+    [ -n "$jobs" ] && build_opts=("-j $jobs")
+}
+
+set_clangtidy() {
+    lint_clangtidy=true
+}
+
+usage() {
+    echo
+    cat <<EOF
+Usage: $(basename "$0") [OPTIONS]
+
+OPTIONS:
+  General Options:
+    -h, --help            Show this help message and exit
+    -j JOBS, --jobs JOBS  Build or lint in parallel using a specific number of jobs
+    -l, --list            List all targets available
+
+  Build Options:
+    -b TARGET, --build TARGET
+                          Build a specific target
+    -r TARGET, --run TARGET
+                          Build and run a specific target
+    -c, --clean           Clean the working tree
+    -u, --configure       Force configure and do not build
+    -d, --debug           Enable debug
+    -v, --verbose         Print a verbose output
+
+  Lint Options:
+    -n, --lint            Lint the code
+    -e, --edit            Lint and edit the code
+    --clang-tidy          Lint using also clang-tidy
+EOF
+}
+
+CMAKE_FILENAME="CMakeCache.txt"
+CMAKE_PREFIX_PATH="~/Qt/5.15.2/gcc_64/lib/cmake/"
+DEBUG_FILENAME=".sbsdebug"
+VERBOSE_FILENAME=".sbsverbose"
+BUILD_DIRNAME="build"
+TTY_BLUE="\033[34m"
+TTY_BOLD="\033[1m"
+TTY_RESET="\033[0m"
+
+sbs_base=
+source_dir=
+build_dir=
+build_host_dir=
+toolchain_file=
+found_cmake=false
+found_miosixgpp=false
+found_ccache=false
+found_ninja=false
+found_python=false
+found_cppcheck=false
+found_clangtidy=false
+found_clangformat=false
+found_stflash=false
+found_stlink=false
+config_debug=false
+config_verbose=false
+jobs=
+lint_clangtidy=false
+
+print_banner
+init_dirs
+
+for arg in "$@"; do
+    shift
+    case "$arg" in
+        --build)      set -- "$@" "-b";;
+        --clang-tidy) set_clangtidy;;
+        --clean)      set -- "$@" "-c";;
+        --configure)  set -- "$@" "-u";;
+        --debug)      set -- "$@" "-d";;
+        --edit)       set -- "$@" "-e";;
+        --run)        set -- "$@" "-r";;
+        --help)       set -- "$@" "-h";;
+        --jobs)       set -- "$@" "-j";;
+        --lint)       set -- "$@" "-n";;
+        --list)       set -- "$@" "-l";;
+        --test)       set -- "$@" "-t";;
+        --verbose)    set -- "$@" "-v";;
+        *)            set -- "$@" "$arg"
+    esac
+done
+
+while getopts b:cder:hj:lnt:uv opt; do
+    case "$opt" in
+        b) find_deps && build "$build_dir" "$OPTARG"; exit;;
+        c) find_deps && clean_all; exit;;
+        d) set_debug;;
+        e) find_deps && lint true; exit;;
+        r) find_deps && build "$build_dir" "$OPTARG" && run "$build_dir" "$OPTARG"; exit;;
+        h) usage; exit 0;;
+        j) set_jobs "$OPTARG";;
+        l) find_deps && list; exit;;
+        n) find_deps && lint false; exit;;
+        t) find_deps && run_tests "$OPTARG"; exit;;
+        u) find_deps && configure "$build_dir"; exit;;
+        v) set_verbose;;
+        ?) usage; exit 2;;
+    esac
+done
+shift $((OPTIND - 1))
+
+find_deps && build_all
diff --git a/scripts/linter.py b/scripts/linter.py
new file mode 100755
index 0000000000000000000000000000000000000000..a0c8297311cc4c8ccd1331675cc38081a1dc40b2
--- /dev/null
+++ b/scripts/linter.py
@@ -0,0 +1,335 @@
+#!/usr/bin/python3
+
+# Copyright (c) 2021 Skyward Experimental Rocketry
+# Author: Alberto Nidasio
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the 'Software'), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+# The linter script offers a lot of functionalities:
+# - Checks for the right copyright notice in all .h and .cpp files
+# - Checks if all .h and .cpp files respects the clang format specified in .clang-format file
+# - Checks if some .h or .cpp files have printfs, asserts or some string used in them
+
+import re
+from collections import Counter
+from subprocess import DEVNULL, STDOUT, call, run, check_output, CalledProcessError
+from argparse import ArgumentParser, RawTextHelpFormatter
+from os import pathconf, walk
+from os.path import join, isdir
+
+# Copyright template for C++ code files and headers
+CPP_TEMPLATE = r'\/\* Copyright \(c\) 20\d\d(?:-20\d\d)? Skyward Experimental Rocketry\n' + \
+    r' \* (Authors?): (.+)\n' + \
+    r' \*\n' + \
+    r' \* Permission is hereby granted, free of charge, to any person obtaining a copy\n' + \
+    r' \* of this software and associated documentation files \(the "Software"\), to deal\n' + \
+    r' \* in the Software without restriction, including without limitation the rights\n' + \
+    r' \* to use, copy, modify, merge, publish, distribute, sublicense, and\/or sell\n' + \
+    r' \* copies of the Software, and to permit persons to whom the Software is\n' + \
+    r' \* furnished to do so, subject to the following conditions:\n' + \
+    r' \*\n' + \
+    r' \* The above copyright notice and this permission notice shall be included in\n' + \
+    r' \* all copies or substantial portions of the Software.\n' + \
+    r' \*\n' + \
+    r' \* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n' + \
+    r' \* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n' + \
+    r' \* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n' + \
+    r' \* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n' + \
+    r' \* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n' + \
+    r' \* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n' + \
+    r' \* THE SOFTWARE.\n' + \
+    r' \*\/'
+AUTHOR_DELIMITER = ','
+
+
+def config_cmd_parser():
+    parser = ArgumentParser(
+        description='The linter script offers a lot of functionalities but it does not modify any file. If no option is specified everything will be checked.',
+        formatter_class=RawTextHelpFormatter)
+    parser.add_argument('directory', nargs='?',
+                        help='Directory where to search files')
+    parser.add_argument(
+        '--copyright', dest='copyright',
+        action='store_true', help='Checks for the right copyright notice in all .h and .cpp files')
+    parser.add_argument(
+        '--format', dest='format',
+        action='store_true', help='Checks if all .h and .cpp files respects the clang format specified in .clang-format file')
+    parser.add_argument(
+        '--find', dest='find',
+        action='store_true', help='Checks if some .h or .cpp files have printfs, asserts or some string used in them')
+    parser.add_argument(
+        '--cppcheck', dest='cppcheck',
+        action='store_true', help='Runs cppcheck for static code analysis')
+    parser.add_argument('-q', '--quiet', dest='quiet',
+                        action='store_true', help='Output only essential messages')
+    return parser
+
+
+def print_banner():
+    # Font: Ivrit
+    print('+------------------------------+')
+    print('|  _     _       _             |')
+    print('| | |   (_)_ __ | |_ ___ _ __  |')
+    print('| | |   | | \'_ \| __/ _ \ \'__| |')
+    print('| | |___| | | | | ||  __/ |    |')
+    print('| |_____|_|_| |_|\__\___|_|    |')
+    print('+------------------------------+')
+
+
+def linter_print(*strings):
+    print('[linter]', *strings)
+
+
+class Colors():
+    BLACK = '\033[30m'
+    RED = '\033[31m'
+    GREEN = '\033[32m'
+    YELLOW = '\033[33m'
+    BLUE = '\033[34m'
+    MAGENTA = '\033[35m'
+    CYAN = '\033[36m'
+    WHITE = '\033[37m'
+    UNDERLINE = '\033[4m'
+    RESET = '\033[0m'
+
+
+# Checks for the right copyright notice in all .h and .cpp files
+def check_copyright(directory):
+    linter_print(Colors.GREEN + 'Copyright check' + Colors.RESET)
+
+    # Statistics
+    totalCheckdFilesCounter = 0
+    filesWithErrorsCounter = 0
+    authors = {}
+    averageAuthorsPerFile = 0
+
+    # Walk through the directory and check each file
+    for dirpath, dirnames, filenames in walk(directory):
+        for filename in [f for f in filenames if f.endswith(('.cpp', '.h'))]:
+            totalCheckdFilesCounter += 1
+
+            # Prepare the complete filepath
+            currentFilepath = join(dirpath, filename)
+
+            # Check the current file
+            with open(currentFilepath) as file:
+                match = re.search(CPP_TEMPLATE, file.read())
+                if not match:
+                    filesWithErrorsCounter += 1
+
+                    # The file's copyright notice does not match the template!
+                    linter_print(Colors.YELLOW + 'Wrong copyright notice in file {0}'.format(
+                        currentFilepath) + Colors.RESET)
+                else:
+                    fileAuthors = [a.strip()
+                                   for a in match.group(2).split(AUTHOR_DELIMITER)]
+
+                    # Check the number of authors against 'Author' or `Authors`
+                    if len(fileAuthors) == 1 and match.group(1)[-1] == 's':
+                        linter_print('\'Authors\' should to be changed to \'Author\' in {0}'.format(
+                            currentFilepath))
+                    if len(fileAuthors) > 1 and match.group(1)[-1] != 's':
+                        linter_print('\'Author\' should to be changed to \'Authors\' in {0}'.format(
+                            currentFilepath))
+
+                    # Save statistics on authors
+                    for author in fileAuthors:
+                        if author in authors:
+                            authors[author] += 1
+                        else:
+                            authors[author] = 1
+                    averageAuthorsPerFile += len(fileAuthors)
+    averageAuthorsPerFile /= totalCheckdFilesCounter
+
+    linter_print('Checked {} files'.format(totalCheckdFilesCounter))
+    if filesWithErrorsCounter == 0:
+        linter_print('All the files have the correct copyright notice')
+    else:
+        linter_print(Colors.RED + '{:.1f}% ({}/{}) of all analyzed files do not match with the copyright template!'.format(
+            100*filesWithErrorsCounter/totalCheckdFilesCounter, filesWithErrorsCounter, totalCheckdFilesCounter) + Colors.RESET)
+
+    if(not args.quiet):
+        linter_print('{:.2} authors per file'.format(
+            averageAuthorsPerFile))
+        linter_print('Number of mentions per author:')
+        for author in authors:
+            linter_print('{:3} - {}'.format(authors[author], author))
+
+    # Exit if error if at least one file isn't correct
+    if(filesWithErrorsCounter > 0):
+        exit(-1)
+
+
+# Checks if all .h and .cpp files respects the clang format specified in .clang-format file
+def check_format(directory):
+    linter_print(Colors.GREEN + 'Formatting check' + Colors.RESET)
+
+    # Statistics
+    totalCheckdFilesCounter = 0
+    filesWithErrorsCounter = 0
+
+    # Walk throgh the directory and check each file
+    for dirpath, dirnames, filenames in walk(directory):
+        for filename in [f for f in filenames if f.endswith(('.cpp', '.h', 'c'))]:
+            totalCheckdFilesCounter += 1
+
+            # Prepare the complete filepath
+            currentFilepath = join(dirpath, filename)
+
+            # Dry run clang-format and check if we have an error
+            returnCode = call(
+                ['clang-format', '-style=file', '--dry-run', '--Werror', '--ferror-limit=1', currentFilepath], stderr=DEVNULL)
+
+            # If and error occurs warn the user
+            if(returnCode != 0):
+                filesWithErrorsCounter += 1
+
+                if(not args.quiet):
+                    linter_print(Colors.YELLOW + 'Wrong code format for file {1}'.format(
+                        returnCode, currentFilepath) + Colors.RESET)
+
+    linter_print('Checked {} files'.format(totalCheckdFilesCounter))
+    if filesWithErrorsCounter == 0:
+        linter_print('All the files match the Skyward formatting style')
+    else:
+        linter_print(Colors.RED + '{:4.1f}% ({}/{}) of all analyzed files do not match Skyward formatting style!'.format(
+            100*filesWithErrorsCounter/totalCheckdFilesCounter, filesWithErrorsCounter, totalCheckdFilesCounter), Colors.RESET)
+
+    # Exit if error if at least one file isn't correct
+    if(filesWithErrorsCounter > 0):
+        exit(-1)
+
+
+def find_in_code(directory, searchTerm, extensionFilters=('.cpp', '.h'), pathFilter=None):
+    linter_print(
+        Colors.GREEN + 'Checking for \'{}\' in code files'.format(searchTerm) + Colors.RESET)
+
+    # Statistics
+    totalCheckdFilesCounter = 0
+    filesWithErrorsCounter = 0
+
+    # Walk through the directory and check each file
+    for dirpath, dirnames, filenames in walk(directory):
+        for filename in [f for f in filenames if f.endswith(extensionFilters) and (not pathFilter or dirpath.find(pathFilter) >= 0)]:
+            totalCheckdFilesCounter += 1
+
+            # Prepare the complete filepath
+            currentFilepath = join(dirpath, filename)
+
+            # Check the current file
+            with open(currentFilepath) as file:
+                fileContent = file.read()
+                # Check for linter off flag
+                if re.search('linter off', fileContent, re.M):
+                    continue
+                match = re.search(searchTerm, fileContent, re.M)
+                if match:
+                    filesWithErrorsCounter += 1
+
+                    # The current file has the error
+                    if(not args.quiet):
+                        linter_print(Colors.YELLOW + 'Found \'{}\' in file {}'.format(searchTerm,
+                                                                                      currentFilepath) + Colors.RESET)
+
+    linter_print('Checked {} files'.format(totalCheckdFilesCounter))
+    if filesWithErrorsCounter == 0:
+        linter_print(
+            'All the files does not contain \'{}\''.format(searchTerm))
+    else:
+        linter_print(Colors.RED + '{:.1f}% ({}/{}) of all analyzed files contain \'{}\'!'.format(
+            100*filesWithErrorsCounter/totalCheckdFilesCounter, filesWithErrorsCounter, totalCheckdFilesCounter, searchTerm) + Colors.RESET)
+
+    return filesWithErrorsCounter
+
+
+def check_find(directory):
+    sum = find_in_code(directory, r'^using namespace', '.h')
+    sum += find_in_code(directory, r'[^a-zA-Z0-9]printf\(', pathFilter='shared')
+    sum += find_in_code(directory, r'( |^)assert\(')
+    sum += find_in_code(directory, '^ *throw ', pathFilter='catch')
+
+    if sum > 0:
+        exit(-1)
+
+
+def check_cppcheck(directory):
+    linter_print(Colors.GREEN + 'cppcheck' + Colors.RESET)
+    # Run cppcheck on the directory
+    try:
+        result = check_output(['cppcheck', '-q', '--language=c++', '--template=gcc', '--std=c++11', '--enable=all', '--inline-suppr',
+                               '--suppress=unmatchedSuppression', '--suppress=unusedFunction', '--suppress=missingInclude',
+                               directory], stderr=STDOUT)
+
+        # Parse results and count errors
+        errors = re.findall(r'\[(\w+)\]', result.decode('utf-8'))
+        errors = Counter(errors)
+
+        if(not args.quiet):
+            linter_print('cppcheck found the following errors:')
+            for error in errors:
+                linter_print('{:3} - {}'.format(errors[error], error))
+
+        totalErrors = sum(errors.values())
+        if(totalErrors > 0):
+            linter_print(
+                Colors.RED + 'cppcheck found {} errors in total'.format(totalErrors) + Colors.RESET)
+            exit(-1)
+        else:
+            linter_print('cppcheck did not find any errors')
+
+    except CalledProcessError as e:
+        linter_print(e.output.decode('utf-8'))
+        exit(-1)
+
+# -------------------------------------------------------------
+# MAIN
+# -------------------------------------------------------------
+
+
+parser = config_cmd_parser()
+args = parser.parse_args()
+
+if(not args.directory):
+    linter_print('No directory specified')
+    print('')
+    parser.print_help()
+    exit(-1)
+
+if(not isdir(args.directory)):
+    linter_print('The specified directory does not exists')
+    exit(-1)
+
+if(args.copyright):
+    check_copyright(args.directory)
+
+if(args.format):
+    check_format(args.directory)
+
+if(args.cppcheck):
+    check_cppcheck(args.directory)
+
+if(args.find):
+    check_find(args.directory)
+
+# Checks everything if no option is specified
+if(not args.copyright and not args.format and not args.find and not args.cppcheck):
+    check_copyright(args.directory)
+    check_format(args.directory)
+    check_find(args.directory)
+    check_cppcheck(args.directory)