diff --git a/.clang-format b/.clang-format
index 43c7648a3b8b1497c07e324f7d289692fa3ce88c..827c89b435020ccdca9a15eb06a972ac5947c742 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,4 +1,13 @@
 {
     BasedOnStyle: Google,
+    AccessModifierOffset: -4,
+    AlignConsecutiveAssignments: true,
+    AllowShortIfStatementsOnASingleLine: false,
+    AllowShortLoopsOnASingleLine: false,
+    BreakBeforeBraces: Allman,
+    ColumnLimit: 80,
+    ConstructorInitializerAllOnOneLineOrOnePerLine: false,
+    IndentCaseLabels: true,
     IndentWidth: 4,
+    KeepEmptyLinesAtTheStartOfBlocks: true,
 }
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index c53785838aad821c4a2754227f28eadad970a4ee..49b400525cead1a262a154b7ed0fe83d29c3f5e7 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -4,14 +4,13 @@
             "name": "Linux",
             "includePath": [
                 "${workspaceFolder}/**",
-                "~/Qt/5.15.2/gcc_64/include/**",
-                "/Users/alberton/Qt/5.15.2/clang_64/include/**"
+                "/Users/alberton/Qt/5.15.2/**"
             ],
             "defines": [],
-            "compilerPath": "/usr/bin/gcc",
+            "compilerPath": "/usr/bin/clang++",
             "cStandard": "gnu17",
             "cppStandard": "gnu++17",
-            "intelliSenseMode": "linux-gcc-x64"
+            "intelliSenseMode": "clang-x64"
         }
     ],
     "version": 4
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 74d9bae1b0355fa2feef595e842cfb7ee44eaaf3..301582c728fb174400df740c940f7813796cca70 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -10,7 +10,90 @@
         "set": "cpp",
         "string_view": "cpp",
         "unordered_map": "cpp",
-        "locale": "cpp"
+        "locale": "cpp",
+        "qlabel": "cpp",
+        "qwidget": "cpp",
+        "__hash_table": "cpp",
+        "__split_buffer": "cpp",
+        "__tree": "cpp",
+        "array": "cpp",
+        "bitset": "cpp",
+        "deque": "cpp",
+        "initializer_list": "cpp",
+        "list": "cpp",
+        "queue": "cpp",
+        "random": "cpp",
+        "stack": "cpp",
+        "vector": "cpp",
+        "iterator": "cpp",
+        "utility": "cpp",
+        "__bit_reference": "cpp",
+        "__bits": "cpp",
+        "__config": "cpp",
+        "__debug": "cpp",
+        "__errc": "cpp",
+        "__locale": "cpp",
+        "__mutex_base": "cpp",
+        "__node_handle": "cpp",
+        "__nullptr": "cpp",
+        "__string": "cpp",
+        "__threading_support": "cpp",
+        "__tuple": "cpp",
+        "atomic": "cpp",
+        "bit": "cpp",
+        "cctype": "cpp",
+        "clocale": "cpp",
+        "cmath": "cpp",
+        "codecvt": "cpp",
+        "compare": "cpp",
+        "complex": "cpp",
+        "concepts": "cpp",
+        "condition_variable": "cpp",
+        "cstdarg": "cpp",
+        "cstddef": "cpp",
+        "cstdint": "cpp",
+        "cstdio": "cpp",
+        "cstdlib": "cpp",
+        "cstring": "cpp",
+        "ctime": "cpp",
+        "cwchar": "cpp",
+        "cwctype": "cpp",
+        "exception": "cpp",
+        "fstream": "cpp",
+        "iomanip": "cpp",
+        "ios": "cpp",
+        "iosfwd": "cpp",
+        "iostream": "cpp",
+        "istream": "cpp",
+        "limits": "cpp",
+        "memory": "cpp",
+        "mutex": "cpp",
+        "new": "cpp",
+        "numbers": "cpp",
+        "numeric": "cpp",
+        "optional": "cpp",
+        "ostream": "cpp",
+        "semaphore": "cpp",
+        "stdexcept": "cpp",
+        "streambuf": "cpp",
+        "system_error": "cpp",
+        "thread": "cpp",
+        "tuple": "cpp",
+        "type_traits": "cpp",
+        "typeinfo": "cpp",
+        "__functional_base": "cpp",
+        "algorithm": "cpp",
+        "functional": "cpp",
+        "*.tcc": "cpp",
+        "memory_resource": "cpp",
+        "source_location": "cpp",
+        "stop_token": "cpp",
+        "cinttypes": "cpp",
+        "qformlayout": "cpp",
+        "qpair": "cpp",
+        "qstring": "cpp",
+        "qregularexpression": "cpp",
+        "qmessagebox": "cpp"
     },
     "editor.defaultFormatter": "chiehyu.vscode-astyle",
     "[xml]": {
diff --git a/Components/SubscriptionsPanel/subscriptionspanel.cpp b/Components/SubscriptionsPanel/subscriptionspanel.cpp
index 5dc1139cdd4ba06ff29eaa8cac2059d2f43a0365..17870ac0051c17bae2ac544a1c78114387d0cb0f 100644
--- a/Components/SubscriptionsPanel/subscriptionspanel.cpp
+++ b/Components/SubscriptionsPanel/subscriptionspanel.cpp
@@ -1,61 +1,65 @@
 #include "subscriptionspanel.h"
-#include "ui_subscriptionspanel.h"
-#include "Components/TopicAndFieldSelector/topicandfieldselector.h"
 
 #include <QDebug>
 
-SubscriptionsPanel::SubscriptionsPanel(const QList<TopicAndFieldFilter>* subscriptionsList) : QWidget(nullptr), ui(new Ui::SubscriptionsPanel) {
+#include "Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.h"
+#include "Components/TopicFilterSelector/topicfilterselector.h"
+#include "ui_subscriptionspanel.h"
+
+SubscriptionsPanel::SubscriptionsPanel(
+    const QList<TopicAndFieldFilter>* subscriptionsList)
+    : QWidget(nullptr), ui(new Ui::SubscriptionsPanel)
+{
     ui->setupUi(this);
     this->setAttribute(Qt::WA_DeleteOnClose, true);
 
-    for(auto s : *subscriptionsList) {
+    for (auto s : *subscriptionsList)
+    {
         addSubscription(s);
     }
 
-    connect(ui->button_addTopic, &QPushButton::clicked, this, &SubscriptionsPanel::onAddTopicClicked);
-    connect(ui->button_addTopicAndField, &QPushButton::clicked, this, &SubscriptionsPanel::onAddTopicAndFieldClicked);
-    connect(ui->button_remove, &QPushButton::clicked, this, &SubscriptionsPanel::onRemoveClicked);
+    connect(ui->button_addTopic, &QPushButton::clicked, this,
+            &SubscriptionsPanel::onAddTopicClicked);
+    connect(ui->button_addTopicAndField, &QPushButton::clicked, this,
+            &SubscriptionsPanel::onAddTopicAndFieldClicked);
+    connect(ui->button_remove, &QPushButton::clicked, this,
+            &SubscriptionsPanel::onRemoveClicked);
 }
 
-SubscriptionsPanel::~SubscriptionsPanel() {
-    delete ui;
-}
+SubscriptionsPanel::~SubscriptionsPanel() { delete ui; }
 
-void SubscriptionsPanel::addSubscription(const TopicAndFieldFilter& filter) {
+void SubscriptionsPanel::addSubscription(const TopicAndFieldFilter& filter)
+{
     QListWidgetItem* listItem = new QListWidgetItem(filter.toString());
     ui->subscriptions_list->addItem(listItem);
     emit SubscriptionAdded(filter);
 }
 
-void SubscriptionsPanel::removeSubscription(QListWidgetItem* item) {
-    emit SubscriptionRemoved(TopicAndFieldFilter::fromStringUnsafe(item->text()));
+void SubscriptionsPanel::removeSubscription(QListWidgetItem* item)
+{
+    emit SubscriptionRemoved(
+        TopicAndFieldFilter::fromStringUnsafe(item->text()));
     delete item;
 }
 
-
-void SubscriptionsPanel::onAddTopicClicked() {
-    TopicAndFieldSelector::selectTopic([this](const TopicAndFieldFilter & topic) {
-        addSubscription(topic);
-    });
+void SubscriptionsPanel::onAddTopicClicked()
+{
+    TopicFilterSelector::selectFilter([this](const TopicFilter& topic)
+                                      { addSubscription(topic); });
 }
 
-void SubscriptionsPanel::onAddTopicAndFieldClicked() {
-    TopicAndFieldSelector::selectTopicAndField([this](const TopicAndFieldFilter & filter) {
-        addSubscription(filter);
-    });
+void SubscriptionsPanel::onAddTopicAndFieldClicked()
+{
+    TopicAndFieldFilterSelector::selectFilter(
+        [this](const TopicAndFieldFilter& filter) { addSubscription(filter); });
 }
 
-void SubscriptionsPanel::onRemoveClicked() {
+void SubscriptionsPanel::onRemoveClicked()
+{
     auto items = ui->subscriptions_list->selectedItems();
 
-    for(auto item : items) {
+    for (auto item : items)
+    {
         removeSubscription(item);
     }
 }
-
-
-
-
-
-
-
diff --git a/Components/SubscriptionsPanel/subscriptionspanel.h b/Components/SubscriptionsPanel/subscriptionspanel.h
index 61007395615bc4eb5f72e85518d754a26b404f37..a38bf4d4d688db0d685db5d9b02e8d8fc0de8cda 100644
--- a/Components/SubscriptionsPanel/subscriptionspanel.h
+++ b/Components/SubscriptionsPanel/subscriptionspanel.h
@@ -1,38 +1,40 @@
 #ifndef SUBSCRIPTIONSPANEL_H
 #define SUBSCRIPTIONSPANEL_H
 
-#include <QWidget>
-#include <QListWidgetItem>
 #include <QList>
+#include <QListWidgetItem>
+#include <QWidget>
+
 #include "Core/Message/topicandfieldfilter.h"
 
-namespace Ui {
+namespace Ui
+{
 class SubscriptionsPanel;
 }
 
-class SubscriptionsPanel : public QWidget {
+class SubscriptionsPanel : public QWidget
+{
     Q_OBJECT
 
-  public:
-    explicit SubscriptionsPanel(const QList<TopicAndFieldFilter>* subscriptionsList);
+public:
+    explicit SubscriptionsPanel(
+        const QList<TopicAndFieldFilter>* subscriptionsList);
     ~SubscriptionsPanel();
 
     void addSubscription(const TopicAndFieldFilter& filter);
     void removeSubscription(QListWidgetItem* item);
 
-  private slots:
+private slots:
     void onAddTopicClicked();
     void onAddTopicAndFieldClicked();
     void onRemoveClicked();
 
-  signals:
+signals:
     void SubscriptionAdded(const TopicAndFieldFilter&);
     void SubscriptionRemoved(const TopicAndFieldFilter&);
 
-  private:
+private:
     Ui::SubscriptionsPanel* ui;
 };
 
-#endif // SUBSCRIPTIONSPANEL_H
-
-
+#endif  // SUBSCRIPTIONSPANEL_H
diff --git a/Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.cpp b/Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c0365982f913b32ceaf430ecb741fb105049f9a
--- /dev/null
+++ b/Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.cpp
@@ -0,0 +1,74 @@
+
+#include "topicandfieldfilterselector.h"
+
+#include <QFormLayout>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QPushButton>
+
+TopicAndFieldFilterSelector::TopicAndFieldFilterSelector(
+    const TopicAndFieldFilter& filter)
+{
+    setAttribute(Qt::WA_DeleteOnClose, true);
+    setWindowTitle("Choose Topic and Field name");
+
+    QFormLayout* form = new QFormLayout;
+    form->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
+    QLineEdit* topicEdit = new QLineEdit;
+    topicEdit->setText(filter.getTopicFilter().toString());
+    form->addRow("Topic:", topicEdit);
+    QLineEdit* fieldEdit = new QLineEdit;
+    fieldEdit->setText(filter.getFieldFilter());
+    form->addRow("Field:", fieldEdit);
+
+    QHBoxLayout* buttons = new QHBoxLayout;
+    QPushButton* cancel  = new QPushButton("Cancel");
+    buttons->addWidget(cancel);
+    QPushButton* select = new QPushButton("Select");
+    buttons->addWidget(select);
+
+    QVBoxLayout* outer = new QVBoxLayout;
+    outer->addLayout(form);
+    outer->addLayout(buttons);
+    setLayout(outer);
+
+    auto onSelect = [=]()
+    {
+        if (topicEdit->text().isEmpty() || fieldEdit->text().isEmpty())
+        {
+            QMessageBox msgBox(nullptr);
+            msgBox.setText("Cannot accept empty fields");
+            msgBox.exec();
+        }
+        else
+        {
+            TopicAndFieldFilter newFilter(topicEdit->text(), fieldEdit->text());
+
+            emit filterSelected(newFilter);
+            deleteLater();
+        }
+    };
+
+    connect(cancel, &QPushButton::clicked, [this]() { deleteLater(); });
+    connect(select, &QPushButton::clicked, onSelect);
+    connect(topicEdit, &QLineEdit::returnPressed, onSelect);
+}
+
+void TopicAndFieldFilterSelector::selectFilter(
+    TopicAndFieldFilterSelector::Handler handler)
+{
+    TopicAndFieldFilterSelector* selector = new TopicAndFieldFilterSelector({});
+    QObject::connect(selector, &TopicAndFieldFilterSelector::filterSelected,
+                     handler);
+    selector->show();
+}
+
+void TopicAndFieldFilterSelector::selectFilter(
+    const TopicAndFieldFilter& filter, Handler handler)
+{
+    TopicAndFieldFilterSelector* selector =
+        new TopicAndFieldFilterSelector(filter);
+    QObject::connect(selector, &TopicAndFieldFilterSelector::filterSelected,
+                     handler);
+    selector->show();
+}
diff --git a/Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.h b/Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7eece9796a40bd5ed47babf52bab2a4dea0ccaf
--- /dev/null
+++ b/Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.h
@@ -0,0 +1,29 @@
+#ifndef TOPICANDFIELDFILTERSELECTOR_H
+#define TOPICANDFIELDFILTERSELECTOR_H
+
+#include <QPair>
+#include <QString>
+#include <QWidget>
+#include <functional>
+
+#include "Core/Message/topicandfieldfilter.h"
+
+class TopicAndFieldFilterSelector : public QWidget
+{
+    Q_OBJECT
+
+public:
+    using Handler = std::function<void(const TopicAndFieldFilter& selector)>;
+
+    static void selectFilter(Handler handler);
+    static void selectFilter(const TopicAndFieldFilter& filter,
+                             Handler handler);
+
+private:
+    TopicAndFieldFilterSelector(const TopicAndFieldFilter& filter);
+
+signals:
+    void filterSelected(const TopicAndFieldFilter&);
+};
+
+#endif  // TOPICANDFIELDFILTERSELECTOR_H
diff --git a/Components/TopicAndFieldSelector/topicandfieldselector.cpp b/Components/TopicAndFieldSelector/topicandfieldselector.cpp
deleted file mode 100644
index 1135c69ea5f167ab0e318c1453375ee79f3cc01c..0000000000000000000000000000000000000000
--- a/Components/TopicAndFieldSelector/topicandfieldselector.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-#include "topicandfieldselector.h"
-
-#include <QFormLayout>
-#include <QLineEdit>
-#include <QMessageBox>
-#include <QPushButton>
-
-void TopicAndFieldSelector::selectTopicAndField(TopicAndFieldSelector::Handler func) {
-    TopicAndFieldSelector* selector = new TopicAndFieldSelector(false);
-    QObject::connect(selector, &TopicAndFieldSelector::topicAndFieldSelected, func);
-    selector->show();
-}
-
-void TopicAndFieldSelector::selectTopic(TopicAndFieldSelector::Handler func) {
-    TopicAndFieldSelector* selector = new TopicAndFieldSelector(true);
-    QObject::connect(selector, &TopicAndFieldSelector::topicSelected, func);
-    selector->show();
-}
-
-TopicAndFieldSelector::TopicAndFieldSelector(bool justTopic) {
-    setAttribute(Qt::WA_DeleteOnClose, true);
-    setWindowTitle(justTopic ? tr("Choose Topic") : tr("Choose Topic and Field name"));
-
-
-    QHBoxLayout* buttons = new QHBoxLayout;
-    QPushButton* cancel = new QPushButton(tr("Cancel"));
-    QPushButton* select = new QPushButton(tr("Select"));
-    buttons->addWidget(cancel);
-    buttons->addWidget(select);
-
-    QFormLayout* form = new QFormLayout;
-    QLineEdit* topicEdit = new QLineEdit;
-    form->addRow(tr("Topic:"), topicEdit);
-
-    QVBoxLayout* outer = new QVBoxLayout;
-    outer->addLayout(form);
-    outer->addLayout(buttons);
-    setLayout(outer);
-
-    connect(cancel, &QPushButton::clicked, [this]() {
-        deleteLater();
-    });
-
-    if(justTopic) {
-        auto lambda = [ = ]() {
-            TopicFilter filter(topicEdit->text());
-
-            if(validityCheck(filter)) {
-                emit topicSelected({filter});
-                deleteLater();
-            }
-        };
-
-        connect(select, &QPushButton::clicked, lambda);
-        connect(topicEdit, &QLineEdit::returnPressed, lambda);
-    } else {
-        QLineEdit* fieldEdit = new QLineEdit;
-        form->addRow(tr("Field:"), fieldEdit);
-
-        auto lambda = [ = ]() {
-            TopicFilter filter(topicEdit->text());
-
-            if(validityCheck(filter)) {
-                if(fieldEdit->text().isEmpty()) {
-                    QMessageBox msgBox(nullptr);
-                    msgBox.setText(tr("Cannot accept empty Field name"));
-                    msgBox.exec();
-                } else {
-                    emit topicAndFieldSelected({filter, fieldEdit->text()});
-                    deleteLater();
-                }
-            }
-        };
-
-        connect(select, &QPushButton::clicked, lambda);
-        connect(fieldEdit, &QLineEdit::returnPressed, lambda);
-    }
-
-}
-
-bool TopicAndFieldSelector::validityCheck(const TopicFilter& filter) {
-    if(!filter.isValid()) {
-        QMessageBox msgBox(nullptr);
-        msgBox.setText(tr("Invalid Topic"));
-        msgBox.exec();
-        return false;
-    }
-    return true;
-}
diff --git a/Components/TopicAndFieldSelector/topicandfieldselector.h b/Components/TopicAndFieldSelector/topicandfieldselector.h
deleted file mode 100644
index 904b70d29fccbc73278fab425dcb4e31e6025955..0000000000000000000000000000000000000000
--- a/Components/TopicAndFieldSelector/topicandfieldselector.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef TOPICANDFIELDSELECTOR_H
-#define TOPICANDFIELDSELECTOR_H
-
-#include <functional>
-#include <QWidget>
-#include <QString>
-#include <QPair>
-#include "Core/Message/topicandfieldfilter.h"
-
-class TopicAndFieldSelector : public QWidget {
-    Q_OBJECT
-  public:
-    using Handler = std::function<void(const TopicAndFieldFilter& selector)>;
-
-    static void selectTopicAndField(Handler func);
-    static void selectTopic(Handler func);
-
-  private:
-    TopicAndFieldSelector(bool justTopic);
-    static bool validityCheck(const TopicFilter&);
-
-  signals:
-    void topicSelected(const TopicAndFieldFilter&);
-    void topicAndFieldSelected(const TopicAndFieldFilter&);
-};
-
-#endif // TOPICANDFIELDSELECTOR_H
diff --git a/Components/TopicFilterSelector/topicfilterselector.cpp b/Components/TopicFilterSelector/topicfilterselector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b4aae6c4573ec281358dfbfaf7c2740476dd70f
--- /dev/null
+++ b/Components/TopicFilterSelector/topicfilterselector.cpp
@@ -0,0 +1,65 @@
+#include "topicfilterselector.h"
+
+#include <QFormLayout>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QPushButton>
+
+TopicFilterSelector::TopicFilterSelector(const TopicFilter& filter)
+{
+    setAttribute(Qt::WA_DeleteOnClose, true);
+    setWindowTitle("Choose Topic and Field name");
+
+    QFormLayout* form = new QFormLayout;
+    form->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
+    QLineEdit* topicEdit = new QLineEdit;
+    topicEdit->setText(filter.toString());
+    form->addRow("Topic:", topicEdit);
+
+    QHBoxLayout* buttons = new QHBoxLayout;
+    QPushButton* cancel  = new QPushButton("Cancel");
+    buttons->addWidget(cancel);
+    QPushButton* select = new QPushButton("Select");
+    buttons->addWidget(select);
+
+    QVBoxLayout* outer = new QVBoxLayout;
+    outer->addLayout(form);
+    outer->addLayout(buttons);
+    setLayout(outer);
+
+    auto onSelect = [=]()
+    {
+        if (topicEdit->text().isEmpty())
+        {
+            QMessageBox msgBox(nullptr);
+            msgBox.setText("Cannot accept empty fields");
+            msgBox.exec();
+        }
+        else
+        {
+            TopicFilter newFilter(topicEdit->text());
+
+            emit filterSelected(newFilter);
+            deleteLater();
+        }
+    };
+
+    connect(cancel, &QPushButton::clicked, [this]() { deleteLater(); });
+    connect(select, &QPushButton::clicked, onSelect);
+    connect(topicEdit, &QLineEdit::returnPressed, onSelect);
+}
+
+void TopicFilterSelector::selectFilter(TopicFilterSelector::Handler handler)
+{
+    TopicFilterSelector* selector = new TopicFilterSelector({});
+    QObject::connect(selector, &TopicFilterSelector::filterSelected, handler);
+    selector->show();
+}
+
+void TopicFilterSelector::selectFilter(const TopicFilter& filter,
+                                       Handler handler)
+{
+    TopicFilterSelector* selector = new TopicFilterSelector(filter);
+    QObject::connect(selector, &TopicFilterSelector::filterSelected, handler);
+    selector->show();
+}
diff --git a/Components/TopicFilterSelector/topicfilterselector.h b/Components/TopicFilterSelector/topicfilterselector.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0141055a7c2d83cef003597522f78748e686d60
--- /dev/null
+++ b/Components/TopicFilterSelector/topicfilterselector.h
@@ -0,0 +1,28 @@
+#ifndef TOPICFILTERSELECTOR_H
+#define TOPICFILTERSELECTOR_H
+
+#include <QPair>
+#include <QString>
+#include <QWidget>
+#include <functional>
+
+#include "Core/Message/topicfilter.h"
+
+class TopicFilterSelector : public QWidget
+{
+    Q_OBJECT
+
+public:
+    using Handler = std::function<void(const TopicFilter& selector)>;
+
+    static void selectFilter(Handler handler);
+    static void selectFilter(const TopicFilter& filter, Handler handler);
+
+private:
+    TopicFilterSelector(const TopicFilter& filter);
+
+signals:
+    void filterSelected(const TopicFilter&);
+};
+
+#endif  // TOPICANDFIELDFILTERSELECTOR_H
diff --git a/Core/Message/modulemessage.cpp b/Core/Message/modulemessage.cpp
index d879ad40c4eaf7b02af3b1682ae356fb1996bc81..71742a05adb59a60c585731b1b28d544763eec0e 100644
--- a/Core/Message/modulemessage.cpp
+++ b/Core/Message/modulemessage.cpp
@@ -1,64 +1,83 @@
 #include "modulemessage.h"
 
-ModuleMessage::ModuleMessage() {
-}
+ModuleMessage::ModuleMessage() {}
 
-ModuleMessage::ModuleMessage(Topic _topic) : topic(_topic) { }
+ModuleMessage::ModuleMessage(Topic _topic) : topic(_topic) {}
 
-ModuleMessage::ModuleMessage(const ModuleMessage& rhs) : topic(rhs.topic), fields(rhs.fields) { }
+ModuleMessage::ModuleMessage(const ModuleMessage& rhs)
+    : topic(rhs.topic), fields(rhs.fields)
+{
+}
 
-ModuleMessage::ModuleMessage(ModuleMessage&& rhs) : topic(rhs.topic), fields(std::move(rhs.fields)) { }
+ModuleMessage::ModuleMessage(ModuleMessage&& rhs)
+    : topic(rhs.topic), fields(std::move(rhs.fields))
+{
+}
 
-ModuleMessage& ModuleMessage::operator=(const ModuleMessage& rhs) {
-    topic = rhs.topic;
+ModuleMessage& ModuleMessage::operator=(const ModuleMessage& rhs)
+{
+    topic  = rhs.topic;
     fields = rhs.fields;
     return *this;
 }
 
-ModuleMessage& ModuleMessage::operator=(ModuleMessage&& rhs) {
-    topic = rhs.topic;
+ModuleMessage& ModuleMessage::operator=(ModuleMessage&& rhs)
+{
+    topic  = rhs.topic;
     fields = std::move(rhs.fields);
     return *this;
 }
 
-MessageField ModuleMessage::getField(QString key) const {
+MessageField ModuleMessage::getField(QString key) const
+{
     auto it = fields.find(key);
-    if(it == fields.cend()) {
+    if (it == fields.cend())
+    {
         return {};
     }
 
     return *it;
 }
 
-Topic ModuleMessage::getTopic() const {
-    return topic;
-}
+Topic ModuleMessage::getTopic() const { return topic; }
 
-void ModuleMessage::setField(QString key, MessageField field) {
+void ModuleMessage::setField(QString key, MessageField field)
+{
     fields[key] = field;
 }
 
-void ModuleMessage::setTopic(Topic _topic) {
-    topic = _topic;
-}
+void ModuleMessage::setTopic(Topic _topic) { topic = _topic; }
 
-void ModuleMessage::setFields(const QMap<QString, MessageField>& _fields) {
+void ModuleMessage::setFields(const QMap<QString, MessageField>& _fields)
+{
     fields = _fields;
 }
 
-void ModuleMessage::setFields(QMap<QString, MessageField>&& _fields) {
+void ModuleMessage::setFields(QMap<QString, MessageField>&& _fields)
+{
     fields = std::move(_fields);
 }
 
-QString ModuleMessage::toString(bool includeTopic) const {
+void ModuleMessage::filterFields(const QString& fieldFilter)
+{
+    for (auto it = fields.begin(); it != fields.end(); it++)
+        if (it.key() != fieldFilter)
+            fields.remove(it.key());
+}
+
+QString ModuleMessage::toString(bool includeTopic) const
+{
     QString str = "{\n\t";
-    if(includeTopic) {
+    if (includeTopic)
+    {
         str.append("<topic>: ");
         str.append(topic.toString());
     }
 
-    for(auto it = fields.keyBegin(); it != fields.keyEnd(); ++it) {
-        if(includeTopic || it != fields.keyBegin()) {
+    for (auto it = fields.keyBegin(); it != fields.keyEnd(); ++it)
+    {
+        if (includeTopic || it != fields.keyBegin())
+        {
             str.append(",\n\t");
         }
         str.append(*it);
diff --git a/Core/Message/modulemessage.h b/Core/Message/modulemessage.h
index 3f9aa279b4af2e64a49bb2781e90ba4a1eec233d..001b7823144399c90084c44ef482e855b5b0bc2a 100644
--- a/Core/Message/modulemessage.h
+++ b/Core/Message/modulemessage.h
@@ -1,8 +1,8 @@
 #ifndef MODULEMESSAGE_H
 #define MODULEMESSAGE_H
 
-#include <QTime>
 #include <QMap>
+#include <QTime>
 
 #include "messagefield.h"
 #include "topic.h"
@@ -10,9 +10,10 @@
 /*
  * Structure of internal GS Messages.
  *
-*/
-class ModuleMessage {
-  public:
+ */
+class ModuleMessage
+{
+public:
     ModuleMessage();
     ModuleMessage(Topic topic);
 
@@ -30,11 +31,16 @@ class ModuleMessage {
     void setFields(const QMap<QString, MessageField>& fields);
     void setFields(QMap<QString, MessageField>&& fields);
 
+    /**
+     * @brief Removes all the fields that do not match the filter.
+     */
+    void filterFields(const QString& fieldFilter);
+
     QString toString(bool includeTopic = false) const;
 
-  private:
+private:
     Topic topic;
     QMap<QString, MessageField> fields;
 };
 
-#endif // MODULEMESSAGE_H
+#endif  // MODULEMESSAGE_H
diff --git a/Core/Message/topicandfieldfilter.cpp b/Core/Message/topicandfieldfilter.cpp
index 26ab2ee96835c4f70503bba8b7507558eb2bd8d0..ac0d44647477e2b9f145dec826b82b61e2e337d5 100644
--- a/Core/Message/topicandfieldfilter.cpp
+++ b/Core/Message/topicandfieldfilter.cpp
@@ -1,53 +1,86 @@
 #include "topicandfieldfilter.h"
 
-TopicAndFieldFilter::TopicAndFieldFilter() : topicFilter(TopicFilter::Any), fieldName("") {}
-TopicAndFieldFilter::TopicAndFieldFilter(const TopicFilter& _topicFilter, const QString& _fieldName)
-    : topicFilter(_topicFilter), fieldName(_fieldName) {}
+TopicAndFieldFilter::TopicAndFieldFilter()
+    : topicFilter(TopicFilter::any()), fieldFilter("")
+{
+}
+
+TopicAndFieldFilter::TopicAndFieldFilter(const QString& topicFilter,
+                                         const QString& fieldFilter)
+    : topicFilter(topicFilter), fieldFilter(fieldFilter)
+{
+}
+
+TopicAndFieldFilter::TopicAndFieldFilter(const TopicFilter& topicFilter,
+                                         const QString& fieldFilter)
+    : topicFilter(topicFilter), fieldFilter(fieldFilter)
+{
+}
 
-bool TopicAndFieldFilter::operator==(const TopicAndFieldFilter& rhs) const {
-    return topicFilter == rhs.topicFilter && fieldName == rhs.fieldName;
+bool TopicAndFieldFilter::operator==(const TopicAndFieldFilter& rhs) const
+{
+    return topicFilter == rhs.topicFilter && fieldFilter == rhs.fieldFilter;
 }
 
-bool TopicAndFieldFilter::matchTopic(const Topic& topic) const {
+bool TopicAndFieldFilter::matchTopic(const Topic& topic) const
+{
     return topicFilter.match(topic);
 }
 
-bool TopicAndFieldFilter::matchMessage(const ModuleMessage& message, MessageField& extracted) const {
-    if(!matchTopic(message.getTopic())) {
+bool TopicAndFieldFilter::matchMessage(const ModuleMessage& message,
+                                       MessageField& field) const
+{
+    // Check if the message matches the topic
+    if (!matchTopic(message.getTopic()))
         return false;
-    }
 
-    if(fieldName.isEmpty()) {
-        extracted = MessageField(message.toString());
-    } else {
-        extracted = message.getField(fieldName);
-    }
-    return true;
+    // If the field filter is empty, the message is transformed into a single
+    // string field
+    if (fieldFilter.isEmpty())
+        field = MessageField(message.toString());
+    else
+        field = message.getField(fieldFilter);
 
+    return true;
 }
 
-TopicFilter TopicAndFieldFilter::getTopic() const {
-    return topicFilter;
-}
+bool TopicAndFieldFilter::filterMessage(ModuleMessage& message) const
+{
+    // Check if the message matches the topic
+    if (!matchTopic(message.getTopic()))
+        return false;
+
+    // Then filter the message if the field filter is not empty
+    if (!fieldFilter.isEmpty())
+        message.filterFields(fieldFilter);
 
-QString TopicAndFieldFilter::getFieldName() const {
-    return fieldName;
+    return true;
 }
 
-bool TopicAndFieldFilter::isFullFilter() const {
-    return !fieldName.isEmpty();
+TopicFilter TopicAndFieldFilter::getTopicFilter() const { return topicFilter; }
+
+QString TopicAndFieldFilter::getFieldFilter() const { return fieldFilter; }
+
+bool TopicAndFieldFilter::isFullFilter() const
+{
+    return !fieldFilter.isEmpty();
 }
 
-QString TopicAndFieldFilter::toString() const {
-    return topicFilter.toString() + "." + (fieldName.isEmpty() ? "*" : fieldName);
+QString TopicAndFieldFilter::toString() const
+{
+    return topicFilter.toString() + "." +
+           (fieldFilter.isEmpty() ? "*" : fieldFilter);
 }
 
-TopicAndFieldFilter TopicAndFieldFilter::fromStringUnsafe(const QString& str) {
+TopicAndFieldFilter TopicAndFieldFilter::fromStringUnsafe(const QString& str)
+{
     int idx = str.indexOf('.');
-    if(idx == -1) {
+    if (idx == -1)
+    {
         return TopicAndFieldFilter(TopicFilter(str));
     }
 
     QString field = str.mid(idx + 1);
-    return TopicAndFieldFilter(TopicFilter(str.mid(0, idx)), field == "*" ? "" : field);
+    return TopicAndFieldFilter(TopicFilter(str.mid(0, idx)),
+                               field == "*" ? "" : field);
 }
diff --git a/Core/Message/topicandfieldfilter.h b/Core/Message/topicandfieldfilter.h
index c42fc1bf2ded3d7232744d53b4d4f773d8b93ec7..d40e633d0820e29d11f3df49185528a5b6c44a0c 100644
--- a/Core/Message/topicandfieldfilter.h
+++ b/Core/Message/topicandfieldfilter.h
@@ -1,42 +1,58 @@
 #ifndef TOPICANDFIELDFILTER_H
 #define TOPICANDFIELDFILTER_H
 
-#include "modulemessage.h"
 #include "messagefield.h"
+#include "modulemessage.h"
 #include "topicfilter.h"
 
-/*
- * TopicAndFieldFilter class represents expressions that can match against Gs message topics,
- * and also select a field from that message.
- * TopicAndFieldFilter can also not select a certain field, in that case, when matches,
- * it returns the entire message converted to string.
+/**
+ * @brief Represents an expressions that can match against topics and fields.
  *
- * See also: Topic, MessageField, ModuleMessage, TopicFilter
-*/
-class TopicAndFieldFilter {
-  public:
-
-
-    /*
-     * fieldName empty -> matchMessage() outputs all the message as a String
-    */
-    TopicAndFieldFilter(const TopicFilter& _topicFilter, const QString& _fieldName = "");
+ * It can also not select a certain field, in that case, when matches, it
+ * returns the entire message converted to string.
+ *
+ * TODO: Support multiple filed matching.
+ */
+class TopicAndFieldFilter
+{
+public:
     TopicAndFieldFilter();
-
+    TopicAndFieldFilter(const QString& topicFilter,
+                        const QString& fieldFilter = "");
+    TopicAndFieldFilter(const TopicFilter& topicFilter,
+                        const QString& fieldFilter = "");
     bool operator==(const TopicAndFieldFilter&) const;
+
+    /**
+     * @brief Check if the given topic is matched by the filter.
+     */
     bool matchTopic(const Topic& topic) const;
-    bool matchMessage(const ModuleMessage& message, MessageField& extracted) const;
 
-    TopicFilter getTopic() const;
-    QString getFieldName() const;
+    /**
+     * @brief Extract the field from a message given the filter.
+     *
+     * @returns true if the message contained the filed.
+     */
+    bool matchMessage(const ModuleMessage& message, MessageField& field) const;
+
+    /**
+     * @brief Removes from the message all the fields that do not match the
+     * filter.
+     *
+     * @warning The provided message is changed if it matched the filter!
+     */
+    bool filterMessage(ModuleMessage& message) const;
+
+    TopicFilter getTopicFilter() const;
+    QString getFieldFilter() const;
     bool isFullFilter() const;
 
     QString toString() const;
     static TopicAndFieldFilter fromStringUnsafe(const QString&);
 
-  private:
+private:
     TopicFilter topicFilter;
-    QString fieldName;
+    QString fieldFilter;
 };
 
-#endif // TOPICANDFIELDFILTER_H
+#endif  // TOPICANDFIELDFILTER_H
diff --git a/Core/Message/topicfilter.cpp b/Core/Message/topicfilter.cpp
index a4d72b864559b0194e1230e9ade6efab0adfc1d8..313cf56c648df3acf0653e7b29932fb4a7e7c9af 100644
--- a/Core/Message/topicfilter.cpp
+++ b/Core/Message/topicfilter.cpp
@@ -1,46 +1,54 @@
 #include "topicfilter.h"
-#include <QRegExp>
-#include <QStringRef>
-
-TopicFilter::TopicFilter(const QString& expr) {
-    if(expr == '*' || expr == '?' || expr.contains(QRegExp("^[A-Za-z0-9$_]+(\\/[A-Za-z0-9$_]+)*(\\/[*?])?$"))) {
-        repr = expr;
-        valid = true;
-    } else {
-        valid = false;
-    }
+
+TopicFilter::TopicFilter(const QString& expression)
+{
+    const QRegularExpression validExprRegex = QRegularExpression(
+        "^(?:([A-Za-z0-9_]+)\\/)?(?:([A-Za-z0-9_]+)\\/?)?([*?]?)$");
+
+    // Check if the string expression is valid
+    valid = validExprRegex.match(expression).hasMatch();
+
+    this->expression = expression;
 }
 
-bool TopicFilter::operator==(const TopicFilter& rhs) const {
-    return repr == rhs.repr;
+bool TopicFilter::operator==(const TopicFilter& rhs) const
+{
+    return expression == rhs.expression;
 }
 
-bool TopicFilter::match(const Topic& topic) const {
-    if(repr == "*" || repr == "?")
+bool TopicFilter::match(const Topic& topic) const
+{
+    // Always true if the filter is a pure wildcard
+    if (expression == "*" || expression == "?")
         return true;
 
-    QString str = topic.toString();
+    QString topicStr = topic.toString();
 
-    if(!isWildcard())
-        return repr == str;
+    // If the filter doesn't contain a wildcard then the topic must match
+    if (!isWildcard())
+        return expression == topicStr;
 
-    QStringRef prefix = repr.midRef(0, repr.lastIndexOf('/'));
-    if(!str.startsWith(prefix) || (str.size() > prefix.size() && str.at(prefix.size()) != '/'))
+    // Extract the filter prefix before the last /
+    QStringRef prefix = expression.midRef(0, expression.lastIndexOf('/'));
+
+    // The topic can match only if it has the same prefix
+    if (!topicStr.startsWith(prefix) ||
+        (topicStr.size() > prefix.size() && topicStr.at(prefix.size()) != '/'))
         return false;
 
-    return repr.at(repr.size() - 1) != '*' || str.size() > prefix.size();
+    return expression.at(expression.size() - 1) != '*' ||
+           topicStr.size() > prefix.size();
 }
 
-bool TopicFilter::isWildcard() const {
-    return !repr.isEmpty() && (repr.at(repr.size() - 1) == '*' || repr.at(repr.size() - 1) == '?');
+bool TopicFilter::isWildcard() const
+{
+    return !expression.isEmpty() &&
+           (expression.at(expression.size() - 1) == '*' ||
+            expression.at(expression.size() - 1) == '?');
 }
 
-bool TopicFilter::isValid() const {
-    return valid;
-}
+bool TopicFilter::isValid() const { return valid; }
 
-QString TopicFilter::toString() const {
-    return repr;
-}
+QString TopicFilter::toString() const { return expression; }
 
-TopicFilter TopicFilter::Any("*");
+const TopicFilter TopicFilter::any() { return TopicFilter("*"); };
diff --git a/Core/Message/topicfilter.h b/Core/Message/topicfilter.h
index 32d4160e2fdee4d1877393db38aa14ce0f3b254d..df70e16bd8f010b590d34bbf98e02895c2c31568 100644
--- a/Core/Message/topicfilter.h
+++ b/Core/Message/topicfilter.h
@@ -1,39 +1,51 @@
 #ifndef TOPICFILTER_H
 #define TOPICFILTER_H
 
+#include <QRegularExpression>
 #include <QString>
+
 #include "topic.h"
 
-/*
- * TopicFilter class represents expressions that can match against Gs message topics.
- * They can contain wildcard symbols * and ? as last token. For example:
- *  "*" and "?" match with all topics
- *  "Prefix/?" matchces with "Prefix", "Prefix/A" and "Prefix/A/B"
+/**
+ * @brief Represents expressions that can match against message topics.
  *
- * The difference between * and ? is that the latter also matches when only the predix is present.
+ * They can contain wildcard symbols * and ? as last token. For example:
+ *  "*" and "?" match with all topics "Prefix/?" matches with "Prefix",
+ * "Prefix/A" and "Prefix/A/B"
  *
- * See also: Topic
-*/
-class TopicFilter {
-  public:
-    TopicFilter(const QString& expr);
-
-    TopicFilter(const TopicFilter&) = default;
-    TopicFilter(TopicFilter&&) = default;
+ * The difference between * and ? is that the latter also matches when only the
+ * prefix is present.
+ */
+class TopicFilter
+{
+public:
+    TopicFilter(const QString& expression = "*");
+    bool operator==(const TopicFilter&) const;
+
+    TopicFilter(const TopicFilter&)            = default;
+    TopicFilter(TopicFilter&&)                 = default;
     TopicFilter& operator=(const TopicFilter&) = default;
-    TopicFilter& operator=(TopicFilter&&) = default;
+    TopicFilter& operator=(TopicFilter&&)      = default;
 
-    bool operator==(const TopicFilter&) const;
+    /**
+     * @brief Returns true if the filter matches the given topic.
+     */
     bool match(const Topic& topic) const;
+
+    /**
+     * @brief Returns true if the filter contains a wildcard.
+     */
     bool isWildcard() const;
+
     bool isValid() const;
+
     QString toString() const;
 
-    static TopicFilter Any;
+    static const TopicFilter any();
 
-  private:
-    QString repr;
+private:
+    QString expression;
     bool valid;
 };
 
-#endif // TOPICFILTER_H
+#endif  // TOPICFILTER_H
diff --git a/Core/modulesmanager.cpp b/Core/modulesmanager.cpp
index 6c437d965195dc3850890c4859dccf4a9e7b7916..c6bcf08d2741f722db2424b1ea7206c2bc8d1c75 100644
--- a/Core/modulesmanager.cpp
+++ b/Core/modulesmanager.cpp
@@ -1,71 +1,70 @@
 #include "modulesmanager.h"
 
+#include <QDir>
 #include <QInputDialog>
 #include <QMessageBox>
-#include <QDir>
 
-#include "Core/module.h"
-#include "Core/xmlobject.h"
 #include "Components/ModulesPicker/modulespicker.h"
 #include "Components/SaveConfigurationDialog/saveconfigurationdialog.h"
+#include "Core/module.h"
+#include "Core/xmlobject.h"
 #include "Modules/skywardhubstrings.h"
 
 ModulesList ModulesManager::modulesListHandler;
 
-ModulesManager::ModulesManager() {
-
-}
+ModulesManager::ModulesManager() {}
 
 ModulesManager::~ModulesManager() {
     clearPages();
-    for(int i = 0; i < menuActions.count(); i++) {
+    for (int i = 0; i < menuActions.count(); i++) {
         delete menuActions[i];
     }
     menuActions.clear();
 }
 
 QString ModulesManager::getModuleName(ModuleId id) {
-    if(ModulesManager::modulesListHandler.containsId(id))
+    if (ModulesManager::modulesListHandler.containsId(id))
         return ModulesManager::modulesListHandler.getModuleName(id);
 
     return "";
 }
 
 Module* ModulesManager::instantiateModuleById(ModuleId id) {
-    if(ModulesManager::modulesListHandler.containsId(id))
+    if (ModulesManager::modulesListHandler.containsId(id))
         return ModulesManager::modulesListHandler.getFactory(id)();
 
     return nullptr;
 }
 
-Module* ModulesManager::instantiateModuleById(ModuleId id, const XmlObject& params) {
+Module* ModulesManager::instantiateModuleById(ModuleId id,
+                                              const XmlObject& params) {
     Module* m = instantiateModuleById(id);
 
-    if(m != nullptr)
-        m->initialize(params);
+    if (m != nullptr) m->initialize(params);
     return m;
 }
 
 Module* ModulesManager::instantiateModuleByName(const QString& moduleName) {
-    return ModulesManager::modulesListHandler.findFactoryByModuleName(moduleName)();
+    return ModulesManager::modulesListHandler.findFactoryByModuleName(
+        moduleName)();
 }
 
-Module* ModulesManager::instantiateModuleByName(const QString& moduleName, const XmlObject& params) {
+Module* ModulesManager::instantiateModuleByName(const QString& moduleName,
+                                                const XmlObject& params) {
     Module* m = instantiateModuleByName(moduleName);
 
-    if(m != nullptr)
-        m->initialize(params);
+    if (m != nullptr) m->initialize(params);
     return m;
 }
 
-QList<Module*>ModulesManager::loadModuleFromXml(XmlObject& xml) {
+QList<Module*> ModulesManager::loadModuleFromXml(XmlObject& xml) {
     QList<Module*> windows;
 
-    for(int i = 0; i < xml.childCount(); i++) {
+    for (int i = 0; i < xml.childCount(); i++) {
         XmlObject* child = xml.getChild(i);
         QString moduleName = child->getObjectName();
         Module* module = ModulesManager::instantiateModuleByName(moduleName);
-        if(module != nullptr) {
+        if (module != nullptr) {
             module->fromXmlObject(*child);
             windows.append(module);
         }
@@ -76,23 +75,23 @@ QList<Module*>ModulesManager::loadModuleFromXml(XmlObject& xml) {
 
 void ModulesManager::setModules(QList<Module*> modules) {
     int i;
-    for(i = 0 ; i < pages.count() && i < modules.count(); i++ ) {
+    for (i = 0; i < pages.count() && i < modules.count(); i++) {
         Module* old = pages[i];
         emit pages[i]->getModuleEventsHandler()->replaceMeWith(old, modules[i]);
         delete old;
     }
-    if(i < pages.count()) {
-        for(int c = pages.count() - 1; c > i; c-- ) {
+    if (i < pages.count()) {
+        for (int c = pages.count() - 1; c > i; c--) {
             delete pages[c];
         }
     }
-    for(; i < modules.count(); i++ ) {
+    for (; i < modules.count(); i++) {
         addPage(modules[i]);
     }
 }
 
 void ModulesManager::addModules(QList<Module*> modules) {
-    for(int i = 0; i < modules.count(); i++) {
+    for (int i = 0; i < modules.count(); i++) {
         addPage(modules[i]);
     }
 }
@@ -105,7 +104,7 @@ void ModulesManager::addPage(Module* module) {
 
 void ModulesManager::removePage(Module* module) {
     int index = pages.indexOf(module);
-    if(index >= 0) {
+    if (index >= 0) {
         pages.removeAt(index);
         disconnectModule(module);
     }
@@ -122,36 +121,47 @@ Module* ModulesManager::invokeModulesPickerService() {
     return p->start();
 
 #endif
-    return  nullptr;
+    return nullptr;
 }
 
 QList<QString> ModulesManager::getModulesNamesList() {
     return ModulesManager::modulesListHandler.getModulesNamesList();
 }
 
-
 void ModulesManager::connectModule(Module* module) {
-    if(module) {
-        connect(module->getModuleEventsHandler(), &ModuleEventsHandler::contextMenuRequest, this, &ModulesManager::onContextMenuRequest);
-        connect(module->getModuleEventsHandler(), &ModuleEventsHandler::beforeDelete, this, &ModulesManager::onModuleDeleted);
-        connect(module->getModuleEventsHandler(), &ModuleEventsHandler::replaceMeWith, this, &ModulesManager::onReplaceMeWith);
+    if (module) {
+        connect(module->getModuleEventsHandler(),
+                &ModuleEventsHandler::contextMenuRequest, this,
+                &ModulesManager::onContextMenuRequest);
+        connect(module->getModuleEventsHandler(),
+                &ModuleEventsHandler::beforeDelete, this,
+                &ModulesManager::onModuleDeleted);
+        connect(module->getModuleEventsHandler(),
+                &ModuleEventsHandler::replaceMeWith, this,
+                &ModulesManager::onReplaceMeWith);
     }
 
-    //connect(module->getModuleEventsHandler(),&ModuleEventsHandler::replaceMeWithModules,this,&ModulesManager::openWindows);
+    // connect(module->getModuleEventsHandler(),&ModuleEventsHandler::replaceMeWithModules,this,&ModulesManager::openWindows);
 }
 
 void ModulesManager::disconnectModule(Module* module) {
-    if(module) {
-        disconnect(module->getModuleEventsHandler(), &ModuleEventsHandler::contextMenuRequest, this, &ModulesManager::onContextMenuRequest);
-        disconnect(module->getModuleEventsHandler(), &ModuleEventsHandler::beforeDelete, this, &ModulesManager::onModuleDeleted);
-        disconnect(module->getModuleEventsHandler(), &ModuleEventsHandler::replaceMeWith, this, &ModulesManager::onReplaceMeWith);
+    if (module) {
+        disconnect(module->getModuleEventsHandler(),
+                   &ModuleEventsHandler::contextMenuRequest, this,
+                   &ModulesManager::onContextMenuRequest);
+        disconnect(module->getModuleEventsHandler(),
+                   &ModuleEventsHandler::beforeDelete, this,
+                   &ModulesManager::onModuleDeleted);
+        disconnect(module->getModuleEventsHandler(),
+                   &ModuleEventsHandler::replaceMeWith, this,
+                   &ModulesManager::onReplaceMeWith);
     }
 }
 
 void ModulesManager::onModuleDeleted(Module* deletedModule) {
     int index = pages.indexOf(deletedModule);
 
-    if(index == 0) {
+    if (index == 0) {
         onFirstPageDeleted();
     } else {
         removePage(deletedModule);
@@ -163,27 +173,25 @@ void ModulesManager::openNewEmptyWindow() {
 }
 
 Module* ModulesManager::getModuleAt(int index) {
-    if(index >= 0 && index < pages.count()) {
+    if (index >= 0 && index < pages.count()) {
         return pages.at(index);
     }
     return nullptr;
 }
 
-int ModulesManager::getModuleCount() {
-    return pages.count();
-}
+int ModulesManager::getModuleCount() { return pages.count(); }
 
 void ModulesManager::clearPages() {
-    for(int i = pages.count() - 1; i >= 0; i--) {
+    for (int i = pages.count() - 1; i >= 0; i--) {
         delete pages[i];
     }
     pages.clear();
 }
 
 void ModulesManager::onReplaceMeWith(Module* sender, Module* newModule) {
-    if(sender != nullptr && newModule != nullptr) {
+    if (sender != nullptr && newModule != nullptr) {
         int index = pages.indexOf(sender);
-        if(index >= 0) {
+        if (index >= 0) {
             pages[index] = newModule;
             connectModule(newModule);
             disconnectModule(sender);
@@ -191,13 +199,9 @@ void ModulesManager::onReplaceMeWith(Module* sender, Module* newModule) {
     }
 }
 
-bool ModulesManager::getRebuild() const {
-    return rebuild;
-}
+bool ModulesManager::getRebuild() const { return rebuild; }
 
-void ModulesManager::setRebuild(bool value) {
-    rebuild = value;
-}
+void ModulesManager::setRebuild(bool value) { rebuild = value; }
 
 void ModulesManager::onContextMenuRequest(QMenu& menu, const QPoint& p) {
     QMenu hubMenu("Hub Menu");
@@ -207,14 +211,16 @@ void ModulesManager::onContextMenuRequest(QMenu& menu, const QPoint& p) {
 }
 
 QList<QAction*> ModulesManager::getHubMenuActions() {
-    if(menuActions.count() == 0) {
+    if (menuActions.count() == 0) {
         QAction* save = new QAction("Save");
         menuActions.append(save);
-        connect(save, &QAction::triggered, this, &ModulesManager::saveConfigurationService);
+        connect(save, &QAction::triggered, this,
+                &ModulesManager::saveConfigurationService);
 
         QAction* openWindows = new QAction("New Window");
         menuActions.append(openWindows);
-        connect(openWindows, &QAction::triggered, this, &ModulesManager::openNewEmptyWindow);
+        connect(openWindows, &QAction::triggered, this,
+                &ModulesManager::openNewEmptyWindow);
     }
 
     return menuActions;
@@ -225,7 +231,7 @@ QList<ModuleInfo> ModulesManager::getModulesInfo() {
 }
 
 void ModulesManager::saveConfigurationService() {
-    if(pages.isEmpty()) {
+    if (pages.isEmpty()) {
         QMessageBox errorMsg;
         errorMsg.setText("No module to be saved found");
         errorMsg.exec();
@@ -238,7 +244,8 @@ void ModulesManager::saveConfigurationService() {
     // Ask configuration data to the user
     SaveConfigurationDialog* saveDialog = new SaveConfigurationDialog();
     saveDialog->setConfigName(SkywardHubStrings::defaultConfigurationFileName);
-    saveDialog->setConfigIconPath(SkywardHubStrings::defaultConfigurationIconPath);
+    saveDialog->setConfigIconPath(
+        SkywardHubStrings::defaultConfigurationIconPath);
     QString configName;
     QString configIconPath;
     QString description;
@@ -247,26 +254,30 @@ void ModulesManager::saveConfigurationService() {
 #endif
 
     XmlObject xml(SkywardHubStrings::configurationNameValue);
-    xml.addAttribute(SkywardHubStrings::configurationIconPathAttribute, configIconPath);
-    xml.addAttribute(SkywardHubStrings::configurationDescriptionAttribute, description);
+    xml.addAttribute(SkywardHubStrings::configurationIconPathAttribute,
+                     configIconPath);
+    xml.addAttribute(SkywardHubStrings::configurationDescriptionAttribute,
+                     description);
 
-    if(ok && !configName.isEmpty()) {
+    if (ok && !configName.isEmpty()) {
         configName = configName.replace(".xml", "");
-        xml.addAttribute(SkywardHubStrings::configurationNameAttribute, configName);
-        if(configName.indexOf(".xml") < 0 ) {
+        xml.addAttribute(SkywardHubStrings::configurationNameAttribute,
+                         configName);
+        if (configName.indexOf(".xml") < 0) {
             configName.append(".xml");
         }
 
-        if(!QDir(SkywardHubStrings::defaultPrefabsFolder).exists()) {
+        if (!QDir(SkywardHubStrings::defaultPrefabsFolder).exists()) {
             QDir().mkpath(SkywardHubStrings::defaultPrefabsFolder);
         }
 
-        for(Module* module : pages) {
+        for (Module* module : pages) {
             xml.addChild(module->toXmlObject());
         }
 
         QString resultTxt = "Impossible to save";
-        if(xml.writeToFile(SkywardHubStrings::defaultPrefabsFolder + configName)) {
+        if (xml.writeToFile(SkywardHubStrings::defaultPrefabsFolder +
+                            configName)) {
             resultTxt = "The configuration has been saved in " + configName;
         }
         QMessageBox resultMsg;
@@ -276,18 +287,17 @@ void ModulesManager::saveConfigurationService() {
 }
 
 void ModulesManager::onFirstPageDeleted() {
-    if(!rebuild)
-        return;
+    if (!rebuild) return;
     QMessageBox msgBox;
     msgBox.setWindowTitle("title");
     msgBox.setText("Do you want to close the App?");
     msgBox.setStandardButtons(QMessageBox::Yes);
     msgBox.addButton(QMessageBox::No);
     msgBox.setDefaultButton(QMessageBox::No);
-    if(msgBox.exec() == QMessageBox::No) {
-        emit pages[0]->getModuleEventsHandler()->replaceMeWith(pages[0], instantiateDefaultModule());
+    if (msgBox.exec() == QMessageBox::No) {
+        emit pages[0]->getModuleEventsHandler()->replaceMeWith(
+            pages[0], instantiateDefaultModule());
     } else {
         emit appQuitRequested();
     }
 }
-
diff --git a/Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp b/Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp
index b3b2c10255d7f10ce55f856992d26efa4f03ea17..ddcd2e8298d972291c70e87c907cdb2a8b15fb45 100644
--- a/Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp
+++ b/Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp
@@ -1,42 +1,55 @@
+#include "incomingmessagesviewermodule.h"
+
 #include <QHBoxLayout>
 
-#include "incomingmessagesviewermodule.h"
 #include "Components/SubscriptionsPanel/subscriptionspanel.h"
 
-IncomingMessagesViewerModule::IncomingMessagesViewerModule(QWidget* parent) : DefaultModule(parent) {
+IncomingMessagesViewerModule::IncomingMessagesViewerModule(QWidget* parent)
+    : DefaultModule(parent)
+{
     setupUi();
     defaultContextMenuSetup();
 
-    getCore()->getModuleMessagesBroker()->subscribe({"*"}, this, [this](const ModuleMessage & msg) {
-        MessageField value;
-        for(auto it = filters.begin(); it != filters.end(); ++it) {
-            if(it->matchMessage(msg, value)) {
-                if(clearEveryMessage) {
-                    edit->setText("");
+    getCore()->getModuleMessagesBroker()->subscribe(
+        {"*"}, this,
+        [this](const ModuleMessage& msg)
+        {
+            MessageField value;
+            for (auto it = filters.begin(); it != filters.end(); ++it)
+            {
+                if (it->matchMessage(msg, value))
+                {
+                    if (clearEveryMessage)
+                    {
+                        edit->setText("");
+                    }
+
+                    QString old = edit->toPlainText().mid(0, 10000);
+                    edit->setText(QTime::currentTime().toString("hh.mm.ss") +
+                                  " [" + msg.getTopic().toString() +
+                                  (it->isFullFilter()
+                                       ? (QString(".") + it->getFieldFilter())
+                                       : "") +
+                                  "]: " + value.getString() + "\n" + old);
                 }
-
-                QString old = edit->toPlainText().mid(0, 10000);
-                edit->setText(QTime::currentTime().toString("hh.mm.ss") + " ["
-                              + msg.getTopic().toString() + (it->isFullFilter() ? (QString(".") + it->getFieldName()) : "")
-                              + "]: " + value.getString() + "\n" + old);
             }
-        }
-    });
+        });
 }
 
-IncomingMessagesViewerModule::~IncomingMessagesViewerModule() {
+IncomingMessagesViewerModule::~IncomingMessagesViewerModule()
+{
     getCore()->getModuleMessagesBroker()->unsubscribe({"*"}, this);
 }
 
-QWidget* IncomingMessagesViewerModule::toWidget() {
-    return this;
-}
+QWidget* IncomingMessagesViewerModule::toWidget() { return this; }
 
-XmlObject IncomingMessagesViewerModule::toXmlObject() {
+XmlObject IncomingMessagesViewerModule::toXmlObject()
+{
     XmlObject obj(getName(ModuleId::INCOMINGMESSAGESVIEWER));
     obj.addAttribute("clearEveryMessage", clearEveryMessage ? "1" : "0");
 
-    for(int i = 0; i < filters.count(); i++) {
+    for (int i = 0; i < filters.count(); i++)
+    {
         XmlObject subscription("Subscription");
         subscription.addAttribute("Value", filters[i].toString());
         obj.addChild(subscription);
@@ -45,58 +58,70 @@ XmlObject IncomingMessagesViewerModule::toXmlObject() {
     return obj;
 }
 
-void IncomingMessagesViewerModule::fromXmlObject(const XmlObject& xmlObject) {
+void IncomingMessagesViewerModule::fromXmlObject(const XmlObject& xmlObject)
+{
     clearEveryMessage = xmlObject.getAttribute("clearEveryMessage") == "1";
 
-    for(int i = 0; i < xmlObject.childCount(); i++) {
+    for (int i = 0; i < xmlObject.childCount(); i++)
+    {
         XmlObject child = xmlObject.childAt(i);
-        if(child.getObjectName() == "Subscription") {
-            auto subscription = TopicAndFieldFilter::fromStringUnsafe(child.getAttribute("Value"));
+        if (child.getObjectName() == "Subscription")
+        {
+            auto subscription = TopicAndFieldFilter::fromStringUnsafe(
+                child.getAttribute("Value"));
             addSubscription(subscription);
         }
     }
 }
 
-void IncomingMessagesViewerModule::addSubscription(const TopicAndFieldFilter& filter) {
+void IncomingMessagesViewerModule::addSubscription(
+    const TopicAndFieldFilter& filter)
+{
     filters.append(filter);
 }
 
-void IncomingMessagesViewerModule::removeSubscription(const TopicAndFieldFilter& filter) {
+void IncomingMessagesViewerModule::removeSubscription(
+    const TopicAndFieldFilter& filter)
+{
     filters.removeAll(filter);
 }
 
-void IncomingMessagesViewerModule::addCustomActionsToMenu() {
+void IncomingMessagesViewerModule::addCustomActionsToMenu()
+{
     QAction* clear = new QAction("Clear");
-    connect(clear, &QAction::triggered, this, [this]() {
-        edit->clear();
-    });
+    connect(clear, &QAction::triggered, this, [this]() { edit->clear(); });
 
     QAction* manage = new QAction("Manage subscriptions");
-    connect(manage, &QAction::triggered, this, [this]() {
-        auto* panel = new SubscriptionsPanel(&filters);
-        panel->setWindowTitle("IncomingMessagesViewer subscriptions");
-        connect(panel, &SubscriptionsPanel::SubscriptionAdded, this, &IncomingMessagesViewerModule::addSubscription);
-        connect(panel, &SubscriptionsPanel::SubscriptionRemoved, this, &IncomingMessagesViewerModule::removeSubscription);
-        panel->show();
-    });
+    connect(manage, &QAction::triggered, this,
+            [this]()
+            {
+                auto* panel = new SubscriptionsPanel(&filters);
+                panel->setWindowTitle("IncomingMessagesViewer subscriptions");
+                connect(panel, &SubscriptionsPanel::SubscriptionAdded, this,
+                        &IncomingMessagesViewerModule::addSubscription);
+                connect(panel, &SubscriptionsPanel::SubscriptionRemoved, this,
+                        &IncomingMessagesViewerModule::removeSubscription);
+                panel->show();
+            });
 
     QAction* check = new QAction("Clear every message");
     check->setCheckable(true);
     check->setChecked(clearEveryMessage);
-    connect(check, &QAction::toggled, this, &IncomingMessagesViewerModule::setClearEveryMessage);
+    connect(check, &QAction::toggled, this,
+            &IncomingMessagesViewerModule::setClearEveryMessage);
 
     addActionToMenu(clear);
     addActionToMenu(manage);
     addActionToMenu(check);
 }
 
-
-void IncomingMessagesViewerModule::setClearEveryMessage(bool val) {
+void IncomingMessagesViewerModule::setClearEveryMessage(bool val)
+{
     clearEveryMessage = val;
 }
 
-
-void IncomingMessagesViewerModule::setupUi() {
+void IncomingMessagesViewerModule::setupUi()
+{
     edit = new QTextEdit();
     edit->setReadOnly(true);
     edit->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu);
diff --git a/Modules/StateViewer/stateviewermodule.cpp b/Modules/StateViewer/stateviewermodule.cpp
index 0164c7817aa4b28f4b8e4320c4d0563f0a75a7af..d88b34682f3a16c2d08bd48bd2a186b7ebe4712d 100644
--- a/Modules/StateViewer/stateviewermodule.cpp
+++ b/Modules/StateViewer/stateviewermodule.cpp
@@ -3,11 +3,12 @@
 #include <QInputDialog>
 #include <QLineEdit>
 
-#include "Components/TopicAndFieldSelector/topicandfieldselector.h"
+#include "Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.h"
 #include "Core/modulemessagesbroker.h"
 #include "ui_stateviewermodule.h"
 
-enum states {
+enum states
+{
     INVALID = 0,
     INIT,
     INIT_ERROR,
@@ -23,7 +24,8 @@ enum states {
 };
 
 StateViewerModule::StateViewerModule(QWidget* parent)
-    : DefaultModule(parent), ui(new Ui::StateViewerModule) {
+    : DefaultModule(parent), ui(new Ui::StateViewerModule)
+{
     ui->setupUi(this);
     defaultContextMenuSetup();
 
@@ -52,14 +54,17 @@ StateViewerModule::StateViewerModule(QWidget* parent)
     };
 }
 
-StateViewerModule::~StateViewerModule() {
-    getCore()->getModuleMessagesBroker()->unsubscribe(filter.getTopic(), this);
+StateViewerModule::~StateViewerModule()
+{
+    getCore()->getModuleMessagesBroker()->unsubscribe(filter.getTopicFilter(),
+                                                      this);
     delete ui;
 }
 
 QWidget* StateViewerModule::toWidget() { return this; }
 
-XmlObject StateViewerModule::toXmlObject() {
+XmlObject StateViewerModule::toXmlObject()
+{
     XmlObject obj(getName(ModuleId::STATEVIEWER));
 
     obj.addAttribute("filter", filter.toString());
@@ -67,15 +72,18 @@ XmlObject StateViewerModule::toXmlObject() {
     return obj;
 }
 
-void StateViewerModule::fromXmlObject(const XmlObject& xmlObject) {
-    if (xmlObject.getObjectName() == getName(ModuleId::STATEVIEWER)) {
+void StateViewerModule::fromXmlObject(const XmlObject& xmlObject)
+{
+    if (xmlObject.getObjectName() == getName(ModuleId::STATEVIEWER))
+    {
         auto filter = TopicAndFieldFilter::fromStringUnsafe(
             xmlObject.getAttribute("filter"));
         setFilter(filter);
     }
 }
 
-void StateViewerModule::addCustomActionsToMenu() {
+void StateViewerModule::addCustomActionsToMenu()
+{
     QAction* config = new QAction("Choose input topic and field");
     connect(config, &QAction::triggered, this,
             &StateViewerModule::onConfigureClicked);
@@ -83,52 +91,68 @@ void StateViewerModule::addCustomActionsToMenu() {
     addActionToMenu(config);
 }
 
-void StateViewerModule::onConfigureClicked() {
-    TopicAndFieldSelector::selectTopicAndField(
+void StateViewerModule::onConfigureClicked()
+{
+    TopicAndFieldFilterSelector::selectFilter(
+        filter,
         [this](const TopicAndFieldFilter& filter) { setFilter(filter); });
 }
 
-void StateViewerModule::setFilter(const TopicAndFieldFilter& newFilter) {
-    getCore()->getModuleMessagesBroker()->unsubscribe(filter.getTopic(), this);
+void StateViewerModule::setFilter(const TopicAndFieldFilter& newFilter)
+{
+    getCore()->getModuleMessagesBroker()->unsubscribe(filter.getTopicFilter(),
+                                                      this);
     getCore()->getModuleMessagesBroker()->subscribe(
-        newFilter.getTopic(), this,
+        newFilter.getTopicFilter(), this,
         [this](const ModuleMessage& msg) { onMsgReceived(msg); });
     filter = newFilter;
 }
 
-void StateViewerModule::onMsgReceived(const ModuleMessage& msg) {
+void StateViewerModule::onMsgReceived(const ModuleMessage& msg)
+{
     MessageField field;
 
-    if (!filter.matchMessage(msg, field)) return;
+    if (!filter.matchMessage(msg, field))
+        return;
 
     int value = (int)field.getUInteger(-1);
-    if (value != -1) setState(value);
+    if (value != -1)
+        setState(value);
 }
 
-void StateViewerModule::setState(int state) {
-    if (state != currentState) {
+void StateViewerModule::setState(int state)
+{
+    if (state != currentState)
+    {
         currentState = state;
         updateView(state);
     }
 }
 
-void StateViewerModule::updateView(int state) {
+void StateViewerModule::updateView(int state)
+{
     QString currentStateStyle = "background-color:yellow; color:black;";
-    QString completedStyle = "background-color:green;";
-    QString errorStyle = "background-color:red;";
+    QString completedStyle    = "background-color:green;";
+    QString errorStyle        = "background-color:red;";
 
-    if (state == INIT) {
+    if (state == INIT)
+    {
         ui->label_1_INIT->setStyleSheet(currentStateStyle);
-    } else if (state == INIT_ERROR) {
+    }
+    else if (state == INIT_ERROR)
+    {
         ui->label_1_INIT->setStyleSheet(errorStyle);
-    } else if (state > INIT_ERROR && labelsIndexes.contains(state)) {
+    }
+    else if (state > INIT_ERROR && labelsIndexes.contains(state))
+    {
         int index = labelsIndexes[state];
 
         if (index < labels.count())
             labels[index]->setStyleSheet(currentStateStyle);
     }
 
-    if (labelsIndexes.contains(state)) {
+    if (labelsIndexes.contains(state))
+    {
         int index = labelsIndexes[state];
 
         // Set as completed every state before the current
diff --git a/Modules/StateViewer/stateviewermodule.h b/Modules/StateViewer/stateviewermodule.h
index 2b62b6349c9aaef70f39be903f2c23a9550067f8..2e6e5da0d7cd8c9980f9df486a449ab2cee14573 100644
--- a/Modules/StateViewer/stateviewermodule.h
+++ b/Modules/StateViewer/stateviewermodule.h
@@ -8,14 +8,16 @@
 #include "Core/Message/topicandfieldfilter.h"
 #include "Modules/DefaultModule/defaultmodule.h"
 
-namespace Ui {
+namespace Ui
+{
 class StateViewerModule;
 }
 
-class StateViewerModule : public DefaultModule {
+class StateViewerModule : public DefaultModule
+{
     Q_OBJECT
 
-   public:
+public:
     explicit StateViewerModule(QWidget* parent = nullptr);
     ~StateViewerModule();
 
@@ -24,7 +26,7 @@ class StateViewerModule : public DefaultModule {
     XmlObject toXmlObject() override;
     void fromXmlObject(const XmlObject& xmlObject) override;
 
-   protected:
+protected:
     void addCustomActionsToMenu() override;
     void onConfigureClicked();
     void setFilter(const TopicAndFieldFilter& filter);
@@ -32,7 +34,7 @@ class StateViewerModule : public DefaultModule {
     void setState(int state);
     void updateView(int state);
 
-   private:
+private:
     Ui::StateViewerModule* ui;
     TopicAndFieldFilter filter;
 
diff --git a/SkywardHub.pro b/SkywardHub.pro
index 7d72891ac4668fe8c332a0cdb9b8c62932f00976..40c31260621626001c693ee0ce75fe98dfa1aa74 100644
--- a/SkywardHub.pro
+++ b/SkywardHub.pro
@@ -17,7 +17,8 @@ SOURCES += \
     Components/ToggleButton/togglebutton.cpp \
     Components/ErrorDisplayer/error.cpp \
     Components/ErrorDisplayer/errordisplayer.cpp \
-    Components/TopicAndFieldSelector/topicandfieldselector.cpp \
+    Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.cpp \
+    Components/TopicFilterSelector/topicfilterselector.cpp \
     Core/Message/messagefield.cpp \
     Core/Message/modulemessage.cpp \
     Core/Message/topic.cpp \
@@ -69,7 +70,8 @@ HEADERS += \
     Components/ToggleButton/togglebutton.h \
     Components/ErrorDisplayer/error.h \
     Components/ErrorDisplayer/errordisplayer.h \
-    Components/TopicAndFieldSelector/topicandfieldselector.h \
+    Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.h \
+    Components/TopicFilterSelector/topicfilterselector.h \
     Core/Message/messagefield.h \
     Core/Message/modulemessage.h \
     Core/Message/topic.h \